Gentoo Archives: gentoo-commits

From: "Gordon Malm (gengor)" <gengor@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] linux-patches r1404 - hardened/2.6/trunk/2.6.27
Date: Mon, 24 Nov 2008 01:41:54
Message-Id: E1L4QQb-0004KG-LZ@stork.gentoo.org
1 Author: gengor
2 Date: 2008-11-24 01:39:52 +0000 (Mon, 24 Nov 2008)
3 New Revision: 1404
4
5 Added:
6 hardened/2.6/trunk/2.6.27/4420_grsec-2.1.12-2.6.27.7-200811201849.patch
7 Removed:
8 hardened/2.6/trunk/2.6.27/4420_grsec-2.1.12-2.6.27.6-200811191750.patch
9 Modified:
10 hardened/2.6/trunk/2.6.27/0000_README
11 Log:
12 Released 2.6.27-r2, updating trunk to it
13
14 Modified: hardened/2.6/trunk/2.6.27/0000_README
15 ===================================================================
16 --- hardened/2.6/trunk/2.6.27/0000_README 2008-11-21 19:24:32 UTC (rev 1403)
17 +++ hardened/2.6/trunk/2.6.27/0000_README 2008-11-24 01:39:52 UTC (rev 1404)
18 @@ -3,7 +3,7 @@
19
20 Individual Patch Descriptions:
21 -----------------------------------------------------------------------------
22 -Patch: 4420_grsec-2.1.12-2.6.27.6-200811191750.patch
23 +Patch: 4420_grsec-2.1.12-2.6.27.7-200811201849.patch
24 From: http://www.grsecurity.net
25 Desc: hardened-sources base patch from upstream grsecurity
26
27
28 Deleted: hardened/2.6/trunk/2.6.27/4420_grsec-2.1.12-2.6.27.6-200811191750.patch
29 ===================================================================
30 --- hardened/2.6/trunk/2.6.27/4420_grsec-2.1.12-2.6.27.6-200811191750.patch 2008-11-21 19:24:32 UTC (rev 1403)
31 +++ hardened/2.6/trunk/2.6.27/4420_grsec-2.1.12-2.6.27.6-200811191750.patch 2008-11-24 01:39:52 UTC (rev 1404)
32 @@ -1,37021 +0,0 @@
33 -diff -urNp linux-2.6.27.6/arch/alpha/include/asm/elf.h linux-2.6.27.6/arch/alpha/include/asm/elf.h
34 ---- linux-2.6.27.6/arch/alpha/include/asm/elf.h 2008-11-07 12:55:34.000000000 -0500
35 -+++ linux-2.6.27.6/arch/alpha/include/asm/elf.h 2008-11-18 03:39:50.000000000 -0500
36 -@@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
37 -
38 - #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
39 -
40 -+#ifdef CONFIG_PAX_ASLR
41 -+#define PAX_ELF_ET_DYN_BASE (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
42 -+
43 -+#define PAX_DELTA_MMAP_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 28)
44 -+#define PAX_DELTA_STACK_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 19)
45 -+#endif
46 -+
47 - /* $0 is set by ld.so to a pointer to a function which might be
48 - registered using atexit. This provides a mean for the dynamic
49 - linker to call DT_FINI functions for shared libraries that have
50 -diff -urNp linux-2.6.27.6/arch/alpha/include/asm/kmap_types.h linux-2.6.27.6/arch/alpha/include/asm/kmap_types.h
51 ---- linux-2.6.27.6/arch/alpha/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
52 -+++ linux-2.6.27.6/arch/alpha/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
53 -@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
54 - D(10) KM_IRQ1,
55 - D(11) KM_SOFTIRQ0,
56 - D(12) KM_SOFTIRQ1,
57 --D(13) KM_TYPE_NR
58 -+D(13) KM_CLEARPAGE,
59 -+D(14) KM_TYPE_NR
60 - };
61 -
62 - #undef D
63 -diff -urNp linux-2.6.27.6/arch/alpha/include/asm/pgtable.h linux-2.6.27.6/arch/alpha/include/asm/pgtable.h
64 ---- linux-2.6.27.6/arch/alpha/include/asm/pgtable.h 2008-11-07 12:55:34.000000000 -0500
65 -+++ linux-2.6.27.6/arch/alpha/include/asm/pgtable.h 2008-11-18 03:39:50.000000000 -0500
66 -@@ -101,6 +101,17 @@ struct vm_area_struct;
67 - #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
68 - #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
69 - #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
70 -+
71 -+#ifdef CONFIG_PAX_PAGEEXEC
72 -+# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
73 -+# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
74 -+# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
75 -+#else
76 -+# define PAGE_SHARED_NOEXEC PAGE_SHARED
77 -+# define PAGE_COPY_NOEXEC PAGE_COPY
78 -+# define PAGE_READONLY_NOEXEC PAGE_READONLY
79 -+#endif
80 -+
81 - #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
82 -
83 - #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
84 -diff -urNp linux-2.6.27.6/arch/alpha/kernel/module.c linux-2.6.27.6/arch/alpha/kernel/module.c
85 ---- linux-2.6.27.6/arch/alpha/kernel/module.c 2008-11-07 12:55:34.000000000 -0500
86 -+++ linux-2.6.27.6/arch/alpha/kernel/module.c 2008-11-18 03:38:43.000000000 -0500
87 -@@ -182,7 +182,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
88 -
89 - /* The small sections were sorted to the end of the segment.
90 - The following should definitely cover them. */
91 -- gp = (u64)me->module_core + me->core_size - 0x8000;
92 -+ gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
93 - got = sechdrs[me->arch.gotsecindex].sh_addr;
94 -
95 - for (i = 0; i < n; i++) {
96 -diff -urNp linux-2.6.27.6/arch/alpha/kernel/osf_sys.c linux-2.6.27.6/arch/alpha/kernel/osf_sys.c
97 ---- linux-2.6.27.6/arch/alpha/kernel/osf_sys.c 2008-11-07 12:55:34.000000000 -0500
98 -+++ linux-2.6.27.6/arch/alpha/kernel/osf_sys.c 2008-11-18 03:38:43.000000000 -0500
99 -@@ -1232,6 +1232,10 @@ arch_get_unmapped_area(struct file *filp
100 - merely specific addresses, but regions of memory -- perhaps
101 - this feature should be incorporated into all ports? */
102 -
103 -+#ifdef CONFIG_PAX_RANDMMAP
104 -+ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
105 -+#endif
106 -+
107 - if (addr) {
108 - addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
109 - if (addr != (unsigned long) -ENOMEM)
110 -@@ -1239,8 +1243,8 @@ arch_get_unmapped_area(struct file *filp
111 - }
112 -
113 - /* Next, try allocating at TASK_UNMAPPED_BASE. */
114 -- addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
115 -- len, limit);
116 -+ addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
117 -+
118 - if (addr != (unsigned long) -ENOMEM)
119 - return addr;
120 -
121 -diff -urNp linux-2.6.27.6/arch/alpha/kernel/ptrace.c linux-2.6.27.6/arch/alpha/kernel/ptrace.c
122 ---- linux-2.6.27.6/arch/alpha/kernel/ptrace.c 2008-11-07 12:55:34.000000000 -0500
123 -+++ linux-2.6.27.6/arch/alpha/kernel/ptrace.c 2008-11-18 03:38:43.000000000 -0500
124 -@@ -15,6 +15,7 @@
125 - #include <linux/slab.h>
126 - #include <linux/security.h>
127 - #include <linux/signal.h>
128 -+#include <linux/grsecurity.h>
129 -
130 - #include <asm/uaccess.h>
131 - #include <asm/pgtable.h>
132 -@@ -266,6 +267,9 @@ long arch_ptrace(struct task_struct *chi
133 - size_t copied;
134 - long ret;
135 -
136 -+ if (gr_handle_ptrace(child, request))
137 -+ return -EPERM;
138 -+
139 - switch (request) {
140 - /* When I and D space are separate, these will need to be fixed. */
141 - case PTRACE_PEEKTEXT: /* read word at location addr. */
142 -diff -urNp linux-2.6.27.6/arch/alpha/mm/fault.c linux-2.6.27.6/arch/alpha/mm/fault.c
143 ---- linux-2.6.27.6/arch/alpha/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
144 -+++ linux-2.6.27.6/arch/alpha/mm/fault.c 2008-11-18 03:38:43.000000000 -0500
145 -@@ -54,6 +54,124 @@ __load_new_mm_context(struct mm_struct *
146 - __reload_thread(pcb);
147 - }
148 -
149 -+#ifdef CONFIG_PAX_PAGEEXEC
150 -+/*
151 -+ * PaX: decide what to do with offenders (regs->pc = fault address)
152 -+ *
153 -+ * returns 1 when task should be killed
154 -+ * 2 when patched PLT trampoline was detected
155 -+ * 3 when unpatched PLT trampoline was detected
156 -+ */
157 -+static int pax_handle_fetch_fault(struct pt_regs *regs)
158 -+{
159 -+
160 -+#ifdef CONFIG_PAX_EMUPLT
161 -+ int err;
162 -+
163 -+ do { /* PaX: patched PLT emulation #1 */
164 -+ unsigned int ldah, ldq, jmp;
165 -+
166 -+ err = get_user(ldah, (unsigned int *)regs->pc);
167 -+ err |= get_user(ldq, (unsigned int *)(regs->pc+4));
168 -+ err |= get_user(jmp, (unsigned int *)(regs->pc+8));
169 -+
170 -+ if (err)
171 -+ break;
172 -+
173 -+ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
174 -+ (ldq & 0xFFFF0000U) == 0xA77B0000U &&
175 -+ jmp == 0x6BFB0000U)
176 -+ {
177 -+ unsigned long r27, addr;
178 -+ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
179 -+ unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
180 -+
181 -+ addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
182 -+ err = get_user(r27, (unsigned long *)addr);
183 -+ if (err)
184 -+ break;
185 -+
186 -+ regs->r27 = r27;
187 -+ regs->pc = r27;
188 -+ return 2;
189 -+ }
190 -+ } while (0);
191 -+
192 -+ do { /* PaX: patched PLT emulation #2 */
193 -+ unsigned int ldah, lda, br;
194 -+
195 -+ err = get_user(ldah, (unsigned int *)regs->pc);
196 -+ err |= get_user(lda, (unsigned int *)(regs->pc+4));
197 -+ err |= get_user(br, (unsigned int *)(regs->pc+8));
198 -+
199 -+ if (err)
200 -+ break;
201 -+
202 -+ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
203 -+ (lda & 0xFFFF0000U) == 0xA77B0000U &&
204 -+ (br & 0xFFE00000U) == 0xC3E00000U)
205 -+ {
206 -+ unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
207 -+ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
208 -+ unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
209 -+
210 -+ regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
211 -+ regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
212 -+ return 2;
213 -+ }
214 -+ } while (0);
215 -+
216 -+ do { /* PaX: unpatched PLT emulation */
217 -+ unsigned int br;
218 -+
219 -+ err = get_user(br, (unsigned int *)regs->pc);
220 -+
221 -+ if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
222 -+ unsigned int br2, ldq, nop, jmp;
223 -+ unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
224 -+
225 -+ addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
226 -+ err = get_user(br2, (unsigned int *)addr);
227 -+ err |= get_user(ldq, (unsigned int *)(addr+4));
228 -+ err |= get_user(nop, (unsigned int *)(addr+8));
229 -+ err |= get_user(jmp, (unsigned int *)(addr+12));
230 -+ err |= get_user(resolver, (unsigned long *)(addr+16));
231 -+
232 -+ if (err)
233 -+ break;
234 -+
235 -+ if (br2 == 0xC3600000U &&
236 -+ ldq == 0xA77B000CU &&
237 -+ nop == 0x47FF041FU &&
238 -+ jmp == 0x6B7B0000U)
239 -+ {
240 -+ regs->r28 = regs->pc+4;
241 -+ regs->r27 = addr+16;
242 -+ regs->pc = resolver;
243 -+ return 3;
244 -+ }
245 -+ }
246 -+ } while (0);
247 -+#endif
248 -+
249 -+ return 1;
250 -+}
251 -+
252 -+void pax_report_insns(void *pc, void *sp)
253 -+{
254 -+ unsigned long i;
255 -+
256 -+ printk(KERN_ERR "PAX: bytes at PC: ");
257 -+ for (i = 0; i < 5; i++) {
258 -+ unsigned int c;
259 -+ if (get_user(c, (unsigned int *)pc+i))
260 -+ printk(KERN_CONT "???????? ");
261 -+ else
262 -+ printk(KERN_CONT "%08x ", c);
263 -+ }
264 -+ printk("\n");
265 -+}
266 -+#endif
267 -
268 - /*
269 - * This routine handles page faults. It determines the address,
270 -@@ -131,8 +249,29 @@ do_page_fault(unsigned long address, uns
271 - good_area:
272 - si_code = SEGV_ACCERR;
273 - if (cause < 0) {
274 -- if (!(vma->vm_flags & VM_EXEC))
275 -+ if (!(vma->vm_flags & VM_EXEC)) {
276 -+
277 -+#ifdef CONFIG_PAX_PAGEEXEC
278 -+ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
279 -+ goto bad_area;
280 -+
281 -+ up_read(&mm->mmap_sem);
282 -+ switch (pax_handle_fetch_fault(regs)) {
283 -+
284 -+#ifdef CONFIG_PAX_EMUPLT
285 -+ case 2:
286 -+ case 3:
287 -+ return;
288 -+#endif
289 -+
290 -+ }
291 -+ pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
292 -+ do_group_exit(SIGKILL);
293 -+#else
294 - goto bad_area;
295 -+#endif
296 -+
297 -+ }
298 - } else if (!cause) {
299 - /* Allow reads even for write-only mappings */
300 - if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
301 -diff -urNp linux-2.6.27.6/arch/arm/include/asm/elf.h linux-2.6.27.6/arch/arm/include/asm/elf.h
302 ---- linux-2.6.27.6/arch/arm/include/asm/elf.h 2008-11-07 12:55:34.000000000 -0500
303 -+++ linux-2.6.27.6/arch/arm/include/asm/elf.h 2008-11-18 03:39:50.000000000 -0500
304 -@@ -87,7 +87,14 @@ extern char elf_platform[];
305 - the loader. We need to make sure that it is out of the way of the program
306 - that it will "exec", and that there is sufficient room for the brk. */
307 -
308 --#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
309 -+#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
310 -+
311 -+#ifdef CONFIG_PAX_ASLR
312 -+#define PAX_ELF_ET_DYN_BASE 0x00008000UL
313 -+
314 -+#define PAX_DELTA_MMAP_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
315 -+#define PAX_DELTA_STACK_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
316 -+#endif
317 -
318 - /* When the program starts, a1 contains a pointer to a function to be
319 - registered with atexit, as per the SVR4 ABI. A value of 0 means we
320 -diff -urNp linux-2.6.27.6/arch/arm/include/asm/kmap_types.h linux-2.6.27.6/arch/arm/include/asm/kmap_types.h
321 ---- linux-2.6.27.6/arch/arm/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
322 -+++ linux-2.6.27.6/arch/arm/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
323 -@@ -18,6 +18,7 @@ enum km_type {
324 - KM_IRQ1,
325 - KM_SOFTIRQ0,
326 - KM_SOFTIRQ1,
327 -+ KM_CLEARPAGE,
328 - KM_TYPE_NR
329 - };
330 -
331 -diff -urNp linux-2.6.27.6/arch/arm/mm/mmap.c linux-2.6.27.6/arch/arm/mm/mmap.c
332 ---- linux-2.6.27.6/arch/arm/mm/mmap.c 2008-11-07 12:55:34.000000000 -0500
333 -+++ linux-2.6.27.6/arch/arm/mm/mmap.c 2008-11-18 03:38:43.000000000 -0500
334 -@@ -60,6 +60,10 @@ arch_get_unmapped_area(struct file *filp
335 - if (len > TASK_SIZE)
336 - return -ENOMEM;
337 -
338 -+#ifdef CONFIG_PAX_RANDMMAP
339 -+ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
340 -+#endif
341 -+
342 - if (addr) {
343 - if (do_align)
344 - addr = COLOUR_ALIGN(addr, pgoff);
345 -@@ -72,10 +76,10 @@ arch_get_unmapped_area(struct file *filp
346 - return addr;
347 - }
348 - if (len > mm->cached_hole_size) {
349 -- start_addr = addr = mm->free_area_cache;
350 -+ start_addr = addr = mm->free_area_cache;
351 - } else {
352 -- start_addr = addr = TASK_UNMAPPED_BASE;
353 -- mm->cached_hole_size = 0;
354 -+ start_addr = addr = mm->mmap_base;
355 -+ mm->cached_hole_size = 0;
356 - }
357 -
358 - full_search:
359 -@@ -91,8 +95,8 @@ full_search:
360 - * Start a new search - just in case we missed
361 - * some holes.
362 - */
363 -- if (start_addr != TASK_UNMAPPED_BASE) {
364 -- start_addr = addr = TASK_UNMAPPED_BASE;
365 -+ if (start_addr != mm->mmap_base) {
366 -+ start_addr = addr = mm->mmap_base;
367 - mm->cached_hole_size = 0;
368 - goto full_search;
369 - }
370 -diff -urNp linux-2.6.27.6/arch/avr32/include/asm/elf.h linux-2.6.27.6/arch/avr32/include/asm/elf.h
371 ---- linux-2.6.27.6/arch/avr32/include/asm/elf.h 2008-11-07 12:55:34.000000000 -0500
372 -+++ linux-2.6.27.6/arch/avr32/include/asm/elf.h 2008-11-18 03:39:50.000000000 -0500
373 -@@ -85,8 +85,14 @@ typedef struct user_fpu_struct elf_fpreg
374 - the loader. We need to make sure that it is out of the way of the program
375 - that it will "exec", and that there is sufficient room for the brk. */
376 -
377 --#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
378 -+#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
379 -
380 -+#ifdef CONFIG_PAX_ASLR
381 -+#define PAX_ELF_ET_DYN_BASE 0x00001000UL
382 -+
383 -+#define PAX_DELTA_MMAP_LEN 15
384 -+#define PAX_DELTA_STACK_LEN 15
385 -+#endif
386 -
387 - /* This yields a mask that user programs can use to figure out what
388 - instruction set this CPU supports. This could be done in user space,
389 -diff -urNp linux-2.6.27.6/arch/avr32/include/asm/kmap_types.h linux-2.6.27.6/arch/avr32/include/asm/kmap_types.h
390 ---- linux-2.6.27.6/arch/avr32/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
391 -+++ linux-2.6.27.6/arch/avr32/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
392 -@@ -22,7 +22,8 @@ D(10) KM_IRQ0,
393 - D(11) KM_IRQ1,
394 - D(12) KM_SOFTIRQ0,
395 - D(13) KM_SOFTIRQ1,
396 --D(14) KM_TYPE_NR
397 -+D(14) KM_CLEARPAGE,
398 -+D(15) KM_TYPE_NR
399 - };
400 -
401 - #undef D
402 -diff -urNp linux-2.6.27.6/arch/avr32/mm/fault.c linux-2.6.27.6/arch/avr32/mm/fault.c
403 ---- linux-2.6.27.6/arch/avr32/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
404 -+++ linux-2.6.27.6/arch/avr32/mm/fault.c 2008-11-18 03:38:43.000000000 -0500
405 -@@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
406 -
407 - int exception_trace = 1;
408 -
409 -+#ifdef CONFIG_PAX_PAGEEXEC
410 -+void pax_report_insns(void *pc, void *sp)
411 -+{
412 -+ unsigned long i;
413 -+
414 -+ printk(KERN_ERR "PAX: bytes at PC: ");
415 -+ for (i = 0; i < 20; i++) {
416 -+ unsigned char c;
417 -+ if (get_user(c, (unsigned char *)pc+i))
418 -+ printk(KERN_CONT "???????? ");
419 -+ else
420 -+ printk(KERN_CONT "%02x ", c);
421 -+ }
422 -+ printk("\n");
423 -+}
424 -+#endif
425 -+
426 - /*
427 - * This routine handles page faults. It determines the address and the
428 - * problem, and then passes it off to one of the appropriate routines.
429 -@@ -157,6 +174,16 @@ bad_area:
430 - up_read(&mm->mmap_sem);
431 -
432 - if (user_mode(regs)) {
433 -+
434 -+#ifdef CONFIG_PAX_PAGEEXEC
435 -+ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
436 -+ if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
437 -+ pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
438 -+ do_group_exit(SIGKILL);
439 -+ }
440 -+ }
441 -+#endif
442 -+
443 - if (exception_trace && printk_ratelimit())
444 - printk("%s%s[%d]: segfault at %08lx pc %08lx "
445 - "sp %08lx ecr %lu\n",
446 -diff -urNp linux-2.6.27.6/arch/blackfin/include/asm/kmap_types.h linux-2.6.27.6/arch/blackfin/include/asm/kmap_types.h
447 ---- linux-2.6.27.6/arch/blackfin/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
448 -+++ linux-2.6.27.6/arch/blackfin/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
449 -@@ -15,6 +15,7 @@ enum km_type {
450 - KM_IRQ1,
451 - KM_SOFTIRQ0,
452 - KM_SOFTIRQ1,
453 -+ KM_CLEARPAGE,
454 - KM_TYPE_NR
455 - };
456 -
457 -diff -urNp linux-2.6.27.6/arch/h8300/include/asm/kmap_types.h linux-2.6.27.6/arch/h8300/include/asm/kmap_types.h
458 ---- linux-2.6.27.6/arch/h8300/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
459 -+++ linux-2.6.27.6/arch/h8300/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
460 -@@ -15,6 +15,7 @@ enum km_type {
461 - KM_IRQ1,
462 - KM_SOFTIRQ0,
463 - KM_SOFTIRQ1,
464 -+ KM_CLEARPAGE,
465 - KM_TYPE_NR
466 - };
467 -
468 -diff -urNp linux-2.6.27.6/arch/ia64/ia32/binfmt_elf32.c linux-2.6.27.6/arch/ia64/ia32/binfmt_elf32.c
469 ---- linux-2.6.27.6/arch/ia64/ia32/binfmt_elf32.c 2008-11-07 12:55:34.000000000 -0500
470 -+++ linux-2.6.27.6/arch/ia64/ia32/binfmt_elf32.c 2008-11-18 03:38:43.000000000 -0500
471 -@@ -45,6 +45,13 @@ randomize_stack_top(unsigned long stack_
472 -
473 - #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
474 -
475 -+#ifdef CONFIG_PAX_ASLR
476 -+#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
477 -+
478 -+#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
479 -+#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
480 -+#endif
481 -+
482 - /* Ugly but avoids duplication */
483 - #include "../../../fs/binfmt_elf.c"
484 -
485 -diff -urNp linux-2.6.27.6/arch/ia64/ia32/ia32priv.h linux-2.6.27.6/arch/ia64/ia32/ia32priv.h
486 ---- linux-2.6.27.6/arch/ia64/ia32/ia32priv.h 2008-11-07 12:55:34.000000000 -0500
487 -+++ linux-2.6.27.6/arch/ia64/ia32/ia32priv.h 2008-11-18 03:38:43.000000000 -0500
488 -@@ -296,7 +296,14 @@ typedef struct compat_siginfo {
489 - #define ELF_DATA ELFDATA2LSB
490 - #define ELF_ARCH EM_386
491 -
492 --#define IA32_STACK_TOP IA32_PAGE_OFFSET
493 -+#ifdef CONFIG_PAX_RANDUSTACK
494 -+#define __IA32_DELTA_STACK (current->mm->delta_stack)
495 -+#else
496 -+#define __IA32_DELTA_STACK 0UL
497 -+#endif
498 -+
499 -+#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
500 -+
501 - #define IA32_GATE_OFFSET IA32_PAGE_OFFSET
502 - #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
503 -
504 -diff -urNp linux-2.6.27.6/arch/ia64/include/asm/elf.h linux-2.6.27.6/arch/ia64/include/asm/elf.h
505 ---- linux-2.6.27.6/arch/ia64/include/asm/elf.h 2008-11-07 12:55:34.000000000 -0500
506 -+++ linux-2.6.27.6/arch/ia64/include/asm/elf.h 2008-11-18 03:39:50.000000000 -0500
507 -@@ -43,6 +43,13 @@
508 - */
509 - #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x800000000UL)
510 -
511 -+#ifdef CONFIG_PAX_ASLR
512 -+#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
513 -+
514 -+#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
515 -+#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
516 -+#endif
517 -+
518 - #define PT_IA_64_UNWIND 0x70000001
519 -
520 - /* IA-64 relocations: */
521 -diff -urNp linux-2.6.27.6/arch/ia64/include/asm/kmap_types.h linux-2.6.27.6/arch/ia64/include/asm/kmap_types.h
522 ---- linux-2.6.27.6/arch/ia64/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
523 -+++ linux-2.6.27.6/arch/ia64/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
524 -@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
525 - D(10) KM_IRQ1,
526 - D(11) KM_SOFTIRQ0,
527 - D(12) KM_SOFTIRQ1,
528 --D(13) KM_TYPE_NR
529 -+D(13) KM_CLEARPAGE,
530 -+D(14) KM_TYPE_NR
531 - };
532 -
533 - #undef D
534 -diff -urNp linux-2.6.27.6/arch/ia64/include/asm/pgtable.h linux-2.6.27.6/arch/ia64/include/asm/pgtable.h
535 ---- linux-2.6.27.6/arch/ia64/include/asm/pgtable.h 2008-11-07 12:55:34.000000000 -0500
536 -+++ linux-2.6.27.6/arch/ia64/include/asm/pgtable.h 2008-11-18 03:39:50.000000000 -0500
537 -@@ -143,6 +143,17 @@
538 - #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
539 - #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
540 - #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
541 -+
542 -+#ifdef CONFIG_PAX_PAGEEXEC
543 -+# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
544 -+# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
545 -+# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
546 -+#else
547 -+# define PAGE_SHARED_NOEXEC PAGE_SHARED
548 -+# define PAGE_READONLY_NOEXEC PAGE_READONLY
549 -+# define PAGE_COPY_NOEXEC PAGE_COPY
550 -+#endif
551 -+
552 - #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
553 - #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
554 - #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
555 -diff -urNp linux-2.6.27.6/arch/ia64/kernel/module.c linux-2.6.27.6/arch/ia64/kernel/module.c
556 ---- linux-2.6.27.6/arch/ia64/kernel/module.c 2008-11-07 12:55:34.000000000 -0500
557 -+++ linux-2.6.27.6/arch/ia64/kernel/module.c 2008-11-18 03:38:43.000000000 -0500
558 -@@ -312,8 +312,7 @@ module_alloc (unsigned long size)
559 - void
560 - module_free (struct module *mod, void *module_region)
561 - {
562 -- if (mod && mod->arch.init_unw_table &&
563 -- module_region == mod->module_init) {
564 -+ if (mod && mod->arch.init_unw_table && module_region == mod->module_init_rx) {
565 - unw_remove_unwind_table(mod->arch.init_unw_table);
566 - mod->arch.init_unw_table = NULL;
567 - }
568 -@@ -491,15 +490,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
569 - }
570 -
571 - static inline int
572 -+in_init_rx (const struct module *mod, uint64_t addr)
573 -+{
574 -+ return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
575 -+}
576 -+
577 -+static inline int
578 -+in_init_rw (const struct module *mod, uint64_t addr)
579 -+{
580 -+ return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
581 -+}
582 -+
583 -+static inline int
584 - in_init (const struct module *mod, uint64_t addr)
585 - {
586 -- return addr - (uint64_t) mod->module_init < mod->init_size;
587 -+ return in_init_rx(mod, addr) || in_init_rw(mod, addr);
588 -+}
589 -+
590 -+static inline int
591 -+in_core_rx (const struct module *mod, uint64_t addr)
592 -+{
593 -+ return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
594 -+}
595 -+
596 -+static inline int
597 -+in_core_rw (const struct module *mod, uint64_t addr)
598 -+{
599 -+ return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
600 - }
601 -
602 - static inline int
603 - in_core (const struct module *mod, uint64_t addr)
604 - {
605 -- return addr - (uint64_t) mod->module_core < mod->core_size;
606 -+ return in_core_rx(mod, addr) || in_core_rw(mod, addr);
607 - }
608 -
609 - static inline int
610 -@@ -683,7 +706,14 @@ do_reloc (struct module *mod, uint8_t r_
611 - break;
612 -
613 - case RV_BDREL:
614 -- val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
615 -+ if (in_init_rx(mod, val))
616 -+ val -= (uint64_t) mod->module_init_rx;
617 -+ else if (in_init_rw(mod, val))
618 -+ val -= (uint64_t) mod->module_init_rw;
619 -+ else if (in_core_rx(mod, val))
620 -+ val -= (uint64_t) mod->module_core_rx;
621 -+ else if (in_core_rw(mod, val))
622 -+ val -= (uint64_t) mod->module_core_rw;
623 - break;
624 -
625 - case RV_LTV:
626 -@@ -817,15 +847,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
627 - * addresses have been selected...
628 - */
629 - uint64_t gp;
630 -- if (mod->core_size > MAX_LTOFF)
631 -+ if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
632 - /*
633 - * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
634 - * at the end of the module.
635 - */
636 -- gp = mod->core_size - MAX_LTOFF / 2;
637 -+ gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
638 - else
639 -- gp = mod->core_size / 2;
640 -- gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
641 -+ gp = (mod->core_size_rx + mod->core_size_rw) / 2;
642 -+ gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
643 - mod->arch.gp = gp;
644 - DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
645 - }
646 -diff -urNp linux-2.6.27.6/arch/ia64/kernel/sys_ia64.c linux-2.6.27.6/arch/ia64/kernel/sys_ia64.c
647 ---- linux-2.6.27.6/arch/ia64/kernel/sys_ia64.c 2008-11-07 12:55:34.000000000 -0500
648 -+++ linux-2.6.27.6/arch/ia64/kernel/sys_ia64.c 2008-11-18 03:38:43.000000000 -0500
649 -@@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
650 - if (REGION_NUMBER(addr) == RGN_HPAGE)
651 - addr = 0;
652 - #endif
653 -+
654 -+#ifdef CONFIG_PAX_RANDMMAP
655 -+ if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
656 -+ addr = mm->free_area_cache;
657 -+ else
658 -+#endif
659 -+
660 - if (!addr)
661 - addr = mm->free_area_cache;
662 -
663 -@@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil
664 - for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
665 - /* At this point: (!vma || addr < vma->vm_end). */
666 - if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
667 -- if (start_addr != TASK_UNMAPPED_BASE) {
668 -+ if (start_addr != mm->mmap_base) {
669 - /* Start a new search --- just in case we missed some holes. */
670 -- addr = TASK_UNMAPPED_BASE;
671 -+ addr = mm->mmap_base;
672 - goto full_search;
673 - }
674 - return -ENOMEM;
675 -diff -urNp linux-2.6.27.6/arch/ia64/mm/fault.c linux-2.6.27.6/arch/ia64/mm/fault.c
676 ---- linux-2.6.27.6/arch/ia64/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
677 -+++ linux-2.6.27.6/arch/ia64/mm/fault.c 2008-11-18 03:38:43.000000000 -0500
678 -@@ -72,6 +72,23 @@ mapped_kernel_page_is_present (unsigned
679 - return pte_present(pte);
680 - }
681 -
682 -+#ifdef CONFIG_PAX_PAGEEXEC
683 -+void pax_report_insns(void *pc, void *sp)
684 -+{
685 -+ unsigned long i;
686 -+
687 -+ printk(KERN_ERR "PAX: bytes at PC: ");
688 -+ for (i = 0; i < 8; i++) {
689 -+ unsigned int c;
690 -+ if (get_user(c, (unsigned int *)pc+i))
691 -+ printk(KERN_CONT "???????? ");
692 -+ else
693 -+ printk(KERN_CONT "%08x ", c);
694 -+ }
695 -+ printk("\n");
696 -+}
697 -+#endif
698 -+
699 - void __kprobes
700 - ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
701 - {
702 -@@ -145,9 +162,23 @@ ia64_do_page_fault (unsigned long addres
703 - mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
704 - | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
705 -
706 -- if ((vma->vm_flags & mask) != mask)
707 -+ if ((vma->vm_flags & mask) != mask) {
708 -+
709 -+#ifdef CONFIG_PAX_PAGEEXEC
710 -+ if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
711 -+ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
712 -+ goto bad_area;
713 -+
714 -+ up_read(&mm->mmap_sem);
715 -+ pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
716 -+ do_group_exit(SIGKILL);
717 -+ }
718 -+#endif
719 -+
720 - goto bad_area;
721 -
722 -+ }
723 -+
724 - survive:
725 - /*
726 - * If for any reason at all we couldn't handle the fault, make
727 -diff -urNp linux-2.6.27.6/arch/ia64/mm/init.c linux-2.6.27.6/arch/ia64/mm/init.c
728 ---- linux-2.6.27.6/arch/ia64/mm/init.c 2008-11-07 12:55:34.000000000 -0500
729 -+++ linux-2.6.27.6/arch/ia64/mm/init.c 2008-11-18 03:38:43.000000000 -0500
730 -@@ -122,6 +122,19 @@ ia64_init_addr_space (void)
731 - vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
732 - vma->vm_end = vma->vm_start + PAGE_SIZE;
733 - vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
734 -+
735 -+#ifdef CONFIG_PAX_PAGEEXEC
736 -+ if (current->mm->pax_flags & MF_PAX_PAGEEXEC) {
737 -+ vma->vm_flags &= ~VM_EXEC;
738 -+
739 -+#ifdef CONFIG_PAX_MPROTECT
740 -+ if (current->mm->pax_flags & MF_PAX_MPROTECT)
741 -+ vma->vm_flags &= ~VM_MAYEXEC;
742 -+#endif
743 -+
744 -+ }
745 -+#endif
746 -+
747 - vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
748 - down_write(&current->mm->mmap_sem);
749 - if (insert_vm_struct(current->mm, vma)) {
750 -diff -urNp linux-2.6.27.6/arch/m68knommu/include/asm/kmap_types.h linux-2.6.27.6/arch/m68knommu/include/asm/kmap_types.h
751 ---- linux-2.6.27.6/arch/m68knommu/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
752 -+++ linux-2.6.27.6/arch/m68knommu/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
753 -@@ -15,6 +15,7 @@ enum km_type {
754 - KM_IRQ1,
755 - KM_SOFTIRQ0,
756 - KM_SOFTIRQ1,
757 -+ KM_CLEARPAGE,
758 - KM_TYPE_NR
759 - };
760 -
761 -diff -urNp linux-2.6.27.6/arch/mips/kernel/binfmt_elfn32.c linux-2.6.27.6/arch/mips/kernel/binfmt_elfn32.c
762 ---- linux-2.6.27.6/arch/mips/kernel/binfmt_elfn32.c 2008-11-07 12:55:34.000000000 -0500
763 -+++ linux-2.6.27.6/arch/mips/kernel/binfmt_elfn32.c 2008-11-18 03:38:43.000000000 -0500
764 -@@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
765 - #undef ELF_ET_DYN_BASE
766 - #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
767 -
768 -+#ifdef CONFIG_PAX_ASLR
769 -+#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
770 -+
771 -+#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
772 -+#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
773 -+#endif
774 -+
775 - #include <asm/processor.h>
776 - #include <linux/module.h>
777 - #include <linux/elfcore.h>
778 -diff -urNp linux-2.6.27.6/arch/mips/kernel/binfmt_elfo32.c linux-2.6.27.6/arch/mips/kernel/binfmt_elfo32.c
779 ---- linux-2.6.27.6/arch/mips/kernel/binfmt_elfo32.c 2008-11-07 12:55:34.000000000 -0500
780 -+++ linux-2.6.27.6/arch/mips/kernel/binfmt_elfo32.c 2008-11-18 03:38:43.000000000 -0500
781 -@@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
782 - #undef ELF_ET_DYN_BASE
783 - #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
784 -
785 -+#ifdef CONFIG_PAX_ASLR
786 -+#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
787 -+
788 -+#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
789 -+#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
790 -+#endif
791 -+
792 - #include <asm/processor.h>
793 - #include <linux/module.h>
794 - #include <linux/elfcore.h>
795 -diff -urNp linux-2.6.27.6/arch/mips/kernel/process.c linux-2.6.27.6/arch/mips/kernel/process.c
796 ---- linux-2.6.27.6/arch/mips/kernel/process.c 2008-11-07 12:55:34.000000000 -0500
797 -+++ linux-2.6.27.6/arch/mips/kernel/process.c 2008-11-18 03:38:43.000000000 -0500
798 -@@ -458,15 +458,3 @@ unsigned long get_wchan(struct task_stru
799 - out:
800 - return pc;
801 - }
802 --
803 --/*
804 -- * Don't forget that the stack pointer must be aligned on a 8 bytes
805 -- * boundary for 32-bits ABI and 16 bytes for 64-bits ABI.
806 -- */
807 --unsigned long arch_align_stack(unsigned long sp)
808 --{
809 -- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
810 -- sp -= get_random_int() & ~PAGE_MASK;
811 --
812 -- return sp & ALMASK;
813 --}
814 -diff -urNp linux-2.6.27.6/arch/mips/kernel/syscall.c linux-2.6.27.6/arch/mips/kernel/syscall.c
815 ---- linux-2.6.27.6/arch/mips/kernel/syscall.c 2008-11-07 12:55:34.000000000 -0500
816 -+++ linux-2.6.27.6/arch/mips/kernel/syscall.c 2008-11-18 03:38:43.000000000 -0500
817 -@@ -100,6 +100,11 @@ unsigned long arch_get_unmapped_area(str
818 - do_color_align = 0;
819 - if (filp || (flags & MAP_SHARED))
820 - do_color_align = 1;
821 -+
822 -+#ifdef CONFIG_PAX_RANDMMAP
823 -+ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
824 -+#endif
825 -+
826 - if (addr) {
827 - if (do_color_align)
828 - addr = COLOUR_ALIGN(addr, pgoff);
829 -@@ -110,7 +115,7 @@ unsigned long arch_get_unmapped_area(str
830 - (!vmm || addr + len <= vmm->vm_start))
831 - return addr;
832 - }
833 -- addr = TASK_UNMAPPED_BASE;
834 -+ addr = current->mm->mmap_base;
835 - if (do_color_align)
836 - addr = COLOUR_ALIGN(addr, pgoff);
837 - else
838 -diff -urNp linux-2.6.27.6/arch/mips/mm/fault.c linux-2.6.27.6/arch/mips/mm/fault.c
839 ---- linux-2.6.27.6/arch/mips/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
840 -+++ linux-2.6.27.6/arch/mips/mm/fault.c 2008-11-18 03:38:43.000000000 -0500
841 -@@ -26,6 +26,23 @@
842 - #include <asm/ptrace.h>
843 - #include <asm/highmem.h> /* For VMALLOC_END */
844 -
845 -+#ifdef CONFIG_PAX_PAGEEXEC
846 -+void pax_report_insns(void *pc)
847 -+{
848 -+ unsigned long i;
849 -+
850 -+ printk(KERN_ERR "PAX: bytes at PC: ");
851 -+ for (i = 0; i < 5; i++) {
852 -+ unsigned int c;
853 -+ if (get_user(c, (unsigned int *)pc+i))
854 -+ printk(KERN_CONT "???????? ");
855 -+ else
856 -+ printk(KERN_CONT "%08x ", c);
857 -+ }
858 -+ printk("\n");
859 -+}
860 -+#endif
861 -+
862 - /*
863 - * This routine handles page faults. It determines the address,
864 - * and the problem, and then passes it off to one of the appropriate
865 -diff -urNp linux-2.6.27.6/arch/parisc/kernel/module.c linux-2.6.27.6/arch/parisc/kernel/module.c
866 ---- linux-2.6.27.6/arch/parisc/kernel/module.c 2008-11-07 12:55:34.000000000 -0500
867 -+++ linux-2.6.27.6/arch/parisc/kernel/module.c 2008-11-18 03:38:43.000000000 -0500
868 -@@ -75,16 +75,38 @@
869 -
870 - /* three functions to determine where in the module core
871 - * or init pieces the location is */
872 -+static inline int in_init_rx(struct module *me, void *loc)
873 -+{
874 -+ return (loc >= me->module_init_rx &&
875 -+ loc < (me->module_init_rx + me->init_size_rx));
876 -+}
877 -+
878 -+static inline int in_init_rw(struct module *me, void *loc)
879 -+{
880 -+ return (loc >= me->module_init_rw &&
881 -+ loc < (me->module_init_rw + me->init_size_rw));
882 -+}
883 -+
884 - static inline int in_init(struct module *me, void *loc)
885 - {
886 -- return (loc >= me->module_init &&
887 -- loc <= (me->module_init + me->init_size));
888 -+ return in_init_rx(me, loc) || in_init_rw(me, loc);
889 -+}
890 -+
891 -+static inline int in_core_rx(struct module *me, void *loc)
892 -+{
893 -+ return (loc >= me->module_core_rx &&
894 -+ loc < (me->module_core_rx + me->core_size_rx));
895 -+}
896 -+
897 -+static inline int in_core_rw(struct module *me, void *loc)
898 -+{
899 -+ return (loc >= me->module_core_rw &&
900 -+ loc < (me->module_core_rw + me->core_size_rw));
901 - }
902 -
903 - static inline int in_core(struct module *me, void *loc)
904 - {
905 -- return (loc >= me->module_core &&
906 -- loc <= (me->module_core + me->core_size));
907 -+ return in_core_rx(me, loc) || in_core_rw(me, loc);
908 - }
909 -
910 - static inline int in_local(struct module *me, void *loc)
911 -@@ -298,21 +320,21 @@ int module_frob_arch_sections(CONST Elf_
912 - }
913 -
914 - /* align things a bit */
915 -- me->core_size = ALIGN(me->core_size, 16);
916 -- me->arch.got_offset = me->core_size;
917 -- me->core_size += gots * sizeof(struct got_entry);
918 --
919 -- me->core_size = ALIGN(me->core_size, 16);
920 -- me->arch.fdesc_offset = me->core_size;
921 -- me->core_size += fdescs * sizeof(Elf_Fdesc);
922 --
923 -- me->core_size = ALIGN(me->core_size, 16);
924 -- me->arch.stub_offset = me->core_size;
925 -- me->core_size += stubs * sizeof(struct stub_entry);
926 --
927 -- me->init_size = ALIGN(me->init_size, 16);
928 -- me->arch.init_stub_offset = me->init_size;
929 -- me->init_size += init_stubs * sizeof(struct stub_entry);
930 -+ me->core_size_rw = ALIGN(me->core_size_rw, 16);
931 -+ me->arch.got_offset = me->core_size_rw;
932 -+ me->core_size_rw += gots * sizeof(struct got_entry);
933 -+
934 -+ me->core_size_rw = ALIGN(me->core_size_rw, 16);
935 -+ me->arch.fdesc_offset = me->core_size_rw;
936 -+ me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
937 -+
938 -+ me->core_size_rx = ALIGN(me->core_size_rx, 16);
939 -+ me->arch.stub_offset = me->core_size_rx;
940 -+ me->core_size_rx += stubs * sizeof(struct stub_entry);
941 -+
942 -+ me->init_size_rx = ALIGN(me->init_size_rx, 16);
943 -+ me->arch.init_stub_offset = me->init_size_rx;
944 -+ me->init_size_rx += init_stubs * sizeof(struct stub_entry);
945 -
946 - me->arch.got_max = gots;
947 - me->arch.fdesc_max = fdescs;
948 -@@ -332,7 +354,7 @@ static Elf64_Word get_got(struct module
949 -
950 - BUG_ON(value == 0);
951 -
952 -- got = me->module_core + me->arch.got_offset;
953 -+ got = me->module_core_rw + me->arch.got_offset;
954 - for (i = 0; got[i].addr; i++)
955 - if (got[i].addr == value)
956 - goto out;
957 -@@ -350,7 +372,7 @@ static Elf64_Word get_got(struct module
958 - #ifdef CONFIG_64BIT
959 - static Elf_Addr get_fdesc(struct module *me, unsigned long value)
960 - {
961 -- Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
962 -+ Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
963 -
964 - if (!value) {
965 - printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
966 -@@ -368,7 +390,7 @@ static Elf_Addr get_fdesc(struct module
967 -
968 - /* Create new one */
969 - fdesc->addr = value;
970 -- fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
971 -+ fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
972 - return (Elf_Addr)fdesc;
973 - }
974 - #endif /* CONFIG_64BIT */
975 -@@ -388,12 +410,12 @@ static Elf_Addr get_stub(struct module *
976 - if(init_section) {
977 - i = me->arch.init_stub_count++;
978 - BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
979 -- stub = me->module_init + me->arch.init_stub_offset +
980 -+ stub = me->module_init_rx + me->arch.init_stub_offset +
981 - i * sizeof(struct stub_entry);
982 - } else {
983 - i = me->arch.stub_count++;
984 - BUG_ON(me->arch.stub_count > me->arch.stub_max);
985 -- stub = me->module_core + me->arch.stub_offset +
986 -+ stub = me->module_core_rx + me->arch.stub_offset +
987 - i * sizeof(struct stub_entry);
988 - }
989 -
990 -@@ -761,7 +783,7 @@ register_unwind_table(struct module *me,
991 -
992 - table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
993 - end = table + sechdrs[me->arch.unwind_section].sh_size;
994 -- gp = (Elf_Addr)me->module_core + me->arch.got_offset;
995 -+ gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
996 -
997 - DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
998 - me->arch.unwind_section, table, end, gp);
999 -diff -urNp linux-2.6.27.6/arch/parisc/kernel/sys_parisc.c linux-2.6.27.6/arch/parisc/kernel/sys_parisc.c
1000 ---- linux-2.6.27.6/arch/parisc/kernel/sys_parisc.c 2008-11-07 12:55:34.000000000 -0500
1001 -+++ linux-2.6.27.6/arch/parisc/kernel/sys_parisc.c 2008-11-18 03:38:43.000000000 -0500
1002 -@@ -98,7 +98,7 @@ unsigned long arch_get_unmapped_area(str
1003 - if (flags & MAP_FIXED)
1004 - return addr;
1005 - if (!addr)
1006 -- addr = TASK_UNMAPPED_BASE;
1007 -+ addr = current->mm->mmap_base;
1008 -
1009 - if (filp) {
1010 - addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
1011 -diff -urNp linux-2.6.27.6/arch/parisc/kernel/traps.c linux-2.6.27.6/arch/parisc/kernel/traps.c
1012 ---- linux-2.6.27.6/arch/parisc/kernel/traps.c 2008-11-07 12:55:34.000000000 -0500
1013 -+++ linux-2.6.27.6/arch/parisc/kernel/traps.c 2008-11-18 03:38:43.000000000 -0500
1014 -@@ -732,9 +732,7 @@ void handle_interruption(int code, struc
1015 -
1016 - down_read(&current->mm->mmap_sem);
1017 - vma = find_vma(current->mm,regs->iaoq[0]);
1018 -- if (vma && (regs->iaoq[0] >= vma->vm_start)
1019 -- && (vma->vm_flags & VM_EXEC)) {
1020 --
1021 -+ if (vma && (regs->iaoq[0] >= vma->vm_start)) {
1022 - fault_address = regs->iaoq[0];
1023 - fault_space = regs->iasq[0];
1024 -
1025 -diff -urNp linux-2.6.27.6/arch/parisc/mm/fault.c linux-2.6.27.6/arch/parisc/mm/fault.c
1026 ---- linux-2.6.27.6/arch/parisc/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
1027 -+++ linux-2.6.27.6/arch/parisc/mm/fault.c 2008-11-18 03:38:43.000000000 -0500
1028 -@@ -16,6 +16,7 @@
1029 - #include <linux/sched.h>
1030 - #include <linux/interrupt.h>
1031 - #include <linux/module.h>
1032 -+#include <linux/unistd.h>
1033 -
1034 - #include <asm/uaccess.h>
1035 - #include <asm/traps.h>
1036 -@@ -53,7 +54,7 @@ DEFINE_PER_CPU(struct exception_data, ex
1037 - static unsigned long
1038 - parisc_acctyp(unsigned long code, unsigned int inst)
1039 - {
1040 -- if (code == 6 || code == 16)
1041 -+ if (code == 6 || code == 7 || code == 16)
1042 - return VM_EXEC;
1043 -
1044 - switch (inst & 0xf0000000) {
1045 -@@ -139,6 +140,116 @@ parisc_acctyp(unsigned long code, unsign
1046 - }
1047 - #endif
1048 -
1049 -+#ifdef CONFIG_PAX_PAGEEXEC
1050 -+/*
1051 -+ * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
1052 -+ *
1053 -+ * returns 1 when task should be killed
1054 -+ * 2 when rt_sigreturn trampoline was detected
1055 -+ * 3 when unpatched PLT trampoline was detected
1056 -+ */
1057 -+static int pax_handle_fetch_fault(struct pt_regs *regs)
1058 -+{
1059 -+
1060 -+#ifdef CONFIG_PAX_EMUPLT
1061 -+ int err;
1062 -+
1063 -+ do { /* PaX: unpatched PLT emulation */
1064 -+ unsigned int bl, depwi;
1065 -+
1066 -+ err = get_user(bl, (unsigned int *)instruction_pointer(regs));
1067 -+ err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
1068 -+
1069 -+ if (err)
1070 -+ break;
1071 -+
1072 -+ if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
1073 -+ unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
1074 -+
1075 -+ err = get_user(ldw, (unsigned int *)addr);
1076 -+ err |= get_user(bv, (unsigned int *)(addr+4));
1077 -+ err |= get_user(ldw2, (unsigned int *)(addr+8));
1078 -+
1079 -+ if (err)
1080 -+ break;
1081 -+
1082 -+ if (ldw == 0x0E801096U &&
1083 -+ bv == 0xEAC0C000U &&
1084 -+ ldw2 == 0x0E881095U)
1085 -+ {
1086 -+ unsigned int resolver, map;
1087 -+
1088 -+ err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
1089 -+ err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
1090 -+ if (err)
1091 -+ break;
1092 -+
1093 -+ regs->gr[20] = instruction_pointer(regs)+8;
1094 -+ regs->gr[21] = map;
1095 -+ regs->gr[22] = resolver;
1096 -+ regs->iaoq[0] = resolver | 3UL;
1097 -+ regs->iaoq[1] = regs->iaoq[0] + 4;
1098 -+ return 3;
1099 -+ }
1100 -+ }
1101 -+ } while (0);
1102 -+#endif
1103 -+
1104 -+#ifdef CONFIG_PAX_EMUTRAMP
1105 -+
1106 -+#ifndef CONFIG_PAX_EMUSIGRT
1107 -+ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
1108 -+ return 1;
1109 -+#endif
1110 -+
1111 -+ do { /* PaX: rt_sigreturn emulation */
1112 -+ unsigned int ldi1, ldi2, bel, nop;
1113 -+
1114 -+ err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
1115 -+ err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
1116 -+ err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
1117 -+ err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
1118 -+
1119 -+ if (err)
1120 -+ break;
1121 -+
1122 -+ if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
1123 -+ ldi2 == 0x3414015AU &&
1124 -+ bel == 0xE4008200U &&
1125 -+ nop == 0x08000240U)
1126 -+ {
1127 -+ regs->gr[25] = (ldi1 & 2) >> 1;
1128 -+ regs->gr[20] = __NR_rt_sigreturn;
1129 -+ regs->gr[31] = regs->iaoq[1] + 16;
1130 -+ regs->sr[0] = regs->iasq[1];
1131 -+ regs->iaoq[0] = 0x100UL;
1132 -+ regs->iaoq[1] = regs->iaoq[0] + 4;
1133 -+ regs->iasq[0] = regs->sr[2];
1134 -+ regs->iasq[1] = regs->sr[2];
1135 -+ return 2;
1136 -+ }
1137 -+ } while (0);
1138 -+#endif
1139 -+
1140 -+ return 1;
1141 -+}
1142 -+
1143 -+void pax_report_insns(void *pc, void *sp)
1144 -+{
1145 -+ unsigned long i;
1146 -+
1147 -+ printk(KERN_ERR "PAX: bytes at PC: ");
1148 -+ for (i = 0; i < 5; i++) {
1149 -+ unsigned int c;
1150 -+ if (get_user(c, (unsigned int *)pc+i))
1151 -+ printk(KERN_CONT "???????? ");
1152 -+ else
1153 -+ printk(KERN_CONT "%08x ", c);
1154 -+ }
1155 -+ printk("\n");
1156 -+}
1157 -+#endif
1158 -+
1159 - void do_page_fault(struct pt_regs *regs, unsigned long code,
1160 - unsigned long address)
1161 - {
1162 -@@ -165,8 +276,33 @@ good_area:
1163 -
1164 - acc_type = parisc_acctyp(code,regs->iir);
1165 -
1166 -- if ((vma->vm_flags & acc_type) != acc_type)
1167 -+ if ((vma->vm_flags & acc_type) != acc_type) {
1168 -+
1169 -+#ifdef CONFIG_PAX_PAGEEXEC
1170 -+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
1171 -+ (address & ~3UL) == instruction_pointer(regs))
1172 -+ {
1173 -+ up_read(&mm->mmap_sem);
1174 -+ switch (pax_handle_fetch_fault(regs)) {
1175 -+
1176 -+#ifdef CONFIG_PAX_EMUPLT
1177 -+ case 3:
1178 -+ return;
1179 -+#endif
1180 -+
1181 -+#ifdef CONFIG_PAX_EMUTRAMP
1182 -+ case 2:
1183 -+ return;
1184 -+#endif
1185 -+
1186 -+ }
1187 -+ pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
1188 -+ do_group_exit(SIGKILL);
1189 -+ }
1190 -+#endif
1191 -+
1192 - goto bad_area;
1193 -+ }
1194 -
1195 - /*
1196 - * If for any reason at all we couldn't handle the fault, make
1197 -diff -urNp linux-2.6.27.6/arch/powerpc/include/asm/elf.h linux-2.6.27.6/arch/powerpc/include/asm/elf.h
1198 ---- linux-2.6.27.6/arch/powerpc/include/asm/elf.h 2008-11-07 12:55:34.000000000 -0500
1199 -+++ linux-2.6.27.6/arch/powerpc/include/asm/elf.h 2008-11-18 03:39:50.000000000 -0500
1200 -@@ -180,6 +180,18 @@ typedef elf_fpreg_t elf_vsrreghalf_t32[E
1201 -
1202 - #define ELF_ET_DYN_BASE (0x20000000)
1203 -
1204 -+#ifdef CONFIG_PAX_ASLR
1205 -+#define PAX_ELF_ET_DYN_BASE (0x10000000UL)
1206 -+
1207 -+#ifdef __powerpc64__
1208 -+#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
1209 -+#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
1210 -+#else
1211 -+#define PAX_DELTA_MMAP_LEN 15
1212 -+#define PAX_DELTA_STACK_LEN 15
1213 -+#endif
1214 -+#endif
1215 -+
1216 - /*
1217 - * Our registers are always unsigned longs, whether we're a 32 bit
1218 - * process or 64 bit, on either a 64 bit or 32 bit kernel.
1219 -diff -urNp linux-2.6.27.6/arch/powerpc/include/asm/kmap_types.h linux-2.6.27.6/arch/powerpc/include/asm/kmap_types.h
1220 ---- linux-2.6.27.6/arch/powerpc/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
1221 -+++ linux-2.6.27.6/arch/powerpc/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
1222 -@@ -26,6 +26,7 @@ enum km_type {
1223 - KM_SOFTIRQ1,
1224 - KM_PPC_SYNC_PAGE,
1225 - KM_PPC_SYNC_ICACHE,
1226 -+ KM_CLEARPAGE,
1227 - KM_TYPE_NR
1228 - };
1229 -
1230 -diff -urNp linux-2.6.27.6/arch/powerpc/include/asm/page_64.h linux-2.6.27.6/arch/powerpc/include/asm/page_64.h
1231 ---- linux-2.6.27.6/arch/powerpc/include/asm/page_64.h 2008-11-07 12:55:34.000000000 -0500
1232 -+++ linux-2.6.27.6/arch/powerpc/include/asm/page_64.h 2008-11-18 03:39:50.000000000 -0500
1233 -@@ -170,15 +170,18 @@ do { \
1234 - * stack by default, so in the absense of a PT_GNU_STACK program header
1235 - * we turn execute permission off.
1236 - */
1237 --#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
1238 -- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1239 -+#define VM_STACK_DEFAULT_FLAGS32 \
1240 -+ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
1241 -+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1242 -
1243 - #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
1244 - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1245 -
1246 -+#ifndef CONFIG_PAX_PAGEEXEC
1247 - #define VM_STACK_DEFAULT_FLAGS \
1248 - (test_thread_flag(TIF_32BIT) ? \
1249 - VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
1250 -+#endif
1251 -
1252 - #include <asm-generic/page.h>
1253 -
1254 -diff -urNp linux-2.6.27.6/arch/powerpc/include/asm/page.h linux-2.6.27.6/arch/powerpc/include/asm/page.h
1255 ---- linux-2.6.27.6/arch/powerpc/include/asm/page.h 2008-11-07 12:55:34.000000000 -0500
1256 -+++ linux-2.6.27.6/arch/powerpc/include/asm/page.h 2008-11-18 03:39:50.000000000 -0500
1257 -@@ -100,8 +100,9 @@ extern phys_addr_t kernstart_addr;
1258 - * and needs to be executable. This means the whole heap ends
1259 - * up being executable.
1260 - */
1261 --#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
1262 -- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1263 -+#define VM_DATA_DEFAULT_FLAGS32 \
1264 -+ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
1265 -+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1266 -
1267 - #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
1268 - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1269 -diff -urNp linux-2.6.27.6/arch/powerpc/kernel/module_32.c linux-2.6.27.6/arch/powerpc/kernel/module_32.c
1270 ---- linux-2.6.27.6/arch/powerpc/kernel/module_32.c 2008-11-07 12:55:34.000000000 -0500
1271 -+++ linux-2.6.27.6/arch/powerpc/kernel/module_32.c 2008-11-18 03:38:43.000000000 -0500
1272 -@@ -158,7 +158,7 @@ int module_frob_arch_sections(Elf32_Ehdr
1273 - me->arch.core_plt_section = i;
1274 - }
1275 - if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
1276 -- printk("Module doesn't contain .plt or .init.plt sections.\n");
1277 -+ printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
1278 - return -ENOEXEC;
1279 - }
1280 -
1281 -@@ -199,11 +199,16 @@ static uint32_t do_plt_call(void *locati
1282 -
1283 - DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
1284 - /* Init, or core PLT? */
1285 -- if (location >= mod->module_core
1286 -- && location < mod->module_core + mod->core_size)
1287 -+ if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
1288 -+ (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
1289 - entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
1290 -- else
1291 -+ else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
1292 -+ (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
1293 - entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
1294 -+ else {
1295 -+ printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
1296 -+ return ~0UL;
1297 -+ }
1298 -
1299 - /* Find this entry, or if that fails, the next avail. entry */
1300 - while (entry->jump[0]) {
1301 -diff -urNp linux-2.6.27.6/arch/powerpc/kernel/signal_32.c linux-2.6.27.6/arch/powerpc/kernel/signal_32.c
1302 ---- linux-2.6.27.6/arch/powerpc/kernel/signal_32.c 2008-11-07 12:55:34.000000000 -0500
1303 -+++ linux-2.6.27.6/arch/powerpc/kernel/signal_32.c 2008-11-18 03:38:43.000000000 -0500
1304 -@@ -857,7 +857,7 @@ int handle_rt_signal32(unsigned long sig
1305 - /* Save user registers on the stack */
1306 - frame = &rt_sf->uc.uc_mcontext;
1307 - addr = frame;
1308 -- if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
1309 -+ if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
1310 - if (save_user_regs(regs, frame, 0))
1311 - goto badframe;
1312 - regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
1313 -diff -urNp linux-2.6.27.6/arch/powerpc/kernel/signal_64.c linux-2.6.27.6/arch/powerpc/kernel/signal_64.c
1314 ---- linux-2.6.27.6/arch/powerpc/kernel/signal_64.c 2008-11-07 12:55:34.000000000 -0500
1315 -+++ linux-2.6.27.6/arch/powerpc/kernel/signal_64.c 2008-11-18 03:38:43.000000000 -0500
1316 -@@ -434,7 +434,7 @@ int handle_rt_signal64(int signr, struct
1317 - current->thread.fpscr.val = 0;
1318 -
1319 - /* Set up to return from userspace. */
1320 -- if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
1321 -+ if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
1322 - regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
1323 - } else {
1324 - err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
1325 -diff -urNp linux-2.6.27.6/arch/powerpc/kernel/vdso.c linux-2.6.27.6/arch/powerpc/kernel/vdso.c
1326 ---- linux-2.6.27.6/arch/powerpc/kernel/vdso.c 2008-11-07 12:55:34.000000000 -0500
1327 -+++ linux-2.6.27.6/arch/powerpc/kernel/vdso.c 2008-11-18 03:38:43.000000000 -0500
1328 -@@ -212,7 +212,7 @@ int arch_setup_additional_pages(struct l
1329 - vdso_base = VDSO32_MBASE;
1330 - #endif
1331 -
1332 -- current->mm->context.vdso_base = 0;
1333 -+ current->mm->context.vdso_base = ~0UL;
1334 -
1335 - /* vDSO has a problem and was disabled, just don't "enable" it for the
1336 - * process
1337 -@@ -229,7 +229,7 @@ int arch_setup_additional_pages(struct l
1338 - */
1339 - down_write(&mm->mmap_sem);
1340 - vdso_base = get_unmapped_area(NULL, vdso_base,
1341 -- vdso_pages << PAGE_SHIFT, 0, 0);
1342 -+ vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
1343 - if (IS_ERR_VALUE(vdso_base)) {
1344 - rc = vdso_base;
1345 - goto fail_mmapsem;
1346 -diff -urNp linux-2.6.27.6/arch/powerpc/mm/fault.c linux-2.6.27.6/arch/powerpc/mm/fault.c
1347 ---- linux-2.6.27.6/arch/powerpc/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
1348 -+++ linux-2.6.27.6/arch/powerpc/mm/fault.c 2008-11-18 03:38:43.000000000 -0500
1349 -@@ -29,6 +29,10 @@
1350 - #include <linux/module.h>
1351 - #include <linux/kprobes.h>
1352 - #include <linux/kdebug.h>
1353 -+#include <linux/slab.h>
1354 -+#include <linux/pagemap.h>
1355 -+#include <linux/compiler.h>
1356 -+#include <linux/unistd.h>
1357 -
1358 - #include <asm/page.h>
1359 - #include <asm/pgtable.h>
1360 -@@ -62,6 +66,363 @@ static inline int notify_page_fault(stru
1361 - }
1362 - #endif
1363 -
1364 -+#ifdef CONFIG_PAX_EMUSIGRT
1365 -+void pax_syscall_close(struct vm_area_struct *vma)
1366 -+{
1367 -+ vma->vm_mm->call_syscall = 0UL;
1368 -+}
1369 -+
1370 -+static int pax_syscall_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1371 -+{
1372 -+ unsigned int *kaddr;
1373 -+
1374 -+ vmf->page = alloc_page(GFP_HIGHUSER);
1375 -+ if (!vmf->page)
1376 -+ return VM_FAULT_OOM;
1377 -+
1378 -+ kaddr = kmap(vmf->page);
1379 -+ memset(kaddr, 0, PAGE_SIZE);
1380 -+ kaddr[0] = 0x44000002U; /* sc */
1381 -+ __flush_dcache_icache(kaddr);
1382 -+ kunmap(vmf->page);
1383 -+ return VM_FAULT_MAJOR;
1384 -+}
1385 -+
1386 -+static struct vm_operations_struct pax_vm_ops = {
1387 -+ .close = pax_syscall_close,
1388 -+ .fault = pax_syscall_fault
1389 -+};
1390 -+
1391 -+static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
1392 -+{
1393 -+ int ret;
1394 -+
1395 -+ vma->vm_mm = current->mm;
1396 -+ vma->vm_start = addr;
1397 -+ vma->vm_end = addr + PAGE_SIZE;
1398 -+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
1399 -+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
1400 -+ vma->vm_ops = &pax_vm_ops;
1401 -+
1402 -+ ret = insert_vm_struct(current->mm, vma);
1403 -+ if (ret)
1404 -+ return ret;
1405 -+
1406 -+ ++current->mm->total_vm;
1407 -+ return 0;
1408 -+}
1409 -+#endif
1410 -+
1411 -+#ifdef CONFIG_PAX_PAGEEXEC
1412 -+/*
1413 -+ * PaX: decide what to do with offenders (regs->nip = fault address)
1414 -+ *
1415 -+ * returns 1 when task should be killed
1416 -+ * 2 when patched GOT trampoline was detected
1417 -+ * 3 when patched PLT trampoline was detected
1418 -+ * 4 when unpatched PLT trampoline was detected
1419 -+ * 5 when sigreturn trampoline was detected
1420 -+ * 6 when rt_sigreturn trampoline was detected
1421 -+ */
1422 -+static int pax_handle_fetch_fault(struct pt_regs *regs)
1423 -+{
1424 -+
1425 -+#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
1426 -+ int err;
1427 -+#endif
1428 -+
1429 -+#ifdef CONFIG_PAX_EMUPLT
1430 -+ do { /* PaX: patched GOT emulation */
1431 -+ unsigned int blrl;
1432 -+
1433 -+ err = get_user(blrl, (unsigned int *)regs->nip);
1434 -+
1435 -+ if (!err && blrl == 0x4E800021U) {
1436 -+ unsigned long temp = regs->nip;
1437 -+
1438 -+ regs->nip = regs->link & 0xFFFFFFFCUL;
1439 -+ regs->link = temp + 4UL;
1440 -+ return 2;
1441 -+ }
1442 -+ } while (0);
1443 -+
1444 -+ do { /* PaX: patched PLT emulation #1 */
1445 -+ unsigned int b;
1446 -+
1447 -+ err = get_user(b, (unsigned int *)regs->nip);
1448 -+
1449 -+ if (!err && (b & 0xFC000003U) == 0x48000000U) {
1450 -+ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
1451 -+ return 3;
1452 -+ }
1453 -+ } while (0);
1454 -+
1455 -+ do { /* PaX: unpatched PLT emulation #1 */
1456 -+ unsigned int li, b;
1457 -+
1458 -+ err = get_user(li, (unsigned int *)regs->nip);
1459 -+ err |= get_user(b, (unsigned int *)(regs->nip+4));
1460 -+
1461 -+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1462 -+ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1463 -+ unsigned long addr = b | 0xFC000000UL;
1464 -+
1465 -+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1466 -+ err = get_user(rlwinm, (unsigned int *)addr);
1467 -+ err |= get_user(add, (unsigned int *)(addr+4));
1468 -+ err |= get_user(li2, (unsigned int *)(addr+8));
1469 -+ err |= get_user(addis2, (unsigned int *)(addr+12));
1470 -+ err |= get_user(mtctr, (unsigned int *)(addr+16));
1471 -+ err |= get_user(li3, (unsigned int *)(addr+20));
1472 -+ err |= get_user(addis3, (unsigned int *)(addr+24));
1473 -+ err |= get_user(bctr, (unsigned int *)(addr+28));
1474 -+
1475 -+ if (err)
1476 -+ break;
1477 -+
1478 -+ if (rlwinm == 0x556C083CU &&
1479 -+ add == 0x7D6C5A14U &&
1480 -+ (li2 & 0xFFFF0000U) == 0x39800000U &&
1481 -+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1482 -+ mtctr == 0x7D8903A6U &&
1483 -+ (li3 & 0xFFFF0000U) == 0x39800000U &&
1484 -+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1485 -+ bctr == 0x4E800420U)
1486 -+ {
1487 -+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1488 -+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1489 -+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1490 -+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1491 -+ regs->ctr += (addis2 & 0xFFFFU) << 16;
1492 -+ regs->nip = regs->ctr;
1493 -+ return 4;
1494 -+ }
1495 -+ }
1496 -+ } while (0);
1497 -+
1498 -+#if 0
1499 -+ do { /* PaX: unpatched PLT emulation #2 */
1500 -+ unsigned int lis, lwzu, b, bctr;
1501 -+
1502 -+ err = get_user(lis, (unsigned int *)regs->nip);
1503 -+ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
1504 -+ err |= get_user(b, (unsigned int *)(regs->nip+8));
1505 -+ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
1506 -+
1507 -+ if (err)
1508 -+ break;
1509 -+
1510 -+ if ((lis & 0xFFFF0000U) == 0x39600000U &&
1511 -+ (lwzu & 0xU) == 0xU &&
1512 -+ (b & 0xFC000003U) == 0x48000000U &&
1513 -+ bctr == 0x4E800420U)
1514 -+ {
1515 -+ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1516 -+ unsigned long addr = b | 0xFC000000UL;
1517 -+
1518 -+ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1519 -+ err = get_user(addis, (unsigned int *)addr);
1520 -+ err |= get_user(addi, (unsigned int *)(addr+4));
1521 -+ err |= get_user(rlwinm, (unsigned int *)(addr+8));
1522 -+ err |= get_user(add, (unsigned int *)(addr+12));
1523 -+ err |= get_user(li2, (unsigned int *)(addr+16));
1524 -+ err |= get_user(addis2, (unsigned int *)(addr+20));
1525 -+ err |= get_user(mtctr, (unsigned int *)(addr+24));
1526 -+ err |= get_user(li3, (unsigned int *)(addr+28));
1527 -+ err |= get_user(addis3, (unsigned int *)(addr+32));
1528 -+ err |= get_user(bctr, (unsigned int *)(addr+36));
1529 -+
1530 -+ if (err)
1531 -+ break;
1532 -+
1533 -+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1534 -+ (addi & 0xFFFF0000U) == 0x396B0000U &&
1535 -+ rlwinm == 0x556C083CU &&
1536 -+ add == 0x7D6C5A14U &&
1537 -+ (li2 & 0xFFFF0000U) == 0x39800000U &&
1538 -+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1539 -+ mtctr == 0x7D8903A6U &&
1540 -+ (li3 & 0xFFFF0000U) == 0x39800000U &&
1541 -+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1542 -+ bctr == 0x4E800420U)
1543 -+ {
1544 -+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1545 -+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1546 -+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1547 -+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1548 -+ regs->ctr += (addis2 & 0xFFFFU) << 16;
1549 -+ regs->nip = regs->ctr;
1550 -+ return 4;
1551 -+ }
1552 -+ }
1553 -+ } while (0);
1554 -+#endif
1555 -+
1556 -+ do { /* PaX: unpatched PLT emulation #3 */
1557 -+ unsigned int li, b;
1558 -+
1559 -+ err = get_user(li, (unsigned int *)regs->nip);
1560 -+ err |= get_user(b, (unsigned int *)(regs->nip+4));
1561 -+
1562 -+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1563 -+ unsigned int addis, lwz, mtctr, bctr;
1564 -+ unsigned long addr = b | 0xFC000000UL;
1565 -+
1566 -+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1567 -+ err = get_user(addis, (unsigned int *)addr);
1568 -+ err |= get_user(lwz, (unsigned int *)(addr+4));
1569 -+ err |= get_user(mtctr, (unsigned int *)(addr+8));
1570 -+ err |= get_user(bctr, (unsigned int *)(addr+12));
1571 -+
1572 -+ if (err)
1573 -+ break;
1574 -+
1575 -+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1576 -+ (lwz & 0xFFFF0000U) == 0x816B0000U &&
1577 -+ mtctr == 0x7D6903A6U &&
1578 -+ bctr == 0x4E800420U)
1579 -+ {
1580 -+ unsigned int r11;
1581 -+
1582 -+ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1583 -+ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1584 -+
1585 -+ err = get_user(r11, (unsigned int *)addr);
1586 -+ if (err)
1587 -+ break;
1588 -+
1589 -+ regs->gpr[PT_R11] = r11;
1590 -+ regs->ctr = r11;
1591 -+ regs->nip = r11;
1592 -+ return 4;
1593 -+ }
1594 -+ }
1595 -+ } while (0);
1596 -+#endif
1597 -+
1598 -+#ifdef CONFIG_PAX_EMUSIGRT
1599 -+ do { /* PaX: sigreturn emulation */
1600 -+ unsigned int li, sc;
1601 -+
1602 -+ err = get_user(li, (unsigned int *)regs->nip);
1603 -+ err |= get_user(sc, (unsigned int *)(regs->nip+4));
1604 -+
1605 -+ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
1606 -+ struct vm_area_struct *vma;
1607 -+ unsigned long call_syscall;
1608 -+
1609 -+ down_read(&current->mm->mmap_sem);
1610 -+ call_syscall = current->mm->call_syscall;
1611 -+ up_read(&current->mm->mmap_sem);
1612 -+ if (likely(call_syscall))
1613 -+ goto emulate;
1614 -+
1615 -+ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1616 -+
1617 -+ down_write(&current->mm->mmap_sem);
1618 -+ if (current->mm->call_syscall) {
1619 -+ call_syscall = current->mm->call_syscall;
1620 -+ up_write(&current->mm->mmap_sem);
1621 -+ if (vma)
1622 -+ kmem_cache_free(vm_area_cachep, vma);
1623 -+ goto emulate;
1624 -+ }
1625 -+
1626 -+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1627 -+ if (!vma || (call_syscall & ~PAGE_MASK)) {
1628 -+ up_write(&current->mm->mmap_sem);
1629 -+ if (vma)
1630 -+ kmem_cache_free(vm_area_cachep, vma);
1631 -+ return 1;
1632 -+ }
1633 -+
1634 -+ if (pax_insert_vma(vma, call_syscall)) {
1635 -+ up_write(&current->mm->mmap_sem);
1636 -+ kmem_cache_free(vm_area_cachep, vma);
1637 -+ return 1;
1638 -+ }
1639 -+
1640 -+ current->mm->call_syscall = call_syscall;
1641 -+ up_write(&current->mm->mmap_sem);
1642 -+
1643 -+emulate:
1644 -+ regs->gpr[PT_R0] = __NR_sigreturn;
1645 -+ regs->nip = call_syscall;
1646 -+ return 5;
1647 -+ }
1648 -+ } while (0);
1649 -+
1650 -+ do { /* PaX: rt_sigreturn emulation */
1651 -+ unsigned int li, sc;
1652 -+
1653 -+ err = get_user(li, (unsigned int *)regs->nip);
1654 -+ err |= get_user(sc, (unsigned int *)(regs->nip+4));
1655 -+
1656 -+ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
1657 -+ struct vm_area_struct *vma;
1658 -+ unsigned int call_syscall;
1659 -+
1660 -+ down_read(&current->mm->mmap_sem);
1661 -+ call_syscall = current->mm->call_syscall;
1662 -+ up_read(&current->mm->mmap_sem);
1663 -+ if (likely(call_syscall))
1664 -+ goto rt_emulate;
1665 -+
1666 -+ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1667 -+
1668 -+ down_write(&current->mm->mmap_sem);
1669 -+ if (current->mm->call_syscall) {
1670 -+ call_syscall = current->mm->call_syscall;
1671 -+ up_write(&current->mm->mmap_sem);
1672 -+ if (vma)
1673 -+ kmem_cache_free(vm_area_cachep, vma);
1674 -+ goto rt_emulate;
1675 -+ }
1676 -+
1677 -+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1678 -+ if (!vma || (call_syscall & ~PAGE_MASK)) {
1679 -+ up_write(&current->mm->mmap_sem);
1680 -+ if (vma)
1681 -+ kmem_cache_free(vm_area_cachep, vma);
1682 -+ return 1;
1683 -+ }
1684 -+
1685 -+ if (pax_insert_vma(vma, call_syscall)) {
1686 -+ up_write(&current->mm->mmap_sem);
1687 -+ kmem_cache_free(vm_area_cachep, vma);
1688 -+ return 1;
1689 -+ }
1690 -+
1691 -+ current->mm->call_syscall = call_syscall;
1692 -+ up_write(&current->mm->mmap_sem);
1693 -+
1694 -+rt_emulate:
1695 -+ regs->gpr[PT_R0] = __NR_rt_sigreturn;
1696 -+ regs->nip = call_syscall;
1697 -+ return 6;
1698 -+ }
1699 -+ } while (0);
1700 -+#endif
1701 -+
1702 -+ return 1;
1703 -+}
1704 -+
1705 -+void pax_report_insns(void *pc, void *sp)
1706 -+{
1707 -+ unsigned long i;
1708 -+
1709 -+ printk(KERN_ERR "PAX: bytes at PC: ");
1710 -+ for (i = 0; i < 5; i++) {
1711 -+ unsigned int c;
1712 -+ if (get_user(c, (unsigned int *)pc+i))
1713 -+ printk(KERN_CONT "???????? ");
1714 -+ else
1715 -+ printk(KERN_CONT "%08x ", c);
1716 -+ }
1717 -+ printk("\n");
1718 -+}
1719 -+#endif
1720 -+
1721 - /*
1722 - * Check whether the instruction at regs->nip is a store using
1723 - * an update addressing form which will update r1.
1724 -@@ -132,7 +493,7 @@ int __kprobes do_page_fault(struct pt_re
1725 - * indicate errors in DSISR but can validly be set in SRR1.
1726 - */
1727 - if (trap == 0x400)
1728 -- error_code &= 0x48200000;
1729 -+ error_code &= 0x58200000;
1730 - else
1731 - is_write = error_code & DSISR_ISSTORE;
1732 - #else
1733 -@@ -331,6 +692,37 @@ bad_area:
1734 - bad_area_nosemaphore:
1735 - /* User mode accesses cause a SIGSEGV */
1736 - if (user_mode(regs)) {
1737 -+
1738 -+#ifdef CONFIG_PAX_PAGEEXEC
1739 -+ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
1740 -+#ifdef CONFIG_PPC64
1741 -+ if (is_exec && (error_code & DSISR_PROTFAULT)) {
1742 -+#else
1743 -+ if (is_exec && regs->nip == address) {
1744 -+#endif
1745 -+ switch (pax_handle_fetch_fault(regs)) {
1746 -+
1747 -+#ifdef CONFIG_PAX_EMUPLT
1748 -+ case 2:
1749 -+ case 3:
1750 -+ case 4:
1751 -+ return 0;
1752 -+#endif
1753 -+
1754 -+#ifdef CONFIG_PAX_EMUSIGRT
1755 -+ case 5:
1756 -+ case 6:
1757 -+ return 0;
1758 -+#endif
1759 -+
1760 -+ }
1761 -+
1762 -+ pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[PT_R1]);
1763 -+ do_group_exit(SIGKILL);
1764 -+ }
1765 -+ }
1766 -+#endif
1767 -+
1768 - _exception(SIGSEGV, regs, code, address);
1769 - return 0;
1770 - }
1771 -diff -urNp linux-2.6.27.6/arch/powerpc/mm/mmap.c linux-2.6.27.6/arch/powerpc/mm/mmap.c
1772 ---- linux-2.6.27.6/arch/powerpc/mm/mmap.c 2008-11-07 12:55:34.000000000 -0500
1773 -+++ linux-2.6.27.6/arch/powerpc/mm/mmap.c 2008-11-18 03:38:43.000000000 -0500
1774 -@@ -75,10 +75,22 @@ void arch_pick_mmap_layout(struct mm_str
1775 - */
1776 - if (mmap_is_legacy()) {
1777 - mm->mmap_base = TASK_UNMAPPED_BASE;
1778 -+
1779 -+#ifdef CONFIG_PAX_RANDMMAP
1780 -+ if (mm->pax_flags & MF_PAX_RANDMMAP)
1781 -+ mm->mmap_base += mm->delta_mmap;
1782 -+#endif
1783 -+
1784 - mm->get_unmapped_area = arch_get_unmapped_area;
1785 - mm->unmap_area = arch_unmap_area;
1786 - } else {
1787 - mm->mmap_base = mmap_base();
1788 -+
1789 -+#ifdef CONFIG_PAX_RANDMMAP
1790 -+ if (mm->pax_flags & MF_PAX_RANDMMAP)
1791 -+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
1792 -+#endif
1793 -+
1794 - mm->get_unmapped_area = arch_get_unmapped_area_topdown;
1795 - mm->unmap_area = arch_unmap_area_topdown;
1796 - }
1797 -diff -urNp linux-2.6.27.6/arch/s390/include/asm/kmap_types.h linux-2.6.27.6/arch/s390/include/asm/kmap_types.h
1798 ---- linux-2.6.27.6/arch/s390/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
1799 -+++ linux-2.6.27.6/arch/s390/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
1800 -@@ -16,6 +16,7 @@ enum km_type {
1801 - KM_IRQ1,
1802 - KM_SOFTIRQ0,
1803 - KM_SOFTIRQ1,
1804 -+ KM_CLEARPAGE,
1805 - KM_TYPE_NR
1806 - };
1807 -
1808 -diff -urNp linux-2.6.27.6/arch/s390/kernel/module.c linux-2.6.27.6/arch/s390/kernel/module.c
1809 ---- linux-2.6.27.6/arch/s390/kernel/module.c 2008-11-07 12:55:34.000000000 -0500
1810 -+++ linux-2.6.27.6/arch/s390/kernel/module.c 2008-11-18 03:38:43.000000000 -0500
1811 -@@ -166,11 +166,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
1812 -
1813 - /* Increase core size by size of got & plt and set start
1814 - offsets for got and plt. */
1815 -- me->core_size = ALIGN(me->core_size, 4);
1816 -- me->arch.got_offset = me->core_size;
1817 -- me->core_size += me->arch.got_size;
1818 -- me->arch.plt_offset = me->core_size;
1819 -- me->core_size += me->arch.plt_size;
1820 -+ me->core_size_rw = ALIGN(me->core_size_rw, 4);
1821 -+ me->arch.got_offset = me->core_size_rw;
1822 -+ me->core_size_rw += me->arch.got_size;
1823 -+ me->arch.plt_offset = me->core_size_rx;
1824 -+ me->core_size_rx += me->arch.plt_size;
1825 - return 0;
1826 - }
1827 -
1828 -@@ -256,7 +256,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1829 - if (info->got_initialized == 0) {
1830 - Elf_Addr *gotent;
1831 -
1832 -- gotent = me->module_core + me->arch.got_offset +
1833 -+ gotent = me->module_core_rw + me->arch.got_offset +
1834 - info->got_offset;
1835 - *gotent = val;
1836 - info->got_initialized = 1;
1837 -@@ -280,7 +280,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1838 - else if (r_type == R_390_GOTENT ||
1839 - r_type == R_390_GOTPLTENT)
1840 - *(unsigned int *) loc =
1841 -- (val + (Elf_Addr) me->module_core - loc) >> 1;
1842 -+ (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
1843 - else if (r_type == R_390_GOT64 ||
1844 - r_type == R_390_GOTPLT64)
1845 - *(unsigned long *) loc = val;
1846 -@@ -294,7 +294,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1847 - case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
1848 - if (info->plt_initialized == 0) {
1849 - unsigned int *ip;
1850 -- ip = me->module_core + me->arch.plt_offset +
1851 -+ ip = me->module_core_rx + me->arch.plt_offset +
1852 - info->plt_offset;
1853 - #ifndef CONFIG_64BIT
1854 - ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
1855 -@@ -316,7 +316,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1856 - val = me->arch.plt_offset - me->arch.got_offset +
1857 - info->plt_offset + rela->r_addend;
1858 - else
1859 -- val = (Elf_Addr) me->module_core +
1860 -+ val = (Elf_Addr) me->module_core_rx +
1861 - me->arch.plt_offset + info->plt_offset +
1862 - rela->r_addend - loc;
1863 - if (r_type == R_390_PLT16DBL)
1864 -@@ -336,7 +336,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1865 - case R_390_GOTOFF32: /* 32 bit offset to GOT. */
1866 - case R_390_GOTOFF64: /* 64 bit offset to GOT. */
1867 - val = val + rela->r_addend -
1868 -- ((Elf_Addr) me->module_core + me->arch.got_offset);
1869 -+ ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
1870 - if (r_type == R_390_GOTOFF16)
1871 - *(unsigned short *) loc = val;
1872 - else if (r_type == R_390_GOTOFF32)
1873 -@@ -346,7 +346,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1874 - break;
1875 - case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
1876 - case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
1877 -- val = (Elf_Addr) me->module_core + me->arch.got_offset +
1878 -+ val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
1879 - rela->r_addend - loc;
1880 - if (r_type == R_390_GOTPC)
1881 - *(unsigned int *) loc = val;
1882 -diff -urNp linux-2.6.27.6/arch/sh/include/asm/kmap_types.h linux-2.6.27.6/arch/sh/include/asm/kmap_types.h
1883 ---- linux-2.6.27.6/arch/sh/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
1884 -+++ linux-2.6.27.6/arch/sh/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
1885 -@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
1886 - D(10) KM_IRQ1,
1887 - D(11) KM_SOFTIRQ0,
1888 - D(12) KM_SOFTIRQ1,
1889 --D(13) KM_TYPE_NR
1890 -+D(13) KM_CLEARPAGE,
1891 -+D(14) KM_TYPE_NR
1892 - };
1893 -
1894 - #undef D
1895 -diff -urNp linux-2.6.27.6/arch/sparc/include/asm/elf_32.h linux-2.6.27.6/arch/sparc/include/asm/elf_32.h
1896 ---- linux-2.6.27.6/arch/sparc/include/asm/elf_32.h 2008-11-07 12:55:34.000000000 -0500
1897 -+++ linux-2.6.27.6/arch/sparc/include/asm/elf_32.h 2008-11-18 03:39:50.000000000 -0500
1898 -@@ -119,6 +119,13 @@ typedef struct {
1899 -
1900 - #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
1901 -
1902 -+#ifdef CONFIG_PAX_ASLR
1903 -+#define PAX_ELF_ET_DYN_BASE 0x10000UL
1904 -+
1905 -+#define PAX_DELTA_MMAP_LEN 16
1906 -+#define PAX_DELTA_STACK_LEN 16
1907 -+#endif
1908 -+
1909 - /* This yields a mask that user programs can use to figure out what
1910 - instruction set this cpu supports. This can NOT be done in userspace
1911 - on Sparc. */
1912 -diff -urNp linux-2.6.27.6/arch/sparc/include/asm/elf_64.h linux-2.6.27.6/arch/sparc/include/asm/elf_64.h
1913 ---- linux-2.6.27.6/arch/sparc/include/asm/elf_64.h 2008-11-07 12:55:34.000000000 -0500
1914 -+++ linux-2.6.27.6/arch/sparc/include/asm/elf_64.h 2008-11-18 03:39:50.000000000 -0500
1915 -@@ -163,6 +163,12 @@ typedef struct {
1916 - #define ELF_ET_DYN_BASE 0x0000010000000000UL
1917 - #define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL
1918 -
1919 -+#ifdef CONFIG_PAX_ASLR
1920 -+#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
1921 -+
1922 -+#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 14 : 28 )
1923 -+#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 15 : 29 )
1924 -+#endif
1925 -
1926 - /* This yields a mask that user programs can use to figure out what
1927 - instruction set this cpu supports. */
1928 -diff -urNp linux-2.6.27.6/arch/sparc/include/asm/kmap_types.h linux-2.6.27.6/arch/sparc/include/asm/kmap_types.h
1929 ---- linux-2.6.27.6/arch/sparc/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
1930 -+++ linux-2.6.27.6/arch/sparc/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
1931 -@@ -19,6 +19,7 @@ enum km_type {
1932 - KM_IRQ1,
1933 - KM_SOFTIRQ0,
1934 - KM_SOFTIRQ1,
1935 -+ KM_CLEARPAGE,
1936 - KM_TYPE_NR
1937 - };
1938 -
1939 -diff -urNp linux-2.6.27.6/arch/sparc/include/asm/pgtable_32.h linux-2.6.27.6/arch/sparc/include/asm/pgtable_32.h
1940 ---- linux-2.6.27.6/arch/sparc/include/asm/pgtable_32.h 2008-11-07 12:55:34.000000000 -0500
1941 -+++ linux-2.6.27.6/arch/sparc/include/asm/pgtable_32.h 2008-11-18 03:39:50.000000000 -0500
1942 -@@ -47,6 +47,13 @@ BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
1943 - BTFIXUPDEF_INT(page_none)
1944 - BTFIXUPDEF_INT(page_copy)
1945 - BTFIXUPDEF_INT(page_readonly)
1946 -+
1947 -+#ifdef CONFIG_PAX_PAGEEXEC
1948 -+BTFIXUPDEF_INT(page_shared_noexec)
1949 -+BTFIXUPDEF_INT(page_copy_noexec)
1950 -+BTFIXUPDEF_INT(page_readonly_noexec)
1951 -+#endif
1952 -+
1953 - BTFIXUPDEF_INT(page_kernel)
1954 -
1955 - #define PMD_SHIFT SUN4C_PMD_SHIFT
1956 -@@ -68,6 +75,16 @@ extern pgprot_t PAGE_SHARED;
1957 - #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
1958 - #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
1959 -
1960 -+#ifdef CONFIG_PAX_PAGEEXEC
1961 -+extern pgprot_t PAGE_SHARED_NOEXEC;
1962 -+# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec))
1963 -+# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec))
1964 -+#else
1965 -+# define PAGE_SHARED_NOEXEC PAGE_SHARED
1966 -+# define PAGE_COPY_NOEXEC PAGE_COPY
1967 -+# define PAGE_READONLY_NOEXEC PAGE_READONLY
1968 -+#endif
1969 -+
1970 - extern unsigned long page_kernel;
1971 -
1972 - #ifdef MODULE
1973 -diff -urNp linux-2.6.27.6/arch/sparc/include/asm/pgtsrmmu.h linux-2.6.27.6/arch/sparc/include/asm/pgtsrmmu.h
1974 ---- linux-2.6.27.6/arch/sparc/include/asm/pgtsrmmu.h 2008-11-07 12:55:34.000000000 -0500
1975 -+++ linux-2.6.27.6/arch/sparc/include/asm/pgtsrmmu.h 2008-11-18 03:39:50.000000000 -0500
1976 -@@ -115,6 +115,13 @@
1977 - SRMMU_EXEC | SRMMU_REF)
1978 - #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
1979 - SRMMU_EXEC | SRMMU_REF)
1980 -+
1981 -+#ifdef CONFIG_PAX_PAGEEXEC
1982 -+#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_WRITE | SRMMU_REF)
1983 -+#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_REF)
1984 -+#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_REF)
1985 -+#endif
1986 -+
1987 - #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
1988 - SRMMU_DIRTY | SRMMU_REF)
1989 -
1990 -diff -urNp linux-2.6.27.6/arch/sparc/kernel/sys_sparc.c linux-2.6.27.6/arch/sparc/kernel/sys_sparc.c
1991 ---- linux-2.6.27.6/arch/sparc/kernel/sys_sparc.c 2008-11-07 12:55:34.000000000 -0500
1992 -+++ linux-2.6.27.6/arch/sparc/kernel/sys_sparc.c 2008-11-18 03:38:43.000000000 -0500
1993 -@@ -56,7 +56,7 @@ unsigned long arch_get_unmapped_area(str
1994 - if (ARCH_SUN4C_SUN4 && len > 0x20000000)
1995 - return -ENOMEM;
1996 - if (!addr)
1997 -- addr = TASK_UNMAPPED_BASE;
1998 -+ addr = current->mm->mmap_base;
1999 -
2000 - if (flags & MAP_SHARED)
2001 - addr = COLOUR_ALIGN(addr);
2002 -diff -urNp linux-2.6.27.6/arch/sparc/Makefile linux-2.6.27.6/arch/sparc/Makefile
2003 ---- linux-2.6.27.6/arch/sparc/Makefile 2008-11-07 12:55:34.000000000 -0500
2004 -+++ linux-2.6.27.6/arch/sparc/Makefile 2008-11-18 03:38:43.000000000 -0500
2005 -@@ -37,7 +37,7 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc
2006 - # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
2007 - INIT_Y := $(patsubst %/, %/built-in.o, $(init-y))
2008 - CORE_Y := $(core-y)
2009 --CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
2010 -+CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
2011 - CORE_Y := $(patsubst %/, %/built-in.o, $(CORE_Y))
2012 - DRIVERS_Y := $(patsubst %/, %/built-in.o, $(drivers-y))
2013 - NET_Y := $(patsubst %/, %/built-in.o, $(net-y))
2014 -diff -urNp linux-2.6.27.6/arch/sparc/mm/fault.c linux-2.6.27.6/arch/sparc/mm/fault.c
2015 ---- linux-2.6.27.6/arch/sparc/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
2016 -+++ linux-2.6.27.6/arch/sparc/mm/fault.c 2008-11-18 03:38:43.000000000 -0500
2017 -@@ -21,6 +21,9 @@
2018 - #include <linux/interrupt.h>
2019 - #include <linux/module.h>
2020 - #include <linux/kdebug.h>
2021 -+#include <linux/slab.h>
2022 -+#include <linux/pagemap.h>
2023 -+#include <linux/compiler.h>
2024 -
2025 - #include <asm/system.h>
2026 - #include <asm/page.h>
2027 -@@ -167,6 +170,249 @@ static unsigned long compute_si_addr(str
2028 - return safe_compute_effective_address(regs, insn);
2029 - }
2030 -
2031 -+#ifdef CONFIG_PAX_PAGEEXEC
2032 -+void pax_emuplt_close(struct vm_area_struct *vma)
2033 -+{
2034 -+ vma->vm_mm->call_dl_resolve = 0UL;
2035 -+}
2036 -+
2037 -+static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
2038 -+{
2039 -+ unsigned int *kaddr;
2040 -+
2041 -+ vmf->page = alloc_page(GFP_HIGHUSER);
2042 -+ if (!vmf->page)
2043 -+ return VM_FAULT_OOM;
2044 -+
2045 -+ kaddr = kmap(vmf->page);
2046 -+ memset(kaddr, 0, PAGE_SIZE);
2047 -+ kaddr[0] = 0x9DE3BFA8U; /* save */
2048 -+ flush_dcache_page(vmf->page);
2049 -+ kunmap(vmf->page);
2050 -+ return VM_FAULT_MAJOR;
2051 -+}
2052 -+
2053 -+static struct vm_operations_struct pax_vm_ops = {
2054 -+ .close = pax_emuplt_close,
2055 -+ .fault = pax_emuplt_fault
2056 -+};
2057 -+
2058 -+static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2059 -+{
2060 -+ int ret;
2061 -+
2062 -+ vma->vm_mm = current->mm;
2063 -+ vma->vm_start = addr;
2064 -+ vma->vm_end = addr + PAGE_SIZE;
2065 -+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2066 -+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
2067 -+ vma->vm_ops = &pax_vm_ops;
2068 -+
2069 -+ ret = insert_vm_struct(current->mm, vma);
2070 -+ if (ret)
2071 -+ return ret;
2072 -+
2073 -+ ++current->mm->total_vm;
2074 -+ return 0;
2075 -+}
2076 -+
2077 -+/*
2078 -+ * PaX: decide what to do with offenders (regs->pc = fault address)
2079 -+ *
2080 -+ * returns 1 when task should be killed
2081 -+ * 2 when patched PLT trampoline was detected
2082 -+ * 3 when unpatched PLT trampoline was detected
2083 -+ */
2084 -+static int pax_handle_fetch_fault(struct pt_regs *regs)
2085 -+{
2086 -+
2087 -+#ifdef CONFIG_PAX_EMUPLT
2088 -+ int err;
2089 -+
2090 -+ do { /* PaX: patched PLT emulation #1 */
2091 -+ unsigned int sethi1, sethi2, jmpl;
2092 -+
2093 -+ err = get_user(sethi1, (unsigned int *)regs->pc);
2094 -+ err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
2095 -+ err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
2096 -+
2097 -+ if (err)
2098 -+ break;
2099 -+
2100 -+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2101 -+ (sethi2 & 0xFFC00000U) == 0x03000000U &&
2102 -+ (jmpl & 0xFFFFE000U) == 0x81C06000U)
2103 -+ {
2104 -+ unsigned int addr;
2105 -+
2106 -+ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
2107 -+ addr = regs->u_regs[UREG_G1];
2108 -+ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
2109 -+ regs->pc = addr;
2110 -+ regs->npc = addr+4;
2111 -+ return 2;
2112 -+ }
2113 -+ } while (0);
2114 -+
2115 -+ { /* PaX: patched PLT emulation #2 */
2116 -+ unsigned int ba;
2117 -+
2118 -+ err = get_user(ba, (unsigned int *)regs->pc);
2119 -+
2120 -+ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
2121 -+ unsigned int addr;
2122 -+
2123 -+ addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
2124 -+ regs->pc = addr;
2125 -+ regs->npc = addr+4;
2126 -+ return 2;
2127 -+ }
2128 -+ }
2129 -+
2130 -+ do { /* PaX: patched PLT emulation #3 */
2131 -+ unsigned int sethi, jmpl, nop;
2132 -+
2133 -+ err = get_user(sethi, (unsigned int *)regs->pc);
2134 -+ err |= get_user(jmpl, (unsigned int *)(regs->pc+4));
2135 -+ err |= get_user(nop, (unsigned int *)(regs->pc+8));
2136 -+
2137 -+ if (err)
2138 -+ break;
2139 -+
2140 -+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
2141 -+ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
2142 -+ nop == 0x01000000U)
2143 -+ {
2144 -+ unsigned int addr;
2145 -+
2146 -+ addr = (sethi & 0x003FFFFFU) << 10;
2147 -+ regs->u_regs[UREG_G1] = addr;
2148 -+ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
2149 -+ regs->pc = addr;
2150 -+ regs->npc = addr+4;
2151 -+ return 2;
2152 -+ }
2153 -+ } while (0);
2154 -+
2155 -+ do { /* PaX: unpatched PLT emulation step 1 */
2156 -+ unsigned int sethi, ba, nop;
2157 -+
2158 -+ err = get_user(sethi, (unsigned int *)regs->pc);
2159 -+ err |= get_user(ba, (unsigned int *)(regs->pc+4));
2160 -+ err |= get_user(nop, (unsigned int *)(regs->pc+8));
2161 -+
2162 -+ if (err)
2163 -+ break;
2164 -+
2165 -+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
2166 -+ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
2167 -+ nop == 0x01000000U)
2168 -+ {
2169 -+ unsigned int addr, save, call;
2170 -+
2171 -+ if ((ba & 0xFFC00000U) == 0x30800000U)
2172 -+ addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
2173 -+ else
2174 -+ addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
2175 -+
2176 -+ err = get_user(save, (unsigned int *)addr);
2177 -+ err |= get_user(call, (unsigned int *)(addr+4));
2178 -+ err |= get_user(nop, (unsigned int *)(addr+8));
2179 -+ if (err)
2180 -+ break;
2181 -+
2182 -+ if (save == 0x9DE3BFA8U &&
2183 -+ (call & 0xC0000000U) == 0x40000000U &&
2184 -+ nop == 0x01000000U)
2185 -+ {
2186 -+ struct vm_area_struct *vma;
2187 -+ unsigned long call_dl_resolve;
2188 -+
2189 -+ down_read(&current->mm->mmap_sem);
2190 -+ call_dl_resolve = current->mm->call_dl_resolve;
2191 -+ up_read(&current->mm->mmap_sem);
2192 -+ if (likely(call_dl_resolve))
2193 -+ goto emulate;
2194 -+
2195 -+ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
2196 -+
2197 -+ down_write(&current->mm->mmap_sem);
2198 -+ if (current->mm->call_dl_resolve) {
2199 -+ call_dl_resolve = current->mm->call_dl_resolve;
2200 -+ up_write(&current->mm->mmap_sem);
2201 -+ if (vma)
2202 -+ kmem_cache_free(vm_area_cachep, vma);
2203 -+ goto emulate;
2204 -+ }
2205 -+
2206 -+ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2207 -+ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
2208 -+ up_write(&current->mm->mmap_sem);
2209 -+ if (vma)
2210 -+ kmem_cache_free(vm_area_cachep, vma);
2211 -+ return 1;
2212 -+ }
2213 -+
2214 -+ if (pax_insert_vma(vma, call_dl_resolve)) {
2215 -+ up_write(&current->mm->mmap_sem);
2216 -+ kmem_cache_free(vm_area_cachep, vma);
2217 -+ return 1;
2218 -+ }
2219 -+
2220 -+ current->mm->call_dl_resolve = call_dl_resolve;
2221 -+ up_write(&current->mm->mmap_sem);
2222 -+
2223 -+emulate:
2224 -+ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
2225 -+ regs->pc = call_dl_resolve;
2226 -+ regs->npc = addr+4;
2227 -+ return 3;
2228 -+ }
2229 -+ }
2230 -+ } while (0);
2231 -+
2232 -+ do { /* PaX: unpatched PLT emulation step 2 */
2233 -+ unsigned int save, call, nop;
2234 -+
2235 -+ err = get_user(save, (unsigned int *)(regs->pc-4));
2236 -+ err |= get_user(call, (unsigned int *)regs->pc);
2237 -+ err |= get_user(nop, (unsigned int *)(regs->pc+4));
2238 -+ if (err)
2239 -+ break;
2240 -+
2241 -+ if (save == 0x9DE3BFA8U &&
2242 -+ (call & 0xC0000000U) == 0x40000000U &&
2243 -+ nop == 0x01000000U)
2244 -+ {
2245 -+ unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
2246 -+
2247 -+ regs->u_regs[UREG_RETPC] = regs->pc;
2248 -+ regs->pc = dl_resolve;
2249 -+ regs->npc = dl_resolve+4;
2250 -+ return 3;
2251 -+ }
2252 -+ } while (0);
2253 -+#endif
2254 -+
2255 -+ return 1;
2256 -+}
2257 -+
2258 -+void pax_report_insns(void *pc, void *sp)
2259 -+{
2260 -+ unsigned long i;
2261 -+
2262 -+ printk(KERN_ERR "PAX: bytes at PC: ");
2263 -+ for (i = 0; i < 5; i++) {
2264 -+ unsigned int c;
2265 -+ if (get_user(c, (unsigned int *)pc+i))
2266 -+ printk(KERN_CONT "???????? ");
2267 -+ else
2268 -+ printk(KERN_CONT "%08x ", c);
2269 -+ }
2270 -+ printk("\n");
2271 -+}
2272 -+#endif
2273 -+
2274 - asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
2275 - unsigned long address)
2276 - {
2277 -@@ -231,6 +477,24 @@ good_area:
2278 - if(!(vma->vm_flags & VM_WRITE))
2279 - goto bad_area;
2280 - } else {
2281 -+
2282 -+#ifdef CONFIG_PAX_PAGEEXEC
2283 -+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
2284 -+ up_read(&mm->mmap_sem);
2285 -+ switch (pax_handle_fetch_fault(regs)) {
2286 -+
2287 -+#ifdef CONFIG_PAX_EMUPLT
2288 -+ case 2:
2289 -+ case 3:
2290 -+ return;
2291 -+#endif
2292 -+
2293 -+ }
2294 -+ pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]);
2295 -+ do_group_exit(SIGKILL);
2296 -+ }
2297 -+#endif
2298 -+
2299 - /* Allow reads even for write-only mappings */
2300 - if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
2301 - goto bad_area;
2302 -diff -urNp linux-2.6.27.6/arch/sparc/mm/init.c linux-2.6.27.6/arch/sparc/mm/init.c
2303 ---- linux-2.6.27.6/arch/sparc/mm/init.c 2008-11-07 12:55:34.000000000 -0500
2304 -+++ linux-2.6.27.6/arch/sparc/mm/init.c 2008-11-18 03:38:43.000000000 -0500
2305 -@@ -312,6 +312,9 @@ extern void device_scan(void);
2306 - pgprot_t PAGE_SHARED __read_mostly;
2307 - EXPORT_SYMBOL(PAGE_SHARED);
2308 -
2309 -+pgprot_t PAGE_SHARED_NOEXEC __read_mostly;
2310 -+EXPORT_SYMBOL(PAGE_SHARED_NOEXEC);
2311 -+
2312 - void __init paging_init(void)
2313 - {
2314 - switch(sparc_cpu_model) {
2315 -@@ -337,17 +340,17 @@ void __init paging_init(void)
2316 -
2317 - /* Initialize the protection map with non-constant, MMU dependent values. */
2318 - protection_map[0] = PAGE_NONE;
2319 -- protection_map[1] = PAGE_READONLY;
2320 -- protection_map[2] = PAGE_COPY;
2321 -- protection_map[3] = PAGE_COPY;
2322 -+ protection_map[1] = PAGE_READONLY_NOEXEC;
2323 -+ protection_map[2] = PAGE_COPY_NOEXEC;
2324 -+ protection_map[3] = PAGE_COPY_NOEXEC;
2325 - protection_map[4] = PAGE_READONLY;
2326 - protection_map[5] = PAGE_READONLY;
2327 - protection_map[6] = PAGE_COPY;
2328 - protection_map[7] = PAGE_COPY;
2329 - protection_map[8] = PAGE_NONE;
2330 -- protection_map[9] = PAGE_READONLY;
2331 -- protection_map[10] = PAGE_SHARED;
2332 -- protection_map[11] = PAGE_SHARED;
2333 -+ protection_map[9] = PAGE_READONLY_NOEXEC;
2334 -+ protection_map[10] = PAGE_SHARED_NOEXEC;
2335 -+ protection_map[11] = PAGE_SHARED_NOEXEC;
2336 - protection_map[12] = PAGE_READONLY;
2337 - protection_map[13] = PAGE_READONLY;
2338 - protection_map[14] = PAGE_SHARED;
2339 -diff -urNp linux-2.6.27.6/arch/sparc/mm/srmmu.c linux-2.6.27.6/arch/sparc/mm/srmmu.c
2340 ---- linux-2.6.27.6/arch/sparc/mm/srmmu.c 2008-11-07 12:55:34.000000000 -0500
2341 -+++ linux-2.6.27.6/arch/sparc/mm/srmmu.c 2008-11-18 03:38:43.000000000 -0500
2342 -@@ -2163,6 +2163,13 @@ void __init ld_mmu_srmmu(void)
2343 - PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED);
2344 - BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
2345 - BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
2346 -+
2347 -+#ifdef CONFIG_PAX_PAGEEXEC
2348 -+ PAGE_SHARED_NOEXEC = pgprot_val(SRMMU_PAGE_SHARED_NOEXEC);
2349 -+ BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
2350 -+ BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
2351 -+#endif
2352 -+
2353 - BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
2354 - page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
2355 -
2356 -diff -urNp linux-2.6.27.6/arch/sparc64/kernel/Makefile linux-2.6.27.6/arch/sparc64/kernel/Makefile
2357 ---- linux-2.6.27.6/arch/sparc64/kernel/Makefile 2008-11-07 12:55:34.000000000 -0500
2358 -+++ linux-2.6.27.6/arch/sparc64/kernel/Makefile 2008-11-18 03:38:43.000000000 -0500
2359 -@@ -3,7 +3,7 @@
2360 - #
2361 -
2362 - EXTRA_AFLAGS := -ansi
2363 --EXTRA_CFLAGS := -Werror
2364 -+#EXTRA_CFLAGS := -Werror
2365 -
2366 - extra-y := head.o init_task.o vmlinux.lds
2367 -
2368 -diff -urNp linux-2.6.27.6/arch/sparc64/kernel/sys_sparc.c linux-2.6.27.6/arch/sparc64/kernel/sys_sparc.c
2369 ---- linux-2.6.27.6/arch/sparc64/kernel/sys_sparc.c 2008-11-07 12:55:34.000000000 -0500
2370 -+++ linux-2.6.27.6/arch/sparc64/kernel/sys_sparc.c 2008-11-18 03:38:43.000000000 -0500
2371 -@@ -124,7 +124,7 @@ unsigned long arch_get_unmapped_area(str
2372 - /* We do not accept a shared mapping if it would violate
2373 - * cache aliasing constraints.
2374 - */
2375 -- if ((flags & MAP_SHARED) &&
2376 -+ if ((filp || (flags & MAP_SHARED)) &&
2377 - ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
2378 - return -EINVAL;
2379 - return addr;
2380 -@@ -139,6 +139,10 @@ unsigned long arch_get_unmapped_area(str
2381 - if (filp || (flags & MAP_SHARED))
2382 - do_color_align = 1;
2383 -
2384 -+#ifdef CONFIG_PAX_RANDMMAP
2385 -+ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2386 -+#endif
2387 -+
2388 - if (addr) {
2389 - if (do_color_align)
2390 - addr = COLOUR_ALIGN(addr, pgoff);
2391 -@@ -152,9 +156,9 @@ unsigned long arch_get_unmapped_area(str
2392 - }
2393 -
2394 - if (len > mm->cached_hole_size) {
2395 -- start_addr = addr = mm->free_area_cache;
2396 -+ start_addr = addr = mm->free_area_cache;
2397 - } else {
2398 -- start_addr = addr = TASK_UNMAPPED_BASE;
2399 -+ start_addr = addr = mm->mmap_base;
2400 - mm->cached_hole_size = 0;
2401 - }
2402 -
2403 -@@ -174,8 +178,8 @@ full_search:
2404 - vma = find_vma(mm, VA_EXCLUDE_END);
2405 - }
2406 - if (unlikely(task_size < addr)) {
2407 -- if (start_addr != TASK_UNMAPPED_BASE) {
2408 -- start_addr = addr = TASK_UNMAPPED_BASE;
2409 -+ if (start_addr != mm->mmap_base) {
2410 -+ start_addr = addr = mm->mmap_base;
2411 - mm->cached_hole_size = 0;
2412 - goto full_search;
2413 - }
2414 -@@ -215,7 +219,7 @@ arch_get_unmapped_area_topdown(struct fi
2415 - /* We do not accept a shared mapping if it would violate
2416 - * cache aliasing constraints.
2417 - */
2418 -- if ((flags & MAP_SHARED) &&
2419 -+ if ((filp || (flags & MAP_SHARED)) &&
2420 - ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
2421 - return -EINVAL;
2422 - return addr;
2423 -@@ -378,6 +382,12 @@ void arch_pick_mmap_layout(struct mm_str
2424 - current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
2425 - sysctl_legacy_va_layout) {
2426 - mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
2427 -+
2428 -+#ifdef CONFIG_PAX_RANDMMAP
2429 -+ if (mm->pax_flags & MF_PAX_RANDMMAP)
2430 -+ mm->mmap_base += mm->delta_mmap;
2431 -+#endif
2432 -+
2433 - mm->get_unmapped_area = arch_get_unmapped_area;
2434 - mm->unmap_area = arch_unmap_area;
2435 - } else {
2436 -@@ -392,6 +402,12 @@ void arch_pick_mmap_layout(struct mm_str
2437 - gap = (task_size / 6 * 5);
2438 -
2439 - mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
2440 -+
2441 -+#ifdef CONFIG_PAX_RANDMMAP
2442 -+ if (mm->pax_flags & MF_PAX_RANDMMAP)
2443 -+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
2444 -+#endif
2445 -+
2446 - mm->get_unmapped_area = arch_get_unmapped_area_topdown;
2447 - mm->unmap_area = arch_unmap_area_topdown;
2448 - }
2449 -diff -urNp linux-2.6.27.6/arch/sparc64/mm/fault.c linux-2.6.27.6/arch/sparc64/mm/fault.c
2450 ---- linux-2.6.27.6/arch/sparc64/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
2451 -+++ linux-2.6.27.6/arch/sparc64/mm/fault.c 2008-11-18 03:38:43.000000000 -0500
2452 -@@ -19,6 +19,9 @@
2453 - #include <linux/interrupt.h>
2454 - #include <linux/kprobes.h>
2455 - #include <linux/kdebug.h>
2456 -+#include <linux/slab.h>
2457 -+#include <linux/pagemap.h>
2458 -+#include <linux/compiler.h>
2459 -
2460 - #include <asm/page.h>
2461 - #include <asm/pgtable.h>
2462 -@@ -261,6 +264,367 @@ cannot_handle:
2463 - unhandled_fault (address, current, regs);
2464 - }
2465 -
2466 -+#ifdef CONFIG_PAX_PAGEEXEC
2467 -+#ifdef CONFIG_PAX_EMUPLT
2468 -+static void pax_emuplt_close(struct vm_area_struct *vma)
2469 -+{
2470 -+ vma->vm_mm->call_dl_resolve = 0UL;
2471 -+}
2472 -+
2473 -+static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
2474 -+{
2475 -+ unsigned int *kaddr;
2476 -+
2477 -+ vmf->page = alloc_page(GFP_HIGHUSER);
2478 -+ if (!vmf->page)
2479 -+ return VM_FAULT_OOM;
2480 -+
2481 -+ kaddr = kmap(vmf->page);
2482 -+ memset(kaddr, 0, PAGE_SIZE);
2483 -+ kaddr[0] = 0x9DE3BFA8U; /* save */
2484 -+ flush_dcache_page(vmf->page);
2485 -+ kunmap(vmf->page);
2486 -+ return VM_FAULT_MAJOR;
2487 -+}
2488 -+
2489 -+static struct vm_operations_struct pax_vm_ops = {
2490 -+ .close = pax_emuplt_close,
2491 -+ .fault = pax_emuplt_fault
2492 -+};
2493 -+
2494 -+static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2495 -+{
2496 -+ int ret;
2497 -+
2498 -+ vma->vm_mm = current->mm;
2499 -+ vma->vm_start = addr;
2500 -+ vma->vm_end = addr + PAGE_SIZE;
2501 -+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2502 -+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
2503 -+ vma->vm_ops = &pax_vm_ops;
2504 -+
2505 -+ ret = insert_vm_struct(current->mm, vma);
2506 -+ if (ret)
2507 -+ return ret;
2508 -+
2509 -+ ++current->mm->total_vm;
2510 -+ return 0;
2511 -+}
2512 -+#endif
2513 -+
2514 -+/*
2515 -+ * PaX: decide what to do with offenders (regs->tpc = fault address)
2516 -+ *
2517 -+ * returns 1 when task should be killed
2518 -+ * 2 when patched PLT trampoline was detected
2519 -+ * 3 when unpatched PLT trampoline was detected
2520 -+ */
2521 -+static int pax_handle_fetch_fault(struct pt_regs *regs)
2522 -+{
2523 -+
2524 -+#ifdef CONFIG_PAX_EMUPLT
2525 -+ int err;
2526 -+
2527 -+ do { /* PaX: patched PLT emulation #1 */
2528 -+ unsigned int sethi1, sethi2, jmpl;
2529 -+
2530 -+ err = get_user(sethi1, (unsigned int *)regs->tpc);
2531 -+ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2532 -+ err |= get_user(jmpl, (unsigned int *)(regs->tpc+8));
2533 -+
2534 -+ if (err)
2535 -+ break;
2536 -+
2537 -+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2538 -+ (sethi2 & 0xFFC00000U) == 0x03000000U &&
2539 -+ (jmpl & 0xFFFFE000U) == 0x81C06000U)
2540 -+ {
2541 -+ unsigned long addr;
2542 -+
2543 -+ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
2544 -+ addr = regs->u_regs[UREG_G1];
2545 -+ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
2546 -+ regs->tpc = addr;
2547 -+ regs->tnpc = addr+4;
2548 -+ return 2;
2549 -+ }
2550 -+ } while (0);
2551 -+
2552 -+ { /* PaX: patched PLT emulation #2 */
2553 -+ unsigned int ba;
2554 -+
2555 -+ err = get_user(ba, (unsigned int *)regs->tpc);
2556 -+
2557 -+ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
2558 -+ unsigned long addr;
2559 -+
2560 -+ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
2561 -+ regs->tpc = addr;
2562 -+ regs->tnpc = addr+4;
2563 -+ return 2;
2564 -+ }
2565 -+ }
2566 -+
2567 -+ do { /* PaX: patched PLT emulation #3 */
2568 -+ unsigned int sethi, jmpl, nop;
2569 -+
2570 -+ err = get_user(sethi, (unsigned int *)regs->tpc);
2571 -+ err |= get_user(jmpl, (unsigned int *)(regs->tpc+4));
2572 -+ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2573 -+
2574 -+ if (err)
2575 -+ break;
2576 -+
2577 -+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
2578 -+ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
2579 -+ nop == 0x01000000U)
2580 -+ {
2581 -+ unsigned long addr;
2582 -+
2583 -+ addr = (sethi & 0x003FFFFFU) << 10;
2584 -+ regs->u_regs[UREG_G1] = addr;
2585 -+ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
2586 -+ regs->tpc = addr;
2587 -+ regs->tnpc = addr+4;
2588 -+ return 2;
2589 -+ }
2590 -+ } while (0);
2591 -+
2592 -+ do { /* PaX: patched PLT emulation #4 */
2593 -+ unsigned int mov1, call, mov2;
2594 -+
2595 -+ err = get_user(mov1, (unsigned int *)regs->tpc);
2596 -+ err |= get_user(call, (unsigned int *)(regs->tpc+4));
2597 -+ err |= get_user(mov2, (unsigned int *)(regs->tpc+8));
2598 -+
2599 -+ if (err)
2600 -+ break;
2601 -+
2602 -+ if (mov1 == 0x8210000FU &&
2603 -+ (call & 0xC0000000U) == 0x40000000U &&
2604 -+ mov2 == 0x9E100001U)
2605 -+ {
2606 -+ unsigned long addr;
2607 -+
2608 -+ regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
2609 -+ addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
2610 -+ regs->tpc = addr;
2611 -+ regs->tnpc = addr+4;
2612 -+ return 2;
2613 -+ }
2614 -+ } while (0);
2615 -+
2616 -+ do { /* PaX: patched PLT emulation #5 */
2617 -+ unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
2618 -+
2619 -+ err = get_user(sethi1, (unsigned int *)regs->tpc);
2620 -+ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2621 -+ err |= get_user(or1, (unsigned int *)(regs->tpc+8));
2622 -+ err |= get_user(or2, (unsigned int *)(regs->tpc+12));
2623 -+ err |= get_user(sllx, (unsigned int *)(regs->tpc+16));
2624 -+ err |= get_user(jmpl, (unsigned int *)(regs->tpc+20));
2625 -+ err |= get_user(nop, (unsigned int *)(regs->tpc+24));
2626 -+
2627 -+ if (err)
2628 -+ break;
2629 -+
2630 -+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2631 -+ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
2632 -+ (or1 & 0xFFFFE000U) == 0x82106000U &&
2633 -+ (or2 & 0xFFFFE000U) == 0x8A116000U &&
2634 -+ sllx == 0x83287020 &&
2635 -+ jmpl == 0x81C04005U &&
2636 -+ nop == 0x01000000U)
2637 -+ {
2638 -+ unsigned long addr;
2639 -+
2640 -+ regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
2641 -+ regs->u_regs[UREG_G1] <<= 32;
2642 -+ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
2643 -+ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
2644 -+ regs->tpc = addr;
2645 -+ regs->tnpc = addr+4;
2646 -+ return 2;
2647 -+ }
2648 -+ } while (0);
2649 -+
2650 -+ do { /* PaX: patched PLT emulation #6 */
2651 -+ unsigned int sethi1, sethi2, sllx, or, jmpl, nop;
2652 -+
2653 -+ err = get_user(sethi1, (unsigned int *)regs->tpc);
2654 -+ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2655 -+ err |= get_user(sllx, (unsigned int *)(regs->tpc+8));
2656 -+ err |= get_user(or, (unsigned int *)(regs->tpc+12));
2657 -+ err |= get_user(jmpl, (unsigned int *)(regs->tpc+16));
2658 -+ err |= get_user(nop, (unsigned int *)(regs->tpc+20));
2659 -+
2660 -+ if (err)
2661 -+ break;
2662 -+
2663 -+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2664 -+ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
2665 -+ sllx == 0x83287020 &&
2666 -+ (or & 0xFFFFE000U) == 0x8A116000U &&
2667 -+ jmpl == 0x81C04005U &&
2668 -+ nop == 0x01000000U)
2669 -+ {
2670 -+ unsigned long addr;
2671 -+
2672 -+ regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
2673 -+ regs->u_regs[UREG_G1] <<= 32;
2674 -+ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
2675 -+ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
2676 -+ regs->tpc = addr;
2677 -+ regs->tnpc = addr+4;
2678 -+ return 2;
2679 -+ }
2680 -+ } while (0);
2681 -+
2682 -+ do { /* PaX: patched PLT emulation #7 */
2683 -+ unsigned int sethi, ba, nop;
2684 -+
2685 -+ err = get_user(sethi, (unsigned int *)regs->tpc);
2686 -+ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
2687 -+ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2688 -+
2689 -+ if (err)
2690 -+ break;
2691 -+
2692 -+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
2693 -+ (ba & 0xFFF00000U) == 0x30600000U &&
2694 -+ nop == 0x01000000U)
2695 -+ {
2696 -+ unsigned long addr;
2697 -+
2698 -+ addr = (sethi & 0x003FFFFFU) << 10;
2699 -+ regs->u_regs[UREG_G1] = addr;
2700 -+ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
2701 -+ regs->tpc = addr;
2702 -+ regs->tnpc = addr+4;
2703 -+ return 2;
2704 -+ }
2705 -+ } while (0);
2706 -+
2707 -+ do { /* PaX: unpatched PLT emulation step 1 */
2708 -+ unsigned int sethi, ba, nop;
2709 -+
2710 -+ err = get_user(sethi, (unsigned int *)regs->tpc);
2711 -+ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
2712 -+ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2713 -+
2714 -+ if (err)
2715 -+ break;
2716 -+
2717 -+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
2718 -+ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
2719 -+ nop == 0x01000000U)
2720 -+ {
2721 -+ unsigned long addr;
2722 -+ unsigned int save, call;
2723 -+
2724 -+ if ((ba & 0xFFC00000U) == 0x30800000U)
2725 -+ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
2726 -+ else
2727 -+ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
2728 -+
2729 -+ err = get_user(save, (unsigned int *)addr);
2730 -+ err |= get_user(call, (unsigned int *)(addr+4));
2731 -+ err |= get_user(nop, (unsigned int *)(addr+8));
2732 -+ if (err)
2733 -+ break;
2734 -+
2735 -+ if (save == 0x9DE3BFA8U &&
2736 -+ (call & 0xC0000000U) == 0x40000000U &&
2737 -+ nop == 0x01000000U)
2738 -+ {
2739 -+ struct vm_area_struct *vma;
2740 -+ unsigned long call_dl_resolve;
2741 -+
2742 -+ down_read(&current->mm->mmap_sem);
2743 -+ call_dl_resolve = current->mm->call_dl_resolve;
2744 -+ up_read(&current->mm->mmap_sem);
2745 -+ if (likely(call_dl_resolve))
2746 -+ goto emulate;
2747 -+
2748 -+ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
2749 -+
2750 -+ down_write(&current->mm->mmap_sem);
2751 -+ if (current->mm->call_dl_resolve) {
2752 -+ call_dl_resolve = current->mm->call_dl_resolve;
2753 -+ up_write(&current->mm->mmap_sem);
2754 -+ if (vma)
2755 -+ kmem_cache_free(vm_area_cachep, vma);
2756 -+ goto emulate;
2757 -+ }
2758 -+
2759 -+ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2760 -+ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
2761 -+ up_write(&current->mm->mmap_sem);
2762 -+ if (vma)
2763 -+ kmem_cache_free(vm_area_cachep, vma);
2764 -+ return 1;
2765 -+ }
2766 -+
2767 -+ if (pax_insert_vma(vma, call_dl_resolve)) {
2768 -+ up_write(&current->mm->mmap_sem);
2769 -+ kmem_cache_free(vm_area_cachep, vma);
2770 -+ return 1;
2771 -+ }
2772 -+
2773 -+ current->mm->call_dl_resolve = call_dl_resolve;
2774 -+ up_write(&current->mm->mmap_sem);
2775 -+
2776 -+emulate:
2777 -+ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
2778 -+ regs->tpc = call_dl_resolve;
2779 -+ regs->tnpc = addr+4;
2780 -+ return 3;
2781 -+ }
2782 -+ }
2783 -+ } while (0);
2784 -+
2785 -+ do { /* PaX: unpatched PLT emulation step 2 */
2786 -+ unsigned int save, call, nop;
2787 -+
2788 -+ err = get_user(save, (unsigned int *)(regs->tpc-4));
2789 -+ err |= get_user(call, (unsigned int *)regs->tpc);
2790 -+ err |= get_user(nop, (unsigned int *)(regs->tpc+4));
2791 -+ if (err)
2792 -+ break;
2793 -+
2794 -+ if (save == 0x9DE3BFA8U &&
2795 -+ (call & 0xC0000000U) == 0x40000000U &&
2796 -+ nop == 0x01000000U)
2797 -+ {
2798 -+ unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
2799 -+
2800 -+ regs->u_regs[UREG_RETPC] = regs->tpc;
2801 -+ regs->tpc = dl_resolve;
2802 -+ regs->tnpc = dl_resolve+4;
2803 -+ return 3;
2804 -+ }
2805 -+ } while (0);
2806 -+#endif
2807 -+
2808 -+ return 1;
2809 -+}
2810 -+
2811 -+void pax_report_insns(void *pc, void *sp)
2812 -+{
2813 -+ unsigned long i;
2814 -+
2815 -+ printk(KERN_ERR "PAX: bytes at PC: ");
2816 -+ for (i = 0; i < 5; i++) {
2817 -+ unsigned int c;
2818 -+ if (get_user(c, (unsigned int *)pc+i))
2819 -+ printk(KERN_CONT "???????? ");
2820 -+ else
2821 -+ printk(KERN_CONT "%08x ", c);
2822 -+ }
2823 -+ printk("\n");
2824 -+}
2825 -+#endif
2826 -+
2827 - asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
2828 - {
2829 - struct mm_struct *mm = current->mm;
2830 -@@ -302,8 +666,10 @@ asmlinkage void __kprobes do_sparc64_fau
2831 - goto intr_or_no_mm;
2832 -
2833 - if (test_thread_flag(TIF_32BIT)) {
2834 -- if (!(regs->tstate & TSTATE_PRIV))
2835 -+ if (!(regs->tstate & TSTATE_PRIV)) {
2836 - regs->tpc &= 0xffffffff;
2837 -+ regs->tnpc &= 0xffffffff;
2838 -+ }
2839 - address &= 0xffffffff;
2840 - }
2841 -
2842 -@@ -320,6 +686,29 @@ asmlinkage void __kprobes do_sparc64_fau
2843 - if (!vma)
2844 - goto bad_area;
2845 -
2846 -+#ifdef CONFIG_PAX_PAGEEXEC
2847 -+ /* PaX: detect ITLB misses on non-exec pages */
2848 -+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
2849 -+ !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
2850 -+ {
2851 -+ if (address != regs->tpc)
2852 -+ goto good_area;
2853 -+
2854 -+ up_read(&mm->mmap_sem);
2855 -+ switch (pax_handle_fetch_fault(regs)) {
2856 -+
2857 -+#ifdef CONFIG_PAX_EMUPLT
2858 -+ case 2:
2859 -+ case 3:
2860 -+ return;
2861 -+#endif
2862 -+
2863 -+ }
2864 -+ pax_report_fault(regs, (void *)regs->tpc, (void *)(regs->u_regs[UREG_FP] + STACK_BIAS));
2865 -+ do_group_exit(SIGKILL);
2866 -+ }
2867 -+#endif
2868 -+
2869 - /* Pure DTLB misses do not tell us whether the fault causing
2870 - * load/store/atomic was a write or not, it only says that there
2871 - * was no match. So in such a case we (carefully) read the
2872 -diff -urNp linux-2.6.27.6/arch/sparc64/mm/Makefile linux-2.6.27.6/arch/sparc64/mm/Makefile
2873 ---- linux-2.6.27.6/arch/sparc64/mm/Makefile 2008-11-07 12:55:34.000000000 -0500
2874 -+++ linux-2.6.27.6/arch/sparc64/mm/Makefile 2008-11-18 03:38:43.000000000 -0500
2875 -@@ -2,7 +2,7 @@
2876 - #
2877 -
2878 - EXTRA_AFLAGS := -ansi
2879 --EXTRA_CFLAGS := -Werror
2880 -+#EXTRA_CFLAGS := -Werror
2881 -
2882 - obj-y := ultra.o tlb.o tsb.o fault.o init.o generic.o
2883 -
2884 -diff -urNp linux-2.6.27.6/arch/um/sys-i386/syscalls.c linux-2.6.27.6/arch/um/sys-i386/syscalls.c
2885 ---- linux-2.6.27.6/arch/um/sys-i386/syscalls.c 2008-11-07 12:55:34.000000000 -0500
2886 -+++ linux-2.6.27.6/arch/um/sys-i386/syscalls.c 2008-11-18 03:38:43.000000000 -0500
2887 -@@ -10,6 +10,21 @@
2888 - #include "asm/uaccess.h"
2889 - #include "asm/unistd.h"
2890 -
2891 -+int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
2892 -+{
2893 -+ unsigned long pax_task_size = TASK_SIZE;
2894 -+
2895 -+#ifdef CONFIG_PAX_SEGMEXEC
2896 -+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
2897 -+ pax_task_size = SEGMEXEC_TASK_SIZE;
2898 -+#endif
2899 -+
2900 -+ if (len > pax_task_size || addr > pax_task_size - len)
2901 -+ return -EINVAL;
2902 -+
2903 -+ return 0;
2904 -+}
2905 -+
2906 - /*
2907 - * Perform the select(nd, in, out, ex, tv) and mmap() system
2908 - * calls. Linux/i386 didn't use to be able to handle more than
2909 -diff -urNp linux-2.6.27.6/arch/x86/boot/bitops.h linux-2.6.27.6/arch/x86/boot/bitops.h
2910 ---- linux-2.6.27.6/arch/x86/boot/bitops.h 2008-11-07 12:55:34.000000000 -0500
2911 -+++ linux-2.6.27.6/arch/x86/boot/bitops.h 2008-11-18 03:38:44.000000000 -0500
2912 -@@ -26,7 +26,7 @@ static inline int variable_test_bit(int
2913 - u8 v;
2914 - const u32 *p = (const u32 *)addr;
2915 -
2916 -- asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
2917 -+ asm volatile("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
2918 - return v;
2919 - }
2920 -
2921 -@@ -37,7 +37,7 @@ static inline int variable_test_bit(int
2922 -
2923 - static inline void set_bit(int nr, void *addr)
2924 - {
2925 -- asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
2926 -+ asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
2927 - }
2928 -
2929 - #endif /* BOOT_BITOPS_H */
2930 -diff -urNp linux-2.6.27.6/arch/x86/boot/boot.h linux-2.6.27.6/arch/x86/boot/boot.h
2931 ---- linux-2.6.27.6/arch/x86/boot/boot.h 2008-11-07 12:55:34.000000000 -0500
2932 -+++ linux-2.6.27.6/arch/x86/boot/boot.h 2008-11-18 03:38:44.000000000 -0500
2933 -@@ -80,7 +80,7 @@ static inline void io_delay(void)
2934 - static inline u16 ds(void)
2935 - {
2936 - u16 seg;
2937 -- asm("movw %%ds,%0" : "=rm" (seg));
2938 -+ asm volatile("movw %%ds,%0" : "=rm" (seg));
2939 - return seg;
2940 - }
2941 -
2942 -@@ -176,7 +176,7 @@ static inline void wrgs32(u32 v, addr_t
2943 - static inline int memcmp(const void *s1, const void *s2, size_t len)
2944 - {
2945 - u8 diff;
2946 -- asm("repe; cmpsb; setnz %0"
2947 -+ asm volatile("repe; cmpsb; setnz %0"
2948 - : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
2949 - return diff;
2950 - }
2951 -diff -urNp linux-2.6.27.6/arch/x86/boot/compressed/head_32.S linux-2.6.27.6/arch/x86/boot/compressed/head_32.S
2952 ---- linux-2.6.27.6/arch/x86/boot/compressed/head_32.S 2008-11-07 12:55:34.000000000 -0500
2953 -+++ linux-2.6.27.6/arch/x86/boot/compressed/head_32.S 2008-11-18 03:38:44.000000000 -0500
2954 -@@ -70,7 +70,7 @@ startup_32:
2955 - addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebx
2956 - andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebx
2957 - #else
2958 -- movl $LOAD_PHYSICAL_ADDR, %ebx
2959 -+ movl $____LOAD_PHYSICAL_ADDR, %ebx
2960 - #endif
2961 -
2962 - /* Replace the compressed data size with the uncompressed size */
2963 -@@ -105,7 +105,7 @@ startup_32:
2964 - addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebp
2965 - andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebp
2966 - #else
2967 -- movl $LOAD_PHYSICAL_ADDR, %ebp
2968 -+ movl $____LOAD_PHYSICAL_ADDR, %ebp
2969 - #endif
2970 -
2971 - /*
2972 -@@ -159,16 +159,15 @@ relocated:
2973 - * and where it was actually loaded.
2974 - */
2975 - movl %ebp, %ebx
2976 -- subl $LOAD_PHYSICAL_ADDR, %ebx
2977 -+ subl $____LOAD_PHYSICAL_ADDR, %ebx
2978 - jz 2f /* Nothing to be done if loaded at compiled addr. */
2979 - /*
2980 - * Process relocations.
2981 - */
2982 -
2983 - 1: subl $4, %edi
2984 -- movl 0(%edi), %ecx
2985 -- testl %ecx, %ecx
2986 -- jz 2f
2987 -+ movl (%edi), %ecx
2988 -+ jecxz 2f
2989 - addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
2990 - jmp 1b
2991 - 2:
2992 -diff -urNp linux-2.6.27.6/arch/x86/boot/compressed/misc.c linux-2.6.27.6/arch/x86/boot/compressed/misc.c
2993 ---- linux-2.6.27.6/arch/x86/boot/compressed/misc.c 2008-11-07 12:55:34.000000000 -0500
2994 -+++ linux-2.6.27.6/arch/x86/boot/compressed/misc.c 2008-11-18 03:38:44.000000000 -0500
2995 -@@ -371,7 +371,7 @@ static void parse_elf(void *output)
2996 - case PT_LOAD:
2997 - #ifdef CONFIG_RELOCATABLE
2998 - dest = output;
2999 -- dest += (phdr->p_paddr - LOAD_PHYSICAL_ADDR);
3000 -+ dest += (phdr->p_paddr - ____LOAD_PHYSICAL_ADDR);
3001 - #else
3002 - dest = (void *)(phdr->p_paddr);
3003 - #endif
3004 -@@ -423,7 +423,7 @@ asmlinkage void decompress_kernel(void *
3005 - if (heap > ((-__PAGE_OFFSET-(512<<20)-1) & 0x7fffffff))
3006 - error("Destination address too large");
3007 - #ifndef CONFIG_RELOCATABLE
3008 -- if ((u32)output != LOAD_PHYSICAL_ADDR)
3009 -+ if ((u32)output != ____LOAD_PHYSICAL_ADDR)
3010 - error("Wrong destination address");
3011 - #endif
3012 - #endif
3013 -diff -urNp linux-2.6.27.6/arch/x86/boot/compressed/relocs.c linux-2.6.27.6/arch/x86/boot/compressed/relocs.c
3014 ---- linux-2.6.27.6/arch/x86/boot/compressed/relocs.c 2008-11-07 12:55:34.000000000 -0500
3015 -+++ linux-2.6.27.6/arch/x86/boot/compressed/relocs.c 2008-11-18 03:38:44.000000000 -0500
3016 -@@ -10,8 +10,11 @@
3017 - #define USE_BSD
3018 - #include <endian.h>
3019 -
3020 -+#include "../../../../include/linux/autoconf.h"
3021 -+
3022 - #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
3023 - static Elf32_Ehdr ehdr;
3024 -+static Elf32_Phdr *phdr;
3025 - static unsigned long reloc_count, reloc_idx;
3026 - static unsigned long *relocs;
3027 -
3028 -@@ -245,6 +248,36 @@ static void read_ehdr(FILE *fp)
3029 - }
3030 - }
3031 -
3032 -+static void read_phdrs(FILE *fp)
3033 -+{
3034 -+ int i;
3035 -+
3036 -+ phdr = calloc(ehdr.e_phnum, sizeof(Elf32_Phdr));
3037 -+ if (!phdr) {
3038 -+ die("Unable to allocate %d program headers\n",
3039 -+ ehdr.e_phnum);
3040 -+ }
3041 -+ if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) {
3042 -+ die("Seek to %d failed: %s\n",
3043 -+ ehdr.e_phoff, strerror(errno));
3044 -+ }
3045 -+ if (fread(phdr, sizeof(*phdr), ehdr.e_phnum, fp) != ehdr.e_phnum) {
3046 -+ die("Cannot read ELF program headers: %s\n",
3047 -+ strerror(errno));
3048 -+ }
3049 -+ for(i = 0; i < ehdr.e_phnum; i++) {
3050 -+ phdr[i].p_type = elf32_to_cpu(phdr[i].p_type);
3051 -+ phdr[i].p_offset = elf32_to_cpu(phdr[i].p_offset);
3052 -+ phdr[i].p_vaddr = elf32_to_cpu(phdr[i].p_vaddr);
3053 -+ phdr[i].p_paddr = elf32_to_cpu(phdr[i].p_paddr);
3054 -+ phdr[i].p_filesz = elf32_to_cpu(phdr[i].p_filesz);
3055 -+ phdr[i].p_memsz = elf32_to_cpu(phdr[i].p_memsz);
3056 -+ phdr[i].p_flags = elf32_to_cpu(phdr[i].p_flags);
3057 -+ phdr[i].p_align = elf32_to_cpu(phdr[i].p_align);
3058 -+ }
3059 -+
3060 -+}
3061 -+
3062 - static void read_shdrs(FILE *fp)
3063 - {
3064 - int i;
3065 -@@ -341,6 +374,8 @@ static void read_symtabs(FILE *fp)
3066 - static void read_relocs(FILE *fp)
3067 - {
3068 - int i,j;
3069 -+ uint32_t base;
3070 -+
3071 - for (i = 0; i < ehdr.e_shnum; i++) {
3072 - struct section *sec = &secs[i];
3073 - if (sec->shdr.sh_type != SHT_REL) {
3074 -@@ -360,9 +395,18 @@ static void read_relocs(FILE *fp)
3075 - die("Cannot read symbol table: %s\n",
3076 - strerror(errno));
3077 - }
3078 -+ base = 0;
3079 -+ for (j = 0; j < ehdr.e_phnum; j++) {
3080 -+ if (phdr[j].p_type != PT_LOAD )
3081 -+ continue;
3082 -+ 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)
3083 -+ continue;
3084 -+ base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr;
3085 -+ break;
3086 -+ }
3087 - for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) {
3088 - Elf32_Rel *rel = &sec->reltab[j];
3089 -- rel->r_offset = elf32_to_cpu(rel->r_offset);
3090 -+ rel->r_offset = elf32_to_cpu(rel->r_offset) + base;
3091 - rel->r_info = elf32_to_cpu(rel->r_info);
3092 - }
3093 - }
3094 -@@ -504,6 +548,23 @@ static void walk_relocs(void (*visit)(El
3095 - if (sym->st_shndx == SHN_ABS) {
3096 - continue;
3097 - }
3098 -+ /* Don't relocate actual per-cpu variables, they are absolute indices, not addresses */
3099 -+ if (!strcmp(sec_name(sym->st_shndx), ".data.percpu") && strncmp(sym_name(sym_strtab, sym), "__per_cpu_", 10))
3100 -+ continue;
3101 -+#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32)
3102 -+ /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */
3103 -+ if (!strcmp(sec_name(sym->st_shndx), ".init.text"))
3104 -+ continue;
3105 -+ if (!strcmp(sec_name(sym->st_shndx), ".exit.text"))
3106 -+ continue;
3107 -+ if (!strcmp(sec_name(sym->st_shndx), ".text.head")) {
3108 -+ if (strcmp(sym_name(sym_strtab, sym), "__init_end") &&
3109 -+ strcmp(sym_name(sym_strtab, sym), "KERNEL_TEXT_OFFSET"))
3110 -+ continue;
3111 -+ }
3112 -+ if (!strcmp(sec_name(sym->st_shndx), ".text"))
3113 -+ continue;
3114 -+#endif
3115 - if (r_type == R_386_PC32) {
3116 - /* PC relative relocations don't need to be adjusted */
3117 - }
3118 -@@ -631,6 +692,7 @@ int main(int argc, char **argv)
3119 - fname, strerror(errno));
3120 - }
3121 - read_ehdr(fp);
3122 -+ read_phdrs(fp);
3123 - read_shdrs(fp);
3124 - read_strtabs(fp);
3125 - read_symtabs(fp);
3126 -diff -urNp linux-2.6.27.6/arch/x86/boot/cpucheck.c linux-2.6.27.6/arch/x86/boot/cpucheck.c
3127 ---- linux-2.6.27.6/arch/x86/boot/cpucheck.c 2008-11-07 12:55:34.000000000 -0500
3128 -+++ linux-2.6.27.6/arch/x86/boot/cpucheck.c 2008-11-18 03:38:44.000000000 -0500
3129 -@@ -74,7 +74,7 @@ static int has_fpu(void)
3130 - u16 fcw = -1, fsw = -1;
3131 - u32 cr0;
3132 -
3133 -- asm("movl %%cr0,%0" : "=r" (cr0));
3134 -+ asm volatile("movl %%cr0,%0" : "=r" (cr0));
3135 - if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
3136 - cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
3137 - asm volatile("movl %0,%%cr0" : : "r" (cr0));
3138 -@@ -90,7 +90,7 @@ static int has_eflag(u32 mask)
3139 - {
3140 - u32 f0, f1;
3141 -
3142 -- asm("pushfl ; "
3143 -+ asm volatile("pushfl ; "
3144 - "pushfl ; "
3145 - "popl %0 ; "
3146 - "movl %0,%1 ; "
3147 -@@ -115,7 +115,7 @@ static void get_flags(void)
3148 - set_bit(X86_FEATURE_FPU, cpu.flags);
3149 -
3150 - if (has_eflag(X86_EFLAGS_ID)) {
3151 -- asm("cpuid"
3152 -+ asm volatile("cpuid"
3153 - : "=a" (max_intel_level),
3154 - "=b" (cpu_vendor[0]),
3155 - "=d" (cpu_vendor[1]),
3156 -@@ -124,7 +124,7 @@ static void get_flags(void)
3157 -
3158 - if (max_intel_level >= 0x00000001 &&
3159 - max_intel_level <= 0x0000ffff) {
3160 -- asm("cpuid"
3161 -+ asm volatile("cpuid"
3162 - : "=a" (tfms),
3163 - "=c" (cpu.flags[4]),
3164 - "=d" (cpu.flags[0])
3165 -@@ -136,7 +136,7 @@ static void get_flags(void)
3166 - cpu.model += ((tfms >> 16) & 0xf) << 4;
3167 - }
3168 -
3169 -- asm("cpuid"
3170 -+ asm volatile("cpuid"
3171 - : "=a" (max_amd_level)
3172 - : "a" (0x80000000)
3173 - : "ebx", "ecx", "edx");
3174 -@@ -144,7 +144,7 @@ static void get_flags(void)
3175 - if (max_amd_level >= 0x80000001 &&
3176 - max_amd_level <= 0x8000ffff) {
3177 - u32 eax = 0x80000001;
3178 -- asm("cpuid"
3179 -+ asm volatile("cpuid"
3180 - : "+a" (eax),
3181 - "=c" (cpu.flags[6]),
3182 - "=d" (cpu.flags[1])
3183 -@@ -203,9 +203,9 @@ int check_cpu(int *cpu_level_ptr, int *r
3184 - u32 ecx = MSR_K7_HWCR;
3185 - u32 eax, edx;
3186 -
3187 -- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3188 -+ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3189 - eax &= ~(1 << 15);
3190 -- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3191 -+ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3192 -
3193 - get_flags(); /* Make sure it really did something */
3194 - err = check_flags();
3195 -@@ -218,9 +218,9 @@ int check_cpu(int *cpu_level_ptr, int *r
3196 - u32 ecx = MSR_VIA_FCR;
3197 - u32 eax, edx;
3198 -
3199 -- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3200 -+ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3201 - eax |= (1<<1)|(1<<7);
3202 -- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3203 -+ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3204 -
3205 - set_bit(X86_FEATURE_CX8, cpu.flags);
3206 - err = check_flags();
3207 -@@ -231,12 +231,12 @@ int check_cpu(int *cpu_level_ptr, int *r
3208 - u32 eax, edx;
3209 - u32 level = 1;
3210 -
3211 -- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3212 -- asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
3213 -- asm("cpuid"
3214 -+ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3215 -+ asm volatile("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
3216 -+ asm volatile("cpuid"
3217 - : "+a" (level), "=d" (cpu.flags[0])
3218 - : : "ecx", "ebx");
3219 -- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3220 -+ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3221 -
3222 - err = check_flags();
3223 - }
3224 -diff -urNp linux-2.6.27.6/arch/x86/boot/edd.c linux-2.6.27.6/arch/x86/boot/edd.c
3225 ---- linux-2.6.27.6/arch/x86/boot/edd.c 2008-11-07 12:55:34.000000000 -0500
3226 -+++ linux-2.6.27.6/arch/x86/boot/edd.c 2008-11-18 03:38:44.000000000 -0500
3227 -@@ -76,7 +76,7 @@ static int get_edd_info(u8 devno, struct
3228 - ax = 0x4100;
3229 - bx = EDDMAGIC1;
3230 - dx = devno;
3231 -- asm("pushfl; stc; int $0x13; setc %%al; popfl"
3232 -+ asm volatile("pushfl; stc; int $0x13; setc %%al; popfl"
3233 - : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
3234 - : : "esi", "edi");
3235 -
3236 -@@ -95,7 +95,7 @@ static int get_edd_info(u8 devno, struct
3237 - ei->params.length = sizeof(ei->params);
3238 - ax = 0x4800;
3239 - dx = devno;
3240 -- asm("pushfl; int $0x13; popfl"
3241 -+ asm volatile("pushfl; int $0x13; popfl"
3242 - : "+a" (ax), "+d" (dx), "=m" (ei->params)
3243 - : "S" (&ei->params)
3244 - : "ebx", "ecx", "edi");
3245 -@@ -106,7 +106,7 @@ static int get_edd_info(u8 devno, struct
3246 - ax = 0x0800;
3247 - dx = devno;
3248 - di = 0;
3249 -- asm("pushw %%es; "
3250 -+ asm volatile("pushw %%es; "
3251 - "movw %%di,%%es; "
3252 - "pushfl; stc; int $0x13; setc %%al; popfl; "
3253 - "popw %%es"
3254 -diff -urNp linux-2.6.27.6/arch/x86/boot/main.c linux-2.6.27.6/arch/x86/boot/main.c
3255 ---- linux-2.6.27.6/arch/x86/boot/main.c 2008-11-07 12:55:34.000000000 -0500
3256 -+++ linux-2.6.27.6/arch/x86/boot/main.c 2008-11-18 03:38:44.000000000 -0500
3257 -@@ -78,7 +78,7 @@ static void query_ist(void)
3258 - if (cpu.level < 6)
3259 - return;
3260 -
3261 -- asm("int $0x15"
3262 -+ asm volatile("int $0x15"
3263 - : "=a" (boot_params.ist_info.signature),
3264 - "=b" (boot_params.ist_info.command),
3265 - "=c" (boot_params.ist_info.event),
3266 -diff -urNp linux-2.6.27.6/arch/x86/boot/mca.c linux-2.6.27.6/arch/x86/boot/mca.c
3267 ---- linux-2.6.27.6/arch/x86/boot/mca.c 2008-11-07 12:55:34.000000000 -0500
3268 -+++ linux-2.6.27.6/arch/x86/boot/mca.c 2008-11-18 03:38:44.000000000 -0500
3269 -@@ -19,7 +19,7 @@ int query_mca(void)
3270 - u8 err;
3271 - u16 es, bx, len;
3272 -
3273 -- asm("pushw %%es ; "
3274 -+ asm volatile("pushw %%es ; "
3275 - "int $0x15 ; "
3276 - "setc %0 ; "
3277 - "movw %%es, %1 ; "
3278 -diff -urNp linux-2.6.27.6/arch/x86/boot/memory.c linux-2.6.27.6/arch/x86/boot/memory.c
3279 ---- linux-2.6.27.6/arch/x86/boot/memory.c 2008-11-07 12:55:34.000000000 -0500
3280 -+++ linux-2.6.27.6/arch/x86/boot/memory.c 2008-11-18 03:38:44.000000000 -0500
3281 -@@ -30,7 +30,7 @@ static int detect_memory_e820(void)
3282 - /* Important: %edx is clobbered by some BIOSes,
3283 - so it must be either used for the error output
3284 - or explicitly marked clobbered. */
3285 -- asm("int $0x15; setc %0"
3286 -+ asm volatile("int $0x15; setc %0"
3287 - : "=d" (err), "+b" (next), "=a" (id), "+c" (size),
3288 - "=m" (*desc)
3289 - : "D" (desc), "d" (SMAP), "a" (0xe820));
3290 -@@ -65,7 +65,7 @@ static int detect_memory_e801(void)
3291 -
3292 - bx = cx = dx = 0;
3293 - ax = 0xe801;
3294 -- asm("stc; int $0x15; setc %0"
3295 -+ asm volatile("stc; int $0x15; setc %0"
3296 - : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
3297 -
3298 - if (err)
3299 -@@ -95,7 +95,7 @@ static int detect_memory_88(void)
3300 - u8 err;
3301 -
3302 - ax = 0x8800;
3303 -- asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
3304 -+ asm volatile("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
3305 -
3306 - boot_params.screen_info.ext_mem_k = ax;
3307 -
3308 -diff -urNp linux-2.6.27.6/arch/x86/boot/video.c linux-2.6.27.6/arch/x86/boot/video.c
3309 ---- linux-2.6.27.6/arch/x86/boot/video.c 2008-11-07 12:55:34.000000000 -0500
3310 -+++ linux-2.6.27.6/arch/x86/boot/video.c 2008-11-18 03:38:44.000000000 -0500
3311 -@@ -23,7 +23,7 @@ static void store_cursor_position(void)
3312 -
3313 - ax = 0x0300;
3314 - bx = 0;
3315 -- asm(INT10
3316 -+ asm volatile(INT10
3317 - : "=d" (curpos), "+a" (ax), "+b" (bx)
3318 - : : "ecx", "esi", "edi");
3319 -
3320 -@@ -38,7 +38,7 @@ static void store_video_mode(void)
3321 - /* N.B.: the saving of the video page here is a bit silly,
3322 - since we pretty much assume page 0 everywhere. */
3323 - ax = 0x0f00;
3324 -- asm(INT10
3325 -+ asm volatile(INT10
3326 - : "+a" (ax), "=b" (page)
3327 - : : "ecx", "edx", "esi", "edi");
3328 -
3329 -diff -urNp linux-2.6.27.6/arch/x86/boot/video-vesa.c linux-2.6.27.6/arch/x86/boot/video-vesa.c
3330 ---- linux-2.6.27.6/arch/x86/boot/video-vesa.c 2008-11-07 12:55:34.000000000 -0500
3331 -+++ linux-2.6.27.6/arch/x86/boot/video-vesa.c 2008-11-18 03:38:44.000000000 -0500
3332 -@@ -41,7 +41,7 @@ static int vesa_probe(void)
3333 -
3334 - ax = 0x4f00;
3335 - di = (size_t)&vginfo;
3336 -- asm(INT10
3337 -+ asm volatile(INT10
3338 - : "+a" (ax), "+D" (di), "=m" (vginfo)
3339 - : : "ebx", "ecx", "edx", "esi");
3340 -
3341 -@@ -68,7 +68,7 @@ static int vesa_probe(void)
3342 - ax = 0x4f01;
3343 - cx = mode;
3344 - di = (size_t)&vminfo;
3345 -- asm(INT10
3346 -+ asm volatile(INT10
3347 - : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
3348 - : : "ebx", "edx", "esi");
3349 -
3350 -@@ -123,7 +123,7 @@ static int vesa_set_mode(struct mode_inf
3351 - ax = 0x4f01;
3352 - cx = vesa_mode;
3353 - di = (size_t)&vminfo;
3354 -- asm(INT10
3355 -+ asm volatile(INT10
3356 - : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
3357 - : : "ebx", "edx", "esi");
3358 -
3359 -@@ -203,19 +203,20 @@ static void vesa_dac_set_8bits(void)
3360 - /* Save the VESA protected mode info */
3361 - static void vesa_store_pm_info(void)
3362 - {
3363 -- u16 ax, bx, di, es;
3364 -+ u16 ax, bx, cx, di, es;
3365 -
3366 - ax = 0x4f0a;
3367 -- bx = di = 0;
3368 -- asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
3369 -- : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
3370 -- : : "ecx", "esi");
3371 -+ bx = cx = di = 0;
3372 -+ asm volatile("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
3373 -+ : "=d" (es), "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di)
3374 -+ : : "esi");
3375 -
3376 - if (ax != 0x004f)
3377 - return;
3378 -
3379 - boot_params.screen_info.vesapm_seg = es;
3380 - boot_params.screen_info.vesapm_off = di;
3381 -+ boot_params.screen_info.vesapm_size = cx;
3382 - }
3383 -
3384 - /*
3385 -@@ -269,7 +270,7 @@ void vesa_store_edid(void)
3386 - /* Note: The VBE DDC spec is different from the main VESA spec;
3387 - we genuinely have to assume all registers are destroyed here. */
3388 -
3389 -- asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
3390 -+ asm volatile("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
3391 - : "+a" (ax), "+b" (bx)
3392 - : "c" (cx), "D" (di)
3393 - : "esi");
3394 -@@ -285,7 +286,7 @@ void vesa_store_edid(void)
3395 - cx = 0; /* Controller 0 */
3396 - dx = 0; /* EDID block number */
3397 - di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
3398 -- asm(INT10
3399 -+ asm volatile(INT10
3400 - : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info)
3401 - : "c" (cx), "D" (di)
3402 - : "esi");
3403 -diff -urNp linux-2.6.27.6/arch/x86/boot/video-vga.c linux-2.6.27.6/arch/x86/boot/video-vga.c
3404 ---- linux-2.6.27.6/arch/x86/boot/video-vga.c 2008-11-07 12:55:34.000000000 -0500
3405 -+++ linux-2.6.27.6/arch/x86/boot/video-vga.c 2008-11-18 03:38:44.000000000 -0500
3406 -@@ -225,7 +225,7 @@ static int vga_probe(void)
3407 - };
3408 - u8 vga_flag;
3409 -
3410 -- asm(INT10
3411 -+ asm volatile(INT10
3412 - : "=b" (ega_bx)
3413 - : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
3414 - : "ecx", "edx", "esi", "edi");
3415 -@@ -237,7 +237,7 @@ static int vga_probe(void)
3416 - /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
3417 - if ((u8)ega_bx != 0x10) {
3418 - /* EGA/VGA */
3419 -- asm(INT10
3420 -+ asm volatile(INT10
3421 - : "=a" (vga_flag)
3422 - : "a" (0x1a00)
3423 - : "ebx", "ecx", "edx", "esi", "edi");
3424 -diff -urNp linux-2.6.27.6/arch/x86/boot/voyager.c linux-2.6.27.6/arch/x86/boot/voyager.c
3425 ---- linux-2.6.27.6/arch/x86/boot/voyager.c 2008-11-07 12:55:34.000000000 -0500
3426 -+++ linux-2.6.27.6/arch/x86/boot/voyager.c 2008-11-18 03:38:44.000000000 -0500
3427 -@@ -23,7 +23,7 @@ int query_voyager(void)
3428 -
3429 - data_ptr[0] = 0xff; /* Flag on config not found(?) */
3430 -
3431 -- asm("pushw %%es ; "
3432 -+ asm volatile("pushw %%es ; "
3433 - "int $0x15 ; "
3434 - "setc %0 ; "
3435 - "movw %%es, %1 ; "
3436 -diff -urNp linux-2.6.27.6/arch/x86/ia32/ia32_signal.c linux-2.6.27.6/arch/x86/ia32/ia32_signal.c
3437 ---- linux-2.6.27.6/arch/x86/ia32/ia32_signal.c 2008-11-07 12:55:34.000000000 -0500
3438 -+++ linux-2.6.27.6/arch/x86/ia32/ia32_signal.c 2008-11-18 03:38:44.000000000 -0500
3439 -@@ -535,6 +535,7 @@ int ia32_setup_rt_frame(int sig, struct
3440 - __NR_ia32_rt_sigreturn,
3441 - 0x80cd,
3442 - 0,
3443 -+ 0
3444 - };
3445 -
3446 - frame = get_sigframe(ka, regs, sizeof(*frame));
3447 -diff -urNp linux-2.6.27.6/arch/x86/Kconfig linux-2.6.27.6/arch/x86/Kconfig
3448 ---- linux-2.6.27.6/arch/x86/Kconfig 2008-11-17 20:03:30.000000000 -0500
3449 -+++ linux-2.6.27.6/arch/x86/Kconfig 2008-11-18 03:38:44.000000000 -0500
3450 -@@ -912,7 +912,7 @@ config PAGE_OFFSET
3451 - hex
3452 - default 0xB0000000 if VMSPLIT_3G_OPT
3453 - default 0x80000000 if VMSPLIT_2G
3454 -- default 0x78000000 if VMSPLIT_2G_OPT
3455 -+ default 0x70000000 if VMSPLIT_2G_OPT
3456 - default 0x40000000 if VMSPLIT_1G
3457 - default 0xC0000000
3458 - depends on X86_32
3459 -@@ -1293,8 +1293,7 @@ config KEXEC_JUMP
3460 - config PHYSICAL_START
3461 - hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
3462 - default "0x1000000" if X86_NUMAQ
3463 -- default "0x200000" if X86_64
3464 -- default "0x100000"
3465 -+ default "0x200000"
3466 - help
3467 - This gives the physical address where the kernel is loaded.
3468 -
3469 -@@ -1386,9 +1385,9 @@ config HOTPLUG_CPU
3470 - suspend.
3471 -
3472 - config COMPAT_VDSO
3473 -- def_bool y
3474 -+ def_bool n
3475 - prompt "Compat VDSO support"
3476 -- depends on X86_32 || IA32_EMULATION
3477 -+ depends on (X86_32 || IA32_EMULATION) && !PAX_NOEXEC
3478 - help
3479 - Map the 32-bit VDSO to the predictable old-style address too.
3480 - ---help---
3481 -diff -urNp linux-2.6.27.6/arch/x86/Kconfig.cpu linux-2.6.27.6/arch/x86/Kconfig.cpu
3482 ---- linux-2.6.27.6/arch/x86/Kconfig.cpu 2008-11-07 12:55:34.000000000 -0500
3483 -+++ linux-2.6.27.6/arch/x86/Kconfig.cpu 2008-11-18 03:38:44.000000000 -0500
3484 -@@ -340,7 +340,7 @@ config X86_PPRO_FENCE
3485 -
3486 - config X86_F00F_BUG
3487 - def_bool y
3488 -- depends on M586MMX || M586TSC || M586 || M486 || M386
3489 -+ depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
3490 -
3491 - config X86_WP_WORKS_OK
3492 - def_bool y
3493 -@@ -360,7 +360,7 @@ config X86_POPAD_OK
3494 -
3495 - config X86_ALIGNMENT_16
3496 - def_bool y
3497 -- depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
3498 -+ depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MCORE2 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
3499 -
3500 - config X86_INTEL_USERCOPY
3501 - def_bool y
3502 -@@ -406,7 +406,7 @@ config X86_CMPXCHG64
3503 - # generates cmov.
3504 - config X86_CMOV
3505 - def_bool y
3506 -- depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || X86_64)
3507 -+ depends on (MK8 || MK7 || MCORE2 || MPSC || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || X86_64)
3508 -
3509 - config X86_MINIMUM_CPU_FAMILY
3510 - int
3511 -diff -urNp linux-2.6.27.6/arch/x86/Kconfig.debug linux-2.6.27.6/arch/x86/Kconfig.debug
3512 ---- linux-2.6.27.6/arch/x86/Kconfig.debug 2008-11-07 12:55:34.000000000 -0500
3513 -+++ linux-2.6.27.6/arch/x86/Kconfig.debug 2008-11-18 03:38:44.000000000 -0500
3514 -@@ -94,7 +94,7 @@ config X86_PTDUMP
3515 - config DEBUG_RODATA
3516 - bool "Write protect kernel read-only data structures"
3517 - default y
3518 -- depends on DEBUG_KERNEL
3519 -+ depends on DEBUG_KERNEL && BROKEN
3520 - help
3521 - Mark the kernel read-only data as write-protected in the pagetables,
3522 - in order to catch accidental (and incorrect) writes to such const
3523 -diff -urNp linux-2.6.27.6/arch/x86/kernel/acpi/boot.c linux-2.6.27.6/arch/x86/kernel/acpi/boot.c
3524 ---- linux-2.6.27.6/arch/x86/kernel/acpi/boot.c 2008-11-07 12:55:34.000000000 -0500
3525 -+++ linux-2.6.27.6/arch/x86/kernel/acpi/boot.c 2008-11-18 03:38:44.000000000 -0500
3526 -@@ -1635,7 +1635,7 @@ static struct dmi_system_id __initdata a
3527 - DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6715b"),
3528 - },
3529 - },
3530 -- {}
3531 -+ { NULL, NULL, {{0, NULL}}, NULL}
3532 - };
3533 -
3534 - /*
3535 -diff -urNp linux-2.6.27.6/arch/x86/kernel/acpi/realmode/wakeup.S linux-2.6.27.6/arch/x86/kernel/acpi/realmode/wakeup.S
3536 ---- linux-2.6.27.6/arch/x86/kernel/acpi/realmode/wakeup.S 2008-11-07 12:55:34.000000000 -0500
3537 -+++ linux-2.6.27.6/arch/x86/kernel/acpi/realmode/wakeup.S 2008-11-18 03:38:44.000000000 -0500
3538 -@@ -104,7 +104,7 @@ _start:
3539 - movl %eax, %ecx
3540 - orl %edx, %ecx
3541 - jz 1f
3542 -- movl $0xc0000080, %ecx
3543 -+ mov $MSR_EFER, %ecx
3544 - wrmsr
3545 - 1:
3546 -
3547 -diff -urNp linux-2.6.27.6/arch/x86/kernel/acpi/sleep.c linux-2.6.27.6/arch/x86/kernel/acpi/sleep.c
3548 ---- linux-2.6.27.6/arch/x86/kernel/acpi/sleep.c 2008-11-07 12:55:34.000000000 -0500
3549 -+++ linux-2.6.27.6/arch/x86/kernel/acpi/sleep.c 2008-11-18 03:38:44.000000000 -0500
3550 -@@ -37,6 +37,10 @@ int acpi_save_state_mem(void)
3551 - {
3552 - struct wakeup_header *header;
3553 -
3554 -+#ifdef CONFIG_PAX_KERNEXEC
3555 -+ unsigned long cr0;
3556 -+#endif
3557 -+
3558 - if (!acpi_realmode) {
3559 - printk(KERN_ERR "Could not allocate memory during boot, "
3560 - "S3 disabled\n");
3561 -@@ -99,8 +103,18 @@ int acpi_save_state_mem(void)
3562 - header->trampoline_segment = setup_trampoline() >> 4;
3563 - #ifdef CONFIG_SMP
3564 - stack_start.sp = temp_stack + 4096;
3565 -+
3566 -+#ifdef CONFIG_PAX_KERNEXEC
3567 -+ pax_open_kernel(cr0);
3568 -+#endif
3569 -+
3570 - early_gdt_descr.address =
3571 - (unsigned long)get_cpu_gdt_table(smp_processor_id());
3572 -+
3573 -+#ifdef CONFIG_PAX_KERNEXEC
3574 -+ pax_close_kernel(cr0);
3575 -+#endif
3576 -+
3577 - #endif
3578 - initial_code = (unsigned long)wakeup_long64;
3579 - saved_magic = 0x123456789abcdef0;
3580 -diff -urNp linux-2.6.27.6/arch/x86/kernel/acpi/wakeup_32.S linux-2.6.27.6/arch/x86/kernel/acpi/wakeup_32.S
3581 ---- linux-2.6.27.6/arch/x86/kernel/acpi/wakeup_32.S 2008-11-07 12:55:34.000000000 -0500
3582 -+++ linux-2.6.27.6/arch/x86/kernel/acpi/wakeup_32.S 2008-11-18 03:38:44.000000000 -0500
3583 -@@ -30,13 +30,11 @@ wakeup_pmode_return:
3584 - # and restore the stack ... but you need gdt for this to work
3585 - movl saved_context_esp, %esp
3586 -
3587 -- movl %cs:saved_magic, %eax
3588 -- cmpl $0x12345678, %eax
3589 -+ cmpl $0x12345678, saved_magic
3590 - jne bogus_magic
3591 -
3592 - # jump to place where we left off
3593 -- movl saved_eip, %eax
3594 -- jmp *%eax
3595 -+ jmp *(saved_eip)
3596 -
3597 - bogus_magic:
3598 - jmp bogus_magic
3599 -diff -urNp linux-2.6.27.6/arch/x86/kernel/alternative.c linux-2.6.27.6/arch/x86/kernel/alternative.c
3600 ---- linux-2.6.27.6/arch/x86/kernel/alternative.c 2008-11-07 12:55:34.000000000 -0500
3601 -+++ linux-2.6.27.6/arch/x86/kernel/alternative.c 2008-11-18 03:38:44.000000000 -0500
3602 -@@ -393,7 +393,7 @@ void apply_paravirt(struct paravirt_patc
3603 -
3604 - BUG_ON(p->len > MAX_PATCH_LEN);
3605 - /* prep the buffer with the original instructions */
3606 -- memcpy(insnbuf, p->instr, p->len);
3607 -+ memcpy(insnbuf, ktla_ktva(p->instr), p->len);
3608 - used = pv_init_ops.patch(p->instrtype, p->clobbers, insnbuf,
3609 - (unsigned long)p->instr, p->len);
3610 -
3611 -@@ -473,11 +473,26 @@ void __init alternative_instructions(voi
3612 - * instructions. And on the local CPU you need to be protected again NMI or MCE
3613 - * handlers seeing an inconsistent instruction while you patch.
3614 - */
3615 --void *text_poke_early(void *addr, const void *opcode, size_t len)
3616 -+void *__kprobes text_poke_early(void *addr, const void *opcode, size_t len)
3617 - {
3618 - unsigned long flags;
3619 -+
3620 -+#ifdef CONFIG_PAX_KERNEXEC
3621 -+ unsigned long cr0;
3622 -+#endif
3623 -+
3624 - local_irq_save(flags);
3625 -- memcpy(addr, opcode, len);
3626 -+
3627 -+#ifdef CONFIG_PAX_KERNEXEC
3628 -+ pax_open_kernel(cr0);
3629 -+#endif
3630 -+
3631 -+ memcpy(ktla_ktva(addr), opcode, len);
3632 -+
3633 -+#ifdef CONFIG_PAX_KERNEXEC
3634 -+ pax_close_kernel(cr0);
3635 -+#endif
3636 -+
3637 - local_irq_restore(flags);
3638 - sync_core();
3639 - /* Could also do a CLFLUSH here to speed up CPU recovery; but
3640 -@@ -498,33 +513,27 @@ void *text_poke_early(void *addr, const
3641 - */
3642 - void *__kprobes text_poke(void *addr, const void *opcode, size_t len)
3643 - {
3644 -- unsigned long flags;
3645 -- char *vaddr;
3646 -- int nr_pages = 2;
3647 -+ unsigned char *vaddr = ktla_ktva(addr);
3648 - struct page *pages[2];
3649 -- int i;
3650 -+ size_t i;
3651 -+
3652 -+ if (!core_kernel_text((unsigned long)addr)
3653 -
3654 -- if (!core_kernel_text((unsigned long)addr)) {
3655 -- pages[0] = vmalloc_to_page(addr);
3656 -- pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
3657 -+#if defined(CONFIG_X86_32) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
3658 -+ && (vaddr < MODULES_VADDR || MODULES_END < vaddr)
3659 -+#endif
3660 -+
3661 -+ ) {
3662 -+ pages[0] = vmalloc_to_page(vaddr);
3663 -+ pages[1] = vmalloc_to_page(vaddr + PAGE_SIZE);
3664 - } else {
3665 -- pages[0] = virt_to_page(addr);
3666 -+ pages[0] = virt_to_page(vaddr);
3667 - WARN_ON(!PageReserved(pages[0]));
3668 -- pages[1] = virt_to_page(addr + PAGE_SIZE);
3669 -+ pages[1] = virt_to_page(vaddr + PAGE_SIZE);
3670 - }
3671 - BUG_ON(!pages[0]);
3672 -- if (!pages[1])
3673 -- nr_pages = 1;
3674 -- vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL);
3675 -- BUG_ON(!vaddr);
3676 -- local_irq_save(flags);
3677 -- memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len);
3678 -- local_irq_restore(flags);
3679 -- vunmap(vaddr);
3680 -- sync_core();
3681 -- /* Could also do a CLFLUSH here to speed up CPU recovery; but
3682 -- that causes hangs on some VIA CPUs. */
3683 -+ text_poke_early(addr, opcode, len);
3684 - for (i = 0; i < len; i++)
3685 -- BUG_ON(((char *)addr)[i] != ((char *)opcode)[i]);
3686 -+ BUG_ON((vaddr)[i] != ((unsigned char *)opcode)[i]);
3687 - return addr;
3688 - }
3689 -diff -urNp linux-2.6.27.6/arch/x86/kernel/apm_32.c linux-2.6.27.6/arch/x86/kernel/apm_32.c
3690 ---- linux-2.6.27.6/arch/x86/kernel/apm_32.c 2008-11-07 12:55:34.000000000 -0500
3691 -+++ linux-2.6.27.6/arch/x86/kernel/apm_32.c 2008-11-18 03:38:44.000000000 -0500
3692 -@@ -408,7 +408,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitq
3693 - static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
3694 - static struct apm_user *user_list;
3695 - static DEFINE_SPINLOCK(user_list_lock);
3696 --static const struct desc_struct bad_bios_desc = { { { 0, 0x00409200 } } };
3697 -+static const struct desc_struct bad_bios_desc = { { { 0, 0x00409300 } } };
3698 -
3699 - static const char driver_version[] = "1.16ac"; /* no spaces */
3700 -
3701 -@@ -603,19 +603,42 @@ static u8 apm_bios_call(u32 func, u32 eb
3702 - struct desc_struct save_desc_40;
3703 - struct desc_struct *gdt;
3704 -
3705 -+#ifdef CONFIG_PAX_KERNEXEC
3706 -+ unsigned long cr0;
3707 -+#endif
3708 -+
3709 - cpus = apm_save_cpus();
3710 -
3711 - cpu = get_cpu();
3712 - gdt = get_cpu_gdt_table(cpu);
3713 - save_desc_40 = gdt[0x40 / 8];
3714 -+
3715 -+#ifdef CONFIG_PAX_KERNEXEC
3716 -+ pax_open_kernel(cr0);
3717 -+#endif
3718 -+
3719 - gdt[0x40 / 8] = bad_bios_desc;
3720 -
3721 -+#ifdef CONFIG_PAX_KERNEXEC
3722 -+ pax_close_kernel(cr0);
3723 -+#endif
3724 -+
3725 - apm_irq_save(flags);
3726 - APM_DO_SAVE_SEGS;
3727 - apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
3728 - APM_DO_RESTORE_SEGS;
3729 - apm_irq_restore(flags);
3730 -+
3731 -+#ifdef CONFIG_PAX_KERNEXEC
3732 -+ pax_open_kernel(cr0);
3733 -+#endif
3734 -+
3735 - gdt[0x40 / 8] = save_desc_40;
3736 -+
3737 -+#ifdef CONFIG_PAX_KERNEXEC
3738 -+ pax_close_kernel(cr0);
3739 -+#endif
3740 -+
3741 - put_cpu();
3742 - apm_restore_cpus(cpus);
3743 -
3744 -@@ -646,19 +669,42 @@ static u8 apm_bios_call_simple(u32 func,
3745 - struct desc_struct save_desc_40;
3746 - struct desc_struct *gdt;
3747 -
3748 -+#ifdef CONFIG_PAX_KERNEXEC
3749 -+ unsigned long cr0;
3750 -+#endif
3751 -+
3752 - cpus = apm_save_cpus();
3753 -
3754 - cpu = get_cpu();
3755 - gdt = get_cpu_gdt_table(cpu);
3756 - save_desc_40 = gdt[0x40 / 8];
3757 -+
3758 -+#ifdef CONFIG_PAX_KERNEXEC
3759 -+ pax_open_kernel(cr0);
3760 -+#endif
3761 -+
3762 - gdt[0x40 / 8] = bad_bios_desc;
3763 -
3764 -+#ifdef CONFIG_PAX_KERNEXEC
3765 -+ pax_close_kernel(cr0);
3766 -+#endif
3767 -+
3768 - apm_irq_save(flags);
3769 - APM_DO_SAVE_SEGS;
3770 - error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
3771 - APM_DO_RESTORE_SEGS;
3772 - apm_irq_restore(flags);
3773 -+
3774 -+#ifdef CONFIG_PAX_KERNEXEC
3775 -+ pax_open_kernel(cr0);
3776 -+#endif
3777 -+
3778 - gdt[0x40 / 8] = save_desc_40;
3779 -+
3780 -+#ifdef CONFIG_PAX_KERNEXEC
3781 -+ pax_close_kernel(cr0);
3782 -+#endif
3783 -+
3784 - put_cpu();
3785 - apm_restore_cpus(cpus);
3786 - return error;
3787 -@@ -930,7 +976,7 @@ recalc:
3788 -
3789 - static void apm_power_off(void)
3790 - {
3791 -- unsigned char po_bios_call[] = {
3792 -+ const unsigned char po_bios_call[] = {
3793 - 0xb8, 0x00, 0x10, /* movw $0x1000,ax */
3794 - 0x8e, 0xd0, /* movw ax,ss */
3795 - 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */
3796 -@@ -1877,7 +1923,10 @@ static const struct file_operations apm_
3797 - static struct miscdevice apm_device = {
3798 - APM_MINOR_DEV,
3799 - "apm_bios",
3800 -- &apm_bios_fops
3801 -+ &apm_bios_fops,
3802 -+ {NULL, NULL},
3803 -+ NULL,
3804 -+ NULL
3805 - };
3806 -
3807 -
3808 -@@ -2198,7 +2247,7 @@ static struct dmi_system_id __initdata a
3809 - { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
3810 - },
3811 -
3812 -- { }
3813 -+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
3814 - };
3815 -
3816 - /*
3817 -@@ -2216,6 +2265,10 @@ static int __init apm_init(void)
3818 - struct desc_struct *gdt;
3819 - int err;
3820 -
3821 -+#ifdef CONFIG_PAX_KERNEXEC
3822 -+ unsigned long cr0;
3823 -+#endif
3824 -+
3825 - dmi_check_system(apm_dmi_table);
3826 -
3827 - if (apm_info.bios.version == 0 || paravirt_enabled() || machine_is_olpc()) {
3828 -@@ -2289,9 +2342,18 @@ static int __init apm_init(void)
3829 - * This is for buggy BIOS's that refer to (real mode) segment 0x40
3830 - * even though they are called in protected mode.
3831 - */
3832 -+
3833 -+#ifdef CONFIG_PAX_KERNEXEC
3834 -+ pax_open_kernel(cr0);
3835 -+#endif
3836 -+
3837 - set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
3838 - _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
3839 -
3840 -+#ifdef CONFIG_PAX_KERNEXEC
3841 -+ pax_close_kernel(cr0);
3842 -+#endif
3843 -+
3844 - /*
3845 - * Set up the long jump entry point to the APM BIOS, which is called
3846 - * from inline assembly.
3847 -@@ -2310,6 +2372,11 @@ static int __init apm_init(void)
3848 - * code to that CPU.
3849 - */
3850 - gdt = get_cpu_gdt_table(0);
3851 -+
3852 -+#ifdef CONFIG_PAX_KERNEXEC
3853 -+ pax_open_kernel(cr0);
3854 -+#endif
3855 -+
3856 - set_base(gdt[APM_CS >> 3],
3857 - __va((unsigned long)apm_info.bios.cseg << 4));
3858 - set_base(gdt[APM_CS_16 >> 3],
3859 -@@ -2317,6 +2384,10 @@ static int __init apm_init(void)
3860 - set_base(gdt[APM_DS >> 3],
3861 - __va((unsigned long)apm_info.bios.dseg << 4));
3862 -
3863 -+#ifdef CONFIG_PAX_KERNEXEC
3864 -+ pax_close_kernel(cr0);
3865 -+#endif
3866 -+
3867 - proc_create("apm", 0, NULL, &apm_file_ops);
3868 -
3869 - kapmd_task = kthread_create(apm, NULL, "kapmd");
3870 -diff -urNp linux-2.6.27.6/arch/x86/kernel/asm-offsets_32.c linux-2.6.27.6/arch/x86/kernel/asm-offsets_32.c
3871 ---- linux-2.6.27.6/arch/x86/kernel/asm-offsets_32.c 2008-11-07 12:55:34.000000000 -0500
3872 -+++ linux-2.6.27.6/arch/x86/kernel/asm-offsets_32.c 2008-11-18 03:38:44.000000000 -0500
3873 -@@ -100,6 +100,7 @@ void foo(void)
3874 - DEFINE(PTRS_PER_PTE, PTRS_PER_PTE);
3875 - DEFINE(PTRS_PER_PMD, PTRS_PER_PMD);
3876 - DEFINE(PTRS_PER_PGD, PTRS_PER_PGD);
3877 -+ DEFINE(PERCPU_MODULE_RESERVE, PERCPU_MODULE_RESERVE);
3878 -
3879 - OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
3880 -
3881 -@@ -113,6 +114,7 @@ void foo(void)
3882 - OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
3883 - OFFSET(PV_CPU_irq_enable_sysexit, pv_cpu_ops, irq_enable_sysexit);
3884 - OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
3885 -+ OFFSET(PV_CPU_write_cr0, pv_cpu_ops, write_cr0);
3886 - #endif
3887 -
3888 - #ifdef CONFIG_XEN
3889 -diff -urNp linux-2.6.27.6/arch/x86/kernel/asm-offsets_64.c linux-2.6.27.6/arch/x86/kernel/asm-offsets_64.c
3890 ---- linux-2.6.27.6/arch/x86/kernel/asm-offsets_64.c 2008-11-07 12:55:34.000000000 -0500
3891 -+++ linux-2.6.27.6/arch/x86/kernel/asm-offsets_64.c 2008-11-18 03:38:44.000000000 -0500
3892 -@@ -122,6 +122,7 @@ int main(void)
3893 - ENTRY(cr8);
3894 - BLANK();
3895 - #undef ENTRY
3896 -+ DEFINE(TSS_size, sizeof(struct tss_struct));
3897 - DEFINE(TSS_ist, offsetof(struct tss_struct, x86_tss.ist));
3898 - BLANK();
3899 - DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
3900 -diff -urNp linux-2.6.27.6/arch/x86/kernel/cpu/common_64.c linux-2.6.27.6/arch/x86/kernel/cpu/common_64.c
3901 ---- linux-2.6.27.6/arch/x86/kernel/cpu/common_64.c 2008-11-07 12:55:34.000000000 -0500
3902 -+++ linux-2.6.27.6/arch/x86/kernel/cpu/common_64.c 2008-11-18 03:38:44.000000000 -0500
3903 -@@ -37,22 +37,6 @@
3904 -
3905 - #include "cpu.h"
3906 -
3907 --/* We need valid kernel segments for data and code in long mode too
3908 -- * IRET will check the segment types kkeil 2000/10/28
3909 -- * Also sysret mandates a special GDT layout
3910 -- */
3911 --/* The TLS descriptors are currently at a different place compared to i386.
3912 -- Hopefully nobody expects them at a fixed place (Wine?) */
3913 --DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
3914 -- [GDT_ENTRY_KERNEL32_CS] = { { { 0x0000ffff, 0x00cf9b00 } } },
3915 -- [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00af9b00 } } },
3916 -- [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9300 } } },
3917 -- [GDT_ENTRY_DEFAULT_USER32_CS] = { { { 0x0000ffff, 0x00cffb00 } } },
3918 -- [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff300 } } },
3919 -- [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00affb00 } } },
3920 --} };
3921 --EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
3922 --
3923 - __u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
3924 -
3925 - /* Current gdt points %fs at the "master" per-cpu area: after this,
3926 -@@ -457,15 +441,13 @@ cpumask_t cpu_initialized __cpuinitdata
3927 - struct x8664_pda **_cpu_pda __read_mostly;
3928 - EXPORT_SYMBOL(_cpu_pda);
3929 -
3930 --struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
3931 -+struct desc_ptr idt_descr __read_only = { 256 * 16 - 1, (unsigned long) idt_table };
3932 -
3933 - char boot_cpu_stack[IRQSTACKSIZE] __page_aligned_bss;
3934 -
3935 - unsigned long __supported_pte_mask __read_mostly = ~0UL;
3936 - EXPORT_SYMBOL_GPL(__supported_pte_mask);
3937 -
3938 --static int do_not_nx __cpuinitdata;
3939 --
3940 - /* noexec=on|off
3941 - Control non executable mappings for 64bit processes.
3942 -
3943 -@@ -478,9 +460,7 @@ static int __init nonx_setup(char *str)
3944 - return -EINVAL;
3945 - if (!strncmp(str, "on", 2)) {
3946 - __supported_pte_mask |= _PAGE_NX;
3947 -- do_not_nx = 0;
3948 - } else if (!strncmp(str, "off", 3)) {
3949 -- do_not_nx = 1;
3950 - __supported_pte_mask &= ~_PAGE_NX;
3951 - }
3952 - return 0;
3953 -@@ -576,7 +556,7 @@ void __cpuinit check_efer(void)
3954 - unsigned long efer;
3955 -
3956 - rdmsrl(MSR_EFER, efer);
3957 -- if (!(efer & EFER_NX) || do_not_nx)
3958 -+ if (!(efer & EFER_NX))
3959 - __supported_pte_mask &= ~_PAGE_NX;
3960 - }
3961 -
3962 -@@ -598,7 +578,7 @@ DEFINE_PER_CPU(struct orig_ist, orig_ist
3963 - void __cpuinit cpu_init(void)
3964 - {
3965 - int cpu = stack_smp_processor_id();
3966 -- struct tss_struct *t = &per_cpu(init_tss, cpu);
3967 -+ struct tss_struct *t = init_tss + cpu;
3968 - struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu);
3969 - unsigned long v;
3970 - char *estacks = NULL;
3971 -diff -urNp linux-2.6.27.6/arch/x86/kernel/cpu/common.c linux-2.6.27.6/arch/x86/kernel/cpu/common.c
3972 ---- linux-2.6.27.6/arch/x86/kernel/cpu/common.c 2008-11-07 12:55:34.000000000 -0500
3973 -+++ linux-2.6.27.6/arch/x86/kernel/cpu/common.c 2008-11-18 03:38:44.000000000 -0500
3974 -@@ -4,7 +4,6 @@
3975 - #include <linux/smp.h>
3976 - #include <linux/module.h>
3977 - #include <linux/percpu.h>
3978 --#include <linux/bootmem.h>
3979 - #include <asm/processor.h>
3980 - #include <asm/i387.h>
3981 - #include <asm/msr.h>
3982 -@@ -22,42 +21,6 @@
3983 -
3984 - #include "cpu.h"
3985 -
3986 --DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
3987 -- [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } },
3988 -- [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } },
3989 -- [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } },
3990 -- [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } },
3991 -- /*
3992 -- * Segments used for calling PnP BIOS have byte granularity.
3993 -- * They code segments and data segments have fixed 64k limits,
3994 -- * the transfer segment sizes are set at run time.
3995 -- */
3996 -- /* 32-bit code */
3997 -- [GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } },
3998 -- /* 16-bit code */
3999 -- [GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } },
4000 -- /* 16-bit data */
4001 -- [GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } },
4002 -- /* 16-bit data */
4003 -- [GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } },
4004 -- /* 16-bit data */
4005 -- [GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } },
4006 -- /*
4007 -- * The APM segments have byte granularity and their bases
4008 -- * are set at run time. All have 64k limits.
4009 -- */
4010 -- /* 32-bit code */
4011 -- [GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } },
4012 -- /* 16-bit code */
4013 -- [GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } },
4014 -- /* data */
4015 -- [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } },
4016 --
4017 -- [GDT_ENTRY_ESPFIX_SS] = { { { 0x00000000, 0x00c09200 } } },
4018 -- [GDT_ENTRY_PERCPU] = { { { 0x00000000, 0x00000000 } } },
4019 --} };
4020 --EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
4021 --
4022 - __u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
4023 -
4024 - static int cachesize_override __cpuinitdata = -1;
4025 -@@ -493,6 +456,10 @@ static void __cpuinit identify_cpu(struc
4026 - * we do "generic changes."
4027 - */
4028 -
4029 -+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
4030 -+ setup_clear_cpu_cap(X86_FEATURE_SEP);
4031 -+#endif
4032 -+
4033 - /* If the model name is still unset, do table lookup. */
4034 - if (!c->x86_model_id[0]) {
4035 - char *p;
4036 -@@ -629,7 +596,7 @@ static __init int setup_disablecpuid(cha
4037 - }
4038 - __setup("clearcpuid=", setup_disablecpuid);
4039 -
4040 --cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
4041 -+cpumask_t cpu_initialized = CPU_MASK_NONE;
4042 -
4043 - void __init early_cpu_init(void)
4044 - {
4045 -@@ -658,7 +625,7 @@ void switch_to_new_gdt(void)
4046 - {
4047 - struct desc_ptr gdt_descr;
4048 -
4049 -- gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
4050 -+ gdt_descr.address = (unsigned long)get_cpu_gdt_table(smp_processor_id());
4051 - gdt_descr.size = GDT_SIZE - 1;
4052 - load_gdt(&gdt_descr);
4053 - asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory");
4054 -@@ -674,7 +641,7 @@ void __cpuinit cpu_init(void)
4055 - {
4056 - int cpu = smp_processor_id();
4057 - struct task_struct *curr = current;
4058 -- struct tss_struct *t = &per_cpu(init_tss, cpu);
4059 -+ struct tss_struct *t = init_tss + cpu;
4060 - struct thread_struct *thread = &curr->thread;
4061 -
4062 - if (cpu_test_and_set(cpu, cpu_initialized)) {
4063 -@@ -729,7 +696,7 @@ void __cpuinit cpu_init(void)
4064 - }
4065 -
4066 - #ifdef CONFIG_HOTPLUG_CPU
4067 --void __cpuinit cpu_uninit(void)
4068 -+void cpu_uninit(void)
4069 - {
4070 - int cpu = raw_smp_processor_id();
4071 - cpu_clear(cpu, cpu_initialized);
4072 -diff -urNp linux-2.6.27.6/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c linux-2.6.27.6/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
4073 ---- linux-2.6.27.6/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-11-07 12:55:34.000000000 -0500
4074 -+++ linux-2.6.27.6/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-11-18 03:38:44.000000000 -0500
4075 -@@ -560,7 +560,7 @@ static const struct dmi_system_id sw_any
4076 - DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
4077 - },
4078 - },
4079 -- { }
4080 -+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
4081 - };
4082 - #endif
4083 -
4084 -diff -urNp linux-2.6.27.6/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c linux-2.6.27.6/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
4085 ---- linux-2.6.27.6/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2008-11-07 12:55:34.000000000 -0500
4086 -+++ linux-2.6.27.6/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2008-11-18 03:38:44.000000000 -0500
4087 -@@ -225,7 +225,7 @@ static struct cpu_model models[] =
4088 - { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
4089 - { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
4090 -
4091 -- { NULL, }
4092 -+ { NULL, NULL, 0, NULL}
4093 - };
4094 - #undef _BANIAS
4095 - #undef BANIAS
4096 -diff -urNp linux-2.6.27.6/arch/x86/kernel/cpu/intel.c linux-2.6.27.6/arch/x86/kernel/cpu/intel.c
4097 ---- linux-2.6.27.6/arch/x86/kernel/cpu/intel.c 2008-11-07 12:55:34.000000000 -0500
4098 -+++ linux-2.6.27.6/arch/x86/kernel/cpu/intel.c 2008-11-18 03:38:44.000000000 -0500
4099 -@@ -107,7 +107,7 @@ static void __cpuinit trap_init_f00f_bug
4100 - * Update the IDT descriptor and reload the IDT so that
4101 - * it uses the read-only mapped virtual address.
4102 - */
4103 -- idt_descr.address = fix_to_virt(FIX_F00F_IDT);
4104 -+ idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
4105 - load_idt(&idt_descr);
4106 - }
4107 - #endif
4108 -diff -urNp linux-2.6.27.6/arch/x86/kernel/cpu/mcheck/mce_64.c linux-2.6.27.6/arch/x86/kernel/cpu/mcheck/mce_64.c
4109 ---- linux-2.6.27.6/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-11-07 12:55:34.000000000 -0500
4110 -+++ linux-2.6.27.6/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-11-18 03:38:44.000000000 -0500
4111 -@@ -681,6 +681,7 @@ static struct miscdevice mce_log_device
4112 - MISC_MCELOG_MINOR,
4113 - "mcelog",
4114 - &mce_chrdev_ops,
4115 -+ {NULL, NULL}, NULL, NULL
4116 - };
4117 -
4118 - static unsigned long old_cr4 __initdata;
4119 -diff -urNp linux-2.6.27.6/arch/x86/kernel/cpu/mtrr/generic.c linux-2.6.27.6/arch/x86/kernel/cpu/mtrr/generic.c
4120 ---- linux-2.6.27.6/arch/x86/kernel/cpu/mtrr/generic.c 2008-11-07 12:55:34.000000000 -0500
4121 -+++ linux-2.6.27.6/arch/x86/kernel/cpu/mtrr/generic.c 2008-11-18 03:38:44.000000000 -0500
4122 -@@ -31,11 +31,11 @@ static struct fixed_range_block fixed_ra
4123 - { MTRRfix64K_00000_MSR, 1 }, /* one 64k MTRR */
4124 - { MTRRfix16K_80000_MSR, 2 }, /* two 16k MTRRs */
4125 - { MTRRfix4K_C0000_MSR, 8 }, /* eight 4k MTRRs */
4126 -- {}
4127 -+ { 0, 0 }
4128 - };
4129 -
4130 - static unsigned long smp_changes_mask;
4131 --static struct mtrr_state mtrr_state = {};
4132 -+static struct mtrr_state mtrr_state;
4133 - static int mtrr_state_set;
4134 - u64 mtrr_tom2;
4135 -
4136 -diff -urNp linux-2.6.27.6/arch/x86/kernel/crash.c linux-2.6.27.6/arch/x86/kernel/crash.c
4137 ---- linux-2.6.27.6/arch/x86/kernel/crash.c 2008-11-07 12:55:34.000000000 -0500
4138 -+++ linux-2.6.27.6/arch/x86/kernel/crash.c 2008-11-18 03:38:44.000000000 -0500
4139 -@@ -59,7 +59,7 @@ static int crash_nmi_callback(struct not
4140 - local_irq_disable();
4141 -
4142 - #ifdef CONFIG_X86_32
4143 -- if (!user_mode_vm(regs)) {
4144 -+ if (!user_mode(regs)) {
4145 - crash_fixup_ss_esp(&fixed_regs, regs);
4146 - regs = &fixed_regs;
4147 - }
4148 -diff -urNp linux-2.6.27.6/arch/x86/kernel/doublefault_32.c linux-2.6.27.6/arch/x86/kernel/doublefault_32.c
4149 ---- linux-2.6.27.6/arch/x86/kernel/doublefault_32.c 2008-11-07 12:55:34.000000000 -0500
4150 -+++ linux-2.6.27.6/arch/x86/kernel/doublefault_32.c 2008-11-18 03:38:44.000000000 -0500
4151 -@@ -11,7 +11,7 @@
4152 -
4153 - #define DOUBLEFAULT_STACKSIZE (1024)
4154 - static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
4155 --#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
4156 -+#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
4157 -
4158 - #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
4159 -
4160 -@@ -21,7 +21,7 @@ static void doublefault_fn(void)
4161 - unsigned long gdt, tss;
4162 -
4163 - store_gdt(&gdt_desc);
4164 -- gdt = gdt_desc.address;
4165 -+ gdt = (unsigned long)gdt_desc.address;
4166 -
4167 - printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
4168 -
4169 -@@ -60,10 +60,10 @@ struct tss_struct doublefault_tss __cach
4170 - /* 0x2 bit is always set */
4171 - .flags = X86_EFLAGS_SF | 0x2,
4172 - .sp = STACK_START,
4173 -- .es = __USER_DS,
4174 -+ .es = __KERNEL_DS,
4175 - .cs = __KERNEL_CS,
4176 - .ss = __KERNEL_DS,
4177 -- .ds = __USER_DS,
4178 -+ .ds = __KERNEL_DS,
4179 - .fs = __KERNEL_PERCPU,
4180 -
4181 - .__cr3 = __pa(swapper_pg_dir)
4182 -diff -urNp linux-2.6.27.6/arch/x86/kernel/efi_32.c linux-2.6.27.6/arch/x86/kernel/efi_32.c
4183 ---- linux-2.6.27.6/arch/x86/kernel/efi_32.c 2008-11-07 12:55:34.000000000 -0500
4184 -+++ linux-2.6.27.6/arch/x86/kernel/efi_32.c 2008-11-18 03:38:44.000000000 -0500
4185 -@@ -38,70 +38,38 @@
4186 - */
4187 -
4188 - static unsigned long efi_rt_eflags;
4189 --static pgd_t efi_bak_pg_dir_pointer[2];
4190 -+static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS];
4191 -
4192 --void efi_call_phys_prelog(void)
4193 -+void __init efi_call_phys_prelog(void)
4194 - {
4195 -- unsigned long cr4;
4196 -- unsigned long temp;
4197 - struct desc_ptr gdt_descr;
4198 -
4199 - local_irq_save(efi_rt_eflags);
4200 -
4201 -- /*
4202 -- * If I don't have PAE, I should just duplicate two entries in page
4203 -- * directory. If I have PAE, I just need to duplicate one entry in
4204 -- * page directory.
4205 -- */
4206 -- cr4 = read_cr4_safe();
4207 -
4208 -- if (cr4 & X86_CR4_PAE) {
4209 -- efi_bak_pg_dir_pointer[0].pgd =
4210 -- swapper_pg_dir[pgd_index(0)].pgd;
4211 -- swapper_pg_dir[0].pgd =
4212 -- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
4213 -- } else {
4214 -- efi_bak_pg_dir_pointer[0].pgd =
4215 -- swapper_pg_dir[pgd_index(0)].pgd;
4216 -- efi_bak_pg_dir_pointer[1].pgd =
4217 -- swapper_pg_dir[pgd_index(0x400000)].pgd;
4218 -- swapper_pg_dir[pgd_index(0)].pgd =
4219 -- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
4220 -- temp = PAGE_OFFSET + 0x400000;
4221 -- swapper_pg_dir[pgd_index(0x400000)].pgd =
4222 -- swapper_pg_dir[pgd_index(temp)].pgd;
4223 -- }
4224 -+ clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
4225 -+ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
4226 -+ min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
4227 -
4228 - /*
4229 - * After the lock is released, the original page table is restored.
4230 - */
4231 - __flush_tlb_all();
4232 -
4233 -- gdt_descr.address = __pa(get_cpu_gdt_table(0));
4234 -+ gdt_descr.address = (struct desc_struct *)__pa(get_cpu_gdt_table(0));
4235 - gdt_descr.size = GDT_SIZE - 1;
4236 - load_gdt(&gdt_descr);
4237 - }
4238 -
4239 --void efi_call_phys_epilog(void)
4240 -+void __init efi_call_phys_epilog(void)
4241 - {
4242 -- unsigned long cr4;
4243 - struct desc_ptr gdt_descr;
4244 -
4245 -- gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
4246 -+ gdt_descr.address = get_cpu_gdt_table(0);
4247 - gdt_descr.size = GDT_SIZE - 1;
4248 - load_gdt(&gdt_descr);
4249 -
4250 -- cr4 = read_cr4_safe();
4251 --
4252 -- if (cr4 & X86_CR4_PAE) {
4253 -- swapper_pg_dir[pgd_index(0)].pgd =
4254 -- efi_bak_pg_dir_pointer[0].pgd;
4255 -- } else {
4256 -- swapper_pg_dir[pgd_index(0)].pgd =
4257 -- efi_bak_pg_dir_pointer[0].pgd;
4258 -- swapper_pg_dir[pgd_index(0x400000)].pgd =
4259 -- efi_bak_pg_dir_pointer[1].pgd;
4260 -- }
4261 -+ clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
4262 -
4263 - /*
4264 - * After the lock is released, the original page table is restored.
4265 -diff -urNp linux-2.6.27.6/arch/x86/kernel/efi_stub_32.S linux-2.6.27.6/arch/x86/kernel/efi_stub_32.S
4266 ---- linux-2.6.27.6/arch/x86/kernel/efi_stub_32.S 2008-11-07 12:55:34.000000000 -0500
4267 -+++ linux-2.6.27.6/arch/x86/kernel/efi_stub_32.S 2008-11-18 03:38:44.000000000 -0500
4268 -@@ -6,6 +6,7 @@
4269 - */
4270 -
4271 - #include <linux/linkage.h>
4272 -+#include <linux/init.h>
4273 - #include <asm/page.h>
4274 -
4275 - /*
4276 -@@ -20,7 +21,7 @@
4277 - * service functions will comply with gcc calling convention, too.
4278 - */
4279 -
4280 --.text
4281 -+__INIT
4282 - ENTRY(efi_call_phys)
4283 - /*
4284 - * 0. The function can only be called in Linux kernel. So CS has been
4285 -@@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
4286 - * The mapping of lower virtual memory has been created in prelog and
4287 - * epilog.
4288 - */
4289 -- movl $1f, %edx
4290 -- subl $__PAGE_OFFSET, %edx
4291 -- jmp *%edx
4292 -+ jmp 1f-__PAGE_OFFSET
4293 - 1:
4294 -
4295 - /*
4296 -@@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
4297 - * parameter 2, ..., param n. To make things easy, we save the return
4298 - * address of efi_call_phys in a global variable.
4299 - */
4300 -- popl %edx
4301 -- movl %edx, saved_return_addr
4302 -- /* get the function pointer into ECX*/
4303 -- popl %ecx
4304 -- movl %ecx, efi_rt_function_ptr
4305 -- movl $2f, %edx
4306 -- subl $__PAGE_OFFSET, %edx
4307 -- pushl %edx
4308 -+ popl (saved_return_addr)
4309 -+ popl (efi_rt_function_ptr)
4310 -
4311 - /*
4312 - * 3. Clear PG bit in %CR0.
4313 -@@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
4314 - /*
4315 - * 5. Call the physical function.
4316 - */
4317 -- jmp *%ecx
4318 -+ call *(efi_rt_function_ptr-__PAGE_OFFSET)
4319 -
4320 --2:
4321 - /*
4322 - * 6. After EFI runtime service returns, control will return to
4323 - * following instruction. We'd better readjust stack pointer first.
4324 -@@ -88,34 +80,27 @@ ENTRY(efi_call_phys)
4325 - movl %cr0, %edx
4326 - orl $0x80000000, %edx
4327 - movl %edx, %cr0
4328 -- jmp 1f
4329 --1:
4330 -+
4331 - /*
4332 - * 8. Now restore the virtual mode from flat mode by
4333 - * adding EIP with PAGE_OFFSET.
4334 - */
4335 -- movl $1f, %edx
4336 -- jmp *%edx
4337 -+ jmp 1f+__PAGE_OFFSET
4338 - 1:
4339 -
4340 - /*
4341 - * 9. Balance the stack. And because EAX contain the return value,
4342 - * we'd better not clobber it.
4343 - */
4344 -- leal efi_rt_function_ptr, %edx
4345 -- movl (%edx), %ecx
4346 -- pushl %ecx
4347 -+ pushl (efi_rt_function_ptr)
4348 -
4349 - /*
4350 -- * 10. Push the saved return address onto the stack and return.
4351 -+ * 10. Return to the saved return address.
4352 - */
4353 -- leal saved_return_addr, %edx
4354 -- movl (%edx), %ecx
4355 -- pushl %ecx
4356 -- ret
4357 -+ jmpl *(saved_return_addr)
4358 - .previous
4359 -
4360 --.data
4361 -+__INITDATA
4362 - saved_return_addr:
4363 - .long 0
4364 - efi_rt_function_ptr:
4365 -diff -urNp linux-2.6.27.6/arch/x86/kernel/entry_32.S linux-2.6.27.6/arch/x86/kernel/entry_32.S
4366 ---- linux-2.6.27.6/arch/x86/kernel/entry_32.S 2008-11-07 12:55:34.000000000 -0500
4367 -+++ linux-2.6.27.6/arch/x86/kernel/entry_32.S 2008-11-18 03:38:44.000000000 -0500
4368 -@@ -101,7 +101,7 @@
4369 - #define resume_userspace_sig resume_userspace
4370 - #endif
4371 -
4372 --#define SAVE_ALL \
4373 -+#define __SAVE_ALL(_DS) \
4374 - cld; \
4375 - pushl %fs; \
4376 - CFI_ADJUST_CFA_OFFSET 4;\
4377 -@@ -133,12 +133,26 @@
4378 - pushl %ebx; \
4379 - CFI_ADJUST_CFA_OFFSET 4;\
4380 - CFI_REL_OFFSET ebx, 0;\
4381 -- movl $(__USER_DS), %edx; \
4382 -+ movl $(_DS), %edx; \
4383 - movl %edx, %ds; \
4384 - movl %edx, %es; \
4385 - movl $(__KERNEL_PERCPU), %edx; \
4386 - movl %edx, %fs
4387 -
4388 -+#ifdef CONFIG_PAX_KERNEXEC
4389 -+#define SAVE_ALL \
4390 -+ __SAVE_ALL(__KERNEL_DS); \
4391 -+ GET_CR0_INTO_EDX; \
4392 -+ movl %edx, %esi; \
4393 -+ orl $X86_CR0_WP, %edx; \
4394 -+ xorl %edx, %esi; \
4395 -+ SET_CR0_FROM_EDX
4396 -+#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
4397 -+#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
4398 -+#else
4399 -+#define SAVE_ALL __SAVE_ALL(__USER_DS)
4400 -+#endif
4401 -+
4402 - #define RESTORE_INT_REGS \
4403 - popl %ebx; \
4404 - CFI_ADJUST_CFA_OFFSET -4;\
4405 -@@ -229,6 +243,11 @@ ENTRY(ret_from_fork)
4406 - CFI_ADJUST_CFA_OFFSET 4
4407 - popfl
4408 - CFI_ADJUST_CFA_OFFSET -4
4409 -+
4410 -+#ifdef CONFIG_PAX_KERNEXEC
4411 -+ xorl %esi, %esi
4412 -+#endif
4413 -+
4414 - jmp syscall_exit
4415 - CFI_ENDPROC
4416 - END(ret_from_fork)
4417 -@@ -252,7 +271,17 @@ check_userspace:
4418 - movb PT_CS(%esp), %al
4419 - andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax
4420 - cmpl $USER_RPL, %eax
4421 -+
4422 -+#ifdef CONFIG_PAX_KERNEXEC
4423 -+ jae resume_userspace
4424 -+
4425 -+ GET_CR0_INTO_EDX
4426 -+ xorl %esi, %edx
4427 -+ SET_CR0_FROM_EDX
4428 -+ jmp resume_kernel
4429 -+#else
4430 - jb resume_kernel # not returning to v8086 or userspace
4431 -+#endif
4432 -
4433 - ENTRY(resume_userspace)
4434 - LOCKDEP_SYS_EXIT
4435 -@@ -314,10 +343,9 @@ sysenter_past_esp:
4436 - /*CFI_REL_OFFSET cs, 0*/
4437 - /*
4438 - * Push current_thread_info()->sysenter_return to the stack.
4439 -- * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
4440 -- * pushed above; +8 corresponds to copy_thread's esp0 setting.
4441 - */
4442 -- pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
4443 -+ GET_THREAD_INFO(%ebp)
4444 -+ pushl TI_sysenter_return(%ebp)
4445 - CFI_ADJUST_CFA_OFFSET 4
4446 - CFI_REL_OFFSET eip, 0
4447 -
4448 -@@ -330,9 +358,17 @@ sysenter_past_esp:
4449 - * Load the potential sixth argument from user stack.
4450 - * Careful about security.
4451 - */
4452 -+ movl PT_OLDESP(%esp),%ebp
4453 -+
4454 -+#ifdef CONFIG_PAX_MEMORY_UDEREF
4455 -+ mov PT_OLDSS(%esp),%ds
4456 -+1: movl %ds:(%ebp),%ebp
4457 -+#else
4458 - cmpl $__PAGE_OFFSET-3,%ebp
4459 - jae syscall_fault
4460 - 1: movl (%ebp),%ebp
4461 -+#endif
4462 -+
4463 - movl %ebp,PT_EBP(%esp)
4464 - .section __ex_table,"a"
4465 - .align 4
4466 -@@ -356,12 +392,23 @@ sysenter_do_call:
4467 - testw $_TIF_ALLWORK_MASK, %cx
4468 - jne sysexit_audit
4469 - sysenter_exit:
4470 -+
4471 -+#ifdef CONFIG_PAX_RANDKSTACK
4472 -+ pushl %eax
4473 -+ CFI_ADJUST_CFA_OFFSET 4
4474 -+ call pax_randomize_kstack
4475 -+ popl %eax
4476 -+ CFI_ADJUST_CFA_OFFSET -4
4477 -+#endif
4478 -+
4479 - /* if something modifies registers it must also disable sysexit */
4480 - movl PT_EIP(%esp), %edx
4481 - movl PT_OLDESP(%esp), %ecx
4482 - xorl %ebp,%ebp
4483 - TRACE_IRQS_ON
4484 - 1: mov PT_FS(%esp), %fs
4485 -+2: mov PT_DS(%esp), %ds
4486 -+3: mov PT_ES(%esp), %es
4487 - ENABLE_INTERRUPTS_SYSEXIT
4488 -
4489 - #ifdef CONFIG_AUDITSYSCALL
4490 -@@ -404,11 +451,17 @@ sysexit_audit:
4491 -
4492 - CFI_ENDPROC
4493 - .pushsection .fixup,"ax"
4494 --2: movl $0,PT_FS(%esp)
4495 -+4: movl $0,PT_FS(%esp)
4496 -+ jmp 1b
4497 -+5: movl $0,PT_DS(%esp)
4498 -+ jmp 1b
4499 -+6: movl $0,PT_ES(%esp)
4500 - jmp 1b
4501 - .section __ex_table,"a"
4502 - .align 4
4503 -- .long 1b,2b
4504 -+ .long 1b,4b
4505 -+ .long 2b,5b
4506 -+ .long 3b,6b
4507 - .popsection
4508 - ENDPROC(ia32_sysenter_target)
4509 -
4510 -@@ -438,6 +491,10 @@ syscall_exit:
4511 - testw $_TIF_ALLWORK_MASK, %cx # current->work
4512 - jne syscall_exit_work
4513 -
4514 -+#ifdef CONFIG_PAX_RANDKSTACK
4515 -+ call pax_randomize_kstack
4516 -+#endif
4517 -+
4518 - restore_all:
4519 - movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
4520 - # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
4521 -@@ -531,25 +588,19 @@ work_resched:
4522 -
4523 - work_notifysig: # deal with pending signals and
4524 - # notify-resume requests
4525 -+ movl %esp, %eax
4526 - #ifdef CONFIG_VM86
4527 - testl $X86_EFLAGS_VM, PT_EFLAGS(%esp)
4528 -- movl %esp, %eax
4529 -- jne work_notifysig_v86 # returning to kernel-space or
4530 -+ jz 1f # returning to kernel-space or
4531 - # vm86-space
4532 -- xorl %edx, %edx
4533 -- call do_notify_resume
4534 -- jmp resume_userspace_sig
4535 -
4536 -- ALIGN
4537 --work_notifysig_v86:
4538 - pushl %ecx # save ti_flags for do_notify_resume
4539 - CFI_ADJUST_CFA_OFFSET 4
4540 - call save_v86_state # %eax contains pt_regs pointer
4541 - popl %ecx
4542 - CFI_ADJUST_CFA_OFFSET -4
4543 - movl %eax, %esp
4544 --#else
4545 -- movl %esp, %eax
4546 -+1:
4547 - #endif
4548 - xorl %edx, %edx
4549 - call do_notify_resume
4550 -@@ -595,17 +646,24 @@ syscall_badsys:
4551 - END(syscall_badsys)
4552 - CFI_ENDPROC
4553 -
4554 --#define FIXUP_ESPFIX_STACK \
4555 -- /* since we are on a wrong stack, we cant make it a C code :( */ \
4556 -- PER_CPU(gdt_page, %ebx); \
4557 -- GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \
4558 -- addl %esp, %eax; \
4559 -- pushl $__KERNEL_DS; \
4560 -- CFI_ADJUST_CFA_OFFSET 4; \
4561 -- pushl %eax; \
4562 -- CFI_ADJUST_CFA_OFFSET 4; \
4563 -- lss (%esp), %esp; \
4564 -+.macro FIXUP_ESPFIX_STACK
4565 -+ /* since we are on a wrong stack, we cant make it a C code :( */
4566 -+#ifdef CONFIG_SMP
4567 -+ movl PER_CPU_VAR(cpu_number), %ebx;
4568 -+ shll $PAGE_SHIFT_asm, %ebx;
4569 -+ addl $cpu_gdt_table, %ebx;
4570 -+#else
4571 -+ movl $cpu_gdt_table, %ebx;
4572 -+#endif
4573 -+ GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah);
4574 -+ addl %esp, %eax;
4575 -+ pushl $__KERNEL_DS;
4576 -+ CFI_ADJUST_CFA_OFFSET 4;
4577 -+ pushl %eax;
4578 -+ CFI_ADJUST_CFA_OFFSET 4;
4579 -+ lss (%esp), %esp;
4580 - CFI_ADJUST_CFA_OFFSET -8;
4581 -+.endm
4582 - #define UNWIND_ESPFIX_STACK \
4583 - movl %ss, %eax; \
4584 - /* see if on espfix stack */ \
4585 -@@ -622,7 +680,7 @@ END(syscall_badsys)
4586 - * Build the entry stubs and pointer table with
4587 - * some assembler magic.
4588 - */
4589 --.section .rodata,"a"
4590 -+.section .rodata,"a",@progbits
4591 - ENTRY(interrupt)
4592 - .text
4593 -
4594 -@@ -722,12 +780,21 @@ error_code:
4595 - popl %ecx
4596 - CFI_ADJUST_CFA_OFFSET -4
4597 - /*CFI_REGISTER es, ecx*/
4598 -+
4599 -+#ifdef CONFIG_PAX_KERNEXEC
4600 -+ GET_CR0_INTO_EDX
4601 -+ movl %edx, %esi
4602 -+ orl $X86_CR0_WP, %edx
4603 -+ xorl %edx, %esi
4604 -+ SET_CR0_FROM_EDX
4605 -+#endif
4606 -+
4607 - movl PT_FS(%esp), %edi # get the function address
4608 - movl PT_ORIG_EAX(%esp), %edx # get the error code
4609 - movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
4610 - mov %ecx, PT_FS(%esp)
4611 - /*CFI_REL_OFFSET fs, ES*/
4612 -- movl $(__USER_DS), %ecx
4613 -+ movl $(__KERNEL_DS), %ecx
4614 - movl %ecx, %ds
4615 - movl %ecx, %es
4616 - movl %esp,%eax # pt_regs pointer
4617 -@@ -861,6 +928,13 @@ nmi_stack_correct:
4618 - xorl %edx,%edx # zero error code
4619 - movl %esp,%eax # pt_regs pointer
4620 - call do_nmi
4621 -+
4622 -+#ifdef CONFIG_PAX_KERNEXEC
4623 -+ GET_CR0_INTO_EDX
4624 -+ xorl %esi, %edx
4625 -+ SET_CR0_FROM_EDX
4626 -+#endif
4627 -+
4628 - jmp restore_nocheck_notrace
4629 - CFI_ENDPROC
4630 -
4631 -@@ -901,6 +975,13 @@ nmi_espfix_stack:
4632 - FIXUP_ESPFIX_STACK # %eax == %esp
4633 - xorl %edx,%edx # zero error code
4634 - call do_nmi
4635 -+
4636 -+#ifdef CONFIG_PAX_KERNEXEC
4637 -+ GET_CR0_INTO_EDX
4638 -+ xorl %esi, %edx
4639 -+ SET_CR0_FROM_EDX
4640 -+#endif
4641 -+
4642 - RESTORE_REGS
4643 - lss 12+4(%esp), %esp # back to espfix stack
4644 - CFI_ADJUST_CFA_OFFSET -24
4645 -@@ -1226,7 +1307,6 @@ END(mcount)
4646 - #endif /* CONFIG_DYNAMIC_FTRACE */
4647 - #endif /* CONFIG_FTRACE */
4648 -
4649 --.section .rodata,"a"
4650 - #include "syscall_table_32.S"
4651 -
4652 - syscall_table_size=(.-sys_call_table)
4653 -diff -urNp linux-2.6.27.6/arch/x86/kernel/entry_64.S linux-2.6.27.6/arch/x86/kernel/entry_64.S
4654 ---- linux-2.6.27.6/arch/x86/kernel/entry_64.S 2008-11-07 12:55:34.000000000 -0500
4655 -+++ linux-2.6.27.6/arch/x86/kernel/entry_64.S 2008-11-18 03:38:44.000000000 -0500
4656 -@@ -930,17 +930,18 @@ END(spurious_interrupt)
4657 - xorl %ebx,%ebx
4658 - 1:
4659 - .if \ist
4660 -- movq %gs:pda_data_offset, %rbp
4661 -+ imul $TSS_size, %gs:pda_cpunumber, %ebp
4662 -+ lea init_tss(%rbp), %rbp
4663 - .endif
4664 - movq %rsp,%rdi
4665 - movq ORIG_RAX(%rsp),%rsi
4666 - movq $-1,ORIG_RAX(%rsp)
4667 - .if \ist
4668 -- subq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
4669 -+ subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
4670 - .endif
4671 - call \sym
4672 - .if \ist
4673 -- addq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
4674 -+ addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
4675 - .endif
4676 - DISABLE_INTERRUPTS(CLBR_NONE)
4677 - .if \irqtrace
4678 -diff -urNp linux-2.6.27.6/arch/x86/kernel/ftrace.c linux-2.6.27.6/arch/x86/kernel/ftrace.c
4679 ---- linux-2.6.27.6/arch/x86/kernel/ftrace.c 2008-11-07 12:55:34.000000000 -0500
4680 -+++ linux-2.6.27.6/arch/x86/kernel/ftrace.c 2008-11-18 03:38:44.000000000 -0500
4681 -@@ -103,7 +103,7 @@ notrace int ftrace_update_ftrace_func(ft
4682 - unsigned char old[MCOUNT_INSN_SIZE], *new;
4683 - int ret;
4684 -
4685 -- memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE);
4686 -+ memcpy(old, (void *)ktla_ktva((unsigned long)ftrace_call), MCOUNT_INSN_SIZE);
4687 - new = ftrace_call_replace(ip, (unsigned long)func);
4688 - ret = ftrace_modify_code(ip, old, new);
4689 -
4690 -@@ -120,7 +120,7 @@ notrace int ftrace_mcount_set(unsigned l
4691 - * Replace the mcount stub with a pointer to the
4692 - * ip recorder function.
4693 - */
4694 -- memcpy(old, &mcount_call, MCOUNT_INSN_SIZE);
4695 -+ memcpy(old, ktla_ktva(mcount_call), MCOUNT_INSN_SIZE);
4696 - new = ftrace_call_replace(ip, *addr);
4697 - *addr = ftrace_modify_code(ip, old, new);
4698 -
4699 -diff -urNp linux-2.6.27.6/arch/x86/kernel/head32.c linux-2.6.27.6/arch/x86/kernel/head32.c
4700 ---- linux-2.6.27.6/arch/x86/kernel/head32.c 2008-11-07 12:55:34.000000000 -0500
4701 -+++ linux-2.6.27.6/arch/x86/kernel/head32.c 2008-11-18 03:38:44.000000000 -0500
4702 -@@ -12,10 +12,11 @@
4703 - #include <asm/sections.h>
4704 - #include <asm/e820.h>
4705 - #include <asm/bios_ebda.h>
4706 -+#include <asm/boot.h>
4707 -
4708 - void __init i386_start_kernel(void)
4709 - {
4710 -- reserve_early(__pa_symbol(&_text), __pa_symbol(&_end), "TEXT DATA BSS");
4711 -+ reserve_early(LOAD_PHYSICAL_ADDR, __pa_symbol(&_end), "TEXT DATA BSS");
4712 -
4713 - #ifdef CONFIG_BLK_DEV_INITRD
4714 - /* Reserve INITRD */
4715 -diff -urNp linux-2.6.27.6/arch/x86/kernel/head_32.S linux-2.6.27.6/arch/x86/kernel/head_32.S
4716 ---- linux-2.6.27.6/arch/x86/kernel/head_32.S 2008-11-07 12:55:34.000000000 -0500
4717 -+++ linux-2.6.27.6/arch/x86/kernel/head_32.S 2008-11-18 03:38:44.000000000 -0500
4718 -@@ -19,6 +19,7 @@
4719 - #include <asm/asm-offsets.h>
4720 - #include <asm/setup.h>
4721 - #include <asm/processor-flags.h>
4722 -+#include <asm/msr-index.h>
4723 -
4724 - /* Physical address */
4725 - #define pa(X) ((X) - __PAGE_OFFSET)
4726 -@@ -64,17 +65,22 @@ LOW_PAGES = 1<<(32-PAGE_SHIFT_asm)
4727 - LOW_PAGES = LOW_PAGES + 0x1000000
4728 - #endif
4729 -
4730 --#if PTRS_PER_PMD > 1
4731 --PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD
4732 --#else
4733 --PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD)
4734 --#endif
4735 -+PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PTE)
4736 - BOOTBITMAP_SIZE = LOW_PAGES / 8
4737 - ALLOCATOR_SLOP = 4
4738 -
4739 - INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
4740 -
4741 - /*
4742 -+ * Real beginning of normal "text" segment
4743 -+ */
4744 -+ENTRY(stext)
4745 -+ENTRY(_stext)
4746 -+
4747 -+.section .text.startup,"ax",@progbits
4748 -+ ljmp $(__BOOT_CS),$phys_startup_32
4749 -+
4750 -+/*
4751 - * 32-bit kernel entrypoint; only used by the boot CPU. On entry,
4752 - * %esi points to the real-mode code as a 32-bit pointer.
4753 - * CS and DS must be 4 GB flat segments, but we don't depend on
4754 -@@ -82,6 +88,12 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE +
4755 - * can.
4756 - */
4757 - .section .text.head,"ax",@progbits
4758 -+
4759 -+#ifdef CONFIG_PAX_KERNEXEC
4760 -+/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
4761 -+.fill 4096,1,0xcc
4762 -+#endif
4763 -+
4764 - ENTRY(startup_32)
4765 - /* test KEEP_SEGMENTS flag to see if the bootloader is asking
4766 - us to not reload segments */
4767 -@@ -99,6 +111,56 @@ ENTRY(startup_32)
4768 - movl %eax,%gs
4769 - 2:
4770 -
4771 -+ movl $pa(cpu_gdt_table),%edi
4772 -+ movl $__per_cpu_start,%eax
4773 -+ movw %ax,__KERNEL_PERCPU + 2(%edi)
4774 -+ rorl $16,%eax
4775 -+ movb %al,__KERNEL_PERCPU + 4(%edi)
4776 -+ movb %ah,__KERNEL_PERCPU + 7(%edi)
4777 -+ movl $__per_cpu_end + PERCPU_MODULE_RESERVE - 1,%eax
4778 -+ subl $__per_cpu_start,%eax
4779 -+ movw %ax,__KERNEL_PERCPU + 0(%edi)
4780 -+
4781 -+#ifdef CONFIG_PAX_MEMORY_UDEREF
4782 -+ /* check for VMware */
4783 -+ movl $0x564d5868,%eax
4784 -+ xorl %ebx,%ebx
4785 -+ movl $0xa,%ecx
4786 -+ movl $0x5658,%edx
4787 -+ in (%dx),%eax
4788 -+ cmpl $0x564d5868,%ebx
4789 -+ jz 2f
4790 -+
4791 -+ movl $NR_CPUS,%ecx
4792 -+ movl $pa(cpu_gdt_table),%edi
4793 -+1:
4794 -+ movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),GDT_ENTRY_KERNEL_DS * 8 + 4(%edi)
4795 -+ addl $PAGE_SIZE_asm,%edi
4796 -+ loop 1b
4797 -+2:
4798 -+#endif
4799 -+
4800 -+#ifdef CONFIG_PAX_KERNEXEC
4801 -+ movl $pa(boot_gdt),%edi
4802 -+ movl $KERNEL_TEXT_OFFSET,%eax
4803 -+ movw %ax,__BOOT_CS + 2(%edi)
4804 -+ rorl $16,%eax
4805 -+ movb %al,__BOOT_CS + 4(%edi)
4806 -+ movb %ah,__BOOT_CS + 7(%edi)
4807 -+ rorl $16,%eax
4808 -+
4809 -+ movl $NR_CPUS,%ecx
4810 -+ movl $pa(cpu_gdt_table),%edi
4811 -+1:
4812 -+ movw %ax,__KERNEL_CS + 2(%edi)
4813 -+ rorl $16,%eax
4814 -+ movb %al,__KERNEL_CS + 4(%edi)
4815 -+ movb %ah,__KERNEL_CS + 7(%edi)
4816 -+ rorl $16,%eax
4817 -+ addl $PAGE_SIZE_asm,%edi
4818 -+ loop 1b
4819 -+#endif
4820 -+
4821 - /*
4822 - * Clear BSS first so that there are no surprises...
4823 - */
4824 -@@ -142,9 +204,7 @@ ENTRY(startup_32)
4825 - cmpl $num_subarch_entries, %eax
4826 - jae bad_subarch
4827 -
4828 -- movl pa(subarch_entries)(,%eax,4), %eax
4829 -- subl $__PAGE_OFFSET, %eax
4830 -- jmp *%eax
4831 -+ jmp *pa(subarch_entries)(,%eax,4)
4832 -
4833 - bad_subarch:
4834 - WEAK(lguest_entry)
4835 -@@ -156,9 +216,9 @@ WEAK(xen_entry)
4836 - __INITDATA
4837 -
4838 - subarch_entries:
4839 -- .long default_entry /* normal x86/PC */
4840 -- .long lguest_entry /* lguest hypervisor */
4841 -- .long xen_entry /* Xen hypervisor */
4842 -+ .long pa(default_entry) /* normal x86/PC */
4843 -+ .long pa(lguest_entry) /* lguest hypervisor */
4844 -+ .long pa(xen_entry) /* Xen hypervisor */
4845 - num_subarch_entries = (. - subarch_entries) / 4
4846 - .previous
4847 - #endif /* CONFIG_PARAVIRT */
4848 -@@ -172,7 +232,7 @@ num_subarch_entries = (. - subarch_entri
4849 - *
4850 - * Note that the stack is not yet set up!
4851 - */
4852 --#define PTE_ATTR 0x007 /* PRESENT+RW+USER */
4853 -+#define PTE_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
4854 - #define PDE_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
4855 - #define PGD_ATTR 0x001 /* PRESENT (no other attributes) */
4856 -
4857 -@@ -224,8 +284,7 @@ default_entry:
4858 - movl %eax, pa(max_pfn_mapped)
4859 -
4860 - /* Do early initialization of the fixmap area */
4861 -- movl $pa(swapper_pg_fixmap)+PDE_ATTR,%eax
4862 -- movl %eax,pa(swapper_pg_pmd+0x1000*KPMDS-8)
4863 -+ movl $pa(swapper_pg_fixmap)+PDE_ATTR,pa(swapper_pg_pmd+0x1000*KPMDS-8)
4864 - #else /* Not PAE */
4865 -
4866 - page_pde_offset = (__PAGE_OFFSET >> 20);
4867 -@@ -257,8 +316,7 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
4868 - movl %eax, pa(max_pfn_mapped)
4869 -
4870 - /* Do early initialization of the fixmap area */
4871 -- movl $pa(swapper_pg_fixmap)+PDE_ATTR,%eax
4872 -- movl %eax,pa(swapper_pg_dir+0xffc)
4873 -+ movl $pa(swapper_pg_fixmap)+PDE_ATTR,pa(swapper_pg_dir+0xffc)
4874 - #endif
4875 - jmp 3f
4876 - /*
4877 -@@ -322,13 +380,16 @@ ENTRY(startup_32_smp)
4878 - jnc 6f
4879 -
4880 - /* Setup EFER (Extended Feature Enable Register) */
4881 -- movl $0xc0000080, %ecx
4882 -+ movl $MSR_EFER, %ecx
4883 - rdmsr
4884 -
4885 - btsl $11, %eax
4886 - /* Make changes effective */
4887 - wrmsr
4888 -
4889 -+ btsl $63-32,pa(__supported_pte_mask+4)
4890 -+ movl $1,pa(nx_enabled)
4891 -+
4892 - 6:
4893 -
4894 - /*
4895 -@@ -354,9 +415,7 @@ ENTRY(startup_32_smp)
4896 -
4897 - #ifdef CONFIG_SMP
4898 - cmpb $0, ready
4899 -- jz 1f /* Initial CPU cleans BSS */
4900 -- jmp checkCPUtype
4901 --1:
4902 -+ jnz checkCPUtype /* Initial CPU cleans BSS */
4903 - #endif /* CONFIG_SMP */
4904 -
4905 - /*
4906 -@@ -433,12 +492,12 @@ is386: movl $2,%ecx # set MP
4907 - ljmp $(__KERNEL_CS),$1f
4908 - 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
4909 - movl %eax,%ss # after changing gdt.
4910 -- movl %eax,%fs # gets reset once there's real percpu
4911 --
4912 -- movl $(__USER_DS),%eax # DS/ES contains default USER segment
4913 - movl %eax,%ds
4914 - movl %eax,%es
4915 -
4916 -+ movl $(__KERNEL_PERCPU), %eax
4917 -+ movl %eax,%fs # set this cpu's percpu
4918 -+
4919 - xorl %eax,%eax # Clear GS and LDT
4920 - movl %eax,%gs
4921 - lldt %ax
4922 -@@ -448,12 +507,6 @@ is386: movl $2,%ecx # set MP
4923 - #ifdef CONFIG_SMP
4924 - movb ready, %cl
4925 - movb $1, ready
4926 -- cmpb $0,%cl # the first CPU calls start_kernel
4927 -- je 1f
4928 -- movl $(__KERNEL_PERCPU), %eax
4929 -- movl %eax,%fs # set this cpu's percpu
4930 -- movl (stack_start), %esp
4931 --1:
4932 - #endif /* CONFIG_SMP */
4933 - jmp *(initial_code)
4934 -
4935 -@@ -539,15 +592,15 @@ early_page_fault:
4936 - jmp early_fault
4937 -
4938 - early_fault:
4939 -- cld
4940 - #ifdef CONFIG_PRINTK
4941 -+ cmpl $2,%ss:early_recursion_flag
4942 -+ je hlt_loop
4943 -+ incl %ss:early_recursion_flag
4944 -+ cld
4945 - pusha
4946 - movl $(__KERNEL_DS),%eax
4947 - movl %eax,%ds
4948 - movl %eax,%es
4949 -- cmpl $2,early_recursion_flag
4950 -- je hlt_loop
4951 -- incl early_recursion_flag
4952 - movl %cr2,%eax
4953 - pushl %eax
4954 - pushl %edx /* trapno */
4955 -@@ -557,8 +610,8 @@ early_fault:
4956 - #else
4957 - call printk
4958 - #endif
4959 --#endif
4960 - call dump_stack
4961 -+#endif
4962 - hlt_loop:
4963 - hlt
4964 - jmp hlt_loop
4965 -@@ -566,8 +619,11 @@ hlt_loop:
4966 - /* This is the default interrupt "handler" :-) */
4967 - ALIGN
4968 - ignore_int:
4969 -- cld
4970 - #ifdef CONFIG_PRINTK
4971 -+ cmpl $2,%ss:early_recursion_flag
4972 -+ je hlt_loop
4973 -+ incl %ss:early_recursion_flag
4974 -+ cld
4975 - pushl %eax
4976 - pushl %ecx
4977 - pushl %edx
4978 -@@ -576,9 +632,6 @@ ignore_int:
4979 - movl $(__KERNEL_DS),%eax
4980 - movl %eax,%ds
4981 - movl %eax,%es
4982 -- cmpl $2,early_recursion_flag
4983 -- je hlt_loop
4984 -- incl early_recursion_flag
4985 - pushl 16(%esp)
4986 - pushl 24(%esp)
4987 - pushl 32(%esp)
4988 -@@ -603,36 +656,41 @@ ignore_int:
4989 - ENTRY(initial_code)
4990 - .long i386_start_kernel
4991 -
4992 --.section .text
4993 --/*
4994 -- * Real beginning of normal "text" segment
4995 -- */
4996 --ENTRY(stext)
4997 --ENTRY(_stext)
4998 --
4999 - /*
5000 - * BSS section
5001 - */
5002 --.section ".bss.page_aligned","wa"
5003 -- .align PAGE_SIZE_asm
5004 - #ifdef CONFIG_X86_PAE
5005 -+.section .swapper_pg_pmd,"a",@progbits
5006 - swapper_pg_pmd:
5007 - .fill 1024*KPMDS,4,0
5008 - #else
5009 -+.section .swapper_pg_dir,"a",@progbits
5010 - ENTRY(swapper_pg_dir)
5011 - .fill 1024,4,0
5012 - #endif
5013 - swapper_pg_fixmap:
5014 - .fill 1024,4,0
5015 -+
5016 -+.section .empty_zero_page,"a",@progbits
5017 - ENTRY(empty_zero_page)
5018 - .fill 4096,1,0
5019 -+
5020 -+/*
5021 -+ * The IDT has to be page-aligned to simplify the Pentium
5022 -+ * F0 0F bug workaround.. We have a special link segment
5023 -+ * for this.
5024 -+ */
5025 -+.section .idt,"a",@progbits
5026 -+ENTRY(idt_table)
5027 -+ .fill 256,8,0
5028 -+
5029 - /*
5030 - * This starts the data section.
5031 - */
5032 -+.data
5033 -+
5034 - #ifdef CONFIG_X86_PAE
5035 --.section ".data.page_aligned","wa"
5036 -- /* Page-aligned for the benefit of paravirt? */
5037 -- .align PAGE_SIZE_asm
5038 -+.section .swapper_pg_dir,"a",@progbits
5039 - ENTRY(swapper_pg_dir)
5040 - .long pa(swapper_pg_pmd+PGD_ATTR),0 /* low identity map */
5041 - # if KPMDS == 3
5042 -@@ -655,11 +713,12 @@ ENTRY(swapper_pg_dir)
5043 -
5044 - .data
5045 - ENTRY(stack_start)
5046 -- .long init_thread_union+THREAD_SIZE
5047 -+ .long init_thread_union+THREAD_SIZE-8
5048 - .long __BOOT_DS
5049 -
5050 - ready: .byte 0
5051 -
5052 -+.section .rodata,"a",@progbits
5053 - early_recursion_flag:
5054 - .long 0
5055 -
5056 -@@ -695,7 +754,7 @@ fault_msg:
5057 - .word 0 # 32 bit align gdt_desc.address
5058 - boot_gdt_descr:
5059 - .word __BOOT_DS+7
5060 -- .long boot_gdt - __PAGE_OFFSET
5061 -+ .long pa(boot_gdt)
5062 -
5063 - .word 0 # 32-bit align idt_desc.address
5064 - idt_descr:
5065 -@@ -706,7 +765,7 @@ idt_descr:
5066 - .word 0 # 32 bit align gdt_desc.address
5067 - ENTRY(early_gdt_descr)
5068 - .word GDT_ENTRIES*8-1
5069 -- .long per_cpu__gdt_page /* Overwritten for secondary CPUs */
5070 -+ .long cpu_gdt_table /* Overwritten for secondary CPUs */
5071 -
5072 - /*
5073 - * The boot_gdt must mirror the equivalent in setup.S and is
5074 -@@ -715,5 +774,59 @@ ENTRY(early_gdt_descr)
5075 - .align L1_CACHE_BYTES
5076 - ENTRY(boot_gdt)
5077 - .fill GDT_ENTRY_BOOT_CS,8,0
5078 -- .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
5079 -- .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
5080 -+ .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */
5081 -+ .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */
5082 -+
5083 -+ .align PAGE_SIZE_asm
5084 -+ENTRY(cpu_gdt_table)
5085 -+ .rept NR_CPUS
5086 -+ .quad 0x0000000000000000 /* NULL descriptor */
5087 -+ .quad 0x0000000000000000 /* 0x0b reserved */
5088 -+ .quad 0x0000000000000000 /* 0x13 reserved */
5089 -+ .quad 0x0000000000000000 /* 0x1b reserved */
5090 -+ .quad 0x0000000000000000 /* 0x20 unused */
5091 -+ .quad 0x0000000000000000 /* 0x28 unused */
5092 -+ .quad 0x0000000000000000 /* 0x33 TLS entry 1 */
5093 -+ .quad 0x0000000000000000 /* 0x3b TLS entry 2 */
5094 -+ .quad 0x0000000000000000 /* 0x43 TLS entry 3 */
5095 -+ .quad 0x0000000000000000 /* 0x4b reserved */
5096 -+ .quad 0x0000000000000000 /* 0x53 reserved */
5097 -+ .quad 0x0000000000000000 /* 0x5b reserved */
5098 -+
5099 -+ .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
5100 -+ .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
5101 -+ .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */
5102 -+ .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */
5103 -+
5104 -+ .quad 0x0000000000000000 /* 0x80 TSS descriptor */
5105 -+ .quad 0x0000000000000000 /* 0x88 LDT descriptor */
5106 -+
5107 -+ /*
5108 -+ * Segments used for calling PnP BIOS have byte granularity.
5109 -+ * The code segments and data segments have fixed 64k limits,
5110 -+ * the transfer segment sizes are set at run time.
5111 -+ */
5112 -+ .quad 0x00409b000000ffff /* 0x90 32-bit code */
5113 -+ .quad 0x00009b000000ffff /* 0x98 16-bit code */
5114 -+ .quad 0x000093000000ffff /* 0xa0 16-bit data */
5115 -+ .quad 0x0000930000000000 /* 0xa8 16-bit data */
5116 -+ .quad 0x0000930000000000 /* 0xb0 16-bit data */
5117 -+
5118 -+ /*
5119 -+ * The APM segments have byte granularity and their bases
5120 -+ * are set at run time. All have 64k limits.
5121 -+ */
5122 -+ .quad 0x00409b000000ffff /* 0xb8 APM CS code */
5123 -+ .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */
5124 -+ .quad 0x004093000000ffff /* 0xc8 APM DS data */
5125 -+
5126 -+ .quad 0x00c0930000000000 /* 0xd0 - ESPFIX SS */
5127 -+ .quad 0x0040930000000000 /* 0xd8 - PERCPU */
5128 -+ .quad 0x0000000000000000 /* 0xe0 - PCIBIOS_CS */
5129 -+ .quad 0x0000000000000000 /* 0xe8 - PCIBIOS_DS */
5130 -+ .quad 0x0000000000000000 /* 0xf0 - unused */
5131 -+ .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
5132 -+
5133 -+ /* Be sure this is zeroed to avoid false validations in Xen */
5134 -+ .fill PAGE_SIZE_asm - GDT_SIZE,1,0
5135 -+ .endr
5136 -diff -urNp linux-2.6.27.6/arch/x86/kernel/head64.c linux-2.6.27.6/arch/x86/kernel/head64.c
5137 ---- linux-2.6.27.6/arch/x86/kernel/head64.c 2008-11-07 12:55:34.000000000 -0500
5138 -+++ linux-2.6.27.6/arch/x86/kernel/head64.c 2008-11-18 03:38:44.000000000 -0500
5139 -@@ -93,6 +93,8 @@ void __init x86_64_start_kernel(char * r
5140 - /* clear bss before set_intr_gate with early_idt_handler */
5141 - clear_bss();
5142 -
5143 -+ x86_64_init_pda();
5144 -+
5145 - /* Make NULL pointers segfault */
5146 - zap_identity_mappings();
5147 -
5148 -@@ -110,8 +112,6 @@ void __init x86_64_start_kernel(char * r
5149 -
5150 - early_printk("Kernel alive\n");
5151 -
5152 -- x86_64_init_pda();
5153 --
5154 - early_printk("Kernel really alive\n");
5155 -
5156 - x86_64_start_reservations(real_mode_data);
5157 -diff -urNp linux-2.6.27.6/arch/x86/kernel/head_64.S linux-2.6.27.6/arch/x86/kernel/head_64.S
5158 ---- linux-2.6.27.6/arch/x86/kernel/head_64.S 2008-11-07 12:55:34.000000000 -0500
5159 -+++ linux-2.6.27.6/arch/x86/kernel/head_64.S 2008-11-18 03:38:44.000000000 -0500
5160 -@@ -38,6 +38,10 @@ L4_PAGE_OFFSET = pgd_index(__PAGE_OFFSET
5161 - L3_PAGE_OFFSET = pud_index(__PAGE_OFFSET)
5162 - L4_START_KERNEL = pgd_index(__START_KERNEL_map)
5163 - L3_START_KERNEL = pud_index(__START_KERNEL_map)
5164 -+L4_VMALLOC_START = pgd_index(VMALLOC_START)
5165 -+L3_VMALLOC_START = pud_index(VMALLOC_START)
5166 -+L4_VMEMMAP_START = pgd_index(VMEMMAP_START)
5167 -+L3_VMEMMAP_START = pud_index(VMEMMAP_START)
5168 -
5169 - .text
5170 - .section .text.head
5171 -@@ -85,14 +89,17 @@ startup_64:
5172 - */
5173 - addq %rbp, init_level4_pgt + 0(%rip)
5174 - addq %rbp, init_level4_pgt + (L4_PAGE_OFFSET*8)(%rip)
5175 -+ addq %rbp, init_level4_pgt + (L4_VMALLOC_START*8)(%rip)
5176 -+ addq %rbp, init_level4_pgt + (L4_VMEMMAP_START*8)(%rip)
5177 - addq %rbp, init_level4_pgt + (L4_START_KERNEL*8)(%rip)
5178 -
5179 - addq %rbp, level3_ident_pgt + 0(%rip)
5180 -
5181 -- addq %rbp, level3_kernel_pgt + (510*8)(%rip)
5182 -- addq %rbp, level3_kernel_pgt + (511*8)(%rip)
5183 -+ addq %rbp, level3_kernel_pgt + (L3_START_KERNEL*8)(%rip)
5184 -+ addq %rbp, level3_kernel_pgt + (L3_START_KERNEL*8+8)(%rip)
5185 -
5186 - addq %rbp, level2_fixmap_pgt + (506*8)(%rip)
5187 -+ addq %rbp, level2_fixmap_pgt + (507*8)(%rip)
5188 -
5189 - /* Add an Identity mapping if I am above 1G */
5190 - leaq _text(%rip), %rdi
5191 -@@ -187,6 +194,10 @@ ENTRY(secondary_startup_64)
5192 - btl $20,%edi /* No Execute supported? */
5193 - jnc 1f
5194 - btsl $_EFER_NX, %eax
5195 -+ leaq init_level4_pgt(%rip), %rdi
5196 -+ btsq $_PAGE_BIT_NX, 8*L4_PAGE_OFFSET(%rdi)
5197 -+ btsq $_PAGE_BIT_NX, 8*L4_VMALLOC_START(%rdi)
5198 -+ btsq $_PAGE_BIT_NX, 8*L4_VMEMMAP_START(%rdi)
5199 - 1: wrmsr /* Make changes effective */
5200 -
5201 - /* Setup cr0 */
5202 -@@ -257,16 +268,16 @@ ENTRY(secondary_startup_64)
5203 - .align 8
5204 - ENTRY(initial_code)
5205 - .quad x86_64_start_kernel
5206 -- __FINITDATA
5207 -
5208 - ENTRY(stack_start)
5209 - .quad init_thread_union+THREAD_SIZE-8
5210 - .word 0
5211 -+ __FINITDATA
5212 -
5213 - bad_address:
5214 - jmp bad_address
5215 -
5216 -- .section ".init.text","ax"
5217 -+ __INIT
5218 - #ifdef CONFIG_EARLY_PRINTK
5219 - .globl early_idt_handlers
5220 - early_idt_handlers:
5221 -@@ -311,18 +322,23 @@ ENTRY(early_idt_handler)
5222 - #endif /* EARLY_PRINTK */
5223 - 1: hlt
5224 - jmp 1b
5225 -+ .previous
5226 -
5227 - #ifdef CONFIG_EARLY_PRINTK
5228 -+ __INITDATA
5229 - early_recursion_flag:
5230 - .long 0
5231 -+ .previous
5232 -
5233 -+ .section .rodata,"a",@progbits
5234 - early_idt_msg:
5235 - .asciz "PANIC: early exception %02lx rip %lx:%lx error %lx cr2 %lx\n"
5236 - early_idt_ripmsg:
5237 - .asciz "RIP %s\n"
5238 --#endif /* CONFIG_EARLY_PRINTK */
5239 - .previous
5240 -+#endif /* CONFIG_EARLY_PRINTK */
5241 -
5242 -+ .section .rodata,"a",@progbits
5243 - .balign PAGE_SIZE
5244 -
5245 - #define NEXT_PAGE(name) \
5246 -@@ -347,6 +363,10 @@ NEXT_PAGE(init_level4_pgt)
5247 - .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
5248 - .org init_level4_pgt + L4_PAGE_OFFSET*8, 0
5249 - .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
5250 -+ .org init_level4_pgt + L4_VMALLOC_START*8, 0
5251 -+ .quad level3_vmalloc_pgt - __START_KERNEL_map + _KERNPG_TABLE
5252 -+ .org init_level4_pgt + L4_VMEMMAP_START*8, 0
5253 -+ .quad level3_vmemmap_pgt - __START_KERNEL_map + _KERNPG_TABLE
5254 - .org init_level4_pgt + L4_START_KERNEL*8, 0
5255 - /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
5256 - .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE
5257 -@@ -355,6 +375,12 @@ NEXT_PAGE(level3_ident_pgt)
5258 - .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
5259 - .fill 511,8,0
5260 -
5261 -+NEXT_PAGE(level3_vmalloc_pgt)
5262 -+ .fill 512,8,0
5263 -+
5264 -+NEXT_PAGE(level3_vmemmap_pgt)
5265 -+ .fill 512,8,0
5266 -+
5267 - NEXT_PAGE(level3_kernel_pgt)
5268 - .fill L3_START_KERNEL,8,0
5269 - /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */
5270 -@@ -364,12 +390,16 @@ NEXT_PAGE(level3_kernel_pgt)
5271 - NEXT_PAGE(level2_fixmap_pgt)
5272 - .fill 506,8,0
5273 - .quad level1_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE
5274 -- /* 8MB reserved for vsyscalls + a 2MB hole = 4 + 1 entries */
5275 -- .fill 5,8,0
5276 -+ .quad level1_vsyscall_pgt - __START_KERNEL_map + _PAGE_TABLE
5277 -+ /* 6MB reserved for vsyscalls + a 2MB hole = 3 + 1 entries */
5278 -+ .fill 4,8,0
5279 -
5280 - NEXT_PAGE(level1_fixmap_pgt)
5281 - .fill 512,8,0
5282 -
5283 -+NEXT_PAGE(level1_vsyscall_pgt)
5284 -+ .fill 512,8,0
5285 -+
5286 - NEXT_PAGE(level2_ident_pgt)
5287 - /* Since I easily can, map the first 1G.
5288 - * Don't set NX because code runs from these pages.
5289 -@@ -396,19 +426,39 @@ NEXT_PAGE(level2_spare_pgt)
5290 - #undef PMDS
5291 - #undef NEXT_PAGE
5292 -
5293 -- .data
5294 -+ .align PAGE_SIZE
5295 -+ENTRY(cpu_gdt_table)
5296 -+ .rept NR_CPUS
5297 -+ .quad 0x0000000000000000 /* NULL descriptor */
5298 -+ .quad 0x00cf9b000000ffff /* __KERNEL32_CS */
5299 -+ .quad 0x00af9b000000ffff /* __KERNEL_CS */
5300 -+ .quad 0x00cf93000000ffff /* __KERNEL_DS */
5301 -+ .quad 0x00cffb000000ffff /* __USER32_CS */
5302 -+ .quad 0x00cff3000000ffff /* __USER_DS, __USER32_DS */
5303 -+ .quad 0x00affb000000ffff /* __USER_CS */
5304 -+ .quad 0x0 /* unused */
5305 -+ .quad 0,0 /* TSS */
5306 -+ .quad 0,0 /* LDT */
5307 -+ .quad 0,0,0 /* three TLS descriptors */
5308 -+ .quad 0x0000f40000000000 /* node/CPU stored in limit */
5309 -+ /* asm/segment.h:GDT_ENTRIES must match this */
5310 -+
5311 -+ /* zero the remaining page */
5312 -+ .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
5313 -+ .endr
5314 -+
5315 - .align 16
5316 - .globl early_gdt_descr
5317 - early_gdt_descr:
5318 - .word GDT_ENTRIES*8-1
5319 -- .quad per_cpu__gdt_page
5320 -+ .quad cpu_gdt_table
5321 -
5322 - ENTRY(phys_base)
5323 - /* This must match the first entry in level2_kernel_pgt */
5324 - .quad 0x0000000000000000
5325 -
5326 - #include "../../x86/xen/xen-head.S"
5327 --
5328 -+
5329 - .section .bss, "aw", @nobits
5330 - .align L1_CACHE_BYTES
5331 - ENTRY(idt_table)
5332 -diff -urNp linux-2.6.27.6/arch/x86/kernel/i386_ksyms_32.c linux-2.6.27.6/arch/x86/kernel/i386_ksyms_32.c
5333 ---- linux-2.6.27.6/arch/x86/kernel/i386_ksyms_32.c 2008-11-07 12:55:34.000000000 -0500
5334 -+++ linux-2.6.27.6/arch/x86/kernel/i386_ksyms_32.c 2008-11-18 03:38:44.000000000 -0500
5335 -@@ -10,8 +10,12 @@
5336 - EXPORT_SYMBOL(mcount);
5337 - #endif
5338 -
5339 -+EXPORT_SYMBOL_GPL(cpu_gdt_table);
5340 -+
5341 - /* Networking helper routines. */
5342 - EXPORT_SYMBOL(csum_partial_copy_generic);
5343 -+EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
5344 -+EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
5345 -
5346 - EXPORT_SYMBOL(__get_user_1);
5347 - EXPORT_SYMBOL(__get_user_2);
5348 -@@ -26,3 +30,7 @@ EXPORT_SYMBOL(strstr);
5349 -
5350 - EXPORT_SYMBOL(csum_partial);
5351 - EXPORT_SYMBOL(empty_zero_page);
5352 -+
5353 -+#ifdef CONFIG_PAX_KERNEXEC
5354 -+EXPORT_SYMBOL(KERNEL_TEXT_OFFSET);
5355 -+#endif
5356 -diff -urNp linux-2.6.27.6/arch/x86/kernel/init_task.c linux-2.6.27.6/arch/x86/kernel/init_task.c
5357 ---- linux-2.6.27.6/arch/x86/kernel/init_task.c 2008-11-07 12:55:34.000000000 -0500
5358 -+++ linux-2.6.27.6/arch/x86/kernel/init_task.c 2008-11-18 03:38:44.000000000 -0500
5359 -@@ -42,5 +42,5 @@ EXPORT_SYMBOL(init_task);
5360 - * section. Since TSS's are completely CPU-local, we want them
5361 - * on exact cacheline boundaries, to eliminate cacheline ping-pong.
5362 - */
5363 --DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
5364 --
5365 -+struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
5366 -+EXPORT_SYMBOL(init_tss);
5367 -diff -urNp linux-2.6.27.6/arch/x86/kernel/ioport.c linux-2.6.27.6/arch/x86/kernel/ioport.c
5368 ---- linux-2.6.27.6/arch/x86/kernel/ioport.c 2008-11-07 12:55:34.000000000 -0500
5369 -+++ linux-2.6.27.6/arch/x86/kernel/ioport.c 2008-11-18 03:38:44.000000000 -0500
5370 -@@ -14,6 +14,7 @@
5371 - #include <linux/slab.h>
5372 - #include <linux/thread_info.h>
5373 - #include <linux/syscalls.h>
5374 -+#include <linux/grsecurity.h>
5375 -
5376 - /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
5377 - static void set_bitmap(unsigned long *bitmap, unsigned int base,
5378 -@@ -40,6 +41,12 @@ asmlinkage long sys_ioperm(unsigned long
5379 -
5380 - if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
5381 - return -EINVAL;
5382 -+#ifdef CONFIG_GRKERNSEC_IO
5383 -+ if (turn_on) {
5384 -+ gr_handle_ioperm();
5385 -+ return -EPERM;
5386 -+ }
5387 -+#endif
5388 - if (turn_on && !capable(CAP_SYS_RAWIO))
5389 - return -EPERM;
5390 -
5391 -@@ -66,7 +73,7 @@ asmlinkage long sys_ioperm(unsigned long
5392 - * because the ->io_bitmap_max value must match the bitmap
5393 - * contents:
5394 - */
5395 -- tss = &per_cpu(init_tss, get_cpu());
5396 -+ tss = init_tss + get_cpu();
5397 -
5398 - set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
5399 -
5400 -@@ -121,8 +128,13 @@ static int do_iopl(unsigned int level, s
5401 - return -EINVAL;
5402 - /* Trying to gain more privileges? */
5403 - if (level > old) {
5404 -+#ifdef CONFIG_GRKERNSEC_IO
5405 -+ gr_handle_iopl();
5406 -+ return -EPERM;
5407 -+#else
5408 - if (!capable(CAP_SYS_RAWIO))
5409 - return -EPERM;
5410 -+#endif
5411 - }
5412 - regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
5413 -
5414 -diff -urNp linux-2.6.27.6/arch/x86/kernel/irq_32.c linux-2.6.27.6/arch/x86/kernel/irq_32.c
5415 ---- linux-2.6.27.6/arch/x86/kernel/irq_32.c 2008-11-07 12:55:34.000000000 -0500
5416 -+++ linux-2.6.27.6/arch/x86/kernel/irq_32.c 2008-11-18 03:38:44.000000000 -0500
5417 -@@ -116,7 +116,7 @@ execute_on_irq_stack(int overflow, struc
5418 - return 0;
5419 -
5420 - /* build the stack frame on the IRQ stack */
5421 -- isp = (u32 *) ((char*)irqctx + sizeof(*irqctx));
5422 -+ isp = (u32 *) ((char*)irqctx + sizeof(*irqctx) - 8);
5423 - irqctx->tinfo.task = curctx->tinfo.task;
5424 - irqctx->tinfo.previous_esp = current_stack_pointer;
5425 -
5426 -@@ -197,7 +197,7 @@ asmlinkage void do_softirq(void)
5427 - irqctx->tinfo.previous_esp = current_stack_pointer;
5428 -
5429 - /* build the stack frame on the softirq stack */
5430 -- isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
5431 -+ isp = (u32*) ((char*)irqctx + sizeof(*irqctx) - 8);
5432 -
5433 - call_on_stack(__do_softirq, isp);
5434 - /*
5435 -diff -urNp linux-2.6.27.6/arch/x86/kernel/kprobes.c linux-2.6.27.6/arch/x86/kernel/kprobes.c
5436 ---- linux-2.6.27.6/arch/x86/kernel/kprobes.c 2008-11-07 12:55:34.000000000 -0500
5437 -+++ linux-2.6.27.6/arch/x86/kernel/kprobes.c 2008-11-18 04:48:35.000000000 -0500
5438 -@@ -166,9 +166,24 @@ static void __kprobes set_jmp_op(void *f
5439 - char op;
5440 - s32 raddr;
5441 - } __attribute__((packed)) * jop;
5442 -- jop = (struct __arch_jmp_op *)from;
5443 -+
5444 -+#ifdef CONFIG_PAX_KERNEXEC
5445 -+ unsigned long cr0;
5446 -+#endif
5447 -+
5448 -+ jop = (struct __arch_jmp_op *)(ktla_ktva(from));
5449 -+
5450 -+#ifdef CONFIG_PAX_KERNEXEC
5451 -+ pax_open_kernel(cr0);
5452 -+#endif
5453 -+
5454 - jop->raddr = (s32)((long)(to) - ((long)(from) + 5));
5455 - jop->op = RELATIVEJUMP_INSTRUCTION;
5456 -+
5457 -+#ifdef CONFIG_PAX_KERNEXEC
5458 -+ pax_close_kernel(cr0);
5459 -+#endif
5460 -+
5461 - }
5462 -
5463 - /*
5464 -@@ -342,16 +357,29 @@ static void __kprobes fix_riprel(struct
5465 -
5466 - static void __kprobes arch_copy_kprobe(struct kprobe *p)
5467 - {
5468 -- memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
5469 -+
5470 -+#ifdef CONFIG_PAX_KERNEXEC
5471 -+ unsigned long cr0;
5472 -+#endif
5473 -+
5474 -+#ifdef CONFIG_PAX_KERNEXEC
5475 -+ pax_open_kernel(cr0);
5476 -+#endif
5477 -+
5478 -+ memcpy(p->ainsn.insn, ktla_ktva(p->addr), MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
5479 -+
5480 -+#ifdef CONFIG_PAX_KERNEXEC
5481 -+ pax_close_kernel(cr0);
5482 -+#endif
5483 -
5484 - fix_riprel(p);
5485 -
5486 -- if (can_boost(p->addr))
5487 -+ if (can_boost(ktla_ktva(p->addr)))
5488 - p->ainsn.boostable = 0;
5489 - else
5490 - p->ainsn.boostable = -1;
5491 -
5492 -- p->opcode = *p->addr;
5493 -+ p->opcode = *(ktla_ktva(p->addr));
5494 - }
5495 -
5496 - int __kprobes arch_prepare_kprobe(struct kprobe *p)
5497 -@@ -428,7 +456,7 @@ static void __kprobes prepare_singlestep
5498 - if (p->opcode == BREAKPOINT_INSTRUCTION)
5499 - regs->ip = (unsigned long)p->addr;
5500 - else
5501 -- regs->ip = (unsigned long)p->ainsn.insn;
5502 -+ regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
5503 - }
5504 -
5505 - void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
5506 -@@ -449,7 +477,7 @@ static void __kprobes setup_singlestep(s
5507 - if (p->ainsn.boostable == 1 && !p->post_handler) {
5508 - /* Boost up -- we can execute copied instructions directly */
5509 - reset_current_kprobe();
5510 -- regs->ip = (unsigned long)p->ainsn.insn;
5511 -+ regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
5512 - preempt_enable_no_resched();
5513 - return;
5514 - }
5515 -@@ -519,7 +547,7 @@ static int __kprobes kprobe_handler(stru
5516 - struct kprobe_ctlblk *kcb;
5517 -
5518 - addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t));
5519 -- if (*addr != BREAKPOINT_INSTRUCTION) {
5520 -+ if (*(kprobe_opcode_t *)ktla_ktva((unsigned long)addr) != BREAKPOINT_INSTRUCTION) {
5521 - /*
5522 - * The breakpoint instruction was removed right
5523 - * after we hit it. Another cpu has removed
5524 -@@ -770,7 +798,7 @@ static void __kprobes resume_execution(s
5525 - struct pt_regs *regs, struct kprobe_ctlblk *kcb)
5526 - {
5527 - unsigned long *tos = stack_addr(regs);
5528 -- unsigned long copy_ip = (unsigned long)p->ainsn.insn;
5529 -+ unsigned long copy_ip = ktva_ktla((unsigned long)p->ainsn.insn);
5530 - unsigned long orig_ip = (unsigned long)p->addr;
5531 - kprobe_opcode_t *insn = p->ainsn.insn;
5532 -
5533 -@@ -953,7 +981,7 @@ int __kprobes kprobe_exceptions_notify(s
5534 - struct die_args *args = data;
5535 - int ret = NOTIFY_DONE;
5536 -
5537 -- if (args->regs && user_mode_vm(args->regs))
5538 -+ if (args->regs && user_mode(args->regs))
5539 - return ret;
5540 -
5541 - switch (val) {
5542 -diff -urNp linux-2.6.27.6/arch/x86/kernel/ldt.c linux-2.6.27.6/arch/x86/kernel/ldt.c
5543 ---- linux-2.6.27.6/arch/x86/kernel/ldt.c 2008-11-07 12:55:34.000000000 -0500
5544 -+++ linux-2.6.27.6/arch/x86/kernel/ldt.c 2008-11-18 03:38:44.000000000 -0500
5545 -@@ -63,13 +63,13 @@ static int alloc_ldt(mm_context_t *pc, i
5546 - if (reload) {
5547 - #ifdef CONFIG_SMP
5548 - preempt_disable();
5549 -- load_LDT(pc);
5550 -+ load_LDT_nolock(pc);
5551 - if (!cpus_equal(current->mm->cpu_vm_mask,
5552 - cpumask_of_cpu(smp_processor_id())))
5553 - smp_call_function(flush_ldt, current->mm, 1);
5554 - preempt_enable();
5555 - #else
5556 -- load_LDT(pc);
5557 -+ load_LDT_nolock(pc);
5558 - #endif
5559 - }
5560 - if (oldsize) {
5561 -@@ -108,6 +108,24 @@ int init_new_context(struct task_struct
5562 - retval = copy_ldt(&mm->context, &old_mm->context);
5563 - mutex_unlock(&old_mm->context.lock);
5564 - }
5565 -+
5566 -+ if (tsk == current) {
5567 -+ mm->context.vdso = ~0UL;
5568 -+
5569 -+#ifdef CONFIG_X86_32
5570 -+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5571 -+ mm->context.user_cs_base = 0UL;
5572 -+ mm->context.user_cs_limit = ~0UL;
5573 -+
5574 -+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
5575 -+ cpus_clear(mm->context.cpu_user_cs_mask);
5576 -+#endif
5577 -+
5578 -+#endif
5579 -+#endif
5580 -+
5581 -+ }
5582 -+
5583 - return retval;
5584 - }
5585 -
5586 -@@ -221,6 +239,13 @@ static int write_ldt(void __user *ptr, u
5587 - }
5588 - }
5589 -
5590 -+#ifdef CONFIG_PAX_SEGMEXEC
5591 -+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
5592 -+ error = -EINVAL;
5593 -+ goto out_unlock;
5594 -+ }
5595 -+#endif
5596 -+
5597 - fill_ldt(&ldt, &ldt_info);
5598 - if (oldmode)
5599 - ldt.avl = 0;
5600 -diff -urNp linux-2.6.27.6/arch/x86/kernel/machine_kexec_32.c linux-2.6.27.6/arch/x86/kernel/machine_kexec_32.c
5601 ---- linux-2.6.27.6/arch/x86/kernel/machine_kexec_32.c 2008-11-07 12:55:34.000000000 -0500
5602 -+++ linux-2.6.27.6/arch/x86/kernel/machine_kexec_32.c 2008-11-18 03:38:44.000000000 -0500
5603 -@@ -34,7 +34,7 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED
5604 - static u32 kexec_pte0[1024] PAGE_ALIGNED;
5605 - static u32 kexec_pte1[1024] PAGE_ALIGNED;
5606 -
5607 --static void set_idt(void *newidt, __u16 limit)
5608 -+static void set_idt(struct desc_struct *newidt, __u16 limit)
5609 - {
5610 - struct desc_ptr curidt;
5611 -
5612 -@@ -46,7 +46,7 @@ static void set_idt(void *newidt, __u16
5613 - }
5614 -
5615 -
5616 --static void set_gdt(void *newgdt, __u16 limit)
5617 -+static void set_gdt(struct desc_struct *newgdt, __u16 limit)
5618 - {
5619 - struct desc_ptr curgdt;
5620 -
5621 -@@ -145,7 +145,7 @@ void machine_kexec(struct kimage *image)
5622 - }
5623 -
5624 - control_page = page_address(image->control_code_page);
5625 -- memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE);
5626 -+ memcpy(control_page, (void *)ktla_ktva((unsigned long)relocate_kernel), KEXEC_CONTROL_CODE_MAX_SIZE);
5627 -
5628 - relocate_kernel_ptr = control_page;
5629 - page_list[PA_CONTROL_PAGE] = __pa(control_page);
5630 -diff -urNp linux-2.6.27.6/arch/x86/kernel/module_32.c linux-2.6.27.6/arch/x86/kernel/module_32.c
5631 ---- linux-2.6.27.6/arch/x86/kernel/module_32.c 2008-11-07 12:55:34.000000000 -0500
5632 -+++ linux-2.6.27.6/arch/x86/kernel/module_32.c 2008-11-18 03:38:44.000000000 -0500
5633 -@@ -23,6 +23,9 @@
5634 - #include <linux/kernel.h>
5635 - #include <linux/bug.h>
5636 -
5637 -+#include <asm/desc.h>
5638 -+#include <asm/pgtable.h>
5639 -+
5640 - #if 0
5641 - #define DEBUGP printk
5642 - #else
5643 -@@ -33,9 +36,31 @@ void *module_alloc(unsigned long size)
5644 - {
5645 - if (size == 0)
5646 - return NULL;
5647 -+
5648 -+#ifdef CONFIG_PAX_KERNEXEC
5649 -+ return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
5650 -+#else
5651 - return vmalloc_exec(size);
5652 -+#endif
5653 -+
5654 - }
5655 -
5656 -+#ifdef CONFIG_PAX_KERNEXEC
5657 -+void *module_alloc_exec(unsigned long size)
5658 -+{
5659 -+ struct vm_struct *area;
5660 -+
5661 -+ if (size == 0)
5662 -+ return NULL;
5663 -+
5664 -+ area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
5665 -+ if (area)
5666 -+ return area->addr;
5667 -+
5668 -+ return NULL;
5669 -+}
5670 -+EXPORT_SYMBOL(module_alloc_exec);
5671 -+#endif
5672 -
5673 - /* Free memory returned from module_alloc */
5674 - void module_free(struct module *mod, void *module_region)
5675 -@@ -45,6 +70,45 @@ void module_free(struct module *mod, voi
5676 - table entries. */
5677 - }
5678 -
5679 -+#ifdef CONFIG_PAX_KERNEXEC
5680 -+void module_free_exec(struct module *mod, void *module_region)
5681 -+{
5682 -+ struct vm_struct **p, *tmp;
5683 -+
5684 -+ if (!module_region)
5685 -+ return;
5686 -+
5687 -+ if ((PAGE_SIZE-1) & (unsigned long)module_region) {
5688 -+ printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
5689 -+ WARN_ON(1);
5690 -+ return;
5691 -+ }
5692 -+
5693 -+ write_lock(&vmlist_lock);
5694 -+ for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next)
5695 -+ if (tmp->addr == module_region)
5696 -+ break;
5697 -+
5698 -+ if (tmp) {
5699 -+ unsigned long cr0;
5700 -+
5701 -+ pax_open_kernel(cr0);
5702 -+ memset(tmp->addr, 0xCC, tmp->size);
5703 -+ pax_close_kernel(cr0);
5704 -+
5705 -+ *p = tmp->next;
5706 -+ kfree(tmp);
5707 -+ }
5708 -+ write_unlock(&vmlist_lock);
5709 -+
5710 -+ if (!tmp) {
5711 -+ printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
5712 -+ module_region);
5713 -+ WARN_ON(1);
5714 -+ }
5715 -+}
5716 -+#endif
5717 -+
5718 - /* We don't need anything special. */
5719 - int module_frob_arch_sections(Elf_Ehdr *hdr,
5720 - Elf_Shdr *sechdrs,
5721 -@@ -63,14 +127,20 @@ int apply_relocate(Elf32_Shdr *sechdrs,
5722 - unsigned int i;
5723 - Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
5724 - Elf32_Sym *sym;
5725 -- uint32_t *location;
5726 -+ uint32_t *plocation, location;
5727 -+
5728 -+#ifdef CONFIG_PAX_KERNEXEC
5729 -+ unsigned long cr0;
5730 -+#endif
5731 -
5732 - DEBUGP("Applying relocate section %u to %u\n", relsec,
5733 - sechdrs[relsec].sh_info);
5734 - for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
5735 - /* This is where to make the change */
5736 -- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
5737 -- + rel[i].r_offset;
5738 -+ plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
5739 -+ location = (uint32_t)plocation;
5740 -+ if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
5741 -+ plocation = ktla_ktva((void *)plocation);
5742 - /* This is the symbol it is referring to. Note that all
5743 - undefined symbols have been resolved. */
5744 - sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
5745 -@@ -78,12 +148,32 @@ int apply_relocate(Elf32_Shdr *sechdrs,
5746 -
5747 - switch (ELF32_R_TYPE(rel[i].r_info)) {
5748 - case R_386_32:
5749 -+
5750 -+#ifdef CONFIG_PAX_KERNEXEC
5751 -+ pax_open_kernel(cr0);
5752 -+#endif
5753 -+
5754 - /* We add the value into the location given */
5755 -- *location += sym->st_value;
5756 -+ *plocation += sym->st_value;
5757 -+
5758 -+#ifdef CONFIG_PAX_KERNEXEC
5759 -+ pax_close_kernel(cr0);
5760 -+#endif
5761 -+
5762 - break;
5763 - case R_386_PC32:
5764 -+
5765 -+#ifdef CONFIG_PAX_KERNEXEC
5766 -+ pax_open_kernel(cr0);
5767 -+#endif
5768 -+
5769 - /* Add the value, subtract its postition */
5770 -- *location += sym->st_value - (uint32_t)location;
5771 -+ *plocation += sym->st_value - location;
5772 -+
5773 -+#ifdef CONFIG_PAX_KERNEXEC
5774 -+ pax_close_kernel(cr0);
5775 -+#endif
5776 -+
5777 - break;
5778 - default:
5779 - printk(KERN_ERR "module %s: Unknown relocation: %u\n",
5780 -diff -urNp linux-2.6.27.6/arch/x86/kernel/module_64.c linux-2.6.27.6/arch/x86/kernel/module_64.c
5781 ---- linux-2.6.27.6/arch/x86/kernel/module_64.c 2008-11-07 12:55:34.000000000 -0500
5782 -+++ linux-2.6.27.6/arch/x86/kernel/module_64.c 2008-11-18 03:38:44.000000000 -0500
5783 -@@ -40,7 +40,7 @@ void module_free(struct module *mod, voi
5784 - table entries. */
5785 - }
5786 -
5787 --void *module_alloc(unsigned long size)
5788 -+static void *__module_alloc(unsigned long size, pgprot_t prot)
5789 - {
5790 - struct vm_struct *area;
5791 -
5792 -@@ -54,8 +54,31 @@ void *module_alloc(unsigned long size)
5793 - if (!area)
5794 - return NULL;
5795 -
5796 -- return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
5797 -+ return __vmalloc_area(area, GFP_KERNEL | __GFP_ZERO, prot);
5798 -+}
5799 -+
5800 -+#ifdef CONFIG_PAX_KERNEXEC
5801 -+void *module_alloc(unsigned long size)
5802 -+{
5803 -+ return __module_alloc(size, PAGE_KERNEL);
5804 -+}
5805 -+
5806 -+void module_free_exec(struct module *mod, void *module_region)
5807 -+{
5808 -+ module_free(mod, module_region);
5809 -+}
5810 -+
5811 -+void *module_alloc_exec(unsigned long size)
5812 -+{
5813 -+ return __module_alloc(size, PAGE_KERNEL_RX);
5814 - }
5815 -+#else
5816 -+void *module_alloc(unsigned long size)
5817 -+{
5818 -+ return __module_alloc(size, PAGE_KERNEL_EXEC);
5819 -+}
5820 -+#endif
5821 -+
5822 - #endif
5823 -
5824 - /* We don't need anything special. */
5825 -@@ -77,7 +100,11 @@ int apply_relocate_add(Elf64_Shdr *sechd
5826 - Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
5827 - Elf64_Sym *sym;
5828 - void *loc;
5829 -- u64 val;
5830 -+ u64 val;
5831 -+
5832 -+#ifdef CONFIG_PAX_KERNEXEC
5833 -+ unsigned long cr0;
5834 -+#endif
5835 -
5836 - DEBUGP("Applying relocate section %u to %u\n", relsec,
5837 - sechdrs[relsec].sh_info);
5838 -@@ -101,21 +128,61 @@ int apply_relocate_add(Elf64_Shdr *sechd
5839 - case R_X86_64_NONE:
5840 - break;
5841 - case R_X86_64_64:
5842 -+
5843 -+#ifdef CONFIG_PAX_KERNEXEC
5844 -+ pax_open_kernel(cr0);
5845 -+#endif
5846 -+
5847 - *(u64 *)loc = val;
5848 -+
5849 -+#ifdef CONFIG_PAX_KERNEXEC
5850 -+ pax_close_kernel(cr0);
5851 -+#endif
5852 -+
5853 - break;
5854 - case R_X86_64_32:
5855 -+
5856 -+#ifdef CONFIG_PAX_KERNEXEC
5857 -+ pax_open_kernel(cr0);
5858 -+#endif
5859 -+
5860 - *(u32 *)loc = val;
5861 -+
5862 -+#ifdef CONFIG_PAX_KERNEXEC
5863 -+ pax_close_kernel(cr0);
5864 -+#endif
5865 -+
5866 - if (val != *(u32 *)loc)
5867 - goto overflow;
5868 - break;
5869 - case R_X86_64_32S:
5870 -+
5871 -+#ifdef CONFIG_PAX_KERNEXEC
5872 -+ pax_open_kernel(cr0);
5873 -+#endif
5874 -+
5875 - *(s32 *)loc = val;
5876 -+
5877 -+#ifdef CONFIG_PAX_KERNEXEC
5878 -+ pax_close_kernel(cr0);
5879 -+#endif
5880 -+
5881 - if ((s64)val != *(s32 *)loc)
5882 - goto overflow;
5883 - break;
5884 - case R_X86_64_PC32:
5885 - val -= (u64)loc;
5886 -+
5887 -+#ifdef CONFIG_PAX_KERNEXEC
5888 -+ pax_open_kernel(cr0);
5889 -+#endif
5890 -+
5891 - *(u32 *)loc = val;
5892 -+
5893 -+#ifdef CONFIG_PAX_KERNEXEC
5894 -+ pax_close_kernel(cr0);
5895 -+#endif
5896 -+
5897 - #if 0
5898 - if ((s64)val != *(s32 *)loc)
5899 - goto overflow;
5900 -diff -urNp linux-2.6.27.6/arch/x86/kernel/paravirt.c linux-2.6.27.6/arch/x86/kernel/paravirt.c
5901 ---- linux-2.6.27.6/arch/x86/kernel/paravirt.c 2008-11-07 12:55:34.000000000 -0500
5902 -+++ linux-2.6.27.6/arch/x86/kernel/paravirt.c 2008-11-18 03:38:44.000000000 -0500
5903 -@@ -44,7 +44,7 @@ void _paravirt_nop(void)
5904 - {
5905 - }
5906 -
5907 --static void __init default_banner(void)
5908 -+static void default_banner(void)
5909 - {
5910 - printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
5911 - pv_info.name);
5912 -@@ -164,7 +164,7 @@ unsigned paravirt_patch_insns(void *insn
5913 - if (insn_len > len || start == NULL)
5914 - insn_len = len;
5915 - else
5916 -- memcpy(insnbuf, start, insn_len);
5917 -+ memcpy(insnbuf, ktla_ktva(start), insn_len);
5918 -
5919 - return insn_len;
5920 - }
5921 -@@ -279,21 +279,21 @@ void __init paravirt_use_bytelocks(void)
5922 - #endif
5923 - }
5924 -
5925 --struct pv_info pv_info = {
5926 -+struct pv_info pv_info __read_only = {
5927 - .name = "bare hardware",
5928 - .paravirt_enabled = 0,
5929 - .kernel_rpl = 0,
5930 - .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */
5931 - };
5932 -
5933 --struct pv_init_ops pv_init_ops = {
5934 -+struct pv_init_ops pv_init_ops __read_only = {
5935 - .patch = native_patch,
5936 - .banner = default_banner,
5937 - .arch_setup = paravirt_nop,
5938 - .memory_setup = machine_specific_memory_setup,
5939 - };
5940 -
5941 --struct pv_time_ops pv_time_ops = {
5942 -+struct pv_time_ops pv_time_ops __read_only = {
5943 - .time_init = hpet_time_init,
5944 - .get_wallclock = native_get_wallclock,
5945 - .set_wallclock = native_set_wallclock,
5946 -@@ -301,7 +301,7 @@ struct pv_time_ops pv_time_ops = {
5947 - .get_tsc_khz = native_calibrate_tsc,
5948 - };
5949 -
5950 --struct pv_irq_ops pv_irq_ops = {
5951 -+struct pv_irq_ops pv_irq_ops __read_only = {
5952 - .init_IRQ = native_init_IRQ,
5953 - .save_fl = native_save_fl,
5954 - .restore_fl = native_restore_fl,
5955 -@@ -314,7 +314,7 @@ struct pv_irq_ops pv_irq_ops = {
5956 - #endif
5957 - };
5958 -
5959 --struct pv_cpu_ops pv_cpu_ops = {
5960 -+struct pv_cpu_ops pv_cpu_ops __read_only = {
5961 - .cpuid = native_cpuid,
5962 - .get_debugreg = native_get_debugreg,
5963 - .set_debugreg = native_set_debugreg,
5964 -@@ -371,7 +371,7 @@ struct pv_cpu_ops pv_cpu_ops = {
5965 - },
5966 - };
5967 -
5968 --struct pv_apic_ops pv_apic_ops = {
5969 -+struct pv_apic_ops pv_apic_ops __read_only = {
5970 - #ifdef CONFIG_X86_LOCAL_APIC
5971 - .apic_write = native_apic_write,
5972 - .apic_read = native_apic_read,
5973 -@@ -381,7 +381,7 @@ struct pv_apic_ops pv_apic_ops = {
5974 - #endif
5975 - };
5976 -
5977 --struct pv_mmu_ops pv_mmu_ops = {
5978 -+struct pv_mmu_ops pv_mmu_ops __read_only = {
5979 - #ifndef CONFIG_X86_64
5980 - .pagetable_setup_start = native_pagetable_setup_start,
5981 - .pagetable_setup_done = native_pagetable_setup_done,
5982 -@@ -461,7 +461,7 @@ struct pv_mmu_ops pv_mmu_ops = {
5983 - .set_fixmap = native_set_fixmap,
5984 - };
5985 -
5986 --struct pv_lock_ops pv_lock_ops = {
5987 -+struct pv_lock_ops pv_lock_ops __read_only = {
5988 - #ifdef CONFIG_SMP
5989 - .spin_is_locked = __ticket_spin_is_locked,
5990 - .spin_is_contended = __ticket_spin_is_contended,
5991 -diff -urNp linux-2.6.27.6/arch/x86/kernel/process_32.c linux-2.6.27.6/arch/x86/kernel/process_32.c
5992 ---- linux-2.6.27.6/arch/x86/kernel/process_32.c 2008-11-07 12:55:34.000000000 -0500
5993 -+++ linux-2.6.27.6/arch/x86/kernel/process_32.c 2008-11-18 03:38:44.000000000 -0500
5994 -@@ -62,8 +62,10 @@ asmlinkage void ret_from_fork(void) __as
5995 - DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
5996 - EXPORT_PER_CPU_SYMBOL(current_task);
5997 -
5998 -+#ifdef CONFIG_SMP
5999 - DEFINE_PER_CPU(int, cpu_number);
6000 - EXPORT_PER_CPU_SYMBOL(cpu_number);
6001 -+#endif
6002 -
6003 - /*
6004 - * Return saved PC of a blocked thread.
6005 -@@ -71,6 +73,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_number);
6006 - unsigned long thread_saved_pc(struct task_struct *tsk)
6007 - {
6008 - return ((unsigned long *)tsk->thread.sp)[3];
6009 -+//XXX return tsk->thread.eip;
6010 - }
6011 -
6012 - #ifdef CONFIG_HOTPLUG_CPU
6013 -@@ -162,7 +165,7 @@ void __show_registers(struct pt_regs *re
6014 - unsigned long sp;
6015 - unsigned short ss, gs;
6016 -
6017 -- if (user_mode_vm(regs)) {
6018 -+ if (user_mode(regs)) {
6019 - sp = regs->sp;
6020 - ss = regs->ss & 0xffff;
6021 - savesegment(gs, gs);
6022 -@@ -239,8 +242,8 @@ int kernel_thread(int (*fn)(void *), voi
6023 - regs.bx = (unsigned long) fn;
6024 - regs.dx = (unsigned long) arg;
6025 -
6026 -- regs.ds = __USER_DS;
6027 -- regs.es = __USER_DS;
6028 -+ regs.ds = __KERNEL_DS;
6029 -+ regs.es = __KERNEL_DS;
6030 - regs.fs = __KERNEL_PERCPU;
6031 - regs.orig_ax = -1;
6032 - regs.ip = (unsigned long) kernel_thread_helper;
6033 -@@ -262,7 +265,7 @@ void exit_thread(void)
6034 - struct task_struct *tsk = current;
6035 - struct thread_struct *t = &tsk->thread;
6036 - int cpu = get_cpu();
6037 -- struct tss_struct *tss = &per_cpu(init_tss, cpu);
6038 -+ struct tss_struct *tss = init_tss + cpu;
6039 -
6040 - kfree(t->io_bitmap_ptr);
6041 - t->io_bitmap_ptr = NULL;
6042 -@@ -283,6 +286,7 @@ void flush_thread(void)
6043 - {
6044 - struct task_struct *tsk = current;
6045 -
6046 -+ loadsegment(gs, 0);
6047 - tsk->thread.debugreg0 = 0;
6048 - tsk->thread.debugreg1 = 0;
6049 - tsk->thread.debugreg2 = 0;
6050 -@@ -322,7 +326,7 @@ int copy_thread(int nr, unsigned long cl
6051 - struct task_struct *tsk;
6052 - int err;
6053 -
6054 -- childregs = task_pt_regs(p);
6055 -+ childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
6056 - *childregs = *regs;
6057 - childregs->ax = 0;
6058 - childregs->sp = sp;
6059 -@@ -351,6 +355,7 @@ int copy_thread(int nr, unsigned long cl
6060 - * Set a new TLS for the child thread?
6061 - */
6062 - if (clone_flags & CLONE_SETTLS)
6063 -+//XXX needs set_fs()?
6064 - err = do_set_thread_area(p, -1,
6065 - (struct user_desc __user *)childregs->si, 0);
6066 -
6067 -@@ -550,7 +555,7 @@ struct task_struct * __switch_to(struct
6068 - struct thread_struct *prev = &prev_p->thread,
6069 - *next = &next_p->thread;
6070 - int cpu = smp_processor_id();
6071 -- struct tss_struct *tss = &per_cpu(init_tss, cpu);
6072 -+ struct tss_struct *tss = init_tss + cpu;
6073 -
6074 - /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
6075 -
6076 -@@ -578,6 +583,11 @@ struct task_struct * __switch_to(struct
6077 - */
6078 - savesegment(gs, prev->gs);
6079 -
6080 -+#ifdef CONFIG_PAX_MEMORY_UDEREF
6081 -+ if (!segment_eq(task_thread_info(prev_p)->addr_limit, task_thread_info(next_p)->addr_limit))
6082 -+ __set_fs(task_thread_info(next_p)->addr_limit, cpu);
6083 -+#endif
6084 -+
6085 - /*
6086 - * Load the per-thread Thread-Local Storage descriptor.
6087 - */
6088 -@@ -716,15 +726,27 @@ unsigned long get_wchan(struct task_stru
6089 - return 0;
6090 - }
6091 -
6092 --unsigned long arch_align_stack(unsigned long sp)
6093 -+#ifdef CONFIG_PAX_RANDKSTACK
6094 -+asmlinkage void pax_randomize_kstack(void)
6095 - {
6096 -- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
6097 -- sp -= get_random_int() % 8192;
6098 -- return sp & ~0xf;
6099 --}
6100 -+ struct thread_struct *thread = &current->thread;
6101 -+ unsigned long time;
6102 -
6103 --unsigned long arch_randomize_brk(struct mm_struct *mm)
6104 --{
6105 -- unsigned long range_end = mm->brk + 0x02000000;
6106 -- return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
6107 -+ if (!randomize_va_space)
6108 -+ return;
6109 -+
6110 -+ rdtscl(time);
6111 -+
6112 -+ /* P4 seems to return a 0 LSB, ignore it */
6113 -+#ifdef CONFIG_MPENTIUM4
6114 -+ time &= 0x1EUL;
6115 -+ time <<= 2;
6116 -+#else
6117 -+ time &= 0xFUL;
6118 -+ time <<= 3;
6119 -+#endif
6120 -+
6121 -+ thread->sp0 ^= time;
6122 -+ load_sp0(init_tss + smp_processor_id(), thread);
6123 - }
6124 -+#endif
6125 -diff -urNp linux-2.6.27.6/arch/x86/kernel/process_64.c linux-2.6.27.6/arch/x86/kernel/process_64.c
6126 ---- linux-2.6.27.6/arch/x86/kernel/process_64.c 2008-11-07 12:55:34.000000000 -0500
6127 -+++ linux-2.6.27.6/arch/x86/kernel/process_64.c 2008-11-18 03:38:44.000000000 -0500
6128 -@@ -119,6 +119,8 @@ static inline void play_dead(void)
6129 - void cpu_idle(void)
6130 - {
6131 - current_thread_info()->status |= TS_POLLING;
6132 -+ current->stack_canary = pax_get_random_long();
6133 -+ write_pda(stack_canary, current->stack_canary);
6134 - /* endless idle loop with no priority at all */
6135 - while (1) {
6136 - tick_nohz_stop_sched_tick(1);
6137 -@@ -228,7 +230,7 @@ void exit_thread(void)
6138 - struct thread_struct *t = &me->thread;
6139 -
6140 - if (me->thread.io_bitmap_ptr) {
6141 -- struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
6142 -+ struct tss_struct *tss = init_tss + get_cpu();
6143 -
6144 - kfree(t->io_bitmap_ptr);
6145 - t->io_bitmap_ptr = NULL;
6146 -@@ -541,7 +543,7 @@ __switch_to(struct task_struct *prev_p,
6147 - struct thread_struct *prev = &prev_p->thread;
6148 - struct thread_struct *next = &next_p->thread;
6149 - int cpu = smp_processor_id();
6150 -- struct tss_struct *tss = &per_cpu(init_tss, cpu);
6151 -+ struct tss_struct *tss = init_tss + cpu;
6152 - unsigned fsindex, gsindex;
6153 -
6154 - /* we're going to use this soon, after a few expensive things */
6155 -@@ -630,7 +632,6 @@ __switch_to(struct task_struct *prev_p,
6156 - (unsigned long)task_stack_page(next_p) +
6157 - THREAD_SIZE - PDA_STACKOFFSET);
6158 - #ifdef CONFIG_CC_STACKPROTECTOR
6159 -- write_pda(stack_canary, next_p->stack_canary);
6160 - /*
6161 - * Build time only check to make sure the stack_canary is at
6162 - * offset 40 in the pda; this is a gcc ABI requirement
6163 -@@ -729,12 +730,11 @@ unsigned long get_wchan(struct task_stru
6164 - if (!p || p == current || p->state==TASK_RUNNING)
6165 - return 0;
6166 - stack = (unsigned long)task_stack_page(p);
6167 -- if (p->thread.sp < stack || p->thread.sp >= stack+THREAD_SIZE)
6168 -+ if (p->thread.sp < stack || p->thread.sp > stack+THREAD_SIZE-8-sizeof(u64))
6169 - return 0;
6170 - fp = *(u64 *)(p->thread.sp);
6171 - do {
6172 -- if (fp < (unsigned long)stack ||
6173 -- fp >= (unsigned long)stack+THREAD_SIZE)
6174 -+ if (fp < stack || fp > stack+THREAD_SIZE-8-sizeof(u64))
6175 - return 0;
6176 - ip = *(u64 *)(fp+8);
6177 - if (!in_sched_functions(ip))
6178 -@@ -844,16 +844,3 @@ long sys_arch_prctl(int code, unsigned l
6179 - {
6180 - return do_arch_prctl(current, code, addr);
6181 - }
6182 --
6183 --unsigned long arch_align_stack(unsigned long sp)
6184 --{
6185 -- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
6186 -- sp -= get_random_int() % 8192;
6187 -- return sp & ~0xf;
6188 --}
6189 --
6190 --unsigned long arch_randomize_brk(struct mm_struct *mm)
6191 --{
6192 -- unsigned long range_end = mm->brk + 0x02000000;
6193 -- return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
6194 --}
6195 -diff -urNp linux-2.6.27.6/arch/x86/kernel/ptrace.c linux-2.6.27.6/arch/x86/kernel/ptrace.c
6196 ---- linux-2.6.27.6/arch/x86/kernel/ptrace.c 2008-11-07 12:55:34.000000000 -0500
6197 -+++ linux-2.6.27.6/arch/x86/kernel/ptrace.c 2008-11-18 03:38:44.000000000 -0500
6198 -@@ -1369,7 +1369,7 @@ void send_sigtrap(struct task_struct *ts
6199 - info.si_code = TRAP_BRKPT;
6200 -
6201 - /* User-mode ip? */
6202 -- info.si_addr = user_mode_vm(regs) ? (void __user *) regs->ip : NULL;
6203 -+ info.si_addr = user_mode(regs) ? (void __user *) regs->ip : NULL;
6204 -
6205 - /* Send us the fake SIGTRAP */
6206 - force_sig_info(SIGTRAP, &info, tsk);
6207 -diff -urNp linux-2.6.27.6/arch/x86/kernel/reboot.c linux-2.6.27.6/arch/x86/kernel/reboot.c
6208 ---- linux-2.6.27.6/arch/x86/kernel/reboot.c 2008-11-07 12:55:34.000000000 -0500
6209 -+++ linux-2.6.27.6/arch/x86/kernel/reboot.c 2008-11-18 03:38:44.000000000 -0500
6210 -@@ -28,7 +28,7 @@ void (*pm_power_off)(void);
6211 - EXPORT_SYMBOL(pm_power_off);
6212 -
6213 - static const struct desc_ptr no_idt = {};
6214 --static int reboot_mode;
6215 -+static unsigned short reboot_mode;
6216 - enum reboot_type reboot_type = BOOT_KBD;
6217 - int reboot_force;
6218 -
6219 -@@ -193,7 +193,7 @@ static struct dmi_system_id __initdata r
6220 - DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
6221 - },
6222 - },
6223 -- { }
6224 -+ { NULL, NULL, {{0, NULL}}, NULL}
6225 - };
6226 -
6227 - static int __init reboot_init(void)
6228 -@@ -209,12 +209,12 @@ core_initcall(reboot_init);
6229 - controller to pulse the CPU reset line, which is more thorough, but
6230 - doesn't work with at least one type of 486 motherboard. It is easy
6231 - to stop this code working; hence the copious comments. */
6232 --static const unsigned long long
6233 --real_mode_gdt_entries [3] =
6234 -+static struct desc_struct
6235 -+real_mode_gdt_entries [3] __read_only =
6236 - {
6237 -- 0x0000000000000000ULL, /* Null descriptor */
6238 -- 0x00009b000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
6239 -- 0x000093000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
6240 -+ {{{0x00000000, 0x00000000}}}, /* Null descriptor */
6241 -+ {{{0x0000ffff, 0x00009b00}}}, /* 16-bit real-mode 64k code at 0x00000000 */
6242 -+ {{{0x0100ffff, 0x00009300}}} /* 16-bit real-mode 64k data at 0x00000100 */
6243 - };
6244 -
6245 - static const struct desc_ptr
6246 -@@ -263,7 +263,7 @@ static const unsigned char jump_to_bios
6247 - * specified by the code and length parameters.
6248 - * We assume that length will aways be less that 100!
6249 - */
6250 --void machine_real_restart(const unsigned char *code, int length)
6251 -+void machine_real_restart(const unsigned char *code, unsigned int length)
6252 - {
6253 - local_irq_disable();
6254 -
6255 -@@ -283,8 +283,8 @@ void machine_real_restart(const unsigned
6256 - /* Remap the kernel at virtual address zero, as well as offset zero
6257 - from the kernel segment. This assumes the kernel segment starts at
6258 - virtual address PAGE_OFFSET. */
6259 -- memcpy(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
6260 -- sizeof(swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
6261 -+ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
6262 -+ min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
6263 -
6264 - /*
6265 - * Use `swapper_pg_dir' as our page directory.
6266 -@@ -296,16 +296,15 @@ void machine_real_restart(const unsigned
6267 - boot)". This seems like a fairly standard thing that gets set by
6268 - REBOOT.COM programs, and the previous reset routine did this
6269 - too. */
6270 -- *((unsigned short *)0x472) = reboot_mode;
6271 -+ *(unsigned short *)(__va(0x472)) = reboot_mode;
6272 -
6273 - /* For the switch to real mode, copy some code to low memory. It has
6274 - to be in the first 64k because it is running in 16-bit mode, and it
6275 - has to have the same physical and virtual address, because it turns
6276 - off paging. Copy it near the end of the first page, out of the way
6277 - of BIOS variables. */
6278 -- memcpy((void *)(0x1000 - sizeof(real_mode_switch) - 100),
6279 -- real_mode_switch, sizeof (real_mode_switch));
6280 -- memcpy((void *)(0x1000 - 100), code, length);
6281 -+ memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch));
6282 -+ memcpy(__va(0x1000 - 100), code, length);
6283 -
6284 - /* Set up the IDT for real mode. */
6285 - load_idt(&real_mode_idt);
6286 -diff -urNp linux-2.6.27.6/arch/x86/kernel/setup.c linux-2.6.27.6/arch/x86/kernel/setup.c
6287 ---- linux-2.6.27.6/arch/x86/kernel/setup.c 2008-11-17 20:03:30.000000000 -0500
6288 -+++ linux-2.6.27.6/arch/x86/kernel/setup.c 2008-11-18 03:38:44.000000000 -0500
6289 -@@ -682,8 +682,8 @@ void __init setup_arch(char **cmdline_p)
6290 -
6291 - if (!boot_params.hdr.root_flags)
6292 - root_mountflags &= ~MS_RDONLY;
6293 -- init_mm.start_code = (unsigned long) _text;
6294 -- init_mm.end_code = (unsigned long) _etext;
6295 -+ init_mm.start_code = ktla_ktva((unsigned long) _text);
6296 -+ init_mm.end_code = ktla_ktva((unsigned long) _etext);
6297 - init_mm.end_data = (unsigned long) _edata;
6298 - #ifdef CONFIG_X86_32
6299 - init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
6300 -@@ -691,9 +691,9 @@ void __init setup_arch(char **cmdline_p)
6301 - init_mm.brk = (unsigned long) &_end;
6302 - #endif
6303 -
6304 -- code_resource.start = virt_to_phys(_text);
6305 -- code_resource.end = virt_to_phys(_etext)-1;
6306 -- data_resource.start = virt_to_phys(_etext);
6307 -+ code_resource.start = virt_to_phys(ktla_ktva(_text));
6308 -+ code_resource.end = virt_to_phys(ktla_ktva(_etext))-1;
6309 -+ data_resource.start = virt_to_phys(_data);
6310 - data_resource.end = virt_to_phys(_edata)-1;
6311 - bss_resource.start = virt_to_phys(&__bss_start);
6312 - bss_resource.end = virt_to_phys(&__bss_stop)-1;
6313 -diff -urNp linux-2.6.27.6/arch/x86/kernel/setup_percpu.c linux-2.6.27.6/arch/x86/kernel/setup_percpu.c
6314 ---- linux-2.6.27.6/arch/x86/kernel/setup_percpu.c 2008-11-07 12:55:34.000000000 -0500
6315 -+++ linux-2.6.27.6/arch/x86/kernel/setup_percpu.c 2008-11-18 03:38:44.000000000 -0500
6316 -@@ -166,7 +166,11 @@ void __init setup_per_cpu_areas(void)
6317 - else
6318 - ptr = alloc_bootmem_pages_node(NODE_DATA(node), size);
6319 - #endif
6320 -+#ifdef CONFIG_X86_32
6321 -+ __per_cpu_offset[cpu] = ptr - __per_cpu_start;
6322 -+#else
6323 - per_cpu_offset(cpu) = ptr - __per_cpu_start;
6324 -+#endif
6325 - memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
6326 -
6327 - }
6328 -diff -urNp linux-2.6.27.6/arch/x86/kernel/signal_32.c linux-2.6.27.6/arch/x86/kernel/signal_32.c
6329 ---- linux-2.6.27.6/arch/x86/kernel/signal_32.c 2008-11-07 12:55:34.000000000 -0500
6330 -+++ linux-2.6.27.6/arch/x86/kernel/signal_32.c 2008-11-18 03:38:44.000000000 -0500
6331 -@@ -378,9 +378,9 @@ setup_frame(int sig, struct k_sigaction
6332 - }
6333 -
6334 - if (current->mm->context.vdso)
6335 -- restorer = VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
6336 -+ restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
6337 - else
6338 -- restorer = &frame->retcode;
6339 -+ restorer = (void __user *)&frame->retcode;
6340 - if (ka->sa.sa_flags & SA_RESTORER)
6341 - restorer = ka->sa.sa_restorer;
6342 -
6343 -@@ -460,7 +460,7 @@ static int setup_rt_frame(int sig, struc
6344 - goto give_sigsegv;
6345 -
6346 - /* Set up to return from userspace. */
6347 -- restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
6348 -+ restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
6349 - if (ka->sa.sa_flags & SA_RESTORER)
6350 - restorer = ka->sa.sa_restorer;
6351 - err |= __put_user(restorer, &frame->pretcode);
6352 -@@ -590,7 +590,7 @@ static void do_signal(struct pt_regs *re
6353 - * X86_32: vm86 regs switched out by assembly code before reaching
6354 - * here, so testing against kernel CS suffices.
6355 - */
6356 -- if (!user_mode(regs))
6357 -+ if (!user_mode_novm(regs))
6358 - return;
6359 -
6360 - if (current_thread_info()->status & TS_RESTORE_SIGMASK)
6361 -diff -urNp linux-2.6.27.6/arch/x86/kernel/signal_64.c linux-2.6.27.6/arch/x86/kernel/signal_64.c
6362 ---- linux-2.6.27.6/arch/x86/kernel/signal_64.c 2008-11-07 12:55:34.000000000 -0500
6363 -+++ linux-2.6.27.6/arch/x86/kernel/signal_64.c 2008-11-18 03:38:44.000000000 -0500
6364 -@@ -312,8 +312,8 @@ static int setup_rt_frame(int sig, struc
6365 - err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
6366 - err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
6367 - if (sizeof(*set) == 16) {
6368 -- __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
6369 -- __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
6370 -+ err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
6371 -+ err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
6372 - } else
6373 - err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
6374 -
6375 -diff -urNp linux-2.6.27.6/arch/x86/kernel/smpboot.c linux-2.6.27.6/arch/x86/kernel/smpboot.c
6376 ---- linux-2.6.27.6/arch/x86/kernel/smpboot.c 2008-11-07 12:55:34.000000000 -0500
6377 -+++ linux-2.6.27.6/arch/x86/kernel/smpboot.c 2008-11-18 03:38:44.000000000 -0500
6378 -@@ -816,6 +816,11 @@ static int __cpuinit do_boot_cpu(int api
6379 - .cpu = cpu,
6380 - .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
6381 - };
6382 -+
6383 -+#ifdef CONFIG_PAX_KERNEXEC
6384 -+ unsigned long cr0;
6385 -+#endif
6386 -+
6387 - INIT_WORK(&c_idle.work, do_fork_idle);
6388 -
6389 - #ifdef CONFIG_X86_64
6390 -@@ -866,7 +871,17 @@ do_rest:
6391 - cpu_pda(cpu)->pcurrent = c_idle.idle;
6392 - clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
6393 - #endif
6394 -+
6395 -+#ifdef CONFIG_PAX_KERNEXEC
6396 -+ pax_open_kernel(cr0);
6397 -+#endif
6398 -+
6399 - early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
6400 -+
6401 -+#ifdef CONFIG_PAX_KERNEXEC
6402 -+ pax_close_kernel(cr0);
6403 -+#endif
6404 -+
6405 - initial_code = (unsigned long)start_secondary;
6406 - stack_start.sp = (void *) c_idle.idle->thread.sp;
6407 -
6408 -diff -urNp linux-2.6.27.6/arch/x86/kernel/smpcommon.c linux-2.6.27.6/arch/x86/kernel/smpcommon.c
6409 ---- linux-2.6.27.6/arch/x86/kernel/smpcommon.c 2008-11-07 12:55:34.000000000 -0500
6410 -+++ linux-2.6.27.6/arch/x86/kernel/smpcommon.c 2008-11-18 03:38:44.000000000 -0500
6411 -@@ -3,9 +3,10 @@
6412 - */
6413 - #include <linux/module.h>
6414 - #include <asm/smp.h>
6415 -+#include <asm/sections.h>
6416 -
6417 - #ifdef CONFIG_X86_32
6418 --DEFINE_PER_CPU(unsigned long, this_cpu_off);
6419 -+DEFINE_PER_CPU(unsigned long, this_cpu_off) = (unsigned long)__per_cpu_start;
6420 - EXPORT_PER_CPU_SYMBOL(this_cpu_off);
6421 -
6422 - /*
6423 -@@ -15,16 +16,19 @@ EXPORT_PER_CPU_SYMBOL(this_cpu_off);
6424 - */
6425 - __cpuinit void init_gdt(int cpu)
6426 - {
6427 -- struct desc_struct gdt;
6428 -+ struct desc_struct d, *gdt = get_cpu_gdt_table(cpu);
6429 -+ unsigned long base, limit;
6430 -
6431 -- pack_descriptor(&gdt, __per_cpu_offset[cpu], 0xFFFFF,
6432 -- 0x2 | DESCTYPE_S, 0x8);
6433 -- gdt.s = 1;
6434 -+ base = per_cpu_offset(cpu);
6435 -+ limit = PERCPU_ENOUGH_ROOM - 1;
6436 -+ if (limit < 64*1024)
6437 -+ pack_descriptor(&d, base, limit, 0x80 | DESCTYPE_S | 0x3, 0x4);
6438 -+ else
6439 -+ pack_descriptor(&d, base, limit >> PAGE_SHIFT, 0x80 | DESCTYPE_S | 0x3, 0xC);
6440 -
6441 -- write_gdt_entry(get_cpu_gdt_table(cpu),
6442 -- GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S);
6443 -+ write_gdt_entry(gdt, GDT_ENTRY_PERCPU, &d, DESCTYPE_S);
6444 -
6445 -- per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu];
6446 -+ per_cpu(this_cpu_off, cpu) = base;
6447 - per_cpu(cpu_number, cpu) = cpu;
6448 - }
6449 - #endif
6450 -diff -urNp linux-2.6.27.6/arch/x86/kernel/step.c linux-2.6.27.6/arch/x86/kernel/step.c
6451 ---- linux-2.6.27.6/arch/x86/kernel/step.c 2008-11-07 12:55:34.000000000 -0500
6452 -+++ linux-2.6.27.6/arch/x86/kernel/step.c 2008-11-18 03:38:44.000000000 -0500
6453 -@@ -23,22 +23,20 @@ unsigned long convert_ip_to_linear(struc
6454 - * and APM bios ones we just ignore here.
6455 - */
6456 - if ((seg & SEGMENT_TI_MASK) == SEGMENT_LDT) {
6457 -- u32 *desc;
6458 -+ struct desc_struct *desc;
6459 - unsigned long base;
6460 -
6461 -- seg &= ~7UL;
6462 -+ seg >>= 3;
6463 -
6464 - mutex_lock(&child->mm->context.lock);
6465 -- if (unlikely((seg >> 3) >= child->mm->context.size))
6466 -- addr = -1L; /* bogus selector, access would fault */
6467 -+ if (unlikely(seg >= child->mm->context.size))
6468 -+ addr = -EINVAL;
6469 - else {
6470 -- desc = child->mm->context.ldt + seg;
6471 -- base = ((desc[0] >> 16) |
6472 -- ((desc[1] & 0xff) << 16) |
6473 -- (desc[1] & 0xff000000));
6474 -+ desc = &child->mm->context.ldt[seg];
6475 -+ base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000);
6476 -
6477 - /* 16-bit code segment? */
6478 -- if (!((desc[1] >> 22) & 1))
6479 -+ if (!((desc->b >> 22) & 1))
6480 - addr &= 0xffff;
6481 - addr += base;
6482 - }
6483 -@@ -54,6 +52,9 @@ static int is_setting_trap_flag(struct t
6484 - unsigned char opcode[15];
6485 - unsigned long addr = convert_ip_to_linear(child, regs);
6486 -
6487 -+ if (addr == -EINVAL)
6488 -+ return 0;
6489 -+
6490 - copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
6491 - for (i = 0; i < copied; i++) {
6492 - switch (opcode[i]) {
6493 -@@ -75,7 +76,7 @@ static int is_setting_trap_flag(struct t
6494 -
6495 - #ifdef CONFIG_X86_64
6496 - case 0x40 ... 0x4f:
6497 -- if (regs->cs != __USER_CS)
6498 -+ if ((regs->cs & 0xffff) != __USER_CS)
6499 - /* 32-bit mode: register increment */
6500 - return 0;
6501 - /* 64-bit mode: REX prefix */
6502 -diff -urNp linux-2.6.27.6/arch/x86/kernel/syscall_table_32.S linux-2.6.27.6/arch/x86/kernel/syscall_table_32.S
6503 ---- linux-2.6.27.6/arch/x86/kernel/syscall_table_32.S 2008-11-07 12:55:34.000000000 -0500
6504 -+++ linux-2.6.27.6/arch/x86/kernel/syscall_table_32.S 2008-11-18 03:38:44.000000000 -0500
6505 -@@ -1,3 +1,4 @@
6506 -+.section .rodata,"a",@progbits
6507 - ENTRY(sys_call_table)
6508 - .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
6509 - .long sys_exit
6510 -diff -urNp linux-2.6.27.6/arch/x86/kernel/sys_i386_32.c linux-2.6.27.6/arch/x86/kernel/sys_i386_32.c
6511 ---- linux-2.6.27.6/arch/x86/kernel/sys_i386_32.c 2008-11-07 12:55:34.000000000 -0500
6512 -+++ linux-2.6.27.6/arch/x86/kernel/sys_i386_32.c 2008-11-18 03:38:44.000000000 -0500
6513 -@@ -22,6 +22,21 @@
6514 - #include <linux/uaccess.h>
6515 - #include <linux/unistd.h>
6516 -
6517 -+int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
6518 -+{
6519 -+ unsigned long pax_task_size = TASK_SIZE;
6520 -+
6521 -+#ifdef CONFIG_PAX_SEGMEXEC
6522 -+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
6523 -+ pax_task_size = SEGMEXEC_TASK_SIZE;
6524 -+#endif
6525 -+
6526 -+ if (len > pax_task_size || addr > pax_task_size - len)
6527 -+ return -EINVAL;
6528 -+
6529 -+ return 0;
6530 -+}
6531 -+
6532 - asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
6533 - unsigned long prot, unsigned long flags,
6534 - unsigned long fd, unsigned long pgoff)
6535 -@@ -81,6 +96,205 @@ out:
6536 - return err;
6537 - }
6538 -
6539 -+unsigned long
6540 -+arch_get_unmapped_area(struct file *filp, unsigned long addr,
6541 -+ unsigned long len, unsigned long pgoff, unsigned long flags)
6542 -+{
6543 -+ struct mm_struct *mm = current->mm;
6544 -+ struct vm_area_struct *vma;
6545 -+ unsigned long start_addr, pax_task_size = TASK_SIZE;
6546 -+
6547 -+#ifdef CONFIG_PAX_SEGMEXEC
6548 -+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
6549 -+ pax_task_size = SEGMEXEC_TASK_SIZE;
6550 -+#endif
6551 -+
6552 -+ if (len > pax_task_size)
6553 -+ return -ENOMEM;
6554 -+
6555 -+ if (flags & MAP_FIXED)
6556 -+ return addr;
6557 -+
6558 -+#ifdef CONFIG_PAX_RANDMMAP
6559 -+ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6560 -+#endif
6561 -+
6562 -+ if (addr) {
6563 -+ addr = PAGE_ALIGN(addr);
6564 -+ vma = find_vma(mm, addr);
6565 -+ if (pax_task_size - len >= addr &&
6566 -+ (!vma || addr + len <= vma->vm_start))
6567 -+ return addr;
6568 -+ }
6569 -+ if (len > mm->cached_hole_size) {
6570 -+ start_addr = addr = mm->free_area_cache;
6571 -+ } else {
6572 -+ start_addr = addr = mm->mmap_base;
6573 -+ mm->cached_hole_size = 0;
6574 -+ }
6575 -+
6576 -+#ifdef CONFIG_PAX_PAGEEXEC
6577 -+ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
6578 -+ start_addr = 0x00110000UL;
6579 -+
6580 -+#ifdef CONFIG_PAX_RANDMMAP
6581 -+ if (mm->pax_flags & MF_PAX_RANDMMAP)
6582 -+ start_addr += mm->delta_mmap & 0x03FFF000UL;
6583 -+#endif
6584 -+
6585 -+ if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
6586 -+ start_addr = addr = mm->mmap_base;
6587 -+ else
6588 -+ addr = start_addr;
6589 -+ }
6590 -+#endif
6591 -+
6592 -+full_search:
6593 -+ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
6594 -+ /* At this point: (!vma || addr < vma->vm_end). */
6595 -+ if (pax_task_size - len < addr) {
6596 -+ /*
6597 -+ * Start a new search - just in case we missed
6598 -+ * some holes.
6599 -+ */
6600 -+ if (start_addr != mm->mmap_base) {
6601 -+ start_addr = addr = mm->mmap_base;
6602 -+ mm->cached_hole_size = 0;
6603 -+ goto full_search;
6604 -+ }
6605 -+ return -ENOMEM;
6606 -+ }
6607 -+ if (!vma || addr + len <= vma->vm_start) {
6608 -+ /*
6609 -+ * Remember the place where we stopped the search:
6610 -+ */
6611 -+ mm->free_area_cache = addr + len;
6612 -+ return addr;
6613 -+ }
6614 -+ if (addr + mm->cached_hole_size < vma->vm_start)
6615 -+ mm->cached_hole_size = vma->vm_start - addr;
6616 -+ addr = vma->vm_end;
6617 -+ if (mm->start_brk <= addr && addr < mm->mmap_base) {
6618 -+ start_addr = addr = mm->mmap_base;
6619 -+ mm->cached_hole_size = 0;
6620 -+ goto full_search;
6621 -+ }
6622 -+ }
6623 -+}
6624 -+
6625 -+unsigned long
6626 -+arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
6627 -+ const unsigned long len, const unsigned long pgoff,
6628 -+ const unsigned long flags)
6629 -+{
6630 -+ struct vm_area_struct *vma;
6631 -+ struct mm_struct *mm = current->mm;
6632 -+ unsigned long base = mm->mmap_base, addr = addr0, pax_task_size = TASK_SIZE;
6633 -+
6634 -+#ifdef CONFIG_PAX_SEGMEXEC
6635 -+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
6636 -+ pax_task_size = SEGMEXEC_TASK_SIZE;
6637 -+#endif
6638 -+
6639 -+ /* requested length too big for entire address space */
6640 -+ if (len > pax_task_size)
6641 -+ return -ENOMEM;
6642 -+
6643 -+ if (flags & MAP_FIXED)
6644 -+ return addr;
6645 -+
6646 -+#ifdef CONFIG_PAX_PAGEEXEC
6647 -+ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
6648 -+ goto bottomup;
6649 -+#endif
6650 -+
6651 -+#ifdef CONFIG_PAX_RANDMMAP
6652 -+ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6653 -+#endif
6654 -+
6655 -+ /* requesting a specific address */
6656 -+ if (addr) {
6657 -+ addr = PAGE_ALIGN(addr);
6658 -+ vma = find_vma(mm, addr);
6659 -+ if (pax_task_size - len >= addr &&
6660 -+ (!vma || addr + len <= vma->vm_start))
6661 -+ return addr;
6662 -+ }
6663 -+
6664 -+ /* check if free_area_cache is useful for us */
6665 -+ if (len <= mm->cached_hole_size) {
6666 -+ mm->cached_hole_size = 0;
6667 -+ mm->free_area_cache = mm->mmap_base;
6668 -+ }
6669 -+
6670 -+ /* either no address requested or can't fit in requested address hole */
6671 -+ addr = mm->free_area_cache;
6672 -+
6673 -+ /* make sure it can fit in the remaining address space */
6674 -+ if (addr > len) {
6675 -+ vma = find_vma(mm, addr-len);
6676 -+ if (!vma || addr <= vma->vm_start)
6677 -+ /* remember the address as a hint for next time */
6678 -+ return (mm->free_area_cache = addr-len);
6679 -+ }
6680 -+
6681 -+ if (mm->mmap_base < len)
6682 -+ goto bottomup;
6683 -+
6684 -+ addr = mm->mmap_base-len;
6685 -+
6686 -+ do {
6687 -+ /*
6688 -+ * Lookup failure means no vma is above this address,
6689 -+ * else if new region fits below vma->vm_start,
6690 -+ * return with success:
6691 -+ */
6692 -+ vma = find_vma(mm, addr);
6693 -+ if (!vma || addr+len <= vma->vm_start)
6694 -+ /* remember the address as a hint for next time */
6695 -+ return (mm->free_area_cache = addr);
6696 -+
6697 -+ /* remember the largest hole we saw so far */
6698 -+ if (addr + mm->cached_hole_size < vma->vm_start)
6699 -+ mm->cached_hole_size = vma->vm_start - addr;
6700 -+
6701 -+ /* try just below the current vma->vm_start */
6702 -+ addr = vma->vm_start-len;
6703 -+ } while (len < vma->vm_start);
6704 -+
6705 -+bottomup:
6706 -+ /*
6707 -+ * A failed mmap() very likely causes application failure,
6708 -+ * so fall back to the bottom-up function here. This scenario
6709 -+ * can happen with large stack limits and large mmap()
6710 -+ * allocations.
6711 -+ */
6712 -+
6713 -+#ifdef CONFIG_PAX_SEGMEXEC
6714 -+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
6715 -+ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
6716 -+ else
6717 -+#endif
6718 -+
6719 -+ mm->mmap_base = TASK_UNMAPPED_BASE;
6720 -+
6721 -+#ifdef CONFIG_PAX_RANDMMAP
6722 -+ if (mm->pax_flags & MF_PAX_RANDMMAP)
6723 -+ mm->mmap_base += mm->delta_mmap;
6724 -+#endif
6725 -+
6726 -+ mm->free_area_cache = mm->mmap_base;
6727 -+ mm->cached_hole_size = ~0UL;
6728 -+ addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
6729 -+ /*
6730 -+ * Restore the topdown base:
6731 -+ */
6732 -+ mm->mmap_base = base;
6733 -+ mm->free_area_cache = base;
6734 -+ mm->cached_hole_size = ~0UL;
6735 -+
6736 -+ return addr;
6737 -+}
6738 -
6739 - struct sel_arg_struct {
6740 - unsigned long n;
6741 -diff -urNp linux-2.6.27.6/arch/x86/kernel/sys_x86_64.c linux-2.6.27.6/arch/x86/kernel/sys_x86_64.c
6742 ---- linux-2.6.27.6/arch/x86/kernel/sys_x86_64.c 2008-11-07 12:55:34.000000000 -0500
6743 -+++ linux-2.6.27.6/arch/x86/kernel/sys_x86_64.c 2008-11-18 03:38:44.000000000 -0500
6744 -@@ -45,8 +45,8 @@ out:
6745 - return error;
6746 - }
6747 -
6748 --static void find_start_end(unsigned long flags, unsigned long *begin,
6749 -- unsigned long *end)
6750 -+static void find_start_end(struct mm_struct *mm, unsigned long flags,
6751 -+ unsigned long *begin, unsigned long *end)
6752 - {
6753 - if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
6754 - unsigned long new_begin;
6755 -@@ -65,7 +65,7 @@ static void find_start_end(unsigned long
6756 - *begin = new_begin;
6757 - }
6758 - } else {
6759 -- *begin = TASK_UNMAPPED_BASE;
6760 -+ *begin = mm->mmap_base;
6761 - *end = TASK_SIZE;
6762 - }
6763 - }
6764 -@@ -82,11 +82,15 @@ arch_get_unmapped_area(struct file *filp
6765 - if (flags & MAP_FIXED)
6766 - return addr;
6767 -
6768 -- find_start_end(flags, &begin, &end);
6769 -+ find_start_end(mm, flags, &begin, &end);
6770 -
6771 - if (len > end)
6772 - return -ENOMEM;
6773 -
6774 -+#ifdef CONFIG_PAX_RANDMMAP
6775 -+ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6776 -+#endif
6777 -+
6778 - if (addr) {
6779 - addr = PAGE_ALIGN(addr);
6780 - vma = find_vma(mm, addr);
6781 -@@ -141,7 +145,7 @@ arch_get_unmapped_area_topdown(struct fi
6782 - {
6783 - struct vm_area_struct *vma;
6784 - struct mm_struct *mm = current->mm;
6785 -- unsigned long addr = addr0;
6786 -+ unsigned long base = mm->mmap_base, addr = addr0;
6787 -
6788 - /* requested length too big for entire address space */
6789 - if (len > TASK_SIZE)
6790 -@@ -154,6 +158,10 @@ arch_get_unmapped_area_topdown(struct fi
6791 - if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT))
6792 - goto bottomup;
6793 -
6794 -+#ifdef CONFIG_PAX_RANDMMAP
6795 -+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
6796 -+#endif
6797 -+
6798 - /* requesting a specific address */
6799 - if (addr) {
6800 - addr = PAGE_ALIGN(addr);
6801 -@@ -211,13 +219,21 @@ bottomup:
6802 - * can happen with large stack limits and large mmap()
6803 - * allocations.
6804 - */
6805 -+ mm->mmap_base = TASK_UNMAPPED_BASE;
6806 -+
6807 -+#ifdef CONFIG_PAX_RANDMMAP
6808 -+ if (mm->pax_flags & MF_PAX_RANDMMAP)
6809 -+ mm->mmap_base += mm->delta_mmap;
6810 -+#endif
6811 -+
6812 -+ mm->free_area_cache = mm->mmap_base;
6813 - mm->cached_hole_size = ~0UL;
6814 -- mm->free_area_cache = TASK_UNMAPPED_BASE;
6815 - addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
6816 - /*
6817 - * Restore the topdown base:
6818 - */
6819 -- mm->free_area_cache = mm->mmap_base;
6820 -+ mm->mmap_base = base;
6821 -+ mm->free_area_cache = base;
6822 - mm->cached_hole_size = ~0UL;
6823 -
6824 - return addr;
6825 -diff -urNp linux-2.6.27.6/arch/x86/kernel/time_32.c linux-2.6.27.6/arch/x86/kernel/time_32.c
6826 ---- linux-2.6.27.6/arch/x86/kernel/time_32.c 2008-11-07 12:55:34.000000000 -0500
6827 -+++ linux-2.6.27.6/arch/x86/kernel/time_32.c 2008-11-18 03:38:44.000000000 -0500
6828 -@@ -49,20 +49,30 @@ unsigned long profile_pc(struct pt_regs
6829 - if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs) &&
6830 - in_lock_functions(pc)) {
6831 - #ifdef CONFIG_FRAME_POINTER
6832 -- return *(unsigned long *)(regs->bp + 4);
6833 -+ return ktla_ktva(*(unsigned long *)(regs->bp + 4));
6834 - #else
6835 - unsigned long *sp = (unsigned long *)&regs->sp;
6836 -
6837 - /* Return address is either directly at stack pointer
6838 - or above a saved flags. Eflags has bits 22-31 zero,
6839 - kernel addresses don't. */
6840 -+
6841 -+#ifdef CONFIG_PAX_KERNEXEC
6842 -+ return ktla_ktva(sp[0]);
6843 -+#else
6844 - if (sp[0] >> 22)
6845 - return sp[0];
6846 - if (sp[1] >> 22)
6847 - return sp[1];
6848 - #endif
6849 -+
6850 -+#endif
6851 - }
6852 - #endif
6853 -+
6854 -+ if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs))
6855 -+ pc = ktla_ktva(pc);
6856 -+
6857 - return pc;
6858 - }
6859 - EXPORT_SYMBOL(profile_pc);
6860 -diff -urNp linux-2.6.27.6/arch/x86/kernel/tlb_32.c linux-2.6.27.6/arch/x86/kernel/tlb_32.c
6861 ---- linux-2.6.27.6/arch/x86/kernel/tlb_32.c 2008-11-07 12:55:34.000000000 -0500
6862 -+++ linux-2.6.27.6/arch/x86/kernel/tlb_32.c 2008-11-18 03:38:44.000000000 -0500
6863 -@@ -5,7 +5,7 @@
6864 - #include <asm/tlbflush.h>
6865 -
6866 - DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate)
6867 -- ____cacheline_aligned = { &init_mm, 0, };
6868 -+ ____cacheline_aligned = { &init_mm, 0, {0} };
6869 -
6870 - /* must come after the send_IPI functions above for inlining */
6871 - #include <mach_ipi.h>
6872 -diff -urNp linux-2.6.27.6/arch/x86/kernel/tls.c linux-2.6.27.6/arch/x86/kernel/tls.c
6873 ---- linux-2.6.27.6/arch/x86/kernel/tls.c 2008-11-07 12:55:34.000000000 -0500
6874 -+++ linux-2.6.27.6/arch/x86/kernel/tls.c 2008-11-18 03:38:44.000000000 -0500
6875 -@@ -84,6 +84,11 @@ int do_set_thread_area(struct task_struc
6876 - if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
6877 - return -EINVAL;
6878 -
6879 -+#ifdef CONFIG_PAX_SEGMEXEC
6880 -+ if ((p->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
6881 -+ return -EINVAL;
6882 -+#endif
6883 -+
6884 - set_tls_desc(p, idx, &info, 1);
6885 -
6886 - return 0;
6887 -diff -urNp linux-2.6.27.6/arch/x86/kernel/traps_32.c linux-2.6.27.6/arch/x86/kernel/traps_32.c
6888 ---- linux-2.6.27.6/arch/x86/kernel/traps_32.c 2008-11-07 12:55:34.000000000 -0500
6889 -+++ linux-2.6.27.6/arch/x86/kernel/traps_32.c 2008-11-18 03:38:44.000000000 -0500
6890 -@@ -70,14 +70,6 @@ asmlinkage int system_call(void);
6891 - /* Do we ignore FPU interrupts ? */
6892 - char ignore_fpu_irq;
6893 -
6894 --/*
6895 -- * The IDT has to be page-aligned to simplify the Pentium
6896 -- * F0 0F bug workaround.. We have a special link segment
6897 -- * for this.
6898 -- */
6899 --gate_desc idt_table[256]
6900 -- __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, };
6901 --
6902 - int panic_on_unrecovered_nmi;
6903 - int kstack_depth_to_print = 24;
6904 - static unsigned int code_bytes = 64;
6905 -@@ -320,21 +312,22 @@ void show_registers(struct pt_regs *regs
6906 - * When in-kernel, we also print out the stack and code at the
6907 - * time of the fault..
6908 - */
6909 -- if (!user_mode_vm(regs)) {
6910 -+ if (!user_mode(regs)) {
6911 - unsigned int code_prologue = code_bytes * 43 / 64;
6912 - unsigned int code_len = code_bytes;
6913 - unsigned char c;
6914 - u8 *ip;
6915 -+ unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->cs) >> 3]);
6916 -
6917 - printk("\n" KERN_EMERG "Stack: ");
6918 - show_stack_log_lvl(NULL, regs, &regs->sp, 0, KERN_EMERG);
6919 -
6920 - printk(KERN_EMERG "Code: ");
6921 -
6922 -- ip = (u8 *)regs->ip - code_prologue;
6923 -+ ip = (u8 *)regs->ip - code_prologue + cs_base;
6924 - if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
6925 - /* try starting at EIP */
6926 -- ip = (u8 *)regs->ip;
6927 -+ ip = (u8 *)regs->ip + cs_base;
6928 - code_len = code_len - code_prologue + 1;
6929 - }
6930 - for (i = 0; i < code_len; i++, ip++) {
6931 -@@ -343,7 +336,7 @@ void show_registers(struct pt_regs *regs
6932 - printk(" Bad EIP value.");
6933 - break;
6934 - }
6935 -- if (ip == (u8 *)regs->ip)
6936 -+ if (ip == (u8 *)regs->ip + cs_base)
6937 - printk("<%02x> ", c);
6938 - else
6939 - printk("%02x ", c);
6940 -@@ -356,6 +349,7 @@ int is_valid_bugaddr(unsigned long ip)
6941 - {
6942 - unsigned short ud2;
6943 -
6944 -+ ip = ktla_ktva(ip);
6945 - if (ip < PAGE_OFFSET)
6946 - return 0;
6947 - if (probe_kernel_address((unsigned short *)ip, ud2))
6948 -@@ -469,7 +463,7 @@ void die(const char *str, struct pt_regs
6949 - static inline void
6950 - die_if_kernel(const char *str, struct pt_regs *regs, long err)
6951 - {
6952 -- if (!user_mode_vm(regs))
6953 -+ if (!user_mode(regs))
6954 - die(str, regs, err);
6955 - }
6956 -
6957 -@@ -479,7 +473,7 @@ do_trap(int trapnr, int signr, char *str
6958 - {
6959 - struct task_struct *tsk = current;
6960 -
6961 -- if (regs->flags & X86_VM_MASK) {
6962 -+ if (v8086_mode(regs)) {
6963 - if (vm86)
6964 - goto vm86_trap;
6965 - goto trap_signal;
6966 -@@ -513,6 +507,12 @@ kernel_trap:
6967 - tsk->thread.trap_no = trapnr;
6968 - die(str, regs, error_code);
6969 - }
6970 -+
6971 -+#ifdef CONFIG_PAX_REFCOUNT
6972 -+ if (trapnr == 4)
6973 -+ pax_report_refcount_overflow(regs);
6974 -+#endif
6975 -+
6976 - return;
6977 -
6978 - vm86_trap:
6979 -@@ -595,7 +595,7 @@ do_general_protection(struct pt_regs *re
6980 - int cpu;
6981 -
6982 - cpu = get_cpu();
6983 -- tss = &per_cpu(init_tss, cpu);
6984 -+ tss = init_tss + cpu;
6985 - thread = &current->thread;
6986 -
6987 - /*
6988 -@@ -627,13 +627,29 @@ do_general_protection(struct pt_regs *re
6989 - }
6990 - put_cpu();
6991 -
6992 -- if (regs->flags & X86_VM_MASK)
6993 -+ if (v8086_mode(regs))
6994 - goto gp_in_vm86;
6995 -
6996 - tsk = current;
6997 -- if (!user_mode(regs))
6998 -+ if (!user_mode_novm(regs))
6999 - goto gp_in_kernel;
7000 -
7001 -+#ifdef CONFIG_PAX_PAGEEXEC
7002 -+ if (!nx_enabled && tsk->mm && (tsk->mm->pax_flags & MF_PAX_PAGEEXEC)) {
7003 -+ struct mm_struct *mm = tsk->mm;
7004 -+ unsigned long limit;
7005 -+
7006 -+ down_write(&mm->mmap_sem);
7007 -+ limit = mm->context.user_cs_limit;
7008 -+ if (limit < TASK_SIZE) {
7009 -+ track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC);
7010 -+ up_write(&mm->mmap_sem);
7011 -+ return;
7012 -+ }
7013 -+ up_write(&mm->mmap_sem);
7014 -+ }
7015 -+#endif
7016 -+
7017 - tsk->thread.error_code = error_code;
7018 - tsk->thread.trap_no = 13;
7019 -
7020 -@@ -664,6 +680,13 @@ gp_in_kernel:
7021 - if (notify_die(DIE_GPF, "general protection fault", regs,
7022 - error_code, 13, SIGSEGV) == NOTIFY_STOP)
7023 - return;
7024 -+
7025 -+#ifdef CONFIG_PAX_KERNEXEC
7026 -+ if ((regs->cs & 0xFFFF) == __KERNEL_CS)
7027 -+ die("PAX: suspicious general protection fault", regs, error_code);
7028 -+ else
7029 -+#endif
7030 -+
7031 - die("general protection fault", regs, error_code);
7032 - }
7033 -
7034 -@@ -766,7 +789,7 @@ void notrace __kprobes die_nmi(char *str
7035 - * If we are in kernel we are probably nested up pretty bad
7036 - * and might aswell get out now while we still can:
7037 - */
7038 -- if (!user_mode_vm(regs)) {
7039 -+ if (!user_mode(regs)) {
7040 - current->thread.trap_no = 2;
7041 - crash_kexec(regs);
7042 - }
7043 -@@ -915,7 +938,7 @@ void __kprobes do_debug(struct pt_regs *
7044 - goto clear_dr7;
7045 - }
7046 -
7047 -- if (regs->flags & X86_VM_MASK)
7048 -+ if (v8086_mode(regs))
7049 - goto debug_vm86;
7050 -
7051 - /* Save debug status register where ptrace can see it */
7052 -@@ -931,7 +954,7 @@ void __kprobes do_debug(struct pt_regs *
7053 - * check for kernel mode by just checking the CPL
7054 - * of CS.
7055 - */
7056 -- if (!user_mode(regs))
7057 -+ if (!user_mode_novm(regs))
7058 - goto clear_TF_reenable;
7059 - }
7060 -
7061 -@@ -1086,7 +1109,7 @@ void do_simd_coprocessor_error(struct pt
7062 - * Handle strange cache flush from user space exception
7063 - * in all other cases. This is undocumented behaviour.
7064 - */
7065 -- if (regs->flags & X86_VM_MASK) {
7066 -+ if (v8086_mode(regs)) {
7067 - handle_vm86_fault((struct kernel_vm86_regs *)regs, error_code);
7068 - return;
7069 - }
7070 -@@ -1106,19 +1129,14 @@ void do_spurious_interrupt_bug(struct pt
7071 -
7072 - unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp)
7073 - {
7074 -- struct desc_struct *gdt = get_cpu_gdt_table(smp_processor_id());
7075 - unsigned long base = (kesp - uesp) & -THREAD_SIZE;
7076 - unsigned long new_kesp = kesp - base;
7077 - unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
7078 -- __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
7079 -+ struct desc_struct ss;
7080 -
7081 - /* Set up base for espfix segment */
7082 -- desc &= 0x00f0ff0000000000ULL;
7083 -- desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
7084 -- ((((__u64)base) << 32) & 0xff00000000000000ULL) |
7085 -- ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
7086 -- (lim_pages & 0xffff);
7087 -- *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
7088 -+ pack_descriptor(&ss, base, lim_pages, 0x93, 0xC);
7089 -+ write_gdt_entry(get_cpu_gdt_table(smp_processor_id()), GDT_ENTRY_ESPFIX_SS, &ss, DESCTYPE_S);
7090 -
7091 - return new_kesp;
7092 - }
7093 -diff -urNp linux-2.6.27.6/arch/x86/kernel/traps_64.c linux-2.6.27.6/arch/x86/kernel/traps_64.c
7094 ---- linux-2.6.27.6/arch/x86/kernel/traps_64.c 2008-11-07 12:55:34.000000000 -0500
7095 -+++ linux-2.6.27.6/arch/x86/kernel/traps_64.c 2008-11-18 03:38:44.000000000 -0500
7096 -@@ -634,6 +634,12 @@ kernel_trap:
7097 - tsk->thread.trap_no = trapnr;
7098 - die(str, regs, error_code);
7099 - }
7100 -+
7101 -+#ifdef CONFIG_PAX_REFCOUNT
7102 -+ if (trapnr == 4)
7103 -+ pax_report_refcount_overflow(regs);
7104 -+#endif
7105 -+
7106 - return;
7107 - }
7108 -
7109 -diff -urNp linux-2.6.27.6/arch/x86/kernel/tsc.c linux-2.6.27.6/arch/x86/kernel/tsc.c
7110 ---- linux-2.6.27.6/arch/x86/kernel/tsc.c 2008-11-17 20:03:30.000000000 -0500
7111 -+++ linux-2.6.27.6/arch/x86/kernel/tsc.c 2008-11-18 03:38:44.000000000 -0500
7112 -@@ -554,7 +554,7 @@ static struct dmi_system_id __initdata b
7113 - DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
7114 - },
7115 - },
7116 -- {}
7117 -+ { NULL, NULL, {{0, NULL}}, NULL}
7118 - };
7119 -
7120 - /*
7121 -diff -urNp linux-2.6.27.6/arch/x86/kernel/vm86_32.c linux-2.6.27.6/arch/x86/kernel/vm86_32.c
7122 ---- linux-2.6.27.6/arch/x86/kernel/vm86_32.c 2008-11-07 12:55:34.000000000 -0500
7123 -+++ linux-2.6.27.6/arch/x86/kernel/vm86_32.c 2008-11-18 03:38:44.000000000 -0500
7124 -@@ -147,7 +147,7 @@ struct pt_regs *save_v86_state(struct ke
7125 - do_exit(SIGSEGV);
7126 - }
7127 -
7128 -- tss = &per_cpu(init_tss, get_cpu());
7129 -+ tss = init_tss + get_cpu();
7130 - current->thread.sp0 = current->thread.saved_sp0;
7131 - current->thread.sysenter_cs = __KERNEL_CS;
7132 - load_sp0(tss, &current->thread);
7133 -@@ -324,7 +324,7 @@ static void do_sys_vm86(struct kernel_vm
7134 - tsk->thread.saved_fs = info->regs32->fs;
7135 - savesegment(gs, tsk->thread.saved_gs);
7136 -
7137 -- tss = &per_cpu(init_tss, get_cpu());
7138 -+ tss = init_tss + get_cpu();
7139 - tsk->thread.sp0 = (unsigned long) &info->VM86_TSS_ESP0;
7140 - if (cpu_has_sep)
7141 - tsk->thread.sysenter_cs = 0;
7142 -diff -urNp linux-2.6.27.6/arch/x86/kernel/vmi_32.c linux-2.6.27.6/arch/x86/kernel/vmi_32.c
7143 ---- linux-2.6.27.6/arch/x86/kernel/vmi_32.c 2008-11-07 12:55:34.000000000 -0500
7144 -+++ linux-2.6.27.6/arch/x86/kernel/vmi_32.c 2008-11-18 03:38:44.000000000 -0500
7145 -@@ -102,18 +102,43 @@ static unsigned patch_internal(int call,
7146 - {
7147 - u64 reloc;
7148 - struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
7149 -+
7150 -+#ifdef CONFIG_PAX_KERNEXEC
7151 -+ unsigned long cr0;
7152 -+#endif
7153 -+
7154 - reloc = call_vrom_long_func(vmi_rom, get_reloc, call);
7155 - switch(rel->type) {
7156 - case VMI_RELOCATION_CALL_REL:
7157 - BUG_ON(len < 5);
7158 -+
7159 -+#ifdef CONFIG_PAX_KERNEXEC
7160 -+ pax_open_kernel(cr0);
7161 -+#endif
7162 -+
7163 - *(char *)insnbuf = MNEM_CALL;
7164 - patch_offset(insnbuf, ip, (unsigned long)rel->eip);
7165 -+
7166 -+#ifdef CONFIG_PAX_KERNEXEC
7167 -+ pax_close_kernel(cr0);
7168 -+#endif
7169 -+
7170 - return 5;
7171 -
7172 - case VMI_RELOCATION_JUMP_REL:
7173 - BUG_ON(len < 5);
7174 -+
7175 -+#ifdef CONFIG_PAX_KERNEXEC
7176 -+ pax_open_kernel(cr0);
7177 -+#endif
7178 -+
7179 - *(char *)insnbuf = MNEM_JMP;
7180 - patch_offset(insnbuf, ip, (unsigned long)rel->eip);
7181 -+
7182 -+#ifdef CONFIG_PAX_KERNEXEC
7183 -+ pax_close_kernel(cr0);
7184 -+#endif
7185 -+
7186 - return 5;
7187 -
7188 - case VMI_RELOCATION_NOP:
7189 -@@ -516,14 +541,14 @@ static void vmi_set_pud(pud_t *pudp, pud
7190 -
7191 - static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
7192 - {
7193 -- const pte_t pte = { .pte = 0 };
7194 -+ const pte_t pte = __pte(0ULL);
7195 - vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE);
7196 - vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
7197 - }
7198 -
7199 - static void vmi_pmd_clear(pmd_t *pmd)
7200 - {
7201 -- const pte_t pte = { .pte = 0 };
7202 -+ const pte_t pte = __pte(0ULL);
7203 - vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD);
7204 - vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD);
7205 - }
7206 -@@ -552,8 +577,8 @@ vmi_startup_ipi_hook(int phys_apicid, un
7207 - ap.ss = __KERNEL_DS;
7208 - ap.esp = (unsigned long) start_esp;
7209 -
7210 -- ap.ds = __USER_DS;
7211 -- ap.es = __USER_DS;
7212 -+ ap.ds = __KERNEL_DS;
7213 -+ ap.es = __KERNEL_DS;
7214 - ap.fs = __KERNEL_PERCPU;
7215 - ap.gs = 0;
7216 -
7217 -@@ -748,12 +773,20 @@ static inline int __init activate_vmi(vo
7218 - u64 reloc;
7219 - const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc;
7220 -
7221 -+#ifdef CONFIG_PAX_KERNEXEC
7222 -+ unsigned long cr0;
7223 -+#endif
7224 -+
7225 - if (call_vrom_func(vmi_rom, vmi_init) != 0) {
7226 - printk(KERN_ERR "VMI ROM failed to initialize!");
7227 - return 0;
7228 - }
7229 - savesegment(cs, kernel_cs);
7230 -
7231 -+#ifdef CONFIG_PAX_KERNEXEC
7232 -+ pax_open_kernel(cr0);
7233 -+#endif
7234 -+
7235 - pv_info.paravirt_enabled = 1;
7236 - pv_info.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
7237 - pv_info.name = "vmi";
7238 -@@ -943,6 +976,10 @@ static inline int __init activate_vmi(vo
7239 -
7240 - para_fill(pv_irq_ops.safe_halt, Halt);
7241 -
7242 -+#ifdef CONFIG_PAX_KERNEXEC
7243 -+ pax_close_kernel(cr0);
7244 -+#endif
7245 -+
7246 - /*
7247 - * Alternative instruction rewriting doesn't happen soon enough
7248 - * to convert VMI_IRET to a call instead of a jump; so we have
7249 -diff -urNp linux-2.6.27.6/arch/x86/kernel/vmlinux_32.lds.S linux-2.6.27.6/arch/x86/kernel/vmlinux_32.lds.S
7250 ---- linux-2.6.27.6/arch/x86/kernel/vmlinux_32.lds.S 2008-11-07 12:55:34.000000000 -0500
7251 -+++ linux-2.6.27.6/arch/x86/kernel/vmlinux_32.lds.S 2008-11-18 03:38:44.000000000 -0500
7252 -@@ -15,6 +15,20 @@
7253 - #include <asm/page.h>
7254 - #include <asm/cache.h>
7255 - #include <asm/boot.h>
7256 -+#include <asm/segment.h>
7257 -+
7258 -+#ifdef CONFIG_X86_PAE
7259 -+#define PMD_SHIFT 21
7260 -+#else
7261 -+#define PMD_SHIFT 22
7262 -+#endif
7263 -+#define PMD_SIZE (1 << PMD_SHIFT)
7264 -+
7265 -+#ifdef CONFIG_PAX_KERNEXEC
7266 -+#define __KERNEL_TEXT_OFFSET (__PAGE_OFFSET + (((____LOAD_PHYSICAL_ADDR + 2*(PMD_SIZE - 1)) - 1) & ~(PMD_SIZE - 1)))
7267 -+#else
7268 -+#define __KERNEL_TEXT_OFFSET 0
7269 -+#endif
7270 -
7271 - OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
7272 - OUTPUT_ARCH(i386)
7273 -@@ -22,81 +36,23 @@ ENTRY(phys_startup_32)
7274 - jiffies = jiffies_64;
7275 -
7276 - PHDRS {
7277 -- text PT_LOAD FLAGS(5); /* R_E */
7278 -- data PT_LOAD FLAGS(7); /* RWE */
7279 -- note PT_NOTE FLAGS(0); /* ___ */
7280 -+ initdata PT_LOAD FLAGS(6); /* RW_ */
7281 -+ percpu PT_LOAD FLAGS(6); /* RW_ */
7282 -+ inittext PT_LOAD FLAGS(5); /* R_E */
7283 -+ text PT_LOAD FLAGS(5); /* R_E */
7284 -+ rodata PT_LOAD FLAGS(4); /* R__ */
7285 -+ data PT_LOAD FLAGS(6); /* RW_ */
7286 -+ note PT_NOTE FLAGS(0); /* ___ */
7287 - }
7288 - SECTIONS
7289 - {
7290 -- . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
7291 -- phys_startup_32 = startup_32 - LOAD_OFFSET;
7292 --
7293 -- .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
7294 -- _text = .; /* Text and read-only data */
7295 -- *(.text.head)
7296 -- } :text = 0x9090
7297 --
7298 -- /* read-only */
7299 -- .text : AT(ADDR(.text) - LOAD_OFFSET) {
7300 -- . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
7301 -- *(.text.page_aligned)
7302 -- TEXT_TEXT
7303 -- SCHED_TEXT
7304 -- LOCK_TEXT
7305 -- KPROBES_TEXT
7306 -- *(.fixup)
7307 -- *(.gnu.warning)
7308 -- _etext = .; /* End of text section */
7309 -- } :text = 0x9090
7310 --
7311 -- NOTES :text :note
7312 -+ . = LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR;
7313 -
7314 -- . = ALIGN(16); /* Exception table */
7315 -- __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
7316 -- __start___ex_table = .;
7317 -- *(__ex_table)
7318 -- __stop___ex_table = .;
7319 -- } :text = 0x9090
7320 --
7321 -- RODATA
7322 --
7323 -- /* writeable */
7324 -- . = ALIGN(PAGE_SIZE);
7325 -- .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
7326 -- DATA_DATA
7327 -- CONSTRUCTORS
7328 -- } :data
7329 --
7330 -- . = ALIGN(PAGE_SIZE);
7331 -- .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
7332 -- __nosave_begin = .;
7333 -- *(.data.nosave)
7334 -- . = ALIGN(PAGE_SIZE);
7335 -- __nosave_end = .;
7336 -- }
7337 --
7338 -- . = ALIGN(PAGE_SIZE);
7339 -- .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7340 -- *(.data.page_aligned)
7341 -- *(.data.idt)
7342 -- }
7343 --
7344 -- . = ALIGN(32);
7345 -- .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
7346 -- *(.data.cacheline_aligned)
7347 -- }
7348 --
7349 -- /* rarely changed data like cpu maps */
7350 -- . = ALIGN(32);
7351 -- .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
7352 -- *(.data.read_mostly)
7353 -- _edata = .; /* End of data section */
7354 -- }
7355 --
7356 -- . = ALIGN(THREAD_SIZE); /* init_task */
7357 -- .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
7358 -- *(.data.init_task)
7359 -- }
7360 -+ .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
7361 -+ __LOAD_PHYSICAL_ADDR = . - LOAD_OFFSET;
7362 -+ phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
7363 -+ *(.text.startup)
7364 -+ } :initdata
7365 -
7366 - /* might get freed after init */
7367 - . = ALIGN(PAGE_SIZE);
7368 -@@ -114,14 +70,8 @@ SECTIONS
7369 - . = ALIGN(PAGE_SIZE);
7370 -
7371 - /* will be freed after init */
7372 -- . = ALIGN(PAGE_SIZE); /* Init code and data */
7373 -- .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
7374 -- __init_begin = .;
7375 -- _sinittext = .;
7376 -- INIT_TEXT
7377 -- _einittext = .;
7378 -- }
7379 - .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
7380 -+ __init_begin = .;
7381 - INIT_DATA
7382 - }
7383 - . = ALIGN(16);
7384 -@@ -161,11 +111,6 @@ SECTIONS
7385 - *(.parainstructions)
7386 - __parainstructions_end = .;
7387 - }
7388 -- /* .exit.text is discard at runtime, not link time, to deal with references
7389 -- from .altinstructions and .eh_frame */
7390 -- .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
7391 -- EXIT_TEXT
7392 -- }
7393 - .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
7394 - EXIT_DATA
7395 - }
7396 -@@ -178,17 +123,136 @@ SECTIONS
7397 - }
7398 - #endif
7399 - . = ALIGN(PAGE_SIZE);
7400 -- .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
7401 -- __per_cpu_start = .;
7402 -+ per_cpu_start = .;
7403 -+ .data.percpu (0) : AT(ADDR(.data.percpu) - LOAD_OFFSET + per_cpu_start) {
7404 -+ __per_cpu_start = . + per_cpu_start;
7405 -+ LONG(0)
7406 - *(.data.percpu)
7407 - *(.data.percpu.shared_aligned)
7408 -- __per_cpu_end = .;
7409 -- }
7410 -+ __per_cpu_end = . + per_cpu_start;
7411 -+ } :percpu
7412 -+ . += per_cpu_start;
7413 - . = ALIGN(PAGE_SIZE);
7414 - /* freed after init ends here */
7415 -
7416 -+ . = ALIGN(PAGE_SIZE); /* Init code and data */
7417 -+ .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7418 -+ _sinittext = .;
7419 -+ INIT_TEXT
7420 -+ _einittext = .;
7421 -+ } :inittext
7422 -+
7423 -+ /* .exit.text is discard at runtime, not link time, to deal with references
7424 -+ from .altinstructions and .eh_frame */
7425 -+ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7426 -+ EXIT_TEXT
7427 -+ }
7428 -+
7429 -+ .filler : AT(ADDR(.filler) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7430 -+ BYTE(0)
7431 -+ . = ALIGN(2*PMD_SIZE) - 1;
7432 -+ }
7433 -+
7434 -+ /* freed after init ends here */
7435 -+
7436 -+ .text.head : AT(ADDR(.text.head) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7437 -+ __init_end = . + __KERNEL_TEXT_OFFSET;
7438 -+ KERNEL_TEXT_OFFSET = . + __KERNEL_TEXT_OFFSET;
7439 -+ _text = .; /* Text and read-only data */
7440 -+ *(.text.head)
7441 -+ } :text = 0x9090
7442 -+
7443 -+ /* read-only */
7444 -+ .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7445 -+ . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
7446 -+ *(.text.page_aligned)
7447 -+ TEXT_TEXT
7448 -+ SCHED_TEXT
7449 -+ LOCK_TEXT
7450 -+ KPROBES_TEXT
7451 -+ *(.fixup)
7452 -+ *(.gnu.warning)
7453 -+ _etext = .; /* End of text section */
7454 -+ } :text = 0x9090
7455 -+
7456 -+ . += __KERNEL_TEXT_OFFSET;
7457 -+
7458 -+ . = ALIGN(4096); /* Exception table */
7459 -+ __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
7460 -+ __start___ex_table = .;
7461 -+ *(__ex_table)
7462 -+ __stop___ex_table = .;
7463 -+ } :rodata
7464 -+
7465 -+ NOTES :rodata :note
7466 -+
7467 -+ RO_DATA(PAGE_SIZE)
7468 -+
7469 -+ . = ALIGN(PAGE_SIZE);
7470 -+ .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
7471 -+ *(.idt)
7472 -+ . = ALIGN(PAGE_SIZE);
7473 -+ *(.empty_zero_page)
7474 -+ *(.swapper_pg_pmd)
7475 -+ *(.swapper_pg_dir)
7476 -+ }
7477 -+
7478 -+#ifdef CONFIG_PAX_KERNEXEC
7479 -+
7480 -+#ifdef CONFIG_MODULES
7481 -+ . = ALIGN(PAGE_SIZE);
7482 -+ .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
7483 -+ MODULES_VADDR = .;
7484 -+ BYTE(0)
7485 -+ . += (6 * 1024 * 1024);
7486 -+ . = ALIGN( PMD_SIZE) - 1;
7487 -+ MODULES_END = .;
7488 -+ }
7489 -+#else
7490 -+ . = ALIGN(PMD_SIZE) - 1;
7491 -+#endif
7492 -+
7493 -+#endif
7494 -+
7495 -+ /* writeable */
7496 -+ . = ALIGN(PAGE_SIZE);
7497 -+ .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
7498 -+ _data = .;
7499 -+ DATA_DATA
7500 -+ CONSTRUCTORS
7501 -+ } :data
7502 -+
7503 -+ . = ALIGN(PAGE_SIZE);
7504 -+ .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
7505 -+ __nosave_begin = .;
7506 -+ *(.data.nosave)
7507 -+ . = ALIGN(PAGE_SIZE);
7508 -+ __nosave_end = .;
7509 -+ }
7510 -+
7511 -+ . = ALIGN(PAGE_SIZE);
7512 -+ .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7513 -+ *(.data.page_aligned)
7514 -+ }
7515 -+
7516 -+ . = ALIGN(32);
7517 -+ .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
7518 -+ *(.data.cacheline_aligned)
7519 -+ }
7520 -+
7521 -+ /* rarely changed data like cpu maps */
7522 -+ . = ALIGN(32);
7523 -+ .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
7524 -+ *(.data.read_mostly)
7525 -+ _edata = .; /* End of data section */
7526 -+ }
7527 -+
7528 -+ . = ALIGN(THREAD_SIZE); /* init_task */
7529 -+ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
7530 -+ *(.data.init_task)
7531 -+ }
7532 -+
7533 - .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
7534 -- __init_end = .;
7535 - __bss_start = .; /* BSS */
7536 - *(.bss.page_aligned)
7537 - *(.bss)
7538 -diff -urNp linux-2.6.27.6/arch/x86/kernel/vmlinux_64.lds.S linux-2.6.27.6/arch/x86/kernel/vmlinux_64.lds.S
7539 ---- linux-2.6.27.6/arch/x86/kernel/vmlinux_64.lds.S 2008-11-07 12:55:34.000000000 -0500
7540 -+++ linux-2.6.27.6/arch/x86/kernel/vmlinux_64.lds.S 2008-11-18 03:38:44.000000000 -0500
7541 -@@ -16,7 +16,7 @@ jiffies_64 = jiffies;
7542 - _proxy_pda = 1;
7543 - PHDRS {
7544 - text PT_LOAD FLAGS(5); /* R_E */
7545 -- data PT_LOAD FLAGS(7); /* RWE */
7546 -+ data PT_LOAD FLAGS(6); /* RW_ */
7547 - user PT_LOAD FLAGS(7); /* RWE */
7548 - data.init PT_LOAD FLAGS(7); /* RWE */
7549 - note PT_NOTE FLAGS(0); /* ___ */
7550 -@@ -49,17 +49,20 @@ SECTIONS
7551 - __stop___ex_table = .;
7552 - } :text = 0x9090
7553 -
7554 -- RODATA
7555 -+ RO_DATA(PAGE_SIZE)
7556 -
7557 -+#ifdef CONFIG_PAX_KERNEXEC
7558 -+ . = ALIGN(2*1024*1024); /* Align data segment to PMD size boundary */
7559 -+#else
7560 - . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */
7561 -+#endif
7562 - /* Data */
7563 -+ _data = .;
7564 - .data : AT(ADDR(.data) - LOAD_OFFSET) {
7565 - DATA_DATA
7566 - CONSTRUCTORS
7567 - } :data
7568 -
7569 -- _edata = .; /* End of data section */
7570 --
7571 - . = ALIGN(PAGE_SIZE);
7572 - . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
7573 - .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
7574 -@@ -70,9 +73,27 @@ SECTIONS
7575 - *(.data.read_mostly)
7576 - }
7577 -
7578 -+ . = ALIGN(THREAD_SIZE); /* init_task */
7579 -+ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
7580 -+ *(.data.init_task)
7581 -+ }
7582 -+
7583 -+ . = ALIGN(PAGE_SIZE);
7584 -+ .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7585 -+ *(.data.page_aligned)
7586 -+ }
7587 -+
7588 -+ . = ALIGN(PAGE_SIZE);
7589 -+ __nosave_begin = .;
7590 -+ .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
7591 -+ . = ALIGN(PAGE_SIZE);
7592 -+ __nosave_end = .;
7593 -+
7594 -+ _edata = .; /* End of data section */
7595 -+
7596 - #define VSYSCALL_ADDR (-10*1024*1024)
7597 --#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
7598 --#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
7599 -+#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
7600 -+#define VSYSCALL_VIRT_ADDR ((ADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
7601 -
7602 - #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
7603 - #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
7604 -@@ -120,23 +141,13 @@ SECTIONS
7605 - #undef VVIRT_OFFSET
7606 - #undef VVIRT
7607 -
7608 -- . = ALIGN(THREAD_SIZE); /* init_task */
7609 -- .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
7610 -- *(.data.init_task)
7611 -- }:data.init
7612 --
7613 -- . = ALIGN(PAGE_SIZE);
7614 -- .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7615 -- *(.data.page_aligned)
7616 -- }
7617 --
7618 - /* might get freed after init */
7619 - . = ALIGN(PAGE_SIZE);
7620 - __smp_alt_begin = .;
7621 - __smp_locks = .;
7622 - .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
7623 - *(.smp_locks)
7624 -- }
7625 -+ } :data.init
7626 - __smp_locks_end = .;
7627 - . = ALIGN(PAGE_SIZE);
7628 - __smp_alt_end = .;
7629 -@@ -213,16 +224,11 @@ SECTIONS
7630 - . = ALIGN(PAGE_SIZE);
7631 - __init_end = .;
7632 -
7633 -- . = ALIGN(PAGE_SIZE);
7634 -- __nosave_begin = .;
7635 -- .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
7636 -- . = ALIGN(PAGE_SIZE);
7637 -- __nosave_end = .;
7638 --
7639 - __bss_start = .; /* BSS */
7640 - .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
7641 - *(.bss.page_aligned)
7642 - *(.bss)
7643 -+ . = ALIGN(2*1024*1024);
7644 - }
7645 - __bss_stop = .;
7646 -
7647 -diff -urNp linux-2.6.27.6/arch/x86/kernel/vsyscall_64.c linux-2.6.27.6/arch/x86/kernel/vsyscall_64.c
7648 ---- linux-2.6.27.6/arch/x86/kernel/vsyscall_64.c 2008-11-07 12:55:34.000000000 -0500
7649 -+++ linux-2.6.27.6/arch/x86/kernel/vsyscall_64.c 2008-11-18 03:38:44.000000000 -0500
7650 -@@ -236,13 +236,13 @@ static ctl_table kernel_table2[] = {
7651 - .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int),
7652 - .mode = 0644,
7653 - .proc_handler = vsyscall_sysctl_change },
7654 -- {}
7655 -+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
7656 - };
7657 -
7658 - static ctl_table kernel_root_table2[] = {
7659 - { .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555,
7660 - .child = kernel_table2 },
7661 -- {}
7662 -+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
7663 - };
7664 - #endif
7665 -
7666 -diff -urNp linux-2.6.27.6/arch/x86/kvm/svm.c linux-2.6.27.6/arch/x86/kvm/svm.c
7667 ---- linux-2.6.27.6/arch/x86/kvm/svm.c 2008-11-07 12:55:34.000000000 -0500
7668 -+++ linux-2.6.27.6/arch/x86/kvm/svm.c 2008-11-18 03:38:44.000000000 -0500
7669 -@@ -1515,7 +1515,19 @@ static void reload_tss(struct kvm_vcpu *
7670 - int cpu = raw_smp_processor_id();
7671 -
7672 - struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu);
7673 -+
7674 -+#ifdef CONFIG_PAX_KERNEXEC
7675 -+ unsigned long cr0;
7676 -+
7677 -+ pax_open_kernel(cr0);
7678 -+#endif
7679 -+
7680 - svm_data->tss_desc->type = 9; /* available 32/64-bit TSS */
7681 -+
7682 -+#ifdef CONFIG_PAX_KERNEXEC
7683 -+ pax_close_kernel(cr0);
7684 -+#endif
7685 -+
7686 - load_TR_desc();
7687 - }
7688 -
7689 -diff -urNp linux-2.6.27.6/arch/x86/kvm/vmx.c linux-2.6.27.6/arch/x86/kvm/vmx.c
7690 ---- linux-2.6.27.6/arch/x86/kvm/vmx.c 2008-11-07 12:55:34.000000000 -0500
7691 -+++ linux-2.6.27.6/arch/x86/kvm/vmx.c 2008-11-18 03:38:44.000000000 -0500
7692 -@@ -115,7 +115,7 @@ static struct vmcs_config {
7693 - u32 vmentry_ctrl;
7694 - } vmcs_config;
7695 -
7696 --struct vmx_capability {
7697 -+static struct vmx_capability {
7698 - u32 ept;
7699 - u32 vpid;
7700 - } vmx_capability;
7701 -@@ -484,9 +484,23 @@ static void reload_tss(void)
7702 - struct descriptor_table gdt;
7703 - struct desc_struct *descs;
7704 -
7705 -+#ifdef CONFIG_PAX_KERNEXEC
7706 -+ unsigned long cr0;
7707 -+#endif
7708 -+
7709 - kvm_get_gdt(&gdt);
7710 - descs = (void *)gdt.base;
7711 -+
7712 -+#ifdef CONFIG_PAX_KERNEXEC
7713 -+ pax_open_kernel(cr0);
7714 -+#endif
7715 -+
7716 - descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
7717 -+
7718 -+#ifdef CONFIG_PAX_KERNEXEC
7719 -+ pax_close_kernel(cr0);
7720 -+#endif
7721 -+
7722 - load_TR_desc();
7723 - }
7724 -
7725 -@@ -3069,7 +3083,7 @@ static void vmx_vcpu_run(struct kvm_vcpu
7726 - (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
7727 - (GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS)) == 0;
7728 -
7729 -- asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
7730 -+ asm("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS));
7731 - vmx->launched = 1;
7732 -
7733 - intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
7734 -diff -urNp linux-2.6.27.6/arch/x86/kvm/x86.c linux-2.6.27.6/arch/x86/kvm/x86.c
7735 ---- linux-2.6.27.6/arch/x86/kvm/x86.c 2008-11-07 12:55:34.000000000 -0500
7736 -+++ linux-2.6.27.6/arch/x86/kvm/x86.c 2008-11-18 03:38:44.000000000 -0500
7737 -@@ -63,35 +63,35 @@ static int kvm_dev_ioctl_get_supported_c
7738 - struct kvm_x86_ops *kvm_x86_ops;
7739 -
7740 - struct kvm_stats_debugfs_item debugfs_entries[] = {
7741 -- { "pf_fixed", VCPU_STAT(pf_fixed) },
7742 -- { "pf_guest", VCPU_STAT(pf_guest) },
7743 -- { "tlb_flush", VCPU_STAT(tlb_flush) },
7744 -- { "invlpg", VCPU_STAT(invlpg) },
7745 -- { "exits", VCPU_STAT(exits) },
7746 -- { "io_exits", VCPU_STAT(io_exits) },
7747 -- { "mmio_exits", VCPU_STAT(mmio_exits) },
7748 -- { "signal_exits", VCPU_STAT(signal_exits) },
7749 -- { "irq_window", VCPU_STAT(irq_window_exits) },
7750 -- { "nmi_window", VCPU_STAT(nmi_window_exits) },
7751 -- { "halt_exits", VCPU_STAT(halt_exits) },
7752 -- { "halt_wakeup", VCPU_STAT(halt_wakeup) },
7753 -- { "hypercalls", VCPU_STAT(hypercalls) },
7754 -- { "request_irq", VCPU_STAT(request_irq_exits) },
7755 -- { "irq_exits", VCPU_STAT(irq_exits) },
7756 -- { "host_state_reload", VCPU_STAT(host_state_reload) },
7757 -- { "efer_reload", VCPU_STAT(efer_reload) },
7758 -- { "fpu_reload", VCPU_STAT(fpu_reload) },
7759 -- { "insn_emulation", VCPU_STAT(insn_emulation) },
7760 -- { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail) },
7761 -- { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped) },
7762 -- { "mmu_pte_write", VM_STAT(mmu_pte_write) },
7763 -- { "mmu_pte_updated", VM_STAT(mmu_pte_updated) },
7764 -- { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped) },
7765 -- { "mmu_flooded", VM_STAT(mmu_flooded) },
7766 -- { "mmu_recycled", VM_STAT(mmu_recycled) },
7767 -- { "mmu_cache_miss", VM_STAT(mmu_cache_miss) },
7768 -- { "remote_tlb_flush", VM_STAT(remote_tlb_flush) },
7769 -- { "largepages", VM_STAT(lpages) },
7770 -+ { "pf_fixed", VCPU_STAT(pf_fixed), NULL },
7771 -+ { "pf_guest", VCPU_STAT(pf_guest), NULL },
7772 -+ { "tlb_flush", VCPU_STAT(tlb_flush), NULL },
7773 -+ { "invlpg", VCPU_STAT(invlpg), NULL },
7774 -+ { "exits", VCPU_STAT(exits), NULL },
7775 -+ { "io_exits", VCPU_STAT(io_exits), NULL },
7776 -+ { "mmio_exits", VCPU_STAT(mmio_exits), NULL },
7777 -+ { "signal_exits", VCPU_STAT(signal_exits), NULL },
7778 -+ { "irq_window", VCPU_STAT(irq_window_exits), NULL },
7779 -+ { "nmi_window", VCPU_STAT(nmi_window_exits), NULL },
7780 -+ { "halt_exits", VCPU_STAT(halt_exits), NULL },
7781 -+ { "halt_wakeup", VCPU_STAT(halt_wakeup), NULL },
7782 -+ { "hypercalls", VCPU_STAT(hypercalls), NULL },
7783 -+ { "request_irq", VCPU_STAT(request_irq_exits), NULL },
7784 -+ { "irq_exits", VCPU_STAT(irq_exits), NULL },
7785 -+ { "host_state_reload", VCPU_STAT(host_state_reload), NULL },
7786 -+ { "efer_reload", VCPU_STAT(efer_reload), NULL },
7787 -+ { "fpu_reload", VCPU_STAT(fpu_reload), NULL },
7788 -+ { "insn_emulation", VCPU_STAT(insn_emulation), NULL },
7789 -+ { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail), NULL },
7790 -+ { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped), NULL },
7791 -+ { "mmu_pte_write", VM_STAT(mmu_pte_write), NULL },
7792 -+ { "mmu_pte_updated", VM_STAT(mmu_pte_updated), NULL },
7793 -+ { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped), NULL },
7794 -+ { "mmu_flooded", VM_STAT(mmu_flooded), NULL },
7795 -+ { "mmu_recycled", VM_STAT(mmu_recycled), NULL },
7796 -+ { "mmu_cache_miss", VM_STAT(mmu_cache_miss), NULL },
7797 -+ { "remote_tlb_flush", VM_STAT(remote_tlb_flush), NULL },
7798 -+ { "largepages", VM_STAT(lpages), NULL },
7799 - { NULL }
7800 - };
7801 -
7802 -@@ -1274,7 +1274,7 @@ static int kvm_vcpu_ioctl_set_lapic(stru
7803 - static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
7804 - struct kvm_interrupt *irq)
7805 - {
7806 -- if (irq->irq < 0 || irq->irq >= 256)
7807 -+ if (irq->irq >= 256)
7808 - return -EINVAL;
7809 - if (irqchip_in_kernel(vcpu->kvm))
7810 - return -ENXIO;
7811 -diff -urNp linux-2.6.27.6/arch/x86/lib/checksum_32.S linux-2.6.27.6/arch/x86/lib/checksum_32.S
7812 ---- linux-2.6.27.6/arch/x86/lib/checksum_32.S 2008-11-07 12:55:34.000000000 -0500
7813 -+++ linux-2.6.27.6/arch/x86/lib/checksum_32.S 2008-11-18 03:38:44.000000000 -0500
7814 -@@ -28,7 +28,8 @@
7815 - #include <linux/linkage.h>
7816 - #include <asm/dwarf2.h>
7817 - #include <asm/errno.h>
7818 --
7819 -+#include <asm/segment.h>
7820 -+
7821 - /*
7822 - * computes a partial checksum, e.g. for TCP/UDP fragments
7823 - */
7824 -@@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic (
7825 -
7826 - #define ARGBASE 16
7827 - #define FP 12
7828 --
7829 --ENTRY(csum_partial_copy_generic)
7830 -+
7831 -+ENTRY(csum_partial_copy_generic_to_user)
7832 - CFI_STARTPROC
7833 -+ pushl $(__USER_DS)
7834 -+ CFI_ADJUST_CFA_OFFSET 4
7835 -+ popl %es
7836 -+ CFI_ADJUST_CFA_OFFSET -4
7837 -+ jmp csum_partial_copy_generic
7838 -+
7839 -+ENTRY(csum_partial_copy_generic_from_user)
7840 -+ pushl $(__USER_DS)
7841 -+ CFI_ADJUST_CFA_OFFSET 4
7842 -+ popl %ds
7843 -+ CFI_ADJUST_CFA_OFFSET -4
7844 -+
7845 -+ENTRY(csum_partial_copy_generic)
7846 - subl $4,%esp
7847 - CFI_ADJUST_CFA_OFFSET 4
7848 - pushl %edi
7849 -@@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic)
7850 - jmp 4f
7851 - SRC(1: movw (%esi), %bx )
7852 - addl $2, %esi
7853 --DST( movw %bx, (%edi) )
7854 -+DST( movw %bx, %es:(%edi) )
7855 - addl $2, %edi
7856 - addw %bx, %ax
7857 - adcl $0, %eax
7858 -@@ -343,30 +357,30 @@ DST( movw %bx, (%edi) )
7859 - SRC(1: movl (%esi), %ebx )
7860 - SRC( movl 4(%esi), %edx )
7861 - adcl %ebx, %eax
7862 --DST( movl %ebx, (%edi) )
7863 -+DST( movl %ebx, %es:(%edi) )
7864 - adcl %edx, %eax
7865 --DST( movl %edx, 4(%edi) )
7866 -+DST( movl %edx, %es:4(%edi) )
7867 -
7868 - SRC( movl 8(%esi), %ebx )
7869 - SRC( movl 12(%esi), %edx )
7870 - adcl %ebx, %eax
7871 --DST( movl %ebx, 8(%edi) )
7872 -+DST( movl %ebx, %es:8(%edi) )
7873 - adcl %edx, %eax
7874 --DST( movl %edx, 12(%edi) )
7875 -+DST( movl %edx, %es:12(%edi) )
7876 -
7877 - SRC( movl 16(%esi), %ebx )
7878 - SRC( movl 20(%esi), %edx )
7879 - adcl %ebx, %eax
7880 --DST( movl %ebx, 16(%edi) )
7881 -+DST( movl %ebx, %es:16(%edi) )
7882 - adcl %edx, %eax
7883 --DST( movl %edx, 20(%edi) )
7884 -+DST( movl %edx, %es:20(%edi) )
7885 -
7886 - SRC( movl 24(%esi), %ebx )
7887 - SRC( movl 28(%esi), %edx )
7888 - adcl %ebx, %eax
7889 --DST( movl %ebx, 24(%edi) )
7890 -+DST( movl %ebx, %es:24(%edi) )
7891 - adcl %edx, %eax
7892 --DST( movl %edx, 28(%edi) )
7893 -+DST( movl %edx, %es:28(%edi) )
7894 -
7895 - lea 32(%esi), %esi
7896 - lea 32(%edi), %edi
7897 -@@ -380,7 +394,7 @@ DST( movl %edx, 28(%edi) )
7898 - shrl $2, %edx # This clears CF
7899 - SRC(3: movl (%esi), %ebx )
7900 - adcl %ebx, %eax
7901 --DST( movl %ebx, (%edi) )
7902 -+DST( movl %ebx, %es:(%edi) )
7903 - lea 4(%esi), %esi
7904 - lea 4(%edi), %edi
7905 - dec %edx
7906 -@@ -392,12 +406,12 @@ DST( movl %ebx, (%edi) )
7907 - jb 5f
7908 - SRC( movw (%esi), %cx )
7909 - leal 2(%esi), %esi
7910 --DST( movw %cx, (%edi) )
7911 -+DST( movw %cx, %es:(%edi) )
7912 - leal 2(%edi), %edi
7913 - je 6f
7914 - shll $16,%ecx
7915 - SRC(5: movb (%esi), %cl )
7916 --DST( movb %cl, (%edi) )
7917 -+DST( movb %cl, %es:(%edi) )
7918 - 6: addl %ecx, %eax
7919 - adcl $0, %eax
7920 - 7:
7921 -@@ -408,7 +422,7 @@ DST( movb %cl, (%edi) )
7922 -
7923 - 6001:
7924 - movl ARGBASE+20(%esp), %ebx # src_err_ptr
7925 -- movl $-EFAULT, (%ebx)
7926 -+ movl $-EFAULT, %ss:(%ebx)
7927 -
7928 - # zero the complete destination - computing the rest
7929 - # is too much work
7930 -@@ -421,11 +435,19 @@ DST( movb %cl, (%edi) )
7931 -
7932 - 6002:
7933 - movl ARGBASE+24(%esp), %ebx # dst_err_ptr
7934 -- movl $-EFAULT,(%ebx)
7935 -+ movl $-EFAULT,%ss:(%ebx)
7936 - jmp 5000b
7937 -
7938 - .previous
7939 -
7940 -+ pushl %ss
7941 -+ CFI_ADJUST_CFA_OFFSET 4
7942 -+ popl %ds
7943 -+ CFI_ADJUST_CFA_OFFSET -4
7944 -+ pushl %ss
7945 -+ CFI_ADJUST_CFA_OFFSET 4
7946 -+ popl %es
7947 -+ CFI_ADJUST_CFA_OFFSET -4
7948 - popl %ebx
7949 - CFI_ADJUST_CFA_OFFSET -4
7950 - CFI_RESTORE ebx
7951 -@@ -439,26 +461,41 @@ DST( movb %cl, (%edi) )
7952 - CFI_ADJUST_CFA_OFFSET -4
7953 - ret
7954 - CFI_ENDPROC
7955 --ENDPROC(csum_partial_copy_generic)
7956 -+ENDPROC(csum_partial_copy_generic_to_user)
7957 -
7958 - #else
7959 -
7960 - /* Version for PentiumII/PPro */
7961 -
7962 - #define ROUND1(x) \
7963 -+ nop; nop; nop; \
7964 - SRC(movl x(%esi), %ebx ) ; \
7965 - addl %ebx, %eax ; \
7966 -- DST(movl %ebx, x(%edi) ) ;
7967 -+ DST(movl %ebx, %es:x(%edi)) ;
7968 -
7969 - #define ROUND(x) \
7970 -+ nop; nop; nop; \
7971 - SRC(movl x(%esi), %ebx ) ; \
7972 - adcl %ebx, %eax ; \
7973 -- DST(movl %ebx, x(%edi) ) ;
7974 -+ DST(movl %ebx, %es:x(%edi)) ;
7975 -
7976 - #define ARGBASE 12
7977 --
7978 --ENTRY(csum_partial_copy_generic)
7979 -+
7980 -+ENTRY(csum_partial_copy_generic_to_user)
7981 - CFI_STARTPROC
7982 -+ pushl $(__USER_DS)
7983 -+ CFI_ADJUST_CFA_OFFSET 4
7984 -+ popl %es
7985 -+ CFI_ADJUST_CFA_OFFSET -4
7986 -+ jmp csum_partial_copy_generic
7987 -+
7988 -+ENTRY(csum_partial_copy_generic_from_user)
7989 -+ pushl $(__USER_DS)
7990 -+ CFI_ADJUST_CFA_OFFSET 4
7991 -+ popl %ds
7992 -+ CFI_ADJUST_CFA_OFFSET -4
7993 -+
7994 -+ENTRY(csum_partial_copy_generic)
7995 - pushl %ebx
7996 - CFI_ADJUST_CFA_OFFSET 4
7997 - CFI_REL_OFFSET ebx, 0
7998 -@@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic)
7999 - subl %ebx, %edi
8000 - lea -1(%esi),%edx
8001 - andl $-32,%edx
8002 -- lea 3f(%ebx,%ebx), %ebx
8003 -+ lea 3f(%ebx,%ebx,2), %ebx
8004 - testl %esi, %esi
8005 - jmp *%ebx
8006 - 1: addl $64,%esi
8007 -@@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic)
8008 - jb 5f
8009 - SRC( movw (%esi), %dx )
8010 - leal 2(%esi), %esi
8011 --DST( movw %dx, (%edi) )
8012 -+DST( movw %dx, %es:(%edi) )
8013 - leal 2(%edi), %edi
8014 - je 6f
8015 - shll $16,%edx
8016 - 5:
8017 - SRC( movb (%esi), %dl )
8018 --DST( movb %dl, (%edi) )
8019 -+DST( movb %dl, %es:(%edi) )
8020 - 6: addl %edx, %eax
8021 - adcl $0, %eax
8022 - 7:
8023 - .section .fixup, "ax"
8024 - 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
8025 -- movl $-EFAULT, (%ebx)
8026 -+ movl $-EFAULT, %ss:(%ebx)
8027 - # zero the complete destination (computing the rest is too much work)
8028 - movl ARGBASE+8(%esp),%edi # dst
8029 - movl ARGBASE+12(%esp),%ecx # len
8030 -@@ -523,10 +560,18 @@ DST( movb %dl, (%edi) )
8031 - rep; stosb
8032 - jmp 7b
8033 - 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
8034 -- movl $-EFAULT, (%ebx)
8035 -+ movl $-EFAULT, %ss:(%ebx)
8036 - jmp 7b
8037 - .previous
8038 -
8039 -+ pushl %ss
8040 -+ CFI_ADJUST_CFA_OFFSET 4
8041 -+ popl %ds
8042 -+ CFI_ADJUST_CFA_OFFSET -4
8043 -+ pushl %ss
8044 -+ CFI_ADJUST_CFA_OFFSET 4
8045 -+ popl %es
8046 -+ CFI_ADJUST_CFA_OFFSET -4
8047 - popl %esi
8048 - CFI_ADJUST_CFA_OFFSET -4
8049 - CFI_RESTORE esi
8050 -@@ -538,7 +583,7 @@ DST( movb %dl, (%edi) )
8051 - CFI_RESTORE ebx
8052 - ret
8053 - CFI_ENDPROC
8054 --ENDPROC(csum_partial_copy_generic)
8055 -+ENDPROC(csum_partial_copy_generic_to_user)
8056 -
8057 - #undef ROUND
8058 - #undef ROUND1
8059 -diff -urNp linux-2.6.27.6/arch/x86/lib/clear_page_64.S linux-2.6.27.6/arch/x86/lib/clear_page_64.S
8060 ---- linux-2.6.27.6/arch/x86/lib/clear_page_64.S 2008-11-07 12:55:34.000000000 -0500
8061 -+++ linux-2.6.27.6/arch/x86/lib/clear_page_64.S 2008-11-18 03:38:44.000000000 -0500
8062 -@@ -44,7 +44,7 @@ ENDPROC(clear_page)
8063 -
8064 - #include <asm/cpufeature.h>
8065 -
8066 -- .section .altinstr_replacement,"ax"
8067 -+ .section .altinstr_replacement,"a"
8068 - 1: .byte 0xeb /* jmp <disp8> */
8069 - .byte (clear_page_c - clear_page) - (2f - 1b) /* offset */
8070 - 2:
8071 -diff -urNp linux-2.6.27.6/arch/x86/lib/copy_page_64.S linux-2.6.27.6/arch/x86/lib/copy_page_64.S
8072 ---- linux-2.6.27.6/arch/x86/lib/copy_page_64.S 2008-11-07 12:55:34.000000000 -0500
8073 -+++ linux-2.6.27.6/arch/x86/lib/copy_page_64.S 2008-11-18 03:38:44.000000000 -0500
8074 -@@ -104,7 +104,7 @@ ENDPROC(copy_page)
8075 -
8076 - #include <asm/cpufeature.h>
8077 -
8078 -- .section .altinstr_replacement,"ax"
8079 -+ .section .altinstr_replacement,"a"
8080 - 1: .byte 0xeb /* jmp <disp8> */
8081 - .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */
8082 - 2:
8083 -diff -urNp linux-2.6.27.6/arch/x86/lib/copy_user_64.S linux-2.6.27.6/arch/x86/lib/copy_user_64.S
8084 ---- linux-2.6.27.6/arch/x86/lib/copy_user_64.S 2008-11-07 12:55:34.000000000 -0500
8085 -+++ linux-2.6.27.6/arch/x86/lib/copy_user_64.S 2008-11-18 03:38:44.000000000 -0500
8086 -@@ -21,7 +21,7 @@
8087 - .byte 0xe9 /* 32bit jump */
8088 - .long \orig-1f /* by default jump to orig */
8089 - 1:
8090 -- .section .altinstr_replacement,"ax"
8091 -+ .section .altinstr_replacement,"a"
8092 - 2: .byte 0xe9 /* near jump with 32bit immediate */
8093 - .long \alt-1b /* offset */ /* or alternatively to alt */
8094 - .previous
8095 -@@ -106,6 +106,8 @@ ENDPROC(__copy_from_user_inatomic)
8096 - ENTRY(bad_from_user)
8097 - bad_from_user:
8098 - CFI_STARTPROC
8099 -+ testl %edx,%edx
8100 -+ js bad_to_user
8101 - movl %edx,%ecx
8102 - xorl %eax,%eax
8103 - rep
8104 -diff -urNp linux-2.6.27.6/arch/x86/lib/getuser.S linux-2.6.27.6/arch/x86/lib/getuser.S
8105 ---- linux-2.6.27.6/arch/x86/lib/getuser.S 2008-11-07 12:55:34.000000000 -0500
8106 -+++ linux-2.6.27.6/arch/x86/lib/getuser.S 2008-11-18 03:38:44.000000000 -0500
8107 -@@ -33,6 +33,7 @@
8108 - #include <asm/asm-offsets.h>
8109 - #include <asm/thread_info.h>
8110 - #include <asm/asm.h>
8111 -+#include <asm/segment.h>
8112 -
8113 - .text
8114 - ENTRY(__get_user_1)
8115 -@@ -40,7 +41,19 @@ ENTRY(__get_user_1)
8116 - GET_THREAD_INFO(%_ASM_DX)
8117 - cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
8118 - jae bad_get_user
8119 -+
8120 -+#ifdef CONFIG_X86_32
8121 -+ pushl $(__USER_DS)
8122 -+ popl %ds
8123 -+#endif
8124 -+
8125 - 1: movzb (%_ASM_AX),%edx
8126 -+
8127 -+#ifdef CONFIG_X86_32
8128 -+ pushl %ss
8129 -+ pop %ds
8130 -+#endif
8131 -+
8132 - xor %eax,%eax
8133 - ret
8134 - CFI_ENDPROC
8135 -@@ -53,7 +66,19 @@ ENTRY(__get_user_2)
8136 - GET_THREAD_INFO(%_ASM_DX)
8137 - cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
8138 - jae bad_get_user
8139 -+
8140 -+#ifdef CONFIG_X86_32
8141 -+ pushl $(__USER_DS)
8142 -+ popl %ds
8143 -+#endif
8144 -+
8145 - 2: movzwl -1(%_ASM_AX),%edx
8146 -+
8147 -+#ifdef CONFIG_X86_32
8148 -+ pushl %ss
8149 -+ pop %ds
8150 -+#endif
8151 -+
8152 - xor %eax,%eax
8153 - ret
8154 - CFI_ENDPROC
8155 -@@ -66,7 +91,19 @@ ENTRY(__get_user_4)
8156 - GET_THREAD_INFO(%_ASM_DX)
8157 - cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
8158 - jae bad_get_user
8159 -+
8160 -+#ifdef CONFIG_X86_32
8161 -+ pushl $(__USER_DS)
8162 -+ popl %ds
8163 -+#endif
8164 -+
8165 - 3: mov -3(%_ASM_AX),%edx
8166 -+
8167 -+#ifdef CONFIG_X86_32
8168 -+ pushl %ss
8169 -+ pop %ds
8170 -+#endif
8171 -+
8172 - xor %eax,%eax
8173 - ret
8174 - CFI_ENDPROC
8175 -@@ -89,6 +126,12 @@ ENDPROC(__get_user_8)
8176 -
8177 - bad_get_user:
8178 - CFI_STARTPROC
8179 -+
8180 -+#ifdef CONFIG_X86_32
8181 -+ pushl %ss
8182 -+ pop %ds
8183 -+#endif
8184 -+
8185 - xor %edx,%edx
8186 - mov $(-EFAULT),%_ASM_AX
8187 - ret
8188 -diff -urNp linux-2.6.27.6/arch/x86/lib/memcpy_64.S linux-2.6.27.6/arch/x86/lib/memcpy_64.S
8189 ---- linux-2.6.27.6/arch/x86/lib/memcpy_64.S 2008-11-07 12:55:34.000000000 -0500
8190 -+++ linux-2.6.27.6/arch/x86/lib/memcpy_64.S 2008-11-18 03:38:44.000000000 -0500
8191 -@@ -114,7 +114,7 @@ ENDPROC(__memcpy)
8192 - /* Some CPUs run faster using the string copy instructions.
8193 - It is also a lot simpler. Use this when possible */
8194 -
8195 -- .section .altinstr_replacement,"ax"
8196 -+ .section .altinstr_replacement,"a"
8197 - 1: .byte 0xeb /* jmp <disp8> */
8198 - .byte (memcpy_c - memcpy) - (2f - 1b) /* offset */
8199 - 2:
8200 -diff -urNp linux-2.6.27.6/arch/x86/lib/memset_64.S linux-2.6.27.6/arch/x86/lib/memset_64.S
8201 ---- linux-2.6.27.6/arch/x86/lib/memset_64.S 2008-11-07 12:55:34.000000000 -0500
8202 -+++ linux-2.6.27.6/arch/x86/lib/memset_64.S 2008-11-18 03:38:44.000000000 -0500
8203 -@@ -118,7 +118,7 @@ ENDPROC(__memset)
8204 -
8205 - #include <asm/cpufeature.h>
8206 -
8207 -- .section .altinstr_replacement,"ax"
8208 -+ .section .altinstr_replacement,"a"
8209 - 1: .byte 0xeb /* jmp <disp8> */
8210 - .byte (memset_c - memset) - (2f - 1b) /* offset */
8211 - 2:
8212 -diff -urNp linux-2.6.27.6/arch/x86/lib/mmx_32.c linux-2.6.27.6/arch/x86/lib/mmx_32.c
8213 ---- linux-2.6.27.6/arch/x86/lib/mmx_32.c 2008-11-07 12:55:34.000000000 -0500
8214 -+++ linux-2.6.27.6/arch/x86/lib/mmx_32.c 2008-11-18 03:38:44.000000000 -0500
8215 -@@ -29,6 +29,7 @@ void *_mmx_memcpy(void *to, const void *
8216 - {
8217 - void *p;
8218 - int i;
8219 -+ unsigned long cr0;
8220 -
8221 - if (unlikely(in_interrupt()))
8222 - return __memcpy(to, from, len);
8223 -@@ -39,44 +40,72 @@ void *_mmx_memcpy(void *to, const void *
8224 - kernel_fpu_begin();
8225 -
8226 - __asm__ __volatile__ (
8227 -- "1: prefetch (%0)\n" /* This set is 28 bytes */
8228 -- " prefetch 64(%0)\n"
8229 -- " prefetch 128(%0)\n"
8230 -- " prefetch 192(%0)\n"
8231 -- " prefetch 256(%0)\n"
8232 -+ "1: prefetch (%1)\n" /* This set is 28 bytes */
8233 -+ " prefetch 64(%1)\n"
8234 -+ " prefetch 128(%1)\n"
8235 -+ " prefetch 192(%1)\n"
8236 -+ " prefetch 256(%1)\n"
8237 - "2: \n"
8238 - ".section .fixup, \"ax\"\n"
8239 -- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8240 -+ "3: \n"
8241 -+
8242 -+#ifdef CONFIG_PAX_KERNEXEC
8243 -+ " movl %%cr0, %0\n"
8244 -+ " movl %0, %%eax\n"
8245 -+ " andl $0xFFFEFFFF, %%eax\n"
8246 -+ " movl %%eax, %%cr0\n"
8247 -+#endif
8248 -+
8249 -+ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8250 -+
8251 -+#ifdef CONFIG_PAX_KERNEXEC
8252 -+ " movl %0, %%cr0\n"
8253 -+#endif
8254 -+
8255 - " jmp 2b\n"
8256 - ".previous\n"
8257 - _ASM_EXTABLE(1b, 3b)
8258 -- : : "r" (from));
8259 -+ : "=&r" (cr0) : "r" (from) : "ax");
8260 -
8261 - for ( ; i > 5; i--) {
8262 - __asm__ __volatile__ (
8263 -- "1: prefetch 320(%0)\n"
8264 -- "2: movq (%0), %%mm0\n"
8265 -- " movq 8(%0), %%mm1\n"
8266 -- " movq 16(%0), %%mm2\n"
8267 -- " movq 24(%0), %%mm3\n"
8268 -- " movq %%mm0, (%1)\n"
8269 -- " movq %%mm1, 8(%1)\n"
8270 -- " movq %%mm2, 16(%1)\n"
8271 -- " movq %%mm3, 24(%1)\n"
8272 -- " movq 32(%0), %%mm0\n"
8273 -- " movq 40(%0), %%mm1\n"
8274 -- " movq 48(%0), %%mm2\n"
8275 -- " movq 56(%0), %%mm3\n"
8276 -- " movq %%mm0, 32(%1)\n"
8277 -- " movq %%mm1, 40(%1)\n"
8278 -- " movq %%mm2, 48(%1)\n"
8279 -- " movq %%mm3, 56(%1)\n"
8280 -+ "1: prefetch 320(%1)\n"
8281 -+ "2: movq (%1), %%mm0\n"
8282 -+ " movq 8(%1), %%mm1\n"
8283 -+ " movq 16(%1), %%mm2\n"
8284 -+ " movq 24(%1), %%mm3\n"
8285 -+ " movq %%mm0, (%2)\n"
8286 -+ " movq %%mm1, 8(%2)\n"
8287 -+ " movq %%mm2, 16(%2)\n"
8288 -+ " movq %%mm3, 24(%2)\n"
8289 -+ " movq 32(%1), %%mm0\n"
8290 -+ " movq 40(%1), %%mm1\n"
8291 -+ " movq 48(%1), %%mm2\n"
8292 -+ " movq 56(%1), %%mm3\n"
8293 -+ " movq %%mm0, 32(%2)\n"
8294 -+ " movq %%mm1, 40(%2)\n"
8295 -+ " movq %%mm2, 48(%2)\n"
8296 -+ " movq %%mm3, 56(%2)\n"
8297 - ".section .fixup, \"ax\"\n"
8298 -- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8299 -+ "3:\n"
8300 -+
8301 -+#ifdef CONFIG_PAX_KERNEXEC
8302 -+ " movl %%cr0, %0\n"
8303 -+ " movl %0, %%eax\n"
8304 -+ " andl $0xFFFEFFFF, %%eax\n"
8305 -+ " movl %%eax, %%cr0\n"
8306 -+#endif
8307 -+
8308 -+ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8309 -+
8310 -+#ifdef CONFIG_PAX_KERNEXEC
8311 -+ " movl %0, %%cr0\n"
8312 -+#endif
8313 -+
8314 - " jmp 2b\n"
8315 - ".previous\n"
8316 - _ASM_EXTABLE(1b, 3b)
8317 -- : : "r" (from), "r" (to) : "memory");
8318 -+ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
8319 -
8320 - from += 64;
8321 - to += 64;
8322 -@@ -158,6 +187,7 @@ static void fast_clear_page(void *page)
8323 - static void fast_copy_page(void *to, void *from)
8324 - {
8325 - int i;
8326 -+ unsigned long cr0;
8327 -
8328 - kernel_fpu_begin();
8329 -
8330 -@@ -166,42 +196,70 @@ static void fast_copy_page(void *to, voi
8331 - * but that is for later. -AV
8332 - */
8333 - __asm__ __volatile__(
8334 -- "1: prefetch (%0)\n"
8335 -- " prefetch 64(%0)\n"
8336 -- " prefetch 128(%0)\n"
8337 -- " prefetch 192(%0)\n"
8338 -- " prefetch 256(%0)\n"
8339 -+ "1: prefetch (%1)\n"
8340 -+ " prefetch 64(%1)\n"
8341 -+ " prefetch 128(%1)\n"
8342 -+ " prefetch 192(%1)\n"
8343 -+ " prefetch 256(%1)\n"
8344 - "2: \n"
8345 - ".section .fixup, \"ax\"\n"
8346 -- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8347 -+ "3: \n"
8348 -+
8349 -+#ifdef CONFIG_PAX_KERNEXEC
8350 -+ " movl %%cr0, %0\n"
8351 -+ " movl %0, %%eax\n"
8352 -+ " andl $0xFFFEFFFF, %%eax\n"
8353 -+ " movl %%eax, %%cr0\n"
8354 -+#endif
8355 -+
8356 -+ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8357 -+
8358 -+#ifdef CONFIG_PAX_KERNEXEC
8359 -+ " movl %0, %%cr0\n"
8360 -+#endif
8361 -+
8362 - " jmp 2b\n"
8363 - ".previous\n"
8364 -- _ASM_EXTABLE(1b, 3b) : : "r" (from));
8365 -+ _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
8366 -
8367 - for (i = 0; i < (4096-320)/64; i++) {
8368 - __asm__ __volatile__ (
8369 -- "1: prefetch 320(%0)\n"
8370 -- "2: movq (%0), %%mm0\n"
8371 -- " movntq %%mm0, (%1)\n"
8372 -- " movq 8(%0), %%mm1\n"
8373 -- " movntq %%mm1, 8(%1)\n"
8374 -- " movq 16(%0), %%mm2\n"
8375 -- " movntq %%mm2, 16(%1)\n"
8376 -- " movq 24(%0), %%mm3\n"
8377 -- " movntq %%mm3, 24(%1)\n"
8378 -- " movq 32(%0), %%mm4\n"
8379 -- " movntq %%mm4, 32(%1)\n"
8380 -- " movq 40(%0), %%mm5\n"
8381 -- " movntq %%mm5, 40(%1)\n"
8382 -- " movq 48(%0), %%mm6\n"
8383 -- " movntq %%mm6, 48(%1)\n"
8384 -- " movq 56(%0), %%mm7\n"
8385 -- " movntq %%mm7, 56(%1)\n"
8386 -+ "1: prefetch 320(%1)\n"
8387 -+ "2: movq (%1), %%mm0\n"
8388 -+ " movntq %%mm0, (%2)\n"
8389 -+ " movq 8(%1), %%mm1\n"
8390 -+ " movntq %%mm1, 8(%2)\n"
8391 -+ " movq 16(%1), %%mm2\n"
8392 -+ " movntq %%mm2, 16(%2)\n"
8393 -+ " movq 24(%1), %%mm3\n"
8394 -+ " movntq %%mm3, 24(%2)\n"
8395 -+ " movq 32(%1), %%mm4\n"
8396 -+ " movntq %%mm4, 32(%2)\n"
8397 -+ " movq 40(%1), %%mm5\n"
8398 -+ " movntq %%mm5, 40(%2)\n"
8399 -+ " movq 48(%1), %%mm6\n"
8400 -+ " movntq %%mm6, 48(%2)\n"
8401 -+ " movq 56(%1), %%mm7\n"
8402 -+ " movntq %%mm7, 56(%2)\n"
8403 - ".section .fixup, \"ax\"\n"
8404 -- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8405 -+ "3:\n"
8406 -+
8407 -+#ifdef CONFIG_PAX_KERNEXEC
8408 -+ " movl %%cr0, %0\n"
8409 -+ " movl %0, %%eax\n"
8410 -+ " andl $0xFFFEFFFF, %%eax\n"
8411 -+ " movl %%eax, %%cr0\n"
8412 -+#endif
8413 -+
8414 -+ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8415 -+
8416 -+#ifdef CONFIG_PAX_KERNEXEC
8417 -+ " movl %0, %%cr0\n"
8418 -+#endif
8419 -+
8420 - " jmp 2b\n"
8421 - ".previous\n"
8422 -- _ASM_EXTABLE(1b, 3b) : : "r" (from), "r" (to) : "memory");
8423 -+ _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
8424 -
8425 - from += 64;
8426 - to += 64;
8427 -@@ -280,47 +338,76 @@ static void fast_clear_page(void *page)
8428 - static void fast_copy_page(void *to, void *from)
8429 - {
8430 - int i;
8431 -+ unsigned long cr0;
8432 -
8433 - kernel_fpu_begin();
8434 -
8435 - __asm__ __volatile__ (
8436 -- "1: prefetch (%0)\n"
8437 -- " prefetch 64(%0)\n"
8438 -- " prefetch 128(%0)\n"
8439 -- " prefetch 192(%0)\n"
8440 -- " prefetch 256(%0)\n"
8441 -+ "1: prefetch (%1)\n"
8442 -+ " prefetch 64(%1)\n"
8443 -+ " prefetch 128(%1)\n"
8444 -+ " prefetch 192(%1)\n"
8445 -+ " prefetch 256(%1)\n"
8446 - "2: \n"
8447 - ".section .fixup, \"ax\"\n"
8448 -- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8449 -+ "3: \n"
8450 -+
8451 -+#ifdef CONFIG_PAX_KERNEXEC
8452 -+ " movl %%cr0, %0\n"
8453 -+ " movl %0, %%eax\n"
8454 -+ " andl $0xFFFEFFFF, %%eax\n"
8455 -+ " movl %%eax, %%cr0\n"
8456 -+#endif
8457 -+
8458 -+ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8459 -+
8460 -+#ifdef CONFIG_PAX_KERNEXEC
8461 -+ " movl %0, %%cr0\n"
8462 -+#endif
8463 -+
8464 - " jmp 2b\n"
8465 - ".previous\n"
8466 -- _ASM_EXTABLE(1b, 3b) : : "r" (from));
8467 -+ _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
8468 -
8469 - for (i = 0; i < 4096/64; i++) {
8470 - __asm__ __volatile__ (
8471 -- "1: prefetch 320(%0)\n"
8472 -- "2: movq (%0), %%mm0\n"
8473 -- " movq 8(%0), %%mm1\n"
8474 -- " movq 16(%0), %%mm2\n"
8475 -- " movq 24(%0), %%mm3\n"
8476 -- " movq %%mm0, (%1)\n"
8477 -- " movq %%mm1, 8(%1)\n"
8478 -- " movq %%mm2, 16(%1)\n"
8479 -- " movq %%mm3, 24(%1)\n"
8480 -- " movq 32(%0), %%mm0\n"
8481 -- " movq 40(%0), %%mm1\n"
8482 -- " movq 48(%0), %%mm2\n"
8483 -- " movq 56(%0), %%mm3\n"
8484 -- " movq %%mm0, 32(%1)\n"
8485 -- " movq %%mm1, 40(%1)\n"
8486 -- " movq %%mm2, 48(%1)\n"
8487 -- " movq %%mm3, 56(%1)\n"
8488 -+ "1: prefetch 320(%1)\n"
8489 -+ "2: movq (%1), %%mm0\n"
8490 -+ " movq 8(%1), %%mm1\n"
8491 -+ " movq 16(%1), %%mm2\n"
8492 -+ " movq 24(%1), %%mm3\n"
8493 -+ " movq %%mm0, (%2)\n"
8494 -+ " movq %%mm1, 8(%2)\n"
8495 -+ " movq %%mm2, 16(%2)\n"
8496 -+ " movq %%mm3, 24(%2)\n"
8497 -+ " movq 32(%1), %%mm0\n"
8498 -+ " movq 40(%1), %%mm1\n"
8499 -+ " movq 48(%1), %%mm2\n"
8500 -+ " movq 56(%1), %%mm3\n"
8501 -+ " movq %%mm0, 32(%2)\n"
8502 -+ " movq %%mm1, 40(%2)\n"
8503 -+ " movq %%mm2, 48(%2)\n"
8504 -+ " movq %%mm3, 56(%2)\n"
8505 - ".section .fixup, \"ax\"\n"
8506 -- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8507 -+ "3:\n"
8508 -+
8509 -+#ifdef CONFIG_PAX_KERNEXEC
8510 -+ " movl %%cr0, %0\n"
8511 -+ " movl %0, %%eax\n"
8512 -+ " andl $0xFFFEFFFF, %%eax\n"
8513 -+ " movl %%eax, %%cr0\n"
8514 -+#endif
8515 -+
8516 -+ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8517 -+
8518 -+#ifdef CONFIG_PAX_KERNEXEC
8519 -+ " movl %0, %%cr0\n"
8520 -+#endif
8521 -+
8522 - " jmp 2b\n"
8523 - ".previous\n"
8524 - _ASM_EXTABLE(1b, 3b)
8525 -- : : "r" (from), "r" (to) : "memory");
8526 -+ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
8527 -
8528 - from += 64;
8529 - to += 64;
8530 -diff -urNp linux-2.6.27.6/arch/x86/lib/putuser.S linux-2.6.27.6/arch/x86/lib/putuser.S
8531 ---- linux-2.6.27.6/arch/x86/lib/putuser.S 2008-11-07 12:55:34.000000000 -0500
8532 -+++ linux-2.6.27.6/arch/x86/lib/putuser.S 2008-11-18 03:38:44.000000000 -0500
8533 -@@ -15,6 +15,7 @@
8534 - #include <asm/thread_info.h>
8535 - #include <asm/errno.h>
8536 - #include <asm/asm.h>
8537 -+#include <asm/segment.h>
8538 -
8539 -
8540 - /*
8541 -@@ -39,7 +40,19 @@ ENTRY(__put_user_1)
8542 - ENTER
8543 - cmp TI_addr_limit(%_ASM_BX),%_ASM_CX
8544 - jae bad_put_user
8545 -+
8546 -+#ifdef CONFIG_X86_32
8547 -+ pushl $(__USER_DS)
8548 -+ popl %ds
8549 -+#endif
8550 -+
8551 - 1: movb %al,(%_ASM_CX)
8552 -+
8553 -+#ifdef CONFIG_X86_32
8554 -+ pushl %ss
8555 -+ popl %ds
8556 -+#endif
8557 -+
8558 - xor %eax,%eax
8559 - EXIT
8560 - ENDPROC(__put_user_1)
8561 -@@ -50,7 +63,19 @@ ENTRY(__put_user_2)
8562 - sub $1,%_ASM_BX
8563 - cmp %_ASM_BX,%_ASM_CX
8564 - jae bad_put_user
8565 -+
8566 -+#ifdef CONFIG_X86_32
8567 -+ pushl $(__USER_DS)
8568 -+ popl %ds
8569 -+#endif
8570 -+
8571 - 2: movw %ax,(%_ASM_CX)
8572 -+
8573 -+#ifdef CONFIG_X86_32
8574 -+ pushl %ss
8575 -+ popl %ds
8576 -+#endif
8577 -+
8578 - xor %eax,%eax
8579 - EXIT
8580 - ENDPROC(__put_user_2)
8581 -@@ -61,7 +86,19 @@ ENTRY(__put_user_4)
8582 - sub $3,%_ASM_BX
8583 - cmp %_ASM_BX,%_ASM_CX
8584 - jae bad_put_user
8585 -+
8586 -+#ifdef CONFIG_X86_32
8587 -+ pushl $(__USER_DS)
8588 -+ popl %ds
8589 -+#endif
8590 -+
8591 - 3: movl %eax,(%_ASM_CX)
8592 -+
8593 -+#ifdef CONFIG_X86_32
8594 -+ pushl %ss
8595 -+ popl %ds
8596 -+#endif
8597 -+
8598 - xor %eax,%eax
8599 - EXIT
8600 - ENDPROC(__put_user_4)
8601 -@@ -72,16 +109,34 @@ ENTRY(__put_user_8)
8602 - sub $7,%_ASM_BX
8603 - cmp %_ASM_BX,%_ASM_CX
8604 - jae bad_put_user
8605 -+
8606 -+#ifdef CONFIG_X86_32
8607 -+ pushl $(__USER_DS)
8608 -+ popl %ds
8609 -+#endif
8610 -+
8611 - 4: mov %_ASM_AX,(%_ASM_CX)
8612 - #ifdef CONFIG_X86_32
8613 - 5: movl %edx,4(%_ASM_CX)
8614 - #endif
8615 -+
8616 -+#ifdef CONFIG_X86_32
8617 -+ pushl %ss
8618 -+ popl %ds
8619 -+#endif
8620 -+
8621 - xor %eax,%eax
8622 - EXIT
8623 - ENDPROC(__put_user_8)
8624 -
8625 - bad_put_user:
8626 - CFI_STARTPROC
8627 -+
8628 -+#ifdef CONFIG_X86_32
8629 -+ pushl %ss
8630 -+ popl %ds
8631 -+#endif
8632 -+
8633 - movl $-EFAULT,%eax
8634 - EXIT
8635 - END(bad_put_user)
8636 -diff -urNp linux-2.6.27.6/arch/x86/lib/usercopy_32.c linux-2.6.27.6/arch/x86/lib/usercopy_32.c
8637 ---- linux-2.6.27.6/arch/x86/lib/usercopy_32.c 2008-11-07 12:55:34.000000000 -0500
8638 -+++ linux-2.6.27.6/arch/x86/lib/usercopy_32.c 2008-11-18 03:38:44.000000000 -0500
8639 -@@ -29,31 +29,38 @@ static inline int __movsl_is_ok(unsigned
8640 - * Copy a null terminated string from userspace.
8641 - */
8642 -
8643 --#define __do_strncpy_from_user(dst, src, count, res) \
8644 --do { \
8645 -- int __d0, __d1, __d2; \
8646 -- might_sleep(); \
8647 -- __asm__ __volatile__( \
8648 -- " testl %1,%1\n" \
8649 -- " jz 2f\n" \
8650 -- "0: lodsb\n" \
8651 -- " stosb\n" \
8652 -- " testb %%al,%%al\n" \
8653 -- " jz 1f\n" \
8654 -- " decl %1\n" \
8655 -- " jnz 0b\n" \
8656 -- "1: subl %1,%0\n" \
8657 -- "2:\n" \
8658 -- ".section .fixup,\"ax\"\n" \
8659 -- "3: movl %5,%0\n" \
8660 -- " jmp 2b\n" \
8661 -- ".previous\n" \
8662 -- _ASM_EXTABLE(0b,3b) \
8663 -- : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \
8664 -- "=&D" (__d2) \
8665 -- : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
8666 -- : "memory"); \
8667 --} while (0)
8668 -+static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
8669 -+{
8670 -+ int __d0, __d1, __d2;
8671 -+ long res = -EFAULT;
8672 -+
8673 -+ might_sleep();
8674 -+ __asm__ __volatile__(
8675 -+ " movw %w10,%%ds\n"
8676 -+ " testl %1,%1\n"
8677 -+ " jz 2f\n"
8678 -+ "0: lodsb\n"
8679 -+ " stosb\n"
8680 -+ " testb %%al,%%al\n"
8681 -+ " jz 1f\n"
8682 -+ " decl %1\n"
8683 -+ " jnz 0b\n"
8684 -+ "1: subl %1,%0\n"
8685 -+ "2:\n"
8686 -+ " pushl %%ss\n"
8687 -+ " popl %%ds\n"
8688 -+ ".section .fixup,\"ax\"\n"
8689 -+ "3: movl %5,%0\n"
8690 -+ " jmp 2b\n"
8691 -+ ".previous\n"
8692 -+ _ASM_EXTABLE(0b,3b)
8693 -+ : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),
8694 -+ "=&D" (__d2)
8695 -+ : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
8696 -+ "r"(__USER_DS)
8697 -+ : "memory");
8698 -+ return res;
8699 -+}
8700 -
8701 - /**
8702 - * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
8703 -@@ -78,9 +85,7 @@ do { \
8704 - long
8705 - __strncpy_from_user(char *dst, const char __user *src, long count)
8706 - {
8707 -- long res;
8708 -- __do_strncpy_from_user(dst, src, count, res);
8709 -- return res;
8710 -+ return __do_strncpy_from_user(dst, src, count);
8711 - }
8712 - EXPORT_SYMBOL(__strncpy_from_user);
8713 -
8714 -@@ -107,7 +112,7 @@ strncpy_from_user(char *dst, const char
8715 - {
8716 - long res = -EFAULT;
8717 - if (access_ok(VERIFY_READ, src, 1))
8718 -- __do_strncpy_from_user(dst, src, count, res);
8719 -+ res = __do_strncpy_from_user(dst, src, count);
8720 - return res;
8721 - }
8722 - EXPORT_SYMBOL(strncpy_from_user);
8723 -@@ -116,24 +121,30 @@ EXPORT_SYMBOL(strncpy_from_user);
8724 - * Zero Userspace
8725 - */
8726 -
8727 --#define __do_clear_user(addr,size) \
8728 --do { \
8729 -- int __d0; \
8730 -- might_sleep(); \
8731 -- __asm__ __volatile__( \
8732 -- "0: rep; stosl\n" \
8733 -- " movl %2,%0\n" \
8734 -- "1: rep; stosb\n" \
8735 -- "2:\n" \
8736 -- ".section .fixup,\"ax\"\n" \
8737 -- "3: lea 0(%2,%0,4),%0\n" \
8738 -- " jmp 2b\n" \
8739 -- ".previous\n" \
8740 -- _ASM_EXTABLE(0b,3b) \
8741 -- _ASM_EXTABLE(1b,2b) \
8742 -- : "=&c"(size), "=&D" (__d0) \
8743 -- : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
8744 --} while (0)
8745 -+static unsigned long __do_clear_user(void __user *addr, unsigned long size)
8746 -+{
8747 -+ int __d0;
8748 -+
8749 -+ might_sleep();
8750 -+ __asm__ __volatile__(
8751 -+ " movw %w6,%%es\n"
8752 -+ "0: rep; stosl\n"
8753 -+ " movl %2,%0\n"
8754 -+ "1: rep; stosb\n"
8755 -+ "2:\n"
8756 -+ " pushl %%ss\n"
8757 -+ " popl %%es\n"
8758 -+ ".section .fixup,\"ax\"\n"
8759 -+ "3: lea 0(%2,%0,4),%0\n"
8760 -+ " jmp 2b\n"
8761 -+ ".previous\n"
8762 -+ _ASM_EXTABLE(0b,3b)
8763 -+ _ASM_EXTABLE(1b,2b)
8764 -+ : "=&c"(size), "=&D" (__d0)
8765 -+ : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
8766 -+ "r"(__USER_DS));
8767 -+ return size;
8768 -+}
8769 -
8770 - /**
8771 - * clear_user: - Zero a block of memory in user space.
8772 -@@ -150,7 +161,7 @@ clear_user(void __user *to, unsigned lon
8773 - {
8774 - might_sleep();
8775 - if (access_ok(VERIFY_WRITE, to, n))
8776 -- __do_clear_user(to, n);
8777 -+ n = __do_clear_user(to, n);
8778 - return n;
8779 - }
8780 - EXPORT_SYMBOL(clear_user);
8781 -@@ -169,8 +180,7 @@ EXPORT_SYMBOL(clear_user);
8782 - unsigned long
8783 - __clear_user(void __user *to, unsigned long n)
8784 - {
8785 -- __do_clear_user(to, n);
8786 -- return n;
8787 -+ return __do_clear_user(to, n);
8788 - }
8789 - EXPORT_SYMBOL(__clear_user);
8790 -
8791 -@@ -193,14 +203,17 @@ long strnlen_user(const char __user *s,
8792 - might_sleep();
8793 -
8794 - __asm__ __volatile__(
8795 -+ " movw %w8,%%es\n"
8796 - " testl %0, %0\n"
8797 - " jz 3f\n"
8798 -- " andl %0,%%ecx\n"
8799 -+ " movl %0,%%ecx\n"
8800 - "0: repne; scasb\n"
8801 - " setne %%al\n"
8802 - " subl %%ecx,%0\n"
8803 - " addl %0,%%eax\n"
8804 - "1:\n"
8805 -+ " pushl %%ss\n"
8806 -+ " popl %%es\n"
8807 - ".section .fixup,\"ax\"\n"
8808 - "2: xorl %%eax,%%eax\n"
8809 - " jmp 1b\n"
8810 -@@ -212,7 +225,7 @@ long strnlen_user(const char __user *s,
8811 - " .long 0b,2b\n"
8812 - ".previous"
8813 - :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
8814 -- :"0" (n), "1" (s), "2" (0), "3" (mask)
8815 -+ :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
8816 - :"cc");
8817 - return res & mask;
8818 - }
8819 -@@ -220,10 +233,11 @@ EXPORT_SYMBOL(strnlen_user);
8820 -
8821 - #ifdef CONFIG_X86_INTEL_USERCOPY
8822 - static unsigned long
8823 --__copy_user_intel(void __user *to, const void *from, unsigned long size)
8824 -+__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
8825 - {
8826 - int d0, d1;
8827 - __asm__ __volatile__(
8828 -+ " movw %w6, %%es\n"
8829 - " .align 2,0x90\n"
8830 - "1: movl 32(%4), %%eax\n"
8831 - " cmpl $67, %0\n"
8832 -@@ -232,36 +246,36 @@ __copy_user_intel(void __user *to, const
8833 - " .align 2,0x90\n"
8834 - "3: movl 0(%4), %%eax\n"
8835 - "4: movl 4(%4), %%edx\n"
8836 -- "5: movl %%eax, 0(%3)\n"
8837 -- "6: movl %%edx, 4(%3)\n"
8838 -+ "5: movl %%eax, %%es:0(%3)\n"
8839 -+ "6: movl %%edx, %%es:4(%3)\n"
8840 - "7: movl 8(%4), %%eax\n"
8841 - "8: movl 12(%4),%%edx\n"
8842 -- "9: movl %%eax, 8(%3)\n"
8843 -- "10: movl %%edx, 12(%3)\n"
8844 -+ "9: movl %%eax, %%es:8(%3)\n"
8845 -+ "10: movl %%edx, %%es:12(%3)\n"
8846 - "11: movl 16(%4), %%eax\n"
8847 - "12: movl 20(%4), %%edx\n"
8848 -- "13: movl %%eax, 16(%3)\n"
8849 -- "14: movl %%edx, 20(%3)\n"
8850 -+ "13: movl %%eax, %%es:16(%3)\n"
8851 -+ "14: movl %%edx, %%es:20(%3)\n"
8852 - "15: movl 24(%4), %%eax\n"
8853 - "16: movl 28(%4), %%edx\n"
8854 -- "17: movl %%eax, 24(%3)\n"
8855 -- "18: movl %%edx, 28(%3)\n"
8856 -+ "17: movl %%eax, %%es:24(%3)\n"
8857 -+ "18: movl %%edx, %%es:28(%3)\n"
8858 - "19: movl 32(%4), %%eax\n"
8859 - "20: movl 36(%4), %%edx\n"
8860 -- "21: movl %%eax, 32(%3)\n"
8861 -- "22: movl %%edx, 36(%3)\n"
8862 -+ "21: movl %%eax, %%es:32(%3)\n"
8863 -+ "22: movl %%edx, %%es:36(%3)\n"
8864 - "23: movl 40(%4), %%eax\n"
8865 - "24: movl 44(%4), %%edx\n"
8866 -- "25: movl %%eax, 40(%3)\n"
8867 -- "26: movl %%edx, 44(%3)\n"
8868 -+ "25: movl %%eax, %%es:40(%3)\n"
8869 -+ "26: movl %%edx, %%es:44(%3)\n"
8870 - "27: movl 48(%4), %%eax\n"
8871 - "28: movl 52(%4), %%edx\n"
8872 -- "29: movl %%eax, 48(%3)\n"
8873 -- "30: movl %%edx, 52(%3)\n"
8874 -+ "29: movl %%eax, %%es:48(%3)\n"
8875 -+ "30: movl %%edx, %%es:52(%3)\n"
8876 - "31: movl 56(%4), %%eax\n"
8877 - "32: movl 60(%4), %%edx\n"
8878 -- "33: movl %%eax, 56(%3)\n"
8879 -- "34: movl %%edx, 60(%3)\n"
8880 -+ "33: movl %%eax, %%es:56(%3)\n"
8881 -+ "34: movl %%edx, %%es:60(%3)\n"
8882 - " addl $-64, %0\n"
8883 - " addl $64, %4\n"
8884 - " addl $64, %3\n"
8885 -@@ -275,6 +289,8 @@ __copy_user_intel(void __user *to, const
8886 - "36: movl %%eax, %0\n"
8887 - "37: rep; movsb\n"
8888 - "100:\n"
8889 -+ " pushl %%ss\n"
8890 -+ " popl %%es\n"
8891 - ".section .fixup,\"ax\"\n"
8892 - "101: lea 0(%%eax,%0,4),%0\n"
8893 - " jmp 100b\n"
8894 -@@ -321,7 +337,117 @@ __copy_user_intel(void __user *to, const
8895 - " .long 99b,101b\n"
8896 - ".previous"
8897 - : "=&c"(size), "=&D" (d0), "=&S" (d1)
8898 -- : "1"(to), "2"(from), "0"(size)
8899 -+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
8900 -+ : "eax", "edx", "memory");
8901 -+ return size;
8902 -+}
8903 -+
8904 -+static unsigned long
8905 -+__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
8906 -+{
8907 -+ int d0, d1;
8908 -+ __asm__ __volatile__(
8909 -+ " movw %w6, %%ds\n"
8910 -+ " .align 2,0x90\n"
8911 -+ "1: movl 32(%4), %%eax\n"
8912 -+ " cmpl $67, %0\n"
8913 -+ " jbe 3f\n"
8914 -+ "2: movl 64(%4), %%eax\n"
8915 -+ " .align 2,0x90\n"
8916 -+ "3: movl 0(%4), %%eax\n"
8917 -+ "4: movl 4(%4), %%edx\n"
8918 -+ "5: movl %%eax, %%es:0(%3)\n"
8919 -+ "6: movl %%edx, %%es:4(%3)\n"
8920 -+ "7: movl 8(%4), %%eax\n"
8921 -+ "8: movl 12(%4),%%edx\n"
8922 -+ "9: movl %%eax, %%es:8(%3)\n"
8923 -+ "10: movl %%edx, %%es:12(%3)\n"
8924 -+ "11: movl 16(%4), %%eax\n"
8925 -+ "12: movl 20(%4), %%edx\n"
8926 -+ "13: movl %%eax, %%es:16(%3)\n"
8927 -+ "14: movl %%edx, %%es:20(%3)\n"
8928 -+ "15: movl 24(%4), %%eax\n"
8929 -+ "16: movl 28(%4), %%edx\n"
8930 -+ "17: movl %%eax, %%es:24(%3)\n"
8931 -+ "18: movl %%edx, %%es:28(%3)\n"
8932 -+ "19: movl 32(%4), %%eax\n"
8933 -+ "20: movl 36(%4), %%edx\n"
8934 -+ "21: movl %%eax, %%es:32(%3)\n"
8935 -+ "22: movl %%edx, %%es:36(%3)\n"
8936 -+ "23: movl 40(%4), %%eax\n"
8937 -+ "24: movl 44(%4), %%edx\n"
8938 -+ "25: movl %%eax, %%es:40(%3)\n"
8939 -+ "26: movl %%edx, %%es:44(%3)\n"
8940 -+ "27: movl 48(%4), %%eax\n"
8941 -+ "28: movl 52(%4), %%edx\n"
8942 -+ "29: movl %%eax, %%es:48(%3)\n"
8943 -+ "30: movl %%edx, %%es:52(%3)\n"
8944 -+ "31: movl 56(%4), %%eax\n"
8945 -+ "32: movl 60(%4), %%edx\n"
8946 -+ "33: movl %%eax, %%es:56(%3)\n"
8947 -+ "34: movl %%edx, %%es:60(%3)\n"
8948 -+ " addl $-64, %0\n"
8949 -+ " addl $64, %4\n"
8950 -+ " addl $64, %3\n"
8951 -+ " cmpl $63, %0\n"
8952 -+ " ja 1b\n"
8953 -+ "35: movl %0, %%eax\n"
8954 -+ " shrl $2, %0\n"
8955 -+ " andl $3, %%eax\n"
8956 -+ " cld\n"
8957 -+ "99: rep; movsl\n"
8958 -+ "36: movl %%eax, %0\n"
8959 -+ "37: rep; movsb\n"
8960 -+ "100:\n"
8961 -+ " pushl %%ss\n"
8962 -+ " popl %%ds\n"
8963 -+ ".section .fixup,\"ax\"\n"
8964 -+ "101: lea 0(%%eax,%0,4),%0\n"
8965 -+ " jmp 100b\n"
8966 -+ ".previous\n"
8967 -+ ".section __ex_table,\"a\"\n"
8968 -+ " .align 4\n"
8969 -+ " .long 1b,100b\n"
8970 -+ " .long 2b,100b\n"
8971 -+ " .long 3b,100b\n"
8972 -+ " .long 4b,100b\n"
8973 -+ " .long 5b,100b\n"
8974 -+ " .long 6b,100b\n"
8975 -+ " .long 7b,100b\n"
8976 -+ " .long 8b,100b\n"
8977 -+ " .long 9b,100b\n"
8978 -+ " .long 10b,100b\n"
8979 -+ " .long 11b,100b\n"
8980 -+ " .long 12b,100b\n"
8981 -+ " .long 13b,100b\n"
8982 -+ " .long 14b,100b\n"
8983 -+ " .long 15b,100b\n"
8984 -+ " .long 16b,100b\n"
8985 -+ " .long 17b,100b\n"
8986 -+ " .long 18b,100b\n"
8987 -+ " .long 19b,100b\n"
8988 -+ " .long 20b,100b\n"
8989 -+ " .long 21b,100b\n"
8990 -+ " .long 22b,100b\n"
8991 -+ " .long 23b,100b\n"
8992 -+ " .long 24b,100b\n"
8993 -+ " .long 25b,100b\n"
8994 -+ " .long 26b,100b\n"
8995 -+ " .long 27b,100b\n"
8996 -+ " .long 28b,100b\n"
8997 -+ " .long 29b,100b\n"
8998 -+ " .long 30b,100b\n"
8999 -+ " .long 31b,100b\n"
9000 -+ " .long 32b,100b\n"
9001 -+ " .long 33b,100b\n"
9002 -+ " .long 34b,100b\n"
9003 -+ " .long 35b,100b\n"
9004 -+ " .long 36b,100b\n"
9005 -+ " .long 37b,100b\n"
9006 -+ " .long 99b,101b\n"
9007 -+ ".previous"
9008 -+ : "=&c"(size), "=&D" (d0), "=&S" (d1)
9009 -+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9010 - : "eax", "edx", "memory");
9011 - return size;
9012 - }
9013 -@@ -331,6 +457,7 @@ __copy_user_zeroing_intel(void *to, cons
9014 - {
9015 - int d0, d1;
9016 - __asm__ __volatile__(
9017 -+ " movw %w6, %%ds\n"
9018 - " .align 2,0x90\n"
9019 - "0: movl 32(%4), %%eax\n"
9020 - " cmpl $67, %0\n"
9021 -@@ -339,36 +466,36 @@ __copy_user_zeroing_intel(void *to, cons
9022 - " .align 2,0x90\n"
9023 - "2: movl 0(%4), %%eax\n"
9024 - "21: movl 4(%4), %%edx\n"
9025 -- " movl %%eax, 0(%3)\n"
9026 -- " movl %%edx, 4(%3)\n"
9027 -+ " movl %%eax, %%es:0(%3)\n"
9028 -+ " movl %%edx, %%es:4(%3)\n"
9029 - "3: movl 8(%4), %%eax\n"
9030 - "31: movl 12(%4),%%edx\n"
9031 -- " movl %%eax, 8(%3)\n"
9032 -- " movl %%edx, 12(%3)\n"
9033 -+ " movl %%eax, %%es:8(%3)\n"
9034 -+ " movl %%edx, %%es:12(%3)\n"
9035 - "4: movl 16(%4), %%eax\n"
9036 - "41: movl 20(%4), %%edx\n"
9037 -- " movl %%eax, 16(%3)\n"
9038 -- " movl %%edx, 20(%3)\n"
9039 -+ " movl %%eax, %%es:16(%3)\n"
9040 -+ " movl %%edx, %%es:20(%3)\n"
9041 - "10: movl 24(%4), %%eax\n"
9042 - "51: movl 28(%4), %%edx\n"
9043 -- " movl %%eax, 24(%3)\n"
9044 -- " movl %%edx, 28(%3)\n"
9045 -+ " movl %%eax, %%es:24(%3)\n"
9046 -+ " movl %%edx, %%es:28(%3)\n"
9047 - "11: movl 32(%4), %%eax\n"
9048 - "61: movl 36(%4), %%edx\n"
9049 -- " movl %%eax, 32(%3)\n"
9050 -- " movl %%edx, 36(%3)\n"
9051 -+ " movl %%eax, %%es:32(%3)\n"
9052 -+ " movl %%edx, %%es:36(%3)\n"
9053 - "12: movl 40(%4), %%eax\n"
9054 - "71: movl 44(%4), %%edx\n"
9055 -- " movl %%eax, 40(%3)\n"
9056 -- " movl %%edx, 44(%3)\n"
9057 -+ " movl %%eax, %%es:40(%3)\n"
9058 -+ " movl %%edx, %%es:44(%3)\n"
9059 - "13: movl 48(%4), %%eax\n"
9060 - "81: movl 52(%4), %%edx\n"
9061 -- " movl %%eax, 48(%3)\n"
9062 -- " movl %%edx, 52(%3)\n"
9063 -+ " movl %%eax, %%es:48(%3)\n"
9064 -+ " movl %%edx, %%es:52(%3)\n"
9065 - "14: movl 56(%4), %%eax\n"
9066 - "91: movl 60(%4), %%edx\n"
9067 -- " movl %%eax, 56(%3)\n"
9068 -- " movl %%edx, 60(%3)\n"
9069 -+ " movl %%eax, %%es:56(%3)\n"
9070 -+ " movl %%edx, %%es:60(%3)\n"
9071 - " addl $-64, %0\n"
9072 - " addl $64, %4\n"
9073 - " addl $64, %3\n"
9074 -@@ -382,6 +509,8 @@ __copy_user_zeroing_intel(void *to, cons
9075 - " movl %%eax,%0\n"
9076 - "7: rep; movsb\n"
9077 - "8:\n"
9078 -+ " pushl %%ss\n"
9079 -+ " popl %%ds\n"
9080 - ".section .fixup,\"ax\"\n"
9081 - "9: lea 0(%%eax,%0,4),%0\n"
9082 - "16: pushl %0\n"
9083 -@@ -416,7 +545,7 @@ __copy_user_zeroing_intel(void *to, cons
9084 - " .long 7b,16b\n"
9085 - ".previous"
9086 - : "=&c"(size), "=&D" (d0), "=&S" (d1)
9087 -- : "1"(to), "2"(from), "0"(size)
9088 -+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9089 - : "eax", "edx", "memory");
9090 - return size;
9091 - }
9092 -@@ -432,6 +561,7 @@ static unsigned long __copy_user_zeroing
9093 - int d0, d1;
9094 -
9095 - __asm__ __volatile__(
9096 -+ " movw %w6, %%ds\n"
9097 - " .align 2,0x90\n"
9098 - "0: movl 32(%4), %%eax\n"
9099 - " cmpl $67, %0\n"
9100 -@@ -440,36 +570,36 @@ static unsigned long __copy_user_zeroing
9101 - " .align 2,0x90\n"
9102 - "2: movl 0(%4), %%eax\n"
9103 - "21: movl 4(%4), %%edx\n"
9104 -- " movnti %%eax, 0(%3)\n"
9105 -- " movnti %%edx, 4(%3)\n"
9106 -+ " movnti %%eax, %%es:0(%3)\n"
9107 -+ " movnti %%edx, %%es:4(%3)\n"
9108 - "3: movl 8(%4), %%eax\n"
9109 - "31: movl 12(%4),%%edx\n"
9110 -- " movnti %%eax, 8(%3)\n"
9111 -- " movnti %%edx, 12(%3)\n"
9112 -+ " movnti %%eax, %%es:8(%3)\n"
9113 -+ " movnti %%edx, %%es:12(%3)\n"
9114 - "4: movl 16(%4), %%eax\n"
9115 - "41: movl 20(%4), %%edx\n"
9116 -- " movnti %%eax, 16(%3)\n"
9117 -- " movnti %%edx, 20(%3)\n"
9118 -+ " movnti %%eax, %%es:16(%3)\n"
9119 -+ " movnti %%edx, %%es:20(%3)\n"
9120 - "10: movl 24(%4), %%eax\n"
9121 - "51: movl 28(%4), %%edx\n"
9122 -- " movnti %%eax, 24(%3)\n"
9123 -- " movnti %%edx, 28(%3)\n"
9124 -+ " movnti %%eax, %%es:24(%3)\n"
9125 -+ " movnti %%edx, %%es:28(%3)\n"
9126 - "11: movl 32(%4), %%eax\n"
9127 - "61: movl 36(%4), %%edx\n"
9128 -- " movnti %%eax, 32(%3)\n"
9129 -- " movnti %%edx, 36(%3)\n"
9130 -+ " movnti %%eax, %%es:32(%3)\n"
9131 -+ " movnti %%edx, %%es:36(%3)\n"
9132 - "12: movl 40(%4), %%eax\n"
9133 - "71: movl 44(%4), %%edx\n"
9134 -- " movnti %%eax, 40(%3)\n"
9135 -- " movnti %%edx, 44(%3)\n"
9136 -+ " movnti %%eax, %%es:40(%3)\n"
9137 -+ " movnti %%edx, %%es:44(%3)\n"
9138 - "13: movl 48(%4), %%eax\n"
9139 - "81: movl 52(%4), %%edx\n"
9140 -- " movnti %%eax, 48(%3)\n"
9141 -- " movnti %%edx, 52(%3)\n"
9142 -+ " movnti %%eax, %%es:48(%3)\n"
9143 -+ " movnti %%edx, %%es:52(%3)\n"
9144 - "14: movl 56(%4), %%eax\n"
9145 - "91: movl 60(%4), %%edx\n"
9146 -- " movnti %%eax, 56(%3)\n"
9147 -- " movnti %%edx, 60(%3)\n"
9148 -+ " movnti %%eax, %%es:56(%3)\n"
9149 -+ " movnti %%edx, %%es:60(%3)\n"
9150 - " addl $-64, %0\n"
9151 - " addl $64, %4\n"
9152 - " addl $64, %3\n"
9153 -@@ -484,6 +614,8 @@ static unsigned long __copy_user_zeroing
9154 - " movl %%eax,%0\n"
9155 - "7: rep; movsb\n"
9156 - "8:\n"
9157 -+ " pushl %%ss\n"
9158 -+ " popl %%ds\n"
9159 - ".section .fixup,\"ax\"\n"
9160 - "9: lea 0(%%eax,%0,4),%0\n"
9161 - "16: pushl %0\n"
9162 -@@ -518,7 +650,7 @@ static unsigned long __copy_user_zeroing
9163 - " .long 7b,16b\n"
9164 - ".previous"
9165 - : "=&c"(size), "=&D" (d0), "=&S" (d1)
9166 -- : "1"(to), "2"(from), "0"(size)
9167 -+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9168 - : "eax", "edx", "memory");
9169 - return size;
9170 - }
9171 -@@ -529,6 +661,7 @@ static unsigned long __copy_user_intel_n
9172 - int d0, d1;
9173 -
9174 - __asm__ __volatile__(
9175 -+ " movw %w6, %%ds\n"
9176 - " .align 2,0x90\n"
9177 - "0: movl 32(%4), %%eax\n"
9178 - " cmpl $67, %0\n"
9179 -@@ -537,36 +670,36 @@ static unsigned long __copy_user_intel_n
9180 - " .align 2,0x90\n"
9181 - "2: movl 0(%4), %%eax\n"
9182 - "21: movl 4(%4), %%edx\n"
9183 -- " movnti %%eax, 0(%3)\n"
9184 -- " movnti %%edx, 4(%3)\n"
9185 -+ " movnti %%eax, %%es:0(%3)\n"
9186 -+ " movnti %%edx, %%es:4(%3)\n"
9187 - "3: movl 8(%4), %%eax\n"
9188 - "31: movl 12(%4),%%edx\n"
9189 -- " movnti %%eax, 8(%3)\n"
9190 -- " movnti %%edx, 12(%3)\n"
9191 -+ " movnti %%eax, %%es:8(%3)\n"
9192 -+ " movnti %%edx, %%es:12(%3)\n"
9193 - "4: movl 16(%4), %%eax\n"
9194 - "41: movl 20(%4), %%edx\n"
9195 -- " movnti %%eax, 16(%3)\n"
9196 -- " movnti %%edx, 20(%3)\n"
9197 -+ " movnti %%eax, %%es:16(%3)\n"
9198 -+ " movnti %%edx, %%es:20(%3)\n"
9199 - "10: movl 24(%4), %%eax\n"
9200 - "51: movl 28(%4), %%edx\n"
9201 -- " movnti %%eax, 24(%3)\n"
9202 -- " movnti %%edx, 28(%3)\n"
9203 -+ " movnti %%eax, %%es:24(%3)\n"
9204 -+ " movnti %%edx, %%es:28(%3)\n"
9205 - "11: movl 32(%4), %%eax\n"
9206 - "61: movl 36(%4), %%edx\n"
9207 -- " movnti %%eax, 32(%3)\n"
9208 -- " movnti %%edx, 36(%3)\n"
9209 -+ " movnti %%eax, %%es:32(%3)\n"
9210 -+ " movnti %%edx, %%es:36(%3)\n"
9211 - "12: movl 40(%4), %%eax\n"
9212 - "71: movl 44(%4), %%edx\n"
9213 -- " movnti %%eax, 40(%3)\n"
9214 -- " movnti %%edx, 44(%3)\n"
9215 -+ " movnti %%eax, %%es:40(%3)\n"
9216 -+ " movnti %%edx, %%es:44(%3)\n"
9217 - "13: movl 48(%4), %%eax\n"
9218 - "81: movl 52(%4), %%edx\n"
9219 -- " movnti %%eax, 48(%3)\n"
9220 -- " movnti %%edx, 52(%3)\n"
9221 -+ " movnti %%eax, %%es:48(%3)\n"
9222 -+ " movnti %%edx, %%es:52(%3)\n"
9223 - "14: movl 56(%4), %%eax\n"
9224 - "91: movl 60(%4), %%edx\n"
9225 -- " movnti %%eax, 56(%3)\n"
9226 -- " movnti %%edx, 60(%3)\n"
9227 -+ " movnti %%eax, %%es:56(%3)\n"
9228 -+ " movnti %%edx, %%es:60(%3)\n"
9229 - " addl $-64, %0\n"
9230 - " addl $64, %4\n"
9231 - " addl $64, %3\n"
9232 -@@ -581,6 +714,8 @@ static unsigned long __copy_user_intel_n
9233 - " movl %%eax,%0\n"
9234 - "7: rep; movsb\n"
9235 - "8:\n"
9236 -+ " pushl %%ss\n"
9237 -+ " popl %%ds\n"
9238 - ".section .fixup,\"ax\"\n"
9239 - "9: lea 0(%%eax,%0,4),%0\n"
9240 - "16: jmp 8b\n"
9241 -@@ -609,7 +744,7 @@ static unsigned long __copy_user_intel_n
9242 - " .long 7b,16b\n"
9243 - ".previous"
9244 - : "=&c"(size), "=&D" (d0), "=&S" (d1)
9245 -- : "1"(to), "2"(from), "0"(size)
9246 -+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9247 - : "eax", "edx", "memory");
9248 - return size;
9249 - }
9250 -@@ -622,90 +757,146 @@ static unsigned long __copy_user_intel_n
9251 - */
9252 - unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
9253 - unsigned long size);
9254 --unsigned long __copy_user_intel(void __user *to, const void *from,
9255 -+unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
9256 -+ unsigned long size);
9257 -+unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
9258 - unsigned long size);
9259 - unsigned long __copy_user_zeroing_intel_nocache(void *to,
9260 - const void __user *from, unsigned long size);
9261 - #endif /* CONFIG_X86_INTEL_USERCOPY */
9262 -
9263 - /* Generic arbitrary sized copy. */
9264 --#define __copy_user(to, from, size) \
9265 --do { \
9266 -- int __d0, __d1, __d2; \
9267 -- __asm__ __volatile__( \
9268 -- " cmp $7,%0\n" \
9269 -- " jbe 1f\n" \
9270 -- " movl %1,%0\n" \
9271 -- " negl %0\n" \
9272 -- " andl $7,%0\n" \
9273 -- " subl %0,%3\n" \
9274 -- "4: rep; movsb\n" \
9275 -- " movl %3,%0\n" \
9276 -- " shrl $2,%0\n" \
9277 -- " andl $3,%3\n" \
9278 -- " .align 2,0x90\n" \
9279 -- "0: rep; movsl\n" \
9280 -- " movl %3,%0\n" \
9281 -- "1: rep; movsb\n" \
9282 -- "2:\n" \
9283 -- ".section .fixup,\"ax\"\n" \
9284 -- "5: addl %3,%0\n" \
9285 -- " jmp 2b\n" \
9286 -- "3: lea 0(%3,%0,4),%0\n" \
9287 -- " jmp 2b\n" \
9288 -- ".previous\n" \
9289 -- ".section __ex_table,\"a\"\n" \
9290 -- " .align 4\n" \
9291 -- " .long 4b,5b\n" \
9292 -- " .long 0b,3b\n" \
9293 -- " .long 1b,2b\n" \
9294 -- ".previous" \
9295 -- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
9296 -- : "3"(size), "0"(size), "1"(to), "2"(from) \
9297 -- : "memory"); \
9298 --} while (0)
9299 --
9300 --#define __copy_user_zeroing(to, from, size) \
9301 --do { \
9302 -- int __d0, __d1, __d2; \
9303 -- __asm__ __volatile__( \
9304 -- " cmp $7,%0\n" \
9305 -- " jbe 1f\n" \
9306 -- " movl %1,%0\n" \
9307 -- " negl %0\n" \
9308 -- " andl $7,%0\n" \
9309 -- " subl %0,%3\n" \
9310 -- "4: rep; movsb\n" \
9311 -- " movl %3,%0\n" \
9312 -- " shrl $2,%0\n" \
9313 -- " andl $3,%3\n" \
9314 -- " .align 2,0x90\n" \
9315 -- "0: rep; movsl\n" \
9316 -- " movl %3,%0\n" \
9317 -- "1: rep; movsb\n" \
9318 -- "2:\n" \
9319 -- ".section .fixup,\"ax\"\n" \
9320 -- "5: addl %3,%0\n" \
9321 -- " jmp 6f\n" \
9322 -- "3: lea 0(%3,%0,4),%0\n" \
9323 -- "6: pushl %0\n" \
9324 -- " pushl %%eax\n" \
9325 -- " xorl %%eax,%%eax\n" \
9326 -- " rep; stosb\n" \
9327 -- " popl %%eax\n" \
9328 -- " popl %0\n" \
9329 -- " jmp 2b\n" \
9330 -- ".previous\n" \
9331 -- ".section __ex_table,\"a\"\n" \
9332 -- " .align 4\n" \
9333 -- " .long 4b,5b\n" \
9334 -- " .long 0b,3b\n" \
9335 -- " .long 1b,6b\n" \
9336 -- ".previous" \
9337 -- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
9338 -- : "3"(size), "0"(size), "1"(to), "2"(from) \
9339 -- : "memory"); \
9340 --} while (0)
9341 -+static unsigned long
9342 -+__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
9343 -+{
9344 -+ int __d0, __d1, __d2;
9345 -+
9346 -+ __asm__ __volatile__(
9347 -+ " movw %w8,%%es\n"
9348 -+ " cmp $7,%0\n"
9349 -+ " jbe 1f\n"
9350 -+ " movl %1,%0\n"
9351 -+ " negl %0\n"
9352 -+ " andl $7,%0\n"
9353 -+ " subl %0,%3\n"
9354 -+ "4: rep; movsb\n"
9355 -+ " movl %3,%0\n"
9356 -+ " shrl $2,%0\n"
9357 -+ " andl $3,%3\n"
9358 -+ " .align 2,0x90\n"
9359 -+ "0: rep; movsl\n"
9360 -+ " movl %3,%0\n"
9361 -+ "1: rep; movsb\n"
9362 -+ "2:\n"
9363 -+ " pushl %%ss\n"
9364 -+ " popl %%es\n"
9365 -+ ".section .fixup,\"ax\"\n"
9366 -+ "5: addl %3,%0\n"
9367 -+ " jmp 2b\n"
9368 -+ "3: lea 0(%3,%0,4),%0\n"
9369 -+ " jmp 2b\n"
9370 -+ ".previous\n"
9371 -+ ".section __ex_table,\"a\"\n"
9372 -+ " .align 4\n"
9373 -+ " .long 4b,5b\n"
9374 -+ " .long 0b,3b\n"
9375 -+ " .long 1b,2b\n"
9376 -+ ".previous"
9377 -+ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
9378 -+ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
9379 -+ : "memory");
9380 -+ return size;
9381 -+}
9382 -+
9383 -+static unsigned long
9384 -+__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
9385 -+{
9386 -+ int __d0, __d1, __d2;
9387 -+
9388 -+ __asm__ __volatile__(
9389 -+ " movw %w8,%%ds\n"
9390 -+ " cmp $7,%0\n"
9391 -+ " jbe 1f\n"
9392 -+ " movl %1,%0\n"
9393 -+ " negl %0\n"
9394 -+ " andl $7,%0\n"
9395 -+ " subl %0,%3\n"
9396 -+ "4: rep; movsb\n"
9397 -+ " movl %3,%0\n"
9398 -+ " shrl $2,%0\n"
9399 -+ " andl $3,%3\n"
9400 -+ " .align 2,0x90\n"
9401 -+ "0: rep; movsl\n"
9402 -+ " movl %3,%0\n"
9403 -+ "1: rep; movsb\n"
9404 -+ "2:\n"
9405 -+ " pushl %%ss\n"
9406 -+ " popl %%ds\n"
9407 -+ ".section .fixup,\"ax\"\n"
9408 -+ "5: addl %3,%0\n"
9409 -+ " jmp 2b\n"
9410 -+ "3: lea 0(%3,%0,4),%0\n"
9411 -+ " jmp 2b\n"
9412 -+ ".previous\n"
9413 -+ ".section __ex_table,\"a\"\n"
9414 -+ " .align 4\n"
9415 -+ " .long 4b,5b\n"
9416 -+ " .long 0b,3b\n"
9417 -+ " .long 1b,2b\n"
9418 -+ ".previous"
9419 -+ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
9420 -+ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
9421 -+ : "memory");
9422 -+ return size;
9423 -+}
9424 -+
9425 -+static unsigned long
9426 -+__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
9427 -+{
9428 -+ int __d0, __d1, __d2;
9429 -+
9430 -+ __asm__ __volatile__(
9431 -+ " movw %w8,%%ds\n"
9432 -+ " cmp $7,%0\n"
9433 -+ " jbe 1f\n"
9434 -+ " movl %1,%0\n"
9435 -+ " negl %0\n"
9436 -+ " andl $7,%0\n"
9437 -+ " subl %0,%3\n"
9438 -+ "4: rep; movsb\n"
9439 -+ " movl %3,%0\n"
9440 -+ " shrl $2,%0\n"
9441 -+ " andl $3,%3\n"
9442 -+ " .align 2,0x90\n"
9443 -+ "0: rep; movsl\n"
9444 -+ " movl %3,%0\n"
9445 -+ "1: rep; movsb\n"
9446 -+ "2:\n"
9447 -+ " pushl %%ss\n"
9448 -+ " popl %%ds\n"
9449 -+ ".section .fixup,\"ax\"\n"
9450 -+ "5: addl %3,%0\n"
9451 -+ " jmp 6f\n"
9452 -+ "3: lea 0(%3,%0,4),%0\n"
9453 -+ "6: pushl %0\n"
9454 -+ " pushl %%eax\n"
9455 -+ " xorl %%eax,%%eax\n"
9456 -+ " rep; stosb\n"
9457 -+ " popl %%eax\n"
9458 -+ " popl %0\n"
9459 -+ " jmp 2b\n"
9460 -+ ".previous\n"
9461 -+ ".section __ex_table,\"a\"\n"
9462 -+ " .align 4\n"
9463 -+ " .long 4b,5b\n"
9464 -+ " .long 0b,3b\n"
9465 -+ " .long 1b,6b\n"
9466 -+ ".previous"
9467 -+ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
9468 -+ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
9469 -+ : "memory");
9470 -+ return size;
9471 -+}
9472 -
9473 - unsigned long __copy_to_user_ll(void __user *to, const void *from,
9474 - unsigned long n)
9475 -@@ -768,9 +959,9 @@ survive:
9476 - }
9477 - #endif
9478 - if (movsl_is_ok(to, from, n))
9479 -- __copy_user(to, from, n);
9480 -+ n = __generic_copy_to_user(to, from, n);
9481 - else
9482 -- n = __copy_user_intel(to, from, n);
9483 -+ n = __generic_copy_to_user_intel(to, from, n);
9484 - return n;
9485 - }
9486 - EXPORT_SYMBOL(__copy_to_user_ll);
9487 -@@ -779,7 +970,7 @@ unsigned long __copy_from_user_ll(void *
9488 - unsigned long n)
9489 - {
9490 - if (movsl_is_ok(to, from, n))
9491 -- __copy_user_zeroing(to, from, n);
9492 -+ n = __copy_user_zeroing(to, from, n);
9493 - else
9494 - n = __copy_user_zeroing_intel(to, from, n);
9495 - return n;
9496 -@@ -790,10 +981,9 @@ unsigned long __copy_from_user_ll_nozero
9497 - unsigned long n)
9498 - {
9499 - if (movsl_is_ok(to, from, n))
9500 -- __copy_user(to, from, n);
9501 -+ n = __generic_copy_from_user(to, from, n);
9502 - else
9503 -- n = __copy_user_intel((void __user *)to,
9504 -- (const void *)from, n);
9505 -+ n = __generic_copy_from_user_intel(to, from, n);
9506 - return n;
9507 - }
9508 - EXPORT_SYMBOL(__copy_from_user_ll_nozero);
9509 -@@ -802,12 +992,12 @@ unsigned long __copy_from_user_ll_nocach
9510 - unsigned long n)
9511 - {
9512 - #ifdef CONFIG_X86_INTEL_USERCOPY
9513 -- if (n > 64 && cpu_has_xmm2)
9514 -+ if ( n > 64 && cpu_has_xmm2)
9515 - n = __copy_user_zeroing_intel_nocache(to, from, n);
9516 - else
9517 -- __copy_user_zeroing(to, from, n);
9518 -+ n = __copy_user_zeroing(to, from, n);
9519 - #else
9520 -- __copy_user_zeroing(to, from, n);
9521 -+ n = __copy_user_zeroing(to, from, n);
9522 - #endif
9523 - return n;
9524 - }
9525 -@@ -817,12 +1007,12 @@ unsigned long __copy_from_user_ll_nocach
9526 - unsigned long n)
9527 - {
9528 - #ifdef CONFIG_X86_INTEL_USERCOPY
9529 -- if (n > 64 && cpu_has_xmm2)
9530 -+ if ( n > 64 && cpu_has_xmm2)
9531 - n = __copy_user_intel_nocache(to, from, n);
9532 - else
9533 -- __copy_user(to, from, n);
9534 -+ n = __generic_copy_from_user(to, from, n);
9535 - #else
9536 -- __copy_user(to, from, n);
9537 -+ n = __generic_copy_from_user(to, from, n);
9538 - #endif
9539 - return n;
9540 - }
9541 -@@ -871,8 +1061,35 @@ copy_from_user(void *to, const void __us
9542 - {
9543 - if (access_ok(VERIFY_READ, from, n))
9544 - n = __copy_from_user(to, from, n);
9545 -- else
9546 -+ else if ((long)n > 0)
9547 - memset(to, 0, n);
9548 - return n;
9549 - }
9550 - EXPORT_SYMBOL(copy_from_user);
9551 -+
9552 -+#ifdef CONFIG_PAX_MEMORY_UDEREF
9553 -+void __set_fs(mm_segment_t x, int cpu)
9554 -+{
9555 -+ unsigned long limit = x.seg;
9556 -+ struct desc_struct d;
9557 -+
9558 -+ current_thread_info()->addr_limit = x;
9559 -+ if (likely(limit))
9560 -+ limit = (limit - 1UL) >> PAGE_SHIFT;
9561 -+ pack_descriptor(&d, 0UL, limit, 0xF3, 0xC);
9562 -+ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, &d, DESCTYPE_S);
9563 -+}
9564 -+
9565 -+void set_fs(mm_segment_t x)
9566 -+{
9567 -+ __set_fs(x, get_cpu());
9568 -+ put_cpu_no_resched();
9569 -+}
9570 -+#else
9571 -+void set_fs(mm_segment_t x)
9572 -+{
9573 -+ current_thread_info()->addr_limit = x;
9574 -+}
9575 -+#endif
9576 -+
9577 -+EXPORT_SYMBOL(set_fs);
9578 -diff -urNp linux-2.6.27.6/arch/x86/mach-voyager/voyager_basic.c linux-2.6.27.6/arch/x86/mach-voyager/voyager_basic.c
9579 ---- linux-2.6.27.6/arch/x86/mach-voyager/voyager_basic.c 2008-11-07 12:55:34.000000000 -0500
9580 -+++ linux-2.6.27.6/arch/x86/mach-voyager/voyager_basic.c 2008-11-18 03:38:44.000000000 -0500
9581 -@@ -123,7 +123,7 @@ int __init voyager_memory_detect(int reg
9582 - __u8 cmos[4];
9583 - ClickMap_t *map;
9584 - unsigned long map_addr;
9585 -- unsigned long old;
9586 -+ pte_t old;
9587 -
9588 - if (region >= CLICK_ENTRIES) {
9589 - printk("Voyager: Illegal ClickMap region %d\n", region);
9590 -@@ -138,7 +138,7 @@ int __init voyager_memory_detect(int reg
9591 -
9592 - /* steal page 0 for this */
9593 - old = pg0[0];
9594 -- pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
9595 -+ pg0[0] = __pte((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
9596 - local_flush_tlb();
9597 - /* now clear everything out but page 0 */
9598 - map = (ClickMap_t *) (map_addr & (~PAGE_MASK));
9599 -diff -urNp linux-2.6.27.6/arch/x86/mach-voyager/voyager_smp.c linux-2.6.27.6/arch/x86/mach-voyager/voyager_smp.c
9600 ---- linux-2.6.27.6/arch/x86/mach-voyager/voyager_smp.c 2008-11-07 12:55:34.000000000 -0500
9601 -+++ linux-2.6.27.6/arch/x86/mach-voyager/voyager_smp.c 2008-11-18 03:38:44.000000000 -0500
9602 -@@ -510,6 +510,10 @@ static void __init do_boot_cpu(__u8 cpu)
9603 - __u32 *hijack_vector;
9604 - __u32 start_phys_address = setup_trampoline();
9605 -
9606 -+#ifdef CONFIG_PAX_KERNEXEC
9607 -+ unsigned long cr0;
9608 -+#endif
9609 -+
9610 - /* There's a clever trick to this: The linux trampoline is
9611 - * compiled to begin at absolute location zero, so make the
9612 - * address zero but have the data segment selector compensate
9613 -@@ -529,7 +533,17 @@ static void __init do_boot_cpu(__u8 cpu)
9614 -
9615 - init_gdt(cpu);
9616 - per_cpu(current_task, cpu) = idle;
9617 -- early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
9618 -+
9619 -+#ifdef CONFIG_PAX_KERNEXEC
9620 -+ pax_open_kernel(cr0);
9621 -+#endif
9622 -+
9623 -+ early_gdt_descr.address = get_cpu_gdt_table(cpu);
9624 -+
9625 -+#ifdef CONFIG_PAX_KERNEXEC
9626 -+ pax_close_kernel(cr0);
9627 -+#endif
9628 -+
9629 - irq_ctx_init(cpu);
9630 -
9631 - /* Note: Don't modify initial ss override */
9632 -@@ -1141,7 +1155,7 @@ void smp_local_timer_interrupt(void)
9633 - per_cpu(prof_counter, cpu);
9634 - }
9635 -
9636 -- update_process_times(user_mode_vm(get_irq_regs()));
9637 -+ update_process_times(user_mode(get_irq_regs()));
9638 - }
9639 -
9640 - if (((1 << cpu) & voyager_extended_vic_processors) == 0)
9641 -diff -urNp linux-2.6.27.6/arch/x86/Makefile linux-2.6.27.6/arch/x86/Makefile
9642 ---- linux-2.6.27.6/arch/x86/Makefile 2008-11-07 12:55:34.000000000 -0500
9643 -+++ linux-2.6.27.6/arch/x86/Makefile 2008-11-18 03:38:44.000000000 -0500
9644 -@@ -232,3 +232,12 @@ endef
9645 - CLEAN_FILES += arch/x86/boot/fdimage \
9646 - arch/x86/boot/image.iso \
9647 - arch/x86/boot/mtools.conf
9648 -+
9649 -+define OLD_LD
9650 -+
9651 -+*** ${VERSION}.${PATCHLEVEL} PaX kernels no longer build correctly with old versions of binutils.
9652 -+*** Please upgrade your binutils to 2.18 or newer
9653 -+endef
9654 -+
9655 -+archprepare:
9656 -+ $(if $(LDFLAGS_BUILD_ID),,$(error $(OLD_LD)))
9657 -diff -urNp linux-2.6.27.6/arch/x86/mm/discontig_32.c linux-2.6.27.6/arch/x86/mm/discontig_32.c
9658 ---- linux-2.6.27.6/arch/x86/mm/discontig_32.c 2008-11-07 12:55:34.000000000 -0500
9659 -+++ linux-2.6.27.6/arch/x86/mm/discontig_32.c 2008-11-18 03:38:44.000000000 -0500
9660 -@@ -98,7 +98,6 @@ unsigned long node_memmap_size_bytes(int
9661 - }
9662 - #endif
9663 -
9664 --extern unsigned long find_max_low_pfn(void);
9665 - extern unsigned long highend_pfn, highstart_pfn;
9666 -
9667 - #define LARGE_PAGE_BYTES (PTRS_PER_PTE * PAGE_SIZE)
9668 -diff -urNp linux-2.6.27.6/arch/x86/mm/extable.c linux-2.6.27.6/arch/x86/mm/extable.c
9669 ---- linux-2.6.27.6/arch/x86/mm/extable.c 2008-11-07 12:55:34.000000000 -0500
9670 -+++ linux-2.6.27.6/arch/x86/mm/extable.c 2008-11-18 03:38:44.000000000 -0500
9671 -@@ -1,14 +1,62 @@
9672 - #include <linux/module.h>
9673 - #include <linux/spinlock.h>
9674 -+#include <linux/sort.h>
9675 - #include <asm/uaccess.h>
9676 -
9677 -+/*
9678 -+ * The exception table needs to be sorted so that the binary
9679 -+ * search that we use to find entries in it works properly.
9680 -+ * This is used both for the kernel exception table and for
9681 -+ * the exception tables of modules that get loaded.
9682 -+ */
9683 -+static int cmp_ex(const void *a, const void *b)
9684 -+{
9685 -+ const struct exception_table_entry *x = a, *y = b;
9686 -+
9687 -+ /* avoid overflow */
9688 -+ if (x->insn > y->insn)
9689 -+ return 1;
9690 -+ if (x->insn < y->insn)
9691 -+ return -1;
9692 -+ return 0;
9693 -+}
9694 -+
9695 -+static void swap_ex(void *a, void *b, int size)
9696 -+{
9697 -+ struct exception_table_entry t, *x = a, *y = b;
9698 -+
9699 -+#ifdef CONFIG_PAX_KERNEXEC
9700 -+ unsigned long cr0;
9701 -+#endif
9702 -+
9703 -+ t = *x;
9704 -+
9705 -+#ifdef CONFIG_PAX_KERNEXEC
9706 -+ pax_open_kernel(cr0);
9707 -+#endif
9708 -+
9709 -+ *x = *y;
9710 -+ *y = t;
9711 -+
9712 -+#ifdef CONFIG_PAX_KERNEXEC
9713 -+ pax_close_kernel(cr0);
9714 -+#endif
9715 -+
9716 -+}
9717 -+
9718 -+void sort_extable(struct exception_table_entry *start,
9719 -+ struct exception_table_entry *finish)
9720 -+{
9721 -+ sort(start, finish - start, sizeof(struct exception_table_entry),
9722 -+ cmp_ex, swap_ex);
9723 -+}
9724 -
9725 - int fixup_exception(struct pt_regs *regs)
9726 - {
9727 - const struct exception_table_entry *fixup;
9728 -
9729 - #ifdef CONFIG_PNPBIOS
9730 -- if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) {
9731 -+ if (unlikely(!v8086_mode(regs) && SEGMENT_IS_PNP_CODE(regs->cs))) {
9732 - extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
9733 - extern u32 pnp_bios_is_utter_crap;
9734 - pnp_bios_is_utter_crap = 1;
9735 -diff -urNp linux-2.6.27.6/arch/x86/mm/fault.c linux-2.6.27.6/arch/x86/mm/fault.c
9736 ---- linux-2.6.27.6/arch/x86/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
9737 -+++ linux-2.6.27.6/arch/x86/mm/fault.c 2008-11-18 03:38:44.000000000 -0500
9738 -@@ -26,6 +26,8 @@
9739 - #include <linux/kprobes.h>
9740 - #include <linux/uaccess.h>
9741 - #include <linux/kdebug.h>
9742 -+#include <linux/unistd.h>
9743 -+#include <linux/compiler.h>
9744 -
9745 - #include <asm/system.h>
9746 - #include <asm/desc.h>
9747 -@@ -35,6 +37,7 @@
9748 - #include <asm/tlbflush.h>
9749 - #include <asm/proto.h>
9750 - #include <asm-generic/sections.h>
9751 -+#include <asm/tlbflush.h>
9752 -
9753 - /*
9754 - * Page fault error code bits
9755 -@@ -66,7 +69,7 @@ static inline int notify_page_fault(stru
9756 - int ret = 0;
9757 -
9758 - /* kprobe_running() needs smp_processor_id() */
9759 -- if (!user_mode_vm(regs)) {
9760 -+ if (!user_mode(regs)) {
9761 - preempt_disable();
9762 - if (kprobe_running() && kprobe_fault_handler(regs, 14))
9763 - ret = 1;
9764 -@@ -264,6 +267,30 @@ bad:
9765 - #endif
9766 - }
9767 -
9768 -+#ifdef CONFIG_PAX_EMUTRAMP
9769 -+static int pax_handle_fetch_fault(struct pt_regs *regs);
9770 -+#endif
9771 -+
9772 -+#ifdef CONFIG_PAX_PAGEEXEC
9773 -+static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
9774 -+{
9775 -+ pgd_t *pgd;
9776 -+ pud_t *pud;
9777 -+ pmd_t *pmd;
9778 -+
9779 -+ pgd = pgd_offset(mm, address);
9780 -+ if (!pgd_present(*pgd))
9781 -+ return NULL;
9782 -+ pud = pud_offset(pgd, address);
9783 -+ if (!pud_present(*pud))
9784 -+ return NULL;
9785 -+ pmd = pmd_offset(pud, address);
9786 -+ if (!pmd_present(*pmd))
9787 -+ return NULL;
9788 -+ return pmd;
9789 -+}
9790 -+#endif
9791 -+
9792 - #ifdef CONFIG_X86_32
9793 - static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
9794 - {
9795 -@@ -350,7 +377,7 @@ static int is_errata93(struct pt_regs *r
9796 - static int is_errata100(struct pt_regs *regs, unsigned long address)
9797 - {
9798 - #ifdef CONFIG_X86_64
9799 -- if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) &&
9800 -+ if ((regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT)) &&
9801 - (address >> 32))
9802 - return 1;
9803 - #endif
9804 -@@ -387,14 +414,31 @@ static void show_fault_oops(struct pt_re
9805 - #endif
9806 -
9807 - #ifdef CONFIG_X86_PAE
9808 -- if (error_code & PF_INSTR) {
9809 -+ if (nx_enabled && (error_code & PF_INSTR)) {
9810 - unsigned int level;
9811 - pte_t *pte = lookup_address(address, &level);
9812 -
9813 - if (pte && pte_present(*pte) && !pte_exec(*pte))
9814 - printk(KERN_CRIT "kernel tried to execute "
9815 - "NX-protected page - exploit attempt? "
9816 -- "(uid: %d)\n", current->uid);
9817 -+ "(uid: %d, task: %s, pid: %d)\n",
9818 -+ current->uid, current->comm, task_pid_nr(current));
9819 -+ }
9820 -+#endif
9821 -+
9822 -+#ifdef CONFIG_PAX_KERNEXEC
9823 -+#ifdef CONFIG_MODULES
9824 -+ if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
9825 -+#else
9826 -+ if (init_mm.start_code <= address && address < init_mm.end_code)
9827 -+#endif
9828 -+ {
9829 -+ if (current->signal->curr_ip)
9830 -+ printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
9831 -+ NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current->uid, current->euid);
9832 -+ else
9833 -+ printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
9834 -+ current->comm, task_pid_nr(current), current->uid, current->euid);
9835 - }
9836 - #endif
9837 -
9838 -@@ -586,13 +630,22 @@ void __kprobes do_page_fault(struct pt_r
9839 - struct task_struct *tsk;
9840 - struct mm_struct *mm;
9841 - struct vm_area_struct *vma;
9842 -- unsigned long address;
9843 - int write, si_code;
9844 - int fault;
9845 - #ifdef CONFIG_X86_64
9846 - unsigned long flags;
9847 - #endif
9848 -
9849 -+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
9850 -+ pte_t *pte;
9851 -+ pmd_t *pmd;
9852 -+ spinlock_t *ptl;
9853 -+ unsigned char pte_mask;
9854 -+#endif
9855 -+
9856 -+ /* get the address */
9857 -+ const unsigned long address = read_cr2();
9858 -+
9859 - /*
9860 - * We can fault from pretty much anywhere, with unknown IRQ state.
9861 - */
9862 -@@ -602,9 +655,6 @@ void __kprobes do_page_fault(struct pt_r
9863 - mm = tsk->mm;
9864 - prefetchw(&mm->mmap_sem);
9865 -
9866 -- /* get the address */
9867 -- address = read_cr2();
9868 --
9869 - si_code = SEGV_MAPERR;
9870 -
9871 - if (notify_page_fault(regs))
9872 -@@ -657,7 +707,7 @@ void __kprobes do_page_fault(struct pt_r
9873 - * atomic region then we must not take the fault.
9874 - */
9875 - if (in_atomic() || !mm)
9876 -- goto bad_area_nosemaphore;
9877 -+ goto bad_area_nopax;
9878 - #else /* CONFIG_X86_64 */
9879 - if (likely(regs->flags & X86_EFLAGS_IF))
9880 - local_irq_enable();
9881 -@@ -670,13 +720,13 @@ void __kprobes do_page_fault(struct pt_r
9882 - * atomic region then we must not take the fault.
9883 - */
9884 - if (unlikely(in_atomic() || !mm))
9885 -- goto bad_area_nosemaphore;
9886 -+ goto bad_area_nopax;
9887 -
9888 - /*
9889 - * User-mode registers count as a user access even for any
9890 - * potential system fault or CPU buglet.
9891 - */
9892 -- if (user_mode_vm(regs))
9893 -+ if (user_mode(regs))
9894 - error_code |= PF_USER;
9895 - again:
9896 - #endif
9897 -@@ -698,10 +748,104 @@ again:
9898 - if (!down_read_trylock(&mm->mmap_sem)) {
9899 - if ((error_code & PF_USER) == 0 &&
9900 - !search_exception_tables(regs->ip))
9901 -- goto bad_area_nosemaphore;
9902 -+ goto bad_area_nopax;
9903 - down_read(&mm->mmap_sem);
9904 - }
9905 -
9906 -+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
9907 -+ if (nx_enabled || (error_code & (PF_PROT|PF_USER)) != (PF_PROT|PF_USER) || v8086_mode(regs) ||
9908 -+ !(mm->pax_flags & MF_PAX_PAGEEXEC))
9909 -+ goto not_pax_fault;
9910 -+
9911 -+ /* PaX: it's our fault, let's handle it if we can */
9912 -+
9913 -+ /* PaX: take a look at read faults before acquiring any locks */
9914 -+ if (unlikely(!(error_code & PF_WRITE) && (regs->ip == address))) {
9915 -+ /* instruction fetch attempt from a protected page in user mode */
9916 -+ up_read(&mm->mmap_sem);
9917 -+
9918 -+#ifdef CONFIG_PAX_EMUTRAMP
9919 -+ switch (pax_handle_fetch_fault(regs)) {
9920 -+ case 2:
9921 -+ return;
9922 -+ }
9923 -+#endif
9924 -+
9925 -+ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
9926 -+ do_group_exit(SIGKILL);
9927 -+ }
9928 -+
9929 -+ pmd = pax_get_pmd(mm, address);
9930 -+ if (unlikely(!pmd))
9931 -+ goto not_pax_fault;
9932 -+
9933 -+ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
9934 -+ if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
9935 -+ pte_unmap_unlock(pte, ptl);
9936 -+ goto not_pax_fault;
9937 -+ }
9938 -+
9939 -+ if (unlikely((error_code & PF_WRITE) && !pte_write(*pte))) {
9940 -+ /* write attempt to a protected page in user mode */
9941 -+ pte_unmap_unlock(pte, ptl);
9942 -+ goto not_pax_fault;
9943 -+ }
9944 -+
9945 -+#ifdef CONFIG_SMP
9946 -+ if (likely(address > get_limit(regs->cs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
9947 -+#else
9948 -+ if (likely(address > get_limit(regs->cs)))
9949 -+#endif
9950 -+ {
9951 -+ set_pte(pte, pte_mkread(*pte));
9952 -+ __flush_tlb_one(address);
9953 -+ pte_unmap_unlock(pte, ptl);
9954 -+ up_read(&mm->mmap_sem);
9955 -+ return;
9956 -+ }
9957 -+
9958 -+ pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & PF_WRITE) << (_PAGE_BIT_DIRTY-1));
9959 -+
9960 -+ /*
9961 -+ * PaX: fill DTLB with user rights and retry
9962 -+ */
9963 -+ __asm__ __volatile__ (
9964 -+#ifdef CONFIG_PAX_MEMORY_UDEREF
9965 -+ "movw %w4,%%es\n"
9966 -+#endif
9967 -+ "orb %2,(%1)\n"
9968 -+#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
9969 -+/*
9970 -+ * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
9971 -+ * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
9972 -+ * page fault when examined during a TLB load attempt. this is true not only
9973 -+ * for PTEs holding a non-present entry but also present entries that will
9974 -+ * raise a page fault (such as those set up by PaX, or the copy-on-write
9975 -+ * mechanism). in effect it means that we do *not* need to flush the TLBs
9976 -+ * for our target pages since their PTEs are simply not in the TLBs at all.
9977 -+
9978 -+ * the best thing in omitting it is that we gain around 15-20% speed in the
9979 -+ * fast path of the page fault handler and can get rid of tracing since we
9980 -+ * can no longer flush unintended entries.
9981 -+ */
9982 -+ "invlpg (%0)\n"
9983 -+#endif
9984 -+ "testb $0,%%es:(%0)\n"
9985 -+ "xorb %3,(%1)\n"
9986 -+#ifdef CONFIG_PAX_MEMORY_UDEREF
9987 -+ "pushl %%ss\n"
9988 -+ "popl %%es\n"
9989 -+#endif
9990 -+ :
9991 -+ : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
9992 -+ : "memory", "cc");
9993 -+ pte_unmap_unlock(pte, ptl);
9994 -+ up_read(&mm->mmap_sem);
9995 -+ return;
9996 -+
9997 -+not_pax_fault:
9998 -+#endif
9999 -+
10000 - vma = find_vma(mm, address);
10001 - if (!vma)
10002 - goto bad_area;
10003 -@@ -719,6 +863,12 @@ again:
10004 - if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp)
10005 - goto bad_area;
10006 - }
10007 -+
10008 -+#ifdef CONFIG_PAX_SEGMEXEC
10009 -+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)
10010 -+ goto bad_area;
10011 -+#endif
10012 -+
10013 - if (expand_stack(vma, address))
10014 - goto bad_area;
10015 - /*
10016 -@@ -728,6 +878,8 @@ again:
10017 - good_area:
10018 - si_code = SEGV_ACCERR;
10019 - write = 0;
10020 -+ if (nx_enabled && (error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
10021 -+ goto bad_area;
10022 - switch (error_code & (PF_PROT|PF_WRITE)) {
10023 - default: /* 3: write, present */
10024 - /* fall through */
10025 -@@ -785,6 +937,54 @@ bad_area:
10026 - up_read(&mm->mmap_sem);
10027 -
10028 - bad_area_nosemaphore:
10029 -+
10030 -+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10031 -+ if (mm && (error_code & PF_USER)) {
10032 -+ unsigned long ip = regs->ip;
10033 -+
10034 -+ if (v8086_mode(regs))
10035 -+ ip = ((regs->cs & 0xffff) << 4) + (regs->ip & 0xffff);
10036 -+
10037 -+ /*
10038 -+ * It's possible to have interrupts off here.
10039 -+ */
10040 -+ local_irq_enable();
10041 -+
10042 -+#ifdef CONFIG_PAX_PAGEEXEC
10043 -+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) &&
10044 -+ ((nx_enabled && (error_code & PF_INSTR)) || (!(error_code & (PF_PROT | PF_WRITE)) && regs->ip == address))) {
10045 -+
10046 -+#ifdef CONFIG_PAX_EMUTRAMP
10047 -+ switch (pax_handle_fetch_fault(regs)) {
10048 -+ case 2:
10049 -+ return;
10050 -+ }
10051 -+#endif
10052 -+
10053 -+ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
10054 -+ do_group_exit(SIGKILL);
10055 -+ }
10056 -+#endif
10057 -+
10058 -+#ifdef CONFIG_PAX_SEGMEXEC
10059 -+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & (PF_PROT | PF_WRITE)) && (regs->ip + SEGMEXEC_TASK_SIZE == address)) {
10060 -+
10061 -+#ifdef CONFIG_PAX_EMUTRAMP
10062 -+ switch (pax_handle_fetch_fault(regs)) {
10063 -+ case 2:
10064 -+ return;
10065 -+ }
10066 -+#endif
10067 -+
10068 -+ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
10069 -+ do_group_exit(SIGKILL);
10070 -+ }
10071 -+#endif
10072 -+
10073 -+ }
10074 -+#endif
10075 -+
10076 -+bad_area_nopax:
10077 - /* User mode accesses just cause a SIGSEGV */
10078 - if (error_code & PF_USER) {
10079 - /*
10080 -@@ -863,7 +1063,7 @@ no_context:
10081 - #ifdef CONFIG_X86_32
10082 - die("Oops", regs, error_code);
10083 - bust_spinlocks(0);
10084 -- do_exit(SIGKILL);
10085 -+ do_group_exit(SIGKILL);
10086 - #else
10087 - if (__die("Oops", regs, error_code))
10088 - regs = NULL;
10089 -@@ -877,17 +1077,17 @@ no_context:
10090 - * us unable to handle the page fault gracefully.
10091 - */
10092 - out_of_memory:
10093 -- up_read(&mm->mmap_sem);
10094 - if (is_global_init(tsk)) {
10095 - yield();
10096 - #ifdef CONFIG_X86_32
10097 -- down_read(&mm->mmap_sem);
10098 - goto survive;
10099 - #else
10100 -+ up_read(&mm->mmap_sem);
10101 - goto again;
10102 - #endif
10103 - }
10104 -
10105 -+ up_read(&mm->mmap_sem);
10106 - printk("VM: killing process %s\n", tsk->comm);
10107 - if (error_code & PF_USER)
10108 - do_group_exit(SIGKILL);
10109 -@@ -959,3 +1159,174 @@ void vmalloc_sync_all(void)
10110 - }
10111 - #endif
10112 - }
10113 -+
10114 -+#ifdef CONFIG_PAX_EMUTRAMP
10115 -+static int pax_handle_fetch_fault_32(struct pt_regs *regs)
10116 -+{
10117 -+ int err;
10118 -+
10119 -+ do { /* PaX: gcc trampoline emulation #1 */
10120 -+ unsigned char mov1, mov2;
10121 -+ unsigned short jmp;
10122 -+ unsigned int addr1, addr2;
10123 -+
10124 -+#ifdef CONFIG_X86_64
10125 -+ if ((regs->ip + 11) >> 32)
10126 -+ break;
10127 -+#endif
10128 -+
10129 -+ err = get_user(mov1, (unsigned char __user *)regs->ip);
10130 -+ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
10131 -+ err |= get_user(mov2, (unsigned char __user *)(regs->ip + 5));
10132 -+ err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
10133 -+ err |= get_user(jmp, (unsigned short __user *)(regs->ip + 10));
10134 -+
10135 -+ if (err)
10136 -+ break;
10137 -+
10138 -+ if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
10139 -+ regs->cx = addr1;
10140 -+ regs->ax = addr2;
10141 -+ regs->ip = addr2;
10142 -+ return 2;
10143 -+ }
10144 -+ } while (0);
10145 -+
10146 -+ do { /* PaX: gcc trampoline emulation #2 */
10147 -+ unsigned char mov, jmp;
10148 -+ unsigned int addr1, addr2;
10149 -+
10150 -+#ifdef CONFIG_X86_64
10151 -+ if ((regs->ip + 9) >> 32)
10152 -+ break;
10153 -+#endif
10154 -+
10155 -+ err = get_user(mov, (unsigned char __user *)regs->ip);
10156 -+ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
10157 -+ err |= get_user(jmp, (unsigned char __user *)(regs->ip + 5));
10158 -+ err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
10159 -+
10160 -+ if (err)
10161 -+ break;
10162 -+
10163 -+ if (mov == 0xB9 && jmp == 0xE9) {
10164 -+ regs->cx = addr1;
10165 -+ regs->ip = (unsigned int)(regs->ip + addr2 + 10);
10166 -+ return 2;
10167 -+ }
10168 -+ } while (0);
10169 -+
10170 -+ return 1; /* PaX in action */
10171 -+}
10172 -+
10173 -+#ifdef CONFIG_X86_64
10174 -+static int pax_handle_fetch_fault_64(struct pt_regs *regs)
10175 -+{
10176 -+ int err;
10177 -+
10178 -+ do { /* PaX: gcc trampoline emulation #1 */
10179 -+ unsigned short mov1, mov2, jmp1;
10180 -+ unsigned char jmp2;
10181 -+ unsigned int addr1;
10182 -+ unsigned long addr2;
10183 -+
10184 -+ err = get_user(mov1, (unsigned short __user *)regs->ip);
10185 -+ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 2));
10186 -+ err |= get_user(mov2, (unsigned short __user *)(regs->ip + 6));
10187 -+ err |= get_user(addr2, (unsigned long __user *)(regs->ip + 8));
10188 -+ err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 16));
10189 -+ err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 18));
10190 -+
10191 -+ if (err)
10192 -+ break;
10193 -+
10194 -+ if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
10195 -+ regs->r11 = addr1;
10196 -+ regs->r10 = addr2;
10197 -+ regs->ip = addr1;
10198 -+ return 2;
10199 -+ }
10200 -+ } while (0);
10201 -+
10202 -+ do { /* PaX: gcc trampoline emulation #2 */
10203 -+ unsigned short mov1, mov2, jmp1;
10204 -+ unsigned char jmp2;
10205 -+ unsigned long addr1, addr2;
10206 -+
10207 -+ err = get_user(mov1, (unsigned short __user *)regs->ip);
10208 -+ err |= get_user(addr1, (unsigned long __user *)(regs->ip + 2));
10209 -+ err |= get_user(mov2, (unsigned short __user *)(regs->ip + 10));
10210 -+ err |= get_user(addr2, (unsigned long __user *)(regs->ip + 12));
10211 -+ err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 20));
10212 -+ err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 22));
10213 -+
10214 -+ if (err)
10215 -+ break;
10216 -+
10217 -+ if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
10218 -+ regs->r11 = addr1;
10219 -+ regs->r10 = addr2;
10220 -+ regs->ip = addr1;
10221 -+ return 2;
10222 -+ }
10223 -+ } while (0);
10224 -+
10225 -+ return 1; /* PaX in action */
10226 -+}
10227 -+#endif
10228 -+
10229 -+/*
10230 -+ * PaX: decide what to do with offenders (regs->ip = fault address)
10231 -+ *
10232 -+ * returns 1 when task should be killed
10233 -+ * 2 when gcc trampoline was detected
10234 -+ */
10235 -+static int pax_handle_fetch_fault(struct pt_regs *regs)
10236 -+{
10237 -+ if (v8086_mode(regs))
10238 -+ return 1;
10239 -+
10240 -+ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
10241 -+ return 1;
10242 -+
10243 -+#ifdef CONFIG_X86_32
10244 -+ return pax_handle_fetch_fault_32(regs);
10245 -+#else
10246 -+ if (regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT))
10247 -+ return pax_handle_fetch_fault_32(regs);
10248 -+ else
10249 -+ return pax_handle_fetch_fault_64(regs);
10250 -+#endif
10251 -+}
10252 -+#endif
10253 -+
10254 -+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10255 -+void pax_report_insns(void *pc, void *sp)
10256 -+{
10257 -+ long i;
10258 -+
10259 -+ printk(KERN_ERR "PAX: bytes at PC: ");
10260 -+ for (i = 0; i < 20; i++) {
10261 -+ unsigned char c;
10262 -+ if (get_user(c, (unsigned char __user *)pc+i))
10263 -+ printk(KERN_CONT "?? ");
10264 -+ else
10265 -+ printk(KERN_CONT "%02x ", c);
10266 -+ }
10267 -+ printk("\n");
10268 -+
10269 -+ printk(KERN_ERR "PAX: bytes at SP-%lu: ", (unsigned long)sizeof(long));
10270 -+ for (i = -1; i < 80 / sizeof(long); i++) {
10271 -+ unsigned long c;
10272 -+ if (get_user(c, (unsigned long __user *)sp+i))
10273 -+#ifdef CONFIG_X86_32
10274 -+ printk(KERN_CONT "???????? ");
10275 -+#else
10276 -+ printk(KERN_CONT "???????????????? ");
10277 -+#endif
10278 -+ else
10279 -+ printk(KERN_CONT "%0*lx ", 2 * (int)sizeof(long), c);
10280 -+ }
10281 -+ printk("\n");
10282 -+}
10283 -+#endif
10284 -diff -urNp linux-2.6.27.6/arch/x86/mm/highmem_32.c linux-2.6.27.6/arch/x86/mm/highmem_32.c
10285 ---- linux-2.6.27.6/arch/x86/mm/highmem_32.c 2008-11-07 12:55:34.000000000 -0500
10286 -+++ linux-2.6.27.6/arch/x86/mm/highmem_32.c 2008-11-18 03:38:44.000000000 -0500
10287 -@@ -74,6 +74,10 @@ void *kmap_atomic_prot(struct page *page
10288 - enum fixed_addresses idx;
10289 - unsigned long vaddr;
10290 -
10291 -+#ifdef CONFIG_PAX_KERNEXEC
10292 -+ unsigned long cr0;
10293 -+#endif
10294 -+
10295 - /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
10296 - pagefault_disable();
10297 -
10298 -@@ -85,7 +89,17 @@ void *kmap_atomic_prot(struct page *page
10299 - idx = type + KM_TYPE_NR*smp_processor_id();
10300 - vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
10301 - BUG_ON(!pte_none(*(kmap_pte-idx)));
10302 -+
10303 -+#ifdef CONFIG_PAX_KERNEXEC
10304 -+ pax_open_kernel(cr0);
10305 -+#endif
10306 -+
10307 - set_pte(kmap_pte-idx, mk_pte(page, prot));
10308 -+
10309 -+#ifdef CONFIG_PAX_KERNEXEC
10310 -+ pax_close_kernel(cr0);
10311 -+#endif
10312 -+
10313 - arch_flush_lazy_mmu_mode();
10314 -
10315 - return (void *)vaddr;
10316 -@@ -101,15 +115,29 @@ void kunmap_atomic(void *kvaddr, enum km
10317 - unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
10318 - enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
10319 -
10320 -+#ifdef CONFIG_PAX_KERNEXEC
10321 -+ unsigned long cr0;
10322 -+#endif
10323 -+
10324 - /*
10325 - * Force other mappings to Oops if they'll try to access this pte
10326 - * without first remap it. Keeping stale mappings around is a bad idea
10327 - * also, in case the page changes cacheability attributes or becomes
10328 - * a protected page in a hypervisor.
10329 - */
10330 -- if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx))
10331 -+ if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) {
10332 -+
10333 -+#ifdef CONFIG_PAX_KERNEXEC
10334 -+ pax_open_kernel(cr0);
10335 -+#endif
10336 -+
10337 - kpte_clear_flush(kmap_pte-idx, vaddr);
10338 -- else {
10339 -+
10340 -+#ifdef CONFIG_PAX_KERNEXEC
10341 -+ pax_close_kernel(cr0);
10342 -+#endif
10343 -+
10344 -+ } else {
10345 - #ifdef CONFIG_DEBUG_HIGHMEM
10346 - BUG_ON(vaddr < PAGE_OFFSET);
10347 - BUG_ON(vaddr >= (unsigned long)high_memory);
10348 -@@ -128,11 +156,25 @@ void *kmap_atomic_pfn(unsigned long pfn,
10349 - enum fixed_addresses idx;
10350 - unsigned long vaddr;
10351 -
10352 -+#ifdef CONFIG_PAX_KERNEXEC
10353 -+ unsigned long cr0;
10354 -+#endif
10355 -+
10356 - pagefault_disable();
10357 -
10358 - idx = type + KM_TYPE_NR*smp_processor_id();
10359 - vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
10360 -+
10361 -+#ifdef CONFIG_PAX_KERNEXEC
10362 -+ pax_open_kernel(cr0);
10363 -+#endif
10364 -+
10365 - set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
10366 -+
10367 -+#ifdef CONFIG_PAX_KERNEXEC
10368 -+ pax_close_kernel(cr0);
10369 -+#endif
10370 -+
10371 - arch_flush_lazy_mmu_mode();
10372 -
10373 - return (void*) vaddr;
10374 -diff -urNp linux-2.6.27.6/arch/x86/mm/hugetlbpage.c linux-2.6.27.6/arch/x86/mm/hugetlbpage.c
10375 ---- linux-2.6.27.6/arch/x86/mm/hugetlbpage.c 2008-11-07 12:55:34.000000000 -0500
10376 -+++ linux-2.6.27.6/arch/x86/mm/hugetlbpage.c 2008-11-18 03:38:44.000000000 -0500
10377 -@@ -263,13 +263,18 @@ static unsigned long hugetlb_get_unmappe
10378 - struct hstate *h = hstate_file(file);
10379 - struct mm_struct *mm = current->mm;
10380 - struct vm_area_struct *vma;
10381 -- unsigned long start_addr;
10382 -+ unsigned long start_addr, pax_task_size = TASK_SIZE;
10383 -+
10384 -+#ifdef CONFIG_PAX_SEGMEXEC
10385 -+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
10386 -+ pax_task_size = SEGMEXEC_TASK_SIZE;
10387 -+#endif
10388 -
10389 - if (len > mm->cached_hole_size) {
10390 -- start_addr = mm->free_area_cache;
10391 -+ start_addr = mm->free_area_cache;
10392 - } else {
10393 -- start_addr = TASK_UNMAPPED_BASE;
10394 -- mm->cached_hole_size = 0;
10395 -+ start_addr = mm->mmap_base;
10396 -+ mm->cached_hole_size = 0;
10397 - }
10398 -
10399 - full_search:
10400 -@@ -277,13 +282,13 @@ full_search:
10401 -
10402 - for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
10403 - /* At this point: (!vma || addr < vma->vm_end). */
10404 -- if (TASK_SIZE - len < addr) {
10405 -+ if (pax_task_size - len < addr) {
10406 - /*
10407 - * Start a new search - just in case we missed
10408 - * some holes.
10409 - */
10410 -- if (start_addr != TASK_UNMAPPED_BASE) {
10411 -- start_addr = TASK_UNMAPPED_BASE;
10412 -+ if (start_addr != mm->mmap_base) {
10413 -+ start_addr = mm->mmap_base;
10414 - mm->cached_hole_size = 0;
10415 - goto full_search;
10416 - }
10417 -@@ -306,9 +311,8 @@ static unsigned long hugetlb_get_unmappe
10418 - struct hstate *h = hstate_file(file);
10419 - struct mm_struct *mm = current->mm;
10420 - struct vm_area_struct *vma, *prev_vma;
10421 -- unsigned long base = mm->mmap_base, addr = addr0;
10422 -+ unsigned long base = mm->mmap_base, addr;
10423 - unsigned long largest_hole = mm->cached_hole_size;
10424 -- int first_time = 1;
10425 -
10426 - /* don't allow allocations above current base */
10427 - if (mm->free_area_cache > base)
10428 -@@ -318,7 +322,7 @@ static unsigned long hugetlb_get_unmappe
10429 - largest_hole = 0;
10430 - mm->free_area_cache = base;
10431 - }
10432 --try_again:
10433 -+
10434 - /* make sure it can fit in the remaining address space */
10435 - if (mm->free_area_cache < len)
10436 - goto fail;
10437 -@@ -360,22 +364,26 @@ try_again:
10438 -
10439 - fail:
10440 - /*
10441 -- * if hint left us with no space for the requested
10442 -- * mapping then try again:
10443 -- */
10444 -- if (first_time) {
10445 -- mm->free_area_cache = base;
10446 -- largest_hole = 0;
10447 -- first_time = 0;
10448 -- goto try_again;
10449 -- }
10450 -- /*
10451 - * A failed mmap() very likely causes application failure,
10452 - * so fall back to the bottom-up function here. This scenario
10453 - * can happen with large stack limits and large mmap()
10454 - * allocations.
10455 - */
10456 -- mm->free_area_cache = TASK_UNMAPPED_BASE;
10457 -+
10458 -+#ifdef CONFIG_PAX_SEGMEXEC
10459 -+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
10460 -+ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
10461 -+ else
10462 -+#endif
10463 -+
10464 -+ mm->mmap_base = TASK_UNMAPPED_BASE;
10465 -+
10466 -+#ifdef CONFIG_PAX_RANDMMAP
10467 -+ if (mm->pax_flags & MF_PAX_RANDMMAP)
10468 -+ mm->mmap_base += mm->delta_mmap;
10469 -+#endif
10470 -+
10471 -+ mm->free_area_cache = mm->mmap_base;
10472 - mm->cached_hole_size = ~0UL;
10473 - addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
10474 - len, pgoff, flags);
10475 -@@ -383,6 +391,7 @@ fail:
10476 - /*
10477 - * Restore the topdown base:
10478 - */
10479 -+ mm->mmap_base = base;
10480 - mm->free_area_cache = base;
10481 - mm->cached_hole_size = ~0UL;
10482 -
10483 -@@ -396,10 +405,17 @@ hugetlb_get_unmapped_area(struct file *f
10484 - struct hstate *h = hstate_file(file);
10485 - struct mm_struct *mm = current->mm;
10486 - struct vm_area_struct *vma;
10487 -+ unsigned long pax_task_size = TASK_SIZE;
10488 -
10489 - if (len & ~huge_page_mask(h))
10490 - return -EINVAL;
10491 -- if (len > TASK_SIZE)
10492 -+
10493 -+#ifdef CONFIG_PAX_SEGMEXEC
10494 -+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
10495 -+ pax_task_size = SEGMEXEC_TASK_SIZE;
10496 -+#endif
10497 -+
10498 -+ if (len > pax_task_size)
10499 - return -ENOMEM;
10500 -
10501 - if (flags & MAP_FIXED) {
10502 -@@ -411,7 +427,7 @@ hugetlb_get_unmapped_area(struct file *f
10503 - if (addr) {
10504 - addr = ALIGN(addr, huge_page_size(h));
10505 - vma = find_vma(mm, addr);
10506 -- if (TASK_SIZE - len >= addr &&
10507 -+ if (pax_task_size - len >= addr &&
10508 - (!vma || addr + len <= vma->vm_start))
10509 - return addr;
10510 - }
10511 -diff -urNp linux-2.6.27.6/arch/x86/mm/init_32.c linux-2.6.27.6/arch/x86/mm/init_32.c
10512 ---- linux-2.6.27.6/arch/x86/mm/init_32.c 2008-11-07 12:55:34.000000000 -0500
10513 -+++ linux-2.6.27.6/arch/x86/mm/init_32.c 2008-11-18 03:38:44.000000000 -0500
10514 -@@ -47,6 +47,7 @@
10515 - #include <asm/paravirt.h>
10516 - #include <asm/setup.h>
10517 - #include <asm/cacheflush.h>
10518 -+#include <asm/desc.h>
10519 -
10520 - unsigned int __VMALLOC_RESERVE = 128 << 20;
10521 -
10522 -@@ -80,35 +81,6 @@ static __init void *alloc_low_page(unsig
10523 - }
10524 -
10525 - /*
10526 -- * Creates a middle page table and puts a pointer to it in the
10527 -- * given global directory entry. This only returns the gd entry
10528 -- * in non-PAE compilation mode, since the middle layer is folded.
10529 -- */
10530 --static pmd_t * __init one_md_table_init(pgd_t *pgd)
10531 --{
10532 -- pud_t *pud;
10533 -- pmd_t *pmd_table;
10534 --
10535 --#ifdef CONFIG_X86_PAE
10536 -- unsigned long phys;
10537 -- if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
10538 -- if (after_init_bootmem)
10539 -- pmd_table = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
10540 -- else
10541 -- pmd_table = (pmd_t *)alloc_low_page(&phys);
10542 -- paravirt_alloc_pmd(&init_mm, __pa(pmd_table) >> PAGE_SHIFT);
10543 -- set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
10544 -- pud = pud_offset(pgd, 0);
10545 -- BUG_ON(pmd_table != pmd_offset(pud, 0));
10546 -- }
10547 --#endif
10548 -- pud = pud_offset(pgd, 0);
10549 -- pmd_table = pmd_offset(pud, 0);
10550 --
10551 -- return pmd_table;
10552 --}
10553 --
10554 --/*
10555 - * Create a page table and place a pointer to it in a middle page
10556 - * directory entry:
10557 - */
10558 -@@ -130,7 +102,11 @@ static pte_t * __init one_page_table_ini
10559 - }
10560 -
10561 - paravirt_alloc_pte(&init_mm, __pa(page_table) >> PAGE_SHIFT);
10562 -+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10563 -+ set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
10564 -+#else
10565 - set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
10566 -+#endif
10567 - BUG_ON(page_table != pte_offset_kernel(pmd, 0));
10568 - }
10569 -
10570 -@@ -152,6 +128,7 @@ page_table_range_init(unsigned long star
10571 - int pgd_idx, pmd_idx;
10572 - unsigned long vaddr;
10573 - pgd_t *pgd;
10574 -+ pud_t *pud;
10575 - pmd_t *pmd;
10576 -
10577 - vaddr = start;
10578 -@@ -160,8 +137,13 @@ page_table_range_init(unsigned long star
10579 - pgd = pgd_base + pgd_idx;
10580 -
10581 - for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
10582 -- pmd = one_md_table_init(pgd);
10583 -- pmd = pmd + pmd_index(vaddr);
10584 -+ pud = pud_offset(pgd, vaddr);
10585 -+ pmd = pmd_offset(pud, vaddr);
10586 -+
10587 -+#ifdef CONFIG_X86_PAE
10588 -+ paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
10589 -+#endif
10590 -+
10591 - for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end);
10592 - pmd++, pmd_idx++) {
10593 - one_page_table_init(pmd);
10594 -@@ -172,11 +154,23 @@ page_table_range_init(unsigned long star
10595 - }
10596 - }
10597 -
10598 --static inline int is_kernel_text(unsigned long addr)
10599 -+static inline int is_kernel_text(unsigned long start, unsigned long end)
10600 - {
10601 -- if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
10602 -- return 1;
10603 -- return 0;
10604 -+ unsigned long etext;
10605 -+
10606 -+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
10607 -+ etext = ktva_ktla((unsigned long)&MODULES_END);
10608 -+#else
10609 -+ etext = (unsigned long)&_etext;
10610 -+#endif
10611 -+
10612 -+ if ((start > ktla_ktva(etext) ||
10613 -+ end <= ktla_ktva((unsigned long)_stext)) &&
10614 -+ (start > ktla_ktva((unsigned long)_einittext) ||
10615 -+ end <= ktla_ktva((unsigned long)_sinittext)) &&
10616 -+ (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000)))
10617 -+ return 0;
10618 -+ return 1;
10619 - }
10620 -
10621 - /*
10622 -@@ -189,9 +183,10 @@ static void __init kernel_physical_mappi
10623 - unsigned long end_pfn,
10624 - int use_pse)
10625 - {
10626 -- int pgd_idx, pmd_idx, pte_ofs;
10627 -+ unsigned int pgd_idx, pmd_idx, pte_ofs;
10628 - unsigned long pfn;
10629 - pgd_t *pgd;
10630 -+ pud_t *pud;
10631 - pmd_t *pmd;
10632 - pte_t *pte;
10633 - unsigned pages_2m = 0, pages_4k = 0;
10634 -@@ -202,8 +197,13 @@ static void __init kernel_physical_mappi
10635 - pfn = start_pfn;
10636 - pgd_idx = pgd_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET);
10637 - pgd = pgd_base + pgd_idx;
10638 -- for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
10639 -- pmd = one_md_table_init(pgd);
10640 -+ for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
10641 -+ pud = pud_offset(pgd, 0);
10642 -+ pmd = pmd_offset(pud, 0);
10643 -+
10644 -+#ifdef CONFIG_X86_PAE
10645 -+ paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
10646 -+#endif
10647 -
10648 - if (pfn >= end_pfn)
10649 - continue;
10650 -@@ -215,21 +215,16 @@ static void __init kernel_physical_mappi
10651 - #endif
10652 - for (; pmd_idx < PTRS_PER_PMD && pfn < end_pfn;
10653 - pmd++, pmd_idx++) {
10654 -- unsigned int addr = pfn * PAGE_SIZE + PAGE_OFFSET;
10655 -+ unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
10656 -
10657 - /*
10658 - * Map with big pages if possible, otherwise
10659 - * create normal page tables:
10660 - */
10661 - if (use_pse) {
10662 -- unsigned int addr2;
10663 - pgprot_t prot = PAGE_KERNEL_LARGE;
10664 -
10665 -- addr2 = (pfn + PTRS_PER_PTE-1) * PAGE_SIZE +
10666 -- PAGE_OFFSET + PAGE_SIZE-1;
10667 --
10668 -- if (is_kernel_text(addr) ||
10669 -- is_kernel_text(addr2))
10670 -+ if (is_kernel_text(address, address + PMD_SIZE))
10671 - prot = PAGE_KERNEL_LARGE_EXEC;
10672 -
10673 - pages_2m++;
10674 -@@ -243,10 +238,10 @@ static void __init kernel_physical_mappi
10675 - pte_ofs = pte_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET);
10676 - pte += pte_ofs;
10677 - for (; pte_ofs < PTRS_PER_PTE && pfn < end_pfn;
10678 -- pte++, pfn++, pte_ofs++, addr += PAGE_SIZE) {
10679 -+ pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
10680 - pgprot_t prot = PAGE_KERNEL;
10681 -
10682 -- if (is_kernel_text(addr))
10683 -+ if (is_kernel_text(address, address + PAGE_SIZE))
10684 - prot = PAGE_KERNEL_EXEC;
10685 -
10686 - pages_4k++;
10687 -@@ -270,7 +265,9 @@ static void __init kernel_physical_mappi
10688 - */
10689 - int devmem_is_allowed(unsigned long pagenr)
10690 - {
10691 -- if (pagenr <= 256)
10692 -+ if (!pagenr)
10693 -+ return 1;
10694 -+ if ((ISA_START_ADDRESS >> PAGE_SHIFT) <= pagenr && pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
10695 - return 1;
10696 - if (!page_is_ram(pagenr))
10697 - return 1;
10698 -@@ -404,7 +401,7 @@ void __init native_pagetable_setup_start
10699 -
10700 - pud = pud_offset(pgd, va);
10701 - pmd = pmd_offset(pud, va);
10702 -- if (!pmd_present(*pmd))
10703 -+ if (!pmd_present(*pmd) || pmd_huge(*pmd))
10704 - break;
10705 -
10706 - pte = pte_offset_kernel(pmd, va);
10707 -@@ -456,9 +453,7 @@ static void __init early_ioremap_page_ta
10708 -
10709 - static void __init pagetable_init(void)
10710 - {
10711 -- pgd_t *pgd_base = swapper_pg_dir;
10712 --
10713 -- permanent_kmaps_init(pgd_base);
10714 -+ permanent_kmaps_init(swapper_pg_dir);
10715 - }
10716 -
10717 - #ifdef CONFIG_ACPI_SLEEP
10718 -@@ -466,12 +461,12 @@ static void __init pagetable_init(void)
10719 - * ACPI suspend needs this for resume, because things like the intel-agp
10720 - * driver might have split up a kernel 4MB mapping.
10721 - */
10722 --char swsusp_pg_dir[PAGE_SIZE]
10723 -+pgd_t swsusp_pg_dir[PTRS_PER_PGD]
10724 - __attribute__ ((aligned(PAGE_SIZE)));
10725 -
10726 - static inline void save_pg_dir(void)
10727 - {
10728 -- memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
10729 -+ clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD);
10730 - }
10731 - #else /* !CONFIG_ACPI_SLEEP */
10732 - static inline void save_pg_dir(void)
10733 -@@ -501,13 +496,11 @@ void zap_low_mappings(void)
10734 -
10735 - int nx_enabled;
10736 -
10737 --pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL);
10738 -+pteval_t __supported_pte_mask __read_only = ~(_PAGE_NX | _PAGE_GLOBAL);
10739 - EXPORT_SYMBOL_GPL(__supported_pte_mask);
10740 -
10741 - #ifdef CONFIG_X86_PAE
10742 -
10743 --static int disable_nx __initdata;
10744 --
10745 - /*
10746 - * noexec = on|off
10747 - *
10748 -@@ -516,40 +509,33 @@ static int disable_nx __initdata;
10749 - * on Enable
10750 - * off Disable
10751 - */
10752 -+#if !defined(CONFIG_PAX_PAGEEXEC)
10753 - static int __init noexec_setup(char *str)
10754 - {
10755 - if (!str || !strcmp(str, "on")) {
10756 -- if (cpu_has_nx) {
10757 -- __supported_pte_mask |= _PAGE_NX;
10758 -- disable_nx = 0;
10759 -- }
10760 -+ if (cpu_has_nx)
10761 -+ nx_enabled = 1;
10762 - } else {
10763 -- if (!strcmp(str, "off")) {
10764 -- disable_nx = 1;
10765 -- __supported_pte_mask &= ~_PAGE_NX;
10766 -- } else {
10767 -+ if (!strcmp(str, "off"))
10768 -+ nx_enabled = 0;
10769 -+ else
10770 - return -EINVAL;
10771 -- }
10772 - }
10773 -
10774 - return 0;
10775 - }
10776 - early_param("noexec", noexec_setup);
10777 -+#endif
10778 -
10779 - static void __init set_nx(void)
10780 - {
10781 -- unsigned int v[4], l, h;
10782 --
10783 -- if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
10784 -- cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
10785 -+ if (!nx_enabled && cpu_has_nx) {
10786 -+ unsigned l, h;
10787 -
10788 -- if ((v[3] & (1 << 20)) && !disable_nx) {
10789 -- rdmsr(MSR_EFER, l, h);
10790 -- l |= EFER_NX;
10791 -- wrmsr(MSR_EFER, l, h);
10792 -- nx_enabled = 1;
10793 -- __supported_pte_mask |= _PAGE_NX;
10794 -- }
10795 -+ __supported_pte_mask &= ~_PAGE_NX;
10796 -+ rdmsr(MSR_EFER, l, h);
10797 -+ l &= ~EFER_NX;
10798 -+ wrmsr(MSR_EFER, l, h);
10799 - }
10800 - }
10801 - #endif
10802 -@@ -920,7 +906,7 @@ void __init mem_init(void)
10803 - set_highmem_pages_init();
10804 -
10805 - codesize = (unsigned long) &_etext - (unsigned long) &_text;
10806 -- datasize = (unsigned long) &_edata - (unsigned long) &_etext;
10807 -+ datasize = (unsigned long) &_edata - (unsigned long) &_data;
10808 - initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
10809 -
10810 - kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
10811 -@@ -966,10 +952,10 @@ void __init mem_init(void)
10812 - ((unsigned long)&__init_end -
10813 - (unsigned long)&__init_begin) >> 10,
10814 -
10815 -- (unsigned long)&_etext, (unsigned long)&_edata,
10816 -- ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
10817 -+ (unsigned long)&_data, (unsigned long)&_edata,
10818 -+ ((unsigned long)&_edata - (unsigned long)&_data) >> 10,
10819 -
10820 -- (unsigned long)&_text, (unsigned long)&_etext,
10821 -+ ktla_ktva((unsigned long)&_text), ktla_ktva((unsigned long)&_etext),
10822 - ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
10823 -
10824 - #ifdef CONFIG_HIGHMEM
10825 -@@ -1099,6 +1085,46 @@ void free_init_pages(char *what, unsigne
10826 -
10827 - void free_initmem(void)
10828 - {
10829 -+
10830 -+#ifdef CONFIG_PAX_KERNEXEC
10831 -+ /* PaX: limit KERNEL_CS to actual size */
10832 -+ unsigned long addr, limit;
10833 -+ struct desc_struct d;
10834 -+ int cpu;
10835 -+ pgd_t *pgd;
10836 -+ pud_t *pud;
10837 -+ pmd_t *pmd;
10838 -+
10839 -+#ifdef CONFIG_MODULES
10840 -+ limit = ktva_ktla((unsigned long)&MODULES_END);
10841 -+#else
10842 -+ limit = (unsigned long)&_etext;
10843 -+#endif
10844 -+ limit = (limit - 1UL) >> PAGE_SHIFT;
10845 -+
10846 -+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
10847 -+ pack_descriptor(&d, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC);
10848 -+ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, &d, DESCTYPE_S);
10849 -+ }
10850 -+
10851 -+ /* PaX: make KERNEL_CS read-only */
10852 -+ for (addr = ktla_ktva((unsigned long)&_text); addr < (unsigned long)&_data; addr += PMD_SIZE) {
10853 -+ pgd = pgd_offset_k(addr);
10854 -+ pud = pud_offset(pgd, addr);
10855 -+ pmd = pmd_offset(pud, addr);
10856 -+ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
10857 -+ }
10858 -+#ifdef CONFIG_X86_PAE
10859 -+ for (addr = (unsigned long)&__init_begin; addr < (unsigned long)&__init_end; addr += PMD_SIZE) {
10860 -+ pgd = pgd_offset_k(addr);
10861 -+ pud = pud_offset(pgd, addr);
10862 -+ pmd = pmd_offset(pud, addr);
10863 -+ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
10864 -+ }
10865 -+#endif
10866 -+ flush_tlb_all();
10867 -+#endif
10868 -+
10869 - free_init_pages("unused kernel memory",
10870 - (unsigned long)(&__init_begin),
10871 - (unsigned long)(&__init_end));
10872 -diff -urNp linux-2.6.27.6/arch/x86/mm/init_64.c linux-2.6.27.6/arch/x86/mm/init_64.c
10873 ---- linux-2.6.27.6/arch/x86/mm/init_64.c 2008-11-07 12:55:34.000000000 -0500
10874 -+++ linux-2.6.27.6/arch/x86/mm/init_64.c 2008-11-18 03:38:44.000000000 -0500
10875 -@@ -118,6 +118,10 @@ set_pte_vaddr_pud(pud_t *pud_page, unsig
10876 - pmd_t *pmd;
10877 - pte_t *pte;
10878 -
10879 -+#ifdef CONFIG_PAX_KERNEXEC
10880 -+ unsigned long cr0;
10881 -+#endif
10882 -+
10883 - pud = pud_page + pud_index(vaddr);
10884 - if (pud_none(*pud)) {
10885 - pmd = (pmd_t *) spp_getpage();
10886 -@@ -142,8 +146,17 @@ set_pte_vaddr_pud(pud_t *pud_page, unsig
10887 - if (!pte_none(*pte) && pte_val(new_pte) &&
10888 - pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask))
10889 - pte_ERROR(*pte);
10890 -+
10891 -+#ifdef CONFIG_PAX_KERNEXEC
10892 -+ pax_open_kernel(cr0);
10893 -+#endif
10894 -+
10895 - set_pte(pte, new_pte);
10896 -
10897 -+#ifdef CONFIG_PAX_KERNEXEC
10898 -+ pax_close_kernel(cr0);
10899 -+#endif
10900 -+
10901 - /*
10902 - * It's enough to flush this one mapping.
10903 - * (PGE mappings get flushed as well)
10904 -@@ -184,14 +197,12 @@ static void __init __init_extra_mapping(
10905 - pgd = pgd_offset_k((unsigned long)__va(phys));
10906 - if (pgd_none(*pgd)) {
10907 - pud = (pud_t *) spp_getpage();
10908 -- set_pgd(pgd, __pgd(__pa(pud) | _KERNPG_TABLE |
10909 -- _PAGE_USER));
10910 -+ set_pgd(pgd, __pgd(__pa(pud) | _PAGE_TABLE));
10911 - }
10912 - pud = pud_offset(pgd, (unsigned long)__va(phys));
10913 - if (pud_none(*pud)) {
10914 - pmd = (pmd_t *) spp_getpage();
10915 -- set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE |
10916 -- _PAGE_USER));
10917 -+ set_pud(pud, __pud(__pa(pmd) | _PAGE_TABLE));
10918 - }
10919 - pmd = pmd_offset(pud, phys);
10920 - BUG_ON(!pmd_none(*pmd));
10921 -@@ -754,7 +765,9 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to
10922 - */
10923 - int devmem_is_allowed(unsigned long pagenr)
10924 - {
10925 -- if (pagenr <= 256)
10926 -+ if (!pagenr)
10927 -+ return 1;
10928 -+ if ((ISA_START_ADDRESS >> PAGE_SHIFT) <= pagenr && pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
10929 - return 1;
10930 - if (!page_is_ram(pagenr))
10931 - return 1;
10932 -@@ -842,6 +855,39 @@ void free_init_pages(char *what, unsigne
10933 -
10934 - void free_initmem(void)
10935 - {
10936 -+
10937 -+#ifdef CONFIG_PAX_KERNEXEC
10938 -+ unsigned long addr, end;
10939 -+ pgd_t *pgd;
10940 -+ pud_t *pud;
10941 -+ pmd_t *pmd;
10942 -+
10943 -+ /* PaX: make kernel code/rodata read-only, rest non-executable */
10944 -+ for (addr = __START_KERNEL_map; addr < __START_KERNEL_map + KERNEL_IMAGE_SIZE; addr += PMD_SIZE) {
10945 -+ pgd = pgd_offset_k(addr);
10946 -+ pud = pud_offset(pgd, addr);
10947 -+ pmd = pmd_offset(pud, addr);
10948 -+ if ((unsigned long)_text <= addr && addr < (unsigned long)_data)
10949 -+ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
10950 -+ else
10951 -+ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
10952 -+ }
10953 -+
10954 -+ addr = (unsigned long)__va(__pa(__START_KERNEL_map));
10955 -+ end = addr + KERNEL_IMAGE_SIZE;
10956 -+ for (; addr < end; addr += PMD_SIZE) {
10957 -+ pgd = pgd_offset_k(addr);
10958 -+ pud = pud_offset(pgd, addr);
10959 -+ pmd = pmd_offset(pud, addr);
10960 -+ if ((unsigned long)__va(__pa(_text)) <= addr && addr < (unsigned long)__va(__pa(_data)))
10961 -+ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
10962 -+ else
10963 -+ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
10964 -+ }
10965 -+
10966 -+ flush_tlb_all();
10967 -+#endif
10968 -+
10969 - free_init_pages("unused kernel memory",
10970 - (unsigned long)(&__init_begin),
10971 - (unsigned long)(&__init_end));
10972 -@@ -1014,7 +1060,7 @@ int in_gate_area_no_task(unsigned long a
10973 -
10974 - const char *arch_vma_name(struct vm_area_struct *vma)
10975 - {
10976 -- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
10977 -+ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
10978 - return "[vdso]";
10979 - if (vma == &gate_vma)
10980 - return "[vsyscall]";
10981 -diff -urNp linux-2.6.27.6/arch/x86/mm/ioremap.c linux-2.6.27.6/arch/x86/mm/ioremap.c
10982 ---- linux-2.6.27.6/arch/x86/mm/ioremap.c 2008-11-07 12:55:34.000000000 -0500
10983 -+++ linux-2.6.27.6/arch/x86/mm/ioremap.c 2008-11-18 03:38:44.000000000 -0500
10984 -@@ -63,8 +63,8 @@ int page_is_ram(unsigned long pagenr)
10985 - * Second special case: Some BIOSen report the PC BIOS
10986 - * area (640->1Mb) as ram even though it is not.
10987 - */
10988 -- if (pagenr >= (BIOS_BEGIN >> PAGE_SHIFT) &&
10989 -- pagenr < (BIOS_END >> PAGE_SHIFT))
10990 -+ if (pagenr >= (ISA_START_ADDRESS >> PAGE_SHIFT) &&
10991 -+ pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
10992 - return 0;
10993 -
10994 - for (i = 0; i < e820.nr_map; i++) {
10995 -@@ -217,6 +217,8 @@ static void __iomem *__ioremap_caller(re
10996 - break;
10997 - }
10998 -
10999 -+ prot = canon_pgprot(prot);
11000 -+
11001 - /*
11002 - * Ok, go for it..
11003 - */
11004 -diff -urNp linux-2.6.27.6/arch/x86/mm/mmap.c linux-2.6.27.6/arch/x86/mm/mmap.c
11005 ---- linux-2.6.27.6/arch/x86/mm/mmap.c 2008-11-07 12:55:34.000000000 -0500
11006 -+++ linux-2.6.27.6/arch/x86/mm/mmap.c 2008-11-18 03:38:44.000000000 -0500
11007 -@@ -36,7 +36,7 @@
11008 - * Leave an at least ~128 MB hole.
11009 - */
11010 - #define MIN_GAP (128*1024*1024)
11011 --#define MAX_GAP (TASK_SIZE/6*5)
11012 -+#define MAX_GAP (pax_task_size/6*5)
11013 -
11014 - /*
11015 - * True on X86_32 or when emulating IA32 on X86_64
11016 -@@ -81,27 +81,40 @@ static unsigned long mmap_rnd(void)
11017 - return rnd << PAGE_SHIFT;
11018 - }
11019 -
11020 --static unsigned long mmap_base(void)
11021 -+static unsigned long mmap_base(struct mm_struct *mm)
11022 - {
11023 - unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
11024 -+ unsigned long pax_task_size = TASK_SIZE;
11025 -+
11026 -+#ifdef CONFIG_PAX_SEGMEXEC
11027 -+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
11028 -+ pax_task_size = SEGMEXEC_TASK_SIZE;
11029 -+#endif
11030 -
11031 - if (gap < MIN_GAP)
11032 - gap = MIN_GAP;
11033 - else if (gap > MAX_GAP)
11034 - gap = MAX_GAP;
11035 -
11036 -- return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
11037 -+ return PAGE_ALIGN(pax_task_size - gap - mmap_rnd());
11038 - }
11039 -
11040 - /*
11041 - * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64
11042 - * does, but not when emulating X86_32
11043 - */
11044 --static unsigned long mmap_legacy_base(void)
11045 -+static unsigned long mmap_legacy_base(struct mm_struct *mm)
11046 - {
11047 -- if (mmap_is_ia32())
11048 -+ if (mmap_is_ia32()) {
11049 -+
11050 -+#ifdef CONFIG_PAX_SEGMEXEC
11051 -+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
11052 -+ return SEGMEXEC_TASK_UNMAPPED_BASE;
11053 -+ else
11054 -+#endif
11055 -+
11056 - return TASK_UNMAPPED_BASE;
11057 -- else
11058 -+ } else
11059 - return TASK_UNMAPPED_BASE + mmap_rnd();
11060 - }
11061 -
11062 -@@ -112,11 +125,23 @@ static unsigned long mmap_legacy_base(vo
11063 - void arch_pick_mmap_layout(struct mm_struct *mm)
11064 - {
11065 - if (mmap_is_legacy()) {
11066 -- mm->mmap_base = mmap_legacy_base();
11067 -+ mm->mmap_base = mmap_legacy_base(mm);
11068 -+
11069 -+#ifdef CONFIG_PAX_RANDMMAP
11070 -+ if (mm->pax_flags & MF_PAX_RANDMMAP)
11071 -+ mm->mmap_base += mm->delta_mmap;
11072 -+#endif
11073 -+
11074 - mm->get_unmapped_area = arch_get_unmapped_area;
11075 - mm->unmap_area = arch_unmap_area;
11076 - } else {
11077 -- mm->mmap_base = mmap_base();
11078 -+ mm->mmap_base = mmap_base(mm);
11079 -+
11080 -+#ifdef CONFIG_PAX_RANDMMAP
11081 -+ if (mm->pax_flags & MF_PAX_RANDMMAP)
11082 -+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
11083 -+#endif
11084 -+
11085 - mm->get_unmapped_area = arch_get_unmapped_area_topdown;
11086 - mm->unmap_area = arch_unmap_area_topdown;
11087 - }
11088 -diff -urNp linux-2.6.27.6/arch/x86/mm/pageattr.c linux-2.6.27.6/arch/x86/mm/pageattr.c
11089 ---- linux-2.6.27.6/arch/x86/mm/pageattr.c 2008-11-07 12:55:34.000000000 -0500
11090 -+++ linux-2.6.27.6/arch/x86/mm/pageattr.c 2008-11-18 03:38:44.000000000 -0500
11091 -@@ -20,6 +20,7 @@
11092 - #include <asm/pgalloc.h>
11093 - #include <asm/proto.h>
11094 - #include <asm/pat.h>
11095 -+#include <asm/desc.h>
11096 -
11097 - /*
11098 - * The current flushing context - we pass it instead of 5 arguments:
11099 -@@ -213,7 +214,7 @@ static inline pgprot_t static_protection
11100 - * Does not cover __inittext since that is gone later on. On
11101 - * 64bit we do not enforce !NX on the low mapping
11102 - */
11103 -- if (within(address, (unsigned long)_text, (unsigned long)_etext))
11104 -+ if (within(address, ktla_ktva((unsigned long)_text), ktla_ktva((unsigned long)_etext)))
11105 - pgprot_val(forbidden) |= _PAGE_NX;
11106 -
11107 - /*
11108 -@@ -275,8 +276,20 @@ EXPORT_SYMBOL_GPL(lookup_address);
11109 - */
11110 - static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
11111 - {
11112 -+
11113 -+#ifdef CONFIG_PAX_KERNEXEC
11114 -+ unsigned long cr0;
11115 -+
11116 -+ pax_open_kernel(cr0);
11117 -+#endif
11118 -+
11119 - /* change init_mm */
11120 - set_pte_atomic(kpte, pte);
11121 -+
11122 -+#ifdef CONFIG_PAX_KERNEXEC
11123 -+ pax_close_kernel(cr0);
11124 -+#endif
11125 -+
11126 - #ifdef CONFIG_X86_32
11127 - if (!SHARED_KERNEL_PMD) {
11128 - struct page *page;
11129 -diff -urNp linux-2.6.27.6/arch/x86/mm/pat.c linux-2.6.27.6/arch/x86/mm/pat.c
11130 ---- linux-2.6.27.6/arch/x86/mm/pat.c 2008-11-07 12:55:34.000000000 -0500
11131 -+++ linux-2.6.27.6/arch/x86/mm/pat.c 2008-11-18 03:38:44.000000000 -0500
11132 -@@ -396,7 +396,7 @@ pgprot_t phys_mem_access_prot(struct fil
11133 - return vma_prot;
11134 - }
11135 -
11136 --#ifdef CONFIG_STRICT_DEVMEM
11137 -+#ifndef CONFIG_STRICT_DEVMEM
11138 - /* This check is done in drivers/char/mem.c in case of STRICT_DEVMEM*/
11139 - static inline int range_is_allowed(unsigned long pfn, unsigned long size)
11140 - {
11141 -diff -urNp linux-2.6.27.6/arch/x86/mm/pgtable_32.c linux-2.6.27.6/arch/x86/mm/pgtable_32.c
11142 ---- linux-2.6.27.6/arch/x86/mm/pgtable_32.c 2008-11-07 12:55:34.000000000 -0500
11143 -+++ linux-2.6.27.6/arch/x86/mm/pgtable_32.c 2008-11-18 03:38:44.000000000 -0500
11144 -@@ -31,6 +31,10 @@ void set_pte_vaddr(unsigned long vaddr,
11145 - pmd_t *pmd;
11146 - pte_t *pte;
11147 -
11148 -+#ifdef CONFIG_PAX_KERNEXEC
11149 -+ unsigned long cr0;
11150 -+#endif
11151 -+
11152 - pgd = swapper_pg_dir + pgd_index(vaddr);
11153 - if (pgd_none(*pgd)) {
11154 - BUG();
11155 -@@ -47,11 +51,20 @@ void set_pte_vaddr(unsigned long vaddr,
11156 - return;
11157 - }
11158 - pte = pte_offset_kernel(pmd, vaddr);
11159 -+
11160 -+#ifdef CONFIG_PAX_KERNEXEC
11161 -+ pax_open_kernel(cr0);
11162 -+#endif
11163 -+
11164 - if (pte_val(pteval))
11165 - set_pte_present(&init_mm, vaddr, pte, pteval);
11166 - else
11167 - pte_clear(&init_mm, vaddr, pte);
11168 -
11169 -+#ifdef CONFIG_PAX_KERNEXEC
11170 -+ pax_close_kernel(cr0);
11171 -+#endif
11172 -+
11173 - /*
11174 - * It's enough to flush this one mapping.
11175 - * (PGE mappings get flushed as well)
11176 -diff -urNp linux-2.6.27.6/arch/x86/oprofile/backtrace.c linux-2.6.27.6/arch/x86/oprofile/backtrace.c
11177 ---- linux-2.6.27.6/arch/x86/oprofile/backtrace.c 2008-11-07 12:55:34.000000000 -0500
11178 -+++ linux-2.6.27.6/arch/x86/oprofile/backtrace.c 2008-11-18 03:38:44.000000000 -0500
11179 -@@ -37,7 +37,7 @@ static void backtrace_address(void *data
11180 - unsigned int *depth = data;
11181 -
11182 - if ((*depth)--)
11183 -- oprofile_add_trace(addr);
11184 -+ oprofile_add_trace(ktla_ktva(addr));
11185 - }
11186 -
11187 - static struct stacktrace_ops backtrace_ops = {
11188 -@@ -79,7 +79,7 @@ x86_backtrace(struct pt_regs * const reg
11189 - struct frame_head *head = (struct frame_head *)frame_pointer(regs);
11190 - unsigned long stack = kernel_trap_sp(regs);
11191 -
11192 -- if (!user_mode_vm(regs)) {
11193 -+ if (!user_mode(regs)) {
11194 - if (depth)
11195 - dump_trace(NULL, regs, (unsigned long *)stack, 0,
11196 - &backtrace_ops, &depth);
11197 -diff -urNp linux-2.6.27.6/arch/x86/oprofile/op_model_p4.c linux-2.6.27.6/arch/x86/oprofile/op_model_p4.c
11198 ---- linux-2.6.27.6/arch/x86/oprofile/op_model_p4.c 2008-11-07 12:55:34.000000000 -0500
11199 -+++ linux-2.6.27.6/arch/x86/oprofile/op_model_p4.c 2008-11-18 03:38:44.000000000 -0500
11200 -@@ -47,7 +47,7 @@ static inline void setup_num_counters(vo
11201 - #endif
11202 - }
11203 -
11204 --static int inline addr_increment(void)
11205 -+static inline int addr_increment(void)
11206 - {
11207 - #ifdef CONFIG_SMP
11208 - return smp_num_siblings == 2 ? 2 : 1;
11209 -diff -urNp linux-2.6.27.6/arch/x86/pci/common.c linux-2.6.27.6/arch/x86/pci/common.c
11210 ---- linux-2.6.27.6/arch/x86/pci/common.c 2008-11-07 12:55:34.000000000 -0500
11211 -+++ linux-2.6.27.6/arch/x86/pci/common.c 2008-11-18 03:38:44.000000000 -0500
11212 -@@ -362,7 +362,7 @@ static struct dmi_system_id __devinitdat
11213 - DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"),
11214 - },
11215 - },
11216 -- {}
11217 -+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
11218 - };
11219 -
11220 - void __init dmi_check_pciprobe(void)
11221 -diff -urNp linux-2.6.27.6/arch/x86/pci/fixup.c linux-2.6.27.6/arch/x86/pci/fixup.c
11222 ---- linux-2.6.27.6/arch/x86/pci/fixup.c 2008-11-07 12:55:34.000000000 -0500
11223 -+++ linux-2.6.27.6/arch/x86/pci/fixup.c 2008-11-18 03:38:44.000000000 -0500
11224 -@@ -365,7 +365,7 @@ static struct dmi_system_id __devinitdat
11225 - DMI_MATCH(DMI_PRODUCT_NAME, "MS-6702E"),
11226 - },
11227 - },
11228 -- {}
11229 -+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11230 - };
11231 -
11232 - /*
11233 -@@ -436,7 +436,7 @@ static struct dmi_system_id __devinitdat
11234 - DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
11235 - },
11236 - },
11237 -- { }
11238 -+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11239 - };
11240 -
11241 - static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
11242 -diff -urNp linux-2.6.27.6/arch/x86/pci/irq.c linux-2.6.27.6/arch/x86/pci/irq.c
11243 ---- linux-2.6.27.6/arch/x86/pci/irq.c 2008-11-07 12:55:34.000000000 -0500
11244 -+++ linux-2.6.27.6/arch/x86/pci/irq.c 2008-11-18 03:38:44.000000000 -0500
11245 -@@ -544,7 +544,7 @@ static __init int intel_router_probe(str
11246 - static struct pci_device_id __initdata pirq_440gx[] = {
11247 - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
11248 - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
11249 -- { },
11250 -+ { PCI_DEVICE(0, 0) }
11251 - };
11252 -
11253 - /* 440GX has a proprietary PIRQ router -- don't use it */
11254 -@@ -1131,7 +1131,7 @@ static struct dmi_system_id __initdata p
11255 - DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
11256 - },
11257 - },
11258 -- { }
11259 -+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11260 - };
11261 -
11262 - int __init pcibios_irq_init(void)
11263 -diff -urNp linux-2.6.27.6/arch/x86/pci/pcbios.c linux-2.6.27.6/arch/x86/pci/pcbios.c
11264 ---- linux-2.6.27.6/arch/x86/pci/pcbios.c 2008-11-07 12:55:34.000000000 -0500
11265 -+++ linux-2.6.27.6/arch/x86/pci/pcbios.c 2008-11-18 03:38:44.000000000 -0500
11266 -@@ -57,50 +57,120 @@ union bios32 {
11267 - static struct {
11268 - unsigned long address;
11269 - unsigned short segment;
11270 --} bios32_indirect = { 0, __KERNEL_CS };
11271 -+} bios32_indirect __read_only = { 0, __PCIBIOS_CS };
11272 -
11273 - /*
11274 - * Returns the entry point for the given service, NULL on error
11275 - */
11276 -
11277 --static unsigned long bios32_service(unsigned long service)
11278 -+static unsigned long __devinit bios32_service(unsigned long service)
11279 - {
11280 - unsigned char return_code; /* %al */
11281 - unsigned long address; /* %ebx */
11282 - unsigned long length; /* %ecx */
11283 - unsigned long entry; /* %edx */
11284 - unsigned long flags;
11285 -+ struct desc_struct d, *gdt;
11286 -+
11287 -+#ifdef CONFIG_PAX_KERNEXEC
11288 -+ unsigned long cr0;
11289 -+#endif
11290 -
11291 - local_irq_save(flags);
11292 -- __asm__("lcall *(%%edi); cld"
11293 -+
11294 -+ gdt = get_cpu_gdt_table(smp_processor_id());
11295 -+
11296 -+#ifdef CONFIG_PAX_KERNEXEC
11297 -+ pax_open_kernel(cr0);
11298 -+#endif
11299 -+
11300 -+ pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x9B, 0xC);
11301 -+ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
11302 -+ pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x93, 0xC);
11303 -+ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
11304 -+
11305 -+#ifdef CONFIG_PAX_KERNEXEC
11306 -+ pax_close_kernel(cr0);
11307 -+#endif
11308 -+
11309 -+ __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld"
11310 - : "=a" (return_code),
11311 - "=b" (address),
11312 - "=c" (length),
11313 - "=d" (entry)
11314 - : "0" (service),
11315 - "1" (0),
11316 -- "D" (&bios32_indirect));
11317 -+ "D" (&bios32_indirect),
11318 -+ "r"(__PCIBIOS_DS)
11319 -+ : "memory");
11320 -+
11321 -+#ifdef CONFIG_PAX_KERNEXEC
11322 -+ pax_open_kernel(cr0);
11323 -+#endif
11324 -+
11325 -+ gdt[GDT_ENTRY_PCIBIOS_CS].a = 0;
11326 -+ gdt[GDT_ENTRY_PCIBIOS_CS].b = 0;
11327 -+ gdt[GDT_ENTRY_PCIBIOS_DS].a = 0;
11328 -+ gdt[GDT_ENTRY_PCIBIOS_DS].b = 0;
11329 -+
11330 -+#ifdef CONFIG_PAX_KERNEXEC
11331 -+ pax_close_kernel(cr0);
11332 -+#endif
11333 -+
11334 - local_irq_restore(flags);
11335 -
11336 - switch (return_code) {
11337 -- case 0:
11338 -- return address + entry;
11339 -- case 0x80: /* Not present */
11340 -- printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
11341 -- return 0;
11342 -- default: /* Shouldn't happen */
11343 -- printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
11344 -- service, return_code);
11345 -+ case 0: {
11346 -+ int cpu;
11347 -+ unsigned char flags;
11348 -+
11349 -+ printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry);
11350 -+ if (address >= 0xFFFF0 || length > 0x100000 - address || length <= entry) {
11351 -+ printk(KERN_WARNING "bios32_service: not valid\n");
11352 - return 0;
11353 -+ }
11354 -+ address = address + PAGE_OFFSET;
11355 -+ length += 16UL; /* some BIOSs underreport this... */
11356 -+ flags = 4;
11357 -+ if (length >= 64*1024*1024) {
11358 -+ length >>= PAGE_SHIFT;
11359 -+ flags |= 8;
11360 -+ }
11361 -+
11362 -+#ifdef CONFIG_PAX_KERNEXEC
11363 -+ pax_open_kernel(cr0);
11364 -+#endif
11365 -+
11366 -+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
11367 -+ gdt = get_cpu_gdt_table(cpu);
11368 -+ pack_descriptor(&d, address, length, 0x9b, flags);
11369 -+ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
11370 -+ pack_descriptor(&d, address, length, 0x93, flags);
11371 -+ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
11372 -+ }
11373 -+
11374 -+#ifdef CONFIG_PAX_KERNEXEC
11375 -+ pax_close_kernel(cr0);
11376 -+#endif
11377 -+
11378 -+ return entry;
11379 -+ }
11380 -+ case 0x80: /* Not present */
11381 -+ printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
11382 -+ return 0;
11383 -+ default: /* Shouldn't happen */
11384 -+ printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
11385 -+ service, return_code);
11386 -+ return 0;
11387 - }
11388 - }
11389 -
11390 - static struct {
11391 - unsigned long address;
11392 - unsigned short segment;
11393 --} pci_indirect = { 0, __KERNEL_CS };
11394 -+} pci_indirect __read_only = { 0, __PCIBIOS_CS };
11395 -
11396 --static int pci_bios_present;
11397 -+static int pci_bios_present __read_only;
11398 -
11399 - static int __devinit check_pcibios(void)
11400 - {
11401 -@@ -109,11 +179,13 @@ static int __devinit check_pcibios(void)
11402 - unsigned long flags, pcibios_entry;
11403 -
11404 - if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
11405 -- pci_indirect.address = pcibios_entry + PAGE_OFFSET;
11406 -+ pci_indirect.address = pcibios_entry;
11407 -
11408 - local_irq_save(flags);
11409 -- __asm__(
11410 -- "lcall *(%%edi); cld\n\t"
11411 -+ __asm__("movw %w6, %%ds\n\t"
11412 -+ "lcall *%%ss:(%%edi); cld\n\t"
11413 -+ "push %%ss\n\t"
11414 -+ "pop %%ds\n\t"
11415 - "jc 1f\n\t"
11416 - "xor %%ah, %%ah\n"
11417 - "1:"
11418 -@@ -122,7 +194,8 @@ static int __devinit check_pcibios(void)
11419 - "=b" (ebx),
11420 - "=c" (ecx)
11421 - : "1" (PCIBIOS_PCI_BIOS_PRESENT),
11422 -- "D" (&pci_indirect)
11423 -+ "D" (&pci_indirect),
11424 -+ "r" (__PCIBIOS_DS)
11425 - : "memory");
11426 - local_irq_restore(flags);
11427 -
11428 -@@ -166,7 +239,10 @@ static int pci_bios_read(unsigned int se
11429 -
11430 - switch (len) {
11431 - case 1:
11432 -- __asm__("lcall *(%%esi); cld\n\t"
11433 -+ __asm__("movw %w6, %%ds\n\t"
11434 -+ "lcall *%%ss:(%%esi); cld\n\t"
11435 -+ "push %%ss\n\t"
11436 -+ "pop %%ds\n\t"
11437 - "jc 1f\n\t"
11438 - "xor %%ah, %%ah\n"
11439 - "1:"
11440 -@@ -175,7 +251,8 @@ static int pci_bios_read(unsigned int se
11441 - : "1" (PCIBIOS_READ_CONFIG_BYTE),
11442 - "b" (bx),
11443 - "D" ((long)reg),
11444 -- "S" (&pci_indirect));
11445 -+ "S" (&pci_indirect),
11446 -+ "r" (__PCIBIOS_DS));
11447 - /*
11448 - * Zero-extend the result beyond 8 bits, do not trust the
11449 - * BIOS having done it:
11450 -@@ -183,7 +260,10 @@ static int pci_bios_read(unsigned int se
11451 - *value &= 0xff;
11452 - break;
11453 - case 2:
11454 -- __asm__("lcall *(%%esi); cld\n\t"
11455 -+ __asm__("movw %w6, %%ds\n\t"
11456 -+ "lcall *%%ss:(%%esi); cld\n\t"
11457 -+ "push %%ss\n\t"
11458 -+ "pop %%ds\n\t"
11459 - "jc 1f\n\t"
11460 - "xor %%ah, %%ah\n"
11461 - "1:"
11462 -@@ -192,7 +272,8 @@ static int pci_bios_read(unsigned int se
11463 - : "1" (PCIBIOS_READ_CONFIG_WORD),
11464 - "b" (bx),
11465 - "D" ((long)reg),
11466 -- "S" (&pci_indirect));
11467 -+ "S" (&pci_indirect),
11468 -+ "r" (__PCIBIOS_DS));
11469 - /*
11470 - * Zero-extend the result beyond 16 bits, do not trust the
11471 - * BIOS having done it:
11472 -@@ -200,7 +281,10 @@ static int pci_bios_read(unsigned int se
11473 - *value &= 0xffff;
11474 - break;
11475 - case 4:
11476 -- __asm__("lcall *(%%esi); cld\n\t"
11477 -+ __asm__("movw %w6, %%ds\n\t"
11478 -+ "lcall *%%ss:(%%esi); cld\n\t"
11479 -+ "push %%ss\n\t"
11480 -+ "pop %%ds\n\t"
11481 - "jc 1f\n\t"
11482 - "xor %%ah, %%ah\n"
11483 - "1:"
11484 -@@ -209,7 +293,8 @@ static int pci_bios_read(unsigned int se
11485 - : "1" (PCIBIOS_READ_CONFIG_DWORD),
11486 - "b" (bx),
11487 - "D" ((long)reg),
11488 -- "S" (&pci_indirect));
11489 -+ "S" (&pci_indirect),
11490 -+ "r" (__PCIBIOS_DS));
11491 - break;
11492 - }
11493 -
11494 -@@ -232,7 +317,10 @@ static int pci_bios_write(unsigned int s
11495 -
11496 - switch (len) {
11497 - case 1:
11498 -- __asm__("lcall *(%%esi); cld\n\t"
11499 -+ __asm__("movw %w6, %%ds\n\t"
11500 -+ "lcall *%%ss:(%%esi); cld\n\t"
11501 -+ "push %%ss\n\t"
11502 -+ "pop %%ds\n\t"
11503 - "jc 1f\n\t"
11504 - "xor %%ah, %%ah\n"
11505 - "1:"
11506 -@@ -241,10 +329,14 @@ static int pci_bios_write(unsigned int s
11507 - "c" (value),
11508 - "b" (bx),
11509 - "D" ((long)reg),
11510 -- "S" (&pci_indirect));
11511 -+ "S" (&pci_indirect),
11512 -+ "r" (__PCIBIOS_DS));
11513 - break;
11514 - case 2:
11515 -- __asm__("lcall *(%%esi); cld\n\t"
11516 -+ __asm__("movw %w6, %%ds\n\t"
11517 -+ "lcall *%%ss:(%%esi); cld\n\t"
11518 -+ "push %%ss\n\t"
11519 -+ "pop %%ds\n\t"
11520 - "jc 1f\n\t"
11521 - "xor %%ah, %%ah\n"
11522 - "1:"
11523 -@@ -253,10 +345,14 @@ static int pci_bios_write(unsigned int s
11524 - "c" (value),
11525 - "b" (bx),
11526 - "D" ((long)reg),
11527 -- "S" (&pci_indirect));
11528 -+ "S" (&pci_indirect),
11529 -+ "r" (__PCIBIOS_DS));
11530 - break;
11531 - case 4:
11532 -- __asm__("lcall *(%%esi); cld\n\t"
11533 -+ __asm__("movw %w6, %%ds\n\t"
11534 -+ "lcall *%%ss:(%%esi); cld\n\t"
11535 -+ "push %%ss\n\t"
11536 -+ "pop %%ds\n\t"
11537 - "jc 1f\n\t"
11538 - "xor %%ah, %%ah\n"
11539 - "1:"
11540 -@@ -265,7 +361,8 @@ static int pci_bios_write(unsigned int s
11541 - "c" (value),
11542 - "b" (bx),
11543 - "D" ((long)reg),
11544 -- "S" (&pci_indirect));
11545 -+ "S" (&pci_indirect),
11546 -+ "r" (__PCIBIOS_DS));
11547 - break;
11548 - }
11549 -
11550 -@@ -369,10 +466,13 @@ struct irq_routing_table * pcibios_get_i
11551 -
11552 - DBG("PCI: Fetching IRQ routing table... ");
11553 - __asm__("push %%es\n\t"
11554 -+ "movw %w8, %%ds\n\t"
11555 - "push %%ds\n\t"
11556 - "pop %%es\n\t"
11557 -- "lcall *(%%esi); cld\n\t"
11558 -+ "lcall *%%ss:(%%esi); cld\n\t"
11559 - "pop %%es\n\t"
11560 -+ "push %%ss\n\t"
11561 -+ "pop %%ds\n"
11562 - "jc 1f\n\t"
11563 - "xor %%ah, %%ah\n"
11564 - "1:"
11565 -@@ -383,7 +483,8 @@ struct irq_routing_table * pcibios_get_i
11566 - "1" (0),
11567 - "D" ((long) &opt),
11568 - "S" (&pci_indirect),
11569 -- "m" (opt)
11570 -+ "m" (opt),
11571 -+ "r" (__PCIBIOS_DS)
11572 - : "memory");
11573 - DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map);
11574 - if (ret & 0xff00)
11575 -@@ -407,7 +508,10 @@ int pcibios_set_irq_routing(struct pci_d
11576 - {
11577 - int ret;
11578 -
11579 -- __asm__("lcall *(%%esi); cld\n\t"
11580 -+ __asm__("movw %w5, %%ds\n\t"
11581 -+ "lcall *%%ss:(%%esi); cld\n\t"
11582 -+ "push %%ss\n\t"
11583 -+ "pop %%ds\n"
11584 - "jc 1f\n\t"
11585 - "xor %%ah, %%ah\n"
11586 - "1:"
11587 -@@ -415,7 +519,8 @@ int pcibios_set_irq_routing(struct pci_d
11588 - : "0" (PCIBIOS_SET_PCI_HW_INT),
11589 - "b" ((dev->bus->number << 8) | dev->devfn),
11590 - "c" ((irq << 8) | (pin + 10)),
11591 -- "S" (&pci_indirect));
11592 -+ "S" (&pci_indirect),
11593 -+ "r" (__PCIBIOS_DS));
11594 - return !(ret & 0xff00);
11595 - }
11596 - EXPORT_SYMBOL(pcibios_set_irq_routing);
11597 -diff -urNp linux-2.6.27.6/arch/x86/power/cpu_32.c linux-2.6.27.6/arch/x86/power/cpu_32.c
11598 ---- linux-2.6.27.6/arch/x86/power/cpu_32.c 2008-11-07 12:55:34.000000000 -0500
11599 -+++ linux-2.6.27.6/arch/x86/power/cpu_32.c 2008-11-18 03:38:44.000000000 -0500
11600 -@@ -66,7 +66,7 @@ static void do_fpu_end(void)
11601 - static void fix_processor_context(void)
11602 - {
11603 - int cpu = smp_processor_id();
11604 -- struct tss_struct *t = &per_cpu(init_tss, cpu);
11605 -+ struct tss_struct *t = init_tss + cpu;
11606 -
11607 - set_tss_desc(cpu, t); /*
11608 - * This just modifies memory; should not be
11609 -diff -urNp linux-2.6.27.6/arch/x86/power/cpu_64.c linux-2.6.27.6/arch/x86/power/cpu_64.c
11610 ---- linux-2.6.27.6/arch/x86/power/cpu_64.c 2008-11-07 12:55:34.000000000 -0500
11611 -+++ linux-2.6.27.6/arch/x86/power/cpu_64.c 2008-11-18 03:38:44.000000000 -0500
11612 -@@ -136,7 +136,11 @@ void restore_processor_state(void)
11613 - static void fix_processor_context(void)
11614 - {
11615 - int cpu = smp_processor_id();
11616 -- struct tss_struct *t = &per_cpu(init_tss, cpu);
11617 -+ struct tss_struct *t = init_tss + cpu;
11618 -+
11619 -+#ifdef CONFIG_PAX_KERNEXEC
11620 -+ unsigned long cr0;
11621 -+#endif
11622 -
11623 - /*
11624 - * This just modifies memory; should not be necessary. But... This
11625 -@@ -145,8 +149,16 @@ static void fix_processor_context(void)
11626 - */
11627 - set_tss_desc(cpu, t);
11628 -
11629 -+#ifdef CONFIG_PAX_KERNEXEC
11630 -+ pax_open_kernel(cr0);
11631 -+#endif
11632 -+
11633 - get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9;
11634 -
11635 -+#ifdef CONFIG_PAX_KERNEXEC
11636 -+ pax_close_kernel(cr0);
11637 -+#endif
11638 -+
11639 - syscall_init(); /* This sets MSR_*STAR and related */
11640 - load_TR_desc(); /* This does ltr */
11641 - load_LDT(&current->active_mm->context); /* This does lldt */
11642 -diff -urNp linux-2.6.27.6/arch/x86/vdso/vdso32-setup.c linux-2.6.27.6/arch/x86/vdso/vdso32-setup.c
11643 ---- linux-2.6.27.6/arch/x86/vdso/vdso32-setup.c 2008-11-07 12:55:34.000000000 -0500
11644 -+++ linux-2.6.27.6/arch/x86/vdso/vdso32-setup.c 2008-11-18 03:38:44.000000000 -0500
11645 -@@ -226,7 +226,7 @@ static inline void map_compat_vdso(int m
11646 - void enable_sep_cpu(void)
11647 - {
11648 - int cpu = get_cpu();
11649 -- struct tss_struct *tss = &per_cpu(init_tss, cpu);
11650 -+ struct tss_struct *tss = init_tss + cpu;
11651 -
11652 - if (!boot_cpu_has(X86_FEATURE_SEP)) {
11653 - put_cpu();
11654 -@@ -249,7 +249,7 @@ static int __init gate_vma_init(void)
11655 - gate_vma.vm_start = FIXADDR_USER_START;
11656 - gate_vma.vm_end = FIXADDR_USER_END;
11657 - gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
11658 -- gate_vma.vm_page_prot = __P101;
11659 -+ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
11660 - /*
11661 - * Make sure the vDSO gets into every core dump.
11662 - * Dumping its contents makes post-mortem fully interpretable later
11663 -@@ -331,7 +331,7 @@ int arch_setup_additional_pages(struct l
11664 - if (compat)
11665 - addr = VDSO_HIGH_BASE;
11666 - else {
11667 -- addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
11668 -+ addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
11669 - if (IS_ERR_VALUE(addr)) {
11670 - ret = addr;
11671 - goto up_fail;
11672 -@@ -358,7 +358,7 @@ int arch_setup_additional_pages(struct l
11673 - goto up_fail;
11674 - }
11675 -
11676 -- current->mm->context.vdso = (void *)addr;
11677 -+ current->mm->context.vdso = addr;
11678 - current_thread_info()->sysenter_return =
11679 - VDSO32_SYMBOL(addr, SYSENTER_RETURN);
11680 -
11681 -@@ -384,7 +384,7 @@ static ctl_table abi_table2[] = {
11682 - .mode = 0644,
11683 - .proc_handler = proc_dointvec
11684 - },
11685 -- {}
11686 -+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
11687 - };
11688 -
11689 - static ctl_table abi_root_table2[] = {
11690 -@@ -394,7 +394,7 @@ static ctl_table abi_root_table2[] = {
11691 - .mode = 0555,
11692 - .child = abi_table2
11693 - },
11694 -- {}
11695 -+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
11696 - };
11697 -
11698 - static __init int ia32_binfmt_init(void)
11699 -@@ -409,8 +409,14 @@ __initcall(ia32_binfmt_init);
11700 -
11701 - const char *arch_vma_name(struct vm_area_struct *vma)
11702 - {
11703 -- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
11704 -+ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
11705 - return "[vdso]";
11706 -+
11707 -+#ifdef CONFIG_PAX_SEGMEXEC
11708 -+ if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso)
11709 -+ return "[vdso]";
11710 -+#endif
11711 -+
11712 - return NULL;
11713 - }
11714 -
11715 -@@ -419,7 +425,7 @@ struct vm_area_struct *get_gate_vma(stru
11716 - struct mm_struct *mm = tsk->mm;
11717 -
11718 - /* Check to see if this task was created in compat vdso mode */
11719 -- if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
11720 -+ if (mm && mm->context.vdso == VDSO_HIGH_BASE)
11721 - return &gate_vma;
11722 - return NULL;
11723 - }
11724 -diff -urNp linux-2.6.27.6/arch/x86/vdso/vma.c linux-2.6.27.6/arch/x86/vdso/vma.c
11725 ---- linux-2.6.27.6/arch/x86/vdso/vma.c 2008-11-07 12:55:34.000000000 -0500
11726 -+++ linux-2.6.27.6/arch/x86/vdso/vma.c 2008-11-18 03:38:44.000000000 -0500
11727 -@@ -123,7 +123,7 @@ int arch_setup_additional_pages(struct l
11728 - if (ret)
11729 - goto up_fail;
11730 -
11731 -- current->mm->context.vdso = (void *)addr;
11732 -+ current->mm->context.vdso = addr;
11733 - up_fail:
11734 - up_write(&mm->mmap_sem);
11735 - return ret;
11736 -diff -urNp linux-2.6.27.6/arch/x86/xen/enlighten.c linux-2.6.27.6/arch/x86/xen/enlighten.c
11737 ---- linux-2.6.27.6/arch/x86/xen/enlighten.c 2008-11-07 12:55:34.000000000 -0500
11738 -+++ linux-2.6.27.6/arch/x86/xen/enlighten.c 2008-11-18 03:38:44.000000000 -0500
11739 -@@ -343,7 +343,7 @@ static void xen_set_ldt(const void *addr
11740 - static void xen_load_gdt(const struct desc_ptr *dtr)
11741 - {
11742 - unsigned long *frames;
11743 -- unsigned long va = dtr->address;
11744 -+ unsigned long va = (unsigned long)dtr->address;
11745 - unsigned int size = dtr->size + 1;
11746 - unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
11747 - int f;
11748 -@@ -358,7 +358,7 @@ static void xen_load_gdt(const struct de
11749 - mcs = xen_mc_entry(sizeof(*frames) * pages);
11750 - frames = mcs.args;
11751 -
11752 -- for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
11753 -+ for (f = 0; va < (unsigned long)dtr->address + size; va += PAGE_SIZE, f++) {
11754 - frames[f] = virt_to_mfn(va);
11755 - make_lowmem_page_readonly((void *)va);
11756 - }
11757 -@@ -467,7 +467,7 @@ static void xen_write_idt_entry(gate_des
11758 -
11759 - preempt_disable();
11760 -
11761 -- start = __get_cpu_var(idt_desc).address;
11762 -+ start = (unsigned long)__get_cpu_var(idt_desc).address;
11763 - end = start + __get_cpu_var(idt_desc).size + 1;
11764 -
11765 - xen_mc_flush();
11766 -@@ -1574,6 +1574,8 @@ static __init pgd_t *xen_setup_kernel_pa
11767 - convert_pfn_mfn(init_level4_pgt);
11768 - convert_pfn_mfn(level3_ident_pgt);
11769 - convert_pfn_mfn(level3_kernel_pgt);
11770 -+ convert_pfn_mfn(level3_vmalloc_pgt);
11771 -+ convert_pfn_mfn(level3_vmemmap_pgt);
11772 -
11773 - l3 = m2v(pgd[pgd_index(__START_KERNEL_map)].pgd);
11774 - l2 = m2v(l3[pud_index(__START_KERNEL_map)].pud);
11775 -@@ -1592,9 +1594,12 @@ static __init pgd_t *xen_setup_kernel_pa
11776 - set_page_prot(init_level4_pgt, PAGE_KERNEL_RO);
11777 - set_page_prot(level3_ident_pgt, PAGE_KERNEL_RO);
11778 - set_page_prot(level3_kernel_pgt, PAGE_KERNEL_RO);
11779 -+ set_page_prot(level3_vmalloc_pgt, PAGE_KERNEL_RO);
11780 -+ set_page_prot(level3_vmemmap_pgt, PAGE_KERNEL_RO);
11781 - set_page_prot(level3_user_vsyscall, PAGE_KERNEL_RO);
11782 - set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO);
11783 - set_page_prot(level2_fixmap_pgt, PAGE_KERNEL_RO);
11784 -+ set_page_prot(level1_fixmap_pgt, PAGE_KERNEL_RO);
11785 -
11786 - /* Pin down new L4 */
11787 - pin_pagetable_pfn(MMUEXT_PIN_L4_TABLE,
11788 -diff -urNp linux-2.6.27.6/arch/x86/xen/smp.c linux-2.6.27.6/arch/x86/xen/smp.c
11789 ---- linux-2.6.27.6/arch/x86/xen/smp.c 2008-11-07 12:55:34.000000000 -0500
11790 -+++ linux-2.6.27.6/arch/x86/xen/smp.c 2008-11-18 03:38:44.000000000 -0500
11791 -@@ -170,11 +170,6 @@ static void __init xen_smp_prepare_boot_
11792 - {
11793 - BUG_ON(smp_processor_id() != 0);
11794 - native_smp_prepare_boot_cpu();
11795 --
11796 -- /* We've switched to the "real" per-cpu gdt, so make sure the
11797 -- old memory can be recycled */
11798 -- make_lowmem_page_readwrite(&per_cpu_var(gdt_page));
11799 --
11800 - xen_setup_vcpu_info_placement();
11801 - }
11802 -
11803 -@@ -232,8 +227,8 @@ cpu_initialize_context(unsigned int cpu,
11804 - gdt = get_cpu_gdt_table(cpu);
11805 -
11806 - ctxt->flags = VGCF_IN_KERNEL;
11807 -- ctxt->user_regs.ds = __USER_DS;
11808 -- ctxt->user_regs.es = __USER_DS;
11809 -+ ctxt->user_regs.ds = __KERNEL_DS;
11810 -+ ctxt->user_regs.es = __KERNEL_DS;
11811 - ctxt->user_regs.ss = __KERNEL_DS;
11812 - #ifdef CONFIG_X86_32
11813 - ctxt->user_regs.fs = __KERNEL_PERCPU;
11814 -diff -urNp linux-2.6.27.6/crypto/async_tx/async_tx.c linux-2.6.27.6/crypto/async_tx/async_tx.c
11815 ---- linux-2.6.27.6/crypto/async_tx/async_tx.c 2008-11-07 12:55:34.000000000 -0500
11816 -+++ linux-2.6.27.6/crypto/async_tx/async_tx.c 2008-11-18 03:38:44.000000000 -0500
11817 -@@ -358,8 +358,8 @@ async_tx_init(void)
11818 - err:
11819 - printk(KERN_ERR "async_tx: initialization failure\n");
11820 -
11821 -- while (--cap >= 0)
11822 -- free_percpu(channel_table[cap]);
11823 -+ while (cap)
11824 -+ free_percpu(channel_table[--cap]);
11825 -
11826 - return 1;
11827 - }
11828 -diff -urNp linux-2.6.27.6/crypto/lrw.c linux-2.6.27.6/crypto/lrw.c
11829 ---- linux-2.6.27.6/crypto/lrw.c 2008-11-07 12:55:34.000000000 -0500
11830 -+++ linux-2.6.27.6/crypto/lrw.c 2008-11-18 03:38:44.000000000 -0500
11831 -@@ -54,7 +54,7 @@ static int setkey(struct crypto_tfm *par
11832 - struct priv *ctx = crypto_tfm_ctx(parent);
11833 - struct crypto_cipher *child = ctx->child;
11834 - int err, i;
11835 -- be128 tmp = { 0 };
11836 -+ be128 tmp = { 0, 0 };
11837 - int bsize = crypto_cipher_blocksize(child);
11838 -
11839 - crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
11840 -diff -urNp linux-2.6.27.6/Documentation/dontdiff linux-2.6.27.6/Documentation/dontdiff
11841 ---- linux-2.6.27.6/Documentation/dontdiff 2008-11-07 12:55:34.000000000 -0500
11842 -+++ linux-2.6.27.6/Documentation/dontdiff 2008-11-18 03:39:50.000000000 -0500
11843 -@@ -3,6 +3,7 @@
11844 - *.bin
11845 - *.cpio
11846 - *.css
11847 -+*.dbg
11848 - *.dvi
11849 - *.eps
11850 - *.fw.gen.S
11851 -@@ -53,9 +54,14 @@ COPYING
11852 - CREDITS
11853 - CVS
11854 - ChangeSet
11855 -+GPATH
11856 -+GRTAGS
11857 -+GSYMS
11858 -+GTAGS
11859 - Image
11860 - Kerntypes
11861 - MODS.txt
11862 -+Module.markers
11863 - Module.symvers
11864 - PENDING
11865 - SCCS
11866 -@@ -66,7 +72,6 @@ aic7*reg_print.c*
11867 - aic7*seq.h*
11868 - aicasm
11869 - aicdb.h*
11870 --asm
11871 - asm-offsets.h
11872 - asm_offsets.h
11873 - autoconf.h*
11874 -@@ -74,6 +79,7 @@ bbootsect
11875 - bin2c
11876 - binkernel.spec
11877 - bootsect
11878 -+bounds.h
11879 - bsetup
11880 - btfixupprep
11881 - build
11882 -@@ -90,6 +96,7 @@ config_data.gz*
11883 - conmakehash
11884 - consolemap_deftbl.c*
11885 - crc32table.h*
11886 -+cpustr.h
11887 - cscope.*
11888 - defkeymap.c*
11889 - devlist.h*
11890 -@@ -138,6 +145,7 @@ miboot*
11891 - mk_elfconfig
11892 - mkboot
11893 - mkbugboot
11894 -+mkcpustr
11895 - mkdep
11896 - mkprep
11897 - mktables
11898 -@@ -179,16 +187,21 @@ times.h*
11899 - tkparse
11900 - trix_boot.h
11901 - utsrelease.h*
11902 --vdso.lds
11903 -+vdso*.lds
11904 - version.h*
11905 - vmlinux
11906 - vmlinux-*
11907 - vmlinux.aout
11908 --vmlinux*.lds*
11909 -+vmlinux.bin.all
11910 -+vmlinux*.lds
11911 -+vmlinux.relocs
11912 - vmlinux*.scr
11913 --vsyscall.lds
11914 -+vsyscall*.lds
11915 -+wakeup.elf
11916 -+wakeup.lds
11917 - wanxlfw.inc
11918 - uImage
11919 - unifdef
11920 -+utsrelease.h
11921 - zImage*
11922 - zconf.hash.c
11923 -diff -urNp linux-2.6.27.6/drivers/acpi/blacklist.c linux-2.6.27.6/drivers/acpi/blacklist.c
11924 ---- linux-2.6.27.6/drivers/acpi/blacklist.c 2008-11-07 12:55:34.000000000 -0500
11925 -+++ linux-2.6.27.6/drivers/acpi/blacklist.c 2008-11-18 03:38:44.000000000 -0500
11926 -@@ -71,7 +71,7 @@ static struct acpi_blacklist_item acpi_b
11927 - {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
11928 - "Incorrect _ADR", 1},
11929 -
11930 -- {""}
11931 -+ {"", "", 0, 0, 0, all_versions, 0}
11932 - };
11933 -
11934 - #if CONFIG_ACPI_BLACKLIST_YEAR
11935 -diff -urNp linux-2.6.27.6/drivers/acpi/osl.c linux-2.6.27.6/drivers/acpi/osl.c
11936 ---- linux-2.6.27.6/drivers/acpi/osl.c 2008-11-07 12:55:34.000000000 -0500
11937 -+++ linux-2.6.27.6/drivers/acpi/osl.c 2008-11-18 03:38:44.000000000 -0500
11938 -@@ -494,6 +494,8 @@ acpi_os_read_memory(acpi_physical_addres
11939 - void __iomem *virt_addr;
11940 -
11941 - virt_addr = ioremap(phys_addr, width);
11942 -+ if (!virt_addr)
11943 -+ return AE_NO_MEMORY;
11944 - if (!value)
11945 - value = &dummy;
11946 -
11947 -@@ -522,6 +524,8 @@ acpi_os_write_memory(acpi_physical_addre
11948 - void __iomem *virt_addr;
11949 -
11950 - virt_addr = ioremap(phys_addr, width);
11951 -+ if (!virt_addr)
11952 -+ return AE_NO_MEMORY;
11953 -
11954 - switch (width) {
11955 - case 8:
11956 -diff -urNp linux-2.6.27.6/drivers/acpi/processor_core.c linux-2.6.27.6/drivers/acpi/processor_core.c
11957 ---- linux-2.6.27.6/drivers/acpi/processor_core.c 2008-11-07 12:55:34.000000000 -0500
11958 -+++ linux-2.6.27.6/drivers/acpi/processor_core.c 2008-11-18 03:38:44.000000000 -0500
11959 -@@ -667,7 +667,7 @@ static int __cpuinit acpi_processor_star
11960 - return 0;
11961 - }
11962 -
11963 -- BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
11964 -+ BUG_ON(pr->id >= nr_cpu_ids);
11965 -
11966 - /*
11967 - * Buggy BIOS check
11968 -diff -urNp linux-2.6.27.6/drivers/acpi/processor_idle.c linux-2.6.27.6/drivers/acpi/processor_idle.c
11969 ---- linux-2.6.27.6/drivers/acpi/processor_idle.c 2008-11-07 12:55:34.000000000 -0500
11970 -+++ linux-2.6.27.6/drivers/acpi/processor_idle.c 2008-11-18 03:38:44.000000000 -0500
11971 -@@ -182,7 +182,7 @@ static struct dmi_system_id __cpuinitdat
11972 - DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
11973 - DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
11974 - (void *)2},
11975 -- {},
11976 -+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
11977 - };
11978 -
11979 - static inline u32 ticks_elapsed(u32 t1, u32 t2)
11980 -diff -urNp linux-2.6.27.6/drivers/acpi/tables/tbfadt.c linux-2.6.27.6/drivers/acpi/tables/tbfadt.c
11981 ---- linux-2.6.27.6/drivers/acpi/tables/tbfadt.c 2008-11-07 12:55:34.000000000 -0500
11982 -+++ linux-2.6.27.6/drivers/acpi/tables/tbfadt.c 2008-11-18 03:38:44.000000000 -0500
11983 -@@ -48,7 +48,7 @@
11984 - ACPI_MODULE_NAME("tbfadt")
11985 -
11986 - /* Local prototypes */
11987 --static void inline
11988 -+static inline void
11989 - acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
11990 - u8 bit_width, u64 address);
11991 -
11992 -@@ -122,7 +122,7 @@ static struct acpi_fadt_info fadt_info_t
11993 - *
11994 - ******************************************************************************/
11995 -
11996 --static void inline
11997 -+static inline void
11998 - acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
11999 - u8 bit_width, u64 address)
12000 - {
12001 -diff -urNp linux-2.6.27.6/drivers/ata/ahci.c linux-2.6.27.6/drivers/ata/ahci.c
12002 ---- linux-2.6.27.6/drivers/ata/ahci.c 2008-11-07 12:55:34.000000000 -0500
12003 -+++ linux-2.6.27.6/drivers/ata/ahci.c 2008-11-18 03:38:44.000000000 -0500
12004 -@@ -591,7 +591,7 @@ static const struct pci_device_id ahci_p
12005 - { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
12006 - PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
12007 -
12008 -- { } /* terminate list */
12009 -+ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
12010 - };
12011 -
12012 -
12013 -diff -urNp linux-2.6.27.6/drivers/ata/ata_piix.c linux-2.6.27.6/drivers/ata/ata_piix.c
12014 ---- linux-2.6.27.6/drivers/ata/ata_piix.c 2008-11-07 12:55:34.000000000 -0500
12015 -+++ linux-2.6.27.6/drivers/ata/ata_piix.c 2008-11-18 03:38:44.000000000 -0500
12016 -@@ -284,7 +284,7 @@ static const struct pci_device_id piix_p
12017 - /* SATA Controller IDE (PCH) */
12018 - { 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
12019 -
12020 -- { } /* terminate list */
12021 -+ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
12022 - };
12023 -
12024 - static struct pci_driver piix_pci_driver = {
12025 -@@ -587,7 +587,7 @@ static const struct ich_laptop ich_lapto
12026 - { 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */
12027 - { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */
12028 - /* end marker */
12029 -- { 0, }
12030 -+ { 0, 0, 0 }
12031 - };
12032 -
12033 - /**
12034 -@@ -1143,7 +1143,7 @@ static int piix_broken_suspend(void)
12035 - },
12036 - },
12037 -
12038 -- { } /* terminate list */
12039 -+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } /* terminate list */
12040 - };
12041 - static const char *oemstrs[] = {
12042 - "Tecra M3,",
12043 -diff -urNp linux-2.6.27.6/drivers/ata/libata-core.c linux-2.6.27.6/drivers/ata/libata-core.c
12044 ---- linux-2.6.27.6/drivers/ata/libata-core.c 2008-11-07 12:55:34.000000000 -0500
12045 -+++ linux-2.6.27.6/drivers/ata/libata-core.c 2008-11-18 03:38:44.000000000 -0500
12046 -@@ -746,7 +746,7 @@ static const struct ata_xfer_ent {
12047 - { ATA_SHIFT_PIO, ATA_NR_PIO_MODES, XFER_PIO_0 },
12048 - { ATA_SHIFT_MWDMA, ATA_NR_MWDMA_MODES, XFER_MW_DMA_0 },
12049 - { ATA_SHIFT_UDMA, ATA_NR_UDMA_MODES, XFER_UDMA_0 },
12050 -- { -1, },
12051 -+ { -1, 0, 0 }
12052 - };
12053 -
12054 - /**
12055 -@@ -2910,7 +2910,7 @@ static const struct ata_timing ata_timin
12056 - { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 20 },
12057 - { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 15 },
12058 -
12059 -- { 0xFF }
12060 -+ { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
12061 - };
12062 -
12063 - #define ENOUGH(v, unit) (((v)-1)/(unit)+1)
12064 -@@ -3999,7 +3999,7 @@ static const struct ata_blacklist_entry
12065 - { "TSSTcorp CDDVDW SH-S202N", "SB01", ATA_HORKAGE_IVB, },
12066 -
12067 - /* End Marker */
12068 -- { }
12069 -+ { NULL, NULL, 0 }
12070 - };
12071 -
12072 - static int strn_pattern_cmp(const char *patt, const char *name, int wildchar)
12073 -diff -urNp linux-2.6.27.6/drivers/char/agp/frontend.c linux-2.6.27.6/drivers/char/agp/frontend.c
12074 ---- linux-2.6.27.6/drivers/char/agp/frontend.c 2008-11-07 12:55:34.000000000 -0500
12075 -+++ linux-2.6.27.6/drivers/char/agp/frontend.c 2008-11-18 03:38:44.000000000 -0500
12076 -@@ -824,7 +824,7 @@ static int agpioc_reserve_wrap(struct ag
12077 - if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
12078 - return -EFAULT;
12079 -
12080 -- if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
12081 -+ if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
12082 - return -EFAULT;
12083 -
12084 - client = agp_find_client_by_pid(reserve.pid);
12085 -diff -urNp linux-2.6.27.6/drivers/char/agp/intel-agp.c linux-2.6.27.6/drivers/char/agp/intel-agp.c
12086 ---- linux-2.6.27.6/drivers/char/agp/intel-agp.c 2008-11-07 12:55:34.000000000 -0500
12087 -+++ linux-2.6.27.6/drivers/char/agp/intel-agp.c 2008-11-18 03:38:44.000000000 -0500
12088 -@@ -2332,7 +2332,7 @@ static struct pci_device_id agp_intel_pc
12089 - ID(PCI_DEVICE_ID_INTEL_IGD_E_HB),
12090 - ID(PCI_DEVICE_ID_INTEL_Q45_HB),
12091 - ID(PCI_DEVICE_ID_INTEL_G45_HB),
12092 -- { }
12093 -+ { 0, 0, 0, 0, 0, 0, 0 }
12094 - };
12095 -
12096 - MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
12097 -diff -urNp linux-2.6.27.6/drivers/char/hpet.c linux-2.6.27.6/drivers/char/hpet.c
12098 ---- linux-2.6.27.6/drivers/char/hpet.c 2008-11-07 12:55:34.000000000 -0500
12099 -+++ linux-2.6.27.6/drivers/char/hpet.c 2008-11-18 03:38:44.000000000 -0500
12100 -@@ -959,7 +959,7 @@ static struct acpi_driver hpet_acpi_driv
12101 - },
12102 - };
12103 -
12104 --static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
12105 -+static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL };
12106 -
12107 - static int __init hpet_init(void)
12108 - {
12109 -diff -urNp linux-2.6.27.6/drivers/char/keyboard.c linux-2.6.27.6/drivers/char/keyboard.c
12110 ---- linux-2.6.27.6/drivers/char/keyboard.c 2008-11-07 12:55:34.000000000 -0500
12111 -+++ linux-2.6.27.6/drivers/char/keyboard.c 2008-11-18 03:38:44.000000000 -0500
12112 -@@ -635,6 +635,16 @@ static void k_spec(struct vc_data *vc, u
12113 - kbd->kbdmode == VC_MEDIUMRAW) &&
12114 - value != KVAL(K_SAK))
12115 - return; /* SAK is allowed even in raw mode */
12116 -+
12117 -+#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
12118 -+ {
12119 -+ void *func = fn_handler[value];
12120 -+ if (func == fn_show_state || func == fn_show_ptregs ||
12121 -+ func == fn_show_mem)
12122 -+ return;
12123 -+ }
12124 -+#endif
12125 -+
12126 - fn_handler[value](vc);
12127 - }
12128 -
12129 -@@ -1388,7 +1398,7 @@ static const struct input_device_id kbd_
12130 - .evbit = { BIT_MASK(EV_SND) },
12131 - },
12132 -
12133 -- { }, /* Terminating entry */
12134 -+ { 0 }, /* Terminating entry */
12135 - };
12136 -
12137 - MODULE_DEVICE_TABLE(input, kbd_ids);
12138 -diff -urNp linux-2.6.27.6/drivers/char/mem.c linux-2.6.27.6/drivers/char/mem.c
12139 ---- linux-2.6.27.6/drivers/char/mem.c 2008-11-07 12:55:34.000000000 -0500
12140 -+++ linux-2.6.27.6/drivers/char/mem.c 2008-11-18 03:38:44.000000000 -0500
12141 -@@ -27,6 +27,7 @@
12142 - #include <linux/splice.h>
12143 - #include <linux/pfn.h>
12144 - #include <linux/smp_lock.h>
12145 -+#include <linux/grsecurity.h>
12146 -
12147 - #include <asm/uaccess.h>
12148 - #include <asm/io.h>
12149 -@@ -35,6 +36,10 @@
12150 - # include <linux/efi.h>
12151 - #endif
12152 -
12153 -+#ifdef CONFIG_GRKERNSEC
12154 -+extern struct file_operations grsec_fops;
12155 -+#endif
12156 -+
12157 - /*
12158 - * Architectures vary in how they handle caching for addresses
12159 - * outside of main memory.
12160 -@@ -192,6 +197,11 @@ static ssize_t write_mem(struct file * f
12161 - if (!valid_phys_addr_range(p, count))
12162 - return -EFAULT;
12163 -
12164 -+#ifdef CONFIG_GRKERNSEC_KMEM
12165 -+ gr_handle_mem_write();
12166 -+ return -EPERM;
12167 -+#endif
12168 -+
12169 - written = 0;
12170 -
12171 - #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
12172 -@@ -350,6 +360,11 @@ static int mmap_mem(struct file * file,
12173 - &vma->vm_page_prot))
12174 - return -EINVAL;
12175 -
12176 -+#ifdef CONFIG_GRKERNSEC_KMEM
12177 -+ if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
12178 -+ return -EPERM;
12179 -+#endif
12180 -+
12181 - vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
12182 - size,
12183 - vma->vm_page_prot);
12184 -@@ -588,6 +603,11 @@ static ssize_t write_kmem(struct file *
12185 - ssize_t written;
12186 - char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
12187 -
12188 -+#ifdef CONFIG_GRKERNSEC_KMEM
12189 -+ gr_handle_kmem_write();
12190 -+ return -EPERM;
12191 -+#endif
12192 -+
12193 - if (p < (unsigned long) high_memory) {
12194 -
12195 - wrote = count;
12196 -@@ -791,6 +811,16 @@ static loff_t memory_lseek(struct file *
12197 -
12198 - static int open_port(struct inode * inode, struct file * filp)
12199 - {
12200 -+#ifdef CONFIG_GRKERNSEC_KMEM
12201 -+ gr_handle_open_port();
12202 -+ return -EPERM;
12203 -+#endif
12204 -+
12205 -+ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
12206 -+}
12207 -+
12208 -+static int open_mem(struct inode * inode, struct file * filp)
12209 -+{
12210 - return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
12211 - }
12212 -
12213 -@@ -798,7 +828,6 @@ static int open_port(struct inode * inod
12214 - #define full_lseek null_lseek
12215 - #define write_zero write_null
12216 - #define read_full read_zero
12217 --#define open_mem open_port
12218 - #define open_kmem open_mem
12219 - #define open_oldmem open_mem
12220 -
12221 -@@ -938,6 +967,11 @@ static int memory_open(struct inode * in
12222 - filp->f_op = &oldmem_fops;
12223 - break;
12224 - #endif
12225 -+#ifdef CONFIG_GRKERNSEC
12226 -+ case 13:
12227 -+ filp->f_op = &grsec_fops;
12228 -+ break;
12229 -+#endif
12230 - default:
12231 - unlock_kernel();
12232 - return -ENXIO;
12233 -@@ -974,6 +1008,9 @@ static const struct {
12234 - #ifdef CONFIG_CRASH_DUMP
12235 - {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
12236 - #endif
12237 -+#ifdef CONFIG_GRKERNSEC
12238 -+ {13,"grsec", S_IRUSR | S_IWUGO, &grsec_fops},
12239 -+#endif
12240 - };
12241 -
12242 - static struct class *mem_class;
12243 -diff -urNp linux-2.6.27.6/drivers/char/nvram.c linux-2.6.27.6/drivers/char/nvram.c
12244 ---- linux-2.6.27.6/drivers/char/nvram.c 2008-11-07 12:55:34.000000000 -0500
12245 -+++ linux-2.6.27.6/drivers/char/nvram.c 2008-11-18 03:38:44.000000000 -0500
12246 -@@ -433,7 +433,10 @@ static const struct file_operations nvra
12247 - static struct miscdevice nvram_dev = {
12248 - NVRAM_MINOR,
12249 - "nvram",
12250 -- &nvram_fops
12251 -+ &nvram_fops,
12252 -+ {NULL, NULL},
12253 -+ NULL,
12254 -+ NULL
12255 - };
12256 -
12257 - static int __init
12258 -diff -urNp linux-2.6.27.6/drivers/char/random.c linux-2.6.27.6/drivers/char/random.c
12259 ---- linux-2.6.27.6/drivers/char/random.c 2008-11-07 12:55:34.000000000 -0500
12260 -+++ linux-2.6.27.6/drivers/char/random.c 2008-11-18 03:38:44.000000000 -0500
12261 -@@ -249,8 +249,13 @@
12262 - /*
12263 - * Configuration information
12264 - */
12265 -+#ifdef CONFIG_GRKERNSEC_RANDNET
12266 -+#define INPUT_POOL_WORDS 512
12267 -+#define OUTPUT_POOL_WORDS 128
12268 -+#else
12269 - #define INPUT_POOL_WORDS 128
12270 - #define OUTPUT_POOL_WORDS 32
12271 -+#endif
12272 - #define SEC_XFER_SIZE 512
12273 -
12274 - /*
12275 -@@ -287,10 +292,17 @@ static struct poolinfo {
12276 - int poolwords;
12277 - int tap1, tap2, tap3, tap4, tap5;
12278 - } poolinfo_table[] = {
12279 -+#ifdef CONFIG_GRKERNSEC_RANDNET
12280 -+ /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
12281 -+ { 512, 411, 308, 208, 104, 1 },
12282 -+ /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
12283 -+ { 128, 103, 76, 51, 25, 1 },
12284 -+#else
12285 - /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
12286 - { 128, 103, 76, 51, 25, 1 },
12287 - /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
12288 - { 32, 26, 20, 14, 7, 1 },
12289 -+#endif
12290 - #if 0
12291 - /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
12292 - { 2048, 1638, 1231, 819, 411, 1 },
12293 -@@ -1166,7 +1178,7 @@ EXPORT_SYMBOL(generate_random_uuid);
12294 - #include <linux/sysctl.h>
12295 -
12296 - static int min_read_thresh = 8, min_write_thresh;
12297 --static int max_read_thresh = INPUT_POOL_WORDS * 32;
12298 -+static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
12299 - static int max_write_thresh = INPUT_POOL_WORDS * 32;
12300 - static char sysctl_bootid[16];
12301 -
12302 -diff -urNp linux-2.6.27.6/drivers/char/tpm/tpm.c linux-2.6.27.6/drivers/char/tpm/tpm.c
12303 ---- linux-2.6.27.6/drivers/char/tpm/tpm.c 2008-11-07 12:55:34.000000000 -0500
12304 -+++ linux-2.6.27.6/drivers/char/tpm/tpm.c 2008-11-18 03:38:44.000000000 -0500
12305 -@@ -1037,7 +1037,7 @@ ssize_t tpm_write(struct file *file, con
12306 -
12307 - mutex_lock(&chip->buffer_mutex);
12308 -
12309 -- if (in_size > TPM_BUFSIZE)
12310 -+ if (in_size > (unsigned int)TPM_BUFSIZE)
12311 - in_size = TPM_BUFSIZE;
12312 -
12313 - if (copy_from_user
12314 -diff -urNp linux-2.6.27.6/drivers/char/vt_ioctl.c linux-2.6.27.6/drivers/char/vt_ioctl.c
12315 ---- linux-2.6.27.6/drivers/char/vt_ioctl.c 2008-11-07 12:55:34.000000000 -0500
12316 -+++ linux-2.6.27.6/drivers/char/vt_ioctl.c 2008-11-18 03:38:44.000000000 -0500
12317 -@@ -96,6 +96,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
12318 - case KDSKBENT:
12319 - if (!perm)
12320 - return -EPERM;
12321 -+
12322 -+#ifdef CONFIG_GRKERNSEC
12323 -+ if (!capable(CAP_SYS_TTY_CONFIG))
12324 -+ return -EPERM;
12325 -+#endif
12326 -+
12327 - if (!i && v == K_NOSUCHMAP) {
12328 - /* deallocate map */
12329 - key_map = key_maps[s];
12330 -@@ -236,6 +242,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry
12331 - goto reterr;
12332 - }
12333 -
12334 -+#ifdef CONFIG_GRKERNSEC
12335 -+ if (!capable(CAP_SYS_TTY_CONFIG)) {
12336 -+ ret = -EPERM;
12337 -+ goto reterr;
12338 -+ }
12339 -+#endif
12340 -+
12341 - q = func_table[i];
12342 - first_free = funcbufptr + (funcbufsize - funcbufleft);
12343 - for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
12344 -diff -urNp linux-2.6.27.6/drivers/edac/edac_core.h linux-2.6.27.6/drivers/edac/edac_core.h
12345 ---- linux-2.6.27.6/drivers/edac/edac_core.h 2008-11-07 12:55:34.000000000 -0500
12346 -+++ linux-2.6.27.6/drivers/edac/edac_core.h 2008-11-18 03:38:44.000000000 -0500
12347 -@@ -85,11 +85,11 @@ extern int edac_debug_level;
12348 -
12349 - #else /* !CONFIG_EDAC_DEBUG */
12350 -
12351 --#define debugf0( ... )
12352 --#define debugf1( ... )
12353 --#define debugf2( ... )
12354 --#define debugf3( ... )
12355 --#define debugf4( ... )
12356 -+#define debugf0( ... ) do {} while (0)
12357 -+#define debugf1( ... ) do {} while (0)
12358 -+#define debugf2( ... ) do {} while (0)
12359 -+#define debugf3( ... ) do {} while (0)
12360 -+#define debugf4( ... ) do {} while (0)
12361 -
12362 - #endif /* !CONFIG_EDAC_DEBUG */
12363 -
12364 -diff -urNp linux-2.6.27.6/drivers/firmware/dmi_scan.c linux-2.6.27.6/drivers/firmware/dmi_scan.c
12365 ---- linux-2.6.27.6/drivers/firmware/dmi_scan.c 2008-11-07 12:55:34.000000000 -0500
12366 -+++ linux-2.6.27.6/drivers/firmware/dmi_scan.c 2008-11-18 03:38:44.000000000 -0500
12367 -@@ -384,11 +384,6 @@ void __init dmi_scan_machine(void)
12368 - }
12369 - }
12370 - else {
12371 -- /*
12372 -- * no iounmap() for that ioremap(); it would be a no-op, but
12373 -- * it's so early in setup that sucker gets confused into doing
12374 -- * what it shouldn't if we actually call it.
12375 -- */
12376 - p = dmi_ioremap(0xF0000, 0x10000);
12377 - if (p == NULL)
12378 - goto out;
12379 -diff -urNp linux-2.6.27.6/drivers/hwmon/fscpos.c linux-2.6.27.6/drivers/hwmon/fscpos.c
12380 ---- linux-2.6.27.6/drivers/hwmon/fscpos.c 2008-11-07 12:55:34.000000000 -0500
12381 -+++ linux-2.6.27.6/drivers/hwmon/fscpos.c 2008-11-18 03:38:44.000000000 -0500
12382 -@@ -240,7 +240,6 @@ static ssize_t set_pwm(struct i2c_client
12383 - unsigned long v = simple_strtoul(buf, NULL, 10);
12384 -
12385 - /* Range: 0..255 */
12386 -- if (v < 0) v = 0;
12387 - if (v > 255) v = 255;
12388 -
12389 - mutex_lock(&data->update_lock);
12390 -diff -urNp linux-2.6.27.6/drivers/hwmon/k8temp.c linux-2.6.27.6/drivers/hwmon/k8temp.c
12391 ---- linux-2.6.27.6/drivers/hwmon/k8temp.c 2008-11-07 12:55:34.000000000 -0500
12392 -+++ linux-2.6.27.6/drivers/hwmon/k8temp.c 2008-11-18 03:38:44.000000000 -0500
12393 -@@ -130,7 +130,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
12394 -
12395 - static struct pci_device_id k8temp_ids[] = {
12396 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
12397 -- { 0 },
12398 -+ { 0, 0, 0, 0, 0, 0, 0 },
12399 - };
12400 -
12401 - MODULE_DEVICE_TABLE(pci, k8temp_ids);
12402 -diff -urNp linux-2.6.27.6/drivers/hwmon/sis5595.c linux-2.6.27.6/drivers/hwmon/sis5595.c
12403 ---- linux-2.6.27.6/drivers/hwmon/sis5595.c 2008-11-07 12:55:34.000000000 -0500
12404 -+++ linux-2.6.27.6/drivers/hwmon/sis5595.c 2008-11-18 03:38:44.000000000 -0500
12405 -@@ -698,7 +698,7 @@ static struct sis5595_data *sis5595_upda
12406 -
12407 - static struct pci_device_id sis5595_pci_ids[] = {
12408 - { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
12409 -- { 0, }
12410 -+ { 0, 0, 0, 0, 0, 0, 0 }
12411 - };
12412 -
12413 - MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
12414 -diff -urNp linux-2.6.27.6/drivers/hwmon/via686a.c linux-2.6.27.6/drivers/hwmon/via686a.c
12415 ---- linux-2.6.27.6/drivers/hwmon/via686a.c 2008-11-07 12:55:34.000000000 -0500
12416 -+++ linux-2.6.27.6/drivers/hwmon/via686a.c 2008-11-18 03:38:44.000000000 -0500
12417 -@@ -768,7 +768,7 @@ static struct via686a_data *via686a_upda
12418 -
12419 - static struct pci_device_id via686a_pci_ids[] = {
12420 - { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
12421 -- { 0, }
12422 -+ { 0, 0, 0, 0, 0, 0, 0 }
12423 - };
12424 -
12425 - MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
12426 -diff -urNp linux-2.6.27.6/drivers/hwmon/vt8231.c linux-2.6.27.6/drivers/hwmon/vt8231.c
12427 ---- linux-2.6.27.6/drivers/hwmon/vt8231.c 2008-11-07 12:55:34.000000000 -0500
12428 -+++ linux-2.6.27.6/drivers/hwmon/vt8231.c 2008-11-18 03:38:44.000000000 -0500
12429 -@@ -698,7 +698,7 @@ static struct platform_driver vt8231_dri
12430 -
12431 - static struct pci_device_id vt8231_pci_ids[] = {
12432 - { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
12433 -- { 0, }
12434 -+ { 0, 0, 0, 0, 0, 0, 0 }
12435 - };
12436 -
12437 - MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
12438 -diff -urNp linux-2.6.27.6/drivers/hwmon/w83791d.c linux-2.6.27.6/drivers/hwmon/w83791d.c
12439 ---- linux-2.6.27.6/drivers/hwmon/w83791d.c 2008-11-07 12:55:34.000000000 -0500
12440 -+++ linux-2.6.27.6/drivers/hwmon/w83791d.c 2008-11-18 03:38:44.000000000 -0500
12441 -@@ -289,8 +289,8 @@ static int w83791d_detect(struct i2c_cli
12442 - struct i2c_board_info *info);
12443 - static int w83791d_remove(struct i2c_client *client);
12444 -
12445 --static int w83791d_read(struct i2c_client *client, u8 register);
12446 --static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
12447 -+static int w83791d_read(struct i2c_client *client, u8 reg);
12448 -+static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
12449 - static struct w83791d_data *w83791d_update_device(struct device *dev);
12450 -
12451 - #ifdef DEBUG
12452 -diff -urNp linux-2.6.27.6/drivers/i2c/busses/i2c-i801.c linux-2.6.27.6/drivers/i2c/busses/i2c-i801.c
12453 ---- linux-2.6.27.6/drivers/i2c/busses/i2c-i801.c 2008-11-07 12:55:34.000000000 -0500
12454 -+++ linux-2.6.27.6/drivers/i2c/busses/i2c-i801.c 2008-11-18 03:38:44.000000000 -0500
12455 -@@ -576,7 +576,7 @@ static struct pci_device_id i801_ids[] =
12456 - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TOLAPAI_1) },
12457 - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) },
12458 - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) },
12459 -- { 0, }
12460 -+ { 0, 0, 0, 0, 0, 0, 0 }
12461 - };
12462 -
12463 - MODULE_DEVICE_TABLE (pci, i801_ids);
12464 -diff -urNp linux-2.6.27.6/drivers/i2c/busses/i2c-piix4.c linux-2.6.27.6/drivers/i2c/busses/i2c-piix4.c
12465 ---- linux-2.6.27.6/drivers/i2c/busses/i2c-piix4.c 2008-11-07 12:55:34.000000000 -0500
12466 -+++ linux-2.6.27.6/drivers/i2c/busses/i2c-piix4.c 2008-11-18 03:38:44.000000000 -0500
12467 -@@ -123,7 +123,7 @@ static struct dmi_system_id __devinitdat
12468 - .ident = "IBM",
12469 - .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
12470 - },
12471 -- { },
12472 -+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL },
12473 - };
12474 -
12475 - static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
12476 -@@ -424,7 +424,7 @@ static struct pci_device_id piix4_ids[]
12477 - PCI_DEVICE_ID_SERVERWORKS_CSB6) },
12478 - { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
12479 - PCI_DEVICE_ID_SERVERWORKS_HT1000SB) },
12480 -- { 0, }
12481 -+ { 0, 0, 0, 0, 0, 0, 0 }
12482 - };
12483 -
12484 - MODULE_DEVICE_TABLE (pci, piix4_ids);
12485 -diff -urNp linux-2.6.27.6/drivers/i2c/busses/i2c-sis630.c linux-2.6.27.6/drivers/i2c/busses/i2c-sis630.c
12486 ---- linux-2.6.27.6/drivers/i2c/busses/i2c-sis630.c 2008-11-07 12:55:34.000000000 -0500
12487 -+++ linux-2.6.27.6/drivers/i2c/busses/i2c-sis630.c 2008-11-18 03:38:44.000000000 -0500
12488 -@@ -472,7 +472,7 @@ static struct i2c_adapter sis630_adapter
12489 - static struct pci_device_id sis630_ids[] __devinitdata = {
12490 - { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
12491 - { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
12492 -- { 0, }
12493 -+ { 0, 0, 0, 0, 0, 0, 0 }
12494 - };
12495 -
12496 - MODULE_DEVICE_TABLE (pci, sis630_ids);
12497 -diff -urNp linux-2.6.27.6/drivers/i2c/busses/i2c-sis96x.c linux-2.6.27.6/drivers/i2c/busses/i2c-sis96x.c
12498 ---- linux-2.6.27.6/drivers/i2c/busses/i2c-sis96x.c 2008-11-07 12:55:34.000000000 -0500
12499 -+++ linux-2.6.27.6/drivers/i2c/busses/i2c-sis96x.c 2008-11-18 03:38:44.000000000 -0500
12500 -@@ -248,7 +248,7 @@ static struct i2c_adapter sis96x_adapter
12501 -
12502 - static struct pci_device_id sis96x_ids[] = {
12503 - { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
12504 -- { 0, }
12505 -+ { 0, 0, 0, 0, 0, 0, 0 }
12506 - };
12507 -
12508 - MODULE_DEVICE_TABLE (pci, sis96x_ids);
12509 -diff -urNp linux-2.6.27.6/drivers/ieee1394/dv1394.c linux-2.6.27.6/drivers/ieee1394/dv1394.c
12510 ---- linux-2.6.27.6/drivers/ieee1394/dv1394.c 2008-11-07 12:55:34.000000000 -0500
12511 -+++ linux-2.6.27.6/drivers/ieee1394/dv1394.c 2008-11-18 03:38:44.000000000 -0500
12512 -@@ -739,7 +739,7 @@ static void frame_prepare(struct video_c
12513 - based upon DIF section and sequence
12514 - */
12515 -
12516 --static void inline
12517 -+static inline void
12518 - frame_put_packet (struct frame *f, struct packet *p)
12519 - {
12520 - int section_type = p->data[0] >> 5; /* section type is in bits 5 - 7 */
12521 -@@ -918,7 +918,7 @@ static int do_dv1394_init(struct video_c
12522 - /* default SYT offset is 3 cycles */
12523 - init->syt_offset = 3;
12524 -
12525 -- if ( (init->channel > 63) || (init->channel < 0) )
12526 -+ if (init->channel > 63)
12527 - init->channel = 63;
12528 -
12529 - chan_mask = (u64)1 << init->channel;
12530 -@@ -2174,7 +2174,7 @@ static struct ieee1394_device_id dv1394_
12531 - .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
12532 - .version = AVC_SW_VERSION_ENTRY & 0xffffff
12533 - },
12534 -- { }
12535 -+ { 0, 0, 0, 0, 0, 0 }
12536 - };
12537 -
12538 - MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
12539 -diff -urNp linux-2.6.27.6/drivers/ieee1394/eth1394.c linux-2.6.27.6/drivers/ieee1394/eth1394.c
12540 ---- linux-2.6.27.6/drivers/ieee1394/eth1394.c 2008-11-07 12:55:34.000000000 -0500
12541 -+++ linux-2.6.27.6/drivers/ieee1394/eth1394.c 2008-11-18 03:38:44.000000000 -0500
12542 -@@ -451,7 +451,7 @@ static struct ieee1394_device_id eth1394
12543 - .specifier_id = ETHER1394_GASP_SPECIFIER_ID,
12544 - .version = ETHER1394_GASP_VERSION,
12545 - },
12546 -- {}
12547 -+ { 0, 0, 0, 0, 0, 0 }
12548 - };
12549 -
12550 - MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
12551 -diff -urNp linux-2.6.27.6/drivers/ieee1394/hosts.c linux-2.6.27.6/drivers/ieee1394/hosts.c
12552 ---- linux-2.6.27.6/drivers/ieee1394/hosts.c 2008-11-07 12:55:34.000000000 -0500
12553 -+++ linux-2.6.27.6/drivers/ieee1394/hosts.c 2008-11-18 03:38:44.000000000 -0500
12554 -@@ -78,6 +78,7 @@ static int dummy_isoctl(struct hpsb_iso
12555 - }
12556 -
12557 - static struct hpsb_host_driver dummy_driver = {
12558 -+ .name = "dummy",
12559 - .transmit_packet = dummy_transmit_packet,
12560 - .devctl = dummy_devctl,
12561 - .isoctl = dummy_isoctl
12562 -diff -urNp linux-2.6.27.6/drivers/ieee1394/ohci1394.c linux-2.6.27.6/drivers/ieee1394/ohci1394.c
12563 ---- linux-2.6.27.6/drivers/ieee1394/ohci1394.c 2008-11-07 12:55:34.000000000 -0500
12564 -+++ linux-2.6.27.6/drivers/ieee1394/ohci1394.c 2008-11-18 03:38:44.000000000 -0500
12565 -@@ -147,9 +147,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
12566 - printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
12567 -
12568 - /* Module Parameters */
12569 --static int phys_dma = 1;
12570 -+static int phys_dma;
12571 - module_param(phys_dma, int, 0444);
12572 --MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 1).");
12573 -+MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 0).");
12574 -
12575 - static void dma_trm_tasklet(unsigned long data);
12576 - static void dma_trm_reset(struct dma_trm_ctx *d);
12577 -@@ -3437,7 +3437,7 @@ static struct pci_device_id ohci1394_pci
12578 - .subvendor = PCI_ANY_ID,
12579 - .subdevice = PCI_ANY_ID,
12580 - },
12581 -- { 0, },
12582 -+ { 0, 0, 0, 0, 0, 0, 0 },
12583 - };
12584 -
12585 - MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
12586 -diff -urNp linux-2.6.27.6/drivers/ieee1394/raw1394.c linux-2.6.27.6/drivers/ieee1394/raw1394.c
12587 ---- linux-2.6.27.6/drivers/ieee1394/raw1394.c 2008-11-07 12:55:34.000000000 -0500
12588 -+++ linux-2.6.27.6/drivers/ieee1394/raw1394.c 2008-11-18 03:38:44.000000000 -0500
12589 -@@ -2968,7 +2968,7 @@ static struct ieee1394_device_id raw1394
12590 - .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
12591 - .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
12592 - .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff},
12593 -- {}
12594 -+ { 0, 0, 0, 0, 0, 0 }
12595 - };
12596 -
12597 - MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
12598 -diff -urNp linux-2.6.27.6/drivers/ieee1394/sbp2.c linux-2.6.27.6/drivers/ieee1394/sbp2.c
12599 ---- linux-2.6.27.6/drivers/ieee1394/sbp2.c 2008-11-07 12:55:34.000000000 -0500
12600 -+++ linux-2.6.27.6/drivers/ieee1394/sbp2.c 2008-11-18 03:38:44.000000000 -0500
12601 -@@ -290,7 +290,7 @@ static struct ieee1394_device_id sbp2_id
12602 - .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
12603 - .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
12604 - .version = SBP2_SW_VERSION_ENTRY & 0xffffff},
12605 -- {}
12606 -+ { 0, 0, 0, 0, 0, 0 }
12607 - };
12608 - MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
12609 -
12610 -@@ -2130,7 +2130,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot
12611 - MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
12612 - MODULE_LICENSE("GPL");
12613 -
12614 --static int sbp2_module_init(void)
12615 -+static int __init sbp2_module_init(void)
12616 - {
12617 - int ret;
12618 -
12619 -diff -urNp linux-2.6.27.6/drivers/ieee1394/video1394.c linux-2.6.27.6/drivers/ieee1394/video1394.c
12620 ---- linux-2.6.27.6/drivers/ieee1394/video1394.c 2008-11-07 12:55:34.000000000 -0500
12621 -+++ linux-2.6.27.6/drivers/ieee1394/video1394.c 2008-11-18 03:38:44.000000000 -0500
12622 -@@ -893,7 +893,7 @@ static long video1394_ioctl(struct file
12623 - if (unlikely(d == NULL))
12624 - return -EFAULT;
12625 -
12626 -- if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) {
12627 -+ if (unlikely(v.buffer>=d->num_desc - 1)) {
12628 - PRINT(KERN_ERR, ohci->host->id,
12629 - "Buffer %d out of range",v.buffer);
12630 - return -EINVAL;
12631 -@@ -959,7 +959,7 @@ static long video1394_ioctl(struct file
12632 - if (unlikely(d == NULL))
12633 - return -EFAULT;
12634 -
12635 -- if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) {
12636 -+ if (unlikely(v.buffer>d->num_desc - 1)) {
12637 - PRINT(KERN_ERR, ohci->host->id,
12638 - "Buffer %d out of range",v.buffer);
12639 - return -EINVAL;
12640 -@@ -1030,7 +1030,7 @@ static long video1394_ioctl(struct file
12641 - d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
12642 - if (d == NULL) return -EFAULT;
12643 -
12644 -- if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
12645 -+ if (v.buffer>=d->num_desc - 1) {
12646 - PRINT(KERN_ERR, ohci->host->id,
12647 - "Buffer %d out of range",v.buffer);
12648 - return -EINVAL;
12649 -@@ -1137,7 +1137,7 @@ static long video1394_ioctl(struct file
12650 - d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
12651 - if (d == NULL) return -EFAULT;
12652 -
12653 -- if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
12654 -+ if (v.buffer>=d->num_desc-1) {
12655 - PRINT(KERN_ERR, ohci->host->id,
12656 - "Buffer %d out of range",v.buffer);
12657 - return -EINVAL;
12658 -@@ -1310,7 +1310,7 @@ static struct ieee1394_device_id video13
12659 - .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
12660 - .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff
12661 - },
12662 -- { }
12663 -+ { 0, 0, 0, 0, 0, 0 }
12664 - };
12665 -
12666 - MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
12667 -diff -urNp linux-2.6.27.6/drivers/input/keyboard/atkbd.c linux-2.6.27.6/drivers/input/keyboard/atkbd.c
12668 ---- linux-2.6.27.6/drivers/input/keyboard/atkbd.c 2008-11-07 12:55:34.000000000 -0500
12669 -+++ linux-2.6.27.6/drivers/input/keyboard/atkbd.c 2008-11-18 03:38:44.000000000 -0500
12670 -@@ -1132,7 +1132,7 @@ static struct serio_device_id atkbd_seri
12671 - .id = SERIO_ANY,
12672 - .extra = SERIO_ANY,
12673 - },
12674 -- { 0 }
12675 -+ { 0, 0, 0, 0 }
12676 - };
12677 -
12678 - MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
12679 -diff -urNp linux-2.6.27.6/drivers/input/mouse/lifebook.c linux-2.6.27.6/drivers/input/mouse/lifebook.c
12680 ---- linux-2.6.27.6/drivers/input/mouse/lifebook.c 2008-11-07 12:55:34.000000000 -0500
12681 -+++ linux-2.6.27.6/drivers/input/mouse/lifebook.c 2008-11-18 03:38:44.000000000 -0500
12682 -@@ -110,7 +110,7 @@ static const struct dmi_system_id lifebo
12683 - DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
12684 - },
12685 - },
12686 -- { }
12687 -+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
12688 - };
12689 -
12690 - static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
12691 -diff -urNp linux-2.6.27.6/drivers/input/mouse/psmouse-base.c linux-2.6.27.6/drivers/input/mouse/psmouse-base.c
12692 ---- linux-2.6.27.6/drivers/input/mouse/psmouse-base.c 2008-11-07 12:55:34.000000000 -0500
12693 -+++ linux-2.6.27.6/drivers/input/mouse/psmouse-base.c 2008-11-18 03:38:44.000000000 -0500
12694 -@@ -1328,7 +1328,7 @@ static struct serio_device_id psmouse_se
12695 - .id = SERIO_ANY,
12696 - .extra = SERIO_ANY,
12697 - },
12698 -- { 0 }
12699 -+ { 0, 0, 0, 0 }
12700 - };
12701 -
12702 - MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
12703 -diff -urNp linux-2.6.27.6/drivers/input/mouse/synaptics.c linux-2.6.27.6/drivers/input/mouse/synaptics.c
12704 ---- linux-2.6.27.6/drivers/input/mouse/synaptics.c 2008-11-07 12:55:34.000000000 -0500
12705 -+++ linux-2.6.27.6/drivers/input/mouse/synaptics.c 2008-11-18 03:38:45.000000000 -0500
12706 -@@ -417,7 +417,7 @@ static void synaptics_process_packet(str
12707 - break;
12708 - case 2:
12709 - if (SYN_MODEL_PEN(priv->model_id))
12710 -- ; /* Nothing, treat a pen as a single finger */
12711 -+ break; /* Nothing, treat a pen as a single finger */
12712 - break;
12713 - case 4 ... 15:
12714 - if (SYN_CAP_PALMDETECT(priv->capabilities))
12715 -@@ -624,7 +624,7 @@ static const struct dmi_system_id toshib
12716 - DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
12717 - },
12718 - },
12719 -- { }
12720 -+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12721 - };
12722 - #endif
12723 -
12724 -diff -urNp linux-2.6.27.6/drivers/input/mousedev.c linux-2.6.27.6/drivers/input/mousedev.c
12725 ---- linux-2.6.27.6/drivers/input/mousedev.c 2008-11-07 12:55:34.000000000 -0500
12726 -+++ linux-2.6.27.6/drivers/input/mousedev.c 2008-11-18 03:38:45.000000000 -0500
12727 -@@ -1064,7 +1064,7 @@ static struct input_handler mousedev_han
12728 -
12729 - #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
12730 - static struct miscdevice psaux_mouse = {
12731 -- PSMOUSE_MINOR, "psaux", &mousedev_fops
12732 -+ PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL
12733 - };
12734 - static int psaux_registered;
12735 - #endif
12736 -diff -urNp linux-2.6.27.6/drivers/input/serio/i8042-x86ia64io.h linux-2.6.27.6/drivers/input/serio/i8042-x86ia64io.h
12737 ---- linux-2.6.27.6/drivers/input/serio/i8042-x86ia64io.h 2008-11-07 12:55:34.000000000 -0500
12738 -+++ linux-2.6.27.6/drivers/input/serio/i8042-x86ia64io.h 2008-11-18 03:38:45.000000000 -0500
12739 -@@ -135,7 +135,7 @@ static struct dmi_system_id __initdata i
12740 - DMI_MATCH(DMI_PRODUCT_VERSION, "5a"),
12741 - },
12742 - },
12743 -- { }
12744 -+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12745 - };
12746 -
12747 - /*
12748 -@@ -322,7 +322,7 @@ static struct dmi_system_id __initdata i
12749 - DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"),
12750 - },
12751 - },
12752 -- { }
12753 -+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12754 - };
12755 -
12756 - #ifdef CONFIG_PNP
12757 -@@ -334,7 +334,7 @@ static struct dmi_system_id __initdata i
12758 - DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
12759 - },
12760 - },
12761 -- { }
12762 -+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12763 - };
12764 - #endif
12765 -
12766 -@@ -401,7 +401,7 @@ static struct dmi_system_id __initdata i
12767 - DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"),
12768 - },
12769 - },
12770 -- { }
12771 -+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12772 - };
12773 -
12774 - #endif /* CONFIG_X86 */
12775 -diff -urNp linux-2.6.27.6/drivers/input/serio/serio_raw.c linux-2.6.27.6/drivers/input/serio/serio_raw.c
12776 ---- linux-2.6.27.6/drivers/input/serio/serio_raw.c 2008-11-07 12:55:34.000000000 -0500
12777 -+++ linux-2.6.27.6/drivers/input/serio/serio_raw.c 2008-11-18 03:38:45.000000000 -0500
12778 -@@ -373,7 +373,7 @@ static struct serio_device_id serio_raw_
12779 - .id = SERIO_ANY,
12780 - .extra = SERIO_ANY,
12781 - },
12782 -- { 0 }
12783 -+ { 0, 0, 0, 0 }
12784 - };
12785 -
12786 - MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
12787 -diff -urNp linux-2.6.27.6/drivers/md/bitmap.c linux-2.6.27.6/drivers/md/bitmap.c
12788 ---- linux-2.6.27.6/drivers/md/bitmap.c 2008-11-07 12:55:34.000000000 -0500
12789 -+++ linux-2.6.27.6/drivers/md/bitmap.c 2008-11-18 03:38:45.000000000 -0500
12790 -@@ -57,7 +57,7 @@
12791 - # if DEBUG > 0
12792 - # define PRINTK(x...) printk(KERN_DEBUG x)
12793 - # else
12794 --# define PRINTK(x...)
12795 -+# define PRINTK(x...) do {} while (0)
12796 - # endif
12797 - #endif
12798 -
12799 -diff -urNp linux-2.6.27.6/drivers/mtd/devices/doc2000.c linux-2.6.27.6/drivers/mtd/devices/doc2000.c
12800 ---- linux-2.6.27.6/drivers/mtd/devices/doc2000.c 2008-11-07 12:55:34.000000000 -0500
12801 -+++ linux-2.6.27.6/drivers/mtd/devices/doc2000.c 2008-11-18 03:38:45.000000000 -0500
12802 -@@ -777,7 +777,7 @@ static int doc_write(struct mtd_info *mt
12803 -
12804 - /* The ECC will not be calculated correctly if less than 512 is written */
12805 - /* DBB-
12806 -- if (len != 0x200 && eccbuf)
12807 -+ if (len != 0x200)
12808 - printk(KERN_WARNING
12809 - "ECC needs a full sector write (adr: %lx size %lx)\n",
12810 - (long) to, (long) len);
12811 -diff -urNp linux-2.6.27.6/drivers/mtd/devices/doc2001.c linux-2.6.27.6/drivers/mtd/devices/doc2001.c
12812 ---- linux-2.6.27.6/drivers/mtd/devices/doc2001.c 2008-11-07 12:55:34.000000000 -0500
12813 -+++ linux-2.6.27.6/drivers/mtd/devices/doc2001.c 2008-11-18 03:38:45.000000000 -0500
12814 -@@ -396,6 +396,8 @@ static int doc_read (struct mtd_info *mt
12815 - /* Don't allow read past end of device */
12816 - if (from >= this->totlen)
12817 - return -EINVAL;
12818 -+ if (!len)
12819 -+ return -EINVAL;
12820 -
12821 - /* Don't allow a single read to cross a 512-byte block boundary */
12822 - if (from + len > ((from | 0x1ff) + 1))
12823 -diff -urNp linux-2.6.27.6/drivers/mtd/devices/slram.c linux-2.6.27.6/drivers/mtd/devices/slram.c
12824 ---- linux-2.6.27.6/drivers/mtd/devices/slram.c 2008-11-07 12:55:34.000000000 -0500
12825 -+++ linux-2.6.27.6/drivers/mtd/devices/slram.c 2008-11-18 03:38:45.000000000 -0500
12826 -@@ -273,7 +273,7 @@ static int parse_cmdline(char *devname,
12827 - }
12828 - T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n",
12829 - devname, devstart, devlength);
12830 -- if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) {
12831 -+ if (devlength % SLRAM_BLK_SZ != 0) {
12832 - E("slram: Illegal start / length parameter.\n");
12833 - return(-EINVAL);
12834 - }
12835 -diff -urNp linux-2.6.27.6/drivers/mtd/ubi/build.c linux-2.6.27.6/drivers/mtd/ubi/build.c
12836 ---- linux-2.6.27.6/drivers/mtd/ubi/build.c 2008-11-07 12:55:34.000000000 -0500
12837 -+++ linux-2.6.27.6/drivers/mtd/ubi/build.c 2008-11-18 03:38:45.000000000 -0500
12838 -@@ -1104,7 +1104,7 @@ static int __init bytes_str_to_int(const
12839 - unsigned long result;
12840 -
12841 - result = simple_strtoul(str, &endp, 0);
12842 -- if (str == endp || result < 0) {
12843 -+ if (str == endp) {
12844 - printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n",
12845 - str);
12846 - return -EINVAL;
12847 -diff -urNp linux-2.6.27.6/drivers/net/eepro100.c linux-2.6.27.6/drivers/net/eepro100.c
12848 ---- linux-2.6.27.6/drivers/net/eepro100.c 2008-11-07 12:55:34.000000000 -0500
12849 -+++ linux-2.6.27.6/drivers/net/eepro100.c 2008-11-18 03:38:45.000000000 -0500
12850 -@@ -47,7 +47,7 @@ static int rxdmacount /* = 0 */;
12851 - # define rx_align(skb) skb_reserve((skb), 2)
12852 - # define RxFD_ALIGNMENT __attribute__ ((aligned (2), packed))
12853 - #else
12854 --# define rx_align(skb)
12855 -+# define rx_align(skb) do {} while (0)
12856 - # define RxFD_ALIGNMENT
12857 - #endif
12858 -
12859 -@@ -2334,33 +2334,33 @@ static void __devexit eepro100_remove_on
12860 - }
12861 -
12862 - static struct pci_device_id eepro100_pci_tbl[] = {
12863 -- { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, },
12864 -- { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, },
12865 -- { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, },
12866 -- { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, },
12867 -- { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, },
12868 -- { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, },
12869 -- { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, },
12870 -- { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, },
12871 -- { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, },
12872 -- { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, },
12873 -- { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, },
12874 -- { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, },
12875 -- { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, },
12876 -- { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, },
12877 -- { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, },
12878 -- { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, },
12879 -- { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, },
12880 -- { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, },
12881 -- { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, },
12882 -- { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, },
12883 -- { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
12884 -- { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, },
12885 -- { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, },
12886 -- { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, },
12887 -- { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, },
12888 -- { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, },
12889 -- { 0,}
12890 -+ { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12891 -+ { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12892 -+ { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12893 -+ { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12894 -+ { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12895 -+ { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12896 -+ { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12897 -+ { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12898 -+ { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12899 -+ { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12900 -+ { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12901 -+ { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12902 -+ { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12903 -+ { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12904 -+ { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12905 -+ { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12906 -+ { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12907 -+ { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12908 -+ { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12909 -+ { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12910 -+ { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12911 -+ { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12912 -+ { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12913 -+ { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12914 -+ { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12915 -+ { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12916 -+ { 0, 0, 0, 0, 0, 0, 0 }
12917 - };
12918 - MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
12919 -
12920 -diff -urNp linux-2.6.27.6/drivers/net/irda/vlsi_ir.c linux-2.6.27.6/drivers/net/irda/vlsi_ir.c
12921 ---- linux-2.6.27.6/drivers/net/irda/vlsi_ir.c 2008-11-07 12:55:34.000000000 -0500
12922 -+++ linux-2.6.27.6/drivers/net/irda/vlsi_ir.c 2008-11-18 03:38:45.000000000 -0500
12923 -@@ -906,13 +906,12 @@ static int vlsi_hard_start_xmit(struct s
12924 - /* no race - tx-ring already empty */
12925 - vlsi_set_baud(idev, iobase);
12926 - netif_wake_queue(ndev);
12927 -- }
12928 -- else
12929 -- ;
12930 -+ } else {
12931 - /* keep the speed change pending like it would
12932 - * for any len>0 packet. tx completion interrupt
12933 - * will apply it when the tx ring becomes empty.
12934 - */
12935 -+ }
12936 - spin_unlock_irqrestore(&idev->lock, flags);
12937 - dev_kfree_skb_any(skb);
12938 - return 0;
12939 -diff -urNp linux-2.6.27.6/drivers/net/pcnet32.c linux-2.6.27.6/drivers/net/pcnet32.c
12940 ---- linux-2.6.27.6/drivers/net/pcnet32.c 2008-11-07 12:55:34.000000000 -0500
12941 -+++ linux-2.6.27.6/drivers/net/pcnet32.c 2008-11-18 03:38:45.000000000 -0500
12942 -@@ -78,7 +78,7 @@ static int cards_found;
12943 - /*
12944 - * VLB I/O addresses
12945 - */
12946 --static unsigned int pcnet32_portlist[] __initdata =
12947 -+static unsigned int pcnet32_portlist[] __devinitdata =
12948 - { 0x300, 0x320, 0x340, 0x360, 0 };
12949 -
12950 - static int pcnet32_debug = 0;
12951 -diff -urNp linux-2.6.27.6/drivers/net/tg3.h linux-2.6.27.6/drivers/net/tg3.h
12952 ---- linux-2.6.27.6/drivers/net/tg3.h 2008-11-07 12:55:34.000000000 -0500
12953 -+++ linux-2.6.27.6/drivers/net/tg3.h 2008-11-18 03:38:45.000000000 -0500
12954 -@@ -102,6 +102,7 @@
12955 - #define CHIPREV_ID_5750_A0 0x4000
12956 - #define CHIPREV_ID_5750_A1 0x4001
12957 - #define CHIPREV_ID_5750_A3 0x4003
12958 -+#define CHIPREV_ID_5750_C1 0x4201
12959 - #define CHIPREV_ID_5750_C2 0x4202
12960 - #define CHIPREV_ID_5752_A0_HW 0x5000
12961 - #define CHIPREV_ID_5752_A0 0x6000
12962 -diff -urNp linux-2.6.27.6/drivers/pci/hotplug/cpqphp_nvram.c linux-2.6.27.6/drivers/pci/hotplug/cpqphp_nvram.c
12963 ---- linux-2.6.27.6/drivers/pci/hotplug/cpqphp_nvram.c 2008-11-07 12:55:34.000000000 -0500
12964 -+++ linux-2.6.27.6/drivers/pci/hotplug/cpqphp_nvram.c 2008-11-18 03:38:45.000000000 -0500
12965 -@@ -425,9 +425,13 @@ static u32 store_HRT (void __iomem *rom_
12966 -
12967 - void compaq_nvram_init (void __iomem *rom_start)
12968 - {
12969 -+
12970 -+#ifndef CONFIG_PAX_KERNEXEC
12971 - if (rom_start) {
12972 - compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
12973 - }
12974 -+#endif
12975 -+
12976 - dbg("int15 entry = %p\n", compaq_int15_entry_point);
12977 -
12978 - /* initialize our int15 lock */
12979 -diff -urNp linux-2.6.27.6/drivers/pci/pcie/aer/aerdrv.c linux-2.6.27.6/drivers/pci/pcie/aer/aerdrv.c
12980 ---- linux-2.6.27.6/drivers/pci/pcie/aer/aerdrv.c 2008-11-07 12:55:34.000000000 -0500
12981 -+++ linux-2.6.27.6/drivers/pci/pcie/aer/aerdrv.c 2008-11-18 03:38:45.000000000 -0500
12982 -@@ -59,7 +59,7 @@ static struct pcie_port_service_id aer_i
12983 - .port_type = PCIE_RC_PORT,
12984 - .service_type = PCIE_PORT_SERVICE_AER,
12985 - },
12986 -- { /* end: all zeroes */ }
12987 -+ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
12988 - };
12989 -
12990 - static struct pci_error_handlers aer_error_handlers = {
12991 -diff -urNp linux-2.6.27.6/drivers/pci/pcie/aer/aerdrv_core.c linux-2.6.27.6/drivers/pci/pcie/aer/aerdrv_core.c
12992 ---- linux-2.6.27.6/drivers/pci/pcie/aer/aerdrv_core.c 2008-11-07 12:55:34.000000000 -0500
12993 -+++ linux-2.6.27.6/drivers/pci/pcie/aer/aerdrv_core.c 2008-11-18 03:38:45.000000000 -0500
12994 -@@ -663,7 +663,7 @@ static void aer_isr_one_error(struct pci
12995 - struct aer_err_source *e_src)
12996 - {
12997 - struct device *s_device;
12998 -- struct aer_err_info e_info = {0, 0, 0,};
12999 -+ struct aer_err_info e_info = {0, 0, 0, {0, 0, 0, 0}};
13000 - int i;
13001 - u16 id;
13002 -
13003 -diff -urNp linux-2.6.27.6/drivers/pci/pcie/portdrv_pci.c linux-2.6.27.6/drivers/pci/pcie/portdrv_pci.c
13004 ---- linux-2.6.27.6/drivers/pci/pcie/portdrv_pci.c 2008-11-07 12:55:34.000000000 -0500
13005 -+++ linux-2.6.27.6/drivers/pci/pcie/portdrv_pci.c 2008-11-18 03:38:45.000000000 -0500
13006 -@@ -264,7 +264,7 @@ static void pcie_portdrv_err_resume(stru
13007 - static const struct pci_device_id port_pci_ids[] = { {
13008 - /* handle any PCI-Express port */
13009 - PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
13010 -- }, { /* end: all zeroes */ }
13011 -+ }, { 0, 0, 0, 0, 0, 0, 0 }
13012 - };
13013 - MODULE_DEVICE_TABLE(pci, port_pci_ids);
13014 -
13015 -diff -urNp linux-2.6.27.6/drivers/pci/proc.c linux-2.6.27.6/drivers/pci/proc.c
13016 ---- linux-2.6.27.6/drivers/pci/proc.c 2008-11-07 12:55:34.000000000 -0500
13017 -+++ linux-2.6.27.6/drivers/pci/proc.c 2008-11-18 03:38:45.000000000 -0500
13018 -@@ -470,7 +470,16 @@ static const struct file_operations proc
13019 - static int __init pci_proc_init(void)
13020 - {
13021 - struct pci_dev *dev = NULL;
13022 -+
13023 -+#ifdef CONFIG_GRKERNSEC_PROC_ADD
13024 -+#ifdef CONFIG_GRKERNSEC_PROC_USER
13025 -+ proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR, NULL);
13026 -+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
13027 -+ proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
13028 -+#endif
13029 -+#else
13030 - proc_bus_pci_dir = proc_mkdir("bus/pci", NULL);
13031 -+#endif
13032 - proc_create("devices", 0, proc_bus_pci_dir,
13033 - &proc_bus_pci_dev_operations);
13034 - proc_initialized = 1;
13035 -diff -urNp linux-2.6.27.6/drivers/pcmcia/ti113x.h linux-2.6.27.6/drivers/pcmcia/ti113x.h
13036 ---- linux-2.6.27.6/drivers/pcmcia/ti113x.h 2008-11-07 12:55:34.000000000 -0500
13037 -+++ linux-2.6.27.6/drivers/pcmcia/ti113x.h 2008-11-18 03:38:45.000000000 -0500
13038 -@@ -897,7 +897,7 @@ static struct pci_device_id ene_tune_tbl
13039 - DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
13040 - ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
13041 -
13042 -- {}
13043 -+ { 0, 0, 0, 0, 0, 0, 0 }
13044 - };
13045 -
13046 - static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
13047 -diff -urNp linux-2.6.27.6/drivers/pcmcia/yenta_socket.c linux-2.6.27.6/drivers/pcmcia/yenta_socket.c
13048 ---- linux-2.6.27.6/drivers/pcmcia/yenta_socket.c 2008-11-07 12:55:34.000000000 -0500
13049 -+++ linux-2.6.27.6/drivers/pcmcia/yenta_socket.c 2008-11-18 03:38:45.000000000 -0500
13050 -@@ -1358,7 +1358,7 @@ static struct pci_device_id yenta_table
13051 -
13052 - /* match any cardbus bridge */
13053 - CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
13054 -- { /* all zeroes */ }
13055 -+ { 0, 0, 0, 0, 0, 0, 0 }
13056 - };
13057 - MODULE_DEVICE_TABLE(pci, yenta_table);
13058 -
13059 -diff -urNp linux-2.6.27.6/drivers/pnp/pnpbios/bioscalls.c linux-2.6.27.6/drivers/pnp/pnpbios/bioscalls.c
13060 ---- linux-2.6.27.6/drivers/pnp/pnpbios/bioscalls.c 2008-11-07 12:55:34.000000000 -0500
13061 -+++ linux-2.6.27.6/drivers/pnp/pnpbios/bioscalls.c 2008-11-18 03:38:45.000000000 -0500
13062 -@@ -60,7 +60,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
13063 - set_limit(gdt[(selname) >> 3], size); \
13064 - } while(0)
13065 -
13066 --static struct desc_struct bad_bios_desc;
13067 -+static struct desc_struct bad_bios_desc __read_only;
13068 -
13069 - /*
13070 - * At some point we want to use this stack frame pointer to unwind
13071 -@@ -87,6 +87,10 @@ static inline u16 call_pnp_bios(u16 func
13072 - struct desc_struct save_desc_40;
13073 - int cpu;
13074 -
13075 -+#ifdef CONFIG_PAX_KERNEXEC
13076 -+ unsigned long cr0;
13077 -+#endif
13078 -+
13079 - /*
13080 - * PnP BIOSes are generally not terribly re-entrant.
13081 - * Also, don't rely on them to save everything correctly.
13082 -@@ -96,8 +100,17 @@ static inline u16 call_pnp_bios(u16 func
13083 -
13084 - cpu = get_cpu();
13085 - save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
13086 -+
13087 -+#ifdef CONFIG_PAX_KERNEXEC
13088 -+ pax_open_kernel(cr0);
13089 -+#endif
13090 -+
13091 - get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
13092 -
13093 -+#ifdef CONFIG_PAX_KERNEXEC
13094 -+ pax_close_kernel(cr0);
13095 -+#endif
13096 -+
13097 - /* On some boxes IRQ's during PnP BIOS calls are deadly. */
13098 - spin_lock_irqsave(&pnp_bios_lock, flags);
13099 -
13100 -@@ -134,7 +147,16 @@ static inline u16 call_pnp_bios(u16 func
13101 - :"memory");
13102 - spin_unlock_irqrestore(&pnp_bios_lock, flags);
13103 -
13104 -+#ifdef CONFIG_PAX_KERNEXEC
13105 -+ pax_open_kernel(cr0);
13106 -+#endif
13107 -+
13108 - get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
13109 -+
13110 -+#ifdef CONFIG_PAX_KERNEXEC
13111 -+ pax_close_kernel(cr0);
13112 -+#endif
13113 -+
13114 - put_cpu();
13115 -
13116 - /* If we get here and this is set then the PnP BIOS faulted on us. */
13117 -@@ -468,16 +490,24 @@ int pnp_bios_read_escd(char *data, u32 n
13118 - return status;
13119 - }
13120 -
13121 --void pnpbios_calls_init(union pnp_bios_install_struct *header)
13122 -+void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
13123 - {
13124 - int i;
13125 -
13126 -+#ifdef CONFIG_PAX_KERNEXEC
13127 -+ unsigned long cr0;
13128 -+#endif
13129 -+
13130 - spin_lock_init(&pnp_bios_lock);
13131 - pnp_bios_callpoint.offset = header->fields.pm16offset;
13132 - pnp_bios_callpoint.segment = PNP_CS16;
13133 -
13134 -+#ifdef CONFIG_PAX_KERNEXEC
13135 -+ pax_open_kernel(cr0);
13136 -+#endif
13137 -+
13138 - bad_bios_desc.a = 0;
13139 -- bad_bios_desc.b = 0x00409200;
13140 -+ bad_bios_desc.b = 0x00409300;
13141 -
13142 - set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
13143 - _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
13144 -@@ -491,4 +521,9 @@ void pnpbios_calls_init(union pnp_bios_i
13145 - set_base(gdt[GDT_ENTRY_PNPBIOS_DS],
13146 - __va(header->fields.pm16dseg));
13147 - }
13148 -+
13149 -+#ifdef CONFIG_PAX_KERNEXEC
13150 -+ pax_close_kernel(cr0);
13151 -+#endif
13152 -+
13153 - }
13154 -diff -urNp linux-2.6.27.6/drivers/pnp/quirks.c linux-2.6.27.6/drivers/pnp/quirks.c
13155 ---- linux-2.6.27.6/drivers/pnp/quirks.c 2008-11-07 12:55:34.000000000 -0500
13156 -+++ linux-2.6.27.6/drivers/pnp/quirks.c 2008-11-18 03:38:45.000000000 -0500
13157 -@@ -327,7 +327,7 @@ static struct pnp_fixup pnp_fixups[] = {
13158 - /* PnP resources that might overlap PCI BARs */
13159 - {"PNP0c01", quirk_system_pci_resources},
13160 - {"PNP0c02", quirk_system_pci_resources},
13161 -- {""}
13162 -+ {"", NULL}
13163 - };
13164 -
13165 - void pnp_fixup_device(struct pnp_dev *dev)
13166 -diff -urNp linux-2.6.27.6/drivers/pnp/resource.c linux-2.6.27.6/drivers/pnp/resource.c
13167 ---- linux-2.6.27.6/drivers/pnp/resource.c 2008-11-07 12:55:34.000000000 -0500
13168 -+++ linux-2.6.27.6/drivers/pnp/resource.c 2008-11-18 03:38:45.000000000 -0500
13169 -@@ -355,7 +355,7 @@ int pnp_check_irq(struct pnp_dev *dev, s
13170 - return 1;
13171 -
13172 - /* check if the resource is valid */
13173 -- if (*irq < 0 || *irq > 15)
13174 -+ if (*irq > 15)
13175 - return 0;
13176 -
13177 - /* check if the resource is reserved */
13178 -@@ -419,7 +419,7 @@ int pnp_check_dma(struct pnp_dev *dev, s
13179 - return 1;
13180 -
13181 - /* check if the resource is valid */
13182 -- if (*dma < 0 || *dma == 4 || *dma > 7)
13183 -+ if (*dma == 4 || *dma > 7)
13184 - return 0;
13185 -
13186 - /* check if the resource is reserved */
13187 -diff -urNp linux-2.6.27.6/drivers/scsi/scsi_logging.h linux-2.6.27.6/drivers/scsi/scsi_logging.h
13188 ---- linux-2.6.27.6/drivers/scsi/scsi_logging.h 2008-11-07 12:55:34.000000000 -0500
13189 -+++ linux-2.6.27.6/drivers/scsi/scsi_logging.h 2008-11-18 03:38:45.000000000 -0500
13190 -@@ -51,7 +51,7 @@ do { \
13191 - } while (0); \
13192 - } while (0)
13193 - #else
13194 --#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
13195 -+#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
13196 - #endif /* CONFIG_SCSI_LOGGING */
13197 -
13198 - /*
13199 -diff -urNp linux-2.6.27.6/drivers/serial/8250_pci.c linux-2.6.27.6/drivers/serial/8250_pci.c
13200 ---- linux-2.6.27.6/drivers/serial/8250_pci.c 2008-11-07 12:55:34.000000000 -0500
13201 -+++ linux-2.6.27.6/drivers/serial/8250_pci.c 2008-11-18 03:38:45.000000000 -0500
13202 -@@ -2859,7 +2859,7 @@ static struct pci_device_id serial_pci_t
13203 - PCI_ANY_ID, PCI_ANY_ID,
13204 - PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
13205 - 0xffff00, pbn_default },
13206 -- { 0, }
13207 -+ { 0, 0, 0, 0, 0, 0, 0 }
13208 - };
13209 -
13210 - static struct pci_driver serial_pci_driver = {
13211 -diff -urNp linux-2.6.27.6/drivers/usb/class/cdc-acm.c linux-2.6.27.6/drivers/usb/class/cdc-acm.c
13212 ---- linux-2.6.27.6/drivers/usb/class/cdc-acm.c 2008-11-07 12:55:34.000000000 -0500
13213 -+++ linux-2.6.27.6/drivers/usb/class/cdc-acm.c 2008-11-18 03:38:45.000000000 -0500
13214 -@@ -1382,7 +1382,7 @@ static struct usb_device_id acm_ids[] =
13215 - USB_CDC_ACM_PROTO_AT_CDMA) },
13216 -
13217 - /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */
13218 -- { }
13219 -+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
13220 - };
13221 -
13222 - MODULE_DEVICE_TABLE (usb, acm_ids);
13223 -diff -urNp linux-2.6.27.6/drivers/usb/class/usblp.c linux-2.6.27.6/drivers/usb/class/usblp.c
13224 ---- linux-2.6.27.6/drivers/usb/class/usblp.c 2008-11-07 12:55:34.000000000 -0500
13225 -+++ linux-2.6.27.6/drivers/usb/class/usblp.c 2008-11-18 03:38:45.000000000 -0500
13226 -@@ -227,7 +227,7 @@ static const struct quirk_printer_struct
13227 - { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
13228 - { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@×××.de> */
13229 - { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
13230 -- { 0, 0 }
13231 -+ { 0, 0, 0 }
13232 - };
13233 -
13234 - static int usblp_wwait(struct usblp *usblp, int nonblock);
13235 -@@ -1401,7 +1401,7 @@ static struct usb_device_id usblp_ids []
13236 - { USB_INTERFACE_INFO(7, 1, 2) },
13237 - { USB_INTERFACE_INFO(7, 1, 3) },
13238 - { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */
13239 -- { } /* Terminating entry */
13240 -+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
13241 - };
13242 -
13243 - MODULE_DEVICE_TABLE (usb, usblp_ids);
13244 -diff -urNp linux-2.6.27.6/drivers/usb/core/hub.c linux-2.6.27.6/drivers/usb/core/hub.c
13245 ---- linux-2.6.27.6/drivers/usb/core/hub.c 2008-11-07 12:55:34.000000000 -0500
13246 -+++ linux-2.6.27.6/drivers/usb/core/hub.c 2008-11-18 03:38:45.000000000 -0500
13247 -@@ -3111,7 +3111,7 @@ static struct usb_device_id hub_id_table
13248 - .bDeviceClass = USB_CLASS_HUB},
13249 - { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
13250 - .bInterfaceClass = USB_CLASS_HUB},
13251 -- { } /* Terminating entry */
13252 -+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
13253 - };
13254 -
13255 - MODULE_DEVICE_TABLE (usb, hub_id_table);
13256 -diff -urNp linux-2.6.27.6/drivers/usb/host/ehci-pci.c linux-2.6.27.6/drivers/usb/host/ehci-pci.c
13257 ---- linux-2.6.27.6/drivers/usb/host/ehci-pci.c 2008-11-07 12:55:34.000000000 -0500
13258 -+++ linux-2.6.27.6/drivers/usb/host/ehci-pci.c 2008-11-18 03:38:45.000000000 -0500
13259 -@@ -390,7 +390,7 @@ static const struct pci_device_id pci_id
13260 - PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
13261 - .driver_data = (unsigned long) &ehci_pci_hc_driver,
13262 - },
13263 -- { /* end: all zeroes */ }
13264 -+ { 0, 0, 0, 0, 0, 0, 0 }
13265 - };
13266 - MODULE_DEVICE_TABLE(pci, pci_ids);
13267 -
13268 -diff -urNp linux-2.6.27.6/drivers/usb/host/uhci-hcd.c linux-2.6.27.6/drivers/usb/host/uhci-hcd.c
13269 ---- linux-2.6.27.6/drivers/usb/host/uhci-hcd.c 2008-11-07 12:55:34.000000000 -0500
13270 -+++ linux-2.6.27.6/drivers/usb/host/uhci-hcd.c 2008-11-18 03:38:45.000000000 -0500
13271 -@@ -928,7 +928,7 @@ static const struct pci_device_id uhci_p
13272 - /* handle any USB UHCI controller */
13273 - PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),
13274 - .driver_data = (unsigned long) &uhci_driver,
13275 -- }, { /* end: all zeroes */ }
13276 -+ }, { 0, 0, 0, 0, 0, 0, 0 }
13277 - };
13278 -
13279 - MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
13280 -diff -urNp linux-2.6.27.6/drivers/usb/storage/debug.h linux-2.6.27.6/drivers/usb/storage/debug.h
13281 ---- linux-2.6.27.6/drivers/usb/storage/debug.h 2008-11-07 12:55:34.000000000 -0500
13282 -+++ linux-2.6.27.6/drivers/usb/storage/debug.h 2008-11-18 03:38:45.000000000 -0500
13283 -@@ -54,9 +54,9 @@ void usb_stor_show_sense( unsigned char
13284 - #define US_DEBUGPX(x...) printk( x )
13285 - #define US_DEBUG(x) x
13286 - #else
13287 --#define US_DEBUGP(x...)
13288 --#define US_DEBUGPX(x...)
13289 --#define US_DEBUG(x)
13290 -+#define US_DEBUGP(x...) do {} while (0)
13291 -+#define US_DEBUGPX(x...) do {} while (0)
13292 -+#define US_DEBUG(x) do {} while (0)
13293 - #endif
13294 -
13295 - #endif
13296 -diff -urNp linux-2.6.27.6/drivers/usb/storage/usb.c linux-2.6.27.6/drivers/usb/storage/usb.c
13297 ---- linux-2.6.27.6/drivers/usb/storage/usb.c 2008-11-07 12:55:34.000000000 -0500
13298 -+++ linux-2.6.27.6/drivers/usb/storage/usb.c 2008-11-18 03:38:45.000000000 -0500
13299 -@@ -136,7 +136,7 @@ static struct usb_device_id storage_usb_
13300 - #undef UNUSUAL_DEV
13301 - #undef USUAL_DEV
13302 - /* Terminating entry */
13303 -- { }
13304 -+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
13305 - };
13306 -
13307 - MODULE_DEVICE_TABLE (usb, storage_usb_ids);
13308 -@@ -176,7 +176,7 @@ static struct us_unusual_dev us_unusual_
13309 - # undef USUAL_DEV
13310 -
13311 - /* Terminating entry */
13312 -- { NULL }
13313 -+ { NULL, NULL, 0, 0, NULL }
13314 - };
13315 -
13316 -
13317 -diff -urNp linux-2.6.27.6/drivers/video/fbcmap.c linux-2.6.27.6/drivers/video/fbcmap.c
13318 ---- linux-2.6.27.6/drivers/video/fbcmap.c 2008-11-07 12:55:34.000000000 -0500
13319 -+++ linux-2.6.27.6/drivers/video/fbcmap.c 2008-11-18 03:38:45.000000000 -0500
13320 -@@ -250,8 +250,7 @@ int fb_set_user_cmap(struct fb_cmap_user
13321 - int rc, size = cmap->len * sizeof(u16);
13322 - struct fb_cmap umap;
13323 -
13324 -- if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
13325 -- !info->fbops->fb_setcmap))
13326 -+ if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)
13327 - return -EINVAL;
13328 -
13329 - memset(&umap, 0, sizeof(struct fb_cmap));
13330 -diff -urNp linux-2.6.27.6/drivers/video/fbmem.c linux-2.6.27.6/drivers/video/fbmem.c
13331 ---- linux-2.6.27.6/drivers/video/fbmem.c 2008-11-07 12:55:34.000000000 -0500
13332 -+++ linux-2.6.27.6/drivers/video/fbmem.c 2008-11-18 03:38:45.000000000 -0500
13333 -@@ -395,7 +395,7 @@ static void fb_do_show_logo(struct fb_in
13334 - image->dx += image->width + 8;
13335 - }
13336 - } else if (rotate == FB_ROTATE_UD) {
13337 -- for (x = 0; x < num && image->dx >= 0; x++) {
13338 -+ for (x = 0; x < num && (__s32)image->dx >= 0; x++) {
13339 - info->fbops->fb_imageblit(info, image);
13340 - image->dx -= image->width + 8;
13341 - }
13342 -@@ -407,7 +407,7 @@ static void fb_do_show_logo(struct fb_in
13343 - image->dy += image->height + 8;
13344 - }
13345 - } else if (rotate == FB_ROTATE_CCW) {
13346 -- for (x = 0; x < num && image->dy >= 0; x++) {
13347 -+ for (x = 0; x < num && (__s32)image->dy >= 0; x++) {
13348 - info->fbops->fb_imageblit(info, image);
13349 - image->dy -= image->height + 8;
13350 - }
13351 -@@ -1083,7 +1083,7 @@ fb_ioctl(struct inode *inode, struct fil
13352 - return - EFAULT;
13353 - if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
13354 - return -EINVAL;
13355 -- if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
13356 -+ if (con2fb.framebuffer >= FB_MAX)
13357 - return -EINVAL;
13358 - #ifdef CONFIG_KMOD
13359 - if (!registered_fb[con2fb.framebuffer])
13360 -diff -urNp linux-2.6.27.6/drivers/video/fbmon.c linux-2.6.27.6/drivers/video/fbmon.c
13361 ---- linux-2.6.27.6/drivers/video/fbmon.c 2008-11-07 12:55:34.000000000 -0500
13362 -+++ linux-2.6.27.6/drivers/video/fbmon.c 2008-11-18 03:38:45.000000000 -0500
13363 -@@ -45,7 +45,7 @@
13364 - #ifdef DEBUG
13365 - #define DPRINTK(fmt, args...) printk(fmt,## args)
13366 - #else
13367 --#define DPRINTK(fmt, args...)
13368 -+#define DPRINTK(fmt, args...) do {} while (0)
13369 - #endif
13370 -
13371 - #define FBMON_FIX_HEADER 1
13372 -diff -urNp linux-2.6.27.6/drivers/video/i810/i810_accel.c linux-2.6.27.6/drivers/video/i810/i810_accel.c
13373 ---- linux-2.6.27.6/drivers/video/i810/i810_accel.c 2008-11-07 12:55:34.000000000 -0500
13374 -+++ linux-2.6.27.6/drivers/video/i810/i810_accel.c 2008-11-18 03:38:45.000000000 -0500
13375 -@@ -73,6 +73,7 @@ static inline int wait_for_space(struct
13376 - }
13377 - }
13378 - printk("ringbuffer lockup!!!\n");
13379 -+ printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
13380 - i810_report_error(mmio);
13381 - par->dev_flags |= LOCKUP;
13382 - info->pixmap.scan_align = 1;
13383 -diff -urNp linux-2.6.27.6/drivers/video/i810/i810_main.c linux-2.6.27.6/drivers/video/i810/i810_main.c
13384 ---- linux-2.6.27.6/drivers/video/i810/i810_main.c 2008-11-07 12:55:34.000000000 -0500
13385 -+++ linux-2.6.27.6/drivers/video/i810/i810_main.c 2008-11-18 03:38:45.000000000 -0500
13386 -@@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t
13387 - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
13388 - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,
13389 - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
13390 -- { 0 },
13391 -+ { 0, 0, 0, 0, 0, 0, 0 },
13392 - };
13393 -
13394 - static struct pci_driver i810fb_driver = {
13395 -@@ -1509,7 +1509,7 @@ static int i810fb_cursor(struct fb_info
13396 - int size = ((cursor->image.width + 7) >> 3) *
13397 - cursor->image.height;
13398 - int i;
13399 -- u8 *data = kmalloc(64 * 8, GFP_ATOMIC);
13400 -+ u8 *data = kmalloc(64 * 8, GFP_KERNEL);
13401 -
13402 - if (data == NULL)
13403 - return -ENOMEM;
13404 -diff -urNp linux-2.6.27.6/drivers/video/modedb.c linux-2.6.27.6/drivers/video/modedb.c
13405 ---- linux-2.6.27.6/drivers/video/modedb.c 2008-11-07 12:55:34.000000000 -0500
13406 -+++ linux-2.6.27.6/drivers/video/modedb.c 2008-11-18 03:38:45.000000000 -0500
13407 -@@ -38,232 +38,232 @@ static const struct fb_videomode modedb[
13408 - {
13409 - /* 640x400 @ 70 Hz, 31.5 kHz hsync */
13410 - NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
13411 -- 0, FB_VMODE_NONINTERLACED
13412 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13413 - }, {
13414 - /* 640x480 @ 60 Hz, 31.5 kHz hsync */
13415 - NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
13416 -- 0, FB_VMODE_NONINTERLACED
13417 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13418 - }, {
13419 - /* 800x600 @ 56 Hz, 35.15 kHz hsync */
13420 - NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
13421 -- 0, FB_VMODE_NONINTERLACED
13422 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13423 - }, {
13424 - /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
13425 - NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
13426 -- 0, FB_VMODE_INTERLACED
13427 -+ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
13428 - }, {
13429 - /* 640x400 @ 85 Hz, 37.86 kHz hsync */
13430 - NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
13431 -- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13432 -+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13433 - }, {
13434 - /* 640x480 @ 72 Hz, 36.5 kHz hsync */
13435 - NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
13436 -- 0, FB_VMODE_NONINTERLACED
13437 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13438 - }, {
13439 - /* 640x480 @ 75 Hz, 37.50 kHz hsync */
13440 - NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
13441 -- 0, FB_VMODE_NONINTERLACED
13442 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13443 - }, {
13444 - /* 800x600 @ 60 Hz, 37.8 kHz hsync */
13445 - NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
13446 -- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13447 -+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13448 - }, {
13449 - /* 640x480 @ 85 Hz, 43.27 kHz hsync */
13450 - NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
13451 -- 0, FB_VMODE_NONINTERLACED
13452 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13453 - }, {
13454 - /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
13455 - NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
13456 -- 0, FB_VMODE_INTERLACED
13457 -+ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
13458 - }, {
13459 - /* 800x600 @ 72 Hz, 48.0 kHz hsync */
13460 - NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
13461 -- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13462 -+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13463 - }, {
13464 - /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
13465 - NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
13466 -- 0, FB_VMODE_NONINTERLACED
13467 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13468 - }, {
13469 - /* 640x480 @ 100 Hz, 53.01 kHz hsync */
13470 - NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
13471 -- 0, FB_VMODE_NONINTERLACED
13472 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13473 - }, {
13474 - /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
13475 - NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
13476 -- 0, FB_VMODE_NONINTERLACED
13477 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13478 - }, {
13479 - /* 800x600 @ 85 Hz, 55.84 kHz hsync */
13480 - NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
13481 -- 0, FB_VMODE_NONINTERLACED
13482 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13483 - }, {
13484 - /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
13485 - NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
13486 -- 0, FB_VMODE_NONINTERLACED
13487 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13488 - }, {
13489 - /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
13490 - NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
13491 -- 0, FB_VMODE_INTERLACED
13492 -+ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
13493 - }, {
13494 - /* 800x600 @ 100 Hz, 64.02 kHz hsync */
13495 - NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
13496 -- 0, FB_VMODE_NONINTERLACED
13497 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13498 - }, {
13499 - /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
13500 - NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
13501 -- 0, FB_VMODE_NONINTERLACED
13502 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13503 - }, {
13504 - /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
13505 - NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
13506 -- 0, FB_VMODE_NONINTERLACED
13507 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13508 - }, {
13509 - /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
13510 - NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
13511 -- 0, FB_VMODE_NONINTERLACED
13512 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13513 - }, {
13514 - /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
13515 - NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
13516 -- 0, FB_VMODE_NONINTERLACED
13517 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13518 - }, {
13519 - /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
13520 - NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13,
13521 -- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13522 -+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13523 - }, {
13524 - /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
13525 - NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
13526 -- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13527 -+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13528 - }, {
13529 - /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
13530 - NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
13531 -- 0, FB_VMODE_NONINTERLACED
13532 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13533 - }, {
13534 - /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
13535 - NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
13536 -- 0, FB_VMODE_NONINTERLACED
13537 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13538 - }, {
13539 - /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
13540 - NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
13541 -- 0, FB_VMODE_NONINTERLACED
13542 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13543 - }, {
13544 - /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
13545 - NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
13546 -- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13547 -+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13548 - }, {
13549 - /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
13550 - NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
13551 -- 0, FB_VMODE_NONINTERLACED
13552 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13553 - }, {
13554 - /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
13555 - NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
13556 -- 0, FB_VMODE_NONINTERLACED
13557 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13558 - }, {
13559 - /* 1024x768 @ 100Hz, 80.21 kHz hsync */
13560 - NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
13561 -- 0, FB_VMODE_NONINTERLACED
13562 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13563 - }, {
13564 - /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
13565 - NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
13566 -- 0, FB_VMODE_NONINTERLACED
13567 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13568 - }, {
13569 - /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
13570 - NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
13571 -- 0, FB_VMODE_NONINTERLACED
13572 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13573 - }, {
13574 - /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
13575 - NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
13576 -- 0, FB_VMODE_NONINTERLACED
13577 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13578 - }, {
13579 - /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
13580 - NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
13581 -- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13582 -+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13583 - }, {
13584 - /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
13585 - NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
13586 -- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13587 -+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13588 - }, {
13589 - /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
13590 - NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
13591 -- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13592 -+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13593 - }, {
13594 - /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
13595 - NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
13596 -- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13597 -+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13598 - }, {
13599 - /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
13600 - NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
13601 -- 0, FB_VMODE_NONINTERLACED
13602 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13603 - }, {
13604 - /* 1800x1440 @ 64Hz, 96.15 kHz hsync */
13605 - NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
13606 -- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13607 -+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13608 - }, {
13609 - /* 1800x1440 @ 70Hz, 104.52 kHz hsync */
13610 - NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
13611 -- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13612 -+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13613 - }, {
13614 - /* 512x384 @ 78 Hz, 31.50 kHz hsync */
13615 - NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
13616 -- 0, FB_VMODE_NONINTERLACED
13617 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13618 - }, {
13619 - /* 512x384 @ 85 Hz, 34.38 kHz hsync */
13620 - NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
13621 -- 0, FB_VMODE_NONINTERLACED
13622 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13623 - }, {
13624 - /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
13625 - NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
13626 -- 0, FB_VMODE_DOUBLE
13627 -+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13628 - }, {
13629 - /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
13630 - NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
13631 -- 0, FB_VMODE_DOUBLE
13632 -+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13633 - }, {
13634 - /* 320x240 @ 72 Hz, 36.5 kHz hsync */
13635 - NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
13636 -- 0, FB_VMODE_DOUBLE
13637 -+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13638 - }, {
13639 - /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
13640 - NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
13641 -- 0, FB_VMODE_DOUBLE
13642 -+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13643 - }, {
13644 - /* 400x300 @ 60 Hz, 37.8 kHz hsync */
13645 - NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
13646 -- 0, FB_VMODE_DOUBLE
13647 -+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13648 - }, {
13649 - /* 400x300 @ 72 Hz, 48.0 kHz hsync */
13650 - NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
13651 -- 0, FB_VMODE_DOUBLE
13652 -+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13653 - }, {
13654 - /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
13655 - NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
13656 -- 0, FB_VMODE_DOUBLE
13657 -+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13658 - }, {
13659 - /* 480x300 @ 60 Hz, 37.8 kHz hsync */
13660 - NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
13661 -- 0, FB_VMODE_DOUBLE
13662 -+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13663 - }, {
13664 - /* 480x300 @ 63 Hz, 39.6 kHz hsync */
13665 - NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
13666 -- 0, FB_VMODE_DOUBLE
13667 -+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13668 - }, {
13669 - /* 480x300 @ 72 Hz, 48.0 kHz hsync */
13670 - NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
13671 -- 0, FB_VMODE_DOUBLE
13672 -+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13673 - }, {
13674 - /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
13675 - NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
13676 - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
13677 -- FB_VMODE_NONINTERLACED
13678 -+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13679 - }, {
13680 - /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
13681 - NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6,
13682 -- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13683 -+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13684 - }, {
13685 - /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
13686 - NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
13687 -- 0, FB_VMODE_NONINTERLACED
13688 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13689 - }, {
13690 - /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */
13691 - NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3,
13692 -- 0, FB_VMODE_NONINTERLACED
13693 -+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13694 - },
13695 - };
13696 -
13697 -diff -urNp linux-2.6.27.6/drivers/video/uvesafb.c linux-2.6.27.6/drivers/video/uvesafb.c
13698 ---- linux-2.6.27.6/drivers/video/uvesafb.c 2008-11-07 12:55:34.000000000 -0500
13699 -+++ linux-2.6.27.6/drivers/video/uvesafb.c 2008-11-18 03:38:45.000000000 -0500
13700 -@@ -18,6 +18,7 @@
13701 - #include <linux/fb.h>
13702 - #include <linux/io.h>
13703 - #include <linux/mutex.h>
13704 -+#include <linux/moduleloader.h>
13705 - #include <video/edid.h>
13706 - #include <video/uvesafb.h>
13707 - #ifdef CONFIG_X86
13708 -@@ -117,7 +118,7 @@ static int uvesafb_helper_start(void)
13709 - NULL,
13710 - };
13711 -
13712 -- return call_usermodehelper(v86d_path, argv, envp, 1);
13713 -+ return call_usermodehelper(v86d_path, argv, envp, UMH_WAIT_PROC);
13714 - }
13715 -
13716 - /*
13717 -@@ -569,10 +570,34 @@ static int __devinit uvesafb_vbe_getpmi(
13718 - if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000) {
13719 - par->pmi_setpal = par->ypan = 0;
13720 - } else {
13721 -+
13722 -+#ifdef CONFIG_PAX_KERNEXEC
13723 -+#ifdef CONFIG_MODULES
13724 -+ unsigned long cr0;
13725 -+
13726 -+ par->pmi_code = module_alloc_exec((u16)task->t.regs.ecx);
13727 -+#endif
13728 -+ if (!par->pmi_code) {
13729 -+ par->pmi_setpal = par->ypan = 0;
13730 -+ return 0;
13731 -+ }
13732 -+#endif
13733 -+
13734 - par->pmi_base = (u16 *)phys_to_virt(((u32)task->t.regs.es << 4)
13735 - + task->t.regs.edi);
13736 -+
13737 -+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13738 -+ pax_open_kernel(cr0);
13739 -+ memcpy(par->pmi_code, par->pmi_base, (u16)task->t.regs.ecx);
13740 -+ pax_close_kernel(cr0);
13741 -+
13742 -+ par->pmi_start = ktva_ktla(par->pmi_code + par->pmi_base[1]);
13743 -+ par->pmi_pal = ktva_ktla(par->pmi_code + par->pmi_base[2]);
13744 -+#else
13745 - par->pmi_start = (u8 *)par->pmi_base + par->pmi_base[1];
13746 - par->pmi_pal = (u8 *)par->pmi_base + par->pmi_base[2];
13747 -+#endif
13748 -+
13749 - printk(KERN_INFO "uvesafb: protected mode interface info at "
13750 - "%04x:%04x\n",
13751 - (u16)task->t.regs.es, (u16)task->t.regs.edi);
13752 -@@ -1827,6 +1852,11 @@ out:
13753 - if (par->vbe_modes)
13754 - kfree(par->vbe_modes);
13755 -
13756 -+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13757 -+ if (par->pmi_code)
13758 -+ module_free_exec(NULL, par->pmi_code);
13759 -+#endif
13760 -+
13761 - framebuffer_release(info);
13762 - return err;
13763 - }
13764 -@@ -1853,6 +1883,12 @@ static int uvesafb_remove(struct platfor
13765 - kfree(par->vbe_state_orig);
13766 - if (par->vbe_state_saved)
13767 - kfree(par->vbe_state_saved);
13768 -+
13769 -+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13770 -+ if (par->pmi_code)
13771 -+ module_free_exec(NULL, par->pmi_code);
13772 -+#endif
13773 -+
13774 - }
13775 -
13776 - framebuffer_release(info);
13777 -diff -urNp linux-2.6.27.6/drivers/video/vesafb.c linux-2.6.27.6/drivers/video/vesafb.c
13778 ---- linux-2.6.27.6/drivers/video/vesafb.c 2008-11-07 12:55:34.000000000 -0500
13779 -+++ linux-2.6.27.6/drivers/video/vesafb.c 2008-11-18 03:38:45.000000000 -0500
13780 -@@ -9,6 +9,7 @@
13781 - */
13782 -
13783 - #include <linux/module.h>
13784 -+#include <linux/moduleloader.h>
13785 - #include <linux/kernel.h>
13786 - #include <linux/errno.h>
13787 - #include <linux/string.h>
13788 -@@ -53,8 +54,8 @@ static int vram_remap __initdata; /*
13789 - static int vram_total __initdata; /* Set total amount of memory */
13790 - static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */
13791 - static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */
13792 --static void (*pmi_start)(void) __read_mostly;
13793 --static void (*pmi_pal) (void) __read_mostly;
13794 -+static void (*pmi_start)(void) __read_only;
13795 -+static void (*pmi_pal) (void) __read_only;
13796 - static int depth __read_mostly;
13797 - static int vga_compat __read_mostly;
13798 - /* --------------------------------------------------------------------- */
13799 -@@ -224,6 +225,7 @@ static int __init vesafb_probe(struct pl
13800 - unsigned int size_vmode;
13801 - unsigned int size_remap;
13802 - unsigned int size_total;
13803 -+ void *pmi_code = NULL;
13804 -
13805 - if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
13806 - return -ENODEV;
13807 -@@ -266,10 +268,6 @@ static int __init vesafb_probe(struct pl
13808 - size_remap = size_total;
13809 - vesafb_fix.smem_len = size_remap;
13810 -
13811 --#ifndef __i386__
13812 -- screen_info.vesapm_seg = 0;
13813 --#endif
13814 --
13815 - if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
13816 - printk(KERN_WARNING
13817 - "vesafb: cannot reserve video memory at 0x%lx\n",
13818 -@@ -302,9 +300,21 @@ static int __init vesafb_probe(struct pl
13819 - printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
13820 - vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
13821 -
13822 -+#ifdef __i386__
13823 -+
13824 -+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13825 -+ pmi_code = module_alloc_exec(screen_info.vesapm_size);
13826 -+ if (!pmi_code)
13827 -+#elif !defined(CONFIG_PAX_KERNEXEC)
13828 -+ if (0)
13829 -+#endif
13830 -+
13831 -+#endif
13832 -+ screen_info.vesapm_seg = 0;
13833 -+
13834 - if (screen_info.vesapm_seg) {
13835 -- printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
13836 -- screen_info.vesapm_seg,screen_info.vesapm_off);
13837 -+ printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n",
13838 -+ screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size);
13839 - }
13840 -
13841 - if (screen_info.vesapm_seg < 0xc000)
13842 -@@ -312,9 +322,29 @@ static int __init vesafb_probe(struct pl
13843 -
13844 - if (ypan || pmi_setpal) {
13845 - unsigned short *pmi_base;
13846 -- pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
13847 -- pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
13848 -- pmi_pal = (void*)((char*)pmi_base + pmi_base[2]);
13849 -+
13850 -+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13851 -+ unsigned long cr0;
13852 -+#endif
13853 -+
13854 -+ pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
13855 -+
13856 -+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13857 -+ pax_open_kernel(cr0);
13858 -+ memcpy(pmi_code, pmi_base, screen_info.vesapm_size);
13859 -+#else
13860 -+ pmi_code = pmi_base;
13861 -+#endif
13862 -+
13863 -+ pmi_start = (void*)((char*)pmi_code + pmi_base[1]);
13864 -+ pmi_pal = (void*)((char*)pmi_code + pmi_base[2]);
13865 -+
13866 -+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13867 -+ pmi_start = ktva_ktla(pmi_start);
13868 -+ pmi_pal = ktva_ktla(pmi_pal);
13869 -+ pax_close_kernel(cr0);
13870 -+#endif
13871 -+
13872 - printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
13873 - if (pmi_base[3]) {
13874 - printk(KERN_INFO "vesafb: pmi: ports = ");
13875 -@@ -456,6 +486,11 @@ static int __init vesafb_probe(struct pl
13876 - info->node, info->fix.id);
13877 - return 0;
13878 - err:
13879 -+
13880 -+#if defined(__i386__) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13881 -+ module_free_exec(NULL, pmi_code);
13882 -+#endif
13883 -+
13884 - if (info->screen_base)
13885 - iounmap(info->screen_base);
13886 - framebuffer_release(info);
13887 -diff -urNp linux-2.6.27.6/fs/9p/vfs_inode.c linux-2.6.27.6/fs/9p/vfs_inode.c
13888 ---- linux-2.6.27.6/fs/9p/vfs_inode.c 2008-11-07 12:55:34.000000000 -0500
13889 -+++ linux-2.6.27.6/fs/9p/vfs_inode.c 2008-11-18 03:38:45.000000000 -0500
13890 -@@ -1021,7 +1021,7 @@ static void *v9fs_vfs_follow_link(struct
13891 - static void
13892 - v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
13893 - {
13894 -- char *s = nd_get_link(nd);
13895 -+ const char *s = nd_get_link(nd);
13896 -
13897 - P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name, s);
13898 - if (!IS_ERR(s))
13899 -diff -urNp linux-2.6.27.6/fs/aio.c linux-2.6.27.6/fs/aio.c
13900 ---- linux-2.6.27.6/fs/aio.c 2008-11-07 12:55:34.000000000 -0500
13901 -+++ linux-2.6.27.6/fs/aio.c 2008-11-18 03:38:45.000000000 -0500
13902 -@@ -114,7 +114,7 @@ static int aio_setup_ring(struct kioctx
13903 - size += sizeof(struct io_event) * nr_events;
13904 - nr_pages = (size + PAGE_SIZE-1) >> PAGE_SHIFT;
13905 -
13906 -- if (nr_pages < 0)
13907 -+ if (nr_pages <= 0)
13908 - return -EINVAL;
13909 -
13910 - nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) / sizeof(struct io_event);
13911 -diff -urNp linux-2.6.27.6/fs/autofs4/symlink.c linux-2.6.27.6/fs/autofs4/symlink.c
13912 ---- linux-2.6.27.6/fs/autofs4/symlink.c 2008-11-07 12:55:34.000000000 -0500
13913 -+++ linux-2.6.27.6/fs/autofs4/symlink.c 2008-11-18 03:38:45.000000000 -0500
13914 -@@ -15,7 +15,7 @@
13915 - static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
13916 - {
13917 - struct autofs_info *ino = autofs4_dentry_ino(dentry);
13918 -- nd_set_link(nd, (char *)ino->u.symlink);
13919 -+ nd_set_link(nd, ino->u.symlink);
13920 - return NULL;
13921 - }
13922 -
13923 -diff -urNp linux-2.6.27.6/fs/befs/linuxvfs.c linux-2.6.27.6/fs/befs/linuxvfs.c
13924 ---- linux-2.6.27.6/fs/befs/linuxvfs.c 2008-11-07 12:55:34.000000000 -0500
13925 -+++ linux-2.6.27.6/fs/befs/linuxvfs.c 2008-11-18 03:38:45.000000000 -0500
13926 -@@ -490,7 +490,7 @@ static void befs_put_link(struct dentry
13927 - {
13928 - befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
13929 - if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
13930 -- char *link = nd_get_link(nd);
13931 -+ const char *link = nd_get_link(nd);
13932 - if (!IS_ERR(link))
13933 - kfree(link);
13934 - }
13935 -diff -urNp linux-2.6.27.6/fs/binfmt_aout.c linux-2.6.27.6/fs/binfmt_aout.c
13936 ---- linux-2.6.27.6/fs/binfmt_aout.c 2008-11-07 12:55:34.000000000 -0500
13937 -+++ linux-2.6.27.6/fs/binfmt_aout.c 2008-11-18 03:38:45.000000000 -0500
13938 -@@ -24,6 +24,7 @@
13939 - #include <linux/binfmts.h>
13940 - #include <linux/personality.h>
13941 - #include <linux/init.h>
13942 -+#include <linux/grsecurity.h>
13943 -
13944 - #include <asm/system.h>
13945 - #include <asm/uaccess.h>
13946 -@@ -124,18 +125,22 @@ static int aout_core_dump(long signr, st
13947 - /* If the size of the dump file exceeds the rlimit, then see what would happen
13948 - if we wrote the stack, but not the data area. */
13949 - #ifdef __sparc__
13950 -+ gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize + dump.u_ssize, 1);
13951 - if ((dump.u_dsize + dump.u_ssize) > limit)
13952 - dump.u_dsize = 0;
13953 - #else
13954 -+ gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE, 1);
13955 - if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > limit)
13956 - dump.u_dsize = 0;
13957 - #endif
13958 -
13959 - /* Make sure we have enough room to write the stack and data areas. */
13960 - #ifdef __sparc__
13961 -+ gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
13962 - if (dump.u_ssize > limit)
13963 - dump.u_ssize = 0;
13964 - #else
13965 -+ gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize + 1) * PAGE_SIZE, 1);
13966 - if ((dump.u_ssize + 1) * PAGE_SIZE > limit)
13967 - dump.u_ssize = 0;
13968 - #endif
13969 -@@ -291,6 +296,8 @@ static int load_aout_binary(struct linux
13970 - rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
13971 - if (rlim >= RLIM_INFINITY)
13972 - rlim = ~0;
13973 -+
13974 -+ gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
13975 - if (ex.a_data + ex.a_bss > rlim)
13976 - return -ENOMEM;
13977 -
13978 -@@ -322,6 +329,28 @@ static int load_aout_binary(struct linux
13979 -
13980 - compute_creds(bprm);
13981 - current->flags &= ~PF_FORKNOEXEC;
13982 -+
13983 -+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
13984 -+ current->mm->pax_flags = 0UL;
13985 -+#endif
13986 -+
13987 -+#ifdef CONFIG_PAX_PAGEEXEC
13988 -+ if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
13989 -+ current->mm->pax_flags |= MF_PAX_PAGEEXEC;
13990 -+
13991 -+#ifdef CONFIG_PAX_EMUTRAMP
13992 -+ if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
13993 -+ current->mm->pax_flags |= MF_PAX_EMUTRAMP;
13994 -+#endif
13995 -+
13996 -+#ifdef CONFIG_PAX_MPROTECT
13997 -+ if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
13998 -+ current->mm->pax_flags |= MF_PAX_MPROTECT;
13999 -+#endif
14000 -+
14001 -+ }
14002 -+#endif
14003 -+
14004 - #ifdef __sparc__
14005 - if (N_MAGIC(ex) == NMAGIC) {
14006 - loff_t pos = fd_offset;
14007 -@@ -413,7 +442,7 @@ static int load_aout_binary(struct linux
14008 -
14009 - down_write(&current->mm->mmap_sem);
14010 - error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
14011 -- PROT_READ | PROT_WRITE | PROT_EXEC,
14012 -+ PROT_READ | PROT_WRITE,
14013 - MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
14014 - fd_offset + ex.a_text);
14015 - up_write(&current->mm->mmap_sem);
14016 -diff -urNp linux-2.6.27.6/fs/binfmt_elf.c linux-2.6.27.6/fs/binfmt_elf.c
14017 ---- linux-2.6.27.6/fs/binfmt_elf.c 2008-11-07 12:55:34.000000000 -0500
14018 -+++ linux-2.6.27.6/fs/binfmt_elf.c 2008-11-18 03:38:45.000000000 -0500
14019 -@@ -38,10 +38,16 @@
14020 - #include <linux/random.h>
14021 - #include <linux/elf.h>
14022 - #include <linux/utsname.h>
14023 -+#include <linux/grsecurity.h>
14024 -+
14025 - #include <asm/uaccess.h>
14026 - #include <asm/param.h>
14027 - #include <asm/page.h>
14028 -
14029 -+#ifdef CONFIG_PAX_SEGMEXEC
14030 -+#include <asm/desc.h>
14031 -+#endif
14032 -+
14033 - static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
14034 - static int load_elf_library(struct file *);
14035 - static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *,
14036 -@@ -84,6 +90,8 @@ static struct linux_binfmt elf_format =
14037 -
14038 - static int set_brk(unsigned long start, unsigned long end)
14039 - {
14040 -+ unsigned long e = end;
14041 -+
14042 - start = ELF_PAGEALIGN(start);
14043 - end = ELF_PAGEALIGN(end);
14044 - if (end > start) {
14045 -@@ -94,7 +102,7 @@ static int set_brk(unsigned long start,
14046 - if (BAD_ADDR(addr))
14047 - return addr;
14048 - }
14049 -- current->mm->start_brk = current->mm->brk = end;
14050 -+ current->mm->start_brk = current->mm->brk = e;
14051 - return 0;
14052 - }
14053 -
14054 -@@ -380,10 +388,10 @@ static unsigned long load_elf_interp(str
14055 - {
14056 - struct elf_phdr *elf_phdata;
14057 - struct elf_phdr *eppnt;
14058 -- unsigned long load_addr = 0;
14059 -+ unsigned long load_addr = 0, pax_task_size = TASK_SIZE;
14060 - int load_addr_set = 0;
14061 - unsigned long last_bss = 0, elf_bss = 0;
14062 -- unsigned long error = ~0UL;
14063 -+ unsigned long error = -EINVAL;
14064 - unsigned long total_size;
14065 - int retval, i, size;
14066 -
14067 -@@ -429,6 +437,11 @@ static unsigned long load_elf_interp(str
14068 - goto out_close;
14069 - }
14070 -
14071 -+#ifdef CONFIG_PAX_SEGMEXEC
14072 -+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
14073 -+ pax_task_size = SEGMEXEC_TASK_SIZE;
14074 -+#endif
14075 -+
14076 - eppnt = elf_phdata;
14077 - for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
14078 - if (eppnt->p_type == PT_LOAD) {
14079 -@@ -472,8 +485,8 @@ static unsigned long load_elf_interp(str
14080 - k = load_addr + eppnt->p_vaddr;
14081 - if (BAD_ADDR(k) ||
14082 - eppnt->p_filesz > eppnt->p_memsz ||
14083 -- eppnt->p_memsz > TASK_SIZE ||
14084 -- TASK_SIZE - eppnt->p_memsz < k) {
14085 -+ eppnt->p_memsz > pax_task_size ||
14086 -+ pax_task_size - eppnt->p_memsz < k) {
14087 - error = -ENOMEM;
14088 - goto out_close;
14089 - }
14090 -@@ -527,6 +540,177 @@ out:
14091 - return error;
14092 - }
14093 -
14094 -+#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
14095 -+static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
14096 -+{
14097 -+ unsigned long pax_flags = 0UL;
14098 -+
14099 -+#ifdef CONFIG_PAX_PAGEEXEC
14100 -+ if (elf_phdata->p_flags & PF_PAGEEXEC)
14101 -+ pax_flags |= MF_PAX_PAGEEXEC;
14102 -+#endif
14103 -+
14104 -+#ifdef CONFIG_PAX_SEGMEXEC
14105 -+ if (elf_phdata->p_flags & PF_SEGMEXEC)
14106 -+ pax_flags |= MF_PAX_SEGMEXEC;
14107 -+#endif
14108 -+
14109 -+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
14110 -+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14111 -+ if (nx_enabled)
14112 -+ pax_flags &= ~MF_PAX_SEGMEXEC;
14113 -+ else
14114 -+ pax_flags &= ~MF_PAX_PAGEEXEC;
14115 -+ }
14116 -+#endif
14117 -+
14118 -+#ifdef CONFIG_PAX_EMUTRAMP
14119 -+ if (elf_phdata->p_flags & PF_EMUTRAMP)
14120 -+ pax_flags |= MF_PAX_EMUTRAMP;
14121 -+#endif
14122 -+
14123 -+#ifdef CONFIG_PAX_MPROTECT
14124 -+ if (elf_phdata->p_flags & PF_MPROTECT)
14125 -+ pax_flags |= MF_PAX_MPROTECT;
14126 -+#endif
14127 -+
14128 -+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
14129 -+ if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
14130 -+ pax_flags |= MF_PAX_RANDMMAP;
14131 -+#endif
14132 -+
14133 -+ return pax_flags;
14134 -+}
14135 -+#endif
14136 -+
14137 -+#ifdef CONFIG_PAX_PT_PAX_FLAGS
14138 -+static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
14139 -+{
14140 -+ unsigned long pax_flags = 0UL;
14141 -+
14142 -+#ifdef CONFIG_PAX_PAGEEXEC
14143 -+ if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
14144 -+ pax_flags |= MF_PAX_PAGEEXEC;
14145 -+#endif
14146 -+
14147 -+#ifdef CONFIG_PAX_SEGMEXEC
14148 -+ if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
14149 -+ pax_flags |= MF_PAX_SEGMEXEC;
14150 -+#endif
14151 -+
14152 -+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
14153 -+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14154 -+ if (nx_enabled)
14155 -+ pax_flags &= ~MF_PAX_SEGMEXEC;
14156 -+ else
14157 -+ pax_flags &= ~MF_PAX_PAGEEXEC;
14158 -+ }
14159 -+#endif
14160 -+
14161 -+#ifdef CONFIG_PAX_EMUTRAMP
14162 -+ if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
14163 -+ pax_flags |= MF_PAX_EMUTRAMP;
14164 -+#endif
14165 -+
14166 -+#ifdef CONFIG_PAX_MPROTECT
14167 -+ if (!(elf_phdata->p_flags & PF_NOMPROTECT))
14168 -+ pax_flags |= MF_PAX_MPROTECT;
14169 -+#endif
14170 -+
14171 -+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
14172 -+ if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
14173 -+ pax_flags |= MF_PAX_RANDMMAP;
14174 -+#endif
14175 -+
14176 -+ return pax_flags;
14177 -+}
14178 -+#endif
14179 -+
14180 -+#ifdef CONFIG_PAX_EI_PAX
14181 -+static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
14182 -+{
14183 -+ unsigned long pax_flags = 0UL;
14184 -+
14185 -+#ifdef CONFIG_PAX_PAGEEXEC
14186 -+ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
14187 -+ pax_flags |= MF_PAX_PAGEEXEC;
14188 -+#endif
14189 -+
14190 -+#ifdef CONFIG_PAX_SEGMEXEC
14191 -+ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
14192 -+ pax_flags |= MF_PAX_SEGMEXEC;
14193 -+#endif
14194 -+
14195 -+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
14196 -+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14197 -+ if (nx_enabled)
14198 -+ pax_flags &= ~MF_PAX_SEGMEXEC;
14199 -+ else
14200 -+ pax_flags &= ~MF_PAX_PAGEEXEC;
14201 -+ }
14202 -+#endif
14203 -+
14204 -+#ifdef CONFIG_PAX_EMUTRAMP
14205 -+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
14206 -+ pax_flags |= MF_PAX_EMUTRAMP;
14207 -+#endif
14208 -+
14209 -+#ifdef CONFIG_PAX_MPROTECT
14210 -+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
14211 -+ pax_flags |= MF_PAX_MPROTECT;
14212 -+#endif
14213 -+
14214 -+#ifdef CONFIG_PAX_ASLR
14215 -+ if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
14216 -+ pax_flags |= MF_PAX_RANDMMAP;
14217 -+#endif
14218 -+
14219 -+ return pax_flags;
14220 -+}
14221 -+#endif
14222 -+
14223 -+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
14224 -+static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
14225 -+{
14226 -+ unsigned long pax_flags = 0UL;
14227 -+
14228 -+#ifdef CONFIG_PAX_PT_PAX_FLAGS
14229 -+ unsigned long i;
14230 -+#endif
14231 -+
14232 -+#ifdef CONFIG_PAX_EI_PAX
14233 -+ pax_flags = pax_parse_ei_pax(elf_ex);
14234 -+#endif
14235 -+
14236 -+#ifdef CONFIG_PAX_PT_PAX_FLAGS
14237 -+ for (i = 0UL; i < elf_ex->e_phnum; i++)
14238 -+ if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
14239 -+ if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
14240 -+ ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
14241 -+ ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
14242 -+ ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
14243 -+ ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
14244 -+ return -EINVAL;
14245 -+
14246 -+#ifdef CONFIG_PAX_SOFTMODE
14247 -+ if (pax_softmode)
14248 -+ pax_flags = pax_parse_softmode(&elf_phdata[i]);
14249 -+ else
14250 -+#endif
14251 -+
14252 -+ pax_flags = pax_parse_hardmode(&elf_phdata[i]);
14253 -+ break;
14254 -+ }
14255 -+#endif
14256 -+
14257 -+ if (0 > pax_check_flags(&pax_flags))
14258 -+ return -EINVAL;
14259 -+
14260 -+ current->mm->pax_flags = pax_flags;
14261 -+ return 0;
14262 -+}
14263 -+#endif
14264 -+
14265 - /*
14266 - * These are the functions used to load ELF style executables and shared
14267 - * libraries. There is no binary dependent code anywhere else.
14268 -@@ -543,6 +727,11 @@ static unsigned long randomize_stack_top
14269 - {
14270 - unsigned int random_variable = 0;
14271 -
14272 -+#ifdef CONFIG_PAX_RANDUSTACK
14273 -+ if (randomize_va_space)
14274 -+ return stack_top - current->mm->delta_stack;
14275 -+#endif
14276 -+
14277 - if ((current->flags & PF_RANDOMIZE) &&
14278 - !(current->personality & ADDR_NO_RANDOMIZE)) {
14279 - random_variable = get_random_int() & STACK_RND_MASK;
14280 -@@ -561,7 +750,7 @@ static int load_elf_binary(struct linux_
14281 - unsigned long load_addr = 0, load_bias = 0;
14282 - int load_addr_set = 0;
14283 - char * elf_interpreter = NULL;
14284 -- unsigned long error;
14285 -+ unsigned long error = 0;
14286 - struct elf_phdr *elf_ppnt, *elf_phdata;
14287 - unsigned long elf_bss, elf_brk;
14288 - int elf_exec_fileno;
14289 -@@ -572,11 +761,11 @@ static int load_elf_binary(struct linux_
14290 - unsigned long start_code, end_code, start_data, end_data;
14291 - unsigned long reloc_func_desc = 0;
14292 - int executable_stack = EXSTACK_DEFAULT;
14293 -- unsigned long def_flags = 0;
14294 - struct {
14295 - struct elfhdr elf_ex;
14296 - struct elfhdr interp_elf_ex;
14297 - } *loc;
14298 -+ unsigned long pax_task_size = TASK_SIZE;
14299 -
14300 - loc = kmalloc(sizeof(*loc), GFP_KERNEL);
14301 - if (!loc) {
14302 -@@ -744,11 +933,80 @@ static int load_elf_binary(struct linux_
14303 -
14304 - /* OK, This is the point of no return */
14305 - current->flags &= ~PF_FORKNOEXEC;
14306 -- current->mm->def_flags = def_flags;
14307 -+
14308 -+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
14309 -+ current->mm->pax_flags = 0UL;
14310 -+#endif
14311 -+
14312 -+#ifdef CONFIG_PAX_DLRESOLVE
14313 -+ current->mm->call_dl_resolve = 0UL;
14314 -+#endif
14315 -+
14316 -+#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
14317 -+ current->mm->call_syscall = 0UL;
14318 -+#endif
14319 -+
14320 -+#ifdef CONFIG_PAX_ASLR
14321 -+ current->mm->delta_mmap = 0UL;
14322 -+ current->mm->delta_stack = 0UL;
14323 -+#endif
14324 -+
14325 -+ current->mm->def_flags = 0;
14326 -+
14327 -+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
14328 -+ if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
14329 -+ send_sig(SIGKILL, current, 0);
14330 -+ goto out_free_dentry;
14331 -+ }
14332 -+#endif
14333 -+
14334 -+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
14335 -+ pax_set_initial_flags(bprm);
14336 -+#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
14337 -+ if (pax_set_initial_flags_func)
14338 -+ (pax_set_initial_flags_func)(bprm);
14339 -+#endif
14340 -+
14341 -+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
14342 -+ if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !nx_enabled) {
14343 -+ current->mm->context.user_cs_limit = PAGE_SIZE;
14344 -+ current->mm->def_flags |= VM_PAGEEXEC;
14345 -+ }
14346 -+#endif
14347 -+
14348 -+#ifdef CONFIG_PAX_SEGMEXEC
14349 -+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
14350 -+ current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
14351 -+ current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE;
14352 -+ pax_task_size = SEGMEXEC_TASK_SIZE;
14353 -+ }
14354 -+#endif
14355 -+
14356 -+#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
14357 -+ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14358 -+ set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
14359 -+ put_cpu_no_resched();
14360 -+ }
14361 -+#endif
14362 -+
14363 -+#ifdef CONFIG_PAX_ASLR
14364 -+ if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
14365 -+ current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT;
14366 -+ current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT;
14367 -+ }
14368 -+#endif
14369 -
14370 - /* Do this immediately, since STACK_TOP as used in setup_arg_pages
14371 - may depend on the personality. */
14372 - SET_PERSONALITY(loc->elf_ex, 0);
14373 -+
14374 -+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
14375 -+ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14376 -+ executable_stack = EXSTACK_DISABLE_X;
14377 -+ current->personality &= ~READ_IMPLIES_EXEC;
14378 -+ } else
14379 -+#endif
14380 -+
14381 - if (elf_read_implies_exec(loc->elf_ex, executable_stack))
14382 - current->personality |= READ_IMPLIES_EXEC;
14383 -
14384 -@@ -829,6 +1087,20 @@ static int load_elf_binary(struct linux_
14385 - #else
14386 - load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
14387 - #endif
14388 -+
14389 -+#ifdef CONFIG_PAX_RANDMMAP
14390 -+ /* PaX: randomize base address at the default exe base if requested */
14391 -+ if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) {
14392 -+#ifdef CONFIG_SPARC64
14393 -+ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1);
14394 -+#else
14395 -+ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT;
14396 -+#endif
14397 -+ load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias);
14398 -+ elf_flags |= MAP_FIXED;
14399 -+ }
14400 -+#endif
14401 -+
14402 - }
14403 -
14404 - error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
14405 -@@ -861,9 +1133,9 @@ static int load_elf_binary(struct linux_
14406 - * allowed task size. Note that p_filesz must always be
14407 - * <= p_memsz so it is only necessary to check p_memsz.
14408 - */
14409 -- if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
14410 -- elf_ppnt->p_memsz > TASK_SIZE ||
14411 -- TASK_SIZE - elf_ppnt->p_memsz < k) {
14412 -+ if (k >= pax_task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
14413 -+ elf_ppnt->p_memsz > pax_task_size ||
14414 -+ pax_task_size - elf_ppnt->p_memsz < k) {
14415 - /* set_brk can never work. Avoid overflows. */
14416 - send_sig(SIGKILL, current, 0);
14417 - retval = -EINVAL;
14418 -@@ -891,6 +1163,11 @@ static int load_elf_binary(struct linux_
14419 - start_data += load_bias;
14420 - end_data += load_bias;
14421 -
14422 -+#ifdef CONFIG_PAX_RANDMMAP
14423 -+ if (current->mm->pax_flags & MF_PAX_RANDMMAP)
14424 -+ elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4);
14425 -+#endif
14426 -+
14427 - /* Calling set_brk effectively mmaps the pages that we need
14428 - * for the bss and break sections. We must do this before
14429 - * mapping in the interpreter, to make sure it doesn't wind
14430 -@@ -902,9 +1179,11 @@ static int load_elf_binary(struct linux_
14431 - goto out_free_dentry;
14432 - }
14433 - if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
14434 -- send_sig(SIGSEGV, current, 0);
14435 -- retval = -EFAULT; /* Nobody gets to see this, but.. */
14436 -- goto out_free_dentry;
14437 -+ /*
14438 -+ * This bss-zeroing can fail if the ELF
14439 -+ * file specifies odd protections. So
14440 -+ * we don't check the return value
14441 -+ */
14442 - }
14443 -
14444 - if (elf_interpreter) {
14445 -@@ -1141,8 +1420,10 @@ static int dump_seek(struct file *file,
14446 - unsigned long n = off;
14447 - if (n > PAGE_SIZE)
14448 - n = PAGE_SIZE;
14449 -- if (!dump_write(file, buf, n))
14450 -+ if (!dump_write(file, buf, n)) {
14451 -+ free_page((unsigned long)buf);
14452 - return 0;
14453 -+ }
14454 - off -= n;
14455 - }
14456 - free_page((unsigned long)buf);
14457 -@@ -1154,7 +1435,7 @@ static int dump_seek(struct file *file,
14458 - * Decide what to dump of a segment, part, all or none.
14459 - */
14460 - static unsigned long vma_dump_size(struct vm_area_struct *vma,
14461 -- unsigned long mm_flags)
14462 -+ unsigned long mm_flags, long signr)
14463 - {
14464 - /* The vma can be set up to tell us the answer directly. */
14465 - if (vma->vm_flags & VM_ALWAYSDUMP)
14466 -@@ -1180,7 +1461,7 @@ static unsigned long vma_dump_size(struc
14467 - if (vma->vm_file == NULL)
14468 - return 0;
14469 -
14470 -- if (FILTER(MAPPED_PRIVATE))
14471 -+ if (signr == SIGKILL || FILTER(MAPPED_PRIVATE))
14472 - goto whole;
14473 -
14474 - /*
14475 -@@ -1266,8 +1547,11 @@ static int writenote(struct memelfnote *
14476 - #undef DUMP_WRITE
14477 -
14478 - #define DUMP_WRITE(addr, nr) \
14479 -+ do { \
14480 -+ gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
14481 - if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
14482 -- goto end_coredump;
14483 -+ goto end_coredump; \
14484 -+ } while (0);
14485 - #define DUMP_SEEK(off) \
14486 - if (!dump_seek(file, (off))) \
14487 - goto end_coredump;
14488 -@@ -1973,7 +2257,7 @@ static int elf_core_dump(long signr, str
14489 - phdr.p_offset = offset;
14490 - phdr.p_vaddr = vma->vm_start;
14491 - phdr.p_paddr = 0;
14492 -- phdr.p_filesz = vma_dump_size(vma, mm_flags);
14493 -+ phdr.p_filesz = vma_dump_size(vma, mm_flags, signr);
14494 - phdr.p_memsz = vma->vm_end - vma->vm_start;
14495 - offset += phdr.p_filesz;
14496 - phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
14497 -@@ -2005,7 +2289,7 @@ static int elf_core_dump(long signr, str
14498 - unsigned long addr;
14499 - unsigned long end;
14500 -
14501 -- end = vma->vm_start + vma_dump_size(vma, mm_flags);
14502 -+ end = vma->vm_start + vma_dump_size(vma, mm_flags, signr);
14503 -
14504 - for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
14505 - struct page *page;
14506 -@@ -2025,6 +2309,7 @@ static int elf_core_dump(long signr, str
14507 - flush_cache_page(tmp_vma, addr,
14508 - page_to_pfn(page));
14509 - kaddr = kmap(page);
14510 -+ gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
14511 - if ((size += PAGE_SIZE) > limit ||
14512 - !dump_write(file, kaddr,
14513 - PAGE_SIZE)) {
14514 -diff -urNp linux-2.6.27.6/fs/binfmt_flat.c linux-2.6.27.6/fs/binfmt_flat.c
14515 ---- linux-2.6.27.6/fs/binfmt_flat.c 2008-11-07 12:55:34.000000000 -0500
14516 -+++ linux-2.6.27.6/fs/binfmt_flat.c 2008-11-18 03:38:45.000000000 -0500
14517 -@@ -561,7 +561,9 @@ static int load_flat_file(struct linux_b
14518 - realdatastart = (unsigned long) -ENOMEM;
14519 - printk("Unable to allocate RAM for process data, errno %d\n",
14520 - (int)-realdatastart);
14521 -+ down_write(&current->mm->mmap_sem);
14522 - do_munmap(current->mm, textpos, text_len);
14523 -+ up_write(&current->mm->mmap_sem);
14524 - ret = realdatastart;
14525 - goto err;
14526 - }
14527 -@@ -583,8 +585,10 @@ static int load_flat_file(struct linux_b
14528 - }
14529 - if (result >= (unsigned long)-4096) {
14530 - printk("Unable to read data+bss, errno %d\n", (int)-result);
14531 -+ down_write(&current->mm->mmap_sem);
14532 - do_munmap(current->mm, textpos, text_len);
14533 - do_munmap(current->mm, realdatastart, data_len + extra);
14534 -+ up_write(&current->mm->mmap_sem);
14535 - ret = result;
14536 - goto err;
14537 - }
14538 -@@ -657,8 +661,10 @@ static int load_flat_file(struct linux_b
14539 - }
14540 - if (result >= (unsigned long)-4096) {
14541 - printk("Unable to read code+data+bss, errno %d\n",(int)-result);
14542 -+ down_write(&current->mm->mmap_sem);
14543 - do_munmap(current->mm, textpos, text_len + data_len + extra +
14544 - MAX_SHARED_LIBS * sizeof(unsigned long));
14545 -+ up_write(&current->mm->mmap_sem);
14546 - ret = result;
14547 - goto err;
14548 - }
14549 -diff -urNp linux-2.6.27.6/fs/binfmt_misc.c linux-2.6.27.6/fs/binfmt_misc.c
14550 ---- linux-2.6.27.6/fs/binfmt_misc.c 2008-11-07 12:55:34.000000000 -0500
14551 -+++ linux-2.6.27.6/fs/binfmt_misc.c 2008-11-18 03:38:45.000000000 -0500
14552 -@@ -696,7 +696,7 @@ static int bm_fill_super(struct super_bl
14553 - static struct tree_descr bm_files[] = {
14554 - [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
14555 - [3] = {"register", &bm_register_operations, S_IWUSR},
14556 -- /* last one */ {""}
14557 -+ /* last one */ {"", NULL, 0}
14558 - };
14559 - int err = simple_fill_super(sb, 0x42494e4d, bm_files);
14560 - if (!err)
14561 -diff -urNp linux-2.6.27.6/fs/bio.c linux-2.6.27.6/fs/bio.c
14562 ---- linux-2.6.27.6/fs/bio.c 2008-11-07 12:55:34.000000000 -0500
14563 -+++ linux-2.6.27.6/fs/bio.c 2008-11-18 03:38:45.000000000 -0500
14564 -@@ -507,7 +507,7 @@ static int __bio_copy_iov(struct bio *bi
14565 -
14566 - while (bv_len && iov_idx < iov_count) {
14567 - unsigned int bytes;
14568 -- char *iov_addr;
14569 -+ char __user *iov_addr;
14570 -
14571 - bytes = min_t(unsigned int,
14572 - iov[iov_idx].iov_len - iov_off, bv_len);
14573 -diff -urNp linux-2.6.27.6/fs/buffer.c linux-2.6.27.6/fs/buffer.c
14574 ---- linux-2.6.27.6/fs/buffer.c 2008-11-07 12:55:34.000000000 -0500
14575 -+++ linux-2.6.27.6/fs/buffer.c 2008-11-18 03:38:45.000000000 -0500
14576 -@@ -41,6 +41,7 @@
14577 - #include <linux/bitops.h>
14578 - #include <linux/mpage.h>
14579 - #include <linux/bit_spinlock.h>
14580 -+#include <linux/grsecurity.h>
14581 -
14582 - static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
14583 -
14584 -@@ -2249,6 +2250,7 @@ int generic_cont_expand_simple(struct in
14585 -
14586 - err = -EFBIG;
14587 - limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
14588 -+ gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
14589 - if (limit != RLIM_INFINITY && size > (loff_t)limit) {
14590 - send_sig(SIGXFSZ, current, 0);
14591 - goto out;
14592 -diff -urNp linux-2.6.27.6/fs/cifs/cifs_uniupr.h linux-2.6.27.6/fs/cifs/cifs_uniupr.h
14593 ---- linux-2.6.27.6/fs/cifs/cifs_uniupr.h 2008-11-07 12:55:34.000000000 -0500
14594 -+++ linux-2.6.27.6/fs/cifs/cifs_uniupr.h 2008-11-18 03:38:45.000000000 -0500
14595 -@@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa
14596 - {0x0490, 0x04cc, UniCaseRangeU0490},
14597 - {0x1e00, 0x1ffc, UniCaseRangeU1e00},
14598 - {0xff40, 0xff5a, UniCaseRangeUff40},
14599 -- {0}
14600 -+ {0, 0, NULL}
14601 - };
14602 - #endif
14603 -
14604 -diff -urNp linux-2.6.27.6/fs/cifs/link.c linux-2.6.27.6/fs/cifs/link.c
14605 ---- linux-2.6.27.6/fs/cifs/link.c 2008-11-07 12:55:34.000000000 -0500
14606 -+++ linux-2.6.27.6/fs/cifs/link.c 2008-11-18 03:38:45.000000000 -0500
14607 -@@ -318,7 +318,7 @@ cifs_readlink(struct dentry *direntry, c
14608 -
14609 - void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
14610 - {
14611 -- char *p = nd_get_link(nd);
14612 -+ const char *p = nd_get_link(nd);
14613 - if (!IS_ERR(p))
14614 - kfree(p);
14615 - }
14616 -diff -urNp linux-2.6.27.6/fs/compat.c linux-2.6.27.6/fs/compat.c
14617 ---- linux-2.6.27.6/fs/compat.c 2008-11-07 12:55:34.000000000 -0500
14618 -+++ linux-2.6.27.6/fs/compat.c 2008-11-18 03:38:45.000000000 -0500
14619 -@@ -51,6 +51,7 @@
14620 - #include <linux/poll.h>
14621 - #include <linux/mm.h>
14622 - #include <linux/eventpoll.h>
14623 -+#include <linux/grsecurity.h>
14624 -
14625 - #include <asm/uaccess.h>
14626 - #include <asm/mmu_context.h>
14627 -@@ -1298,14 +1299,12 @@ static int compat_copy_strings(int argc,
14628 - if (!kmapped_page || kpos != (pos & PAGE_MASK)) {
14629 - struct page *page;
14630 -
14631 --#ifdef CONFIG_STACK_GROWSUP
14632 - ret = expand_stack_downwards(bprm->vma, pos);
14633 - if (ret < 0) {
14634 - /* We've exceed the stack rlimit. */
14635 - ret = -E2BIG;
14636 - goto out;
14637 - }
14638 --#endif
14639 - ret = get_user_pages(current, bprm->mm, pos,
14640 - 1, 1, 1, &page, NULL);
14641 - if (ret <= 0) {
14642 -@@ -1351,6 +1350,11 @@ int compat_do_execve(char * filename,
14643 - compat_uptr_t __user *envp,
14644 - struct pt_regs * regs)
14645 - {
14646 -+#ifdef CONFIG_GRKERNSEC
14647 -+ struct file *old_exec_file;
14648 -+ struct acl_subject_label *old_acl;
14649 -+ struct rlimit old_rlim[RLIM_NLIMITS];
14650 -+#endif
14651 - struct linux_binprm *bprm;
14652 - struct file *file;
14653 - int retval;
14654 -@@ -1371,6 +1375,14 @@ int compat_do_execve(char * filename,
14655 - bprm->filename = filename;
14656 - bprm->interp = filename;
14657 -
14658 -+ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
14659 -+ retval = -EAGAIN;
14660 -+ if (gr_handle_nproc())
14661 -+ goto out_file;
14662 -+ retval = -EACCES;
14663 -+ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
14664 -+ goto out_file;
14665 -+
14666 - retval = bprm_mm_init(bprm);
14667 - if (retval)
14668 - goto out_file;
14669 -@@ -1404,8 +1416,36 @@ int compat_do_execve(char * filename,
14670 - if (retval < 0)
14671 - goto out;
14672 -
14673 -+ if (!gr_tpe_allow(file)) {
14674 -+ retval = -EACCES;
14675 -+ goto out;
14676 -+ }
14677 -+
14678 -+ if (gr_check_crash_exec(file)) {
14679 -+ retval = -EACCES;
14680 -+ goto out;
14681 -+ }
14682 -+
14683 -+ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
14684 -+
14685 -+ gr_handle_exec_args(bprm, (char __user * __user *)argv);
14686 -+
14687 -+#ifdef CONFIG_GRKERNSEC
14688 -+ old_acl = current->acl;
14689 -+ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
14690 -+ old_exec_file = current->exec_file;
14691 -+ get_file(file);
14692 -+ current->exec_file = file;
14693 -+#endif
14694 -+
14695 -+ gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
14696 -+
14697 - retval = search_binary_handler(bprm, regs);
14698 - if (retval >= 0) {
14699 -+#ifdef CONFIG_GRKERNSEC
14700 -+ if (old_exec_file)
14701 -+ fput(old_exec_file);
14702 -+#endif
14703 - /* execve success */
14704 - security_bprm_free(bprm);
14705 - acct_update_integrals(current);
14706 -@@ -1413,6 +1453,13 @@ int compat_do_execve(char * filename,
14707 - return retval;
14708 - }
14709 -
14710 -+#ifdef CONFIG_GRKERNSEC
14711 -+ current->acl = old_acl;
14712 -+ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
14713 -+ fput(current->exec_file);
14714 -+ current->exec_file = old_exec_file;
14715 -+#endif
14716 -+
14717 - out:
14718 - if (bprm->security)
14719 - security_bprm_free(bprm);
14720 -diff -urNp linux-2.6.27.6/fs/compat_ioctl.c linux-2.6.27.6/fs/compat_ioctl.c
14721 ---- linux-2.6.27.6/fs/compat_ioctl.c 2008-11-07 12:55:34.000000000 -0500
14722 -+++ linux-2.6.27.6/fs/compat_ioctl.c 2008-11-18 03:38:45.000000000 -0500
14723 -@@ -1831,15 +1831,15 @@ struct ioctl_trans {
14724 - };
14725 -
14726 - #define HANDLE_IOCTL(cmd,handler) \
14727 -- { (cmd), (ioctl_trans_handler_t)(handler) },
14728 -+ { (cmd), (ioctl_trans_handler_t)(handler), NULL },
14729 -
14730 - /* pointer to compatible structure or no argument */
14731 - #define COMPATIBLE_IOCTL(cmd) \
14732 -- { (cmd), do_ioctl32_pointer },
14733 -+ { (cmd), do_ioctl32_pointer, NULL },
14734 -
14735 - /* argument is an unsigned long integer, not a pointer */
14736 - #define ULONG_IOCTL(cmd) \
14737 -- { (cmd), (ioctl_trans_handler_t)sys_ioctl },
14738 -+ { (cmd), (ioctl_trans_handler_t)sys_ioctl, NULL },
14739 -
14740 - /* ioctl should not be warned about even if it's not implemented.
14741 - Valid reasons to use this:
14742 -diff -urNp linux-2.6.27.6/fs/debugfs/inode.c linux-2.6.27.6/fs/debugfs/inode.c
14743 ---- linux-2.6.27.6/fs/debugfs/inode.c 2008-11-07 12:55:34.000000000 -0500
14744 -+++ linux-2.6.27.6/fs/debugfs/inode.c 2008-11-18 03:38:45.000000000 -0500
14745 -@@ -121,7 +121,7 @@ static inline int debugfs_positive(struc
14746 -
14747 - static int debug_fill_super(struct super_block *sb, void *data, int silent)
14748 - {
14749 -- static struct tree_descr debug_files[] = {{""}};
14750 -+ static struct tree_descr debug_files[] = {{"", NULL, 0}};
14751 -
14752 - return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
14753 - }
14754 -diff -urNp linux-2.6.27.6/fs/exec.c linux-2.6.27.6/fs/exec.c
14755 ---- linux-2.6.27.6/fs/exec.c 2008-11-07 12:55:34.000000000 -0500
14756 -+++ linux-2.6.27.6/fs/exec.c 2008-11-18 03:38:45.000000000 -0500
14757 -@@ -50,6 +50,13 @@
14758 - #include <linux/cn_proc.h>
14759 - #include <linux/audit.h>
14760 - #include <linux/tracehook.h>
14761 -+#include <linux/random.h>
14762 -+#include <linux/grsecurity.h>
14763 -+
14764 -+#ifdef CONFIG_PAX_REFCOUNT
14765 -+#include <linux/kallsyms.h>
14766 -+#include <linux/kdebug.h>
14767 -+#endif
14768 -
14769 - #include <asm/uaccess.h>
14770 - #include <asm/mmu_context.h>
14771 -@@ -64,6 +71,11 @@
14772 - #include <linux/a.out.h>
14773 - #endif
14774 -
14775 -+#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
14776 -+void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
14777 -+EXPORT_SYMBOL(pax_set_initial_flags_func);
14778 -+#endif
14779 -+
14780 - int core_uses_pid;
14781 - char core_pattern[CORENAME_MAX_SIZE] = "core";
14782 - int suid_dumpable = 0;
14783 -@@ -172,18 +184,10 @@ static struct page *get_arg_page(struct
14784 - int write)
14785 - {
14786 - struct page *page;
14787 -- int ret;
14788 -
14789 --#ifdef CONFIG_STACK_GROWSUP
14790 -- if (write) {
14791 -- ret = expand_stack_downwards(bprm->vma, pos);
14792 -- if (ret < 0)
14793 -- return NULL;
14794 -- }
14795 --#endif
14796 -- ret = get_user_pages(current, bprm->mm, pos,
14797 -- 1, write, 1, &page, NULL);
14798 -- if (ret <= 0)
14799 -+ if (0 > expand_stack_downwards(bprm->vma, pos))
14800 -+ return NULL;
14801 -+ if (0 >= get_user_pages(current, bprm->mm, pos, 1, write, 1, &page, NULL))
14802 - return NULL;
14803 -
14804 - if (write) {
14805 -@@ -256,6 +260,11 @@ static int __bprm_mm_init(struct linux_b
14806 - vma->vm_start = vma->vm_end - PAGE_SIZE;
14807 -
14808 - vma->vm_flags = VM_STACK_FLAGS;
14809 -+
14810 -+#ifdef CONFIG_PAX_SEGMEXEC
14811 -+ vma->vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
14812 -+#endif
14813 -+
14814 - vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
14815 - err = insert_vm_struct(mm, vma);
14816 - if (err) {
14817 -@@ -268,6 +277,11 @@ static int __bprm_mm_init(struct linux_b
14818 -
14819 - bprm->p = vma->vm_end - sizeof(void *);
14820 -
14821 -+#ifdef CONFIG_PAX_RANDUSTACK
14822 -+ if (randomize_va_space)
14823 -+ bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK;
14824 -+#endif
14825 -+
14826 - return 0;
14827 -
14828 - err:
14829 -@@ -391,7 +405,7 @@ static int count(char __user * __user *
14830 - if (!p)
14831 - break;
14832 - argv++;
14833 -- if(++i > max)
14834 -+ if (++i > max)
14835 - return -E2BIG;
14836 - cond_resched();
14837 - }
14838 -@@ -531,6 +545,10 @@ static int shift_arg_pages(struct vm_are
14839 - if (vma != find_vma(mm, new_start))
14840 - return -EFAULT;
14841 -
14842 -+#ifdef CONFIG_PAX_SEGMEXEC
14843 -+ BUG_ON(pax_find_mirror_vma(vma));
14844 -+#endif
14845 -+
14846 - /*
14847 - * cover the whole range: [new_start, old_end)
14848 - */
14849 -@@ -619,6 +637,14 @@ int setup_arg_pages(struct linux_binprm
14850 - bprm->exec -= stack_shift;
14851 -
14852 - down_write(&mm->mmap_sem);
14853 -+
14854 -+ /* Move stack pages down in memory. */
14855 -+ if (stack_shift) {
14856 -+ ret = shift_arg_pages(vma, stack_shift);
14857 -+ if (ret)
14858 -+ goto out_unlock;
14859 -+ }
14860 -+
14861 - vm_flags = VM_STACK_FLAGS;
14862 -
14863 - /*
14864 -@@ -632,21 +658,24 @@ int setup_arg_pages(struct linux_binprm
14865 - vm_flags &= ~VM_EXEC;
14866 - vm_flags |= mm->def_flags;
14867 -
14868 -+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
14869 -+ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14870 -+ vm_flags &= ~VM_EXEC;
14871 -+
14872 -+#ifdef CONFIG_PAX_MPROTECT
14873 -+ if (mm->pax_flags & MF_PAX_MPROTECT)
14874 -+ vm_flags &= ~VM_MAYEXEC;
14875 -+#endif
14876 -+
14877 -+ }
14878 -+#endif
14879 -+
14880 - ret = mprotect_fixup(vma, &prev, vma->vm_start, vma->vm_end,
14881 - vm_flags);
14882 - if (ret)
14883 - goto out_unlock;
14884 - BUG_ON(prev != vma);
14885 -
14886 -- /* Move stack pages down in memory. */
14887 -- if (stack_shift) {
14888 -- ret = shift_arg_pages(vma, stack_shift);
14889 -- if (ret) {
14890 -- up_write(&mm->mmap_sem);
14891 -- return ret;
14892 -- }
14893 -- }
14894 --
14895 - #ifdef CONFIG_STACK_GROWSUP
14896 - stack_base = vma->vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
14897 - #else
14898 -@@ -658,7 +687,7 @@ int setup_arg_pages(struct linux_binprm
14899 -
14900 - out_unlock:
14901 - up_write(&mm->mmap_sem);
14902 -- return 0;
14903 -+ return ret;
14904 - }
14905 - EXPORT_SYMBOL(setup_arg_pages);
14906 -
14907 -@@ -1278,6 +1307,11 @@ int do_execve(char * filename,
14908 - char __user *__user *envp,
14909 - struct pt_regs * regs)
14910 - {
14911 -+#ifdef CONFIG_GRKERNSEC
14912 -+ struct file *old_exec_file;
14913 -+ struct acl_subject_label *old_acl;
14914 -+ struct rlimit old_rlim[RLIM_NLIMITS];
14915 -+#endif
14916 - struct linux_binprm *bprm;
14917 - struct file *file;
14918 - struct files_struct *displaced;
14919 -@@ -1297,6 +1331,20 @@ int do_execve(char * filename,
14920 - if (IS_ERR(file))
14921 - goto out_kfree;
14922 -
14923 -+ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
14924 -+
14925 -+ if (gr_handle_nproc()) {
14926 -+ allow_write_access(file);
14927 -+ fput(file);
14928 -+ return -EAGAIN;
14929 -+ }
14930 -+
14931 -+ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
14932 -+ allow_write_access(file);
14933 -+ fput(file);
14934 -+ return -EACCES;
14935 -+ }
14936 -+
14937 - sched_exec();
14938 -
14939 - bprm->file = file;
14940 -@@ -1336,9 +1384,39 @@ int do_execve(char * filename,
14941 - if (retval < 0)
14942 - goto out;
14943 -
14944 -+ if (!gr_tpe_allow(file)) {
14945 -+ retval = -EACCES;
14946 -+ goto out;
14947 -+ }
14948 -+
14949 -+ if (gr_check_crash_exec(file)) {
14950 -+ retval = -EACCES;
14951 -+ goto out;
14952 -+ }
14953 -+
14954 -+ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
14955 -+
14956 -+ gr_handle_exec_args(bprm, argv);
14957 -+
14958 -+#ifdef CONFIG_GRKERNSEC
14959 -+ old_acl = current->acl;
14960 -+ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
14961 -+ old_exec_file = current->exec_file;
14962 -+ get_file(file);
14963 -+ current->exec_file = file;
14964 -+#endif
14965 -+
14966 -+ retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
14967 -+ if (retval < 0)
14968 -+ goto out_fail;
14969 -+
14970 - current->flags &= ~PF_KTHREAD;
14971 - retval = search_binary_handler(bprm,regs);
14972 - if (retval >= 0) {
14973 -+#ifdef CONFIG_GRKERNSEC
14974 -+ if (old_exec_file)
14975 -+ fput(old_exec_file);
14976 -+#endif
14977 - /* execve success */
14978 - security_bprm_free(bprm);
14979 - acct_update_integrals(current);
14980 -@@ -1348,6 +1426,14 @@ int do_execve(char * filename,
14981 - return retval;
14982 - }
14983 -
14984 -+out_fail:
14985 -+#ifdef CONFIG_GRKERNSEC
14986 -+ current->acl = old_acl;
14987 -+ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
14988 -+ fput(current->exec_file);
14989 -+ current->exec_file = old_exec_file;
14990 -+#endif
14991 -+
14992 - out:
14993 - if (bprm->security)
14994 - security_bprm_free(bprm);
14995 -@@ -1511,6 +1597,125 @@ out:
14996 - return ispipe;
14997 - }
14998 -
14999 -+int pax_check_flags(unsigned long *flags)
15000 -+{
15001 -+ int retval = 0;
15002 -+
15003 -+#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC)
15004 -+ if (*flags & MF_PAX_SEGMEXEC)
15005 -+ {
15006 -+ *flags &= ~MF_PAX_SEGMEXEC;
15007 -+ retval = -EINVAL;
15008 -+ }
15009 -+#endif
15010 -+
15011 -+ if ((*flags & MF_PAX_PAGEEXEC)
15012 -+
15013 -+#ifdef CONFIG_PAX_PAGEEXEC
15014 -+ && (*flags & MF_PAX_SEGMEXEC)
15015 -+#endif
15016 -+
15017 -+ )
15018 -+ {
15019 -+ *flags &= ~MF_PAX_PAGEEXEC;
15020 -+ retval = -EINVAL;
15021 -+ }
15022 -+
15023 -+ if ((*flags & MF_PAX_MPROTECT)
15024 -+
15025 -+#ifdef CONFIG_PAX_MPROTECT
15026 -+ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
15027 -+#endif
15028 -+
15029 -+ )
15030 -+ {
15031 -+ *flags &= ~MF_PAX_MPROTECT;
15032 -+ retval = -EINVAL;
15033 -+ }
15034 -+
15035 -+ if ((*flags & MF_PAX_EMUTRAMP)
15036 -+
15037 -+#ifdef CONFIG_PAX_EMUTRAMP
15038 -+ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
15039 -+#endif
15040 -+
15041 -+ )
15042 -+ {
15043 -+ *flags &= ~MF_PAX_EMUTRAMP;
15044 -+ retval = -EINVAL;
15045 -+ }
15046 -+
15047 -+ return retval;
15048 -+}
15049 -+
15050 -+EXPORT_SYMBOL(pax_check_flags);
15051 -+
15052 -+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
15053 -+void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
15054 -+{
15055 -+ struct task_struct *tsk = current;
15056 -+ struct mm_struct *mm = current->mm;
15057 -+ char *buffer_exec = (char *)__get_free_page(GFP_KERNEL);
15058 -+ char *buffer_fault = (char *)__get_free_page(GFP_KERNEL);
15059 -+ char *path_exec = NULL;
15060 -+ char *path_fault = NULL;
15061 -+ unsigned long start = 0UL, end = 0UL, offset = 0UL;
15062 -+
15063 -+ if (buffer_exec && buffer_fault) {
15064 -+ struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL;
15065 -+
15066 -+ down_read(&mm->mmap_sem);
15067 -+ vma = mm->mmap;
15068 -+ while (vma && (!vma_exec || !vma_fault)) {
15069 -+ if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
15070 -+ vma_exec = vma;
15071 -+ if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
15072 -+ vma_fault = vma;
15073 -+ vma = vma->vm_next;
15074 -+ }
15075 -+ if (vma_exec) {
15076 -+ path_exec = d_path(&vma_exec->vm_file->f_path, buffer_exec, PAGE_SIZE);
15077 -+ if (IS_ERR(path_exec))
15078 -+ path_exec = "<path too long>";
15079 -+ }
15080 -+ if (vma_fault) {
15081 -+ start = vma_fault->vm_start;
15082 -+ end = vma_fault->vm_end;
15083 -+ offset = vma_fault->vm_pgoff << PAGE_SHIFT;
15084 -+ if (vma_fault->vm_file) {
15085 -+ path_fault = d_path(&vma_fault->vm_file->f_path, buffer_fault, PAGE_SIZE);
15086 -+ if (IS_ERR(path_fault))
15087 -+ path_fault = "<path too long>";
15088 -+ } else
15089 -+ path_fault = "<anonymous mapping>";
15090 -+ }
15091 -+ up_read(&mm->mmap_sem);
15092 -+ }
15093 -+ if (tsk->signal->curr_ip)
15094 -+ 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);
15095 -+ else
15096 -+ printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
15097 -+ printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
15098 -+ "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
15099 -+ tsk->uid, tsk->euid, pc, sp);
15100 -+ free_page((unsigned long)buffer_exec);
15101 -+ free_page((unsigned long)buffer_fault);
15102 -+ pax_report_insns(pc, sp);
15103 -+ do_coredump(SIGKILL, SIGKILL, regs);
15104 -+}
15105 -+#endif
15106 -+
15107 -+#ifdef CONFIG_PAX_REFCOUNT
15108 -+void pax_report_refcount_overflow(struct pt_regs *regs)
15109 -+{
15110 -+ printk(KERN_ERR "PAX: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n",
15111 -+ current->comm, task_pid_nr(current), current->uid, current->euid);
15112 -+ print_symbol(KERN_ERR "PAX: refcount overflow occured at: %s\n", instruction_pointer(regs));
15113 -+ show_registers(regs);
15114 -+ force_sig_specific(SIGKILL, current);
15115 -+}
15116 -+#endif
15117 -+
15118 - static int zap_process(struct task_struct *start)
15119 - {
15120 - struct task_struct *t;
15121 -@@ -1757,6 +1962,10 @@ int do_coredump(long signr, int exit_cod
15122 - */
15123 - clear_thread_flag(TIF_SIGPENDING);
15124 -
15125 -+ if (signr == SIGKILL || signr == SIGILL)
15126 -+ gr_handle_brute_attach(current);
15127 -+ gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
15128 -+
15129 - /*
15130 - * lock_kernel() because format_corename() is controlled by sysctl, which
15131 - * uses lock_kernel()
15132 -@@ -1777,6 +1986,8 @@ int do_coredump(long signr, int exit_cod
15133 -
15134 - if (ispipe) {
15135 - helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc);
15136 -+ if (!helper_argv)
15137 -+ goto fail_unlock;
15138 - /* Terminate the string before the first option */
15139 - delimit = strchr(corename, ' ');
15140 - if (delimit)
15141 -diff -urNp linux-2.6.27.6/fs/ext2/balloc.c linux-2.6.27.6/fs/ext2/balloc.c
15142 ---- linux-2.6.27.6/fs/ext2/balloc.c 2008-11-07 12:55:34.000000000 -0500
15143 -+++ linux-2.6.27.6/fs/ext2/balloc.c 2008-11-18 03:38:45.000000000 -0500
15144 -@@ -1192,7 +1192,7 @@ static int ext2_has_free_blocks(struct e
15145 -
15146 - free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
15147 - root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
15148 -- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
15149 -+ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
15150 - sbi->s_resuid != current->fsuid &&
15151 - (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
15152 - return 0;
15153 -diff -urNp linux-2.6.27.6/fs/ext3/balloc.c linux-2.6.27.6/fs/ext3/balloc.c
15154 ---- linux-2.6.27.6/fs/ext3/balloc.c 2008-11-07 12:55:34.000000000 -0500
15155 -+++ linux-2.6.27.6/fs/ext3/balloc.c 2008-11-18 03:38:45.000000000 -0500
15156 -@@ -1421,7 +1421,7 @@ static int ext3_has_free_blocks(struct e
15157 -
15158 - free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
15159 - root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
15160 -- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
15161 -+ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
15162 - sbi->s_resuid != current->fsuid &&
15163 - (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
15164 - return 0;
15165 -diff -urNp linux-2.6.27.6/fs/ext3/namei.c linux-2.6.27.6/fs/ext3/namei.c
15166 ---- linux-2.6.27.6/fs/ext3/namei.c 2008-11-07 12:55:34.000000000 -0500
15167 -+++ linux-2.6.27.6/fs/ext3/namei.c 2008-11-18 03:38:45.000000000 -0500
15168 -@@ -1173,9 +1173,9 @@ static struct ext3_dir_entry_2 *do_split
15169 - u32 hash2;
15170 - struct dx_map_entry *map;
15171 - char *data1 = (*bh)->b_data, *data2;
15172 -- unsigned split, move, size, i;
15173 -+ unsigned split, move, size;
15174 - struct ext3_dir_entry_2 *de = NULL, *de2;
15175 -- int err = 0;
15176 -+ int i, err = 0;
15177 -
15178 - bh2 = ext3_append (handle, dir, &newblock, &err);
15179 - if (!(bh2)) {
15180 -diff -urNp linux-2.6.27.6/fs/ext3/xattr.c linux-2.6.27.6/fs/ext3/xattr.c
15181 ---- linux-2.6.27.6/fs/ext3/xattr.c 2008-11-07 12:55:34.000000000 -0500
15182 -+++ linux-2.6.27.6/fs/ext3/xattr.c 2008-11-18 03:38:45.000000000 -0500
15183 -@@ -89,8 +89,8 @@
15184 - printk("\n"); \
15185 - } while (0)
15186 - #else
15187 --# define ea_idebug(f...)
15188 --# define ea_bdebug(f...)
15189 -+# define ea_idebug(f...) do {} while (0)
15190 -+# define ea_bdebug(f...) do {} while (0)
15191 - #endif
15192 -
15193 - static void ext3_xattr_cache_insert(struct buffer_head *);
15194 -diff -urNp linux-2.6.27.6/fs/ext4/balloc.c linux-2.6.27.6/fs/ext4/balloc.c
15195 ---- linux-2.6.27.6/fs/ext4/balloc.c 2008-11-07 12:55:34.000000000 -0500
15196 -+++ linux-2.6.27.6/fs/ext4/balloc.c 2008-11-18 03:38:45.000000000 -0500
15197 -@@ -1617,7 +1617,7 @@ ext4_fsblk_t ext4_has_free_blocks(struct
15198 -
15199 - free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
15200 -
15201 -- if (!capable(CAP_SYS_RESOURCE) &&
15202 -+ if (!capable_nolog(CAP_SYS_RESOURCE) &&
15203 - sbi->s_resuid != current->fsuid &&
15204 - (sbi->s_resgid == 0 || !in_group_p(sbi->s_resgid)))
15205 - root_blocks = ext4_r_blocks_count(sbi->s_es);
15206 -diff -urNp linux-2.6.27.6/fs/ext4/namei.c linux-2.6.27.6/fs/ext4/namei.c
15207 ---- linux-2.6.27.6/fs/ext4/namei.c 2008-11-07 12:55:34.000000000 -0500
15208 -+++ linux-2.6.27.6/fs/ext4/namei.c 2008-11-18 03:38:45.000000000 -0500
15209 -@@ -1176,9 +1176,9 @@ static struct ext4_dir_entry_2 *do_split
15210 - u32 hash2;
15211 - struct dx_map_entry *map;
15212 - char *data1 = (*bh)->b_data, *data2;
15213 -- unsigned split, move, size, i;
15214 -+ unsigned split, move, size;
15215 - struct ext4_dir_entry_2 *de = NULL, *de2;
15216 -- int err = 0;
15217 -+ int i, err = 0;
15218 -
15219 - bh2 = ext4_append (handle, dir, &newblock, &err);
15220 - if (!(bh2)) {
15221 -diff -urNp linux-2.6.27.6/fs/fcntl.c linux-2.6.27.6/fs/fcntl.c
15222 ---- linux-2.6.27.6/fs/fcntl.c 2008-11-07 12:55:34.000000000 -0500
15223 -+++ linux-2.6.27.6/fs/fcntl.c 2008-11-18 03:38:45.000000000 -0500
15224 -@@ -19,6 +19,7 @@
15225 - #include <linux/signal.h>
15226 - #include <linux/rcupdate.h>
15227 - #include <linux/pid_namespace.h>
15228 -+#include <linux/grsecurity.h>
15229 -
15230 - #include <asm/poll.h>
15231 - #include <asm/siginfo.h>
15232 -@@ -259,6 +260,7 @@ static long do_fcntl(int fd, unsigned in
15233 - switch (cmd) {
15234 - case F_DUPFD:
15235 - case F_DUPFD_CLOEXEC:
15236 -+ gr_learn_resource(current, RLIMIT_NOFILE, arg, 0);
15237 - if (arg >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
15238 - break;
15239 - err = alloc_fd(arg, cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0);
15240 -@@ -403,7 +405,8 @@ static inline int sigio_perm(struct task
15241 - return (((fown->euid == 0) ||
15242 - (fown->euid == p->suid) || (fown->euid == p->uid) ||
15243 - (fown->uid == p->suid) || (fown->uid == p->uid)) &&
15244 -- !security_file_send_sigiotask(p, fown, sig));
15245 -+ !security_file_send_sigiotask(p, fown, sig) &&
15246 -+ !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
15247 - }
15248 -
15249 - static void send_sigio_to_task(struct task_struct *p,
15250 -diff -urNp linux-2.6.27.6/fs/file.c linux-2.6.27.6/fs/file.c
15251 ---- linux-2.6.27.6/fs/file.c 2008-11-07 12:55:34.000000000 -0500
15252 -+++ linux-2.6.27.6/fs/file.c 2008-11-18 03:38:45.000000000 -0500
15253 -@@ -19,6 +19,7 @@
15254 - #include <linux/spinlock.h>
15255 - #include <linux/rcupdate.h>
15256 - #include <linux/workqueue.h>
15257 -+#include <linux/grsecurity.h>
15258 -
15259 - struct fdtable_defer {
15260 - spinlock_t lock;
15261 -@@ -256,6 +257,8 @@ int expand_files(struct files_struct *fi
15262 - * N.B. For clone tasks sharing a files structure, this test
15263 - * will limit the total number of files that can be opened.
15264 - */
15265 -+
15266 -+ gr_learn_resource(current, RLIMIT_NOFILE, nr, 0);
15267 - if (nr >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
15268 - return -EMFILE;
15269 -
15270 -diff -urNp linux-2.6.27.6/fs/fuse/control.c linux-2.6.27.6/fs/fuse/control.c
15271 ---- linux-2.6.27.6/fs/fuse/control.c 2008-11-07 12:55:34.000000000 -0500
15272 -+++ linux-2.6.27.6/fs/fuse/control.c 2008-11-18 03:38:45.000000000 -0500
15273 -@@ -159,7 +159,7 @@ void fuse_ctl_remove_conn(struct fuse_co
15274 -
15275 - static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
15276 - {
15277 -- struct tree_descr empty_descr = {""};
15278 -+ struct tree_descr empty_descr = {"", NULL, 0};
15279 - struct fuse_conn *fc;
15280 - int err;
15281 -
15282 -diff -urNp linux-2.6.27.6/fs/fuse/dir.c linux-2.6.27.6/fs/fuse/dir.c
15283 ---- linux-2.6.27.6/fs/fuse/dir.c 2008-11-07 12:55:34.000000000 -0500
15284 -+++ linux-2.6.27.6/fs/fuse/dir.c 2008-11-18 03:38:45.000000000 -0500
15285 -@@ -1072,7 +1072,7 @@ static char *read_link(struct dentry *de
15286 - return link;
15287 - }
15288 -
15289 --static void free_link(char *link)
15290 -+static void free_link(const char *link)
15291 - {
15292 - if (!IS_ERR(link))
15293 - free_page((unsigned long) link);
15294 -diff -urNp linux-2.6.27.6/fs/hfs/inode.c linux-2.6.27.6/fs/hfs/inode.c
15295 ---- linux-2.6.27.6/fs/hfs/inode.c 2008-11-07 12:55:34.000000000 -0500
15296 -+++ linux-2.6.27.6/fs/hfs/inode.c 2008-11-18 03:38:45.000000000 -0500
15297 -@@ -419,7 +419,7 @@ int hfs_write_inode(struct inode *inode,
15298 -
15299 - if (S_ISDIR(main_inode->i_mode)) {
15300 - if (fd.entrylength < sizeof(struct hfs_cat_dir))
15301 -- /* panic? */;
15302 -+ {/* panic? */}
15303 - hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
15304 - sizeof(struct hfs_cat_dir));
15305 - if (rec.type != HFS_CDR_DIR ||
15306 -@@ -440,7 +440,7 @@ int hfs_write_inode(struct inode *inode,
15307 - sizeof(struct hfs_cat_file));
15308 - } else {
15309 - if (fd.entrylength < sizeof(struct hfs_cat_file))
15310 -- /* panic? */;
15311 -+ {/* panic? */}
15312 - hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
15313 - sizeof(struct hfs_cat_file));
15314 - if (rec.type != HFS_CDR_FIL ||
15315 -diff -urNp linux-2.6.27.6/fs/hfsplus/inode.c linux-2.6.27.6/fs/hfsplus/inode.c
15316 ---- linux-2.6.27.6/fs/hfsplus/inode.c 2008-11-07 12:55:34.000000000 -0500
15317 -+++ linux-2.6.27.6/fs/hfsplus/inode.c 2008-11-18 03:38:45.000000000 -0500
15318 -@@ -417,7 +417,7 @@ int hfsplus_cat_read_inode(struct inode
15319 - struct hfsplus_cat_folder *folder = &entry.folder;
15320 -
15321 - if (fd->entrylength < sizeof(struct hfsplus_cat_folder))
15322 -- /* panic? */;
15323 -+ {/* panic? */}
15324 - hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
15325 - sizeof(struct hfsplus_cat_folder));
15326 - hfsplus_get_perms(inode, &folder->permissions, 1);
15327 -@@ -434,7 +434,7 @@ int hfsplus_cat_read_inode(struct inode
15328 - struct hfsplus_cat_file *file = &entry.file;
15329 -
15330 - if (fd->entrylength < sizeof(struct hfsplus_cat_file))
15331 -- /* panic? */;
15332 -+ {/* panic? */}
15333 - hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
15334 - sizeof(struct hfsplus_cat_file));
15335 -
15336 -@@ -490,7 +490,7 @@ int hfsplus_cat_write_inode(struct inode
15337 - struct hfsplus_cat_folder *folder = &entry.folder;
15338 -
15339 - if (fd.entrylength < sizeof(struct hfsplus_cat_folder))
15340 -- /* panic? */;
15341 -+ {/* panic? */}
15342 - hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
15343 - sizeof(struct hfsplus_cat_folder));
15344 - /* simple node checks? */
15345 -@@ -512,7 +512,7 @@ int hfsplus_cat_write_inode(struct inode
15346 - struct hfsplus_cat_file *file = &entry.file;
15347 -
15348 - if (fd.entrylength < sizeof(struct hfsplus_cat_file))
15349 -- /* panic? */;
15350 -+ {/* panic? */}
15351 - hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
15352 - sizeof(struct hfsplus_cat_file));
15353 - hfsplus_inode_write_fork(inode, &file->data_fork);
15354 -diff -urNp linux-2.6.27.6/fs/jffs2/debug.h linux-2.6.27.6/fs/jffs2/debug.h
15355 ---- linux-2.6.27.6/fs/jffs2/debug.h 2008-11-07 12:55:34.000000000 -0500
15356 -+++ linux-2.6.27.6/fs/jffs2/debug.h 2008-11-18 03:38:45.000000000 -0500
15357 -@@ -52,13 +52,13 @@
15358 - #if CONFIG_JFFS2_FS_DEBUG > 0
15359 - #define D1(x) x
15360 - #else
15361 --#define D1(x)
15362 -+#define D1(x) do {} while (0);
15363 - #endif
15364 -
15365 - #if CONFIG_JFFS2_FS_DEBUG > 1
15366 - #define D2(x) x
15367 - #else
15368 --#define D2(x)
15369 -+#define D2(x) do {} while (0);
15370 - #endif
15371 -
15372 - /* The prefixes of JFFS2 messages */
15373 -@@ -114,73 +114,73 @@
15374 - #ifdef JFFS2_DBG_READINODE_MESSAGES
15375 - #define dbg_readinode(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15376 - #else
15377 --#define dbg_readinode(fmt, ...)
15378 -+#define dbg_readinode(fmt, ...) do {} while (0)
15379 - #endif
15380 - #ifdef JFFS2_DBG_READINODE2_MESSAGES
15381 - #define dbg_readinode2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15382 - #else
15383 --#define dbg_readinode2(fmt, ...)
15384 -+#define dbg_readinode2(fmt, ...) do {} while (0)
15385 - #endif
15386 -
15387 - /* Fragtree build debugging messages */
15388 - #ifdef JFFS2_DBG_FRAGTREE_MESSAGES
15389 - #define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15390 - #else
15391 --#define dbg_fragtree(fmt, ...)
15392 -+#define dbg_fragtree(fmt, ...) do {} while (0)
15393 - #endif
15394 - #ifdef JFFS2_DBG_FRAGTREE2_MESSAGES
15395 - #define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15396 - #else
15397 --#define dbg_fragtree2(fmt, ...)
15398 -+#define dbg_fragtree2(fmt, ...) do {} while (0)
15399 - #endif
15400 -
15401 - /* Directory entry list manilulation debugging messages */
15402 - #ifdef JFFS2_DBG_DENTLIST_MESSAGES
15403 - #define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15404 - #else
15405 --#define dbg_dentlist(fmt, ...)
15406 -+#define dbg_dentlist(fmt, ...) do {} while (0)
15407 - #endif
15408 -
15409 - /* Print the messages about manipulating node_refs */
15410 - #ifdef JFFS2_DBG_NODEREF_MESSAGES
15411 - #define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15412 - #else
15413 --#define dbg_noderef(fmt, ...)
15414 -+#define dbg_noderef(fmt, ...) do {} while (0)
15415 - #endif
15416 -
15417 - /* Manipulations with the list of inodes (JFFS2 inocache) */
15418 - #ifdef JFFS2_DBG_INOCACHE_MESSAGES
15419 - #define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15420 - #else
15421 --#define dbg_inocache(fmt, ...)
15422 -+#define dbg_inocache(fmt, ...) do {} while (0)
15423 - #endif
15424 -
15425 - /* Summary debugging messages */
15426 - #ifdef JFFS2_DBG_SUMMARY_MESSAGES
15427 - #define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15428 - #else
15429 --#define dbg_summary(fmt, ...)
15430 -+#define dbg_summary(fmt, ...) do {} while (0)
15431 - #endif
15432 -
15433 - /* File system build messages */
15434 - #ifdef JFFS2_DBG_FSBUILD_MESSAGES
15435 - #define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15436 - #else
15437 --#define dbg_fsbuild(fmt, ...)
15438 -+#define dbg_fsbuild(fmt, ...) do {} while (0)
15439 - #endif
15440 -
15441 - /* Watch the object allocations */
15442 - #ifdef JFFS2_DBG_MEMALLOC_MESSAGES
15443 - #define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15444 - #else
15445 --#define dbg_memalloc(fmt, ...)
15446 -+#define dbg_memalloc(fmt, ...) do {} while (0)
15447 - #endif
15448 -
15449 - /* Watch the XATTR subsystem */
15450 - #ifdef JFFS2_DBG_XATTR_MESSAGES
15451 - #define dbg_xattr(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15452 - #else
15453 --#define dbg_xattr(fmt, ...)
15454 -+#define dbg_xattr(fmt, ...) do {} while (0)
15455 - #endif
15456 -
15457 - /* "Sanity" checks */
15458 -diff -urNp linux-2.6.27.6/fs/jffs2/erase.c linux-2.6.27.6/fs/jffs2/erase.c
15459 ---- linux-2.6.27.6/fs/jffs2/erase.c 2008-11-07 12:55:34.000000000 -0500
15460 -+++ linux-2.6.27.6/fs/jffs2/erase.c 2008-11-18 03:38:45.000000000 -0500
15461 -@@ -431,7 +431,8 @@ static void jffs2_mark_erased_block(stru
15462 - struct jffs2_unknown_node marker = {
15463 - .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
15464 - .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
15465 -- .totlen = cpu_to_je32(c->cleanmarker_size)
15466 -+ .totlen = cpu_to_je32(c->cleanmarker_size),
15467 -+ .hdr_crc = cpu_to_je32(0)
15468 - };
15469 -
15470 - jffs2_prealloc_raw_node_refs(c, jeb, 1);
15471 -diff -urNp linux-2.6.27.6/fs/jffs2/summary.h linux-2.6.27.6/fs/jffs2/summary.h
15472 ---- linux-2.6.27.6/fs/jffs2/summary.h 2008-11-07 12:55:34.000000000 -0500
15473 -+++ linux-2.6.27.6/fs/jffs2/summary.h 2008-11-18 03:38:45.000000000 -0500
15474 -@@ -194,18 +194,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_
15475 -
15476 - #define jffs2_sum_active() (0)
15477 - #define jffs2_sum_init(a) (0)
15478 --#define jffs2_sum_exit(a)
15479 --#define jffs2_sum_disable_collecting(a)
15480 -+#define jffs2_sum_exit(a) do {} while (0)
15481 -+#define jffs2_sum_disable_collecting(a) do {} while (0)
15482 - #define jffs2_sum_is_disabled(a) (0)
15483 --#define jffs2_sum_reset_collected(a)
15484 -+#define jffs2_sum_reset_collected(a) do {} while (0)
15485 - #define jffs2_sum_add_kvec(a,b,c,d) (0)
15486 --#define jffs2_sum_move_collected(a,b)
15487 -+#define jffs2_sum_move_collected(a,b) do {} while (0)
15488 - #define jffs2_sum_write_sumnode(a) (0)
15489 --#define jffs2_sum_add_padding_mem(a,b)
15490 --#define jffs2_sum_add_inode_mem(a,b,c)
15491 --#define jffs2_sum_add_dirent_mem(a,b,c)
15492 --#define jffs2_sum_add_xattr_mem(a,b,c)
15493 --#define jffs2_sum_add_xref_mem(a,b,c)
15494 -+#define jffs2_sum_add_padding_mem(a,b) do {} while (0)
15495 -+#define jffs2_sum_add_inode_mem(a,b,c) do {} while (0)
15496 -+#define jffs2_sum_add_dirent_mem(a,b,c) do {} while (0)
15497 -+#define jffs2_sum_add_xattr_mem(a,b,c) do {} while (0)
15498 -+#define jffs2_sum_add_xref_mem(a,b,c) do {} while (0)
15499 - #define jffs2_sum_scan_sumnode(a,b,c,d,e) (0)
15500 -
15501 - #endif /* CONFIG_JFFS2_SUMMARY */
15502 -diff -urNp linux-2.6.27.6/fs/jffs2/wbuf.c linux-2.6.27.6/fs/jffs2/wbuf.c
15503 ---- linux-2.6.27.6/fs/jffs2/wbuf.c 2008-11-07 12:55:34.000000000 -0500
15504 -+++ linux-2.6.27.6/fs/jffs2/wbuf.c 2008-11-18 03:38:45.000000000 -0500
15505 -@@ -1015,7 +1015,8 @@ static const struct jffs2_unknown_node o
15506 - {
15507 - .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK),
15508 - .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
15509 -- .totlen = constant_cpu_to_je32(8)
15510 -+ .totlen = constant_cpu_to_je32(8),
15511 -+ .hdr_crc = constant_cpu_to_je32(0)
15512 - };
15513 -
15514 - /*
15515 -diff -urNp linux-2.6.27.6/fs/locks.c linux-2.6.27.6/fs/locks.c
15516 ---- linux-2.6.27.6/fs/locks.c 2008-11-07 12:55:34.000000000 -0500
15517 -+++ linux-2.6.27.6/fs/locks.c 2008-11-18 03:38:45.000000000 -0500
15518 -@@ -2005,16 +2005,16 @@ void locks_remove_flock(struct file *fil
15519 - return;
15520 -
15521 - if (filp->f_op && filp->f_op->flock) {
15522 -- struct file_lock fl = {
15523 -+ struct file_lock flock = {
15524 - .fl_pid = current->tgid,
15525 - .fl_file = filp,
15526 - .fl_flags = FL_FLOCK,
15527 - .fl_type = F_UNLCK,
15528 - .fl_end = OFFSET_MAX,
15529 - };
15530 -- filp->f_op->flock(filp, F_SETLKW, &fl);
15531 -- if (fl.fl_ops && fl.fl_ops->fl_release_private)
15532 -- fl.fl_ops->fl_release_private(&fl);
15533 -+ filp->f_op->flock(filp, F_SETLKW, &flock);
15534 -+ if (flock.fl_ops && flock.fl_ops->fl_release_private)
15535 -+ flock.fl_ops->fl_release_private(&flock);
15536 - }
15537 -
15538 - lock_kernel();
15539 -diff -urNp linux-2.6.27.6/fs/namei.c linux-2.6.27.6/fs/namei.c
15540 ---- linux-2.6.27.6/fs/namei.c 2008-11-07 12:55:34.000000000 -0500
15541 -+++ linux-2.6.27.6/fs/namei.c 2008-11-18 04:47:57.000000000 -0500
15542 -@@ -31,6 +31,8 @@
15543 - #include <linux/file.h>
15544 - #include <linux/fcntl.h>
15545 - #include <linux/device_cgroup.h>
15546 -+#include <linux/grsecurity.h>
15547 -+
15548 - #include <asm/uaccess.h>
15549 -
15550 - #define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
15551 -@@ -646,7 +648,7 @@ static __always_inline int __do_follow_l
15552 - cookie = dentry->d_inode->i_op->follow_link(dentry, nd);
15553 - error = PTR_ERR(cookie);
15554 - if (!IS_ERR(cookie)) {
15555 -- char *s = nd_get_link(nd);
15556 -+ const char *s = nd_get_link(nd);
15557 - error = 0;
15558 - if (s)
15559 - error = __vfs_follow_link(nd, s);
15560 -@@ -677,6 +679,13 @@ static inline int do_follow_link(struct
15561 - err = security_inode_follow_link(path->dentry, nd);
15562 - if (err)
15563 - goto loop;
15564 -+
15565 -+ if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
15566 -+ path->dentry->d_inode, path->dentry, nd->path.mnt)) {
15567 -+ err = -EACCES;
15568 -+ goto loop;
15569 -+ }
15570 -+
15571 - current->link_count++;
15572 - current->total_link_count++;
15573 - nd->depth++;
15574 -@@ -1025,11 +1034,18 @@ return_reval:
15575 - break;
15576 - }
15577 - return_base:
15578 -+ if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt)) {
15579 -+ path_put(&nd->path);
15580 -+ return -ENOENT;
15581 -+ }
15582 - return 0;
15583 - out_dput:
15584 - path_put_conditional(&next, nd);
15585 - break;
15586 - }
15587 -+ if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt))
15588 -+ err = -ENOENT;
15589 -+
15590 - path_put(&nd->path);
15591 - return_err:
15592 - return err;
15593 -@@ -1613,9 +1629,17 @@ static int __open_namei_create(struct na
15594 - int error;
15595 - struct dentry *dir = nd->path.dentry;
15596 -
15597 -+ if (!gr_acl_handle_creat(path->dentry, nd->path.dentry, nd->path.mnt, flag, mode)) {
15598 -+ error = -EACCES;
15599 -+ goto out_unlock_dput;
15600 -+ }
15601 -+
15602 - if (!IS_POSIXACL(dir->d_inode))
15603 - mode &= ~current->fs->umask;
15604 - error = vfs_create(dir->d_inode, path->dentry, mode, nd);
15605 -+ if (!error)
15606 -+ gr_handle_create(path->dentry, nd->path.mnt);
15607 -+out_unlock_dput:
15608 - mutex_unlock(&dir->d_inode->i_mutex);
15609 - dput(nd->path.dentry);
15610 - nd->path.dentry = path->dentry;
15611 -@@ -1696,6 +1720,17 @@ struct file *do_filp_open(int dfd, const
15612 - &nd, flag);
15613 - if (error)
15614 - return ERR_PTR(error);
15615 -+
15616 -+ if (gr_handle_rawio(nd.path.dentry->d_inode)) {
15617 -+ error = -EPERM;
15618 -+ goto exit;
15619 -+ }
15620 -+
15621 -+ if (!gr_acl_handle_open(nd.path.dentry, nd.path.mnt, flag)) {
15622 -+ error = -EACCES;
15623 -+ goto exit;
15624 -+ }
15625 -+
15626 - goto ok;
15627 - }
15628 -
15629 -@@ -1759,6 +1794,20 @@ do_last:
15630 - /*
15631 - * It already exists.
15632 - */
15633 -+
15634 -+ if (gr_handle_rawio(path.dentry->d_inode)) {
15635 -+ error = -EPERM;
15636 -+ goto exit_mutex_unlock;
15637 -+ }
15638 -+ if (!gr_acl_handle_open(path.dentry, nd.path.mnt, flag)) {
15639 -+ error = -EACCES;
15640 -+ goto exit_mutex_unlock;
15641 -+ }
15642 -+ if (gr_handle_fifo(path.dentry, nd.path.mnt, dir, flag, acc_mode)) {
15643 -+ error = -EACCES;
15644 -+ goto exit_mutex_unlock;
15645 -+ }
15646 -+
15647 - mutex_unlock(&dir->d_inode->i_mutex);
15648 - audit_inode(pathname, path.dentry);
15649 -
15650 -@@ -1843,6 +1892,13 @@ do_link:
15651 - error = security_inode_follow_link(path.dentry, &nd);
15652 - if (error)
15653 - goto exit_dput;
15654 -+
15655 -+ if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
15656 -+ path.dentry, nd.path.mnt)) {
15657 -+ error = -EACCES;
15658 -+ goto exit_dput;
15659 -+ }
15660 -+
15661 - error = __do_follow_link(&path, &nd);
15662 - if (error) {
15663 - /* Does someone understand code flow here? Or it is only
15664 -@@ -2015,9 +2071,21 @@ asmlinkage long sys_mknodat(int dfd, con
15665 - error = may_mknod(mode);
15666 - if (error)
15667 - goto out_dput;
15668 -+
15669 -+ if (gr_handle_chroot_mknod(dentry, nd.path.mnt, mode)) {
15670 -+ error = -EPERM;
15671 -+ goto out_dput;
15672 -+ }
15673 -+
15674 -+ if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
15675 -+ error = -EACCES;
15676 -+ goto out_dput;
15677 -+ }
15678 -+
15679 - error = mnt_want_write(nd.path.mnt);
15680 - if (error)
15681 - goto out_dput;
15682 -+
15683 - switch (mode & S_IFMT) {
15684 - case 0: case S_IFREG:
15685 - error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd);
15686 -@@ -2031,6 +2099,9 @@ asmlinkage long sys_mknodat(int dfd, con
15687 - break;
15688 - }
15689 - mnt_drop_write(nd.path.mnt);
15690 -+
15691 -+ if (!error)
15692 -+ gr_handle_create(dentry, nd.path.mnt);
15693 - out_dput:
15694 - dput(dentry);
15695 - out_unlock:
15696 -@@ -2084,6 +2155,11 @@ asmlinkage long sys_mkdirat(int dfd, con
15697 - if (IS_ERR(dentry))
15698 - goto out_unlock;
15699 -
15700 -+ if (!gr_acl_handle_mkdir(dentry, nd.path.dentry, nd.path.mnt)) {
15701 -+ error = -EACCES;
15702 -+ goto out_dput;
15703 -+ }
15704 -+
15705 - if (!IS_POSIXACL(nd.path.dentry->d_inode))
15706 - mode &= ~current->fs->umask;
15707 - error = mnt_want_write(nd.path.mnt);
15708 -@@ -2091,6 +2167,10 @@ asmlinkage long sys_mkdirat(int dfd, con
15709 - goto out_dput;
15710 - error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
15711 - mnt_drop_write(nd.path.mnt);
15712 -+
15713 -+ if (!error)
15714 -+ gr_handle_create(dentry, nd.path.mnt);
15715 -+
15716 - out_dput:
15717 - dput(dentry);
15718 - out_unlock:
15719 -@@ -2172,6 +2252,8 @@ static long do_rmdir(int dfd, const char
15720 - char * name;
15721 - struct dentry *dentry;
15722 - struct nameidata nd;
15723 -+ ino_t saved_ino = 0;
15724 -+ dev_t saved_dev = 0;
15725 -
15726 - error = user_path_parent(dfd, pathname, &nd, &name);
15727 - if (error)
15728 -@@ -2193,11 +2275,26 @@ static long do_rmdir(int dfd, const char
15729 - error = PTR_ERR(dentry);
15730 - if (IS_ERR(dentry))
15731 - goto exit2;
15732 -+
15733 -+ if (dentry->d_inode != NULL) {
15734 -+ if (dentry->d_inode->i_nlink <= 1) {
15735 -+ saved_ino = dentry->d_inode->i_ino;
15736 -+ saved_dev = dentry->d_inode->i_sb->s_dev;
15737 -+ }
15738 -+
15739 -+ if (!gr_acl_handle_rmdir(dentry, nd.path.mnt)) {
15740 -+ error = -EACCES;
15741 -+ goto exit3;
15742 -+ }
15743 -+ }
15744 -+
15745 - error = mnt_want_write(nd.path.mnt);
15746 - if (error)
15747 - goto exit3;
15748 - error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
15749 - mnt_drop_write(nd.path.mnt);
15750 -+ if (!error && (saved_dev || saved_ino))
15751 -+ gr_handle_delete(saved_ino, saved_dev);
15752 - exit3:
15753 - dput(dentry);
15754 - exit2:
15755 -@@ -2257,6 +2354,8 @@ static long do_unlinkat(int dfd, const c
15756 - struct dentry *dentry;
15757 - struct nameidata nd;
15758 - struct inode *inode = NULL;
15759 -+ ino_t saved_ino = 0;
15760 -+ dev_t saved_dev = 0;
15761 -
15762 - error = user_path_parent(dfd, pathname, &nd, &name);
15763 - if (error)
15764 -@@ -2273,12 +2372,25 @@ static long do_unlinkat(int dfd, const c
15765 - if (nd.last.name[nd.last.len])
15766 - goto slashes;
15767 - inode = dentry->d_inode;
15768 -- if (inode)
15769 -+ if (inode) {
15770 -+ if (inode->i_nlink <= 1) {
15771 -+ saved_ino = inode->i_ino;
15772 -+ saved_dev = inode->i_sb->s_dev;
15773 -+ }
15774 -+
15775 - atomic_inc(&inode->i_count);
15776 -+
15777 -+ if (!gr_acl_handle_unlink(dentry, nd.path.mnt)) {
15778 -+ error = -EACCES;
15779 -+ goto exit2;
15780 -+ }
15781 -+ }
15782 - error = mnt_want_write(nd.path.mnt);
15783 - if (error)
15784 - goto exit2;
15785 - error = vfs_unlink(nd.path.dentry->d_inode, dentry);
15786 -+ if (!error && (saved_ino || saved_dev))
15787 -+ gr_handle_delete(saved_ino, saved_dev);
15788 - mnt_drop_write(nd.path.mnt);
15789 - exit2:
15790 - dput(dentry);
15791 -@@ -2356,10 +2468,17 @@ asmlinkage long sys_symlinkat(const char
15792 - if (IS_ERR(dentry))
15793 - goto out_unlock;
15794 -
15795 -+ if (!gr_acl_handle_symlink(dentry, nd.path.dentry, nd.path.mnt, from)) {
15796 -+ error = -EACCES;
15797 -+ goto out_dput;
15798 -+ }
15799 -+
15800 - error = mnt_want_write(nd.path.mnt);
15801 - if (error)
15802 - goto out_dput;
15803 - error = vfs_symlink(nd.path.dentry->d_inode, dentry, from);
15804 -+ if (!error)
15805 -+ gr_handle_create(dentry, nd.path.mnt);
15806 - mnt_drop_write(nd.path.mnt);
15807 - out_dput:
15808 - dput(dentry);
15809 -@@ -2453,10 +2572,26 @@ asmlinkage long sys_linkat(int olddfd, c
15810 - error = PTR_ERR(new_dentry);
15811 - if (IS_ERR(new_dentry))
15812 - goto out_unlock;
15813 -+
15814 -+ if (gr_handle_hardlink(old_path.dentry, old_path.mnt,
15815 -+ old_path.dentry->d_inode,
15816 -+ old_path.dentry->d_inode->i_mode, to)) {
15817 -+ error = -EACCES;
15818 -+ goto out_dput;
15819 -+ }
15820 -+
15821 -+ if (!gr_acl_handle_link(new_dentry, nd.path.dentry, nd.path.mnt,
15822 -+ old_path.dentry, old_path.mnt, to)) {
15823 -+ error = -EACCES;
15824 -+ goto out_dput;
15825 -+ }
15826 -+
15827 - error = mnt_want_write(nd.path.mnt);
15828 - if (error)
15829 - goto out_dput;
15830 - error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry);
15831 -+ if (!error)
15832 -+ gr_handle_create(new_dentry, nd.path.mnt);
15833 - mnt_drop_write(nd.path.mnt);
15834 - out_dput:
15835 - dput(new_dentry);
15836 -@@ -2612,8 +2747,10 @@ int vfs_rename(struct inode *old_dir, st
15837 - error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
15838 - else
15839 - error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
15840 -+
15841 - if (!error) {
15842 - const char *new_name = old_dentry->d_name.name;
15843 -+
15844 - fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir,
15845 - new_dentry->d_inode, old_dentry);
15846 - }
15847 -@@ -2685,11 +2822,21 @@ asmlinkage long sys_renameat(int olddfd,
15848 - if (new_dentry == trap)
15849 - goto exit5;
15850 -
15851 -+ error = gr_acl_handle_rename(new_dentry, new_dir, newnd.path.mnt,
15852 -+ old_dentry, old_dir->d_inode, oldnd.path.mnt,
15853 -+ to);
15854 -+ if (error)
15855 -+ goto exit5;
15856 -+
15857 - error = mnt_want_write(oldnd.path.mnt);
15858 - if (error)
15859 - goto exit5;
15860 - error = vfs_rename(old_dir->d_inode, old_dentry,
15861 - new_dir->d_inode, new_dentry);
15862 -+ if (!error)
15863 -+ gr_handle_rename(old_dir->d_inode, new_dir->d_inode, old_dentry,
15864 -+ new_dentry, oldnd.path.mnt, new_dentry->d_inode ? 1 : 0);
15865 -+
15866 - mnt_drop_write(oldnd.path.mnt);
15867 - exit5:
15868 - dput(new_dentry);
15869 -diff -urNp linux-2.6.27.6/fs/namespace.c linux-2.6.27.6/fs/namespace.c
15870 ---- linux-2.6.27.6/fs/namespace.c 2008-11-07 12:55:34.000000000 -0500
15871 -+++ linux-2.6.27.6/fs/namespace.c 2008-11-18 03:38:45.000000000 -0500
15872 -@@ -27,6 +27,7 @@
15873 - #include <linux/ramfs.h>
15874 - #include <linux/log2.h>
15875 - #include <linux/idr.h>
15876 -+#include <linux/grsecurity.h>
15877 - #include <asm/uaccess.h>
15878 - #include <asm/unistd.h>
15879 - #include "pnode.h"
15880 -@@ -1094,6 +1095,8 @@ static int do_umount(struct vfsmount *mn
15881 - lock_kernel();
15882 - retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
15883 - unlock_kernel();
15884 -+
15885 -+ gr_log_remount(mnt->mnt_devname, retval);
15886 - }
15887 - up_write(&sb->s_umount);
15888 - return retval;
15889 -@@ -1117,6 +1120,9 @@ static int do_umount(struct vfsmount *mn
15890 - security_sb_umount_busy(mnt);
15891 - up_write(&namespace_sem);
15892 - release_mounts(&umount_list);
15893 -+
15894 -+ gr_log_unmount(mnt->mnt_devname, retval);
15895 -+
15896 - return retval;
15897 - }
15898 -
15899 -@@ -1949,6 +1955,11 @@ long do_mount(char *dev_name, char *dir_
15900 - if (retval)
15901 - goto dput_out;
15902 -
15903 -+ if (gr_handle_chroot_mount(nd.path.dentry, nd.path.mnt, dev_name)) {
15904 -+ retval = -EPERM;
15905 -+ goto dput_out;
15906 -+ }
15907 -+
15908 - if (flags & MS_REMOUNT)
15909 - retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
15910 - data_page);
15911 -@@ -1963,6 +1974,9 @@ long do_mount(char *dev_name, char *dir_
15912 - dev_name, data_page);
15913 - dput_out:
15914 - path_put(&nd.path);
15915 -+
15916 -+ gr_log_mount(dev_name, dir_name, retval);
15917 -+
15918 - return retval;
15919 - }
15920 -
15921 -@@ -2075,6 +2089,9 @@ asmlinkage long sys_mount(char __user *
15922 - if (retval < 0)
15923 - goto out3;
15924 -
15925 -+ if (gr_handle_chroot_pivot())
15926 -+ return -EPERM;
15927 -+
15928 - lock_kernel();
15929 - retval = do_mount((char *)dev_page, dir_page, (char *)type_page,
15930 - flags, (void *)data_page);
15931 -diff -urNp linux-2.6.27.6/fs/nfs/nfs4proc.c linux-2.6.27.6/fs/nfs/nfs4proc.c
15932 ---- linux-2.6.27.6/fs/nfs/nfs4proc.c 2008-11-07 12:55:34.000000000 -0500
15933 -+++ linux-2.6.27.6/fs/nfs/nfs4proc.c 2008-11-18 03:38:45.000000000 -0500
15934 -@@ -653,7 +653,7 @@ static int _nfs4_do_open_reclaim(struct
15935 - static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
15936 - {
15937 - struct nfs_server *server = NFS_SERVER(state->inode);
15938 -- struct nfs4_exception exception = { };
15939 -+ struct nfs4_exception exception = {0, 0};
15940 - int err;
15941 - do {
15942 - err = _nfs4_do_open_reclaim(ctx, state);
15943 -@@ -695,7 +695,7 @@ static int _nfs4_open_delegation_recall(
15944 -
15945 - int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
15946 - {
15947 -- struct nfs4_exception exception = { };
15948 -+ struct nfs4_exception exception = {0, 0};
15949 - struct nfs_server *server = NFS_SERVER(state->inode);
15950 - int err;
15951 - do {
15952 -@@ -988,7 +988,7 @@ static int _nfs4_open_expired(struct nfs
15953 - static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
15954 - {
15955 - struct nfs_server *server = NFS_SERVER(state->inode);
15956 -- struct nfs4_exception exception = { };
15957 -+ struct nfs4_exception exception = {0, 0};
15958 - int err;
15959 -
15960 - do {
15961 -@@ -1090,7 +1090,7 @@ out_err:
15962 -
15963 - static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred)
15964 - {
15965 -- struct nfs4_exception exception = { };
15966 -+ struct nfs4_exception exception = {0, 0};
15967 - struct nfs4_state *res;
15968 - int status;
15969 -
15970 -@@ -1181,7 +1181,7 @@ static int nfs4_do_setattr(struct inode
15971 - struct nfs4_state *state)
15972 - {
15973 - struct nfs_server *server = NFS_SERVER(inode);
15974 -- struct nfs4_exception exception = { };
15975 -+ struct nfs4_exception exception = {0, 0};
15976 - int err;
15977 - do {
15978 - err = nfs4_handle_exception(server,
15979 -@@ -1494,7 +1494,7 @@ static int _nfs4_server_capabilities(str
15980 -
15981 - int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
15982 - {
15983 -- struct nfs4_exception exception = { };
15984 -+ struct nfs4_exception exception = {0, 0};
15985 - int err;
15986 - do {
15987 - err = nfs4_handle_exception(server,
15988 -@@ -1527,7 +1527,7 @@ static int _nfs4_lookup_root(struct nfs_
15989 - static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
15990 - struct nfs_fsinfo *info)
15991 - {
15992 -- struct nfs4_exception exception = { };
15993 -+ struct nfs4_exception exception = {0, 0};
15994 - int err;
15995 - do {
15996 - err = nfs4_handle_exception(server,
15997 -@@ -1616,7 +1616,7 @@ static int _nfs4_proc_getattr(struct nfs
15998 -
15999 - static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
16000 - {
16001 -- struct nfs4_exception exception = { };
16002 -+ struct nfs4_exception exception = {0, 0};
16003 - int err;
16004 - do {
16005 - err = nfs4_handle_exception(server,
16006 -@@ -1702,7 +1702,7 @@ static int nfs4_proc_lookupfh(struct nfs
16007 - struct qstr *name, struct nfs_fh *fhandle,
16008 - struct nfs_fattr *fattr)
16009 - {
16010 -- struct nfs4_exception exception = { };
16011 -+ struct nfs4_exception exception = {0, 0};
16012 - int err;
16013 - do {
16014 - err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr);
16015 -@@ -1731,7 +1731,7 @@ static int _nfs4_proc_lookup(struct inod
16016 -
16017 - static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
16018 - {
16019 -- struct nfs4_exception exception = { };
16020 -+ struct nfs4_exception exception = {0, 0};
16021 - int err;
16022 - do {
16023 - err = nfs4_handle_exception(NFS_SERVER(dir),
16024 -@@ -1795,7 +1795,7 @@ static int _nfs4_proc_access(struct inod
16025 -
16026 - static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
16027 - {
16028 -- struct nfs4_exception exception = { };
16029 -+ struct nfs4_exception exception = {0, 0};
16030 - int err;
16031 - do {
16032 - err = nfs4_handle_exception(NFS_SERVER(inode),
16033 -@@ -1850,7 +1850,7 @@ static int _nfs4_proc_readlink(struct in
16034 - static int nfs4_proc_readlink(struct inode *inode, struct page *page,
16035 - unsigned int pgbase, unsigned int pglen)
16036 - {
16037 -- struct nfs4_exception exception = { };
16038 -+ struct nfs4_exception exception = {0, 0};
16039 - int err;
16040 - do {
16041 - err = nfs4_handle_exception(NFS_SERVER(inode),
16042 -@@ -1947,7 +1947,7 @@ static int _nfs4_proc_remove(struct inod
16043 -
16044 - static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
16045 - {
16046 -- struct nfs4_exception exception = { };
16047 -+ struct nfs4_exception exception = {0, 0};
16048 - int err;
16049 - do {
16050 - err = nfs4_handle_exception(NFS_SERVER(dir),
16051 -@@ -2019,7 +2019,7 @@ static int _nfs4_proc_rename(struct inod
16052 - static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
16053 - struct inode *new_dir, struct qstr *new_name)
16054 - {
16055 -- struct nfs4_exception exception = { };
16056 -+ struct nfs4_exception exception = {0, 0};
16057 - int err;
16058 - do {
16059 - err = nfs4_handle_exception(NFS_SERVER(old_dir),
16060 -@@ -2066,7 +2066,7 @@ static int _nfs4_proc_link(struct inode
16061 -
16062 - static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
16063 - {
16064 -- struct nfs4_exception exception = { };
16065 -+ struct nfs4_exception exception = {0, 0};
16066 - int err;
16067 - do {
16068 - err = nfs4_handle_exception(NFS_SERVER(inode),
16069 -@@ -2157,7 +2157,7 @@ out:
16070 - static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
16071 - struct page *page, unsigned int len, struct iattr *sattr)
16072 - {
16073 -- struct nfs4_exception exception = { };
16074 -+ struct nfs4_exception exception = {0, 0};
16075 - int err;
16076 - do {
16077 - err = nfs4_handle_exception(NFS_SERVER(dir),
16078 -@@ -2188,7 +2188,7 @@ out:
16079 - static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
16080 - struct iattr *sattr)
16081 - {
16082 -- struct nfs4_exception exception = { };
16083 -+ struct nfs4_exception exception = {0, 0};
16084 - int err;
16085 - do {
16086 - err = nfs4_handle_exception(NFS_SERVER(dir),
16087 -@@ -2237,7 +2237,7 @@ static int _nfs4_proc_readdir(struct den
16088 - static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
16089 - u64 cookie, struct page *page, unsigned int count, int plus)
16090 - {
16091 -- struct nfs4_exception exception = { };
16092 -+ struct nfs4_exception exception = {0, 0};
16093 - int err;
16094 - do {
16095 - err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode),
16096 -@@ -2285,7 +2285,7 @@ out:
16097 - static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
16098 - struct iattr *sattr, dev_t rdev)
16099 - {
16100 -- struct nfs4_exception exception = { };
16101 -+ struct nfs4_exception exception = {0, 0};
16102 - int err;
16103 - do {
16104 - err = nfs4_handle_exception(NFS_SERVER(dir),
16105 -@@ -2314,7 +2314,7 @@ static int _nfs4_proc_statfs(struct nfs_
16106 -
16107 - static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
16108 - {
16109 -- struct nfs4_exception exception = { };
16110 -+ struct nfs4_exception exception = {0, 0};
16111 - int err;
16112 - do {
16113 - err = nfs4_handle_exception(server,
16114 -@@ -2342,7 +2342,7 @@ static int _nfs4_do_fsinfo(struct nfs_se
16115 -
16116 - static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
16117 - {
16118 -- struct nfs4_exception exception = { };
16119 -+ struct nfs4_exception exception = {0, 0};
16120 - int err;
16121 -
16122 - do {
16123 -@@ -2385,7 +2385,7 @@ static int _nfs4_proc_pathconf(struct nf
16124 - static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
16125 - struct nfs_pathconf *pathconf)
16126 - {
16127 -- struct nfs4_exception exception = { };
16128 -+ struct nfs4_exception exception = {0, 0};
16129 - int err;
16130 -
16131 - do {
16132 -@@ -2672,7 +2672,7 @@ out_free:
16133 -
16134 - static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
16135 - {
16136 -- struct nfs4_exception exception = { };
16137 -+ struct nfs4_exception exception = {0, 0};
16138 - ssize_t ret;
16139 - do {
16140 - ret = __nfs4_get_acl_uncached(inode, buf, buflen);
16141 -@@ -2729,7 +2729,7 @@ static int __nfs4_proc_set_acl(struct in
16142 -
16143 - static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
16144 - {
16145 -- struct nfs4_exception exception = { };
16146 -+ struct nfs4_exception exception = {0, 0};
16147 - int err;
16148 - do {
16149 - err = nfs4_handle_exception(NFS_SERVER(inode),
16150 -@@ -3020,7 +3020,7 @@ out:
16151 - int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync)
16152 - {
16153 - struct nfs_server *server = NFS_SERVER(inode);
16154 -- struct nfs4_exception exception = { };
16155 -+ struct nfs4_exception exception = {0, 0};
16156 - int err;
16157 - do {
16158 - err = _nfs4_proc_delegreturn(inode, cred, stateid, issync);
16159 -@@ -3095,7 +3095,7 @@ out:
16160 -
16161 - static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
16162 - {
16163 -- struct nfs4_exception exception = { };
16164 -+ struct nfs4_exception exception = {0, 0};
16165 - int err;
16166 -
16167 - do {
16168 -@@ -3445,7 +3445,7 @@ static int _nfs4_do_setlk(struct nfs4_st
16169 - static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
16170 - {
16171 - struct nfs_server *server = NFS_SERVER(state->inode);
16172 -- struct nfs4_exception exception = { };
16173 -+ struct nfs4_exception exception = {0, 0};
16174 - int err;
16175 -
16176 - do {
16177 -@@ -3463,7 +3463,7 @@ static int nfs4_lock_reclaim(struct nfs4
16178 - static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
16179 - {
16180 - struct nfs_server *server = NFS_SERVER(state->inode);
16181 -- struct nfs4_exception exception = { };
16182 -+ struct nfs4_exception exception = {0, 0};
16183 - int err;
16184 -
16185 - err = nfs4_set_lock_state(state, request);
16186 -@@ -3524,7 +3524,7 @@ out:
16187 -
16188 - static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
16189 - {
16190 -- struct nfs4_exception exception = { };
16191 -+ struct nfs4_exception exception = {0, 0};
16192 - int err;
16193 -
16194 - do {
16195 -@@ -3574,7 +3574,7 @@ nfs4_proc_lock(struct file *filp, int cm
16196 - int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
16197 - {
16198 - struct nfs_server *server = NFS_SERVER(state->inode);
16199 -- struct nfs4_exception exception = { };
16200 -+ struct nfs4_exception exception = {0, 0};
16201 - int err;
16202 -
16203 - err = nfs4_set_lock_state(state, fl);
16204 -diff -urNp linux-2.6.27.6/fs/nfsd/export.c linux-2.6.27.6/fs/nfsd/export.c
16205 ---- linux-2.6.27.6/fs/nfsd/export.c 2008-11-07 12:55:34.000000000 -0500
16206 -+++ linux-2.6.27.6/fs/nfsd/export.c 2008-11-18 03:38:45.000000000 -0500
16207 -@@ -473,7 +473,7 @@ static int secinfo_parse(char **mesg, ch
16208 - * probably discover the problem when someone fails to
16209 - * authenticate.
16210 - */
16211 -- if (f->pseudoflavor < 0)
16212 -+ if ((s32)f->pseudoflavor < 0)
16213 - return -EINVAL;
16214 - err = get_int(mesg, &f->flags);
16215 - if (err)
16216 -diff -urNp linux-2.6.27.6/fs/nls/nls_base.c linux-2.6.27.6/fs/nls/nls_base.c
16217 ---- linux-2.6.27.6/fs/nls/nls_base.c 2008-11-07 12:55:34.000000000 -0500
16218 -+++ linux-2.6.27.6/fs/nls/nls_base.c 2008-11-18 03:38:45.000000000 -0500
16219 -@@ -42,7 +42,7 @@ static const struct utf8_table utf8_tabl
16220 - {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */},
16221 - {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */},
16222 - {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */},
16223 -- {0, /* end of table */}
16224 -+ {0, 0, 0, 0, 0, /* end of table */}
16225 - };
16226 -
16227 - int
16228 -diff -urNp linux-2.6.27.6/fs/ntfs/file.c linux-2.6.27.6/fs/ntfs/file.c
16229 ---- linux-2.6.27.6/fs/ntfs/file.c 2008-11-07 12:55:34.000000000 -0500
16230 -+++ linux-2.6.27.6/fs/ntfs/file.c 2008-11-18 03:38:45.000000000 -0500
16231 -@@ -2291,6 +2291,6 @@ const struct inode_operations ntfs_file_
16232 - #endif /* NTFS_RW */
16233 - };
16234 -
16235 --const struct file_operations ntfs_empty_file_ops = {};
16236 -+const struct file_operations ntfs_empty_file_ops;
16237 -
16238 --const struct inode_operations ntfs_empty_inode_ops = {};
16239 -+const struct inode_operations ntfs_empty_inode_ops;
16240 -diff -urNp linux-2.6.27.6/fs/open.c linux-2.6.27.6/fs/open.c
16241 ---- linux-2.6.27.6/fs/open.c 2008-11-07 12:55:34.000000000 -0500
16242 -+++ linux-2.6.27.6/fs/open.c 2008-11-18 03:38:45.000000000 -0500
16243 -@@ -29,6 +29,7 @@
16244 - #include <linux/rcupdate.h>
16245 - #include <linux/audit.h>
16246 - #include <linux/falloc.h>
16247 -+#include <linux/grsecurity.h>
16248 -
16249 - int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
16250 - {
16251 -@@ -207,6 +208,9 @@ int do_truncate(struct dentry *dentry, l
16252 - if (length < 0)
16253 - return -EINVAL;
16254 -
16255 -+ if (filp && !gr_acl_handle_truncate(dentry, filp->f_path.mnt))
16256 -+ return -EACCES;
16257 -+
16258 - newattrs.ia_size = length;
16259 - newattrs.ia_valid = ATTR_SIZE | time_attrs;
16260 - if (filp) {
16261 -@@ -491,6 +495,9 @@ asmlinkage long sys_faccessat(int dfd, c
16262 - if (__mnt_is_readonly(path.mnt))
16263 - res = -EROFS;
16264 -
16265 -+ if (!res && !gr_acl_handle_access(path.dentry, path.mnt, mode))
16266 -+ res = -EACCES;
16267 -+
16268 - out_path_release:
16269 - path_put(&path);
16270 - out:
16271 -@@ -521,6 +528,8 @@ asmlinkage long sys_chdir(const char __u
16272 - if (error)
16273 - goto dput_and_out;
16274 -
16275 -+ gr_log_chdir(path.dentry, path.mnt);
16276 -+
16277 - set_fs_pwd(current->fs, &path);
16278 -
16279 - dput_and_out:
16280 -@@ -547,6 +556,13 @@ asmlinkage long sys_fchdir(unsigned int
16281 - goto out_putf;
16282 -
16283 - error = inode_permission(inode, MAY_EXEC | MAY_ACCESS);
16284 -+
16285 -+ if (!error && !gr_chroot_fchdir(file->f_path.dentry, file->f_path.mnt))
16286 -+ error = -EPERM;
16287 -+
16288 -+ if (!error)
16289 -+ gr_log_chdir(file->f_path.dentry, file->f_path.mnt);
16290 -+
16291 - if (!error)
16292 - set_fs_pwd(current->fs, &file->f_path);
16293 - out_putf:
16294 -@@ -572,7 +588,14 @@ asmlinkage long sys_chroot(const char __
16295 - if (!capable(CAP_SYS_CHROOT))
16296 - goto dput_and_out;
16297 -
16298 -+ if (gr_handle_chroot_chroot(path.dentry, path.mnt))
16299 -+ goto dput_and_out;
16300 -+
16301 - set_fs_root(current->fs, &path);
16302 -+
16303 -+ gr_handle_chroot_caps(current);
16304 -+ gr_handle_chroot_chdir(&path);
16305 -+
16306 - error = 0;
16307 - dput_and_out:
16308 - path_put(&path);
16309 -@@ -600,13 +623,28 @@ asmlinkage long sys_fchmod(unsigned int
16310 - err = mnt_want_write(file->f_path.mnt);
16311 - if (err)
16312 - goto out_putf;
16313 -+
16314 -+ if (!gr_acl_handle_fchmod(dentry, file->f_path.mnt, mode)) {
16315 -+ err = -EACCES;
16316 -+ goto out_drop_write;
16317 -+ }
16318 -+
16319 - mutex_lock(&inode->i_mutex);
16320 - if (mode == (mode_t) -1)
16321 - mode = inode->i_mode;
16322 -+
16323 -+ if (gr_handle_chroot_chmod(dentry, file->f_path.mnt, mode)) {
16324 -+ err = -EPERM;
16325 -+ mutex_unlock(&inode->i_mutex);
16326 -+ goto out_drop_write;
16327 -+ }
16328 -+
16329 - newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
16330 - newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
16331 - err = notify_change(dentry, &newattrs);
16332 - mutex_unlock(&inode->i_mutex);
16333 -+
16334 -+out_drop_write:
16335 - mnt_drop_write(file->f_path.mnt);
16336 - out_putf:
16337 - fput(file);
16338 -@@ -630,13 +668,28 @@ asmlinkage long sys_fchmodat(int dfd, co
16339 - error = mnt_want_write(path.mnt);
16340 - if (error)
16341 - goto dput_and_out;
16342 -+
16343 -+ if (!gr_acl_handle_chmod(path.dentry, path.mnt, mode)) {
16344 -+ error = -EACCES;
16345 -+ goto out_drop_write;
16346 -+ }
16347 -+
16348 - mutex_lock(&inode->i_mutex);
16349 - if (mode == (mode_t) -1)
16350 - mode = inode->i_mode;
16351 -+
16352 -+ if (gr_handle_chroot_chmod(path.dentry, path.mnt, mode)) {
16353 -+ error = -EACCES;
16354 -+ mutex_unlock(&inode->i_mutex);
16355 -+ goto out_drop_write;
16356 -+ }
16357 -+
16358 - newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
16359 - newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
16360 - error = notify_change(path.dentry, &newattrs);
16361 - mutex_unlock(&inode->i_mutex);
16362 -+
16363 -+out_drop_write:
16364 - mnt_drop_write(path.mnt);
16365 - dput_and_out:
16366 - path_put(&path);
16367 -@@ -649,12 +702,15 @@ asmlinkage long sys_chmod(const char __u
16368 - return sys_fchmodat(AT_FDCWD, filename, mode);
16369 - }
16370 -
16371 --static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
16372 -+static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
16373 - {
16374 - struct inode *inode = dentry->d_inode;
16375 - int error;
16376 - struct iattr newattrs;
16377 -
16378 -+ if (!gr_acl_handle_chown(dentry, mnt))
16379 -+ return -EACCES;
16380 -+
16381 - newattrs.ia_valid = ATTR_CTIME;
16382 - if (user != (uid_t) -1) {
16383 - newattrs.ia_valid |= ATTR_UID;
16384 -@@ -685,7 +741,7 @@ asmlinkage long sys_chown(const char __u
16385 - error = mnt_want_write(path.mnt);
16386 - if (error)
16387 - goto out_release;
16388 -- error = chown_common(path.dentry, user, group);
16389 -+ error = chown_common(path.dentry, user, group, path.mnt);
16390 - mnt_drop_write(path.mnt);
16391 - out_release:
16392 - path_put(&path);
16393 -@@ -710,7 +766,7 @@ asmlinkage long sys_fchownat(int dfd, co
16394 - error = mnt_want_write(path.mnt);
16395 - if (error)
16396 - goto out_release;
16397 -- error = chown_common(path.dentry, user, group);
16398 -+ error = chown_common(path.dentry, user, group, path.mnt);
16399 - mnt_drop_write(path.mnt);
16400 - out_release:
16401 - path_put(&path);
16402 -@@ -729,7 +785,7 @@ asmlinkage long sys_lchown(const char __
16403 - error = mnt_want_write(path.mnt);
16404 - if (error)
16405 - goto out_release;
16406 -- error = chown_common(path.dentry, user, group);
16407 -+ error = chown_common(path.dentry, user, group, path.mnt);
16408 - mnt_drop_write(path.mnt);
16409 - out_release:
16410 - path_put(&path);
16411 -@@ -753,7 +809,7 @@ asmlinkage long sys_fchown(unsigned int
16412 - goto out_fput;
16413 - dentry = file->f_path.dentry;
16414 - audit_inode(NULL, dentry);
16415 -- error = chown_common(dentry, user, group);
16416 -+ error = chown_common(dentry, user, group, file->f_path.mnt);
16417 - mnt_drop_write(file->f_path.mnt);
16418 - out_fput:
16419 - fput(file);
16420 -diff -urNp linux-2.6.27.6/fs/pipe.c linux-2.6.27.6/fs/pipe.c
16421 ---- linux-2.6.27.6/fs/pipe.c 2008-11-07 12:55:34.000000000 -0500
16422 -+++ linux-2.6.27.6/fs/pipe.c 2008-11-18 03:38:45.000000000 -0500
16423 -@@ -851,7 +851,7 @@ void free_pipe_info(struct inode *inode)
16424 - inode->i_pipe = NULL;
16425 - }
16426 -
16427 --static struct vfsmount *pipe_mnt __read_mostly;
16428 -+struct vfsmount *pipe_mnt __read_mostly;
16429 - static int pipefs_delete_dentry(struct dentry *dentry)
16430 - {
16431 - /*
16432 -diff -urNp linux-2.6.27.6/fs/proc/array.c linux-2.6.27.6/fs/proc/array.c
16433 ---- linux-2.6.27.6/fs/proc/array.c 2008-11-07 12:55:34.000000000 -0500
16434 -+++ linux-2.6.27.6/fs/proc/array.c 2008-11-18 03:38:45.000000000 -0500
16435 -@@ -315,6 +315,21 @@ static inline void task_context_switch_c
16436 - p->nivcsw);
16437 - }
16438 -
16439 -+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
16440 -+static inline void task_pax(struct seq_file *m, struct task_struct *p)
16441 -+{
16442 -+ if (p->mm)
16443 -+ seq_printf(m, "PaX:\t%c%c%c%c%c\n",
16444 -+ p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
16445 -+ p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
16446 -+ p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
16447 -+ p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
16448 -+ p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
16449 -+ else
16450 -+ seq_printf(m, "PaX:\t-----\n");
16451 -+}
16452 -+#endif
16453 -+
16454 - int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
16455 - struct pid *pid, struct task_struct *task)
16456 - {
16457 -@@ -334,9 +349,20 @@ int proc_pid_status(struct seq_file *m,
16458 - task_show_regs(m, task);
16459 - #endif
16460 - task_context_switch_counts(m, task);
16461 -+
16462 -+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
16463 -+ task_pax(m, task);
16464 -+#endif
16465 -+
16466 - return 0;
16467 - }
16468 -
16469 -+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16470 -+#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
16471 -+ (_mm->pax_flags & MF_PAX_RANDMMAP || \
16472 -+ _mm->pax_flags & MF_PAX_SEGMEXEC))
16473 -+#endif
16474 -+
16475 - static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
16476 - struct pid *pid, struct task_struct *task, int whole)
16477 - {
16478 -@@ -429,6 +455,19 @@ static int do_task_stat(struct seq_file
16479 - gtime = task_gtime(task);
16480 - }
16481 -
16482 -+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16483 -+ if (PAX_RAND_FLAGS(mm)) {
16484 -+ eip = 0;
16485 -+ esp = 0;
16486 -+ wchan = 0;
16487 -+ }
16488 -+#endif
16489 -+#ifdef CONFIG_GRKERNSEC_HIDESYM
16490 -+ wchan = 0;
16491 -+ eip =0;
16492 -+ esp =0;
16493 -+#endif
16494 -+
16495 - /* scale priority and nice values from timeslices to -20..20 */
16496 - /* to make it look like a "normal" Unix priority/nice value */
16497 - priority = task_prio(task);
16498 -@@ -469,9 +508,15 @@ static int do_task_stat(struct seq_file
16499 - vsize,
16500 - mm ? get_mm_rss(mm) : 0,
16501 - rsslim,
16502 -+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16503 -+ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
16504 -+ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
16505 -+ PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0),
16506 -+#else
16507 - mm ? mm->start_code : 0,
16508 - mm ? mm->end_code : 0,
16509 - mm ? mm->start_stack : 0,
16510 -+#endif
16511 - esp,
16512 - eip,
16513 - /* The signal information here is obsolete.
16514 -@@ -524,3 +569,10 @@ int proc_pid_statm(struct seq_file *m, s
16515 -
16516 - return 0;
16517 - }
16518 -+
16519 -+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
16520 -+int proc_pid_ipaddr(struct task_struct *task, char *buffer)
16521 -+{
16522 -+ return sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
16523 -+}
16524 -+#endif
16525 -diff -urNp linux-2.6.27.6/fs/proc/base.c linux-2.6.27.6/fs/proc/base.c
16526 ---- linux-2.6.27.6/fs/proc/base.c 2008-11-07 12:55:34.000000000 -0500
16527 -+++ linux-2.6.27.6/fs/proc/base.c 2008-11-18 03:38:45.000000000 -0500
16528 -@@ -79,6 +79,8 @@
16529 - #include <linux/oom.h>
16530 - #include <linux/elf.h>
16531 - #include <linux/pid_namespace.h>
16532 -+#include <linux/grsecurity.h>
16533 -+
16534 - #include "internal.h"
16535 -
16536 - /* NOTE:
16537 -@@ -148,7 +150,7 @@ static unsigned int pid_entry_count_dirs
16538 - return count;
16539 - }
16540 -
16541 --int maps_protect;
16542 -+int maps_protect = 1;
16543 - EXPORT_SYMBOL(maps_protect);
16544 -
16545 - static struct fs_struct *get_fs_struct(struct task_struct *task)
16546 -@@ -229,6 +231,9 @@ static int check_mem_permission(struct t
16547 - if (task == current)
16548 - return 0;
16549 -
16550 -+ if (gr_handle_proc_ptrace(task) || gr_acl_handle_procpidmem(task))
16551 -+ return -EPERM;
16552 -+
16553 - /*
16554 - * If current is actively ptrace'ing, and would also be
16555 - * permitted to freshly attach with ptrace now, permit it.
16556 -@@ -312,9 +317,9 @@ static int proc_pid_auxv(struct task_str
16557 - struct mm_struct *mm = get_task_mm(task);
16558 - if (mm) {
16559 - unsigned int nwords = 0;
16560 -- do
16561 -+ do {
16562 - nwords += 2;
16563 -- while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
16564 -+ } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
16565 - res = nwords * sizeof(mm->saved_auxv[0]);
16566 - if (res > PAGE_SIZE)
16567 - res = PAGE_SIZE;
16568 -@@ -1437,7 +1442,11 @@ static struct inode *proc_pid_make_inode
16569 - inode->i_gid = 0;
16570 - if (task_dumpable(task)) {
16571 - inode->i_uid = task->euid;
16572 -+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16573 -+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
16574 -+#else
16575 - inode->i_gid = task->egid;
16576 -+#endif
16577 - }
16578 - security_task_to_inode(task, inode);
16579 -
16580 -@@ -1453,17 +1462,45 @@ static int pid_getattr(struct vfsmount *
16581 - {
16582 - struct inode *inode = dentry->d_inode;
16583 - struct task_struct *task;
16584 -+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16585 -+ struct task_struct *tmp = current;
16586 -+#endif
16587 -+
16588 - generic_fillattr(inode, stat);
16589 -
16590 - rcu_read_lock();
16591 - stat->uid = 0;
16592 - stat->gid = 0;
16593 - task = pid_task(proc_pid(inode), PIDTYPE_PID);
16594 -- if (task) {
16595 -+
16596 -+ if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) {
16597 -+ rcu_read_unlock();
16598 -+ return -ENOENT;
16599 -+ }
16600 -+
16601 -+
16602 -+ if (task
16603 -+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16604 -+ && (!tmp->uid || (tmp->uid == task->uid)
16605 -+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16606 -+ || in_group_p(CONFIG_GRKERNSEC_PROC_GID)
16607 -+#endif
16608 -+ )
16609 -+#endif
16610 -+ ) {
16611 - if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
16612 -+#ifdef CONFIG_GRKERNSEC_PROC_USER
16613 -+ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
16614 -+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16615 -+ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
16616 -+#endif
16617 - task_dumpable(task)) {
16618 - stat->uid = task->euid;
16619 -+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16620 -+ stat->gid = CONFIG_GRKERNSEC_PROC_GID;
16621 -+#else
16622 - stat->gid = task->egid;
16623 -+#endif
16624 - }
16625 - }
16626 - rcu_read_unlock();
16627 -@@ -1491,11 +1528,21 @@ static int pid_revalidate(struct dentry
16628 - {
16629 - struct inode *inode = dentry->d_inode;
16630 - struct task_struct *task = get_proc_task(inode);
16631 -+
16632 - if (task) {
16633 - if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
16634 -+#ifdef CONFIG_GRKERNSEC_PROC_USER
16635 -+ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
16636 -+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16637 -+ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
16638 -+#endif
16639 - task_dumpable(task)) {
16640 - inode->i_uid = task->euid;
16641 -+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16642 -+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
16643 -+#else
16644 - inode->i_gid = task->egid;
16645 -+#endif
16646 - } else {
16647 - inode->i_uid = 0;
16648 - inode->i_gid = 0;
16649 -@@ -1863,12 +1910,22 @@ static const struct file_operations proc
16650 - static int proc_fd_permission(struct inode *inode, int mask)
16651 - {
16652 - int rv;
16653 -+ struct task_struct *task;
16654 -
16655 - rv = generic_permission(inode, mask, NULL);
16656 -- if (rv == 0)
16657 -- return 0;
16658 -+
16659 - if (task_pid(current) == proc_pid(inode))
16660 - rv = 0;
16661 -+
16662 -+ task = get_proc_task(inode);
16663 -+ if (task == NULL)
16664 -+ return rv;
16665 -+
16666 -+ if (gr_acl_handle_procpidmem(task))
16667 -+ rv = -EACCES;
16668 -+
16669 -+ put_task_struct(task);
16670 -+
16671 - return rv;
16672 - }
16673 -
16674 -@@ -1979,6 +2036,9 @@ static struct dentry *proc_pident_lookup
16675 - if (!task)
16676 - goto out_no_task;
16677 -
16678 -+ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
16679 -+ goto out;
16680 -+
16681 - /*
16682 - * Yes, it does not scale. And it should not. Don't add
16683 - * new entries into /proc/<tgid>/ without very good reasons.
16684 -@@ -2023,6 +2083,9 @@ static int proc_pident_readdir(struct fi
16685 - if (!task)
16686 - goto out_no_task;
16687 -
16688 -+ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
16689 -+ goto out;
16690 -+
16691 - ret = 0;
16692 - i = filp->f_pos;
16693 - switch (i) {
16694 -@@ -2385,6 +2448,9 @@ static struct dentry *proc_base_lookup(s
16695 - if (p > last)
16696 - goto out;
16697 -
16698 -+ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
16699 -+ goto out;
16700 -+
16701 - error = proc_base_instantiate(dir, dentry, task, p);
16702 -
16703 - out:
16704 -@@ -2518,6 +2584,9 @@ static const struct pid_entry tgid_base_
16705 - #ifdef CONFIG_TASK_IO_ACCOUNTING
16706 - INF("io", S_IRUGO, tgid_io_accounting),
16707 - #endif
16708 -+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
16709 -+ INF("ipaddr", S_IRUSR, pid_ipaddr),
16710 -+#endif
16711 - };
16712 -
16713 - static int proc_tgid_base_readdir(struct file * filp,
16714 -@@ -2647,7 +2716,14 @@ static struct dentry *proc_pid_instantia
16715 - if (!inode)
16716 - goto out;
16717 -
16718 -+#ifdef CONFIG_GRKERNSEC_PROC_USER
16719 -+ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
16720 -+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16721 -+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
16722 -+ inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP;
16723 -+#else
16724 - inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
16725 -+#endif
16726 - inode->i_op = &proc_tgid_base_inode_operations;
16727 - inode->i_fop = &proc_tgid_base_operations;
16728 - inode->i_flags|=S_IMMUTABLE;
16729 -@@ -2689,7 +2765,11 @@ struct dentry *proc_pid_lookup(struct in
16730 - if (!task)
16731 - goto out;
16732 -
16733 -+ if (gr_check_hidden_task(task))
16734 -+ goto out_put_task;
16735 -+
16736 - result = proc_pid_instantiate(dir, dentry, task, NULL);
16737 -+out_put_task:
16738 - put_task_struct(task);
16739 - out:
16740 - return result;
16741 -@@ -2754,6 +2834,9 @@ int proc_pid_readdir(struct file * filp,
16742 - {
16743 - unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
16744 - struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode);
16745 -+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16746 -+ struct task_struct *tmp = current;
16747 -+#endif
16748 - struct tgid_iter iter;
16749 - struct pid_namespace *ns;
16750 -
16751 -@@ -2772,6 +2855,17 @@ int proc_pid_readdir(struct file * filp,
16752 - for (iter = next_tgid(ns, iter);
16753 - iter.task;
16754 - iter.tgid += 1, iter = next_tgid(ns, iter)) {
16755 -+ if (gr_pid_is_chrooted(iter.task) || gr_check_hidden_task(iter.task)
16756 -+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16757 -+ || (tmp->uid && (iter.task->uid != tmp->uid)
16758 -+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16759 -+ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
16760 -+#endif
16761 -+ )
16762 -+#endif
16763 -+ )
16764 -+ continue;
16765 -+
16766 - filp->f_pos = iter.tgid + TGID_OFFSET;
16767 - if (proc_pid_fill_cache(filp, dirent, filldir, iter) < 0) {
16768 - put_task_struct(iter.task);
16769 -diff -urNp linux-2.6.27.6/fs/proc/inode.c linux-2.6.27.6/fs/proc/inode.c
16770 ---- linux-2.6.27.6/fs/proc/inode.c 2008-11-07 12:55:34.000000000 -0500
16771 -+++ linux-2.6.27.6/fs/proc/inode.c 2008-11-18 03:38:45.000000000 -0500
16772 -@@ -467,7 +467,11 @@ struct inode *proc_get_inode(struct supe
16773 - if (de->mode) {
16774 - inode->i_mode = de->mode;
16775 - inode->i_uid = de->uid;
16776 -+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16777 -+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
16778 -+#else
16779 - inode->i_gid = de->gid;
16780 -+#endif
16781 - }
16782 - if (de->size)
16783 - inode->i_size = de->size;
16784 -diff -urNp linux-2.6.27.6/fs/proc/internal.h linux-2.6.27.6/fs/proc/internal.h
16785 ---- linux-2.6.27.6/fs/proc/internal.h 2008-11-07 12:55:34.000000000 -0500
16786 -+++ linux-2.6.27.6/fs/proc/internal.h 2008-11-18 03:38:45.000000000 -0500
16787 -@@ -55,6 +55,9 @@ extern int proc_pid_status(struct seq_fi
16788 - struct pid *pid, struct task_struct *task);
16789 - extern int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
16790 - struct pid *pid, struct task_struct *task);
16791 -+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
16792 -+extern int proc_pid_ipaddr(struct task_struct *task, char *buffer);
16793 -+#endif
16794 - extern loff_t mem_lseek(struct file *file, loff_t offset, int orig);
16795 -
16796 - extern const struct file_operations proc_maps_operations;
16797 -diff -urNp linux-2.6.27.6/fs/proc/Kconfig linux-2.6.27.6/fs/proc/Kconfig
16798 ---- linux-2.6.27.6/fs/proc/Kconfig 2008-11-07 12:55:34.000000000 -0500
16799 -+++ linux-2.6.27.6/fs/proc/Kconfig 2008-11-18 03:38:45.000000000 -0500
16800 -@@ -30,12 +30,12 @@ config PROC_FS
16801 -
16802 - config PROC_KCORE
16803 - bool "/proc/kcore support" if !ARM
16804 -- depends on PROC_FS && MMU
16805 -+ depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
16806 -
16807 - config PROC_VMCORE
16808 - bool "/proc/vmcore support (EXPERIMENTAL)"
16809 -- depends on PROC_FS && CRASH_DUMP
16810 -- default y
16811 -+ depends on PROC_FS && CRASH_DUMP && !GRKERNSEC
16812 -+ default n
16813 - help
16814 - Exports the dump image of crashed kernel in ELF format.
16815 -
16816 -diff -urNp linux-2.6.27.6/fs/proc/proc_misc.c linux-2.6.27.6/fs/proc/proc_misc.c
16817 ---- linux-2.6.27.6/fs/proc/proc_misc.c 2008-11-07 12:55:34.000000000 -0500
16818 -+++ linux-2.6.27.6/fs/proc/proc_misc.c 2008-11-18 03:38:45.000000000 -0500
16819 -@@ -860,6 +860,8 @@ struct proc_dir_entry *proc_root_kcore;
16820 -
16821 - void __init proc_misc_init(void)
16822 - {
16823 -+ int gr_mode = 0;
16824 -+
16825 - static struct {
16826 - char *name;
16827 - int (*read_proc)(char*,char**,off_t,int,int*,void*);
16828 -@@ -875,13 +877,24 @@ void __init proc_misc_init(void)
16829 - {"stram", stram_read_proc},
16830 - #endif
16831 - {"filesystems", filesystems_read_proc},
16832 -+#ifndef CONFIG_GRKERNSEC_PROC_ADD
16833 - {"cmdline", cmdline_read_proc},
16834 -+#endif
16835 - {"execdomains", execdomains_read_proc},
16836 - {NULL,}
16837 - };
16838 - for (p = simple_ones; p->name; p++)
16839 - create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
16840 -
16841 -+#ifdef CONFIG_GRKERNSEC_PROC_USER
16842 -+ gr_mode = S_IRUSR;
16843 -+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16844 -+ gr_mode = S_IRUSR | S_IRGRP;
16845 -+#endif
16846 -+#ifdef CONFIG_GRKERNSEC_PROC_ADD
16847 -+ create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
16848 -+#endif
16849 -+
16850 - proc_symlink("mounts", NULL, "self/mounts");
16851 -
16852 - /* And now for trickier ones */
16853 -@@ -889,14 +902,18 @@ void __init proc_misc_init(void)
16854 - proc_create("kmsg", S_IRUSR, NULL, &proc_kmsg_operations);
16855 - #endif
16856 - proc_create("locks", 0, NULL, &proc_locks_operations);
16857 -+#ifdef CONFIG_GRKERNSEC_PROC_ADD
16858 -+ proc_create("devices", gr_mode, NULL, &proc_devinfo_operations);
16859 -+#else
16860 - proc_create("devices", 0, NULL, &proc_devinfo_operations);
16861 -+#endif
16862 - proc_create("cpuinfo", 0, NULL, &proc_cpuinfo_operations);
16863 - #ifdef CONFIG_BLOCK
16864 - proc_create("partitions", 0, NULL, &proc_partitions_operations);
16865 - #endif
16866 - proc_create("stat", 0, NULL, &proc_stat_operations);
16867 - proc_create("interrupts", 0, NULL, &proc_interrupts_operations);
16868 --#ifdef CONFIG_SLABINFO
16869 -+#if defined(CONFIG_SLABINFO) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
16870 - proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
16871 - #ifdef CONFIG_DEBUG_SLAB_LEAK
16872 - proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations);
16873 -@@ -918,7 +935,7 @@ void __init proc_misc_init(void)
16874 - #ifdef CONFIG_SCHEDSTATS
16875 - proc_create("schedstat", 0, NULL, &proc_schedstat_operations);
16876 - #endif
16877 --#ifdef CONFIG_PROC_KCORE
16878 -+#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
16879 - proc_root_kcore = proc_create("kcore", S_IRUSR, NULL, &proc_kcore_operations);
16880 - if (proc_root_kcore)
16881 - proc_root_kcore->size =
16882 -diff -urNp linux-2.6.27.6/fs/proc/proc_net.c linux-2.6.27.6/fs/proc/proc_net.c
16883 ---- linux-2.6.27.6/fs/proc/proc_net.c 2008-11-07 12:55:34.000000000 -0500
16884 -+++ linux-2.6.27.6/fs/proc/proc_net.c 2008-11-18 03:38:45.000000000 -0500
16885 -@@ -106,6 +106,14 @@ static struct net *get_proc_task_net(str
16886 - struct nsproxy *ns;
16887 - struct net *net = NULL;
16888 -
16889 -+#ifdef CONFIG_GRKERNSEC_PROC_USER
16890 -+ if (current->fsuid)
16891 -+ return net;
16892 -+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16893 -+ if (current->fsuid && !in_group_p(CONFIG_GRKERNSEC_PROC_GID))
16894 -+ return net;
16895 -+#endif
16896 -+
16897 - rcu_read_lock();
16898 - task = pid_task(proc_pid(dir), PIDTYPE_PID);
16899 - if (task != NULL) {
16900 -diff -urNp linux-2.6.27.6/fs/proc/proc_sysctl.c linux-2.6.27.6/fs/proc/proc_sysctl.c
16901 ---- linux-2.6.27.6/fs/proc/proc_sysctl.c 2008-11-07 12:55:34.000000000 -0500
16902 -+++ linux-2.6.27.6/fs/proc/proc_sysctl.c 2008-11-18 03:38:45.000000000 -0500
16903 -@@ -7,6 +7,8 @@
16904 - #include <linux/security.h>
16905 - #include "internal.h"
16906 -
16907 -+extern __u32 gr_handle_sysctl(const struct ctl_table *table, const int op);
16908 -+
16909 - static struct dentry_operations proc_sys_dentry_operations;
16910 - static const struct file_operations proc_sys_file_operations;
16911 - static const struct inode_operations proc_sys_inode_operations;
16912 -@@ -109,6 +111,9 @@ static struct dentry *proc_sys_lookup(st
16913 - if (!p)
16914 - goto out;
16915 -
16916 -+ if (gr_handle_sysctl(p, MAY_EXEC))
16917 -+ goto out;
16918 -+
16919 - err = ERR_PTR(-ENOMEM);
16920 - inode = proc_sys_make_inode(dir->i_sb, h ? h : head, p);
16921 - if (h)
16922 -@@ -228,6 +233,9 @@ static int scan(struct ctl_table_header
16923 - if (*pos < file->f_pos)
16924 - continue;
16925 -
16926 -+ if (gr_handle_sysctl(table, 0))
16927 -+ continue;
16928 -+
16929 - res = proc_sys_fill_cache(file, dirent, filldir, head, table);
16930 - if (res)
16931 - return res;
16932 -@@ -338,6 +346,9 @@ static int proc_sys_getattr(struct vfsmo
16933 - if (IS_ERR(head))
16934 - return PTR_ERR(head);
16935 -
16936 -+ if (table && gr_handle_sysctl(table, MAY_EXEC))
16937 -+ return -ENOENT;
16938 -+
16939 - generic_fillattr(inode, stat);
16940 - if (table)
16941 - stat->mode = (stat->mode & S_IFMT) | table->mode;
16942 -diff -urNp linux-2.6.27.6/fs/proc/root.c linux-2.6.27.6/fs/proc/root.c
16943 ---- linux-2.6.27.6/fs/proc/root.c 2008-11-07 12:55:34.000000000 -0500
16944 -+++ linux-2.6.27.6/fs/proc/root.c 2008-11-18 03:38:45.000000000 -0500
16945 -@@ -135,7 +135,15 @@ void __init proc_root_init(void)
16946 - #ifdef CONFIG_PROC_DEVICETREE
16947 - proc_device_tree_init();
16948 - #endif
16949 -+#ifdef CONFIG_GRKERNSEC_PROC_ADD
16950 -+#ifdef CONFIG_GRKERNSEC_PROC_USER
16951 -+ proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
16952 -+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16953 -+ proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
16954 -+#endif
16955 -+#else
16956 - proc_mkdir("bus", NULL);
16957 -+#endif
16958 - proc_sys_init();
16959 - }
16960 -
16961 -diff -urNp linux-2.6.27.6/fs/proc/task_mmu.c linux-2.6.27.6/fs/proc/task_mmu.c
16962 ---- linux-2.6.27.6/fs/proc/task_mmu.c 2008-11-07 12:55:34.000000000 -0500
16963 -+++ linux-2.6.27.6/fs/proc/task_mmu.c 2008-11-18 03:38:45.000000000 -0500
16964 -@@ -46,15 +46,26 @@ void task_mem(struct seq_file *m, struct
16965 - "VmStk:\t%8lu kB\n"
16966 - "VmExe:\t%8lu kB\n"
16967 - "VmLib:\t%8lu kB\n"
16968 -- "VmPTE:\t%8lu kB\n",
16969 -- hiwater_vm << (PAGE_SHIFT-10),
16970 -+ "VmPTE:\t%8lu kB\n"
16971 -+
16972 -+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
16973 -+ "CsBase:\t%8lx\nCsLim:\t%8lx\n"
16974 -+#endif
16975 -+
16976 -+ ,hiwater_vm << (PAGE_SHIFT-10),
16977 - (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
16978 - mm->locked_vm << (PAGE_SHIFT-10),
16979 - hiwater_rss << (PAGE_SHIFT-10),
16980 - total_rss << (PAGE_SHIFT-10),
16981 - data << (PAGE_SHIFT-10),
16982 - mm->stack_vm << (PAGE_SHIFT-10), text, lib,
16983 -- (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
16984 -+ (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
16985 -+
16986 -+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
16987 -+ , mm->context.user_cs_base, mm->context.user_cs_limit
16988 -+#endif
16989 -+
16990 -+ );
16991 - }
16992 -
16993 - unsigned long task_vsize(struct mm_struct *mm)
16994 -@@ -198,6 +209,12 @@ static int do_maps_open(struct inode *in
16995 - return ret;
16996 - }
16997 -
16998 -+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16999 -+#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
17000 -+ (_mm->pax_flags & MF_PAX_RANDMMAP || \
17001 -+ _mm->pax_flags & MF_PAX_SEGMEXEC))
17002 -+#endif
17003 -+
17004 - static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
17005 - {
17006 - struct mm_struct *mm = vma->vm_mm;
17007 -@@ -214,13 +231,22 @@ static void show_map_vma(struct seq_file
17008 - }
17009 -
17010 - seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n",
17011 -+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
17012 -+ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
17013 -+ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
17014 -+#else
17015 - vma->vm_start,
17016 - vma->vm_end,
17017 -+#endif
17018 - flags & VM_READ ? 'r' : '-',
17019 - flags & VM_WRITE ? 'w' : '-',
17020 - flags & VM_EXEC ? 'x' : '-',
17021 - flags & VM_MAYSHARE ? 's' : 'p',
17022 -+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
17023 -+ PAX_RAND_FLAGS(mm) ? 0UL : ((loff_t)vma->vm_pgoff) << PAGE_SHIFT,
17024 -+#else
17025 - ((loff_t)vma->vm_pgoff) << PAGE_SHIFT,
17026 -+#endif
17027 - MAJOR(dev), MINOR(dev), ino, &len);
17028 -
17029 - /*
17030 -@@ -234,11 +260,11 @@ static void show_map_vma(struct seq_file
17031 - const char *name = arch_vma_name(vma);
17032 - if (!name) {
17033 - if (mm) {
17034 -- if (vma->vm_start <= mm->start_brk &&
17035 -- vma->vm_end >= mm->brk) {
17036 -+ if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
17037 - name = "[heap]";
17038 -- } else if (vma->vm_start <= mm->start_stack &&
17039 -- vma->vm_end >= mm->start_stack) {
17040 -+ } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
17041 -+ (vma->vm_start <= mm->start_stack &&
17042 -+ vma->vm_end >= mm->start_stack)) {
17043 - name = "[stack]";
17044 - }
17045 - } else {
17046 -@@ -387,9 +413,16 @@ static int show_smap(struct seq_file *m,
17047 - return -EACCES;
17048 -
17049 - memset(&mss, 0, sizeof mss);
17050 -- mss.vma = vma;
17051 -- if (vma->vm_mm && !is_vm_hugetlb_page(vma))
17052 -- walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
17053 -+
17054 -+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
17055 -+ if (!PAX_RAND_FLAGS(vma->vm_mm)) {
17056 -+#endif
17057 -+ mss.vma = vma;
17058 -+ if (vma->vm_mm && !is_vm_hugetlb_page(vma))
17059 -+ walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
17060 -+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
17061 -+ }
17062 -+#endif
17063 -
17064 - show_map_vma(m, vma);
17065 -
17066 -@@ -403,7 +436,11 @@ static int show_smap(struct seq_file *m,
17067 - "Private_Dirty: %8lu kB\n"
17068 - "Referenced: %8lu kB\n"
17069 - "Swap: %8lu kB\n",
17070 -+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
17071 -+ PAX_RAND_FLAGS(vma->vm_mm) ? 0UL : (vma->vm_end - vma->vm_start) >> 10,
17072 -+#else
17073 - (vma->vm_end - vma->vm_start) >> 10,
17074 -+#endif
17075 - mss.resident >> 10,
17076 - (unsigned long)(mss.pss >> (10 + PSS_SHIFT)),
17077 - mss.shared_clean >> 10,
17078 -@@ -757,6 +794,11 @@ static int show_numa_map_checked(struct
17079 - struct proc_maps_private *priv = m->private;
17080 - struct task_struct *task = priv->task;
17081 -
17082 -+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
17083 -+ if (!ptrace_may_access(task, PTRACE_MODE_READ))
17084 -+ return -EACCES;
17085 -+#endif
17086 -+
17087 - if (maps_protect && !ptrace_may_access(task, PTRACE_MODE_READ))
17088 - return -EACCES;
17089 -
17090 -diff -urNp linux-2.6.27.6/fs/readdir.c linux-2.6.27.6/fs/readdir.c
17091 ---- linux-2.6.27.6/fs/readdir.c 2008-11-07 12:55:34.000000000 -0500
17092 -+++ linux-2.6.27.6/fs/readdir.c 2008-11-18 03:38:45.000000000 -0500
17093 -@@ -16,6 +16,8 @@
17094 - #include <linux/security.h>
17095 - #include <linux/syscalls.h>
17096 - #include <linux/unistd.h>
17097 -+#include <linux/namei.h>
17098 -+#include <linux/grsecurity.h>
17099 -
17100 - #include <asm/uaccess.h>
17101 -
17102 -@@ -67,6 +69,7 @@ struct old_linux_dirent {
17103 -
17104 - struct readdir_callback {
17105 - struct old_linux_dirent __user * dirent;
17106 -+ struct file * file;
17107 - int result;
17108 - };
17109 -
17110 -@@ -84,6 +87,10 @@ static int fillonedir(void * __buf, cons
17111 - buf->result = -EOVERFLOW;
17112 - return -EOVERFLOW;
17113 - }
17114 -+
17115 -+ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
17116 -+ return 0;
17117 -+
17118 - buf->result++;
17119 - dirent = buf->dirent;
17120 - if (!access_ok(VERIFY_WRITE, dirent,
17121 -@@ -115,6 +122,7 @@ asmlinkage long old_readdir(unsigned int
17122 -
17123 - buf.result = 0;
17124 - buf.dirent = dirent;
17125 -+ buf.file = file;
17126 -
17127 - error = vfs_readdir(file, fillonedir, &buf);
17128 - if (error >= 0)
17129 -@@ -141,6 +149,7 @@ struct linux_dirent {
17130 - struct getdents_callback {
17131 - struct linux_dirent __user * current_dir;
17132 - struct linux_dirent __user * previous;
17133 -+ struct file * file;
17134 - int count;
17135 - int error;
17136 - };
17137 -@@ -161,6 +170,10 @@ static int filldir(void * __buf, const c
17138 - buf->error = -EOVERFLOW;
17139 - return -EOVERFLOW;
17140 - }
17141 -+
17142 -+ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
17143 -+ return 0;
17144 -+
17145 - dirent = buf->previous;
17146 - if (dirent) {
17147 - if (__put_user(offset, &dirent->d_off))
17148 -@@ -207,6 +220,7 @@ asmlinkage long sys_getdents(unsigned in
17149 - buf.previous = NULL;
17150 - buf.count = count;
17151 - buf.error = 0;
17152 -+ buf.file = file;
17153 -
17154 - error = vfs_readdir(file, filldir, &buf);
17155 - if (error < 0)
17156 -@@ -229,6 +243,7 @@ out:
17157 - struct getdents_callback64 {
17158 - struct linux_dirent64 __user * current_dir;
17159 - struct linux_dirent64 __user * previous;
17160 -+ struct file *file;
17161 - int count;
17162 - int error;
17163 - };
17164 -@@ -243,6 +258,10 @@ static int filldir64(void * __buf, const
17165 - buf->error = -EINVAL; /* only used if we fail.. */
17166 - if (reclen > buf->count)
17167 - return -EINVAL;
17168 -+
17169 -+ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
17170 -+ return 0;
17171 -+
17172 - dirent = buf->previous;
17173 - if (dirent) {
17174 - if (__put_user(offset, &dirent->d_off))
17175 -@@ -289,6 +308,7 @@ asmlinkage long sys_getdents64(unsigned
17176 -
17177 - buf.current_dir = dirent;
17178 - buf.previous = NULL;
17179 -+ buf.file = file;
17180 - buf.count = count;
17181 - buf.error = 0;
17182 -
17183 -diff -urNp linux-2.6.27.6/fs/select.c linux-2.6.27.6/fs/select.c
17184 ---- linux-2.6.27.6/fs/select.c 2008-11-07 12:55:34.000000000 -0500
17185 -+++ linux-2.6.27.6/fs/select.c 2008-11-18 03:38:45.000000000 -0500
17186 -@@ -24,6 +24,7 @@
17187 - #include <linux/fdtable.h>
17188 - #include <linux/fs.h>
17189 - #include <linux/rcupdate.h>
17190 -+#include <linux/grsecurity.h>
17191 -
17192 - #include <asm/uaccess.h>
17193 -
17194 -@@ -658,6 +659,7 @@ int do_sys_poll(struct pollfd __user *uf
17195 - struct poll_list *walk = head;
17196 - unsigned long todo = nfds;
17197 -
17198 -+ gr_learn_resource(current, RLIMIT_NOFILE, nfds, 1);
17199 - if (nfds > current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
17200 - return -EINVAL;
17201 -
17202 -diff -urNp linux-2.6.27.6/fs/smbfs/symlink.c linux-2.6.27.6/fs/smbfs/symlink.c
17203 ---- linux-2.6.27.6/fs/smbfs/symlink.c 2008-11-07 12:55:34.000000000 -0500
17204 -+++ linux-2.6.27.6/fs/smbfs/symlink.c 2008-11-18 03:38:45.000000000 -0500
17205 -@@ -55,7 +55,7 @@ static void *smb_follow_link(struct dent
17206 -
17207 - static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
17208 - {
17209 -- char *s = nd_get_link(nd);
17210 -+ const char *s = nd_get_link(nd);
17211 - if (!IS_ERR(s))
17212 - __putname(s);
17213 - }
17214 -diff -urNp linux-2.6.27.6/fs/sysfs/symlink.c linux-2.6.27.6/fs/sysfs/symlink.c
17215 ---- linux-2.6.27.6/fs/sysfs/symlink.c 2008-11-07 12:55:34.000000000 -0500
17216 -+++ linux-2.6.27.6/fs/sysfs/symlink.c 2008-11-18 03:38:45.000000000 -0500
17217 -@@ -200,7 +200,7 @@ static void *sysfs_follow_link(struct de
17218 -
17219 - static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
17220 - {
17221 -- char *page = nd_get_link(nd);
17222 -+ const char *page = nd_get_link(nd);
17223 - if (!IS_ERR(page))
17224 - free_page((unsigned long)page);
17225 - }
17226 -diff -urNp linux-2.6.27.6/fs/udf/balloc.c linux-2.6.27.6/fs/udf/balloc.c
17227 ---- linux-2.6.27.6/fs/udf/balloc.c 2008-11-07 12:55:34.000000000 -0500
17228 -+++ linux-2.6.27.6/fs/udf/balloc.c 2008-11-18 03:38:45.000000000 -0500
17229 -@@ -169,9 +169,7 @@ static void udf_bitmap_free_blocks(struc
17230 - unsigned long overflow;
17231 -
17232 - mutex_lock(&sbi->s_alloc_mutex);
17233 -- if (bloc.logicalBlockNum < 0 ||
17234 -- (bloc.logicalBlockNum + count) >
17235 -- sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
17236 -+ if (bloc.logicalBlockNum + count > sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
17237 - udf_debug("%d < %d || %d + %d > %d\n",
17238 - bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
17239 - sbi->s_partmaps[bloc.partitionReferenceNum].
17240 -@@ -239,7 +237,7 @@ static int udf_bitmap_prealloc_blocks(st
17241 -
17242 - mutex_lock(&sbi->s_alloc_mutex);
17243 - part_len = sbi->s_partmaps[partition].s_partition_len;
17244 -- if (first_block < 0 || first_block >= part_len)
17245 -+ if (first_block >= part_len)
17246 - goto out;
17247 -
17248 - if (first_block + block_count > part_len)
17249 -@@ -300,7 +298,7 @@ static int udf_bitmap_new_block(struct s
17250 - mutex_lock(&sbi->s_alloc_mutex);
17251 -
17252 - repeat:
17253 -- if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
17254 -+ if (goal >= sbi->s_partmaps[partition].s_partition_len)
17255 - goal = 0;
17256 -
17257 - nr_groups = bitmap->s_nr_groups;
17258 -@@ -438,9 +436,7 @@ static void udf_table_free_blocks(struct
17259 - struct udf_inode_info *iinfo;
17260 -
17261 - mutex_lock(&sbi->s_alloc_mutex);
17262 -- if (bloc.logicalBlockNum < 0 ||
17263 -- (bloc.logicalBlockNum + count) >
17264 -- sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
17265 -+ if (bloc.logicalBlockNum + count > sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
17266 - udf_debug("%d < %d || %d + %d > %d\n",
17267 - bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
17268 - sbi->s_partmaps[bloc.partitionReferenceNum].
17269 -@@ -671,8 +667,7 @@ static int udf_table_prealloc_blocks(str
17270 - int8_t etype = -1;
17271 - struct udf_inode_info *iinfo;
17272 -
17273 -- if (first_block < 0 ||
17274 -- first_block >= sbi->s_partmaps[partition].s_partition_len)
17275 -+ if (first_block >= sbi->s_partmaps[partition].s_partition_len)
17276 - return 0;
17277 -
17278 - iinfo = UDF_I(table);
17279 -@@ -750,7 +745,7 @@ static int udf_table_new_block(struct su
17280 - return newblock;
17281 -
17282 - mutex_lock(&sbi->s_alloc_mutex);
17283 -- if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
17284 -+ if (goal >= sbi->s_partmaps[partition].s_partition_len)
17285 - goal = 0;
17286 -
17287 - /* We search for the closest matching block to goal. If we find
17288 -diff -urNp linux-2.6.27.6/fs/ufs/inode.c linux-2.6.27.6/fs/ufs/inode.c
17289 ---- linux-2.6.27.6/fs/ufs/inode.c 2008-11-07 12:55:34.000000000 -0500
17290 -+++ linux-2.6.27.6/fs/ufs/inode.c 2008-11-18 03:38:45.000000000 -0500
17291 -@@ -56,9 +56,7 @@ static int ufs_block_to_path(struct inod
17292 -
17293 -
17294 - UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
17295 -- if (i_block < 0) {
17296 -- ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
17297 -- } else if (i_block < direct_blocks) {
17298 -+ if (i_block < direct_blocks) {
17299 - offsets[n++] = i_block;
17300 - } else if ((i_block -= direct_blocks) < indirect_blocks) {
17301 - offsets[n++] = UFS_IND_BLOCK;
17302 -@@ -440,8 +438,6 @@ int ufs_getfrag_block(struct inode *inod
17303 - lock_kernel();
17304 -
17305 - UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
17306 -- if (fragment < 0)
17307 -- goto abort_negative;
17308 - if (fragment >
17309 - ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
17310 - << uspi->s_fpbshift))
17311 -@@ -504,10 +500,6 @@ abort:
17312 - unlock_kernel();
17313 - return err;
17314 -
17315 --abort_negative:
17316 -- ufs_warning(sb, "ufs_get_block", "block < 0");
17317 -- goto abort;
17318 --
17319 - abort_too_big:
17320 - ufs_warning(sb, "ufs_get_block", "block > big");
17321 - goto abort;
17322 -diff -urNp linux-2.6.27.6/fs/utimes.c linux-2.6.27.6/fs/utimes.c
17323 ---- linux-2.6.27.6/fs/utimes.c 2008-11-07 12:55:34.000000000 -0500
17324 -+++ linux-2.6.27.6/fs/utimes.c 2008-11-18 03:38:45.000000000 -0500
17325 -@@ -8,6 +8,7 @@
17326 - #include <linux/stat.h>
17327 - #include <linux/utime.h>
17328 - #include <linux/syscalls.h>
17329 -+#include <linux/grsecurity.h>
17330 - #include <asm/uaccess.h>
17331 - #include <asm/unistd.h>
17332 -
17333 -@@ -101,6 +102,12 @@ static int utimes_common(struct path *pa
17334 - goto mnt_drop_write_and_out;
17335 - }
17336 - }
17337 -+
17338 -+ if (!gr_acl_handle_utime(path->dentry, path->mnt)) {
17339 -+ error = -EACCES;
17340 -+ goto mnt_drop_write_and_out;
17341 -+ }
17342 -+
17343 - mutex_lock(&inode->i_mutex);
17344 - error = notify_change(path->dentry, &newattrs);
17345 - mutex_unlock(&inode->i_mutex);
17346 -diff -urNp linux-2.6.27.6/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.27.6/fs/xfs/linux-2.6/xfs_iops.c
17347 ---- linux-2.6.27.6/fs/xfs/linux-2.6/xfs_iops.c 2008-11-07 12:55:34.000000000 -0500
17348 -+++ linux-2.6.27.6/fs/xfs/linux-2.6/xfs_iops.c 2008-11-18 03:38:45.000000000 -0500
17349 -@@ -500,7 +500,7 @@ xfs_vn_put_link(
17350 - struct nameidata *nd,
17351 - void *p)
17352 - {
17353 -- char *s = nd_get_link(nd);
17354 -+ const char *s = nd_get_link(nd);
17355 -
17356 - if (!IS_ERR(s))
17357 - kfree(s);
17358 -diff -urNp linux-2.6.27.6/fs/xfs/xfs_bmap.c linux-2.6.27.6/fs/xfs/xfs_bmap.c
17359 ---- linux-2.6.27.6/fs/xfs/xfs_bmap.c 2008-11-07 12:55:34.000000000 -0500
17360 -+++ linux-2.6.27.6/fs/xfs/xfs_bmap.c 2008-11-18 03:38:45.000000000 -0500
17361 -@@ -360,7 +360,7 @@ xfs_bmap_validate_ret(
17362 - int nmap,
17363 - int ret_nmap);
17364 - #else
17365 --#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
17366 -+#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
17367 - #endif /* DEBUG */
17368 -
17369 - #if defined(XFS_RW_TRACE)
17370 -diff -urNp linux-2.6.27.6/grsecurity/gracl_alloc.c linux-2.6.27.6/grsecurity/gracl_alloc.c
17371 ---- linux-2.6.27.6/grsecurity/gracl_alloc.c 1969-12-31 19:00:00.000000000 -0500
17372 -+++ linux-2.6.27.6/grsecurity/gracl_alloc.c 2008-11-18 03:38:45.000000000 -0500
17373 -@@ -0,0 +1,91 @@
17374 -+#include <linux/kernel.h>
17375 -+#include <linux/mm.h>
17376 -+#include <linux/slab.h>
17377 -+#include <linux/vmalloc.h>
17378 -+#include <linux/gracl.h>
17379 -+#include <linux/grsecurity.h>
17380 -+
17381 -+static unsigned long alloc_stack_next = 1;
17382 -+static unsigned long alloc_stack_size = 1;
17383 -+static void **alloc_stack;
17384 -+
17385 -+static __inline__ int
17386 -+alloc_pop(void)
17387 -+{
17388 -+ if (alloc_stack_next == 1)
17389 -+ return 0;
17390 -+
17391 -+ kfree(alloc_stack[alloc_stack_next - 2]);
17392 -+
17393 -+ alloc_stack_next--;
17394 -+
17395 -+ return 1;
17396 -+}
17397 -+
17398 -+static __inline__ void
17399 -+alloc_push(void *buf)
17400 -+{
17401 -+ if (alloc_stack_next >= alloc_stack_size)
17402 -+ BUG();
17403 -+
17404 -+ alloc_stack[alloc_stack_next - 1] = buf;
17405 -+
17406 -+ alloc_stack_next++;
17407 -+
17408 -+ return;
17409 -+}
17410 -+
17411 -+void *
17412 -+acl_alloc(unsigned long len)
17413 -+{
17414 -+ void *ret;
17415 -+
17416 -+ if (len > PAGE_SIZE)
17417 -+ BUG();
17418 -+
17419 -+ ret = kmalloc(len, GFP_KERNEL);
17420 -+
17421 -+ if (ret)
17422 -+ alloc_push(ret);
17423 -+
17424 -+ return ret;
17425 -+}
17426 -+
17427 -+void
17428 -+acl_free_all(void)
17429 -+{
17430 -+ if (gr_acl_is_enabled() || !alloc_stack)
17431 -+ return;
17432 -+
17433 -+ while (alloc_pop()) ;
17434 -+
17435 -+ if (alloc_stack) {
17436 -+ if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
17437 -+ kfree(alloc_stack);
17438 -+ else
17439 -+ vfree(alloc_stack);
17440 -+ }
17441 -+
17442 -+ alloc_stack = NULL;
17443 -+ alloc_stack_size = 1;
17444 -+ alloc_stack_next = 1;
17445 -+
17446 -+ return;
17447 -+}
17448 -+
17449 -+int
17450 -+acl_alloc_stack_init(unsigned long size)
17451 -+{
17452 -+ if ((size * sizeof (void *)) <= PAGE_SIZE)
17453 -+ alloc_stack =
17454 -+ (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
17455 -+ else
17456 -+ alloc_stack = (void **) vmalloc(size * sizeof (void *));
17457 -+
17458 -+ alloc_stack_size = size;
17459 -+
17460 -+ if (!alloc_stack)
17461 -+ return 0;
17462 -+ else
17463 -+ return 1;
17464 -+}
17465 -diff -urNp linux-2.6.27.6/grsecurity/gracl.c linux-2.6.27.6/grsecurity/gracl.c
17466 ---- linux-2.6.27.6/grsecurity/gracl.c 1969-12-31 19:00:00.000000000 -0500
17467 -+++ linux-2.6.27.6/grsecurity/gracl.c 2008-11-18 03:38:45.000000000 -0500
17468 -@@ -0,0 +1,3722 @@
17469 -+#include <linux/kernel.h>
17470 -+#include <linux/module.h>
17471 -+#include <linux/sched.h>
17472 -+#include <linux/mm.h>
17473 -+#include <linux/file.h>
17474 -+#include <linux/fs.h>
17475 -+#include <linux/namei.h>
17476 -+#include <linux/mount.h>
17477 -+#include <linux/tty.h>
17478 -+#include <linux/proc_fs.h>
17479 -+#include <linux/smp_lock.h>
17480 -+#include <linux/slab.h>
17481 -+#include <linux/vmalloc.h>
17482 -+#include <linux/types.h>
17483 -+#include <linux/sysctl.h>
17484 -+#include <linux/netdevice.h>
17485 -+#include <linux/ptrace.h>
17486 -+#include <linux/gracl.h>
17487 -+#include <linux/gralloc.h>
17488 -+#include <linux/grsecurity.h>
17489 -+#include <linux/grinternal.h>
17490 -+#include <linux/pid_namespace.h>
17491 -+#include <linux/fdtable.h>
17492 -+#include <linux/percpu.h>
17493 -+
17494 -+#include <asm/uaccess.h>
17495 -+#include <asm/errno.h>
17496 -+#include <asm/mman.h>
17497 -+
17498 -+static struct acl_role_db acl_role_set;
17499 -+static struct name_db name_set;
17500 -+static struct inodev_db inodev_set;
17501 -+
17502 -+/* for keeping track of userspace pointers used for subjects, so we
17503 -+ can share references in the kernel as well
17504 -+*/
17505 -+
17506 -+static struct dentry *real_root;
17507 -+static struct vfsmount *real_root_mnt;
17508 -+
17509 -+static struct acl_subj_map_db subj_map_set;
17510 -+
17511 -+static struct acl_role_label *default_role;
17512 -+
17513 -+static u16 acl_sp_role_value;
17514 -+
17515 -+extern char *gr_shared_page[4];
17516 -+static DECLARE_MUTEX(gr_dev_sem);
17517 -+DEFINE_RWLOCK(gr_inode_lock);
17518 -+
17519 -+struct gr_arg *gr_usermode;
17520 -+
17521 -+static unsigned int gr_status = GR_STATUS_INIT;
17522 -+
17523 -+extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
17524 -+extern void gr_clear_learn_entries(void);
17525 -+
17526 -+#ifdef CONFIG_GRKERNSEC_RESLOG
17527 -+extern void gr_log_resource(const struct task_struct *task,
17528 -+ const int res, const unsigned long wanted, const int gt);
17529 -+#endif
17530 -+
17531 -+unsigned char *gr_system_salt;
17532 -+unsigned char *gr_system_sum;
17533 -+
17534 -+static struct sprole_pw **acl_special_roles = NULL;
17535 -+static __u16 num_sprole_pws = 0;
17536 -+
17537 -+static struct acl_role_label *kernel_role = NULL;
17538 -+
17539 -+static unsigned int gr_auth_attempts = 0;
17540 -+static unsigned long gr_auth_expires = 0UL;
17541 -+
17542 -+extern struct vfsmount *sock_mnt;
17543 -+extern struct vfsmount *pipe_mnt;
17544 -+extern struct vfsmount *shm_mnt;
17545 -+static struct acl_object_label *fakefs_obj;
17546 -+
17547 -+extern int gr_init_uidset(void);
17548 -+extern void gr_free_uidset(void);
17549 -+extern void gr_remove_uid(uid_t uid);
17550 -+extern int gr_find_uid(uid_t uid);
17551 -+
17552 -+__inline__ int
17553 -+gr_acl_is_enabled(void)
17554 -+{
17555 -+ return (gr_status & GR_READY);
17556 -+}
17557 -+
17558 -+char gr_roletype_to_char(void)
17559 -+{
17560 -+ switch (current->role->roletype &
17561 -+ (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
17562 -+ GR_ROLE_SPECIAL)) {
17563 -+ case GR_ROLE_DEFAULT:
17564 -+ return 'D';
17565 -+ case GR_ROLE_USER:
17566 -+ return 'U';
17567 -+ case GR_ROLE_GROUP:
17568 -+ return 'G';
17569 -+ case GR_ROLE_SPECIAL:
17570 -+ return 'S';
17571 -+ }
17572 -+
17573 -+ return 'X';
17574 -+}
17575 -+
17576 -+__inline__ int
17577 -+gr_acl_tpe_check(void)
17578 -+{
17579 -+ if (unlikely(!(gr_status & GR_READY)))
17580 -+ return 0;
17581 -+ if (current->role->roletype & GR_ROLE_TPE)
17582 -+ return 1;
17583 -+ else
17584 -+ return 0;
17585 -+}
17586 -+
17587 -+int
17588 -+gr_handle_rawio(const struct inode *inode)
17589 -+{
17590 -+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
17591 -+ if (inode && S_ISBLK(inode->i_mode) &&
17592 -+ grsec_enable_chroot_caps && proc_is_chrooted(current) &&
17593 -+ !capable(CAP_SYS_RAWIO))
17594 -+ return 1;
17595 -+#endif
17596 -+ return 0;
17597 -+}
17598 -+
17599 -+static int
17600 -+gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
17601 -+{
17602 -+ int i;
17603 -+ unsigned long *l1;
17604 -+ unsigned long *l2;
17605 -+ unsigned char *c1;
17606 -+ unsigned char *c2;
17607 -+ int num_longs;
17608 -+
17609 -+ if (likely(lena != lenb))
17610 -+ return 0;
17611 -+
17612 -+ l1 = (unsigned long *)a;
17613 -+ l2 = (unsigned long *)b;
17614 -+
17615 -+ num_longs = lena / sizeof(unsigned long);
17616 -+
17617 -+ for (i = num_longs; i--; l1++, l2++) {
17618 -+ if (unlikely(*l1 != *l2))
17619 -+ return 0;
17620 -+ }
17621 -+
17622 -+ c1 = (unsigned char *) l1;
17623 -+ c2 = (unsigned char *) l2;
17624 -+
17625 -+ i = lena - (num_longs * sizeof(unsigned long));
17626 -+
17627 -+ for (; i--; c1++, c2++) {
17628 -+ if (unlikely(*c1 != *c2))
17629 -+ return 0;
17630 -+ }
17631 -+
17632 -+ return 1;
17633 -+}
17634 -+
17635 -+static char * __our_d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
17636 -+ struct dentry *root, struct vfsmount *rootmnt,
17637 -+ char *buffer, int buflen)
17638 -+{
17639 -+ char * end = buffer+buflen;
17640 -+ char * retval;
17641 -+ int namelen;
17642 -+
17643 -+ *--end = '\0';
17644 -+ buflen--;
17645 -+
17646 -+ if (buflen < 1)
17647 -+ goto Elong;
17648 -+ /* Get '/' right */
17649 -+ retval = end-1;
17650 -+ *retval = '/';
17651 -+
17652 -+ for (;;) {
17653 -+ struct dentry * parent;
17654 -+
17655 -+ if (dentry == root && vfsmnt == rootmnt)
17656 -+ break;
17657 -+ if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
17658 -+ /* Global root? */
17659 -+ spin_lock(&vfsmount_lock);
17660 -+ if (vfsmnt->mnt_parent == vfsmnt) {
17661 -+ spin_unlock(&vfsmount_lock);
17662 -+ goto global_root;
17663 -+ }
17664 -+ dentry = vfsmnt->mnt_mountpoint;
17665 -+ vfsmnt = vfsmnt->mnt_parent;
17666 -+ spin_unlock(&vfsmount_lock);
17667 -+ continue;
17668 -+ }
17669 -+ parent = dentry->d_parent;
17670 -+ prefetch(parent);
17671 -+ namelen = dentry->d_name.len;
17672 -+ buflen -= namelen + 1;
17673 -+ if (buflen < 0)
17674 -+ goto Elong;
17675 -+ end -= namelen;
17676 -+ memcpy(end, dentry->d_name.name, namelen);
17677 -+ *--end = '/';
17678 -+ retval = end;
17679 -+ dentry = parent;
17680 -+ }
17681 -+
17682 -+ return retval;
17683 -+
17684 -+global_root:
17685 -+ namelen = dentry->d_name.len;
17686 -+ buflen -= namelen;
17687 -+ if (buflen < 0)
17688 -+ goto Elong;
17689 -+ retval -= namelen-1; /* hit the slash */
17690 -+ memcpy(retval, dentry->d_name.name, namelen);
17691 -+ return retval;
17692 -+Elong:
17693 -+ return ERR_PTR(-ENAMETOOLONG);
17694 -+}
17695 -+
17696 -+static char *
17697 -+gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
17698 -+ struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
17699 -+{
17700 -+ char *retval;
17701 -+
17702 -+ retval = __our_d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
17703 -+ if (unlikely(IS_ERR(retval)))
17704 -+ retval = strcpy(buf, "<path too long>");
17705 -+ else if (unlikely(retval[1] == '/' && retval[2] == '\0'))
17706 -+ retval[1] = '\0';
17707 -+
17708 -+ return retval;
17709 -+}
17710 -+
17711 -+static char *
17712 -+__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
17713 -+ char *buf, int buflen)
17714 -+{
17715 -+ char *res;
17716 -+
17717 -+ /* we can use real_root, real_root_mnt, because this is only called
17718 -+ by the RBAC system */
17719 -+ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
17720 -+
17721 -+ return res;
17722 -+}
17723 -+
17724 -+static char *
17725 -+d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
17726 -+ char *buf, int buflen)
17727 -+{
17728 -+ char *res;
17729 -+ struct dentry *root;
17730 -+ struct vfsmount *rootmnt;
17731 -+ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
17732 -+
17733 -+ /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
17734 -+ read_lock(&reaper->fs->lock);
17735 -+ root = dget(reaper->fs->root.dentry);
17736 -+ rootmnt = mntget(reaper->fs->root.mnt);
17737 -+ read_unlock(&reaper->fs->lock);
17738 -+
17739 -+ spin_lock(&dcache_lock);
17740 -+ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
17741 -+ spin_unlock(&dcache_lock);
17742 -+
17743 -+ dput(root);
17744 -+ mntput(rootmnt);
17745 -+ return res;
17746 -+}
17747 -+
17748 -+static char *
17749 -+gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
17750 -+{
17751 -+ char *ret;
17752 -+ spin_lock(&dcache_lock);
17753 -+ ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
17754 -+ PAGE_SIZE);
17755 -+ spin_unlock(&dcache_lock);
17756 -+ return ret;
17757 -+}
17758 -+
17759 -+char *
17760 -+gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
17761 -+{
17762 -+ return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
17763 -+ PAGE_SIZE);
17764 -+}
17765 -+
17766 -+char *
17767 -+gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
17768 -+{
17769 -+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
17770 -+ PAGE_SIZE);
17771 -+}
17772 -+
17773 -+char *
17774 -+gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
17775 -+{
17776 -+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
17777 -+ PAGE_SIZE);
17778 -+}
17779 -+
17780 -+char *
17781 -+gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
17782 -+{
17783 -+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
17784 -+ PAGE_SIZE);
17785 -+}
17786 -+
17787 -+char *
17788 -+gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
17789 -+{
17790 -+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
17791 -+ PAGE_SIZE);
17792 -+}
17793 -+
17794 -+__inline__ __u32
17795 -+to_gr_audit(const __u32 reqmode)
17796 -+{
17797 -+ /* masks off auditable permission flags, then shifts them to create
17798 -+ auditing flags, and adds the special case of append auditing if
17799 -+ we're requesting write */
17800 -+ return (((reqmode & ~GR_AUDITS) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
17801 -+}
17802 -+
17803 -+struct acl_subject_label *
17804 -+lookup_subject_map(const struct acl_subject_label *userp)
17805 -+{
17806 -+ unsigned int index = shash(userp, subj_map_set.s_size);
17807 -+ struct subject_map *match;
17808 -+
17809 -+ match = subj_map_set.s_hash[index];
17810 -+
17811 -+ while (match && match->user != userp)
17812 -+ match = match->next;
17813 -+
17814 -+ if (match != NULL)
17815 -+ return match->kernel;
17816 -+ else
17817 -+ return NULL;
17818 -+}
17819 -+
17820 -+static void
17821 -+insert_subj_map_entry(struct subject_map *subjmap)
17822 -+{
17823 -+ unsigned int index = shash(subjmap->user, subj_map_set.s_size);
17824 -+ struct subject_map **curr;
17825 -+
17826 -+ subjmap->prev = NULL;
17827 -+
17828 -+ curr = &subj_map_set.s_hash[index];
17829 -+ if (*curr != NULL)
17830 -+ (*curr)->prev = subjmap;
17831 -+
17832 -+ subjmap->next = *curr;
17833 -+ *curr = subjmap;
17834 -+
17835 -+ return;
17836 -+}
17837 -+
17838 -+static struct acl_role_label *
17839 -+lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
17840 -+ const gid_t gid)
17841 -+{
17842 -+ unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
17843 -+ struct acl_role_label *match;
17844 -+ struct role_allowed_ip *ipp;
17845 -+ unsigned int x;
17846 -+
17847 -+ match = acl_role_set.r_hash[index];
17848 -+
17849 -+ while (match) {
17850 -+ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
17851 -+ for (x = 0; x < match->domain_child_num; x++) {
17852 -+ if (match->domain_children[x] == uid)
17853 -+ goto found;
17854 -+ }
17855 -+ } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
17856 -+ break;
17857 -+ match = match->next;
17858 -+ }
17859 -+found:
17860 -+ if (match == NULL) {
17861 -+ try_group:
17862 -+ index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
17863 -+ match = acl_role_set.r_hash[index];
17864 -+
17865 -+ while (match) {
17866 -+ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
17867 -+ for (x = 0; x < match->domain_child_num; x++) {
17868 -+ if (match->domain_children[x] == gid)
17869 -+ goto found2;
17870 -+ }
17871 -+ } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
17872 -+ break;
17873 -+ match = match->next;
17874 -+ }
17875 -+found2:
17876 -+ if (match == NULL)
17877 -+ match = default_role;
17878 -+ if (match->allowed_ips == NULL)
17879 -+ return match;
17880 -+ else {
17881 -+ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
17882 -+ if (likely
17883 -+ ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
17884 -+ (ntohl(ipp->addr) & ipp->netmask)))
17885 -+ return match;
17886 -+ }
17887 -+ match = default_role;
17888 -+ }
17889 -+ } else if (match->allowed_ips == NULL) {
17890 -+ return match;
17891 -+ } else {
17892 -+ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
17893 -+ if (likely
17894 -+ ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
17895 -+ (ntohl(ipp->addr) & ipp->netmask)))
17896 -+ return match;
17897 -+ }
17898 -+ goto try_group;
17899 -+ }
17900 -+
17901 -+ return match;
17902 -+}
17903 -+
17904 -+struct acl_subject_label *
17905 -+lookup_acl_subj_label(const ino_t ino, const dev_t dev,
17906 -+ const struct acl_role_label *role)
17907 -+{
17908 -+ unsigned int index = fhash(ino, dev, role->subj_hash_size);
17909 -+ struct acl_subject_label *match;
17910 -+
17911 -+ match = role->subj_hash[index];
17912 -+
17913 -+ while (match && (match->inode != ino || match->device != dev ||
17914 -+ (match->mode & GR_DELETED))) {
17915 -+ match = match->next;
17916 -+ }
17917 -+
17918 -+ if (match && !(match->mode & GR_DELETED))
17919 -+ return match;
17920 -+ else
17921 -+ return NULL;
17922 -+}
17923 -+
17924 -+static struct acl_object_label *
17925 -+lookup_acl_obj_label(const ino_t ino, const dev_t dev,
17926 -+ const struct acl_subject_label *subj)
17927 -+{
17928 -+ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
17929 -+ struct acl_object_label *match;
17930 -+
17931 -+ match = subj->obj_hash[index];
17932 -+
17933 -+ while (match && (match->inode != ino || match->device != dev ||
17934 -+ (match->mode & GR_DELETED))) {
17935 -+ match = match->next;
17936 -+ }
17937 -+
17938 -+ if (match && !(match->mode & GR_DELETED))
17939 -+ return match;
17940 -+ else
17941 -+ return NULL;
17942 -+}
17943 -+
17944 -+static struct acl_object_label *
17945 -+lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
17946 -+ const struct acl_subject_label *subj)
17947 -+{
17948 -+ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
17949 -+ struct acl_object_label *match;
17950 -+
17951 -+ match = subj->obj_hash[index];
17952 -+
17953 -+ while (match && (match->inode != ino || match->device != dev ||
17954 -+ !(match->mode & GR_DELETED))) {
17955 -+ match = match->next;
17956 -+ }
17957 -+
17958 -+ if (match && (match->mode & GR_DELETED))
17959 -+ return match;
17960 -+
17961 -+ match = subj->obj_hash[index];
17962 -+
17963 -+ while (match && (match->inode != ino || match->device != dev ||
17964 -+ (match->mode & GR_DELETED))) {
17965 -+ match = match->next;
17966 -+ }
17967 -+
17968 -+ if (match && !(match->mode & GR_DELETED))
17969 -+ return match;
17970 -+ else
17971 -+ return NULL;
17972 -+}
17973 -+
17974 -+static struct name_entry *
17975 -+lookup_name_entry(const char *name)
17976 -+{
17977 -+ unsigned int len = strlen(name);
17978 -+ unsigned int key = full_name_hash(name, len);
17979 -+ unsigned int index = key % name_set.n_size;
17980 -+ struct name_entry *match;
17981 -+
17982 -+ match = name_set.n_hash[index];
17983 -+
17984 -+ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
17985 -+ match = match->next;
17986 -+
17987 -+ return match;
17988 -+}
17989 -+
17990 -+static struct name_entry *
17991 -+lookup_name_entry_create(const char *name)
17992 -+{
17993 -+ unsigned int len = strlen(name);
17994 -+ unsigned int key = full_name_hash(name, len);
17995 -+ unsigned int index = key % name_set.n_size;
17996 -+ struct name_entry *match;
17997 -+
17998 -+ match = name_set.n_hash[index];
17999 -+
18000 -+ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
18001 -+ !match->deleted))
18002 -+ match = match->next;
18003 -+
18004 -+ if (match && match->deleted)
18005 -+ return match;
18006 -+
18007 -+ match = name_set.n_hash[index];
18008 -+
18009 -+ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
18010 -+ match->deleted))
18011 -+ match = match->next;
18012 -+
18013 -+ if (match && !match->deleted)
18014 -+ return match;
18015 -+ else
18016 -+ return NULL;
18017 -+}
18018 -+
18019 -+static struct inodev_entry *
18020 -+lookup_inodev_entry(const ino_t ino, const dev_t dev)
18021 -+{
18022 -+ unsigned int index = fhash(ino, dev, inodev_set.i_size);
18023 -+ struct inodev_entry *match;
18024 -+
18025 -+ match = inodev_set.i_hash[index];
18026 -+
18027 -+ while (match && (match->nentry->inode != ino || match->nentry->device != dev))
18028 -+ match = match->next;
18029 -+
18030 -+ return match;
18031 -+}
18032 -+
18033 -+static void
18034 -+insert_inodev_entry(struct inodev_entry *entry)
18035 -+{
18036 -+ unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
18037 -+ inodev_set.i_size);
18038 -+ struct inodev_entry **curr;
18039 -+
18040 -+ entry->prev = NULL;
18041 -+
18042 -+ curr = &inodev_set.i_hash[index];
18043 -+ if (*curr != NULL)
18044 -+ (*curr)->prev = entry;
18045 -+
18046 -+ entry->next = *curr;
18047 -+ *curr = entry;
18048 -+
18049 -+ return;
18050 -+}
18051 -+
18052 -+static void
18053 -+__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
18054 -+{
18055 -+ unsigned int index =
18056 -+ rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
18057 -+ struct acl_role_label **curr;
18058 -+
18059 -+ role->prev = NULL;
18060 -+
18061 -+ curr = &acl_role_set.r_hash[index];
18062 -+ if (*curr != NULL)
18063 -+ (*curr)->prev = role;
18064 -+
18065 -+ role->next = *curr;
18066 -+ *curr = role;
18067 -+
18068 -+ return;
18069 -+}
18070 -+
18071 -+static void
18072 -+insert_acl_role_label(struct acl_role_label *role)
18073 -+{
18074 -+ int i;
18075 -+
18076 -+ if (role->roletype & GR_ROLE_DOMAIN) {
18077 -+ for (i = 0; i < role->domain_child_num; i++)
18078 -+ __insert_acl_role_label(role, role->domain_children[i]);
18079 -+ } else
18080 -+ __insert_acl_role_label(role, role->uidgid);
18081 -+}
18082 -+
18083 -+static int
18084 -+insert_name_entry(char *name, const ino_t inode, const dev_t device, __u8 deleted)
18085 -+{
18086 -+ struct name_entry **curr, *nentry;
18087 -+ struct inodev_entry *ientry;
18088 -+ unsigned int len = strlen(name);
18089 -+ unsigned int key = full_name_hash(name, len);
18090 -+ unsigned int index = key % name_set.n_size;
18091 -+
18092 -+ curr = &name_set.n_hash[index];
18093 -+
18094 -+ while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
18095 -+ curr = &((*curr)->next);
18096 -+
18097 -+ if (*curr != NULL)
18098 -+ return 1;
18099 -+
18100 -+ nentry = acl_alloc(sizeof (struct name_entry));
18101 -+ if (nentry == NULL)
18102 -+ return 0;
18103 -+ ientry = acl_alloc(sizeof (struct inodev_entry));
18104 -+ if (ientry == NULL)
18105 -+ return 0;
18106 -+ ientry->nentry = nentry;
18107 -+
18108 -+ nentry->key = key;
18109 -+ nentry->name = name;
18110 -+ nentry->inode = inode;
18111 -+ nentry->device = device;
18112 -+ nentry->len = len;
18113 -+ nentry->deleted = deleted;
18114 -+
18115 -+ nentry->prev = NULL;
18116 -+ curr = &name_set.n_hash[index];
18117 -+ if (*curr != NULL)
18118 -+ (*curr)->prev = nentry;
18119 -+ nentry->next = *curr;
18120 -+ *curr = nentry;
18121 -+
18122 -+ /* insert us into the table searchable by inode/dev */
18123 -+ insert_inodev_entry(ientry);
18124 -+
18125 -+ return 1;
18126 -+}
18127 -+
18128 -+static void
18129 -+insert_acl_obj_label(struct acl_object_label *obj,
18130 -+ struct acl_subject_label *subj)
18131 -+{
18132 -+ unsigned int index =
18133 -+ fhash(obj->inode, obj->device, subj->obj_hash_size);
18134 -+ struct acl_object_label **curr;
18135 -+
18136 -+
18137 -+ obj->prev = NULL;
18138 -+
18139 -+ curr = &subj->obj_hash[index];
18140 -+ if (*curr != NULL)
18141 -+ (*curr)->prev = obj;
18142 -+
18143 -+ obj->next = *curr;
18144 -+ *curr = obj;
18145 -+
18146 -+ return;
18147 -+}
18148 -+
18149 -+static void
18150 -+insert_acl_subj_label(struct acl_subject_label *obj,
18151 -+ struct acl_role_label *role)
18152 -+{
18153 -+ unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
18154 -+ struct acl_subject_label **curr;
18155 -+
18156 -+ obj->prev = NULL;
18157 -+
18158 -+ curr = &role->subj_hash[index];
18159 -+ if (*curr != NULL)
18160 -+ (*curr)->prev = obj;
18161 -+
18162 -+ obj->next = *curr;
18163 -+ *curr = obj;
18164 -+
18165 -+ return;
18166 -+}
18167 -+
18168 -+/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
18169 -+
18170 -+static void *
18171 -+create_table(__u32 * len, int elementsize)
18172 -+{
18173 -+ unsigned int table_sizes[] = {
18174 -+ 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
18175 -+ 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
18176 -+ 4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
18177 -+ 268435399, 536870909, 1073741789, 2147483647
18178 -+ };
18179 -+ void *newtable = NULL;
18180 -+ unsigned int pwr = 0;
18181 -+
18182 -+ while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
18183 -+ table_sizes[pwr] <= *len)
18184 -+ pwr++;
18185 -+
18186 -+ if (table_sizes[pwr] <= *len)
18187 -+ return newtable;
18188 -+
18189 -+ if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
18190 -+ newtable =
18191 -+ kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
18192 -+ else
18193 -+ newtable = vmalloc(table_sizes[pwr] * elementsize);
18194 -+
18195 -+ *len = table_sizes[pwr];
18196 -+
18197 -+ return newtable;
18198 -+}
18199 -+
18200 -+static int
18201 -+init_variables(const struct gr_arg *arg)
18202 -+{
18203 -+ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
18204 -+ unsigned int stacksize;
18205 -+
18206 -+ subj_map_set.s_size = arg->role_db.num_subjects;
18207 -+ acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
18208 -+ name_set.n_size = arg->role_db.num_objects;
18209 -+ inodev_set.i_size = arg->role_db.num_objects;
18210 -+
18211 -+ if (!subj_map_set.s_size || !acl_role_set.r_size ||
18212 -+ !name_set.n_size || !inodev_set.i_size)
18213 -+ return 1;
18214 -+
18215 -+ if (!gr_init_uidset())
18216 -+ return 1;
18217 -+
18218 -+ /* set up the stack that holds allocation info */
18219 -+
18220 -+ stacksize = arg->role_db.num_pointers + 5;
18221 -+
18222 -+ if (!acl_alloc_stack_init(stacksize))
18223 -+ return 1;
18224 -+
18225 -+ /* grab reference for the real root dentry and vfsmount */
18226 -+ read_lock(&reaper->fs->lock);
18227 -+ real_root_mnt = mntget(reaper->fs->root.mnt);
18228 -+ real_root = dget(reaper->fs->root.dentry);
18229 -+ read_unlock(&reaper->fs->lock);
18230 -+
18231 -+ fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
18232 -+ if (fakefs_obj == NULL)
18233 -+ return 1;
18234 -+ fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
18235 -+
18236 -+ subj_map_set.s_hash =
18237 -+ (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
18238 -+ acl_role_set.r_hash =
18239 -+ (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
18240 -+ name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
18241 -+ inodev_set.i_hash =
18242 -+ (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
18243 -+
18244 -+ if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
18245 -+ !name_set.n_hash || !inodev_set.i_hash)
18246 -+ return 1;
18247 -+
18248 -+ memset(subj_map_set.s_hash, 0,
18249 -+ sizeof(struct subject_map *) * subj_map_set.s_size);
18250 -+ memset(acl_role_set.r_hash, 0,
18251 -+ sizeof (struct acl_role_label *) * acl_role_set.r_size);
18252 -+ memset(name_set.n_hash, 0,
18253 -+ sizeof (struct name_entry *) * name_set.n_size);
18254 -+ memset(inodev_set.i_hash, 0,
18255 -+ sizeof (struct inodev_entry *) * inodev_set.i_size);
18256 -+
18257 -+ return 0;
18258 -+}
18259 -+
18260 -+/* free information not needed after startup
18261 -+ currently contains user->kernel pointer mappings for subjects
18262 -+*/
18263 -+
18264 -+static void
18265 -+free_init_variables(void)
18266 -+{
18267 -+ __u32 i;
18268 -+
18269 -+ if (subj_map_set.s_hash) {
18270 -+ for (i = 0; i < subj_map_set.s_size; i++) {
18271 -+ if (subj_map_set.s_hash[i]) {
18272 -+ kfree(subj_map_set.s_hash[i]);
18273 -+ subj_map_set.s_hash[i] = NULL;
18274 -+ }
18275 -+ }
18276 -+
18277 -+ if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
18278 -+ PAGE_SIZE)
18279 -+ kfree(subj_map_set.s_hash);
18280 -+ else
18281 -+ vfree(subj_map_set.s_hash);
18282 -+ }
18283 -+
18284 -+ return;
18285 -+}
18286 -+
18287 -+static void
18288 -+free_variables(void)
18289 -+{
18290 -+ struct acl_subject_label *s;
18291 -+ struct acl_role_label *r;
18292 -+ struct task_struct *task, *task2;
18293 -+ unsigned int i, x;
18294 -+
18295 -+ gr_clear_learn_entries();
18296 -+
18297 -+ read_lock(&tasklist_lock);
18298 -+ do_each_thread(task2, task) {
18299 -+ task->acl_sp_role = 0;
18300 -+ task->acl_role_id = 0;
18301 -+ task->acl = NULL;
18302 -+ task->role = NULL;
18303 -+ } while_each_thread(task2, task);
18304 -+ read_unlock(&tasklist_lock);
18305 -+
18306 -+ /* release the reference to the real root dentry and vfsmount */
18307 -+ if (real_root)
18308 -+ dput(real_root);
18309 -+ real_root = NULL;
18310 -+ if (real_root_mnt)
18311 -+ mntput(real_root_mnt);
18312 -+ real_root_mnt = NULL;
18313 -+
18314 -+ /* free all object hash tables */
18315 -+
18316 -+ FOR_EACH_ROLE_START(r, i)
18317 -+ if (r->subj_hash == NULL)
18318 -+ break;
18319 -+ FOR_EACH_SUBJECT_START(r, s, x)
18320 -+ if (s->obj_hash == NULL)
18321 -+ break;
18322 -+ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
18323 -+ kfree(s->obj_hash);
18324 -+ else
18325 -+ vfree(s->obj_hash);
18326 -+ FOR_EACH_SUBJECT_END(s, x)
18327 -+ FOR_EACH_NESTED_SUBJECT_START(r, s)
18328 -+ if (s->obj_hash == NULL)
18329 -+ break;
18330 -+ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
18331 -+ kfree(s->obj_hash);
18332 -+ else
18333 -+ vfree(s->obj_hash);
18334 -+ FOR_EACH_NESTED_SUBJECT_END(s)
18335 -+ if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
18336 -+ kfree(r->subj_hash);
18337 -+ else
18338 -+ vfree(r->subj_hash);
18339 -+ r->subj_hash = NULL;
18340 -+ FOR_EACH_ROLE_END(r,i)
18341 -+
18342 -+ acl_free_all();
18343 -+
18344 -+ if (acl_role_set.r_hash) {
18345 -+ if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
18346 -+ PAGE_SIZE)
18347 -+ kfree(acl_role_set.r_hash);
18348 -+ else
18349 -+ vfree(acl_role_set.r_hash);
18350 -+ }
18351 -+ if (name_set.n_hash) {
18352 -+ if ((name_set.n_size * sizeof (struct name_entry *)) <=
18353 -+ PAGE_SIZE)
18354 -+ kfree(name_set.n_hash);
18355 -+ else
18356 -+ vfree(name_set.n_hash);
18357 -+ }
18358 -+
18359 -+ if (inodev_set.i_hash) {
18360 -+ if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
18361 -+ PAGE_SIZE)
18362 -+ kfree(inodev_set.i_hash);
18363 -+ else
18364 -+ vfree(inodev_set.i_hash);
18365 -+ }
18366 -+
18367 -+ gr_free_uidset();
18368 -+
18369 -+ memset(&name_set, 0, sizeof (struct name_db));
18370 -+ memset(&inodev_set, 0, sizeof (struct inodev_db));
18371 -+ memset(&acl_role_set, 0, sizeof (struct acl_role_db));
18372 -+ memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
18373 -+
18374 -+ default_role = NULL;
18375 -+
18376 -+ return;
18377 -+}
18378 -+
18379 -+static __u32
18380 -+count_user_objs(struct acl_object_label *userp)
18381 -+{
18382 -+ struct acl_object_label o_tmp;
18383 -+ __u32 num = 0;
18384 -+
18385 -+ while (userp) {
18386 -+ if (copy_from_user(&o_tmp, userp,
18387 -+ sizeof (struct acl_object_label)))
18388 -+ break;
18389 -+
18390 -+ userp = o_tmp.prev;
18391 -+ num++;
18392 -+ }
18393 -+
18394 -+ return num;
18395 -+}
18396 -+
18397 -+static struct acl_subject_label *
18398 -+do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
18399 -+
18400 -+static int
18401 -+copy_user_glob(struct acl_object_label *obj)
18402 -+{
18403 -+ struct acl_object_label *g_tmp, **guser;
18404 -+ unsigned int len;
18405 -+ char *tmp;
18406 -+
18407 -+ if (obj->globbed == NULL)
18408 -+ return 0;
18409 -+
18410 -+ guser = &obj->globbed;
18411 -+ while (*guser) {
18412 -+ g_tmp = (struct acl_object_label *)
18413 -+ acl_alloc(sizeof (struct acl_object_label));
18414 -+ if (g_tmp == NULL)
18415 -+ return -ENOMEM;
18416 -+
18417 -+ if (copy_from_user(g_tmp, *guser,
18418 -+ sizeof (struct acl_object_label)))
18419 -+ return -EFAULT;
18420 -+
18421 -+ len = strnlen_user(g_tmp->filename, PATH_MAX);
18422 -+
18423 -+ if (!len || len >= PATH_MAX)
18424 -+ return -EINVAL;
18425 -+
18426 -+ if ((tmp = (char *) acl_alloc(len)) == NULL)
18427 -+ return -ENOMEM;
18428 -+
18429 -+ if (copy_from_user(tmp, g_tmp->filename, len))
18430 -+ return -EFAULT;
18431 -+
18432 -+ g_tmp->filename = tmp;
18433 -+
18434 -+ *guser = g_tmp;
18435 -+ guser = &(g_tmp->next);
18436 -+ }
18437 -+
18438 -+ return 0;
18439 -+}
18440 -+
18441 -+static int
18442 -+copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
18443 -+ struct acl_role_label *role)
18444 -+{
18445 -+ struct acl_object_label *o_tmp;
18446 -+ unsigned int len;
18447 -+ int ret;
18448 -+ char *tmp;
18449 -+
18450 -+ while (userp) {
18451 -+ if ((o_tmp = (struct acl_object_label *)
18452 -+ acl_alloc(sizeof (struct acl_object_label))) == NULL)
18453 -+ return -ENOMEM;
18454 -+
18455 -+ if (copy_from_user(o_tmp, userp,
18456 -+ sizeof (struct acl_object_label)))
18457 -+ return -EFAULT;
18458 -+
18459 -+ userp = o_tmp->prev;
18460 -+
18461 -+ len = strnlen_user(o_tmp->filename, PATH_MAX);
18462 -+
18463 -+ if (!len || len >= PATH_MAX)
18464 -+ return -EINVAL;
18465 -+
18466 -+ if ((tmp = (char *) acl_alloc(len)) == NULL)
18467 -+ return -ENOMEM;
18468 -+
18469 -+ if (copy_from_user(tmp, o_tmp->filename, len))
18470 -+ return -EFAULT;
18471 -+
18472 -+ o_tmp->filename = tmp;
18473 -+
18474 -+ insert_acl_obj_label(o_tmp, subj);
18475 -+ if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
18476 -+ o_tmp->device, (o_tmp->mode & GR_DELETED) ? 1 : 0))
18477 -+ return -ENOMEM;
18478 -+
18479 -+ ret = copy_user_glob(o_tmp);
18480 -+ if (ret)
18481 -+ return ret;
18482 -+
18483 -+ if (o_tmp->nested) {
18484 -+ o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
18485 -+ if (IS_ERR(o_tmp->nested))
18486 -+ return PTR_ERR(o_tmp->nested);
18487 -+
18488 -+ /* insert into nested subject list */
18489 -+ o_tmp->nested->next = role->hash->first;
18490 -+ role->hash->first = o_tmp->nested;
18491 -+ }
18492 -+ }
18493 -+
18494 -+ return 0;
18495 -+}
18496 -+
18497 -+static __u32
18498 -+count_user_subjs(struct acl_subject_label *userp)
18499 -+{
18500 -+ struct acl_subject_label s_tmp;
18501 -+ __u32 num = 0;
18502 -+
18503 -+ while (userp) {
18504 -+ if (copy_from_user(&s_tmp, userp,
18505 -+ sizeof (struct acl_subject_label)))
18506 -+ break;
18507 -+
18508 -+ userp = s_tmp.prev;
18509 -+ /* do not count nested subjects against this count, since
18510 -+ they are not included in the hash table, but are
18511 -+ attached to objects. We have already counted
18512 -+ the subjects in userspace for the allocation
18513 -+ stack
18514 -+ */
18515 -+ if (!(s_tmp.mode & GR_NESTED))
18516 -+ num++;
18517 -+ }
18518 -+
18519 -+ return num;
18520 -+}
18521 -+
18522 -+static int
18523 -+copy_user_allowedips(struct acl_role_label *rolep)
18524 -+{
18525 -+ struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
18526 -+
18527 -+ ruserip = rolep->allowed_ips;
18528 -+
18529 -+ while (ruserip) {
18530 -+ rlast = rtmp;
18531 -+
18532 -+ if ((rtmp = (struct role_allowed_ip *)
18533 -+ acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
18534 -+ return -ENOMEM;
18535 -+
18536 -+ if (copy_from_user(rtmp, ruserip,
18537 -+ sizeof (struct role_allowed_ip)))
18538 -+ return -EFAULT;
18539 -+
18540 -+ ruserip = rtmp->prev;
18541 -+
18542 -+ if (!rlast) {
18543 -+ rtmp->prev = NULL;
18544 -+ rolep->allowed_ips = rtmp;
18545 -+ } else {
18546 -+ rlast->next = rtmp;
18547 -+ rtmp->prev = rlast;
18548 -+ }
18549 -+
18550 -+ if (!ruserip)
18551 -+ rtmp->next = NULL;
18552 -+ }
18553 -+
18554 -+ return 0;
18555 -+}
18556 -+
18557 -+static int
18558 -+copy_user_transitions(struct acl_role_label *rolep)
18559 -+{
18560 -+ struct role_transition *rusertp, *rtmp = NULL, *rlast;
18561 -+
18562 -+ unsigned int len;
18563 -+ char *tmp;
18564 -+
18565 -+ rusertp = rolep->transitions;
18566 -+
18567 -+ while (rusertp) {
18568 -+ rlast = rtmp;
18569 -+
18570 -+ if ((rtmp = (struct role_transition *)
18571 -+ acl_alloc(sizeof (struct role_transition))) == NULL)
18572 -+ return -ENOMEM;
18573 -+
18574 -+ if (copy_from_user(rtmp, rusertp,
18575 -+ sizeof (struct role_transition)))
18576 -+ return -EFAULT;
18577 -+
18578 -+ rusertp = rtmp->prev;
18579 -+
18580 -+ len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
18581 -+
18582 -+ if (!len || len >= GR_SPROLE_LEN)
18583 -+ return -EINVAL;
18584 -+
18585 -+ if ((tmp = (char *) acl_alloc(len)) == NULL)
18586 -+ return -ENOMEM;
18587 -+
18588 -+ if (copy_from_user(tmp, rtmp->rolename, len))
18589 -+ return -EFAULT;
18590 -+
18591 -+ rtmp->rolename = tmp;
18592 -+
18593 -+ if (!rlast) {
18594 -+ rtmp->prev = NULL;
18595 -+ rolep->transitions = rtmp;
18596 -+ } else {
18597 -+ rlast->next = rtmp;
18598 -+ rtmp->prev = rlast;
18599 -+ }
18600 -+
18601 -+ if (!rusertp)
18602 -+ rtmp->next = NULL;
18603 -+ }
18604 -+
18605 -+ return 0;
18606 -+}
18607 -+
18608 -+static struct acl_subject_label *
18609 -+do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
18610 -+{
18611 -+ struct acl_subject_label *s_tmp = NULL, *s_tmp2;
18612 -+ unsigned int len;
18613 -+ char *tmp;
18614 -+ __u32 num_objs;
18615 -+ struct acl_ip_label **i_tmp, *i_utmp2;
18616 -+ struct gr_hash_struct ghash;
18617 -+ struct subject_map *subjmap;
18618 -+ unsigned int i_num;
18619 -+ int err;
18620 -+
18621 -+ s_tmp = lookup_subject_map(userp);
18622 -+
18623 -+ /* we've already copied this subject into the kernel, just return
18624 -+ the reference to it, and don't copy it over again
18625 -+ */
18626 -+ if (s_tmp)
18627 -+ return(s_tmp);
18628 -+
18629 -+ if ((s_tmp = (struct acl_subject_label *)
18630 -+ acl_alloc(sizeof (struct acl_subject_label))) == NULL)
18631 -+ return ERR_PTR(-ENOMEM);
18632 -+
18633 -+ subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
18634 -+ if (subjmap == NULL)
18635 -+ return ERR_PTR(-ENOMEM);
18636 -+
18637 -+ subjmap->user = userp;
18638 -+ subjmap->kernel = s_tmp;
18639 -+ insert_subj_map_entry(subjmap);
18640 -+
18641 -+ if (copy_from_user(s_tmp, userp,
18642 -+ sizeof (struct acl_subject_label)))
18643 -+ return ERR_PTR(-EFAULT);
18644 -+
18645 -+ len = strnlen_user(s_tmp->filename, PATH_MAX);
18646 -+
18647 -+ if (!len || len >= PATH_MAX)
18648 -+ return ERR_PTR(-EINVAL);
18649 -+
18650 -+ if ((tmp = (char *) acl_alloc(len)) == NULL)
18651 -+ return ERR_PTR(-ENOMEM);
18652 -+
18653 -+ if (copy_from_user(tmp, s_tmp->filename, len))
18654 -+ return ERR_PTR(-EFAULT);
18655 -+
18656 -+ s_tmp->filename = tmp;
18657 -+
18658 -+ if (!strcmp(s_tmp->filename, "/"))
18659 -+ role->root_label = s_tmp;
18660 -+
18661 -+ if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
18662 -+ return ERR_PTR(-EFAULT);
18663 -+
18664 -+ /* copy user and group transition tables */
18665 -+
18666 -+ if (s_tmp->user_trans_num) {
18667 -+ uid_t *uidlist;
18668 -+
18669 -+ uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
18670 -+ if (uidlist == NULL)
18671 -+ return ERR_PTR(-ENOMEM);
18672 -+ if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
18673 -+ return ERR_PTR(-EFAULT);
18674 -+
18675 -+ s_tmp->user_transitions = uidlist;
18676 -+ }
18677 -+
18678 -+ if (s_tmp->group_trans_num) {
18679 -+ gid_t *gidlist;
18680 -+
18681 -+ gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
18682 -+ if (gidlist == NULL)
18683 -+ return ERR_PTR(-ENOMEM);
18684 -+ if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
18685 -+ return ERR_PTR(-EFAULT);
18686 -+
18687 -+ s_tmp->group_transitions = gidlist;
18688 -+ }
18689 -+
18690 -+ /* set up object hash table */
18691 -+ num_objs = count_user_objs(ghash.first);
18692 -+
18693 -+ s_tmp->obj_hash_size = num_objs;
18694 -+ s_tmp->obj_hash =
18695 -+ (struct acl_object_label **)
18696 -+ create_table(&(s_tmp->obj_hash_size), sizeof(void *));
18697 -+
18698 -+ if (!s_tmp->obj_hash)
18699 -+ return ERR_PTR(-ENOMEM);
18700 -+
18701 -+ memset(s_tmp->obj_hash, 0,
18702 -+ s_tmp->obj_hash_size *
18703 -+ sizeof (struct acl_object_label *));
18704 -+
18705 -+ /* add in objects */
18706 -+ err = copy_user_objs(ghash.first, s_tmp, role);
18707 -+
18708 -+ if (err)
18709 -+ return ERR_PTR(err);
18710 -+
18711 -+ /* set pointer for parent subject */
18712 -+ if (s_tmp->parent_subject) {
18713 -+ s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
18714 -+
18715 -+ if (IS_ERR(s_tmp2))
18716 -+ return s_tmp2;
18717 -+
18718 -+ s_tmp->parent_subject = s_tmp2;
18719 -+ }
18720 -+
18721 -+ /* add in ip acls */
18722 -+
18723 -+ if (!s_tmp->ip_num) {
18724 -+ s_tmp->ips = NULL;
18725 -+ goto insert;
18726 -+ }
18727 -+
18728 -+ i_tmp =
18729 -+ (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
18730 -+ sizeof (struct
18731 -+ acl_ip_label *));
18732 -+
18733 -+ if (!i_tmp)
18734 -+ return ERR_PTR(-ENOMEM);
18735 -+
18736 -+ for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
18737 -+ *(i_tmp + i_num) =
18738 -+ (struct acl_ip_label *)
18739 -+ acl_alloc(sizeof (struct acl_ip_label));
18740 -+ if (!*(i_tmp + i_num))
18741 -+ return ERR_PTR(-ENOMEM);
18742 -+
18743 -+ if (copy_from_user
18744 -+ (&i_utmp2, s_tmp->ips + i_num,
18745 -+ sizeof (struct acl_ip_label *)))
18746 -+ return ERR_PTR(-EFAULT);
18747 -+
18748 -+ if (copy_from_user
18749 -+ (*(i_tmp + i_num), i_utmp2,
18750 -+ sizeof (struct acl_ip_label)))
18751 -+ return ERR_PTR(-EFAULT);
18752 -+
18753 -+ if ((*(i_tmp + i_num))->iface == NULL)
18754 -+ continue;
18755 -+
18756 -+ len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
18757 -+ if (!len || len >= IFNAMSIZ)
18758 -+ return ERR_PTR(-EINVAL);
18759 -+ tmp = acl_alloc(len);
18760 -+ if (tmp == NULL)
18761 -+ return ERR_PTR(-ENOMEM);
18762 -+ if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
18763 -+ return ERR_PTR(-EFAULT);
18764 -+ (*(i_tmp + i_num))->iface = tmp;
18765 -+ }
18766 -+
18767 -+ s_tmp->ips = i_tmp;
18768 -+
18769 -+insert:
18770 -+ if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
18771 -+ s_tmp->device, (s_tmp->mode & GR_DELETED) ? 1 : 0))
18772 -+ return ERR_PTR(-ENOMEM);
18773 -+
18774 -+ return s_tmp;
18775 -+}
18776 -+
18777 -+static int
18778 -+copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
18779 -+{
18780 -+ struct acl_subject_label s_pre;
18781 -+ struct acl_subject_label * ret;
18782 -+ int err;
18783 -+
18784 -+ while (userp) {
18785 -+ if (copy_from_user(&s_pre, userp,
18786 -+ sizeof (struct acl_subject_label)))
18787 -+ return -EFAULT;
18788 -+
18789 -+ /* do not add nested subjects here, add
18790 -+ while parsing objects
18791 -+ */
18792 -+
18793 -+ if (s_pre.mode & GR_NESTED) {
18794 -+ userp = s_pre.prev;
18795 -+ continue;
18796 -+ }
18797 -+
18798 -+ ret = do_copy_user_subj(userp, role);
18799 -+
18800 -+ err = PTR_ERR(ret);
18801 -+ if (IS_ERR(ret))
18802 -+ return err;
18803 -+
18804 -+ insert_acl_subj_label(ret, role);
18805 -+
18806 -+ userp = s_pre.prev;
18807 -+ }
18808 -+
18809 -+ return 0;
18810 -+}
18811 -+
18812 -+static int
18813 -+copy_user_acl(struct gr_arg *arg)
18814 -+{
18815 -+ struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
18816 -+ struct sprole_pw *sptmp;
18817 -+ struct gr_hash_struct *ghash;
18818 -+ uid_t *domainlist;
18819 -+ unsigned int r_num;
18820 -+ unsigned int len;
18821 -+ char *tmp;
18822 -+ int err = 0;
18823 -+ __u16 i;
18824 -+ __u32 num_subjs;
18825 -+
18826 -+ /* we need a default and kernel role */
18827 -+ if (arg->role_db.num_roles < 2)
18828 -+ return -EINVAL;
18829 -+
18830 -+ /* copy special role authentication info from userspace */
18831 -+
18832 -+ num_sprole_pws = arg->num_sprole_pws;
18833 -+ acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
18834 -+
18835 -+ if (!acl_special_roles) {
18836 -+ err = -ENOMEM;
18837 -+ goto cleanup;
18838 -+ }
18839 -+
18840 -+ for (i = 0; i < num_sprole_pws; i++) {
18841 -+ sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
18842 -+ if (!sptmp) {
18843 -+ err = -ENOMEM;
18844 -+ goto cleanup;
18845 -+ }
18846 -+ if (copy_from_user(sptmp, arg->sprole_pws + i,
18847 -+ sizeof (struct sprole_pw))) {
18848 -+ err = -EFAULT;
18849 -+ goto cleanup;
18850 -+ }
18851 -+
18852 -+ len =
18853 -+ strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
18854 -+
18855 -+ if (!len || len >= GR_SPROLE_LEN) {
18856 -+ err = -EINVAL;
18857 -+ goto cleanup;
18858 -+ }
18859 -+
18860 -+ if ((tmp = (char *) acl_alloc(len)) == NULL) {
18861 -+ err = -ENOMEM;
18862 -+ goto cleanup;
18863 -+ }
18864 -+
18865 -+ if (copy_from_user(tmp, sptmp->rolename, len)) {
18866 -+ err = -EFAULT;
18867 -+ goto cleanup;
18868 -+ }
18869 -+
18870 -+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
18871 -+ printk(KERN_ALERT "Copying special role %s\n", tmp);
18872 -+#endif
18873 -+ sptmp->rolename = tmp;
18874 -+ acl_special_roles[i] = sptmp;
18875 -+ }
18876 -+
18877 -+ r_utmp = (struct acl_role_label **) arg->role_db.r_table;
18878 -+
18879 -+ for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
18880 -+ r_tmp = acl_alloc(sizeof (struct acl_role_label));
18881 -+
18882 -+ if (!r_tmp) {
18883 -+ err = -ENOMEM;
18884 -+ goto cleanup;
18885 -+ }
18886 -+
18887 -+ if (copy_from_user(&r_utmp2, r_utmp + r_num,
18888 -+ sizeof (struct acl_role_label *))) {
18889 -+ err = -EFAULT;
18890 -+ goto cleanup;
18891 -+ }
18892 -+
18893 -+ if (copy_from_user(r_tmp, r_utmp2,
18894 -+ sizeof (struct acl_role_label))) {
18895 -+ err = -EFAULT;
18896 -+ goto cleanup;
18897 -+ }
18898 -+
18899 -+ len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
18900 -+
18901 -+ if (!len || len >= PATH_MAX) {
18902 -+ err = -EINVAL;
18903 -+ goto cleanup;
18904 -+ }
18905 -+
18906 -+ if ((tmp = (char *) acl_alloc(len)) == NULL) {
18907 -+ err = -ENOMEM;
18908 -+ goto cleanup;
18909 -+ }
18910 -+ if (copy_from_user(tmp, r_tmp->rolename, len)) {
18911 -+ err = -EFAULT;
18912 -+ goto cleanup;
18913 -+ }
18914 -+ r_tmp->rolename = tmp;
18915 -+
18916 -+ if (!strcmp(r_tmp->rolename, "default")
18917 -+ && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
18918 -+ default_role = r_tmp;
18919 -+ } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
18920 -+ kernel_role = r_tmp;
18921 -+ }
18922 -+
18923 -+ if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
18924 -+ err = -ENOMEM;
18925 -+ goto cleanup;
18926 -+ }
18927 -+ if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
18928 -+ err = -EFAULT;
18929 -+ goto cleanup;
18930 -+ }
18931 -+
18932 -+ r_tmp->hash = ghash;
18933 -+
18934 -+ num_subjs = count_user_subjs(r_tmp->hash->first);
18935 -+
18936 -+ r_tmp->subj_hash_size = num_subjs;
18937 -+ r_tmp->subj_hash =
18938 -+ (struct acl_subject_label **)
18939 -+ create_table(&(r_tmp->subj_hash_size), sizeof(void *));
18940 -+
18941 -+ if (!r_tmp->subj_hash) {
18942 -+ err = -ENOMEM;
18943 -+ goto cleanup;
18944 -+ }
18945 -+
18946 -+ err = copy_user_allowedips(r_tmp);
18947 -+ if (err)
18948 -+ goto cleanup;
18949 -+
18950 -+ /* copy domain info */
18951 -+ if (r_tmp->domain_children != NULL) {
18952 -+ domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
18953 -+ if (domainlist == NULL) {
18954 -+ err = -ENOMEM;
18955 -+ goto cleanup;
18956 -+ }
18957 -+ if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
18958 -+ err = -EFAULT;
18959 -+ goto cleanup;
18960 -+ }
18961 -+ r_tmp->domain_children = domainlist;
18962 -+ }
18963 -+
18964 -+ err = copy_user_transitions(r_tmp);
18965 -+ if (err)
18966 -+ goto cleanup;
18967 -+
18968 -+ memset(r_tmp->subj_hash, 0,
18969 -+ r_tmp->subj_hash_size *
18970 -+ sizeof (struct acl_subject_label *));
18971 -+
18972 -+ err = copy_user_subjs(r_tmp->hash->first, r_tmp);
18973 -+
18974 -+ if (err)
18975 -+ goto cleanup;
18976 -+
18977 -+ /* set nested subject list to null */
18978 -+ r_tmp->hash->first = NULL;
18979 -+
18980 -+ insert_acl_role_label(r_tmp);
18981 -+ }
18982 -+
18983 -+ goto return_err;
18984 -+ cleanup:
18985 -+ free_variables();
18986 -+ return_err:
18987 -+ return err;
18988 -+
18989 -+}
18990 -+
18991 -+static int
18992 -+gracl_init(struct gr_arg *args)
18993 -+{
18994 -+ int error = 0;
18995 -+
18996 -+ memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
18997 -+ memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
18998 -+
18999 -+ if (init_variables(args)) {
19000 -+ gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
19001 -+ error = -ENOMEM;
19002 -+ free_variables();
19003 -+ goto out;
19004 -+ }
19005 -+
19006 -+ error = copy_user_acl(args);
19007 -+ free_init_variables();
19008 -+ if (error) {
19009 -+ free_variables();
19010 -+ goto out;
19011 -+ }
19012 -+
19013 -+ if ((error = gr_set_acls(0))) {
19014 -+ free_variables();
19015 -+ goto out;
19016 -+ }
19017 -+
19018 -+ gr_status |= GR_READY;
19019 -+ out:
19020 -+ return error;
19021 -+}
19022 -+
19023 -+/* derived from glibc fnmatch() 0: match, 1: no match*/
19024 -+
19025 -+static int
19026 -+glob_match(const char *p, const char *n)
19027 -+{
19028 -+ char c;
19029 -+
19030 -+ while ((c = *p++) != '\0') {
19031 -+ switch (c) {
19032 -+ case '?':
19033 -+ if (*n == '\0')
19034 -+ return 1;
19035 -+ else if (*n == '/')
19036 -+ return 1;
19037 -+ break;
19038 -+ case '\\':
19039 -+ if (*n != c)
19040 -+ return 1;
19041 -+ break;
19042 -+ case '*':
19043 -+ for (c = *p++; c == '?' || c == '*'; c = *p++) {
19044 -+ if (*n == '/')
19045 -+ return 1;
19046 -+ else if (c == '?') {
19047 -+ if (*n == '\0')
19048 -+ return 1;
19049 -+ else
19050 -+ ++n;
19051 -+ }
19052 -+ }
19053 -+ if (c == '\0') {
19054 -+ return 0;
19055 -+ } else {
19056 -+ const char *endp;
19057 -+
19058 -+ if ((endp = strchr(n, '/')) == NULL)
19059 -+ endp = n + strlen(n);
19060 -+
19061 -+ if (c == '[') {
19062 -+ for (--p; n < endp; ++n)
19063 -+ if (!glob_match(p, n))
19064 -+ return 0;
19065 -+ } else if (c == '/') {
19066 -+ while (*n != '\0' && *n != '/')
19067 -+ ++n;
19068 -+ if (*n == '/' && !glob_match(p, n + 1))
19069 -+ return 0;
19070 -+ } else {
19071 -+ for (--p; n < endp; ++n)
19072 -+ if (*n == c && !glob_match(p, n))
19073 -+ return 0;
19074 -+ }
19075 -+
19076 -+ return 1;
19077 -+ }
19078 -+ case '[':
19079 -+ {
19080 -+ int not;
19081 -+ char cold;
19082 -+
19083 -+ if (*n == '\0' || *n == '/')
19084 -+ return 1;
19085 -+
19086 -+ not = (*p == '!' || *p == '^');
19087 -+ if (not)
19088 -+ ++p;
19089 -+
19090 -+ c = *p++;
19091 -+ for (;;) {
19092 -+ unsigned char fn = (unsigned char)*n;
19093 -+
19094 -+ if (c == '\0')
19095 -+ return 1;
19096 -+ else {
19097 -+ if (c == fn)
19098 -+ goto matched;
19099 -+ cold = c;
19100 -+ c = *p++;
19101 -+
19102 -+ if (c == '-' && *p != ']') {
19103 -+ unsigned char cend = *p++;
19104 -+
19105 -+ if (cend == '\0')
19106 -+ return 1;
19107 -+
19108 -+ if (cold <= fn && fn <= cend)
19109 -+ goto matched;
19110 -+
19111 -+ c = *p++;
19112 -+ }
19113 -+ }
19114 -+
19115 -+ if (c == ']')
19116 -+ break;
19117 -+ }
19118 -+ if (!not)
19119 -+ return 1;
19120 -+ break;
19121 -+ matched:
19122 -+ while (c != ']') {
19123 -+ if (c == '\0')
19124 -+ return 1;
19125 -+
19126 -+ c = *p++;
19127 -+ }
19128 -+ if (not)
19129 -+ return 1;
19130 -+ }
19131 -+ break;
19132 -+ default:
19133 -+ if (c != *n)
19134 -+ return 1;
19135 -+ }
19136 -+
19137 -+ ++n;
19138 -+ }
19139 -+
19140 -+ if (*n == '\0')
19141 -+ return 0;
19142 -+
19143 -+ if (*n == '/')
19144 -+ return 0;
19145 -+
19146 -+ return 1;
19147 -+}
19148 -+
19149 -+static struct acl_object_label *
19150 -+chk_glob_label(struct acl_object_label *globbed,
19151 -+ struct dentry *dentry, struct vfsmount *mnt, char **path)
19152 -+{
19153 -+ struct acl_object_label *tmp;
19154 -+
19155 -+ if (*path == NULL)
19156 -+ *path = gr_to_filename_nolock(dentry, mnt);
19157 -+
19158 -+ tmp = globbed;
19159 -+
19160 -+ while (tmp) {
19161 -+ if (!glob_match(tmp->filename, *path))
19162 -+ return tmp;
19163 -+ tmp = tmp->next;
19164 -+ }
19165 -+
19166 -+ return NULL;
19167 -+}
19168 -+
19169 -+static struct acl_object_label *
19170 -+__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
19171 -+ const ino_t curr_ino, const dev_t curr_dev,
19172 -+ const struct acl_subject_label *subj, char **path)
19173 -+{
19174 -+ struct acl_subject_label *tmpsubj;
19175 -+ struct acl_object_label *retval;
19176 -+ struct acl_object_label *retval2;
19177 -+
19178 -+ tmpsubj = (struct acl_subject_label *) subj;
19179 -+ read_lock(&gr_inode_lock);
19180 -+ do {
19181 -+ retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
19182 -+ if (retval) {
19183 -+ if (retval->globbed) {
19184 -+ retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
19185 -+ (struct vfsmount *)orig_mnt, path);
19186 -+ if (retval2)
19187 -+ retval = retval2;
19188 -+ }
19189 -+ break;
19190 -+ }
19191 -+ } while ((tmpsubj = tmpsubj->parent_subject));
19192 -+ read_unlock(&gr_inode_lock);
19193 -+
19194 -+ return retval;
19195 -+}
19196 -+
19197 -+static __inline__ struct acl_object_label *
19198 -+full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
19199 -+ const struct dentry *curr_dentry,
19200 -+ const struct acl_subject_label *subj, char **path)
19201 -+{
19202 -+ return __full_lookup(orig_dentry, orig_mnt,
19203 -+ curr_dentry->d_inode->i_ino,
19204 -+ curr_dentry->d_inode->i_sb->s_dev, subj, path);
19205 -+}
19206 -+
19207 -+static struct acl_object_label *
19208 -+__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
19209 -+ const struct acl_subject_label *subj, char *path)
19210 -+{
19211 -+ struct dentry *dentry = (struct dentry *) l_dentry;
19212 -+ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
19213 -+ struct acl_object_label *retval;
19214 -+
19215 -+ spin_lock(&dcache_lock);
19216 -+
19217 -+ if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt ||
19218 -+ /* ignore Eric Biederman */
19219 -+ IS_PRIVATE(l_dentry->d_inode))) {
19220 -+ retval = fakefs_obj;
19221 -+ goto out;
19222 -+ }
19223 -+
19224 -+ for (;;) {
19225 -+ if (dentry == real_root && mnt == real_root_mnt)
19226 -+ break;
19227 -+
19228 -+ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
19229 -+ if (mnt->mnt_parent == mnt)
19230 -+ break;
19231 -+
19232 -+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
19233 -+ if (retval != NULL)
19234 -+ goto out;
19235 -+
19236 -+ dentry = mnt->mnt_mountpoint;
19237 -+ mnt = mnt->mnt_parent;
19238 -+ continue;
19239 -+ }
19240 -+
19241 -+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
19242 -+ if (retval != NULL)
19243 -+ goto out;
19244 -+
19245 -+ dentry = dentry->d_parent;
19246 -+ }
19247 -+
19248 -+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
19249 -+
19250 -+ if (retval == NULL)
19251 -+ retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
19252 -+out:
19253 -+ spin_unlock(&dcache_lock);
19254 -+ return retval;
19255 -+}
19256 -+
19257 -+static __inline__ struct acl_object_label *
19258 -+chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
19259 -+ const struct acl_subject_label *subj)
19260 -+{
19261 -+ char *path = NULL;
19262 -+ return __chk_obj_label(l_dentry, l_mnt, subj, path);
19263 -+}
19264 -+
19265 -+static __inline__ struct acl_object_label *
19266 -+chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
19267 -+ const struct acl_subject_label *subj, char *path)
19268 -+{
19269 -+ return __chk_obj_label(l_dentry, l_mnt, subj, path);
19270 -+}
19271 -+
19272 -+static struct acl_subject_label *
19273 -+chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
19274 -+ const struct acl_role_label *role)
19275 -+{
19276 -+ struct dentry *dentry = (struct dentry *) l_dentry;
19277 -+ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
19278 -+ struct acl_subject_label *retval;
19279 -+
19280 -+ spin_lock(&dcache_lock);
19281 -+
19282 -+ for (;;) {
19283 -+ if (dentry == real_root && mnt == real_root_mnt)
19284 -+ break;
19285 -+ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
19286 -+ if (mnt->mnt_parent == mnt)
19287 -+ break;
19288 -+
19289 -+ read_lock(&gr_inode_lock);
19290 -+ retval =
19291 -+ lookup_acl_subj_label(dentry->d_inode->i_ino,
19292 -+ dentry->d_inode->i_sb->s_dev, role);
19293 -+ read_unlock(&gr_inode_lock);
19294 -+ if (retval != NULL)
19295 -+ goto out;
19296 -+
19297 -+ dentry = mnt->mnt_mountpoint;
19298 -+ mnt = mnt->mnt_parent;
19299 -+ continue;
19300 -+ }
19301 -+
19302 -+ read_lock(&gr_inode_lock);
19303 -+ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
19304 -+ dentry->d_inode->i_sb->s_dev, role);
19305 -+ read_unlock(&gr_inode_lock);
19306 -+ if (retval != NULL)
19307 -+ goto out;
19308 -+
19309 -+ dentry = dentry->d_parent;
19310 -+ }
19311 -+
19312 -+ read_lock(&gr_inode_lock);
19313 -+ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
19314 -+ dentry->d_inode->i_sb->s_dev, role);
19315 -+ read_unlock(&gr_inode_lock);
19316 -+
19317 -+ if (unlikely(retval == NULL)) {
19318 -+ read_lock(&gr_inode_lock);
19319 -+ retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
19320 -+ real_root->d_inode->i_sb->s_dev, role);
19321 -+ read_unlock(&gr_inode_lock);
19322 -+ }
19323 -+out:
19324 -+ spin_unlock(&dcache_lock);
19325 -+
19326 -+ return retval;
19327 -+}
19328 -+
19329 -+static void
19330 -+gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
19331 -+{
19332 -+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
19333 -+ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
19334 -+ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
19335 -+ 1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
19336 -+
19337 -+ return;
19338 -+}
19339 -+
19340 -+static void
19341 -+gr_log_learn_sysctl(const struct task_struct *task, const char *path, const __u32 mode)
19342 -+{
19343 -+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
19344 -+ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
19345 -+ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
19346 -+ 1, 1, path, (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
19347 -+
19348 -+ return;
19349 -+}
19350 -+
19351 -+static void
19352 -+gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real,
19353 -+ const unsigned int effective, const unsigned int fs)
19354 -+{
19355 -+ security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
19356 -+ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
19357 -+ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
19358 -+ type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
19359 -+
19360 -+ return;
19361 -+}
19362 -+
19363 -+__u32
19364 -+gr_check_link(const struct dentry * new_dentry,
19365 -+ const struct dentry * parent_dentry,
19366 -+ const struct vfsmount * parent_mnt,
19367 -+ const struct dentry * old_dentry, const struct vfsmount * old_mnt)
19368 -+{
19369 -+ struct acl_object_label *obj;
19370 -+ __u32 oldmode, newmode;
19371 -+ __u32 needmode;
19372 -+
19373 -+ if (unlikely(!(gr_status & GR_READY)))
19374 -+ return (GR_CREATE | GR_LINK);
19375 -+
19376 -+ obj = chk_obj_label(old_dentry, old_mnt, current->acl);
19377 -+ oldmode = obj->mode;
19378 -+
19379 -+ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
19380 -+ oldmode |= (GR_CREATE | GR_LINK);
19381 -+
19382 -+ needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
19383 -+ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
19384 -+ needmode |= GR_SETID | GR_AUDIT_SETID;
19385 -+
19386 -+ newmode =
19387 -+ gr_check_create(new_dentry, parent_dentry, parent_mnt,
19388 -+ oldmode | needmode);
19389 -+
19390 -+ needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
19391 -+ GR_SETID | GR_READ | GR_FIND | GR_DELETE |
19392 -+ GR_INHERIT | GR_AUDIT_INHERIT);
19393 -+
19394 -+ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
19395 -+ goto bad;
19396 -+
19397 -+ if ((oldmode & needmode) != needmode)
19398 -+ goto bad;
19399 -+
19400 -+ needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
19401 -+ if ((newmode & needmode) != needmode)
19402 -+ goto bad;
19403 -+
19404 -+ if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
19405 -+ return newmode;
19406 -+bad:
19407 -+ needmode = oldmode;
19408 -+ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
19409 -+ needmode |= GR_SETID;
19410 -+
19411 -+ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
19412 -+ gr_log_learn(current, old_dentry, old_mnt, needmode);
19413 -+ return (GR_CREATE | GR_LINK);
19414 -+ } else if (newmode & GR_SUPPRESS)
19415 -+ return GR_SUPPRESS;
19416 -+ else
19417 -+ return 0;
19418 -+}
19419 -+
19420 -+__u32
19421 -+gr_search_file(const struct dentry * dentry, const __u32 mode,
19422 -+ const struct vfsmount * mnt)
19423 -+{
19424 -+ __u32 retval = mode;
19425 -+ struct acl_subject_label *curracl;
19426 -+ struct acl_object_label *currobj;
19427 -+
19428 -+ if (unlikely(!(gr_status & GR_READY)))
19429 -+ return (mode & ~GR_AUDITS);
19430 -+
19431 -+ curracl = current->acl;
19432 -+
19433 -+ currobj = chk_obj_label(dentry, mnt, curracl);
19434 -+ retval = currobj->mode & mode;
19435 -+
19436 -+ if (unlikely
19437 -+ ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
19438 -+ && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
19439 -+ __u32 new_mode = mode;
19440 -+
19441 -+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
19442 -+
19443 -+ retval = new_mode;
19444 -+
19445 -+ if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
19446 -+ new_mode |= GR_INHERIT;
19447 -+
19448 -+ if (!(mode & GR_NOLEARN))
19449 -+ gr_log_learn(current, dentry, mnt, new_mode);
19450 -+ }
19451 -+
19452 -+ return retval;
19453 -+}
19454 -+
19455 -+__u32
19456 -+gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
19457 -+ const struct vfsmount * mnt, const __u32 mode)
19458 -+{
19459 -+ struct name_entry *match;
19460 -+ struct acl_object_label *matchpo;
19461 -+ struct acl_subject_label *curracl;
19462 -+ char *path;
19463 -+ __u32 retval;
19464 -+
19465 -+ if (unlikely(!(gr_status & GR_READY)))
19466 -+ return (mode & ~GR_AUDITS);
19467 -+
19468 -+ preempt_disable();
19469 -+ path = gr_to_filename_rbac(new_dentry, mnt);
19470 -+ match = lookup_name_entry_create(path);
19471 -+
19472 -+ if (!match)
19473 -+ goto check_parent;
19474 -+
19475 -+ curracl = current->acl;
19476 -+
19477 -+ read_lock(&gr_inode_lock);
19478 -+ matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
19479 -+ read_unlock(&gr_inode_lock);
19480 -+
19481 -+ if (matchpo) {
19482 -+ if ((matchpo->mode & mode) !=
19483 -+ (mode & ~(GR_AUDITS | GR_SUPPRESS))
19484 -+ && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
19485 -+ __u32 new_mode = mode;
19486 -+
19487 -+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
19488 -+
19489 -+ gr_log_learn(current, new_dentry, mnt, new_mode);
19490 -+
19491 -+ preempt_enable();
19492 -+ return new_mode;
19493 -+ }
19494 -+ preempt_enable();
19495 -+ return (matchpo->mode & mode);
19496 -+ }
19497 -+
19498 -+ check_parent:
19499 -+ curracl = current->acl;
19500 -+
19501 -+ matchpo = chk_obj_create_label(parent, mnt, curracl, path);
19502 -+ retval = matchpo->mode & mode;
19503 -+
19504 -+ if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
19505 -+ && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
19506 -+ __u32 new_mode = mode;
19507 -+
19508 -+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
19509 -+
19510 -+ gr_log_learn(current, new_dentry, mnt, new_mode);
19511 -+ preempt_enable();
19512 -+ return new_mode;
19513 -+ }
19514 -+
19515 -+ preempt_enable();
19516 -+ return retval;
19517 -+}
19518 -+
19519 -+int
19520 -+gr_check_hidden_task(const struct task_struct *task)
19521 -+{
19522 -+ if (unlikely(!(gr_status & GR_READY)))
19523 -+ return 0;
19524 -+
19525 -+ if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
19526 -+ return 1;
19527 -+
19528 -+ return 0;
19529 -+}
19530 -+
19531 -+int
19532 -+gr_check_protected_task(const struct task_struct *task)
19533 -+{
19534 -+ if (unlikely(!(gr_status & GR_READY) || !task))
19535 -+ return 0;
19536 -+
19537 -+ if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
19538 -+ task->acl != current->acl)
19539 -+ return 1;
19540 -+
19541 -+ return 0;
19542 -+}
19543 -+
19544 -+void
19545 -+gr_copy_label(struct task_struct *tsk)
19546 -+{
19547 -+ tsk->signal->used_accept = 0;
19548 -+ tsk->acl_sp_role = 0;
19549 -+ tsk->acl_role_id = current->acl_role_id;
19550 -+ tsk->acl = current->acl;
19551 -+ tsk->role = current->role;
19552 -+ tsk->signal->curr_ip = current->signal->curr_ip;
19553 -+ if (current->exec_file)
19554 -+ get_file(current->exec_file);
19555 -+ tsk->exec_file = current->exec_file;
19556 -+ tsk->is_writable = current->is_writable;
19557 -+ if (unlikely(current->signal->used_accept))
19558 -+ current->signal->curr_ip = 0;
19559 -+
19560 -+ return;
19561 -+}
19562 -+
19563 -+static void
19564 -+gr_set_proc_res(struct task_struct *task)
19565 -+{
19566 -+ struct acl_subject_label *proc;
19567 -+ unsigned short i;
19568 -+
19569 -+ proc = task->acl;
19570 -+
19571 -+ if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
19572 -+ return;
19573 -+
19574 -+ for (i = 0; i < (GR_NLIMITS - 1); i++) {
19575 -+ if (!(proc->resmask & (1 << i)))
19576 -+ continue;
19577 -+
19578 -+ task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
19579 -+ task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
19580 -+ }
19581 -+
19582 -+ return;
19583 -+}
19584 -+
19585 -+int
19586 -+gr_check_user_change(int real, int effective, int fs)
19587 -+{
19588 -+ unsigned int i;
19589 -+ __u16 num;
19590 -+ uid_t *uidlist;
19591 -+ int curuid;
19592 -+ int realok = 0;
19593 -+ int effectiveok = 0;
19594 -+ int fsok = 0;
19595 -+
19596 -+ if (unlikely(!(gr_status & GR_READY)))
19597 -+ return 0;
19598 -+
19599 -+ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
19600 -+ gr_log_learn_id_change(current, 'u', real, effective, fs);
19601 -+
19602 -+ num = current->acl->user_trans_num;
19603 -+ uidlist = current->acl->user_transitions;
19604 -+
19605 -+ if (uidlist == NULL)
19606 -+ return 0;
19607 -+
19608 -+ if (real == -1)
19609 -+ realok = 1;
19610 -+ if (effective == -1)
19611 -+ effectiveok = 1;
19612 -+ if (fs == -1)
19613 -+ fsok = 1;
19614 -+
19615 -+ if (current->acl->user_trans_type & GR_ID_ALLOW) {
19616 -+ for (i = 0; i < num; i++) {
19617 -+ curuid = (int)uidlist[i];
19618 -+ if (real == curuid)
19619 -+ realok = 1;
19620 -+ if (effective == curuid)
19621 -+ effectiveok = 1;
19622 -+ if (fs == curuid)
19623 -+ fsok = 1;
19624 -+ }
19625 -+ } else if (current->acl->user_trans_type & GR_ID_DENY) {
19626 -+ for (i = 0; i < num; i++) {
19627 -+ curuid = (int)uidlist[i];
19628 -+ if (real == curuid)
19629 -+ break;
19630 -+ if (effective == curuid)
19631 -+ break;
19632 -+ if (fs == curuid)
19633 -+ break;
19634 -+ }
19635 -+ /* not in deny list */
19636 -+ if (i == num) {
19637 -+ realok = 1;
19638 -+ effectiveok = 1;
19639 -+ fsok = 1;
19640 -+ }
19641 -+ }
19642 -+
19643 -+ if (realok && effectiveok && fsok)
19644 -+ return 0;
19645 -+ else {
19646 -+ gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
19647 -+ return 1;
19648 -+ }
19649 -+}
19650 -+
19651 -+int
19652 -+gr_check_group_change(int real, int effective, int fs)
19653 -+{
19654 -+ unsigned int i;
19655 -+ __u16 num;
19656 -+ gid_t *gidlist;
19657 -+ int curgid;
19658 -+ int realok = 0;
19659 -+ int effectiveok = 0;
19660 -+ int fsok = 0;
19661 -+
19662 -+ if (unlikely(!(gr_status & GR_READY)))
19663 -+ return 0;
19664 -+
19665 -+ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
19666 -+ gr_log_learn_id_change(current, 'g', real, effective, fs);
19667 -+
19668 -+ num = current->acl->group_trans_num;
19669 -+ gidlist = current->acl->group_transitions;
19670 -+
19671 -+ if (gidlist == NULL)
19672 -+ return 0;
19673 -+
19674 -+ if (real == -1)
19675 -+ realok = 1;
19676 -+ if (effective == -1)
19677 -+ effectiveok = 1;
19678 -+ if (fs == -1)
19679 -+ fsok = 1;
19680 -+
19681 -+ if (current->acl->group_trans_type & GR_ID_ALLOW) {
19682 -+ for (i = 0; i < num; i++) {
19683 -+ curgid = (int)gidlist[i];
19684 -+ if (real == curgid)
19685 -+ realok = 1;
19686 -+ if (effective == curgid)
19687 -+ effectiveok = 1;
19688 -+ if (fs == curgid)
19689 -+ fsok = 1;
19690 -+ }
19691 -+ } else if (current->acl->group_trans_type & GR_ID_DENY) {
19692 -+ for (i = 0; i < num; i++) {
19693 -+ curgid = (int)gidlist[i];
19694 -+ if (real == curgid)
19695 -+ break;
19696 -+ if (effective == curgid)
19697 -+ break;
19698 -+ if (fs == curgid)
19699 -+ break;
19700 -+ }
19701 -+ /* not in deny list */
19702 -+ if (i == num) {
19703 -+ realok = 1;
19704 -+ effectiveok = 1;
19705 -+ fsok = 1;
19706 -+ }
19707 -+ }
19708 -+
19709 -+ if (realok && effectiveok && fsok)
19710 -+ return 0;
19711 -+ else {
19712 -+ gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
19713 -+ return 1;
19714 -+ }
19715 -+}
19716 -+
19717 -+void
19718 -+gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
19719 -+{
19720 -+ struct acl_role_label *role = task->role;
19721 -+ struct acl_subject_label *subj = NULL;
19722 -+ struct acl_object_label *obj;
19723 -+ struct file *filp;
19724 -+
19725 -+ if (unlikely(!(gr_status & GR_READY)))
19726 -+ return;
19727 -+
19728 -+ filp = task->exec_file;
19729 -+
19730 -+ /* kernel process, we'll give them the kernel role */
19731 -+ if (unlikely(!filp)) {
19732 -+ task->role = kernel_role;
19733 -+ task->acl = kernel_role->root_label;
19734 -+ return;
19735 -+ } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
19736 -+ role = lookup_acl_role_label(task, uid, gid);
19737 -+
19738 -+ /* perform subject lookup in possibly new role
19739 -+ we can use this result below in the case where role == task->role
19740 -+ */
19741 -+ subj = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, role);
19742 -+
19743 -+ /* if we changed uid/gid, but result in the same role
19744 -+ and are using inheritance, don't lose the inherited subject
19745 -+ if current subject is other than what normal lookup
19746 -+ would result in, we arrived via inheritance, don't
19747 -+ lose subject
19748 -+ */
19749 -+ if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
19750 -+ (subj == task->acl)))
19751 -+ task->acl = subj;
19752 -+
19753 -+ task->role = role;
19754 -+
19755 -+ task->is_writable = 0;
19756 -+
19757 -+ /* ignore additional mmap checks for processes that are writable
19758 -+ by the default ACL */
19759 -+ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
19760 -+ if (unlikely(obj->mode & GR_WRITE))
19761 -+ task->is_writable = 1;
19762 -+ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
19763 -+ if (unlikely(obj->mode & GR_WRITE))
19764 -+ task->is_writable = 1;
19765 -+
19766 -+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
19767 -+ printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
19768 -+#endif
19769 -+
19770 -+ gr_set_proc_res(task);
19771 -+
19772 -+ return;
19773 -+}
19774 -+
19775 -+int
19776 -+gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
19777 -+{
19778 -+ struct task_struct *task = current;
19779 -+ struct acl_subject_label *newacl;
19780 -+ struct acl_object_label *obj;
19781 -+ __u32 retmode;
19782 -+
19783 -+ if (unlikely(!(gr_status & GR_READY)))
19784 -+ return 0;
19785 -+
19786 -+ newacl = chk_subj_label(dentry, mnt, task->role);
19787 -+
19788 -+ task_lock(task);
19789 -+ if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
19790 -+ GR_POVERRIDE) && (task->acl != newacl) &&
19791 -+ !(task->role->roletype & GR_ROLE_GOD) &&
19792 -+ !gr_search_file(dentry, GR_PTRACERD, mnt) &&
19793 -+ !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
19794 -+ (atomic_read(&task->fs->count) > 1 ||
19795 -+ atomic_read(&task->files->count) > 1 ||
19796 -+ atomic_read(&task->sighand->count) > 1)) {
19797 -+ task_unlock(task);
19798 -+ gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
19799 -+ return -EACCES;
19800 -+ }
19801 -+ task_unlock(task);
19802 -+
19803 -+ obj = chk_obj_label(dentry, mnt, task->acl);
19804 -+ retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
19805 -+
19806 -+ if (!(task->acl->mode & GR_INHERITLEARN) &&
19807 -+ ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
19808 -+ if (obj->nested)
19809 -+ task->acl = obj->nested;
19810 -+ else
19811 -+ task->acl = newacl;
19812 -+ } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
19813 -+ gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
19814 -+
19815 -+ task->is_writable = 0;
19816 -+
19817 -+ /* ignore additional mmap checks for processes that are writable
19818 -+ by the default ACL */
19819 -+ obj = chk_obj_label(dentry, mnt, default_role->root_label);
19820 -+ if (unlikely(obj->mode & GR_WRITE))
19821 -+ task->is_writable = 1;
19822 -+ obj = chk_obj_label(dentry, mnt, task->role->root_label);
19823 -+ if (unlikely(obj->mode & GR_WRITE))
19824 -+ task->is_writable = 1;
19825 -+
19826 -+ gr_set_proc_res(task);
19827 -+
19828 -+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
19829 -+ printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
19830 -+#endif
19831 -+ return 0;
19832 -+}
19833 -+
19834 -+/* always called with valid inodev ptr */
19835 -+static void
19836 -+do_handle_delete(struct inodev_entry *inodev, const ino_t ino, const dev_t dev)
19837 -+{
19838 -+ struct acl_object_label *matchpo;
19839 -+ struct acl_subject_label *matchps;
19840 -+ struct acl_subject_label *subj;
19841 -+ struct acl_role_label *role;
19842 -+ unsigned int i, x;
19843 -+
19844 -+ FOR_EACH_ROLE_START(role, i)
19845 -+ FOR_EACH_SUBJECT_START(role, subj, x)
19846 -+ if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
19847 -+ matchpo->mode |= GR_DELETED;
19848 -+ FOR_EACH_SUBJECT_END(subj,x)
19849 -+ FOR_EACH_NESTED_SUBJECT_START(role, subj)
19850 -+ if (subj->inode == ino && subj->device == dev)
19851 -+ subj->mode |= GR_DELETED;
19852 -+ FOR_EACH_NESTED_SUBJECT_END(subj)
19853 -+ if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
19854 -+ matchps->mode |= GR_DELETED;
19855 -+ FOR_EACH_ROLE_END(role,i)
19856 -+
19857 -+ inodev->nentry->deleted = 1;
19858 -+
19859 -+ return;
19860 -+}
19861 -+
19862 -+void
19863 -+gr_handle_delete(const ino_t ino, const dev_t dev)
19864 -+{
19865 -+ struct inodev_entry *inodev;
19866 -+
19867 -+ if (unlikely(!(gr_status & GR_READY)))
19868 -+ return;
19869 -+
19870 -+ write_lock(&gr_inode_lock);
19871 -+ inodev = lookup_inodev_entry(ino, dev);
19872 -+ if (inodev != NULL)
19873 -+ do_handle_delete(inodev, ino, dev);
19874 -+ write_unlock(&gr_inode_lock);
19875 -+
19876 -+ return;
19877 -+}
19878 -+
19879 -+static void
19880 -+update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
19881 -+ const ino_t newinode, const dev_t newdevice,
19882 -+ struct acl_subject_label *subj)
19883 -+{
19884 -+ unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
19885 -+ struct acl_object_label *match;
19886 -+
19887 -+ match = subj->obj_hash[index];
19888 -+
19889 -+ while (match && (match->inode != oldinode ||
19890 -+ match->device != olddevice ||
19891 -+ !(match->mode & GR_DELETED)))
19892 -+ match = match->next;
19893 -+
19894 -+ if (match && (match->inode == oldinode)
19895 -+ && (match->device == olddevice)
19896 -+ && (match->mode & GR_DELETED)) {
19897 -+ if (match->prev == NULL) {
19898 -+ subj->obj_hash[index] = match->next;
19899 -+ if (match->next != NULL)
19900 -+ match->next->prev = NULL;
19901 -+ } else {
19902 -+ match->prev->next = match->next;
19903 -+ if (match->next != NULL)
19904 -+ match->next->prev = match->prev;
19905 -+ }
19906 -+ match->prev = NULL;
19907 -+ match->next = NULL;
19908 -+ match->inode = newinode;
19909 -+ match->device = newdevice;
19910 -+ match->mode &= ~GR_DELETED;
19911 -+
19912 -+ insert_acl_obj_label(match, subj);
19913 -+ }
19914 -+
19915 -+ return;
19916 -+}
19917 -+
19918 -+static void
19919 -+update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
19920 -+ const ino_t newinode, const dev_t newdevice,
19921 -+ struct acl_role_label *role)
19922 -+{
19923 -+ unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
19924 -+ struct acl_subject_label *match;
19925 -+
19926 -+ match = role->subj_hash[index];
19927 -+
19928 -+ while (match && (match->inode != oldinode ||
19929 -+ match->device != olddevice ||
19930 -+ !(match->mode & GR_DELETED)))
19931 -+ match = match->next;
19932 -+
19933 -+ if (match && (match->inode == oldinode)
19934 -+ && (match->device == olddevice)
19935 -+ && (match->mode & GR_DELETED)) {
19936 -+ if (match->prev == NULL) {
19937 -+ role->subj_hash[index] = match->next;
19938 -+ if (match->next != NULL)
19939 -+ match->next->prev = NULL;
19940 -+ } else {
19941 -+ match->prev->next = match->next;
19942 -+ if (match->next != NULL)
19943 -+ match->next->prev = match->prev;
19944 -+ }
19945 -+ match->prev = NULL;
19946 -+ match->next = NULL;
19947 -+ match->inode = newinode;
19948 -+ match->device = newdevice;
19949 -+ match->mode &= ~GR_DELETED;
19950 -+
19951 -+ insert_acl_subj_label(match, role);
19952 -+ }
19953 -+
19954 -+ return;
19955 -+}
19956 -+
19957 -+static void
19958 -+update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
19959 -+ const ino_t newinode, const dev_t newdevice)
19960 -+{
19961 -+ unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
19962 -+ struct inodev_entry *match;
19963 -+
19964 -+ match = inodev_set.i_hash[index];
19965 -+
19966 -+ while (match && (match->nentry->inode != oldinode ||
19967 -+ match->nentry->device != olddevice || !match->nentry->deleted))
19968 -+ match = match->next;
19969 -+
19970 -+ if (match && (match->nentry->inode == oldinode)
19971 -+ && (match->nentry->device == olddevice) &&
19972 -+ match->nentry->deleted) {
19973 -+ if (match->prev == NULL) {
19974 -+ inodev_set.i_hash[index] = match->next;
19975 -+ if (match->next != NULL)
19976 -+ match->next->prev = NULL;
19977 -+ } else {
19978 -+ match->prev->next = match->next;
19979 -+ if (match->next != NULL)
19980 -+ match->next->prev = match->prev;
19981 -+ }
19982 -+ match->prev = NULL;
19983 -+ match->next = NULL;
19984 -+ match->nentry->inode = newinode;
19985 -+ match->nentry->device = newdevice;
19986 -+ match->nentry->deleted = 0;
19987 -+
19988 -+ insert_inodev_entry(match);
19989 -+ }
19990 -+
19991 -+ return;
19992 -+}
19993 -+
19994 -+static void
19995 -+do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
19996 -+ const struct vfsmount *mnt)
19997 -+{
19998 -+ struct acl_subject_label *subj;
19999 -+ struct acl_role_label *role;
20000 -+ unsigned int i, x;
20001 -+
20002 -+ FOR_EACH_ROLE_START(role, i)
20003 -+ update_acl_subj_label(matchn->inode, matchn->device,
20004 -+ dentry->d_inode->i_ino,
20005 -+ dentry->d_inode->i_sb->s_dev, role);
20006 -+
20007 -+ FOR_EACH_NESTED_SUBJECT_START(role, subj)
20008 -+ if ((subj->inode == dentry->d_inode->i_ino) &&
20009 -+ (subj->device == dentry->d_inode->i_sb->s_dev)) {
20010 -+ subj->inode = dentry->d_inode->i_ino;
20011 -+ subj->device = dentry->d_inode->i_sb->s_dev;
20012 -+ }
20013 -+ FOR_EACH_NESTED_SUBJECT_END(subj)
20014 -+ FOR_EACH_SUBJECT_START(role, subj, x)
20015 -+ update_acl_obj_label(matchn->inode, matchn->device,
20016 -+ dentry->d_inode->i_ino,
20017 -+ dentry->d_inode->i_sb->s_dev, subj);
20018 -+ FOR_EACH_SUBJECT_END(subj,x)
20019 -+ FOR_EACH_ROLE_END(role,i)
20020 -+
20021 -+ update_inodev_entry(matchn->inode, matchn->device,
20022 -+ dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
20023 -+
20024 -+ return;
20025 -+}
20026 -+
20027 -+void
20028 -+gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
20029 -+{
20030 -+ struct name_entry *matchn;
20031 -+
20032 -+ if (unlikely(!(gr_status & GR_READY)))
20033 -+ return;
20034 -+
20035 -+ preempt_disable();
20036 -+ matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
20037 -+
20038 -+ if (unlikely((unsigned long)matchn)) {
20039 -+ write_lock(&gr_inode_lock);
20040 -+ do_handle_create(matchn, dentry, mnt);
20041 -+ write_unlock(&gr_inode_lock);
20042 -+ }
20043 -+ preempt_enable();
20044 -+
20045 -+ return;
20046 -+}
20047 -+
20048 -+void
20049 -+gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
20050 -+ struct dentry *old_dentry,
20051 -+ struct dentry *new_dentry,
20052 -+ struct vfsmount *mnt, const __u8 replace)
20053 -+{
20054 -+ struct name_entry *matchn;
20055 -+ struct inodev_entry *inodev;
20056 -+
20057 -+ /* vfs_rename swaps the name and parent link for old_dentry and
20058 -+ new_dentry
20059 -+ at this point, old_dentry has the new name, parent link, and inode
20060 -+ for the renamed file
20061 -+ if a file is being replaced by a rename, new_dentry has the inode
20062 -+ and name for the replaced file
20063 -+ */
20064 -+
20065 -+ if (unlikely(!(gr_status & GR_READY)))
20066 -+ return;
20067 -+
20068 -+ preempt_disable();
20069 -+ matchn = lookup_name_entry(gr_to_filename_rbac(old_dentry, mnt));
20070 -+
20071 -+ /* we wouldn't have to check d_inode if it weren't for
20072 -+ NFS silly-renaming
20073 -+ */
20074 -+
20075 -+ write_lock(&gr_inode_lock);
20076 -+ if (unlikely(replace && new_dentry->d_inode)) {
20077 -+ inodev = lookup_inodev_entry(new_dentry->d_inode->i_ino,
20078 -+ new_dentry->d_inode->i_sb->s_dev);
20079 -+ if (inodev != NULL && (new_dentry->d_inode->i_nlink <= 1))
20080 -+ do_handle_delete(inodev, new_dentry->d_inode->i_ino,
20081 -+ new_dentry->d_inode->i_sb->s_dev);
20082 -+ }
20083 -+
20084 -+ inodev = lookup_inodev_entry(old_dentry->d_inode->i_ino,
20085 -+ old_dentry->d_inode->i_sb->s_dev);
20086 -+ if (inodev != NULL && (old_dentry->d_inode->i_nlink <= 1))
20087 -+ do_handle_delete(inodev, old_dentry->d_inode->i_ino,
20088 -+ old_dentry->d_inode->i_sb->s_dev);
20089 -+
20090 -+ if (unlikely((unsigned long)matchn))
20091 -+ do_handle_create(matchn, old_dentry, mnt);
20092 -+
20093 -+ write_unlock(&gr_inode_lock);
20094 -+ preempt_enable();
20095 -+
20096 -+ return;
20097 -+}
20098 -+
20099 -+static int
20100 -+lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
20101 -+ unsigned char **sum)
20102 -+{
20103 -+ struct acl_role_label *r;
20104 -+ struct role_allowed_ip *ipp;
20105 -+ struct role_transition *trans;
20106 -+ unsigned int i;
20107 -+ int found = 0;
20108 -+
20109 -+ /* check transition table */
20110 -+
20111 -+ for (trans = current->role->transitions; trans; trans = trans->next) {
20112 -+ if (!strcmp(rolename, trans->rolename)) {
20113 -+ found = 1;
20114 -+ break;
20115 -+ }
20116 -+ }
20117 -+
20118 -+ if (!found)
20119 -+ return 0;
20120 -+
20121 -+ /* handle special roles that do not require authentication
20122 -+ and check ip */
20123 -+
20124 -+ FOR_EACH_ROLE_START(r, i)
20125 -+ if (!strcmp(rolename, r->rolename) &&
20126 -+ (r->roletype & GR_ROLE_SPECIAL)) {
20127 -+ found = 0;
20128 -+ if (r->allowed_ips != NULL) {
20129 -+ for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
20130 -+ if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
20131 -+ (ntohl(ipp->addr) & ipp->netmask))
20132 -+ found = 1;
20133 -+ }
20134 -+ } else
20135 -+ found = 2;
20136 -+ if (!found)
20137 -+ return 0;
20138 -+
20139 -+ if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
20140 -+ ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
20141 -+ *salt = NULL;
20142 -+ *sum = NULL;
20143 -+ return 1;
20144 -+ }
20145 -+ }
20146 -+ FOR_EACH_ROLE_END(r,i)
20147 -+
20148 -+ for (i = 0; i < num_sprole_pws; i++) {
20149 -+ if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
20150 -+ *salt = acl_special_roles[i]->salt;
20151 -+ *sum = acl_special_roles[i]->sum;
20152 -+ return 1;
20153 -+ }
20154 -+ }
20155 -+
20156 -+ return 0;
20157 -+}
20158 -+
20159 -+static void
20160 -+assign_special_role(char *rolename)
20161 -+{
20162 -+ struct acl_object_label *obj;
20163 -+ struct acl_role_label *r;
20164 -+ struct acl_role_label *assigned = NULL;
20165 -+ struct task_struct *tsk;
20166 -+ struct file *filp;
20167 -+ unsigned int i;
20168 -+
20169 -+ FOR_EACH_ROLE_START(r, i)
20170 -+ if (!strcmp(rolename, r->rolename) &&
20171 -+ (r->roletype & GR_ROLE_SPECIAL))
20172 -+ assigned = r;
20173 -+ FOR_EACH_ROLE_END(r,i)
20174 -+
20175 -+ if (!assigned)
20176 -+ return;
20177 -+
20178 -+ read_lock(&tasklist_lock);
20179 -+ read_lock(&grsec_exec_file_lock);
20180 -+
20181 -+ tsk = current->parent;
20182 -+ if (tsk == NULL)
20183 -+ goto out_unlock;
20184 -+
20185 -+ filp = tsk->exec_file;
20186 -+ if (filp == NULL)
20187 -+ goto out_unlock;
20188 -+
20189 -+ tsk->is_writable = 0;
20190 -+
20191 -+ tsk->acl_sp_role = 1;
20192 -+ tsk->acl_role_id = ++acl_sp_role_value;
20193 -+ tsk->role = assigned;
20194 -+ tsk->acl = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role);
20195 -+
20196 -+ /* ignore additional mmap checks for processes that are writable
20197 -+ by the default ACL */
20198 -+ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
20199 -+ if (unlikely(obj->mode & GR_WRITE))
20200 -+ tsk->is_writable = 1;
20201 -+ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role->root_label);
20202 -+ if (unlikely(obj->mode & GR_WRITE))
20203 -+ tsk->is_writable = 1;
20204 -+
20205 -+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
20206 -+ printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
20207 -+#endif
20208 -+
20209 -+out_unlock:
20210 -+ read_unlock(&grsec_exec_file_lock);
20211 -+ read_unlock(&tasklist_lock);
20212 -+ return;
20213 -+}
20214 -+
20215 -+int gr_check_secure_terminal(struct task_struct *task)
20216 -+{
20217 -+ struct task_struct *p, *p2, *p3;
20218 -+ struct files_struct *files;
20219 -+ struct fdtable *fdt;
20220 -+ struct file *our_file = NULL, *file;
20221 -+ int i;
20222 -+
20223 -+ if (task->signal->tty == NULL)
20224 -+ return 1;
20225 -+
20226 -+ files = get_files_struct(task);
20227 -+ if (files != NULL) {
20228 -+ rcu_read_lock();
20229 -+ fdt = files_fdtable(files);
20230 -+ for (i=0; i < fdt->max_fds; i++) {
20231 -+ file = fcheck_files(files, i);
20232 -+ if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
20233 -+ get_file(file);
20234 -+ our_file = file;
20235 -+ }
20236 -+ }
20237 -+ rcu_read_unlock();
20238 -+ put_files_struct(files);
20239 -+ }
20240 -+
20241 -+ if (our_file == NULL)
20242 -+ return 1;
20243 -+
20244 -+ read_lock(&tasklist_lock);
20245 -+ do_each_thread(p2, p) {
20246 -+ files = get_files_struct(p);
20247 -+ if (files == NULL ||
20248 -+ (p->signal && p->signal->tty == task->signal->tty)) {
20249 -+ if (files != NULL)
20250 -+ put_files_struct(files);
20251 -+ continue;
20252 -+ }
20253 -+ rcu_read_lock();
20254 -+ fdt = files_fdtable(files);
20255 -+ for (i=0; i < fdt->max_fds; i++) {
20256 -+ file = fcheck_files(files, i);
20257 -+ if (file && S_ISCHR(file->f_path.dentry->d_inode->i_mode) &&
20258 -+ file->f_path.dentry->d_inode->i_rdev == our_file->f_path.dentry->d_inode->i_rdev) {
20259 -+ p3 = task;
20260 -+ while (p3->pid > 0) {
20261 -+ if (p3 == p)
20262 -+ break;
20263 -+ p3 = p3->parent;
20264 -+ }
20265 -+ if (p3 == p)
20266 -+ break;
20267 -+ gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
20268 -+ gr_handle_alertkill(p);
20269 -+ rcu_read_unlock();
20270 -+ put_files_struct(files);
20271 -+ read_unlock(&tasklist_lock);
20272 -+ fput(our_file);
20273 -+ return 0;
20274 -+ }
20275 -+ }
20276 -+ rcu_read_unlock();
20277 -+ put_files_struct(files);
20278 -+ } while_each_thread(p2, p);
20279 -+ read_unlock(&tasklist_lock);
20280 -+
20281 -+ fput(our_file);
20282 -+ return 1;
20283 -+}
20284 -+
20285 -+ssize_t
20286 -+write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
20287 -+{
20288 -+ struct gr_arg_wrapper uwrap;
20289 -+ unsigned char *sprole_salt;
20290 -+ unsigned char *sprole_sum;
20291 -+ int error = sizeof (struct gr_arg_wrapper);
20292 -+ int error2 = 0;
20293 -+
20294 -+ down(&gr_dev_sem);
20295 -+
20296 -+ if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
20297 -+ error = -EPERM;
20298 -+ goto out;
20299 -+ }
20300 -+
20301 -+ if (count != sizeof (struct gr_arg_wrapper)) {
20302 -+ gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
20303 -+ error = -EINVAL;
20304 -+ goto out;
20305 -+ }
20306 -+
20307 -+
20308 -+ if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
20309 -+ gr_auth_expires = 0;
20310 -+ gr_auth_attempts = 0;
20311 -+ }
20312 -+
20313 -+ if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
20314 -+ error = -EFAULT;
20315 -+ goto out;
20316 -+ }
20317 -+
20318 -+ if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
20319 -+ error = -EINVAL;
20320 -+ goto out;
20321 -+ }
20322 -+
20323 -+ if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
20324 -+ error = -EFAULT;
20325 -+ goto out;
20326 -+ }
20327 -+
20328 -+ if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM &&
20329 -+ gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
20330 -+ time_after(gr_auth_expires, get_seconds())) {
20331 -+ error = -EBUSY;
20332 -+ goto out;
20333 -+ }
20334 -+
20335 -+ /* if non-root trying to do anything other than use a special role,
20336 -+ do not attempt authentication, do not count towards authentication
20337 -+ locking
20338 -+ */
20339 -+
20340 -+ if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS &&
20341 -+ gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM &&
20342 -+ current->uid) {
20343 -+ error = -EPERM;
20344 -+ goto out;
20345 -+ }
20346 -+
20347 -+ /* ensure pw and special role name are null terminated */
20348 -+
20349 -+ gr_usermode->pw[GR_PW_LEN - 1] = '\0';
20350 -+ gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
20351 -+
20352 -+ /* Okay.
20353 -+ * We have our enough of the argument structure..(we have yet
20354 -+ * to copy_from_user the tables themselves) . Copy the tables
20355 -+ * only if we need them, i.e. for loading operations. */
20356 -+
20357 -+ switch (gr_usermode->mode) {
20358 -+ case STATUS:
20359 -+ if (gr_status & GR_READY) {
20360 -+ error = 1;
20361 -+ if (!gr_check_secure_terminal(current))
20362 -+ error = 3;
20363 -+ } else
20364 -+ error = 2;
20365 -+ goto out;
20366 -+ case SHUTDOWN:
20367 -+ if ((gr_status & GR_READY)
20368 -+ && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
20369 -+ gr_status &= ~GR_READY;
20370 -+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
20371 -+ free_variables();
20372 -+ memset(gr_usermode, 0, sizeof (struct gr_arg));
20373 -+ memset(gr_system_salt, 0, GR_SALT_LEN);
20374 -+ memset(gr_system_sum, 0, GR_SHA_LEN);
20375 -+ } else if (gr_status & GR_READY) {
20376 -+ gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
20377 -+ error = -EPERM;
20378 -+ } else {
20379 -+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
20380 -+ error = -EAGAIN;
20381 -+ }
20382 -+ break;
20383 -+ case ENABLE:
20384 -+ if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
20385 -+ gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
20386 -+ else {
20387 -+ if (gr_status & GR_READY)
20388 -+ error = -EAGAIN;
20389 -+ else
20390 -+ error = error2;
20391 -+ gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
20392 -+ }
20393 -+ break;
20394 -+ case RELOAD:
20395 -+ if (!(gr_status & GR_READY)) {
20396 -+ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
20397 -+ error = -EAGAIN;
20398 -+ } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
20399 -+ lock_kernel();
20400 -+ gr_status &= ~GR_READY;
20401 -+ free_variables();
20402 -+ if (!(error2 = gracl_init(gr_usermode))) {
20403 -+ unlock_kernel();
20404 -+ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
20405 -+ } else {
20406 -+ unlock_kernel();
20407 -+ error = error2;
20408 -+ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
20409 -+ }
20410 -+ } else {
20411 -+ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
20412 -+ error = -EPERM;
20413 -+ }
20414 -+ break;
20415 -+ case SEGVMOD:
20416 -+ if (unlikely(!(gr_status & GR_READY))) {
20417 -+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
20418 -+ error = -EAGAIN;
20419 -+ break;
20420 -+ }
20421 -+
20422 -+ if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
20423 -+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
20424 -+ if (gr_usermode->segv_device && gr_usermode->segv_inode) {
20425 -+ struct acl_subject_label *segvacl;
20426 -+ segvacl =
20427 -+ lookup_acl_subj_label(gr_usermode->segv_inode,
20428 -+ gr_usermode->segv_device,
20429 -+ current->role);
20430 -+ if (segvacl) {
20431 -+ segvacl->crashes = 0;
20432 -+ segvacl->expires = 0;
20433 -+ }
20434 -+ } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
20435 -+ gr_remove_uid(gr_usermode->segv_uid);
20436 -+ }
20437 -+ } else {
20438 -+ gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
20439 -+ error = -EPERM;
20440 -+ }
20441 -+ break;
20442 -+ case SPROLE:
20443 -+ case SPROLEPAM:
20444 -+ if (unlikely(!(gr_status & GR_READY))) {
20445 -+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
20446 -+ error = -EAGAIN;
20447 -+ break;
20448 -+ }
20449 -+
20450 -+ if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
20451 -+ current->role->expires = 0;
20452 -+ current->role->auth_attempts = 0;
20453 -+ }
20454 -+
20455 -+ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
20456 -+ time_after(current->role->expires, get_seconds())) {
20457 -+ error = -EBUSY;
20458 -+ goto out;
20459 -+ }
20460 -+
20461 -+ if (lookup_special_role_auth
20462 -+ (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
20463 -+ && ((!sprole_salt && !sprole_sum)
20464 -+ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
20465 -+ char *p = "";
20466 -+ assign_special_role(gr_usermode->sp_role);
20467 -+ read_lock(&tasklist_lock);
20468 -+ if (current->parent)
20469 -+ p = current->parent->role->rolename;
20470 -+ read_unlock(&tasklist_lock);
20471 -+ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
20472 -+ p, acl_sp_role_value);
20473 -+ } else {
20474 -+ gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
20475 -+ error = -EPERM;
20476 -+ if(!(current->role->auth_attempts++))
20477 -+ current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
20478 -+
20479 -+ goto out;
20480 -+ }
20481 -+ break;
20482 -+ case UNSPROLE:
20483 -+ if (unlikely(!(gr_status & GR_READY))) {
20484 -+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
20485 -+ error = -EAGAIN;
20486 -+ break;
20487 -+ }
20488 -+
20489 -+ if (current->role->roletype & GR_ROLE_SPECIAL) {
20490 -+ char *p = "";
20491 -+ int i = 0;
20492 -+
20493 -+ read_lock(&tasklist_lock);
20494 -+ if (current->parent) {
20495 -+ p = current->parent->role->rolename;
20496 -+ i = current->parent->acl_role_id;
20497 -+ }
20498 -+ read_unlock(&tasklist_lock);
20499 -+
20500 -+ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
20501 -+ gr_set_acls(1);
20502 -+ } else {
20503 -+ gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
20504 -+ error = -EPERM;
20505 -+ goto out;
20506 -+ }
20507 -+ break;
20508 -+ default:
20509 -+ gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
20510 -+ error = -EINVAL;
20511 -+ break;
20512 -+ }
20513 -+
20514 -+ if (error != -EPERM)
20515 -+ goto out;
20516 -+
20517 -+ if(!(gr_auth_attempts++))
20518 -+ gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
20519 -+
20520 -+ out:
20521 -+ up(&gr_dev_sem);
20522 -+ return error;
20523 -+}
20524 -+
20525 -+int
20526 -+gr_set_acls(const int type)
20527 -+{
20528 -+ struct acl_object_label *obj;
20529 -+ struct task_struct *task, *task2;
20530 -+ struct file *filp;
20531 -+ struct acl_role_label *role = current->role;
20532 -+ __u16 acl_role_id = current->acl_role_id;
20533 -+
20534 -+ read_lock(&tasklist_lock);
20535 -+ read_lock(&grsec_exec_file_lock);
20536 -+ do_each_thread(task2, task) {
20537 -+ /* check to see if we're called from the exit handler,
20538 -+ if so, only replace ACLs that have inherited the admin
20539 -+ ACL */
20540 -+
20541 -+ if (type && (task->role != role ||
20542 -+ task->acl_role_id != acl_role_id))
20543 -+ continue;
20544 -+
20545 -+ task->acl_role_id = 0;
20546 -+ task->acl_sp_role = 0;
20547 -+
20548 -+ if ((filp = task->exec_file)) {
20549 -+ task->role = lookup_acl_role_label(task, task->uid, task->gid);
20550 -+
20551 -+ task->acl =
20552 -+ chk_subj_label(filp->f_path.dentry, filp->f_path.mnt,
20553 -+ task->role);
20554 -+ if (task->acl) {
20555 -+ struct acl_subject_label *curr;
20556 -+ curr = task->acl;
20557 -+
20558 -+ task->is_writable = 0;
20559 -+ /* ignore additional mmap checks for processes that are writable
20560 -+ by the default ACL */
20561 -+ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
20562 -+ if (unlikely(obj->mode & GR_WRITE))
20563 -+ task->is_writable = 1;
20564 -+ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
20565 -+ if (unlikely(obj->mode & GR_WRITE))
20566 -+ task->is_writable = 1;
20567 -+
20568 -+ gr_set_proc_res(task);
20569 -+
20570 -+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
20571 -+ printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
20572 -+#endif
20573 -+ } else {
20574 -+ read_unlock(&grsec_exec_file_lock);
20575 -+ read_unlock(&tasklist_lock);
20576 -+ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
20577 -+ return 1;
20578 -+ }
20579 -+ } else {
20580 -+ // it's a kernel process
20581 -+ task->role = kernel_role;
20582 -+ task->acl = kernel_role->root_label;
20583 -+#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
20584 -+ task->acl->mode &= ~GR_PROCFIND;
20585 -+#endif
20586 -+ }
20587 -+ } while_each_thread(task2, task);
20588 -+ read_unlock(&grsec_exec_file_lock);
20589 -+ read_unlock(&tasklist_lock);
20590 -+ return 0;
20591 -+}
20592 -+
20593 -+void
20594 -+gr_learn_resource(const struct task_struct *task,
20595 -+ const int res, const unsigned long wanted, const int gt)
20596 -+{
20597 -+ struct acl_subject_label *acl;
20598 -+
20599 -+ if (unlikely((gr_status & GR_READY) &&
20600 -+ task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
20601 -+ goto skip_reslog;
20602 -+
20603 -+#ifdef CONFIG_GRKERNSEC_RESLOG
20604 -+ gr_log_resource(task, res, wanted, gt);
20605 -+#endif
20606 -+ skip_reslog:
20607 -+
20608 -+ if (unlikely(!(gr_status & GR_READY) || !wanted))
20609 -+ return;
20610 -+
20611 -+ acl = task->acl;
20612 -+
20613 -+ if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
20614 -+ !(acl->resmask & (1 << (unsigned short) res))))
20615 -+ return;
20616 -+
20617 -+ if (wanted >= acl->res[res].rlim_cur) {
20618 -+ unsigned long res_add;
20619 -+
20620 -+ res_add = wanted;
20621 -+ switch (res) {
20622 -+ case RLIMIT_CPU:
20623 -+ res_add += GR_RLIM_CPU_BUMP;
20624 -+ break;
20625 -+ case RLIMIT_FSIZE:
20626 -+ res_add += GR_RLIM_FSIZE_BUMP;
20627 -+ break;
20628 -+ case RLIMIT_DATA:
20629 -+ res_add += GR_RLIM_DATA_BUMP;
20630 -+ break;
20631 -+ case RLIMIT_STACK:
20632 -+ res_add += GR_RLIM_STACK_BUMP;
20633 -+ break;
20634 -+ case RLIMIT_CORE:
20635 -+ res_add += GR_RLIM_CORE_BUMP;
20636 -+ break;
20637 -+ case RLIMIT_RSS:
20638 -+ res_add += GR_RLIM_RSS_BUMP;
20639 -+ break;
20640 -+ case RLIMIT_NPROC:
20641 -+ res_add += GR_RLIM_NPROC_BUMP;
20642 -+ break;
20643 -+ case RLIMIT_NOFILE:
20644 -+ res_add += GR_RLIM_NOFILE_BUMP;
20645 -+ break;
20646 -+ case RLIMIT_MEMLOCK:
20647 -+ res_add += GR_RLIM_MEMLOCK_BUMP;
20648 -+ break;
20649 -+ case RLIMIT_AS:
20650 -+ res_add += GR_RLIM_AS_BUMP;
20651 -+ break;
20652 -+ case RLIMIT_LOCKS:
20653 -+ res_add += GR_RLIM_LOCKS_BUMP;
20654 -+ break;
20655 -+ }
20656 -+
20657 -+ acl->res[res].rlim_cur = res_add;
20658 -+
20659 -+ if (wanted > acl->res[res].rlim_max)
20660 -+ acl->res[res].rlim_max = res_add;
20661 -+
20662 -+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
20663 -+ task->role->roletype, acl->filename,
20664 -+ acl->res[res].rlim_cur, acl->res[res].rlim_max,
20665 -+ "", (unsigned long) res);
20666 -+ }
20667 -+
20668 -+ return;
20669 -+}
20670 -+
20671 -+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
20672 -+void
20673 -+pax_set_initial_flags(struct linux_binprm *bprm)
20674 -+{
20675 -+ struct task_struct *task = current;
20676 -+ struct acl_subject_label *proc;
20677 -+ unsigned long flags;
20678 -+
20679 -+ if (unlikely(!(gr_status & GR_READY)))
20680 -+ return;
20681 -+
20682 -+ flags = pax_get_flags(task);
20683 -+
20684 -+ proc = task->acl;
20685 -+
20686 -+ if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
20687 -+ flags &= ~MF_PAX_PAGEEXEC;
20688 -+ if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
20689 -+ flags &= ~MF_PAX_SEGMEXEC;
20690 -+ if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
20691 -+ flags &= ~MF_PAX_RANDMMAP;
20692 -+ if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
20693 -+ flags &= ~MF_PAX_EMUTRAMP;
20694 -+ if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
20695 -+ flags &= ~MF_PAX_MPROTECT;
20696 -+
20697 -+ if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
20698 -+ flags |= MF_PAX_PAGEEXEC;
20699 -+ if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
20700 -+ flags |= MF_PAX_SEGMEXEC;
20701 -+ if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
20702 -+ flags |= MF_PAX_RANDMMAP;
20703 -+ if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
20704 -+ flags |= MF_PAX_EMUTRAMP;
20705 -+ if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
20706 -+ flags |= MF_PAX_MPROTECT;
20707 -+
20708 -+ pax_set_flags(task, flags);
20709 -+
20710 -+ return;
20711 -+}
20712 -+#endif
20713 -+
20714 -+#ifdef CONFIG_SYSCTL
20715 -+/* Eric Biederman likes breaking userland ABI and every inode-based security
20716 -+ system to save 35kb of memory */
20717 -+
20718 -+/* we modify the passed in filename, but adjust it back before returning */
20719 -+static struct acl_object_label *gr_lookup_by_name(char *name, unsigned int len)
20720 -+{
20721 -+ struct name_entry *nmatch;
20722 -+ char *p, *lastp = NULL;
20723 -+ struct acl_object_label *obj = NULL, *tmp;
20724 -+ struct acl_subject_label *tmpsubj;
20725 -+ char c = '\0';
20726 -+
20727 -+ read_lock(&gr_inode_lock);
20728 -+
20729 -+ p = name + len - 1;
20730 -+ do {
20731 -+ nmatch = lookup_name_entry(name);
20732 -+ if (lastp != NULL)
20733 -+ *lastp = c;
20734 -+
20735 -+ if (nmatch == NULL)
20736 -+ goto next_component;
20737 -+ tmpsubj = current->acl;
20738 -+ do {
20739 -+ obj = lookup_acl_obj_label(nmatch->inode, nmatch->device, tmpsubj);
20740 -+ if (obj != NULL) {
20741 -+ tmp = obj->globbed;
20742 -+ while (tmp) {
20743 -+ if (!glob_match(tmp->filename, name)) {
20744 -+ obj = tmp;
20745 -+ goto found_obj;
20746 -+ }
20747 -+ tmp = tmp->next;
20748 -+ }
20749 -+ goto found_obj;
20750 -+ }
20751 -+ } while ((tmpsubj = tmpsubj->parent_subject));
20752 -+next_component:
20753 -+ /* end case */
20754 -+ if (p == name)
20755 -+ break;
20756 -+
20757 -+ while (*p != '/')
20758 -+ p--;
20759 -+ if (p == name)
20760 -+ lastp = p + 1;
20761 -+ else {
20762 -+ lastp = p;
20763 -+ p--;
20764 -+ }
20765 -+ c = *lastp;
20766 -+ *lastp = '\0';
20767 -+ } while (1);
20768 -+found_obj:
20769 -+ read_unlock(&gr_inode_lock);
20770 -+ /* obj returned will always be non-null */
20771 -+ return obj;
20772 -+}
20773 -+
20774 -+/* returns 0 when allowing, non-zero on error
20775 -+ op of 0 is used for readdir, so we don't log the names of hidden files
20776 -+*/
20777 -+__u32
20778 -+gr_handle_sysctl(const struct ctl_table *table, const int op)
20779 -+{
20780 -+ ctl_table *tmp;
20781 -+ const char *proc_sys = "/proc/sys";
20782 -+ char *path;
20783 -+ struct acl_object_label *obj;
20784 -+ unsigned short len = 0, pos = 0, depth = 0, i;
20785 -+ __u32 err = 0;
20786 -+ __u32 mode = 0;
20787 -+
20788 -+ if (unlikely(!(gr_status & GR_READY)))
20789 -+ return 0;
20790 -+
20791 -+ /* for now, ignore operations on non-sysctl entries if it's not a
20792 -+ readdir*/
20793 -+ if (table->child != NULL && op != 0)
20794 -+ return 0;
20795 -+
20796 -+ mode |= GR_FIND;
20797 -+ /* it's only a read if it's an entry, read on dirs is for readdir */
20798 -+ if (op & MAY_READ)
20799 -+ mode |= GR_READ;
20800 -+ if (op & MAY_WRITE)
20801 -+ mode |= GR_WRITE;
20802 -+
20803 -+ preempt_disable();
20804 -+
20805 -+ path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
20806 -+
20807 -+ /* it's only a read/write if it's an actual entry, not a dir
20808 -+ (which are opened for readdir)
20809 -+ */
20810 -+
20811 -+ /* convert the requested sysctl entry into a pathname */
20812 -+
20813 -+ for (tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
20814 -+ len += strlen(tmp->procname);
20815 -+ len++;
20816 -+ depth++;
20817 -+ }
20818 -+
20819 -+ if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE) {
20820 -+ /* deny */
20821 -+ goto out;
20822 -+ }
20823 -+
20824 -+ memset(path, 0, PAGE_SIZE);
20825 -+
20826 -+ memcpy(path, proc_sys, strlen(proc_sys));
20827 -+
20828 -+ pos += strlen(proc_sys);
20829 -+
20830 -+ for (; depth > 0; depth--) {
20831 -+ path[pos] = '/';
20832 -+ pos++;
20833 -+ for (i = 1, tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
20834 -+ if (depth == i) {
20835 -+ memcpy(path + pos, tmp->procname,
20836 -+ strlen(tmp->procname));
20837 -+ pos += strlen(tmp->procname);
20838 -+ }
20839 -+ i++;
20840 -+ }
20841 -+ }
20842 -+
20843 -+ obj = gr_lookup_by_name(path, pos);
20844 -+ err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
20845 -+
20846 -+ if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
20847 -+ ((err & mode) != mode))) {
20848 -+ __u32 new_mode = mode;
20849 -+
20850 -+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
20851 -+
20852 -+ err = 0;
20853 -+ gr_log_learn_sysctl(current, path, new_mode);
20854 -+ } else if (!(err & GR_FIND) && !(err & GR_SUPPRESS) && op != 0) {
20855 -+ gr_log_hidden_sysctl(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, path);
20856 -+ err = -ENOENT;
20857 -+ } else if (!(err & GR_FIND)) {
20858 -+ err = -ENOENT;
20859 -+ } else if (((err & mode) & ~GR_FIND) != (mode & ~GR_FIND) && !(err & GR_SUPPRESS)) {
20860 -+ gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
20861 -+ path, (mode & GR_READ) ? " reading" : "",
20862 -+ (mode & GR_WRITE) ? " writing" : "");
20863 -+ err = -EACCES;
20864 -+ } else if ((err & mode) != mode) {
20865 -+ err = -EACCES;
20866 -+ } else if ((((err & mode) & ~GR_FIND) == (mode & ~GR_FIND)) && (err & GR_AUDITS)) {
20867 -+ gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
20868 -+ path, (mode & GR_READ) ? " reading" : "",
20869 -+ (mode & GR_WRITE) ? " writing" : "");
20870 -+ err = 0;
20871 -+ } else
20872 -+ err = 0;
20873 -+
20874 -+ out:
20875 -+ preempt_enable();
20876 -+
20877 -+ return err;
20878 -+}
20879 -+#endif
20880 -+
20881 -+int
20882 -+gr_handle_proc_ptrace(struct task_struct *task)
20883 -+{
20884 -+ struct file *filp;
20885 -+ struct task_struct *tmp = task;
20886 -+ struct task_struct *curtemp = current;
20887 -+ __u32 retmode;
20888 -+
20889 -+ if (unlikely(!(gr_status & GR_READY)))
20890 -+ return 0;
20891 -+
20892 -+ read_lock(&tasklist_lock);
20893 -+ read_lock(&grsec_exec_file_lock);
20894 -+ filp = task->exec_file;
20895 -+
20896 -+ while (tmp->pid > 0) {
20897 -+ if (tmp == curtemp)
20898 -+ break;
20899 -+ tmp = tmp->parent;
20900 -+ }
20901 -+
20902 -+ if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
20903 -+ read_unlock(&grsec_exec_file_lock);
20904 -+ read_unlock(&tasklist_lock);
20905 -+ return 1;
20906 -+ }
20907 -+
20908 -+ retmode = gr_search_file(filp->f_path.dentry, GR_NOPTRACE, filp->f_path.mnt);
20909 -+ read_unlock(&grsec_exec_file_lock);
20910 -+ read_unlock(&tasklist_lock);
20911 -+
20912 -+ if (retmode & GR_NOPTRACE)
20913 -+ return 1;
20914 -+
20915 -+ if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
20916 -+ && (current->acl != task->acl || (current->acl != current->role->root_label
20917 -+ && current->pid != task->pid)))
20918 -+ return 1;
20919 -+
20920 -+ return 0;
20921 -+}
20922 -+
20923 -+int
20924 -+gr_handle_ptrace(struct task_struct *task, const long request)
20925 -+{
20926 -+ struct task_struct *tmp = task;
20927 -+ struct task_struct *curtemp = current;
20928 -+ __u32 retmode;
20929 -+
20930 -+ if (unlikely(!(gr_status & GR_READY)))
20931 -+ return 0;
20932 -+
20933 -+ read_lock(&tasklist_lock);
20934 -+ while (tmp->pid > 0) {
20935 -+ if (tmp == curtemp)
20936 -+ break;
20937 -+ tmp = tmp->parent;
20938 -+ }
20939 -+
20940 -+ if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
20941 -+ read_unlock(&tasklist_lock);
20942 -+ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
20943 -+ return 1;
20944 -+ }
20945 -+ read_unlock(&tasklist_lock);
20946 -+
20947 -+ read_lock(&grsec_exec_file_lock);
20948 -+ if (unlikely(!task->exec_file)) {
20949 -+ read_unlock(&grsec_exec_file_lock);
20950 -+ return 0;
20951 -+ }
20952 -+
20953 -+ retmode = gr_search_file(task->exec_file->f_path.dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_path.mnt);
20954 -+ read_unlock(&grsec_exec_file_lock);
20955 -+
20956 -+ if (retmode & GR_NOPTRACE) {
20957 -+ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
20958 -+ return 1;
20959 -+ }
20960 -+
20961 -+ if (retmode & GR_PTRACERD) {
20962 -+ switch (request) {
20963 -+ case PTRACE_POKETEXT:
20964 -+ case PTRACE_POKEDATA:
20965 -+ case PTRACE_POKEUSR:
20966 -+#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
20967 -+ case PTRACE_SETREGS:
20968 -+ case PTRACE_SETFPREGS:
20969 -+#endif
20970 -+#ifdef CONFIG_X86
20971 -+ case PTRACE_SETFPXREGS:
20972 -+#endif
20973 -+#ifdef CONFIG_ALTIVEC
20974 -+ case PTRACE_SETVRREGS:
20975 -+#endif
20976 -+ return 1;
20977 -+ default:
20978 -+ return 0;
20979 -+ }
20980 -+ } else if (!(current->acl->mode & GR_POVERRIDE) &&
20981 -+ !(current->role->roletype & GR_ROLE_GOD) &&
20982 -+ (current->acl != task->acl)) {
20983 -+ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
20984 -+ return 1;
20985 -+ }
20986 -+
20987 -+ return 0;
20988 -+}
20989 -+
20990 -+static int is_writable_mmap(const struct file *filp)
20991 -+{
20992 -+ struct task_struct *task = current;
20993 -+ struct acl_object_label *obj, *obj2;
20994 -+
20995 -+ if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
20996 -+ !task->is_writable && S_ISREG(filp->f_path.dentry->d_inode->i_mode)) {
20997 -+ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
20998 -+ obj2 = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt,
20999 -+ task->role->root_label);
21000 -+ if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
21001 -+ gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_path.dentry, filp->f_path.mnt);
21002 -+ return 1;
21003 -+ }
21004 -+ }
21005 -+ return 0;
21006 -+}
21007 -+
21008 -+int
21009 -+gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
21010 -+{
21011 -+ __u32 mode;
21012 -+
21013 -+ if (unlikely(!file || !(prot & PROT_EXEC)))
21014 -+ return 1;
21015 -+
21016 -+ if (is_writable_mmap(file))
21017 -+ return 0;
21018 -+
21019 -+ mode =
21020 -+ gr_search_file(file->f_path.dentry,
21021 -+ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
21022 -+ file->f_path.mnt);
21023 -+
21024 -+ if (!gr_tpe_allow(file))
21025 -+ return 0;
21026 -+
21027 -+ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
21028 -+ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
21029 -+ return 0;
21030 -+ } else if (unlikely(!(mode & GR_EXEC))) {
21031 -+ return 0;
21032 -+ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
21033 -+ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
21034 -+ return 1;
21035 -+ }
21036 -+
21037 -+ return 1;
21038 -+}
21039 -+
21040 -+int
21041 -+gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
21042 -+{
21043 -+ __u32 mode;
21044 -+
21045 -+ if (unlikely(!file || !(prot & PROT_EXEC)))
21046 -+ return 1;
21047 -+
21048 -+ if (is_writable_mmap(file))
21049 -+ return 0;
21050 -+
21051 -+ mode =
21052 -+ gr_search_file(file->f_path.dentry,
21053 -+ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
21054 -+ file->f_path.mnt);
21055 -+
21056 -+ if (!gr_tpe_allow(file))
21057 -+ return 0;
21058 -+
21059 -+ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
21060 -+ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
21061 -+ return 0;
21062 -+ } else if (unlikely(!(mode & GR_EXEC))) {
21063 -+ return 0;
21064 -+ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
21065 -+ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
21066 -+ return 1;
21067 -+ }
21068 -+
21069 -+ return 1;
21070 -+}
21071 -+
21072 -+void
21073 -+gr_acl_handle_psacct(struct task_struct *task, const long code)
21074 -+{
21075 -+ unsigned long runtime;
21076 -+ unsigned long cputime;
21077 -+ unsigned int wday, cday;
21078 -+ __u8 whr, chr;
21079 -+ __u8 wmin, cmin;
21080 -+ __u8 wsec, csec;
21081 -+ struct timespec timeval;
21082 -+
21083 -+ if (unlikely(!(gr_status & GR_READY) || !task->acl ||
21084 -+ !(task->acl->mode & GR_PROCACCT)))
21085 -+ return;
21086 -+
21087 -+ do_posix_clock_monotonic_gettime(&timeval);
21088 -+ runtime = timeval.tv_sec - task->start_time.tv_sec;
21089 -+ wday = runtime / (3600 * 24);
21090 -+ runtime -= wday * (3600 * 24);
21091 -+ whr = runtime / 3600;
21092 -+ runtime -= whr * 3600;
21093 -+ wmin = runtime / 60;
21094 -+ runtime -= wmin * 60;
21095 -+ wsec = runtime;
21096 -+
21097 -+ cputime = (task->utime + task->stime) / HZ;
21098 -+ cday = cputime / (3600 * 24);
21099 -+ cputime -= cday * (3600 * 24);
21100 -+ chr = cputime / 3600;
21101 -+ cputime -= chr * 3600;
21102 -+ cmin = cputime / 60;
21103 -+ cputime -= cmin * 60;
21104 -+ csec = cputime;
21105 -+
21106 -+ gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
21107 -+
21108 -+ return;
21109 -+}
21110 -+
21111 -+void gr_set_kernel_label(struct task_struct *task)
21112 -+{
21113 -+ if (gr_status & GR_READY) {
21114 -+ task->role = kernel_role;
21115 -+ task->acl = kernel_role->root_label;
21116 -+ }
21117 -+ return;
21118 -+}
21119 -+
21120 -+int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
21121 -+{
21122 -+ struct task_struct *task = current;
21123 -+ struct dentry *dentry = file->f_path.dentry;
21124 -+ struct vfsmount *mnt = file->f_path.mnt;
21125 -+ struct acl_object_label *obj, *tmp;
21126 -+ struct acl_subject_label *subj;
21127 -+ unsigned int bufsize;
21128 -+ int is_not_root;
21129 -+ char *path;
21130 -+
21131 -+ if (unlikely(!(gr_status & GR_READY)))
21132 -+ return 1;
21133 -+
21134 -+ if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
21135 -+ return 1;
21136 -+
21137 -+ /* ignore Eric Biederman */
21138 -+ if (IS_PRIVATE(dentry->d_inode))
21139 -+ return 1;
21140 -+
21141 -+ subj = task->acl;
21142 -+ do {
21143 -+ obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
21144 -+ if (obj != NULL)
21145 -+ return (obj->mode & GR_FIND) ? 1 : 0;
21146 -+ } while ((subj = subj->parent_subject));
21147 -+
21148 -+ obj = chk_obj_label(dentry, mnt, task->acl);
21149 -+ if (obj->globbed == NULL)
21150 -+ return (obj->mode & GR_FIND) ? 1 : 0;
21151 -+
21152 -+ is_not_root = ((obj->filename[0] == '/') &&
21153 -+ (obj->filename[1] == '\0')) ? 0 : 1;
21154 -+ bufsize = PAGE_SIZE - namelen - is_not_root;
21155 -+
21156 -+ /* check bufsize > PAGE_SIZE || bufsize == 0 */
21157 -+ if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
21158 -+ return 1;
21159 -+
21160 -+ preempt_disable();
21161 -+ path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
21162 -+ bufsize);
21163 -+
21164 -+ bufsize = strlen(path);
21165 -+
21166 -+ /* if base is "/", don't append an additional slash */
21167 -+ if (is_not_root)
21168 -+ *(path + bufsize) = '/';
21169 -+ memcpy(path + bufsize + is_not_root, name, namelen);
21170 -+ *(path + bufsize + namelen + is_not_root) = '\0';
21171 -+
21172 -+ tmp = obj->globbed;
21173 -+ while (tmp) {
21174 -+ if (!glob_match(tmp->filename, path)) {
21175 -+ preempt_enable();
21176 -+ return (tmp->mode & GR_FIND) ? 1 : 0;
21177 -+ }
21178 -+ tmp = tmp->next;
21179 -+ }
21180 -+ preempt_enable();
21181 -+ return (obj->mode & GR_FIND) ? 1 : 0;
21182 -+}
21183 -+
21184 -+EXPORT_SYMBOL(gr_learn_resource);
21185 -+EXPORT_SYMBOL(gr_set_kernel_label);
21186 -+#ifdef CONFIG_SECURITY
21187 -+EXPORT_SYMBOL(gr_check_user_change);
21188 -+EXPORT_SYMBOL(gr_check_group_change);
21189 -+#endif
21190 -+
21191 -diff -urNp linux-2.6.27.6/grsecurity/gracl_cap.c linux-2.6.27.6/grsecurity/gracl_cap.c
21192 ---- linux-2.6.27.6/grsecurity/gracl_cap.c 1969-12-31 19:00:00.000000000 -0500
21193 -+++ linux-2.6.27.6/grsecurity/gracl_cap.c 2008-11-18 03:38:45.000000000 -0500
21194 -@@ -0,0 +1,129 @@
21195 -+#include <linux/kernel.h>
21196 -+#include <linux/module.h>
21197 -+#include <linux/sched.h>
21198 -+#include <linux/gracl.h>
21199 -+#include <linux/grsecurity.h>
21200 -+#include <linux/grinternal.h>
21201 -+
21202 -+static const char *captab_log[] = {
21203 -+ "CAP_CHOWN",
21204 -+ "CAP_DAC_OVERRIDE",
21205 -+ "CAP_DAC_READ_SEARCH",
21206 -+ "CAP_FOWNER",
21207 -+ "CAP_FSETID",
21208 -+ "CAP_KILL",
21209 -+ "CAP_SETGID",
21210 -+ "CAP_SETUID",
21211 -+ "CAP_SETPCAP",
21212 -+ "CAP_LINUX_IMMUTABLE",
21213 -+ "CAP_NET_BIND_SERVICE",
21214 -+ "CAP_NET_BROADCAST",
21215 -+ "CAP_NET_ADMIN",
21216 -+ "CAP_NET_RAW",
21217 -+ "CAP_IPC_LOCK",
21218 -+ "CAP_IPC_OWNER",
21219 -+ "CAP_SYS_MODULE",
21220 -+ "CAP_SYS_RAWIO",
21221 -+ "CAP_SYS_CHROOT",
21222 -+ "CAP_SYS_PTRACE",
21223 -+ "CAP_SYS_PACCT",
21224 -+ "CAP_SYS_ADMIN",
21225 -+ "CAP_SYS_BOOT",
21226 -+ "CAP_SYS_NICE",
21227 -+ "CAP_SYS_RESOURCE",
21228 -+ "CAP_SYS_TIME",
21229 -+ "CAP_SYS_TTY_CONFIG",
21230 -+ "CAP_MKNOD",
21231 -+ "CAP_LEASE",
21232 -+ "CAP_AUDIT_WRITE",
21233 -+ "CAP_AUDIT_CONTROL",
21234 -+ "CAP_SETFCAP",
21235 -+ "CAP_MAC_OVERRIDE",
21236 -+ "CAP_MAC_ADMIN"
21237 -+};
21238 -+
21239 -+EXPORT_SYMBOL(gr_task_is_capable);
21240 -+EXPORT_SYMBOL(gr_is_capable_nolog);
21241 -+
21242 -+int
21243 -+gr_task_is_capable(struct task_struct *task, const int cap)
21244 -+{
21245 -+ struct acl_subject_label *curracl;
21246 -+ kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
21247 -+
21248 -+ if (!gr_acl_is_enabled())
21249 -+ return 1;
21250 -+
21251 -+ curracl = task->acl;
21252 -+
21253 -+ cap_drop = curracl->cap_lower;
21254 -+ cap_mask = curracl->cap_mask;
21255 -+
21256 -+ while ((curracl = curracl->parent_subject)) {
21257 -+ /* if the cap isn't specified in the current computed mask but is specified in the
21258 -+ current level subject, and is lowered in the current level subject, then add
21259 -+ it to the set of dropped capabilities
21260 -+ otherwise, add the current level subject's mask to the current computed mask
21261 -+ */
21262 -+ if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
21263 -+ cap_raise(cap_mask, cap);
21264 -+ if (cap_raised(curracl->cap_lower, cap))
21265 -+ cap_raise(cap_drop, cap);
21266 -+ }
21267 -+ }
21268 -+
21269 -+ if (!cap_raised(cap_drop, cap))
21270 -+ return 1;
21271 -+
21272 -+ curracl = task->acl;
21273 -+
21274 -+ if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
21275 -+ && cap_raised(task->cap_effective, cap)) {
21276 -+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
21277 -+ task->role->roletype, task->uid,
21278 -+ task->gid, task->exec_file ?
21279 -+ gr_to_filename(task->exec_file->f_path.dentry,
21280 -+ task->exec_file->f_path.mnt) : curracl->filename,
21281 -+ curracl->filename, 0UL,
21282 -+ 0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
21283 -+ return 1;
21284 -+ }
21285 -+
21286 -+ if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap))
21287 -+ gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
21288 -+ return 0;
21289 -+}
21290 -+
21291 -+int
21292 -+gr_is_capable_nolog(const int cap)
21293 -+{
21294 -+ struct acl_subject_label *curracl;
21295 -+ kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
21296 -+
21297 -+ if (!gr_acl_is_enabled())
21298 -+ return 1;
21299 -+
21300 -+ curracl = current->acl;
21301 -+
21302 -+ cap_drop = curracl->cap_lower;
21303 -+ cap_mask = curracl->cap_mask;
21304 -+
21305 -+ while ((curracl = curracl->parent_subject)) {
21306 -+ /* if the cap isn't specified in the current computed mask but is specified in the
21307 -+ current level subject, and is lowered in the current level subject, then add
21308 -+ it to the set of dropped capabilities
21309 -+ otherwise, add the current level subject's mask to the current computed mask
21310 -+ */
21311 -+ if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
21312 -+ cap_raise(cap_mask, cap);
21313 -+ if (cap_raised(curracl->cap_lower, cap))
21314 -+ cap_raise(cap_drop, cap);
21315 -+ }
21316 -+ }
21317 -+
21318 -+ if (!cap_raised(cap_drop, cap))
21319 -+ return 1;
21320 -+
21321 -+ return 0;
21322 -+}
21323 -+
21324 -diff -urNp linux-2.6.27.6/grsecurity/gracl_fs.c linux-2.6.27.6/grsecurity/gracl_fs.c
21325 ---- linux-2.6.27.6/grsecurity/gracl_fs.c 1969-12-31 19:00:00.000000000 -0500
21326 -+++ linux-2.6.27.6/grsecurity/gracl_fs.c 2008-11-18 03:38:45.000000000 -0500
21327 -@@ -0,0 +1,423 @@
21328 -+#include <linux/kernel.h>
21329 -+#include <linux/sched.h>
21330 -+#include <linux/types.h>
21331 -+#include <linux/fs.h>
21332 -+#include <linux/file.h>
21333 -+#include <linux/stat.h>
21334 -+#include <linux/grsecurity.h>
21335 -+#include <linux/grinternal.h>
21336 -+#include <linux/gracl.h>
21337 -+
21338 -+__u32
21339 -+gr_acl_handle_hidden_file(const struct dentry * dentry,
21340 -+ const struct vfsmount * mnt)
21341 -+{
21342 -+ __u32 mode;
21343 -+
21344 -+ if (unlikely(!dentry->d_inode))
21345 -+ return GR_FIND;
21346 -+
21347 -+ mode =
21348 -+ gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
21349 -+
21350 -+ if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
21351 -+ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
21352 -+ return mode;
21353 -+ } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
21354 -+ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
21355 -+ return 0;
21356 -+ } else if (unlikely(!(mode & GR_FIND)))
21357 -+ return 0;
21358 -+
21359 -+ return GR_FIND;
21360 -+}
21361 -+
21362 -+__u32
21363 -+gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
21364 -+ const int fmode)
21365 -+{
21366 -+ __u32 reqmode = GR_FIND;
21367 -+ __u32 mode;
21368 -+
21369 -+ if (unlikely(!dentry->d_inode))
21370 -+ return reqmode;
21371 -+
21372 -+ if (unlikely(fmode & O_APPEND))
21373 -+ reqmode |= GR_APPEND;
21374 -+ else if (unlikely(fmode & FMODE_WRITE))
21375 -+ reqmode |= GR_WRITE;
21376 -+ if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
21377 -+ reqmode |= GR_READ;
21378 -+
21379 -+ mode =
21380 -+ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
21381 -+ mnt);
21382 -+
21383 -+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
21384 -+ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
21385 -+ reqmode & GR_READ ? " reading" : "",
21386 -+ reqmode & GR_WRITE ? " writing" : reqmode &
21387 -+ GR_APPEND ? " appending" : "");
21388 -+ return reqmode;
21389 -+ } else
21390 -+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
21391 -+ {
21392 -+ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
21393 -+ reqmode & GR_READ ? " reading" : "",
21394 -+ reqmode & GR_WRITE ? " writing" : reqmode &
21395 -+ GR_APPEND ? " appending" : "");
21396 -+ return 0;
21397 -+ } else if (unlikely((mode & reqmode) != reqmode))
21398 -+ return 0;
21399 -+
21400 -+ return reqmode;
21401 -+}
21402 -+
21403 -+__u32
21404 -+gr_acl_handle_creat(const struct dentry * dentry,
21405 -+ const struct dentry * p_dentry,
21406 -+ const struct vfsmount * p_mnt, const int fmode,
21407 -+ const int imode)
21408 -+{
21409 -+ __u32 reqmode = GR_WRITE | GR_CREATE;
21410 -+ __u32 mode;
21411 -+
21412 -+ if (unlikely(fmode & O_APPEND))
21413 -+ reqmode |= GR_APPEND;
21414 -+ if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
21415 -+ reqmode |= GR_READ;
21416 -+ if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
21417 -+ reqmode |= GR_SETID;
21418 -+
21419 -+ mode =
21420 -+ gr_check_create(dentry, p_dentry, p_mnt,
21421 -+ reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
21422 -+
21423 -+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
21424 -+ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
21425 -+ reqmode & GR_READ ? " reading" : "",
21426 -+ reqmode & GR_WRITE ? " writing" : reqmode &
21427 -+ GR_APPEND ? " appending" : "");
21428 -+ return reqmode;
21429 -+ } else
21430 -+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
21431 -+ {
21432 -+ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
21433 -+ reqmode & GR_READ ? " reading" : "",
21434 -+ reqmode & GR_WRITE ? " writing" : reqmode &
21435 -+ GR_APPEND ? " appending" : "");
21436 -+ return 0;
21437 -+ } else if (unlikely((mode & reqmode) != reqmode))
21438 -+ return 0;
21439 -+
21440 -+ return reqmode;
21441 -+}
21442 -+
21443 -+__u32
21444 -+gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
21445 -+ const int fmode)
21446 -+{
21447 -+ __u32 mode, reqmode = GR_FIND;
21448 -+
21449 -+ if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
21450 -+ reqmode |= GR_EXEC;
21451 -+ if (fmode & S_IWOTH)
21452 -+ reqmode |= GR_WRITE;
21453 -+ if (fmode & S_IROTH)
21454 -+ reqmode |= GR_READ;
21455 -+
21456 -+ mode =
21457 -+ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
21458 -+ mnt);
21459 -+
21460 -+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
21461 -+ gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
21462 -+ reqmode & GR_READ ? " reading" : "",
21463 -+ reqmode & GR_WRITE ? " writing" : "",
21464 -+ reqmode & GR_EXEC ? " executing" : "");
21465 -+ return reqmode;
21466 -+ } else
21467 -+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
21468 -+ {
21469 -+ gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
21470 -+ reqmode & GR_READ ? " reading" : "",
21471 -+ reqmode & GR_WRITE ? " writing" : "",
21472 -+ reqmode & GR_EXEC ? " executing" : "");
21473 -+ return 0;
21474 -+ } else if (unlikely((mode & reqmode) != reqmode))
21475 -+ return 0;
21476 -+
21477 -+ return reqmode;
21478 -+}
21479 -+
21480 -+static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
21481 -+{
21482 -+ __u32 mode;
21483 -+
21484 -+ mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
21485 -+
21486 -+ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
21487 -+ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
21488 -+ return mode;
21489 -+ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
21490 -+ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
21491 -+ return 0;
21492 -+ } else if (unlikely((mode & (reqmode)) != (reqmode)))
21493 -+ return 0;
21494 -+
21495 -+ return (reqmode);
21496 -+}
21497 -+
21498 -+__u32
21499 -+gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
21500 -+{
21501 -+ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
21502 -+}
21503 -+
21504 -+__u32
21505 -+gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
21506 -+{
21507 -+ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
21508 -+}
21509 -+
21510 -+__u32
21511 -+gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
21512 -+{
21513 -+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
21514 -+}
21515 -+
21516 -+__u32
21517 -+gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
21518 -+{
21519 -+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
21520 -+}
21521 -+
21522 -+__u32
21523 -+gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
21524 -+ mode_t mode)
21525 -+{
21526 -+ if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
21527 -+ return 1;
21528 -+
21529 -+ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
21530 -+ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
21531 -+ GR_FCHMOD_ACL_MSG);
21532 -+ } else {
21533 -+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
21534 -+ }
21535 -+}
21536 -+
21537 -+__u32
21538 -+gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
21539 -+ mode_t mode)
21540 -+{
21541 -+ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
21542 -+ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
21543 -+ GR_CHMOD_ACL_MSG);
21544 -+ } else {
21545 -+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
21546 -+ }
21547 -+}
21548 -+
21549 -+__u32
21550 -+gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
21551 -+{
21552 -+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
21553 -+}
21554 -+
21555 -+__u32
21556 -+gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
21557 -+{
21558 -+ return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
21559 -+}
21560 -+
21561 -+__u32
21562 -+gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
21563 -+{
21564 -+ return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
21565 -+ GR_UNIXCONNECT_ACL_MSG);
21566 -+}
21567 -+
21568 -+/* hardlinks require at minimum create permission,
21569 -+ any additional privilege required is based on the
21570 -+ privilege of the file being linked to
21571 -+*/
21572 -+__u32
21573 -+gr_acl_handle_link(const struct dentry * new_dentry,
21574 -+ const struct dentry * parent_dentry,
21575 -+ const struct vfsmount * parent_mnt,
21576 -+ const struct dentry * old_dentry,
21577 -+ const struct vfsmount * old_mnt, const char *to)
21578 -+{
21579 -+ __u32 mode;
21580 -+ __u32 needmode = GR_CREATE | GR_LINK;
21581 -+ __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
21582 -+
21583 -+ mode =
21584 -+ gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
21585 -+ old_mnt);
21586 -+
21587 -+ if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
21588 -+ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
21589 -+ return mode;
21590 -+ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
21591 -+ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
21592 -+ return 0;
21593 -+ } else if (unlikely((mode & needmode) != needmode))
21594 -+ return 0;
21595 -+
21596 -+ return 1;
21597 -+}
21598 -+
21599 -+__u32
21600 -+gr_acl_handle_symlink(const struct dentry * new_dentry,
21601 -+ const struct dentry * parent_dentry,
21602 -+ const struct vfsmount * parent_mnt, const char *from)
21603 -+{
21604 -+ __u32 needmode = GR_WRITE | GR_CREATE;
21605 -+ __u32 mode;
21606 -+
21607 -+ mode =
21608 -+ gr_check_create(new_dentry, parent_dentry, parent_mnt,
21609 -+ GR_CREATE | GR_AUDIT_CREATE |
21610 -+ GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
21611 -+
21612 -+ if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
21613 -+ gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
21614 -+ return mode;
21615 -+ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
21616 -+ gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
21617 -+ return 0;
21618 -+ } else if (unlikely((mode & needmode) != needmode))
21619 -+ return 0;
21620 -+
21621 -+ return (GR_WRITE | GR_CREATE);
21622 -+}
21623 -+
21624 -+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)
21625 -+{
21626 -+ __u32 mode;
21627 -+
21628 -+ mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
21629 -+
21630 -+ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
21631 -+ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
21632 -+ return mode;
21633 -+ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
21634 -+ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
21635 -+ return 0;
21636 -+ } else if (unlikely((mode & (reqmode)) != (reqmode)))
21637 -+ return 0;
21638 -+
21639 -+ return (reqmode);
21640 -+}
21641 -+
21642 -+__u32
21643 -+gr_acl_handle_mknod(const struct dentry * new_dentry,
21644 -+ const struct dentry * parent_dentry,
21645 -+ const struct vfsmount * parent_mnt,
21646 -+ const int mode)
21647 -+{
21648 -+ __u32 reqmode = GR_WRITE | GR_CREATE;
21649 -+ if (unlikely(mode & (S_ISUID | S_ISGID)))
21650 -+ reqmode |= GR_SETID;
21651 -+
21652 -+ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
21653 -+ reqmode, GR_MKNOD_ACL_MSG);
21654 -+}
21655 -+
21656 -+__u32
21657 -+gr_acl_handle_mkdir(const struct dentry *new_dentry,
21658 -+ const struct dentry *parent_dentry,
21659 -+ const struct vfsmount *parent_mnt)
21660 -+{
21661 -+ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
21662 -+ GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
21663 -+}
21664 -+
21665 -+#define RENAME_CHECK_SUCCESS(old, new) \
21666 -+ (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
21667 -+ ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
21668 -+
21669 -+int
21670 -+gr_acl_handle_rename(struct dentry *new_dentry,
21671 -+ struct dentry *parent_dentry,
21672 -+ const struct vfsmount *parent_mnt,
21673 -+ struct dentry *old_dentry,
21674 -+ struct inode *old_parent_inode,
21675 -+ struct vfsmount *old_mnt, const char *newname)
21676 -+{
21677 -+ __u32 comp1, comp2;
21678 -+ int error = 0;
21679 -+
21680 -+ if (unlikely(!gr_acl_is_enabled()))
21681 -+ return 0;
21682 -+
21683 -+ if (!new_dentry->d_inode) {
21684 -+ comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
21685 -+ GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
21686 -+ GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
21687 -+ comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
21688 -+ GR_DELETE | GR_AUDIT_DELETE |
21689 -+ GR_AUDIT_READ | GR_AUDIT_WRITE |
21690 -+ GR_SUPPRESS, old_mnt);
21691 -+ } else {
21692 -+ comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
21693 -+ GR_CREATE | GR_DELETE |
21694 -+ GR_AUDIT_CREATE | GR_AUDIT_DELETE |
21695 -+ GR_AUDIT_READ | GR_AUDIT_WRITE |
21696 -+ GR_SUPPRESS, parent_mnt);
21697 -+ comp2 =
21698 -+ gr_search_file(old_dentry,
21699 -+ GR_READ | GR_WRITE | GR_AUDIT_READ |
21700 -+ GR_DELETE | GR_AUDIT_DELETE |
21701 -+ GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
21702 -+ }
21703 -+
21704 -+ if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
21705 -+ ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
21706 -+ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
21707 -+ else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
21708 -+ && !(comp2 & GR_SUPPRESS)) {
21709 -+ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
21710 -+ error = -EACCES;
21711 -+ } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
21712 -+ error = -EACCES;
21713 -+
21714 -+ return error;
21715 -+}
21716 -+
21717 -+void
21718 -+gr_acl_handle_exit(void)
21719 -+{
21720 -+ u16 id;
21721 -+ char *rolename;
21722 -+ struct file *exec_file;
21723 -+
21724 -+ if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
21725 -+ id = current->acl_role_id;
21726 -+ rolename = current->role->rolename;
21727 -+ gr_set_acls(1);
21728 -+ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
21729 -+ }
21730 -+
21731 -+ write_lock(&grsec_exec_file_lock);
21732 -+ exec_file = current->exec_file;
21733 -+ current->exec_file = NULL;
21734 -+ write_unlock(&grsec_exec_file_lock);
21735 -+
21736 -+ if (exec_file)
21737 -+ fput(exec_file);
21738 -+}
21739 -+
21740 -+int
21741 -+gr_acl_handle_procpidmem(const struct task_struct *task)
21742 -+{
21743 -+ if (unlikely(!gr_acl_is_enabled()))
21744 -+ return 0;
21745 -+
21746 -+ if (task != current && task->acl->mode & GR_PROTPROCFD)
21747 -+ return -EACCES;
21748 -+
21749 -+ return 0;
21750 -+}
21751 -diff -urNp linux-2.6.27.6/grsecurity/gracl_ip.c linux-2.6.27.6/grsecurity/gracl_ip.c
21752 ---- linux-2.6.27.6/grsecurity/gracl_ip.c 1969-12-31 19:00:00.000000000 -0500
21753 -+++ linux-2.6.27.6/grsecurity/gracl_ip.c 2008-11-18 03:38:45.000000000 -0500
21754 -@@ -0,0 +1,313 @@
21755 -+#include <linux/kernel.h>
21756 -+#include <asm/uaccess.h>
21757 -+#include <asm/errno.h>
21758 -+#include <net/sock.h>
21759 -+#include <linux/file.h>
21760 -+#include <linux/fs.h>
21761 -+#include <linux/net.h>
21762 -+#include <linux/in.h>
21763 -+#include <linux/skbuff.h>
21764 -+#include <linux/ip.h>
21765 -+#include <linux/udp.h>
21766 -+#include <linux/smp_lock.h>
21767 -+#include <linux/types.h>
21768 -+#include <linux/sched.h>
21769 -+#include <linux/netdevice.h>
21770 -+#include <linux/inetdevice.h>
21771 -+#include <linux/gracl.h>
21772 -+#include <linux/grsecurity.h>
21773 -+#include <linux/grinternal.h>
21774 -+
21775 -+#define GR_BIND 0x01
21776 -+#define GR_CONNECT 0x02
21777 -+#define GR_INVERT 0x04
21778 -+
21779 -+static const char * gr_protocols[256] = {
21780 -+ "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
21781 -+ "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
21782 -+ "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
21783 -+ "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
21784 -+ "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
21785 -+ "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
21786 -+ "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
21787 -+ "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
21788 -+ "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
21789 -+ "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
21790 -+ "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
21791 -+ "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
21792 -+ "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
21793 -+ "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
21794 -+ "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
21795 -+ "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
21796 -+ "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
21797 -+ "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
21798 -+ "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
21799 -+ "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
21800 -+ "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
21801 -+ "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
21802 -+ "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
21803 -+ "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
21804 -+ "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
21805 -+ "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
21806 -+ "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
21807 -+ "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
21808 -+ "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
21809 -+ "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
21810 -+ "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
21811 -+ "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
21812 -+ };
21813 -+
21814 -+static const char * gr_socktypes[11] = {
21815 -+ "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
21816 -+ "unknown:7", "unknown:8", "unknown:9", "packet"
21817 -+ };
21818 -+
21819 -+const char *
21820 -+gr_proto_to_name(unsigned char proto)
21821 -+{
21822 -+ return gr_protocols[proto];
21823 -+}
21824 -+
21825 -+const char *
21826 -+gr_socktype_to_name(unsigned char type)
21827 -+{
21828 -+ return gr_socktypes[type];
21829 -+}
21830 -+
21831 -+int
21832 -+gr_search_socket(const int domain, const int type, const int protocol)
21833 -+{
21834 -+ struct acl_subject_label *curr;
21835 -+
21836 -+ if (unlikely(!gr_acl_is_enabled()))
21837 -+ goto exit;
21838 -+
21839 -+ if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
21840 -+ || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
21841 -+ goto exit; // let the kernel handle it
21842 -+
21843 -+ curr = current->acl;
21844 -+
21845 -+ if (!curr->ips)
21846 -+ goto exit;
21847 -+
21848 -+ if ((curr->ip_type & (1 << type)) &&
21849 -+ (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
21850 -+ goto exit;
21851 -+
21852 -+ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
21853 -+ /* we don't place acls on raw sockets , and sometimes
21854 -+ dgram/ip sockets are opened for ioctl and not
21855 -+ bind/connect, so we'll fake a bind learn log */
21856 -+ if (type == SOCK_RAW || type == SOCK_PACKET) {
21857 -+ __u32 fakeip = 0;
21858 -+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
21859 -+ current->role->roletype, current->uid,
21860 -+ current->gid, current->exec_file ?
21861 -+ gr_to_filename(current->exec_file->f_path.dentry,
21862 -+ current->exec_file->f_path.mnt) :
21863 -+ curr->filename, curr->filename,
21864 -+ NIPQUAD(fakeip), 0, type,
21865 -+ protocol, GR_CONNECT,
21866 -+NIPQUAD(current->signal->curr_ip));
21867 -+ } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
21868 -+ __u32 fakeip = 0;
21869 -+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
21870 -+ current->role->roletype, current->uid,
21871 -+ current->gid, current->exec_file ?
21872 -+ gr_to_filename(current->exec_file->f_path.dentry,
21873 -+ current->exec_file->f_path.mnt) :
21874 -+ curr->filename, curr->filename,
21875 -+ NIPQUAD(fakeip), 0, type,
21876 -+ protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
21877 -+ }
21878 -+ /* we'll log when they use connect or bind */
21879 -+ goto exit;
21880 -+ }
21881 -+
21882 -+ gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet",
21883 -+ gr_socktype_to_name(type), gr_proto_to_name(protocol));
21884 -+
21885 -+ return 0;
21886 -+ exit:
21887 -+ return 1;
21888 -+}
21889 -+
21890 -+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)
21891 -+{
21892 -+ if ((ip->mode & mode) &&
21893 -+ (ip_port >= ip->low) &&
21894 -+ (ip_port <= ip->high) &&
21895 -+ ((ntohl(ip_addr) & our_netmask) ==
21896 -+ (ntohl(our_addr) & our_netmask))
21897 -+ && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
21898 -+ && (ip->type & (1 << type))) {
21899 -+ if (ip->mode & GR_INVERT)
21900 -+ return 2; // specifically denied
21901 -+ else
21902 -+ return 1; // allowed
21903 -+ }
21904 -+
21905 -+ return 0; // not specifically allowed, may continue parsing
21906 -+}
21907 -+
21908 -+static int
21909 -+gr_search_connectbind(const int mode, const struct sock *sk,
21910 -+ const struct sockaddr_in *addr, const int type)
21911 -+{
21912 -+ char iface[IFNAMSIZ] = {0};
21913 -+ struct acl_subject_label *curr;
21914 -+ struct acl_ip_label *ip;
21915 -+ struct net_device *dev;
21916 -+ struct in_device *idev;
21917 -+ unsigned long i;
21918 -+ int ret;
21919 -+ __u32 ip_addr = 0;
21920 -+ __u32 our_addr;
21921 -+ __u32 our_netmask;
21922 -+ char *p;
21923 -+ __u16 ip_port = 0;
21924 -+
21925 -+ if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
21926 -+ return 1;
21927 -+
21928 -+ curr = current->acl;
21929 -+
21930 -+ if (!curr->ips)
21931 -+ return 1;
21932 -+
21933 -+ ip_addr = addr->sin_addr.s_addr;
21934 -+ ip_port = ntohs(addr->sin_port);
21935 -+
21936 -+ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
21937 -+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
21938 -+ current->role->roletype, current->uid,
21939 -+ current->gid, current->exec_file ?
21940 -+ gr_to_filename(current->exec_file->f_path.dentry,
21941 -+ current->exec_file->f_path.mnt) :
21942 -+ curr->filename, curr->filename,
21943 -+ NIPQUAD(ip_addr), ip_port, type,
21944 -+ sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
21945 -+ return 1;
21946 -+ }
21947 -+
21948 -+ for (i = 0; i < curr->ip_num; i++) {
21949 -+ ip = *(curr->ips + i);
21950 -+ if (ip->iface != NULL) {
21951 -+ strncpy(iface, ip->iface, IFNAMSIZ - 1);
21952 -+ p = strchr(iface, ':');
21953 -+ if (p != NULL)
21954 -+ *p = '\0';
21955 -+ dev = dev_get_by_name(sock_net(sk), iface);
21956 -+ if (dev == NULL)
21957 -+ continue;
21958 -+ idev = in_dev_get(dev);
21959 -+ if (idev == NULL) {
21960 -+ dev_put(dev);
21961 -+ continue;
21962 -+ }
21963 -+ rcu_read_lock();
21964 -+ for_ifa(idev) {
21965 -+ if (!strcmp(ip->iface, ifa->ifa_label)) {
21966 -+ our_addr = ifa->ifa_address;
21967 -+ our_netmask = 0xffffffff;
21968 -+ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
21969 -+ if (ret == 1) {
21970 -+ rcu_read_unlock();
21971 -+ in_dev_put(idev);
21972 -+ dev_put(dev);
21973 -+ return 1;
21974 -+ } else if (ret == 2) {
21975 -+ rcu_read_unlock();
21976 -+ in_dev_put(idev);
21977 -+ dev_put(dev);
21978 -+ goto denied;
21979 -+ }
21980 -+ }
21981 -+ } endfor_ifa(idev);
21982 -+ rcu_read_unlock();
21983 -+ in_dev_put(idev);
21984 -+ dev_put(dev);
21985 -+ } else {
21986 -+ our_addr = ip->addr;
21987 -+ our_netmask = ip->netmask;
21988 -+ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
21989 -+ if (ret == 1)
21990 -+ return 1;
21991 -+ else if (ret == 2)
21992 -+ goto denied;
21993 -+ }
21994 -+ }
21995 -+
21996 -+denied:
21997 -+ if (mode == GR_BIND)
21998 -+ 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));
21999 -+ else if (mode == GR_CONNECT)
22000 -+ 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));
22001 -+
22002 -+ return 0;
22003 -+}
22004 -+
22005 -+int
22006 -+gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
22007 -+{
22008 -+ return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
22009 -+}
22010 -+
22011 -+int
22012 -+gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
22013 -+{
22014 -+ return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
22015 -+}
22016 -+
22017 -+int gr_search_listen(const struct socket *sock)
22018 -+{
22019 -+ struct sock *sk = sock->sk;
22020 -+ struct sockaddr_in addr;
22021 -+
22022 -+ addr.sin_addr.s_addr = inet_sk(sk)->saddr;
22023 -+ addr.sin_port = inet_sk(sk)->sport;
22024 -+
22025 -+ return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
22026 -+}
22027 -+
22028 -+int gr_search_accept(const struct socket *sock)
22029 -+{
22030 -+ struct sock *sk = sock->sk;
22031 -+ struct sockaddr_in addr;
22032 -+
22033 -+ addr.sin_addr.s_addr = inet_sk(sk)->saddr;
22034 -+ addr.sin_port = inet_sk(sk)->sport;
22035 -+
22036 -+ return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
22037 -+}
22038 -+
22039 -+int
22040 -+gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
22041 -+{
22042 -+ if (addr)
22043 -+ return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
22044 -+ else {
22045 -+ struct sockaddr_in sin;
22046 -+ const struct inet_sock *inet = inet_sk(sk);
22047 -+
22048 -+ sin.sin_addr.s_addr = inet->daddr;
22049 -+ sin.sin_port = inet->dport;
22050 -+
22051 -+ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
22052 -+ }
22053 -+}
22054 -+
22055 -+int
22056 -+gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
22057 -+{
22058 -+ struct sockaddr_in sin;
22059 -+
22060 -+ if (unlikely(skb->len < sizeof (struct udphdr)))
22061 -+ return 1; // skip this packet
22062 -+
22063 -+ sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
22064 -+ sin.sin_port = udp_hdr(skb)->source;
22065 -+
22066 -+ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
22067 -+}
22068 -diff -urNp linux-2.6.27.6/grsecurity/gracl_learn.c linux-2.6.27.6/grsecurity/gracl_learn.c
22069 ---- linux-2.6.27.6/grsecurity/gracl_learn.c 1969-12-31 19:00:00.000000000 -0500
22070 -+++ linux-2.6.27.6/grsecurity/gracl_learn.c 2008-11-18 03:38:45.000000000 -0500
22071 -@@ -0,0 +1,211 @@
22072 -+#include <linux/kernel.h>
22073 -+#include <linux/mm.h>
22074 -+#include <linux/sched.h>
22075 -+#include <linux/poll.h>
22076 -+#include <linux/smp_lock.h>
22077 -+#include <linux/string.h>
22078 -+#include <linux/file.h>
22079 -+#include <linux/types.h>
22080 -+#include <linux/vmalloc.h>
22081 -+#include <linux/grinternal.h>
22082 -+
22083 -+extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
22084 -+ size_t count, loff_t *ppos);
22085 -+extern int gr_acl_is_enabled(void);
22086 -+
22087 -+static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
22088 -+static int gr_learn_attached;
22089 -+
22090 -+/* use a 512k buffer */
22091 -+#define LEARN_BUFFER_SIZE (512 * 1024)
22092 -+
22093 -+static DEFINE_SPINLOCK(gr_learn_lock);
22094 -+static DECLARE_MUTEX(gr_learn_user_sem);
22095 -+
22096 -+/* we need to maintain two buffers, so that the kernel context of grlearn
22097 -+ uses a semaphore around the userspace copying, and the other kernel contexts
22098 -+ use a spinlock when copying into the buffer, since they cannot sleep
22099 -+*/
22100 -+static char *learn_buffer;
22101 -+static char *learn_buffer_user;
22102 -+static int learn_buffer_len;
22103 -+static int learn_buffer_user_len;
22104 -+
22105 -+static ssize_t
22106 -+read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
22107 -+{
22108 -+ DECLARE_WAITQUEUE(wait, current);
22109 -+ ssize_t retval = 0;
22110 -+
22111 -+ add_wait_queue(&learn_wait, &wait);
22112 -+ set_current_state(TASK_INTERRUPTIBLE);
22113 -+ do {
22114 -+ down(&gr_learn_user_sem);
22115 -+ spin_lock(&gr_learn_lock);
22116 -+ if (learn_buffer_len)
22117 -+ break;
22118 -+ spin_unlock(&gr_learn_lock);
22119 -+ up(&gr_learn_user_sem);
22120 -+ if (file->f_flags & O_NONBLOCK) {
22121 -+ retval = -EAGAIN;
22122 -+ goto out;
22123 -+ }
22124 -+ if (signal_pending(current)) {
22125 -+ retval = -ERESTARTSYS;
22126 -+ goto out;
22127 -+ }
22128 -+
22129 -+ schedule();
22130 -+ } while (1);
22131 -+
22132 -+ memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
22133 -+ learn_buffer_user_len = learn_buffer_len;
22134 -+ retval = learn_buffer_len;
22135 -+ learn_buffer_len = 0;
22136 -+
22137 -+ spin_unlock(&gr_learn_lock);
22138 -+
22139 -+ if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
22140 -+ retval = -EFAULT;
22141 -+
22142 -+ up(&gr_learn_user_sem);
22143 -+out:
22144 -+ set_current_state(TASK_RUNNING);
22145 -+ remove_wait_queue(&learn_wait, &wait);
22146 -+ return retval;
22147 -+}
22148 -+
22149 -+static unsigned int
22150 -+poll_learn(struct file * file, poll_table * wait)
22151 -+{
22152 -+ poll_wait(file, &learn_wait, wait);
22153 -+
22154 -+ if (learn_buffer_len)
22155 -+ return (POLLIN | POLLRDNORM);
22156 -+
22157 -+ return 0;
22158 -+}
22159 -+
22160 -+void
22161 -+gr_clear_learn_entries(void)
22162 -+{
22163 -+ char *tmp;
22164 -+
22165 -+ down(&gr_learn_user_sem);
22166 -+ if (learn_buffer != NULL) {
22167 -+ spin_lock(&gr_learn_lock);
22168 -+ tmp = learn_buffer;
22169 -+ learn_buffer = NULL;
22170 -+ spin_unlock(&gr_learn_lock);
22171 -+ vfree(learn_buffer);
22172 -+ }
22173 -+ if (learn_buffer_user != NULL) {
22174 -+ vfree(learn_buffer_user);
22175 -+ learn_buffer_user = NULL;
22176 -+ }
22177 -+ learn_buffer_len = 0;
22178 -+ up(&gr_learn_user_sem);
22179 -+
22180 -+ return;
22181 -+}
22182 -+
22183 -+void
22184 -+gr_add_learn_entry(const char *fmt, ...)
22185 -+{
22186 -+ va_list args;
22187 -+ unsigned int len;
22188 -+
22189 -+ if (!gr_learn_attached)
22190 -+ return;
22191 -+
22192 -+ spin_lock(&gr_learn_lock);
22193 -+
22194 -+ /* leave a gap at the end so we know when it's "full" but don't have to
22195 -+ compute the exact length of the string we're trying to append
22196 -+ */
22197 -+ if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
22198 -+ spin_unlock(&gr_learn_lock);
22199 -+ wake_up_interruptible(&learn_wait);
22200 -+ return;
22201 -+ }
22202 -+ if (learn_buffer == NULL) {
22203 -+ spin_unlock(&gr_learn_lock);
22204 -+ return;
22205 -+ }
22206 -+
22207 -+ va_start(args, fmt);
22208 -+ len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
22209 -+ va_end(args);
22210 -+
22211 -+ learn_buffer_len += len + 1;
22212 -+
22213 -+ spin_unlock(&gr_learn_lock);
22214 -+ wake_up_interruptible(&learn_wait);
22215 -+
22216 -+ return;
22217 -+}
22218 -+
22219 -+static int
22220 -+open_learn(struct inode *inode, struct file *file)
22221 -+{
22222 -+ if (file->f_mode & FMODE_READ && gr_learn_attached)
22223 -+ return -EBUSY;
22224 -+ if (file->f_mode & FMODE_READ) {
22225 -+ int retval = 0;
22226 -+ down(&gr_learn_user_sem);
22227 -+ if (learn_buffer == NULL)
22228 -+ learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
22229 -+ if (learn_buffer_user == NULL)
22230 -+ learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
22231 -+ if (learn_buffer == NULL) {
22232 -+ retval = -ENOMEM;
22233 -+ goto out_error;
22234 -+ }
22235 -+ if (learn_buffer_user == NULL) {
22236 -+ retval = -ENOMEM;
22237 -+ goto out_error;
22238 -+ }
22239 -+ learn_buffer_len = 0;
22240 -+ learn_buffer_user_len = 0;
22241 -+ gr_learn_attached = 1;
22242 -+out_error:
22243 -+ up(&gr_learn_user_sem);
22244 -+ return retval;
22245 -+ }
22246 -+ return 0;
22247 -+}
22248 -+
22249 -+static int
22250 -+close_learn(struct inode *inode, struct file *file)
22251 -+{
22252 -+ char *tmp;
22253 -+
22254 -+ if (file->f_mode & FMODE_READ) {
22255 -+ down(&gr_learn_user_sem);
22256 -+ if (learn_buffer != NULL) {
22257 -+ spin_lock(&gr_learn_lock);
22258 -+ tmp = learn_buffer;
22259 -+ learn_buffer = NULL;
22260 -+ spin_unlock(&gr_learn_lock);
22261 -+ vfree(tmp);
22262 -+ }
22263 -+ if (learn_buffer_user != NULL) {
22264 -+ vfree(learn_buffer_user);
22265 -+ learn_buffer_user = NULL;
22266 -+ }
22267 -+ learn_buffer_len = 0;
22268 -+ learn_buffer_user_len = 0;
22269 -+ gr_learn_attached = 0;
22270 -+ up(&gr_learn_user_sem);
22271 -+ }
22272 -+
22273 -+ return 0;
22274 -+}
22275 -+
22276 -+struct file_operations grsec_fops = {
22277 -+ .read = read_learn,
22278 -+ .write = write_grsec_handler,
22279 -+ .open = open_learn,
22280 -+ .release = close_learn,
22281 -+ .poll = poll_learn,
22282 -+};
22283 -diff -urNp linux-2.6.27.6/grsecurity/gracl_res.c linux-2.6.27.6/grsecurity/gracl_res.c
22284 ---- linux-2.6.27.6/grsecurity/gracl_res.c 1969-12-31 19:00:00.000000000 -0500
22285 -+++ linux-2.6.27.6/grsecurity/gracl_res.c 2008-11-18 03:38:45.000000000 -0500
22286 -@@ -0,0 +1,45 @@
22287 -+#include <linux/kernel.h>
22288 -+#include <linux/sched.h>
22289 -+#include <linux/gracl.h>
22290 -+#include <linux/grinternal.h>
22291 -+
22292 -+static const char *restab_log[] = {
22293 -+ [RLIMIT_CPU] = "RLIMIT_CPU",
22294 -+ [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
22295 -+ [RLIMIT_DATA] = "RLIMIT_DATA",
22296 -+ [RLIMIT_STACK] = "RLIMIT_STACK",
22297 -+ [RLIMIT_CORE] = "RLIMIT_CORE",
22298 -+ [RLIMIT_RSS] = "RLIMIT_RSS",
22299 -+ [RLIMIT_NPROC] = "RLIMIT_NPROC",
22300 -+ [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
22301 -+ [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
22302 -+ [RLIMIT_AS] = "RLIMIT_AS",
22303 -+ [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
22304 -+ [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH"
22305 -+};
22306 -+
22307 -+void
22308 -+gr_log_resource(const struct task_struct *task,
22309 -+ const int res, const unsigned long wanted, const int gt)
22310 -+{
22311 -+ if (res == RLIMIT_NPROC &&
22312 -+ (cap_raised(task->cap_effective, CAP_SYS_ADMIN) ||
22313 -+ cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
22314 -+ return;
22315 -+ else if (res == RLIMIT_MEMLOCK &&
22316 -+ cap_raised(task->cap_effective, CAP_IPC_LOCK))
22317 -+ return;
22318 -+
22319 -+ if (!gr_acl_is_enabled() && !grsec_resource_logging)
22320 -+ return;
22321 -+
22322 -+ preempt_disable();
22323 -+
22324 -+ if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
22325 -+ (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
22326 -+ task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
22327 -+ gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
22328 -+ preempt_enable_no_resched();
22329 -+
22330 -+ return;
22331 -+}
22332 -diff -urNp linux-2.6.27.6/grsecurity/gracl_segv.c linux-2.6.27.6/grsecurity/gracl_segv.c
22333 ---- linux-2.6.27.6/grsecurity/gracl_segv.c 1969-12-31 19:00:00.000000000 -0500
22334 -+++ linux-2.6.27.6/grsecurity/gracl_segv.c 2008-11-18 03:38:45.000000000 -0500
22335 -@@ -0,0 +1,304 @@
22336 -+#include <linux/kernel.h>
22337 -+#include <linux/mm.h>
22338 -+#include <asm/uaccess.h>
22339 -+#include <asm/errno.h>
22340 -+#include <asm/mman.h>
22341 -+#include <net/sock.h>
22342 -+#include <linux/file.h>
22343 -+#include <linux/fs.h>
22344 -+#include <linux/net.h>
22345 -+#include <linux/in.h>
22346 -+#include <linux/smp_lock.h>
22347 -+#include <linux/slab.h>
22348 -+#include <linux/types.h>
22349 -+#include <linux/sched.h>
22350 -+#include <linux/timer.h>
22351 -+#include <linux/gracl.h>
22352 -+#include <linux/grsecurity.h>
22353 -+#include <linux/grinternal.h>
22354 -+
22355 -+static struct crash_uid *uid_set;
22356 -+static unsigned short uid_used;
22357 -+static DEFINE_SPINLOCK(gr_uid_lock);
22358 -+extern rwlock_t gr_inode_lock;
22359 -+extern struct acl_subject_label *
22360 -+ lookup_acl_subj_label(const ino_t inode, const dev_t dev,
22361 -+ struct acl_role_label *role);
22362 -+extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
22363 -+
22364 -+int
22365 -+gr_init_uidset(void)
22366 -+{
22367 -+ uid_set =
22368 -+ kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
22369 -+ uid_used = 0;
22370 -+
22371 -+ return uid_set ? 1 : 0;
22372 -+}
22373 -+
22374 -+void
22375 -+gr_free_uidset(void)
22376 -+{
22377 -+ if (uid_set)
22378 -+ kfree(uid_set);
22379 -+
22380 -+ return;
22381 -+}
22382 -+
22383 -+int
22384 -+gr_find_uid(const uid_t uid)
22385 -+{
22386 -+ struct crash_uid *tmp = uid_set;
22387 -+ uid_t buid;
22388 -+ int low = 0, high = uid_used - 1, mid;
22389 -+
22390 -+ while (high >= low) {
22391 -+ mid = (low + high) >> 1;
22392 -+ buid = tmp[mid].uid;
22393 -+ if (buid == uid)
22394 -+ return mid;
22395 -+ if (buid > uid)
22396 -+ high = mid - 1;
22397 -+ if (buid < uid)
22398 -+ low = mid + 1;
22399 -+ }
22400 -+
22401 -+ return -1;
22402 -+}
22403 -+
22404 -+static __inline__ void
22405 -+gr_insertsort(void)
22406 -+{
22407 -+ unsigned short i, j;
22408 -+ struct crash_uid index;
22409 -+
22410 -+ for (i = 1; i < uid_used; i++) {
22411 -+ index = uid_set[i];
22412 -+ j = i;
22413 -+ while ((j > 0) && uid_set[j - 1].uid > index.uid) {
22414 -+ uid_set[j] = uid_set[j - 1];
22415 -+ j--;
22416 -+ }
22417 -+ uid_set[j] = index;
22418 -+ }
22419 -+
22420 -+ return;
22421 -+}
22422 -+
22423 -+static __inline__ void
22424 -+gr_insert_uid(const uid_t uid, const unsigned long expires)
22425 -+{
22426 -+ int loc;
22427 -+
22428 -+ if (uid_used == GR_UIDTABLE_MAX)
22429 -+ return;
22430 -+
22431 -+ loc = gr_find_uid(uid);
22432 -+
22433 -+ if (loc >= 0) {
22434 -+ uid_set[loc].expires = expires;
22435 -+ return;
22436 -+ }
22437 -+
22438 -+ uid_set[uid_used].uid = uid;
22439 -+ uid_set[uid_used].expires = expires;
22440 -+ uid_used++;
22441 -+
22442 -+ gr_insertsort();
22443 -+
22444 -+ return;
22445 -+}
22446 -+
22447 -+void
22448 -+gr_remove_uid(const unsigned short loc)
22449 -+{
22450 -+ unsigned short i;
22451 -+
22452 -+ for (i = loc + 1; i < uid_used; i++)
22453 -+ uid_set[i - 1] = uid_set[i];
22454 -+
22455 -+ uid_used--;
22456 -+
22457 -+ return;
22458 -+}
22459 -+
22460 -+int
22461 -+gr_check_crash_uid(const uid_t uid)
22462 -+{
22463 -+ int loc;
22464 -+ int ret = 0;
22465 -+
22466 -+ if (unlikely(!gr_acl_is_enabled()))
22467 -+ return 0;
22468 -+
22469 -+ spin_lock(&gr_uid_lock);
22470 -+ loc = gr_find_uid(uid);
22471 -+
22472 -+ if (loc < 0)
22473 -+ goto out_unlock;
22474 -+
22475 -+ if (time_before_eq(uid_set[loc].expires, get_seconds()))
22476 -+ gr_remove_uid(loc);
22477 -+ else
22478 -+ ret = 1;
22479 -+
22480 -+out_unlock:
22481 -+ spin_unlock(&gr_uid_lock);
22482 -+ return ret;
22483 -+}
22484 -+
22485 -+static __inline__ int
22486 -+proc_is_setxid(const struct task_struct *task)
22487 -+{
22488 -+ if (task->uid != task->euid || task->uid != task->suid ||
22489 -+ task->uid != task->fsuid)
22490 -+ return 1;
22491 -+ if (task->gid != task->egid || task->gid != task->sgid ||
22492 -+ task->gid != task->fsgid)
22493 -+ return 1;
22494 -+
22495 -+ return 0;
22496 -+}
22497 -+static __inline__ int
22498 -+gr_fake_force_sig(int sig, struct task_struct *t)
22499 -+{
22500 -+ unsigned long int flags;
22501 -+ int ret, blocked, ignored;
22502 -+ struct k_sigaction *action;
22503 -+
22504 -+ spin_lock_irqsave(&t->sighand->siglock, flags);
22505 -+ action = &t->sighand->action[sig-1];
22506 -+ ignored = action->sa.sa_handler == SIG_IGN;
22507 -+ blocked = sigismember(&t->blocked, sig);
22508 -+ if (blocked || ignored) {
22509 -+ action->sa.sa_handler = SIG_DFL;
22510 -+ if (blocked) {
22511 -+ sigdelset(&t->blocked, sig);
22512 -+ recalc_sigpending_and_wake(t);
22513 -+ }
22514 -+ }
22515 -+ if (action->sa.sa_handler == SIG_DFL)
22516 -+ t->signal->flags &= ~SIGNAL_UNKILLABLE;
22517 -+ ret = specific_send_sig_info(sig, SEND_SIG_PRIV, t);
22518 -+
22519 -+ spin_unlock_irqrestore(&t->sighand->siglock, flags);
22520 -+
22521 -+ return ret;
22522 -+}
22523 -+
22524 -+void
22525 -+gr_handle_crash(struct task_struct *task, const int sig)
22526 -+{
22527 -+ struct acl_subject_label *curr;
22528 -+ struct acl_subject_label *curr2;
22529 -+ struct task_struct *tsk, *tsk2;
22530 -+
22531 -+ if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
22532 -+ return;
22533 -+
22534 -+ if (unlikely(!gr_acl_is_enabled()))
22535 -+ return;
22536 -+
22537 -+ curr = task->acl;
22538 -+
22539 -+ if (!(curr->resmask & (1 << GR_CRASH_RES)))
22540 -+ return;
22541 -+
22542 -+ if (time_before_eq(curr->expires, get_seconds())) {
22543 -+ curr->expires = 0;
22544 -+ curr->crashes = 0;
22545 -+ }
22546 -+
22547 -+ curr->crashes++;
22548 -+
22549 -+ if (!curr->expires)
22550 -+ curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
22551 -+
22552 -+ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
22553 -+ time_after(curr->expires, get_seconds())) {
22554 -+ if (task->uid && proc_is_setxid(task)) {
22555 -+ gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
22556 -+ spin_lock(&gr_uid_lock);
22557 -+ gr_insert_uid(task->uid, curr->expires);
22558 -+ spin_unlock(&gr_uid_lock);
22559 -+ curr->expires = 0;
22560 -+ curr->crashes = 0;
22561 -+ read_lock(&tasklist_lock);
22562 -+ do_each_thread(tsk2, tsk) {
22563 -+ if (tsk != task && tsk->uid == task->uid)
22564 -+ gr_fake_force_sig(SIGKILL, tsk);
22565 -+ } while_each_thread(tsk2, tsk);
22566 -+ read_unlock(&tasklist_lock);
22567 -+ } else {
22568 -+ gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
22569 -+ read_lock(&tasklist_lock);
22570 -+ do_each_thread(tsk2, tsk) {
22571 -+ if (likely(tsk != task)) {
22572 -+ curr2 = tsk->acl;
22573 -+
22574 -+ if (curr2->device == curr->device &&
22575 -+ curr2->inode == curr->inode)
22576 -+ gr_fake_force_sig(SIGKILL, tsk);
22577 -+ }
22578 -+ } while_each_thread(tsk2, tsk);
22579 -+ read_unlock(&tasklist_lock);
22580 -+ }
22581 -+ }
22582 -+
22583 -+ return;
22584 -+}
22585 -+
22586 -+int
22587 -+gr_check_crash_exec(const struct file *filp)
22588 -+{
22589 -+ struct acl_subject_label *curr;
22590 -+
22591 -+ if (unlikely(!gr_acl_is_enabled()))
22592 -+ return 0;
22593 -+
22594 -+ read_lock(&gr_inode_lock);
22595 -+ curr = lookup_acl_subj_label(filp->f_path.dentry->d_inode->i_ino,
22596 -+ filp->f_path.dentry->d_inode->i_sb->s_dev,
22597 -+ current->role);
22598 -+ read_unlock(&gr_inode_lock);
22599 -+
22600 -+ if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
22601 -+ (!curr->crashes && !curr->expires))
22602 -+ return 0;
22603 -+
22604 -+ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
22605 -+ time_after(curr->expires, get_seconds()))
22606 -+ return 1;
22607 -+ else if (time_before_eq(curr->expires, get_seconds())) {
22608 -+ curr->crashes = 0;
22609 -+ curr->expires = 0;
22610 -+ }
22611 -+
22612 -+ return 0;
22613 -+}
22614 -+
22615 -+void
22616 -+gr_handle_alertkill(struct task_struct *task)
22617 -+{
22618 -+ struct acl_subject_label *curracl;
22619 -+ __u32 curr_ip;
22620 -+ struct task_struct *p, *p2;
22621 -+
22622 -+ if (unlikely(!gr_acl_is_enabled()))
22623 -+ return;
22624 -+
22625 -+ curracl = task->acl;
22626 -+ curr_ip = task->signal->curr_ip;
22627 -+
22628 -+ if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
22629 -+ read_lock(&tasklist_lock);
22630 -+ do_each_thread(p2, p) {
22631 -+ if (p->signal->curr_ip == curr_ip)
22632 -+ gr_fake_force_sig(SIGKILL, p);
22633 -+ } while_each_thread(p2, p);
22634 -+ read_unlock(&tasklist_lock);
22635 -+ } else if (curracl->mode & GR_KILLPROC)
22636 -+ gr_fake_force_sig(SIGKILL, task);
22637 -+
22638 -+ return;
22639 -+}
22640 -diff -urNp linux-2.6.27.6/grsecurity/gracl_shm.c linux-2.6.27.6/grsecurity/gracl_shm.c
22641 ---- linux-2.6.27.6/grsecurity/gracl_shm.c 1969-12-31 19:00:00.000000000 -0500
22642 -+++ linux-2.6.27.6/grsecurity/gracl_shm.c 2008-11-18 03:38:45.000000000 -0500
22643 -@@ -0,0 +1,33 @@
22644 -+#include <linux/kernel.h>
22645 -+#include <linux/mm.h>
22646 -+#include <linux/sched.h>
22647 -+#include <linux/file.h>
22648 -+#include <linux/ipc.h>
22649 -+#include <linux/gracl.h>
22650 -+#include <linux/grsecurity.h>
22651 -+#include <linux/grinternal.h>
22652 -+
22653 -+int
22654 -+gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
22655 -+ const time_t shm_createtime, const uid_t cuid, const int shmid)
22656 -+{
22657 -+ struct task_struct *task;
22658 -+
22659 -+ if (!gr_acl_is_enabled())
22660 -+ return 1;
22661 -+
22662 -+ task = find_task_by_vpid(shm_cprid);
22663 -+
22664 -+ if (unlikely(!task))
22665 -+ task = find_task_by_vpid(shm_lapid);
22666 -+
22667 -+ if (unlikely(task && (time_before_eq((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
22668 -+ (task->pid == shm_lapid)) &&
22669 -+ (task->acl->mode & GR_PROTSHM) &&
22670 -+ (task->acl != current->acl))) {
22671 -+ gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
22672 -+ return 0;
22673 -+ }
22674 -+
22675 -+ return 1;
22676 -+}
22677 -diff -urNp linux-2.6.27.6/grsecurity/grsec_chdir.c linux-2.6.27.6/grsecurity/grsec_chdir.c
22678 ---- linux-2.6.27.6/grsecurity/grsec_chdir.c 1969-12-31 19:00:00.000000000 -0500
22679 -+++ linux-2.6.27.6/grsecurity/grsec_chdir.c 2008-11-18 03:38:45.000000000 -0500
22680 -@@ -0,0 +1,19 @@
22681 -+#include <linux/kernel.h>
22682 -+#include <linux/sched.h>
22683 -+#include <linux/fs.h>
22684 -+#include <linux/file.h>
22685 -+#include <linux/grsecurity.h>
22686 -+#include <linux/grinternal.h>
22687 -+
22688 -+void
22689 -+gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
22690 -+{
22691 -+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
22692 -+ if ((grsec_enable_chdir && grsec_enable_group &&
22693 -+ in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
22694 -+ !grsec_enable_group)) {
22695 -+ gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
22696 -+ }
22697 -+#endif
22698 -+ return;
22699 -+}
22700 -diff -urNp linux-2.6.27.6/grsecurity/grsec_chroot.c linux-2.6.27.6/grsecurity/grsec_chroot.c
22701 ---- linux-2.6.27.6/grsecurity/grsec_chroot.c 1969-12-31 19:00:00.000000000 -0500
22702 -+++ linux-2.6.27.6/grsecurity/grsec_chroot.c 2008-11-18 03:38:45.000000000 -0500
22703 -@@ -0,0 +1,336 @@
22704 -+#include <linux/kernel.h>
22705 -+#include <linux/module.h>
22706 -+#include <linux/sched.h>
22707 -+#include <linux/file.h>
22708 -+#include <linux/fs.h>
22709 -+#include <linux/mount.h>
22710 -+#include <linux/types.h>
22711 -+#include <linux/pid_namespace.h>
22712 -+#include <linux/grsecurity.h>
22713 -+#include <linux/grinternal.h>
22714 -+
22715 -+int
22716 -+gr_handle_chroot_unix(const pid_t pid)
22717 -+{
22718 -+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
22719 -+ struct pid *spid = NULL;
22720 -+
22721 -+ if (unlikely(!grsec_enable_chroot_unix))
22722 -+ return 1;
22723 -+
22724 -+ if (likely(!proc_is_chrooted(current)))
22725 -+ return 1;
22726 -+
22727 -+ read_lock(&tasklist_lock);
22728 -+
22729 -+ spid = find_vpid(pid);
22730 -+ if (spid) {
22731 -+ struct task_struct *p;
22732 -+ p = pid_task(spid, PIDTYPE_PID);
22733 -+ task_lock(p);
22734 -+ if (unlikely(!have_same_root(current, p))) {
22735 -+ task_unlock(p);
22736 -+ read_unlock(&tasklist_lock);
22737 -+ gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
22738 -+ return 0;
22739 -+ }
22740 -+ task_unlock(p);
22741 -+ }
22742 -+ read_unlock(&tasklist_lock);
22743 -+#endif
22744 -+ return 1;
22745 -+}
22746 -+
22747 -+int
22748 -+gr_handle_chroot_nice(void)
22749 -+{
22750 -+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
22751 -+ if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
22752 -+ gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
22753 -+ return -EPERM;
22754 -+ }
22755 -+#endif
22756 -+ return 0;
22757 -+}
22758 -+
22759 -+int
22760 -+gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
22761 -+{
22762 -+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
22763 -+ if (grsec_enable_chroot_nice && (niceval < task_nice(p))
22764 -+ && proc_is_chrooted(current)) {
22765 -+ gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
22766 -+ return -EACCES;
22767 -+ }
22768 -+#endif
22769 -+ return 0;
22770 -+}
22771 -+
22772 -+int
22773 -+gr_handle_chroot_rawio(const struct inode *inode)
22774 -+{
22775 -+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
22776 -+ if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
22777 -+ inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
22778 -+ return 1;
22779 -+#endif
22780 -+ return 0;
22781 -+}
22782 -+
22783 -+int
22784 -+gr_pid_is_chrooted(struct task_struct *p)
22785 -+{
22786 -+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
22787 -+ if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL)
22788 -+ return 0;
22789 -+
22790 -+ task_lock(p);
22791 -+ if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
22792 -+ !have_same_root(current, p)) {
22793 -+ task_unlock(p);
22794 -+ return 1;
22795 -+ }
22796 -+ task_unlock(p);
22797 -+#endif
22798 -+ return 0;
22799 -+}
22800 -+
22801 -+EXPORT_SYMBOL(gr_pid_is_chrooted);
22802 -+
22803 -+#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
22804 -+int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
22805 -+{
22806 -+ struct dentry *dentry = (struct dentry *)u_dentry;
22807 -+ struct vfsmount *mnt = (struct vfsmount *)u_mnt;
22808 -+ struct dentry *realroot;
22809 -+ struct vfsmount *realrootmnt;
22810 -+ struct dentry *currentroot;
22811 -+ struct vfsmount *currentmnt;
22812 -+ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
22813 -+ int ret = 1;
22814 -+
22815 -+ read_lock(&reaper->fs->lock);
22816 -+ realrootmnt = mntget(reaper->fs->root.mnt);
22817 -+ realroot = dget(reaper->fs->root.dentry);
22818 -+ read_unlock(&reaper->fs->lock);
22819 -+
22820 -+ read_lock(&current->fs->lock);
22821 -+ currentmnt = mntget(current->fs->root.mnt);
22822 -+ currentroot = dget(current->fs->root.dentry);
22823 -+ read_unlock(&current->fs->lock);
22824 -+
22825 -+ spin_lock(&dcache_lock);
22826 -+ for (;;) {
22827 -+ if (unlikely((dentry == realroot && mnt == realrootmnt)
22828 -+ || (dentry == currentroot && mnt == currentmnt)))
22829 -+ break;
22830 -+ if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
22831 -+ if (mnt->mnt_parent == mnt)
22832 -+ break;
22833 -+ dentry = mnt->mnt_mountpoint;
22834 -+ mnt = mnt->mnt_parent;
22835 -+ continue;
22836 -+ }
22837 -+ dentry = dentry->d_parent;
22838 -+ }
22839 -+ spin_unlock(&dcache_lock);
22840 -+
22841 -+ dput(currentroot);
22842 -+ mntput(currentmnt);
22843 -+
22844 -+ /* access is outside of chroot */
22845 -+ if (dentry == realroot && mnt == realrootmnt)
22846 -+ ret = 0;
22847 -+
22848 -+ dput(realroot);
22849 -+ mntput(realrootmnt);
22850 -+ return ret;
22851 -+}
22852 -+#endif
22853 -+
22854 -+int
22855 -+gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
22856 -+{
22857 -+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
22858 -+ if (!grsec_enable_chroot_fchdir)
22859 -+ return 1;
22860 -+
22861 -+ if (!proc_is_chrooted(current))
22862 -+ return 1;
22863 -+ else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
22864 -+ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
22865 -+ return 0;
22866 -+ }
22867 -+#endif
22868 -+ return 1;
22869 -+}
22870 -+
22871 -+int
22872 -+gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
22873 -+ const time_t shm_createtime)
22874 -+{
22875 -+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
22876 -+ struct pid *pid = NULL;
22877 -+ time_t starttime;
22878 -+
22879 -+ if (unlikely(!grsec_enable_chroot_shmat))
22880 -+ return 1;
22881 -+
22882 -+ if (likely(!proc_is_chrooted(current)))
22883 -+ return 1;
22884 -+
22885 -+ read_lock(&tasklist_lock);
22886 -+
22887 -+ pid = find_vpid(shm_cprid);
22888 -+ if (pid) {
22889 -+ struct task_struct *p;
22890 -+ p = pid_task(pid, PIDTYPE_PID);
22891 -+ task_lock(p);
22892 -+ starttime = p->start_time.tv_sec;
22893 -+ if (unlikely(!have_same_root(current, p) &&
22894 -+ time_before_eq((unsigned long)starttime, (unsigned long)shm_createtime))) {
22895 -+ task_unlock(p);
22896 -+ read_unlock(&tasklist_lock);
22897 -+ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
22898 -+ return 0;
22899 -+ }
22900 -+ task_unlock(p);
22901 -+ } else {
22902 -+ pid = find_vpid(shm_lapid);
22903 -+ if (pid) {
22904 -+ struct task_struct *p;
22905 -+ p = pid_task(pid, PIDTYPE_PID);
22906 -+ task_lock(p);
22907 -+ if (unlikely(!have_same_root(current, p))) {
22908 -+ task_unlock(p);
22909 -+ read_unlock(&tasklist_lock);
22910 -+ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
22911 -+ return 0;
22912 -+ }
22913 -+ task_unlock(p);
22914 -+ }
22915 -+ }
22916 -+
22917 -+ read_unlock(&tasklist_lock);
22918 -+#endif
22919 -+ return 1;
22920 -+}
22921 -+
22922 -+void
22923 -+gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
22924 -+{
22925 -+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
22926 -+ if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
22927 -+ gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
22928 -+#endif
22929 -+ return;
22930 -+}
22931 -+
22932 -+int
22933 -+gr_handle_chroot_mknod(const struct dentry *dentry,
22934 -+ const struct vfsmount *mnt, const int mode)
22935 -+{
22936 -+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
22937 -+ if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) &&
22938 -+ proc_is_chrooted(current)) {
22939 -+ gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
22940 -+ return -EPERM;
22941 -+ }
22942 -+#endif
22943 -+ return 0;
22944 -+}
22945 -+
22946 -+int
22947 -+gr_handle_chroot_mount(const struct dentry *dentry,
22948 -+ const struct vfsmount *mnt, const char *dev_name)
22949 -+{
22950 -+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
22951 -+ if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
22952 -+ gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
22953 -+ return -EPERM;
22954 -+ }
22955 -+#endif
22956 -+ return 0;
22957 -+}
22958 -+
22959 -+int
22960 -+gr_handle_chroot_pivot(void)
22961 -+{
22962 -+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
22963 -+ if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
22964 -+ gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
22965 -+ return -EPERM;
22966 -+ }
22967 -+#endif
22968 -+ return 0;
22969 -+}
22970 -+
22971 -+int
22972 -+gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
22973 -+{
22974 -+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
22975 -+ if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
22976 -+ !gr_is_outside_chroot(dentry, mnt)) {
22977 -+ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
22978 -+ return -EPERM;
22979 -+ }
22980 -+#endif
22981 -+ return 0;
22982 -+}
22983 -+
22984 -+void
22985 -+gr_handle_chroot_caps(struct task_struct *task)
22986 -+{
22987 -+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
22988 -+ if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
22989 -+ kernel_cap_t chroot_caps = GR_CHROOT_CAPS;
22990 -+ task->cap_permitted =
22991 -+ cap_drop(task->cap_permitted, chroot_caps);
22992 -+ task->cap_inheritable =
22993 -+ cap_drop(task->cap_inheritable, chroot_caps);
22994 -+ task->cap_effective =
22995 -+ cap_drop(task->cap_effective, chroot_caps);
22996 -+ }
22997 -+#endif
22998 -+ return;
22999 -+}
23000 -+
23001 -+int
23002 -+gr_handle_chroot_sysctl(const int op)
23003 -+{
23004 -+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
23005 -+ if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
23006 -+ && (op & MAY_WRITE))
23007 -+ return -EACCES;
23008 -+#endif
23009 -+ return 0;
23010 -+}
23011 -+
23012 -+void
23013 -+gr_handle_chroot_chdir(struct path *path)
23014 -+{
23015 -+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
23016 -+ if (grsec_enable_chroot_chdir)
23017 -+ set_fs_pwd(current->fs, path);
23018 -+#endif
23019 -+ return;
23020 -+}
23021 -+
23022 -+int
23023 -+gr_handle_chroot_chmod(const struct dentry *dentry,
23024 -+ const struct vfsmount *mnt, const int mode)
23025 -+{
23026 -+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
23027 -+ if (grsec_enable_chroot_chmod &&
23028 -+ ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
23029 -+ proc_is_chrooted(current)) {
23030 -+ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
23031 -+ return -EPERM;
23032 -+ }
23033 -+#endif
23034 -+ return 0;
23035 -+}
23036 -+
23037 -+#ifdef CONFIG_SECURITY
23038 -+EXPORT_SYMBOL(gr_handle_chroot_caps);
23039 -+#endif
23040 -diff -urNp linux-2.6.27.6/grsecurity/grsec_disabled.c linux-2.6.27.6/grsecurity/grsec_disabled.c
23041 ---- linux-2.6.27.6/grsecurity/grsec_disabled.c 1969-12-31 19:00:00.000000000 -0500
23042 -+++ linux-2.6.27.6/grsecurity/grsec_disabled.c 2008-11-18 03:38:45.000000000 -0500
23043 -@@ -0,0 +1,418 @@
23044 -+#include <linux/kernel.h>
23045 -+#include <linux/module.h>
23046 -+#include <linux/sched.h>
23047 -+#include <linux/file.h>
23048 -+#include <linux/fs.h>
23049 -+#include <linux/kdev_t.h>
23050 -+#include <linux/net.h>
23051 -+#include <linux/in.h>
23052 -+#include <linux/ip.h>
23053 -+#include <linux/skbuff.h>
23054 -+#include <linux/sysctl.h>
23055 -+
23056 -+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
23057 -+void
23058 -+pax_set_initial_flags(struct linux_binprm *bprm)
23059 -+{
23060 -+ return;
23061 -+}
23062 -+#endif
23063 -+
23064 -+#ifdef CONFIG_SYSCTL
23065 -+__u32
23066 -+gr_handle_sysctl(const struct ctl_table * table, const int op)
23067 -+{
23068 -+ return 0;
23069 -+}
23070 -+#endif
23071 -+
23072 -+int
23073 -+gr_acl_is_enabled(void)
23074 -+{
23075 -+ return 0;
23076 -+}
23077 -+
23078 -+int
23079 -+gr_handle_rawio(const struct inode *inode)
23080 -+{
23081 -+ return 0;
23082 -+}
23083 -+
23084 -+void
23085 -+gr_acl_handle_psacct(struct task_struct *task, const long code)
23086 -+{
23087 -+ return;
23088 -+}
23089 -+
23090 -+int
23091 -+gr_handle_ptrace(struct task_struct *task, const long request)
23092 -+{
23093 -+ return 0;
23094 -+}
23095 -+
23096 -+int
23097 -+gr_handle_proc_ptrace(struct task_struct *task)
23098 -+{
23099 -+ return 0;
23100 -+}
23101 -+
23102 -+void
23103 -+gr_learn_resource(const struct task_struct *task,
23104 -+ const int res, const unsigned long wanted, const int gt)
23105 -+{
23106 -+ return;
23107 -+}
23108 -+
23109 -+int
23110 -+gr_set_acls(const int type)
23111 -+{
23112 -+ return 0;
23113 -+}
23114 -+
23115 -+int
23116 -+gr_check_hidden_task(const struct task_struct *tsk)
23117 -+{
23118 -+ return 0;
23119 -+}
23120 -+
23121 -+int
23122 -+gr_check_protected_task(const struct task_struct *task)
23123 -+{
23124 -+ return 0;
23125 -+}
23126 -+
23127 -+void
23128 -+gr_copy_label(struct task_struct *tsk)
23129 -+{
23130 -+ return;
23131 -+}
23132 -+
23133 -+void
23134 -+gr_set_pax_flags(struct task_struct *task)
23135 -+{
23136 -+ return;
23137 -+}
23138 -+
23139 -+int
23140 -+gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
23141 -+{
23142 -+ return 0;
23143 -+}
23144 -+
23145 -+void
23146 -+gr_handle_delete(const ino_t ino, const dev_t dev)
23147 -+{
23148 -+ return;
23149 -+}
23150 -+
23151 -+void
23152 -+gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
23153 -+{
23154 -+ return;
23155 -+}
23156 -+
23157 -+void
23158 -+gr_handle_crash(struct task_struct *task, const int sig)
23159 -+{
23160 -+ return;
23161 -+}
23162 -+
23163 -+int
23164 -+gr_check_crash_exec(const struct file *filp)
23165 -+{
23166 -+ return 0;
23167 -+}
23168 -+
23169 -+int
23170 -+gr_check_crash_uid(const uid_t uid)
23171 -+{
23172 -+ return 0;
23173 -+}
23174 -+
23175 -+void
23176 -+gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
23177 -+ struct dentry *old_dentry,
23178 -+ struct dentry *new_dentry,
23179 -+ struct vfsmount *mnt, const __u8 replace)
23180 -+{
23181 -+ return;
23182 -+}
23183 -+
23184 -+int
23185 -+gr_search_socket(const int family, const int type, const int protocol)
23186 -+{
23187 -+ return 1;
23188 -+}
23189 -+
23190 -+int
23191 -+gr_search_connectbind(const int mode, const struct socket *sock,
23192 -+ const struct sockaddr_in *addr)
23193 -+{
23194 -+ return 1;
23195 -+}
23196 -+
23197 -+int
23198 -+gr_task_is_capable(struct task_struct *task, const int cap)
23199 -+{
23200 -+ return 1;
23201 -+}
23202 -+
23203 -+int
23204 -+gr_is_capable_nolog(const int cap)
23205 -+{
23206 -+ return 1;
23207 -+}
23208 -+
23209 -+void
23210 -+gr_handle_alertkill(struct task_struct *task)
23211 -+{
23212 -+ return;
23213 -+}
23214 -+
23215 -+__u32
23216 -+gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
23217 -+{
23218 -+ return 1;
23219 -+}
23220 -+
23221 -+__u32
23222 -+gr_acl_handle_hidden_file(const struct dentry * dentry,
23223 -+ const struct vfsmount * mnt)
23224 -+{
23225 -+ return 1;
23226 -+}
23227 -+
23228 -+__u32
23229 -+gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
23230 -+ const int fmode)
23231 -+{
23232 -+ return 1;
23233 -+}
23234 -+
23235 -+__u32
23236 -+gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
23237 -+{
23238 -+ return 1;
23239 -+}
23240 -+
23241 -+__u32
23242 -+gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
23243 -+{
23244 -+ return 1;
23245 -+}
23246 -+
23247 -+int
23248 -+gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
23249 -+ unsigned int *vm_flags)
23250 -+{
23251 -+ return 1;
23252 -+}
23253 -+
23254 -+__u32
23255 -+gr_acl_handle_truncate(const struct dentry * dentry,
23256 -+ const struct vfsmount * mnt)
23257 -+{
23258 -+ return 1;
23259 -+}
23260 -+
23261 -+__u32
23262 -+gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
23263 -+{
23264 -+ return 1;
23265 -+}
23266 -+
23267 -+__u32
23268 -+gr_acl_handle_access(const struct dentry * dentry,
23269 -+ const struct vfsmount * mnt, const int fmode)
23270 -+{
23271 -+ return 1;
23272 -+}
23273 -+
23274 -+__u32
23275 -+gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
23276 -+ mode_t mode)
23277 -+{
23278 -+ return 1;
23279 -+}
23280 -+
23281 -+__u32
23282 -+gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
23283 -+ mode_t mode)
23284 -+{
23285 -+ return 1;
23286 -+}
23287 -+
23288 -+__u32
23289 -+gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
23290 -+{
23291 -+ return 1;
23292 -+}
23293 -+
23294 -+void
23295 -+grsecurity_init(void)
23296 -+{
23297 -+ return;
23298 -+}
23299 -+
23300 -+__u32
23301 -+gr_acl_handle_mknod(const struct dentry * new_dentry,
23302 -+ const struct dentry * parent_dentry,
23303 -+ const struct vfsmount * parent_mnt,
23304 -+ const int mode)
23305 -+{
23306 -+ return 1;
23307 -+}
23308 -+
23309 -+__u32
23310 -+gr_acl_handle_mkdir(const struct dentry * new_dentry,
23311 -+ const struct dentry * parent_dentry,
23312 -+ const struct vfsmount * parent_mnt)
23313 -+{
23314 -+ return 1;
23315 -+}
23316 -+
23317 -+__u32
23318 -+gr_acl_handle_symlink(const struct dentry * new_dentry,
23319 -+ const struct dentry * parent_dentry,
23320 -+ const struct vfsmount * parent_mnt, const char *from)
23321 -+{
23322 -+ return 1;
23323 -+}
23324 -+
23325 -+__u32
23326 -+gr_acl_handle_link(const struct dentry * new_dentry,
23327 -+ const struct dentry * parent_dentry,
23328 -+ const struct vfsmount * parent_mnt,
23329 -+ const struct dentry * old_dentry,
23330 -+ const struct vfsmount * old_mnt, const char *to)
23331 -+{
23332 -+ return 1;
23333 -+}
23334 -+
23335 -+int
23336 -+gr_acl_handle_rename(const struct dentry *new_dentry,
23337 -+ const struct dentry *parent_dentry,
23338 -+ const struct vfsmount *parent_mnt,
23339 -+ const struct dentry *old_dentry,
23340 -+ const struct inode *old_parent_inode,
23341 -+ const struct vfsmount *old_mnt, const char *newname)
23342 -+{
23343 -+ return 0;
23344 -+}
23345 -+
23346 -+int
23347 -+gr_acl_handle_filldir(const struct file *file, const char *name,
23348 -+ const int namelen, const ino_t ino)
23349 -+{
23350 -+ return 1;
23351 -+}
23352 -+
23353 -+int
23354 -+gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
23355 -+ const time_t shm_createtime, const uid_t cuid, const int shmid)
23356 -+{
23357 -+ return 1;
23358 -+}
23359 -+
23360 -+int
23361 -+gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
23362 -+{
23363 -+ return 1;
23364 -+}
23365 -+
23366 -+int
23367 -+gr_search_accept(const struct socket *sock)
23368 -+{
23369 -+ return 1;
23370 -+}
23371 -+
23372 -+int
23373 -+gr_search_listen(const struct socket *sock)
23374 -+{
23375 -+ return 1;
23376 -+}
23377 -+
23378 -+int
23379 -+gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
23380 -+{
23381 -+ return 1;
23382 -+}
23383 -+
23384 -+__u32
23385 -+gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
23386 -+{
23387 -+ return 1;
23388 -+}
23389 -+
23390 -+__u32
23391 -+gr_acl_handle_creat(const struct dentry * dentry,
23392 -+ const struct dentry * p_dentry,
23393 -+ const struct vfsmount * p_mnt, const int fmode,
23394 -+ const int imode)
23395 -+{
23396 -+ return 1;
23397 -+}
23398 -+
23399 -+void
23400 -+gr_acl_handle_exit(void)
23401 -+{
23402 -+ return;
23403 -+}
23404 -+
23405 -+int
23406 -+gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
23407 -+{
23408 -+ return 1;
23409 -+}
23410 -+
23411 -+void
23412 -+gr_set_role_label(const uid_t uid, const gid_t gid)
23413 -+{
23414 -+ return;
23415 -+}
23416 -+
23417 -+int
23418 -+gr_acl_handle_procpidmem(const struct task_struct *task)
23419 -+{
23420 -+ return 0;
23421 -+}
23422 -+
23423 -+int
23424 -+gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
23425 -+{
23426 -+ return 1;
23427 -+}
23428 -+
23429 -+int
23430 -+gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
23431 -+{
23432 -+ return 1;
23433 -+}
23434 -+
23435 -+void
23436 -+gr_set_kernel_label(struct task_struct *task)
23437 -+{
23438 -+ return;
23439 -+}
23440 -+
23441 -+int
23442 -+gr_check_user_change(int real, int effective, int fs)
23443 -+{
23444 -+ return 0;
23445 -+}
23446 -+
23447 -+int
23448 -+gr_check_group_change(int real, int effective, int fs)
23449 -+{
23450 -+ return 0;
23451 -+}
23452 -+
23453 -+
23454 -+EXPORT_SYMBOL(gr_task_is_capable);
23455 -+EXPORT_SYMBOL(gr_is_capable_nolog);
23456 -+EXPORT_SYMBOL(gr_learn_resource);
23457 -+EXPORT_SYMBOL(gr_set_kernel_label);
23458 -+#ifdef CONFIG_SECURITY
23459 -+EXPORT_SYMBOL(gr_check_user_change);
23460 -+EXPORT_SYMBOL(gr_check_group_change);
23461 -+#endif
23462 -diff -urNp linux-2.6.27.6/grsecurity/grsec_exec.c linux-2.6.27.6/grsecurity/grsec_exec.c
23463 ---- linux-2.6.27.6/grsecurity/grsec_exec.c 1969-12-31 19:00:00.000000000 -0500
23464 -+++ linux-2.6.27.6/grsecurity/grsec_exec.c 2008-11-18 03:38:45.000000000 -0500
23465 -@@ -0,0 +1,88 @@
23466 -+#include <linux/kernel.h>
23467 -+#include <linux/sched.h>
23468 -+#include <linux/file.h>
23469 -+#include <linux/binfmts.h>
23470 -+#include <linux/smp_lock.h>
23471 -+#include <linux/fs.h>
23472 -+#include <linux/types.h>
23473 -+#include <linux/grdefs.h>
23474 -+#include <linux/grinternal.h>
23475 -+#include <linux/capability.h>
23476 -+
23477 -+#include <asm/uaccess.h>
23478 -+
23479 -+#ifdef CONFIG_GRKERNSEC_EXECLOG
23480 -+static char gr_exec_arg_buf[132];
23481 -+static DECLARE_MUTEX(gr_exec_arg_sem);
23482 -+#endif
23483 -+
23484 -+int
23485 -+gr_handle_nproc(void)
23486 -+{
23487 -+#ifdef CONFIG_GRKERNSEC_EXECVE
23488 -+ if (grsec_enable_execve && current->user &&
23489 -+ (atomic_read(&current->user->processes) >
23490 -+ current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
23491 -+ !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
23492 -+ gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
23493 -+ return -EAGAIN;
23494 -+ }
23495 -+#endif
23496 -+ return 0;
23497 -+}
23498 -+
23499 -+void
23500 -+gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
23501 -+{
23502 -+#ifdef CONFIG_GRKERNSEC_EXECLOG
23503 -+ char *grarg = gr_exec_arg_buf;
23504 -+ unsigned int i, x, execlen = 0;
23505 -+ char c;
23506 -+
23507 -+ if (!((grsec_enable_execlog && grsec_enable_group &&
23508 -+ in_group_p(grsec_audit_gid))
23509 -+ || (grsec_enable_execlog && !grsec_enable_group)))
23510 -+ return;
23511 -+
23512 -+ down(&gr_exec_arg_sem);
23513 -+ memset(grarg, 0, sizeof(gr_exec_arg_buf));
23514 -+
23515 -+ if (unlikely(argv == NULL))
23516 -+ goto log;
23517 -+
23518 -+ for (i = 0; i < bprm->argc && execlen < 128; i++) {
23519 -+ const char __user *p;
23520 -+ unsigned int len;
23521 -+
23522 -+ if (copy_from_user(&p, argv + i, sizeof(p)))
23523 -+ goto log;
23524 -+ if (!p)
23525 -+ goto log;
23526 -+ len = strnlen_user(p, 128 - execlen);
23527 -+ if (len > 128 - execlen)
23528 -+ len = 128 - execlen;
23529 -+ else if (len > 0)
23530 -+ len--;
23531 -+ if (copy_from_user(grarg + execlen, p, len))
23532 -+ goto log;
23533 -+
23534 -+ /* rewrite unprintable characters */
23535 -+ for (x = 0; x < len; x++) {
23536 -+ c = *(grarg + execlen + x);
23537 -+ if (c < 32 || c > 126)
23538 -+ *(grarg + execlen + x) = ' ';
23539 -+ }
23540 -+
23541 -+ execlen += len;
23542 -+ *(grarg + execlen) = ' ';
23543 -+ *(grarg + execlen + 1) = '\0';
23544 -+ execlen++;
23545 -+ }
23546 -+
23547 -+ log:
23548 -+ gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_path.dentry,
23549 -+ bprm->file->f_path.mnt, grarg);
23550 -+ up(&gr_exec_arg_sem);
23551 -+#endif
23552 -+ return;
23553 -+}
23554 -diff -urNp linux-2.6.27.6/grsecurity/grsec_fifo.c linux-2.6.27.6/grsecurity/grsec_fifo.c
23555 ---- linux-2.6.27.6/grsecurity/grsec_fifo.c 1969-12-31 19:00:00.000000000 -0500
23556 -+++ linux-2.6.27.6/grsecurity/grsec_fifo.c 2008-11-18 03:38:45.000000000 -0500
23557 -@@ -0,0 +1,22 @@
23558 -+#include <linux/kernel.h>
23559 -+#include <linux/sched.h>
23560 -+#include <linux/fs.h>
23561 -+#include <linux/file.h>
23562 -+#include <linux/grinternal.h>
23563 -+
23564 -+int
23565 -+gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
23566 -+ const struct dentry *dir, const int flag, const int acc_mode)
23567 -+{
23568 -+#ifdef CONFIG_GRKERNSEC_FIFO
23569 -+ if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
23570 -+ !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
23571 -+ (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
23572 -+ (current->fsuid != dentry->d_inode->i_uid)) {
23573 -+ if (!generic_permission(dentry->d_inode, acc_mode, NULL))
23574 -+ gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
23575 -+ return -EACCES;
23576 -+ }
23577 -+#endif
23578 -+ return 0;
23579 -+}
23580 -diff -urNp linux-2.6.27.6/grsecurity/grsec_fork.c linux-2.6.27.6/grsecurity/grsec_fork.c
23581 ---- linux-2.6.27.6/grsecurity/grsec_fork.c 1969-12-31 19:00:00.000000000 -0500
23582 -+++ linux-2.6.27.6/grsecurity/grsec_fork.c 2008-11-18 03:38:45.000000000 -0500
23583 -@@ -0,0 +1,15 @@
23584 -+#include <linux/kernel.h>
23585 -+#include <linux/sched.h>
23586 -+#include <linux/grsecurity.h>
23587 -+#include <linux/grinternal.h>
23588 -+#include <linux/errno.h>
23589 -+
23590 -+void
23591 -+gr_log_forkfail(const int retval)
23592 -+{
23593 -+#ifdef CONFIG_GRKERNSEC_FORKFAIL
23594 -+ if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
23595 -+ gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
23596 -+#endif
23597 -+ return;
23598 -+}
23599 -diff -urNp linux-2.6.27.6/grsecurity/grsec_init.c linux-2.6.27.6/grsecurity/grsec_init.c
23600 ---- linux-2.6.27.6/grsecurity/grsec_init.c 1969-12-31 19:00:00.000000000 -0500
23601 -+++ linux-2.6.27.6/grsecurity/grsec_init.c 2008-11-18 03:38:45.000000000 -0500
23602 -@@ -0,0 +1,230 @@
23603 -+#include <linux/kernel.h>
23604 -+#include <linux/sched.h>
23605 -+#include <linux/mm.h>
23606 -+#include <linux/smp_lock.h>
23607 -+#include <linux/gracl.h>
23608 -+#include <linux/slab.h>
23609 -+#include <linux/vmalloc.h>
23610 -+#include <linux/percpu.h>
23611 -+
23612 -+int grsec_enable_link;
23613 -+int grsec_enable_dmesg;
23614 -+int grsec_enable_fifo;
23615 -+int grsec_enable_execve;
23616 -+int grsec_enable_execlog;
23617 -+int grsec_enable_signal;
23618 -+int grsec_enable_forkfail;
23619 -+int grsec_enable_time;
23620 -+int grsec_enable_audit_textrel;
23621 -+int grsec_enable_group;
23622 -+int grsec_audit_gid;
23623 -+int grsec_enable_chdir;
23624 -+int grsec_enable_audit_ipc;
23625 -+int grsec_enable_mount;
23626 -+int grsec_enable_chroot_findtask;
23627 -+int grsec_enable_chroot_mount;
23628 -+int grsec_enable_chroot_shmat;
23629 -+int grsec_enable_chroot_fchdir;
23630 -+int grsec_enable_chroot_double;
23631 -+int grsec_enable_chroot_pivot;
23632 -+int grsec_enable_chroot_chdir;
23633 -+int grsec_enable_chroot_chmod;
23634 -+int grsec_enable_chroot_mknod;
23635 -+int grsec_enable_chroot_nice;
23636 -+int grsec_enable_chroot_execlog;
23637 -+int grsec_enable_chroot_caps;
23638 -+int grsec_enable_chroot_sysctl;
23639 -+int grsec_enable_chroot_unix;
23640 -+int grsec_enable_tpe;
23641 -+int grsec_tpe_gid;
23642 -+int grsec_enable_tpe_all;
23643 -+int grsec_enable_socket_all;
23644 -+int grsec_socket_all_gid;
23645 -+int grsec_enable_socket_client;
23646 -+int grsec_socket_client_gid;
23647 -+int grsec_enable_socket_server;
23648 -+int grsec_socket_server_gid;
23649 -+int grsec_resource_logging;
23650 -+int grsec_lock;
23651 -+
23652 -+DEFINE_SPINLOCK(grsec_alert_lock);
23653 -+unsigned long grsec_alert_wtime = 0;
23654 -+unsigned long grsec_alert_fyet = 0;
23655 -+
23656 -+DEFINE_SPINLOCK(grsec_audit_lock);
23657 -+
23658 -+DEFINE_RWLOCK(grsec_exec_file_lock);
23659 -+
23660 -+char *gr_shared_page[4];
23661 -+
23662 -+char *gr_alert_log_fmt;
23663 -+char *gr_audit_log_fmt;
23664 -+char *gr_alert_log_buf;
23665 -+char *gr_audit_log_buf;
23666 -+
23667 -+extern struct gr_arg *gr_usermode;
23668 -+extern unsigned char *gr_system_salt;
23669 -+extern unsigned char *gr_system_sum;
23670 -+
23671 -+void
23672 -+grsecurity_init(void)
23673 -+{
23674 -+ int j;
23675 -+ /* create the per-cpu shared pages */
23676 -+
23677 -+#ifdef CONFIG_X86
23678 -+ memset((char *)(0x41a + PAGE_OFFSET), 0, 36);
23679 -+#endif
23680 -+
23681 -+ for (j = 0; j < 4; j++) {
23682 -+ gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
23683 -+ if (gr_shared_page[j] == NULL) {
23684 -+ panic("Unable to allocate grsecurity shared page");
23685 -+ return;
23686 -+ }
23687 -+ }
23688 -+
23689 -+ /* allocate log buffers */
23690 -+ gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
23691 -+ if (!gr_alert_log_fmt) {
23692 -+ panic("Unable to allocate grsecurity alert log format buffer");
23693 -+ return;
23694 -+ }
23695 -+ gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
23696 -+ if (!gr_audit_log_fmt) {
23697 -+ panic("Unable to allocate grsecurity audit log format buffer");
23698 -+ return;
23699 -+ }
23700 -+ gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
23701 -+ if (!gr_alert_log_buf) {
23702 -+ panic("Unable to allocate grsecurity alert log buffer");
23703 -+ return;
23704 -+ }
23705 -+ gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
23706 -+ if (!gr_audit_log_buf) {
23707 -+ panic("Unable to allocate grsecurity audit log buffer");
23708 -+ return;
23709 -+ }
23710 -+
23711 -+ /* allocate memory for authentication structure */
23712 -+ gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
23713 -+ gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
23714 -+ gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
23715 -+
23716 -+ if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
23717 -+ panic("Unable to allocate grsecurity authentication structure");
23718 -+ return;
23719 -+ }
23720 -+
23721 -+#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
23722 -+#ifndef CONFIG_GRKERNSEC_SYSCTL
23723 -+ grsec_lock = 1;
23724 -+#endif
23725 -+#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
23726 -+ grsec_enable_audit_textrel = 1;
23727 -+#endif
23728 -+#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
23729 -+ grsec_enable_group = 1;
23730 -+ grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
23731 -+#endif
23732 -+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
23733 -+ grsec_enable_chdir = 1;
23734 -+#endif
23735 -+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
23736 -+ grsec_enable_audit_ipc = 1;
23737 -+#endif
23738 -+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
23739 -+ grsec_enable_mount = 1;
23740 -+#endif
23741 -+#ifdef CONFIG_GRKERNSEC_LINK
23742 -+ grsec_enable_link = 1;
23743 -+#endif
23744 -+#ifdef CONFIG_GRKERNSEC_DMESG
23745 -+ grsec_enable_dmesg = 1;
23746 -+#endif
23747 -+#ifdef CONFIG_GRKERNSEC_FIFO
23748 -+ grsec_enable_fifo = 1;
23749 -+#endif
23750 -+#ifdef CONFIG_GRKERNSEC_EXECVE
23751 -+ grsec_enable_execve = 1;
23752 -+#endif
23753 -+#ifdef CONFIG_GRKERNSEC_EXECLOG
23754 -+ grsec_enable_execlog = 1;
23755 -+#endif
23756 -+#ifdef CONFIG_GRKERNSEC_SIGNAL
23757 -+ grsec_enable_signal = 1;
23758 -+#endif
23759 -+#ifdef CONFIG_GRKERNSEC_FORKFAIL
23760 -+ grsec_enable_forkfail = 1;
23761 -+#endif
23762 -+#ifdef CONFIG_GRKERNSEC_TIME
23763 -+ grsec_enable_time = 1;
23764 -+#endif
23765 -+#ifdef CONFIG_GRKERNSEC_RESLOG
23766 -+ grsec_resource_logging = 1;
23767 -+#endif
23768 -+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
23769 -+ grsec_enable_chroot_findtask = 1;
23770 -+#endif
23771 -+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
23772 -+ grsec_enable_chroot_unix = 1;
23773 -+#endif
23774 -+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
23775 -+ grsec_enable_chroot_mount = 1;
23776 -+#endif
23777 -+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
23778 -+ grsec_enable_chroot_fchdir = 1;
23779 -+#endif
23780 -+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
23781 -+ grsec_enable_chroot_shmat = 1;
23782 -+#endif
23783 -+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
23784 -+ grsec_enable_chroot_double = 1;
23785 -+#endif
23786 -+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
23787 -+ grsec_enable_chroot_pivot = 1;
23788 -+#endif
23789 -+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
23790 -+ grsec_enable_chroot_chdir = 1;
23791 -+#endif
23792 -+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
23793 -+ grsec_enable_chroot_chmod = 1;
23794 -+#endif
23795 -+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
23796 -+ grsec_enable_chroot_mknod = 1;
23797 -+#endif
23798 -+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
23799 -+ grsec_enable_chroot_nice = 1;
23800 -+#endif
23801 -+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
23802 -+ grsec_enable_chroot_execlog = 1;
23803 -+#endif
23804 -+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
23805 -+ grsec_enable_chroot_caps = 1;
23806 -+#endif
23807 -+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
23808 -+ grsec_enable_chroot_sysctl = 1;
23809 -+#endif
23810 -+#ifdef CONFIG_GRKERNSEC_TPE
23811 -+ grsec_enable_tpe = 1;
23812 -+ grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
23813 -+#ifdef CONFIG_GRKERNSEC_TPE_ALL
23814 -+ grsec_enable_tpe_all = 1;
23815 -+#endif
23816 -+#endif
23817 -+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
23818 -+ grsec_enable_socket_all = 1;
23819 -+ grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
23820 -+#endif
23821 -+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
23822 -+ grsec_enable_socket_client = 1;
23823 -+ grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
23824 -+#endif
23825 -+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
23826 -+ grsec_enable_socket_server = 1;
23827 -+ grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
23828 -+#endif
23829 -+#endif
23830 -+
23831 -+ return;
23832 -+}
23833 -diff -urNp linux-2.6.27.6/grsecurity/grsec_ipc.c linux-2.6.27.6/grsecurity/grsec_ipc.c
23834 ---- linux-2.6.27.6/grsecurity/grsec_ipc.c 1969-12-31 19:00:00.000000000 -0500
23835 -+++ linux-2.6.27.6/grsecurity/grsec_ipc.c 2008-11-18 03:38:45.000000000 -0500
23836 -@@ -0,0 +1,81 @@
23837 -+#include <linux/kernel.h>
23838 -+#include <linux/sched.h>
23839 -+#include <linux/types.h>
23840 -+#include <linux/ipc.h>
23841 -+#include <linux/grsecurity.h>
23842 -+#include <linux/grinternal.h>
23843 -+
23844 -+void
23845 -+gr_log_msgget(const int ret, const int msgflg)
23846 -+{
23847 -+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
23848 -+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
23849 -+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
23850 -+ !grsec_enable_group)) && (ret >= 0)
23851 -+ && (msgflg & IPC_CREAT))
23852 -+ gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
23853 -+#endif
23854 -+ return;
23855 -+}
23856 -+
23857 -+void
23858 -+gr_log_msgrm(const uid_t uid, const uid_t cuid)
23859 -+{
23860 -+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
23861 -+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
23862 -+ grsec_enable_audit_ipc) ||
23863 -+ (grsec_enable_audit_ipc && !grsec_enable_group))
23864 -+ gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
23865 -+#endif
23866 -+ return;
23867 -+}
23868 -+
23869 -+void
23870 -+gr_log_semget(const int err, const int semflg)
23871 -+{
23872 -+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
23873 -+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
23874 -+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
23875 -+ !grsec_enable_group)) && (err >= 0)
23876 -+ && (semflg & IPC_CREAT))
23877 -+ gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
23878 -+#endif
23879 -+ return;
23880 -+}
23881 -+
23882 -+void
23883 -+gr_log_semrm(const uid_t uid, const uid_t cuid)
23884 -+{
23885 -+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
23886 -+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
23887 -+ grsec_enable_audit_ipc) ||
23888 -+ (grsec_enable_audit_ipc && !grsec_enable_group))
23889 -+ gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
23890 -+#endif
23891 -+ return;
23892 -+}
23893 -+
23894 -+void
23895 -+gr_log_shmget(const int err, const int shmflg, const size_t size)
23896 -+{
23897 -+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
23898 -+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
23899 -+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
23900 -+ !grsec_enable_group)) && (err >= 0)
23901 -+ && (shmflg & IPC_CREAT))
23902 -+ gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
23903 -+#endif
23904 -+ return;
23905 -+}
23906 -+
23907 -+void
23908 -+gr_log_shmrm(const uid_t uid, const uid_t cuid)
23909 -+{
23910 -+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
23911 -+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
23912 -+ grsec_enable_audit_ipc) ||
23913 -+ (grsec_enable_audit_ipc && !grsec_enable_group))
23914 -+ gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
23915 -+#endif
23916 -+ return;
23917 -+}
23918 -diff -urNp linux-2.6.27.6/grsecurity/grsec_link.c linux-2.6.27.6/grsecurity/grsec_link.c
23919 ---- linux-2.6.27.6/grsecurity/grsec_link.c 1969-12-31 19:00:00.000000000 -0500
23920 -+++ linux-2.6.27.6/grsecurity/grsec_link.c 2008-11-18 03:38:45.000000000 -0500
23921 -@@ -0,0 +1,39 @@
23922 -+#include <linux/kernel.h>
23923 -+#include <linux/sched.h>
23924 -+#include <linux/fs.h>
23925 -+#include <linux/file.h>
23926 -+#include <linux/grinternal.h>
23927 -+
23928 -+int
23929 -+gr_handle_follow_link(const struct inode *parent,
23930 -+ const struct inode *inode,
23931 -+ const struct dentry *dentry, const struct vfsmount *mnt)
23932 -+{
23933 -+#ifdef CONFIG_GRKERNSEC_LINK
23934 -+ if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
23935 -+ (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
23936 -+ (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
23937 -+ gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
23938 -+ return -EACCES;
23939 -+ }
23940 -+#endif
23941 -+ return 0;
23942 -+}
23943 -+
23944 -+int
23945 -+gr_handle_hardlink(const struct dentry *dentry,
23946 -+ const struct vfsmount *mnt,
23947 -+ struct inode *inode, const int mode, const char *to)
23948 -+{
23949 -+#ifdef CONFIG_GRKERNSEC_LINK
23950 -+ if (grsec_enable_link && current->fsuid != inode->i_uid &&
23951 -+ (!S_ISREG(mode) || (mode & S_ISUID) ||
23952 -+ ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
23953 -+ (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
23954 -+ !capable(CAP_FOWNER) && current->uid) {
23955 -+ gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
23956 -+ return -EPERM;
23957 -+ }
23958 -+#endif
23959 -+ return 0;
23960 -+}
23961 -diff -urNp linux-2.6.27.6/grsecurity/grsec_log.c linux-2.6.27.6/grsecurity/grsec_log.c
23962 ---- linux-2.6.27.6/grsecurity/grsec_log.c 1969-12-31 19:00:00.000000000 -0500
23963 -+++ linux-2.6.27.6/grsecurity/grsec_log.c 2008-11-18 03:38:45.000000000 -0500
23964 -@@ -0,0 +1,269 @@
23965 -+#include <linux/kernel.h>
23966 -+#include <linux/sched.h>
23967 -+#include <linux/file.h>
23968 -+#include <linux/tty.h>
23969 -+#include <linux/fs.h>
23970 -+#include <linux/grinternal.h>
23971 -+
23972 -+#define BEGIN_LOCKS(x) \
23973 -+ read_lock(&tasklist_lock); \
23974 -+ read_lock(&grsec_exec_file_lock); \
23975 -+ if (x != GR_DO_AUDIT) \
23976 -+ spin_lock(&grsec_alert_lock); \
23977 -+ else \
23978 -+ spin_lock(&grsec_audit_lock)
23979 -+
23980 -+#define END_LOCKS(x) \
23981 -+ if (x != GR_DO_AUDIT) \
23982 -+ spin_unlock(&grsec_alert_lock); \
23983 -+ else \
23984 -+ spin_unlock(&grsec_audit_lock); \
23985 -+ read_unlock(&grsec_exec_file_lock); \
23986 -+ read_unlock(&tasklist_lock); \
23987 -+ if (x == GR_DONT_AUDIT) \
23988 -+ gr_handle_alertkill(current)
23989 -+
23990 -+enum {
23991 -+ FLOODING,
23992 -+ NO_FLOODING
23993 -+};
23994 -+
23995 -+extern char *gr_alert_log_fmt;
23996 -+extern char *gr_audit_log_fmt;
23997 -+extern char *gr_alert_log_buf;
23998 -+extern char *gr_audit_log_buf;
23999 -+
24000 -+static int gr_log_start(int audit)
24001 -+{
24002 -+ char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
24003 -+ char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
24004 -+ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
24005 -+
24006 -+ if (audit == GR_DO_AUDIT)
24007 -+ goto set_fmt;
24008 -+
24009 -+ if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
24010 -+ grsec_alert_wtime = jiffies;
24011 -+ grsec_alert_fyet = 0;
24012 -+ } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
24013 -+ grsec_alert_fyet++;
24014 -+ } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
24015 -+ grsec_alert_wtime = jiffies;
24016 -+ grsec_alert_fyet++;
24017 -+ printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
24018 -+ return FLOODING;
24019 -+ } else return FLOODING;
24020 -+
24021 -+set_fmt:
24022 -+ memset(buf, 0, PAGE_SIZE);
24023 -+ if (current->signal->curr_ip && gr_acl_is_enabled()) {
24024 -+ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
24025 -+ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
24026 -+ } else if (current->signal->curr_ip) {
24027 -+ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
24028 -+ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
24029 -+ } else if (gr_acl_is_enabled()) {
24030 -+ sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
24031 -+ snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
24032 -+ } else {
24033 -+ sprintf(fmt, "%s%s", loglevel, "grsec: ");
24034 -+ strcpy(buf, fmt);
24035 -+ }
24036 -+
24037 -+ return NO_FLOODING;
24038 -+}
24039 -+
24040 -+static void gr_log_middle(int audit, const char *msg, va_list ap)
24041 -+{
24042 -+ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
24043 -+ unsigned int len = strlen(buf);
24044 -+
24045 -+ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
24046 -+
24047 -+ return;
24048 -+}
24049 -+
24050 -+static void gr_log_middle_varargs(int audit, const char *msg, ...)
24051 -+{
24052 -+ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
24053 -+ unsigned int len = strlen(buf);
24054 -+ va_list ap;
24055 -+
24056 -+ va_start(ap, msg);
24057 -+ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
24058 -+ va_end(ap);
24059 -+
24060 -+ return;
24061 -+}
24062 -+
24063 -+static void gr_log_end(int audit)
24064 -+{
24065 -+ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
24066 -+ unsigned int len = strlen(buf);
24067 -+
24068 -+ snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
24069 -+ printk("%s\n", buf);
24070 -+
24071 -+ return;
24072 -+}
24073 -+
24074 -+void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
24075 -+{
24076 -+ int logtype;
24077 -+ char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
24078 -+ char *str1, *str2, *str3;
24079 -+ int num1, num2;
24080 -+ unsigned long ulong1, ulong2;
24081 -+ struct dentry *dentry;
24082 -+ struct vfsmount *mnt;
24083 -+ struct file *file;
24084 -+ struct task_struct *task;
24085 -+ va_list ap;
24086 -+
24087 -+ BEGIN_LOCKS(audit);
24088 -+ logtype = gr_log_start(audit);
24089 -+ if (logtype == FLOODING) {
24090 -+ END_LOCKS(audit);
24091 -+ return;
24092 -+ }
24093 -+ va_start(ap, argtypes);
24094 -+ switch (argtypes) {
24095 -+ case GR_TTYSNIFF:
24096 -+ task = va_arg(ap, struct task_struct *);
24097 -+ 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);
24098 -+ break;
24099 -+ case GR_SYSCTL_HIDDEN:
24100 -+ str1 = va_arg(ap, char *);
24101 -+ gr_log_middle_varargs(audit, msg, result, str1);
24102 -+ break;
24103 -+ case GR_RBAC:
24104 -+ dentry = va_arg(ap, struct dentry *);
24105 -+ mnt = va_arg(ap, struct vfsmount *);
24106 -+ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
24107 -+ break;
24108 -+ case GR_RBAC_STR:
24109 -+ dentry = va_arg(ap, struct dentry *);
24110 -+ mnt = va_arg(ap, struct vfsmount *);
24111 -+ str1 = va_arg(ap, char *);
24112 -+ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
24113 -+ break;
24114 -+ case GR_STR_RBAC:
24115 -+ str1 = va_arg(ap, char *);
24116 -+ dentry = va_arg(ap, struct dentry *);
24117 -+ mnt = va_arg(ap, struct vfsmount *);
24118 -+ gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
24119 -+ break;
24120 -+ case GR_RBAC_MODE2:
24121 -+ dentry = va_arg(ap, struct dentry *);
24122 -+ mnt = va_arg(ap, struct vfsmount *);
24123 -+ str1 = va_arg(ap, char *);
24124 -+ str2 = va_arg(ap, char *);
24125 -+ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
24126 -+ break;
24127 -+ case GR_RBAC_MODE3:
24128 -+ dentry = va_arg(ap, struct dentry *);
24129 -+ mnt = va_arg(ap, struct vfsmount *);
24130 -+ str1 = va_arg(ap, char *);
24131 -+ str2 = va_arg(ap, char *);
24132 -+ str3 = va_arg(ap, char *);
24133 -+ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
24134 -+ break;
24135 -+ case GR_FILENAME:
24136 -+ dentry = va_arg(ap, struct dentry *);
24137 -+ mnt = va_arg(ap, struct vfsmount *);
24138 -+ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
24139 -+ break;
24140 -+ case GR_STR_FILENAME:
24141 -+ str1 = va_arg(ap, char *);
24142 -+ dentry = va_arg(ap, struct dentry *);
24143 -+ mnt = va_arg(ap, struct vfsmount *);
24144 -+ gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
24145 -+ break;
24146 -+ case GR_FILENAME_STR:
24147 -+ dentry = va_arg(ap, struct dentry *);
24148 -+ mnt = va_arg(ap, struct vfsmount *);
24149 -+ str1 = va_arg(ap, char *);
24150 -+ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
24151 -+ break;
24152 -+ case GR_FILENAME_TWO_INT:
24153 -+ dentry = va_arg(ap, struct dentry *);
24154 -+ mnt = va_arg(ap, struct vfsmount *);
24155 -+ num1 = va_arg(ap, int);
24156 -+ num2 = va_arg(ap, int);
24157 -+ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
24158 -+ break;
24159 -+ case GR_FILENAME_TWO_INT_STR:
24160 -+ dentry = va_arg(ap, struct dentry *);
24161 -+ mnt = va_arg(ap, struct vfsmount *);
24162 -+ num1 = va_arg(ap, int);
24163 -+ num2 = va_arg(ap, int);
24164 -+ str1 = va_arg(ap, char *);
24165 -+ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
24166 -+ break;
24167 -+ case GR_TEXTREL:
24168 -+ file = va_arg(ap, struct file *);
24169 -+ ulong1 = va_arg(ap, unsigned long);
24170 -+ ulong2 = va_arg(ap, unsigned long);
24171 -+ gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_path.dentry, file->f_path.mnt) : "<anonymous mapping>", ulong1, ulong2);
24172 -+ break;
24173 -+ case GR_PTRACE:
24174 -+ task = va_arg(ap, struct task_struct *);
24175 -+ 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);
24176 -+ break;
24177 -+ case GR_RESOURCE:
24178 -+ task = va_arg(ap, struct task_struct *);
24179 -+ ulong1 = va_arg(ap, unsigned long);
24180 -+ str1 = va_arg(ap, char *);
24181 -+ ulong2 = va_arg(ap, unsigned long);
24182 -+ 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);
24183 -+ break;
24184 -+ case GR_CAP:
24185 -+ task = va_arg(ap, struct task_struct *);
24186 -+ str1 = va_arg(ap, char *);
24187 -+ 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);
24188 -+ break;
24189 -+ case GR_SIG:
24190 -+ task = va_arg(ap, struct task_struct *);
24191 -+ num1 = va_arg(ap, int);
24192 -+ 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);
24193 -+ break;
24194 -+ case GR_CRASH1:
24195 -+ task = va_arg(ap, struct task_struct *);
24196 -+ ulong1 = va_arg(ap, unsigned long);
24197 -+ 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);
24198 -+ break;
24199 -+ case GR_CRASH2:
24200 -+ task = va_arg(ap, struct task_struct *);
24201 -+ ulong1 = va_arg(ap, unsigned long);
24202 -+ 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);
24203 -+ break;
24204 -+ case GR_PSACCT:
24205 -+ {
24206 -+ unsigned int wday, cday;
24207 -+ __u8 whr, chr;
24208 -+ __u8 wmin, cmin;
24209 -+ __u8 wsec, csec;
24210 -+ char cur_tty[64] = { 0 };
24211 -+ char parent_tty[64] = { 0 };
24212 -+
24213 -+ task = va_arg(ap, struct task_struct *);
24214 -+ wday = va_arg(ap, unsigned int);
24215 -+ cday = va_arg(ap, unsigned int);
24216 -+ whr = va_arg(ap, int);
24217 -+ chr = va_arg(ap, int);
24218 -+ wmin = va_arg(ap, int);
24219 -+ cmin = va_arg(ap, int);
24220 -+ wsec = va_arg(ap, int);
24221 -+ csec = va_arg(ap, int);
24222 -+ ulong1 = va_arg(ap, unsigned long);
24223 -+
24224 -+ 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);
24225 -+ }
24226 -+ break;
24227 -+ default:
24228 -+ gr_log_middle(audit, msg, ap);
24229 -+ }
24230 -+ va_end(ap);
24231 -+ gr_log_end(audit);
24232 -+ END_LOCKS(audit);
24233 -+}
24234 -diff -urNp linux-2.6.27.6/grsecurity/grsec_mem.c linux-2.6.27.6/grsecurity/grsec_mem.c
24235 ---- linux-2.6.27.6/grsecurity/grsec_mem.c 1969-12-31 19:00:00.000000000 -0500
24236 -+++ linux-2.6.27.6/grsecurity/grsec_mem.c 2008-11-18 03:38:45.000000000 -0500
24237 -@@ -0,0 +1,71 @@
24238 -+#include <linux/kernel.h>
24239 -+#include <linux/sched.h>
24240 -+#include <linux/mm.h>
24241 -+#include <linux/mman.h>
24242 -+#include <linux/grinternal.h>
24243 -+
24244 -+void
24245 -+gr_handle_ioperm(void)
24246 -+{
24247 -+ gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
24248 -+ return;
24249 -+}
24250 -+
24251 -+void
24252 -+gr_handle_iopl(void)
24253 -+{
24254 -+ gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
24255 -+ return;
24256 -+}
24257 -+
24258 -+void
24259 -+gr_handle_mem_write(void)
24260 -+{
24261 -+ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
24262 -+ return;
24263 -+}
24264 -+
24265 -+void
24266 -+gr_handle_kmem_write(void)
24267 -+{
24268 -+ gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
24269 -+ return;
24270 -+}
24271 -+
24272 -+void
24273 -+gr_handle_open_port(void)
24274 -+{
24275 -+ gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
24276 -+ return;
24277 -+}
24278 -+
24279 -+int
24280 -+gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
24281 -+{
24282 -+ unsigned long start, end;
24283 -+
24284 -+ start = offset;
24285 -+ end = start + vma->vm_end - vma->vm_start;
24286 -+
24287 -+ if (start > end) {
24288 -+ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
24289 -+ return -EPERM;
24290 -+ }
24291 -+
24292 -+ /* allowed ranges : ISA I/O BIOS */
24293 -+ if ((start >= __pa(high_memory))
24294 -+#ifdef CONFIG_X86
24295 -+ || (start >= 0x000a0000 && end <= 0x00100000)
24296 -+ || (start >= 0x00000000 && end <= 0x00001000)
24297 -+#endif
24298 -+ )
24299 -+ return 0;
24300 -+
24301 -+ if (vma->vm_flags & VM_WRITE) {
24302 -+ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
24303 -+ return -EPERM;
24304 -+ } else
24305 -+ vma->vm_flags &= ~VM_MAYWRITE;
24306 -+
24307 -+ return 0;
24308 -+}
24309 -diff -urNp linux-2.6.27.6/grsecurity/grsec_mount.c linux-2.6.27.6/grsecurity/grsec_mount.c
24310 ---- linux-2.6.27.6/grsecurity/grsec_mount.c 1969-12-31 19:00:00.000000000 -0500
24311 -+++ linux-2.6.27.6/grsecurity/grsec_mount.c 2008-11-18 03:38:45.000000000 -0500
24312 -@@ -0,0 +1,34 @@
24313 -+#include <linux/kernel.h>
24314 -+#include <linux/sched.h>
24315 -+#include <linux/grsecurity.h>
24316 -+#include <linux/grinternal.h>
24317 -+
24318 -+void
24319 -+gr_log_remount(const char *devname, const int retval)
24320 -+{
24321 -+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
24322 -+ if (grsec_enable_mount && (retval >= 0))
24323 -+ gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
24324 -+#endif
24325 -+ return;
24326 -+}
24327 -+
24328 -+void
24329 -+gr_log_unmount(const char *devname, const int retval)
24330 -+{
24331 -+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
24332 -+ if (grsec_enable_mount && (retval >= 0))
24333 -+ gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
24334 -+#endif
24335 -+ return;
24336 -+}
24337 -+
24338 -+void
24339 -+gr_log_mount(const char *from, const char *to, const int retval)
24340 -+{
24341 -+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
24342 -+ if (grsec_enable_mount && (retval >= 0))
24343 -+ gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
24344 -+#endif
24345 -+ return;
24346 -+}
24347 -diff -urNp linux-2.6.27.6/grsecurity/grsec_sig.c linux-2.6.27.6/grsecurity/grsec_sig.c
24348 ---- linux-2.6.27.6/grsecurity/grsec_sig.c 1969-12-31 19:00:00.000000000 -0500
24349 -+++ linux-2.6.27.6/grsecurity/grsec_sig.c 2008-11-18 03:38:45.000000000 -0500
24350 -@@ -0,0 +1,58 @@
24351 -+#include <linux/kernel.h>
24352 -+#include <linux/sched.h>
24353 -+#include <linux/delay.h>
24354 -+#include <linux/grsecurity.h>
24355 -+#include <linux/grinternal.h>
24356 -+
24357 -+void
24358 -+gr_log_signal(const int sig, const struct task_struct *t)
24359 -+{
24360 -+#ifdef CONFIG_GRKERNSEC_SIGNAL
24361 -+ if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
24362 -+ (sig == SIGABRT) || (sig == SIGBUS))) {
24363 -+ if (t->pid == current->pid) {
24364 -+ gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
24365 -+ } else {
24366 -+ gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
24367 -+ }
24368 -+ }
24369 -+#endif
24370 -+ return;
24371 -+}
24372 -+
24373 -+int
24374 -+gr_handle_signal(const struct task_struct *p, const int sig)
24375 -+{
24376 -+#ifdef CONFIG_GRKERNSEC
24377 -+ if (current->pid > 1 && gr_check_protected_task(p)) {
24378 -+ gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
24379 -+ return -EPERM;
24380 -+ } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
24381 -+ return -EPERM;
24382 -+ }
24383 -+#endif
24384 -+ return 0;
24385 -+}
24386 -+
24387 -+void gr_handle_brute_attach(struct task_struct *p)
24388 -+{
24389 -+#ifdef CONFIG_GRKERNSEC_BRUTE
24390 -+ read_lock(&tasklist_lock);
24391 -+ read_lock(&grsec_exec_file_lock);
24392 -+ if (p->parent && p->parent->exec_file == p->exec_file)
24393 -+ p->parent->brute = 1;
24394 -+ read_unlock(&grsec_exec_file_lock);
24395 -+ read_unlock(&tasklist_lock);
24396 -+#endif
24397 -+ return;
24398 -+}
24399 -+
24400 -+void gr_handle_brute_check(void)
24401 -+{
24402 -+#ifdef CONFIG_GRKERNSEC_BRUTE
24403 -+ if (current->brute)
24404 -+ msleep(30 * 1000);
24405 -+#endif
24406 -+ return;
24407 -+}
24408 -+
24409 -diff -urNp linux-2.6.27.6/grsecurity/grsec_sock.c linux-2.6.27.6/grsecurity/grsec_sock.c
24410 ---- linux-2.6.27.6/grsecurity/grsec_sock.c 1969-12-31 19:00:00.000000000 -0500
24411 -+++ linux-2.6.27.6/grsecurity/grsec_sock.c 2008-11-18 03:38:45.000000000 -0500
24412 -@@ -0,0 +1,274 @@
24413 -+#include <linux/kernel.h>
24414 -+#include <linux/module.h>
24415 -+#include <linux/sched.h>
24416 -+#include <linux/file.h>
24417 -+#include <linux/net.h>
24418 -+#include <linux/in.h>
24419 -+#include <linux/ip.h>
24420 -+#include <net/sock.h>
24421 -+#include <net/inet_sock.h>
24422 -+#include <linux/grsecurity.h>
24423 -+#include <linux/grinternal.h>
24424 -+#include <linux/gracl.h>
24425 -+
24426 -+#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
24427 -+extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
24428 -+EXPORT_SYMBOL(udp_v4_lookup);
24429 -+#endif
24430 -+
24431 -+kernel_cap_t gr_cap_rtnetlink(struct sock *sock);
24432 -+EXPORT_SYMBOL(gr_cap_rtnetlink);
24433 -+
24434 -+extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
24435 -+extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
24436 -+
24437 -+EXPORT_SYMBOL(gr_search_udp_recvmsg);
24438 -+EXPORT_SYMBOL(gr_search_udp_sendmsg);
24439 -+
24440 -+#ifdef CONFIG_UNIX_MODULE
24441 -+EXPORT_SYMBOL(gr_acl_handle_unix);
24442 -+EXPORT_SYMBOL(gr_acl_handle_mknod);
24443 -+EXPORT_SYMBOL(gr_handle_chroot_unix);
24444 -+EXPORT_SYMBOL(gr_handle_create);
24445 -+#endif
24446 -+
24447 -+#ifdef CONFIG_GRKERNSEC
24448 -+#define gr_conn_table_size 32749
24449 -+struct conn_table_entry {
24450 -+ struct conn_table_entry *next;
24451 -+ struct signal_struct *sig;
24452 -+};
24453 -+
24454 -+struct conn_table_entry *gr_conn_table[gr_conn_table_size];
24455 -+DEFINE_SPINLOCK(gr_conn_table_lock);
24456 -+
24457 -+extern const char * gr_socktype_to_name(unsigned char type);
24458 -+extern const char * gr_proto_to_name(unsigned char proto);
24459 -+
24460 -+static __inline__ int
24461 -+conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
24462 -+{
24463 -+ return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
24464 -+}
24465 -+
24466 -+static __inline__ int
24467 -+conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr,
24468 -+ __u16 sport, __u16 dport)
24469 -+{
24470 -+ if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
24471 -+ sig->gr_sport == sport && sig->gr_dport == dport))
24472 -+ return 1;
24473 -+ else
24474 -+ return 0;
24475 -+}
24476 -+
24477 -+static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
24478 -+{
24479 -+ struct conn_table_entry **match;
24480 -+ unsigned int index;
24481 -+
24482 -+ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
24483 -+ sig->gr_sport, sig->gr_dport,
24484 -+ gr_conn_table_size);
24485 -+
24486 -+ newent->sig = sig;
24487 -+
24488 -+ match = &gr_conn_table[index];
24489 -+ newent->next = *match;
24490 -+ *match = newent;
24491 -+
24492 -+ return;
24493 -+}
24494 -+
24495 -+static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
24496 -+{
24497 -+ struct conn_table_entry *match, *last = NULL;
24498 -+ unsigned int index;
24499 -+
24500 -+ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
24501 -+ sig->gr_sport, sig->gr_dport,
24502 -+ gr_conn_table_size);
24503 -+
24504 -+ match = gr_conn_table[index];
24505 -+ while (match && !conn_match(match->sig,
24506 -+ sig->gr_saddr, sig->gr_daddr, sig->gr_sport,
24507 -+ sig->gr_dport)) {
24508 -+ last = match;
24509 -+ match = match->next;
24510 -+ }
24511 -+
24512 -+ if (match) {
24513 -+ if (last)
24514 -+ last->next = match->next;
24515 -+ else
24516 -+ gr_conn_table[index] = NULL;
24517 -+ kfree(match);
24518 -+ }
24519 -+
24520 -+ return;
24521 -+}
24522 -+
24523 -+static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
24524 -+ __u16 sport, __u16 dport)
24525 -+{
24526 -+ struct conn_table_entry *match;
24527 -+ unsigned int index;
24528 -+
24529 -+ index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
24530 -+
24531 -+ match = gr_conn_table[index];
24532 -+ while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
24533 -+ match = match->next;
24534 -+
24535 -+ if (match)
24536 -+ return match->sig;
24537 -+ else
24538 -+ return NULL;
24539 -+}
24540 -+
24541 -+#endif
24542 -+
24543 -+void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
24544 -+{
24545 -+#ifdef CONFIG_GRKERNSEC
24546 -+ struct signal_struct *sig = task->signal;
24547 -+ struct conn_table_entry *newent;
24548 -+
24549 -+ newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
24550 -+ if (newent == NULL)
24551 -+ return;
24552 -+ /* no bh lock needed since we are called with bh disabled */
24553 -+ spin_lock(&gr_conn_table_lock);
24554 -+ gr_del_task_from_ip_table_nolock(sig);
24555 -+ sig->gr_saddr = inet->rcv_saddr;
24556 -+ sig->gr_daddr = inet->daddr;
24557 -+ sig->gr_sport = inet->sport;
24558 -+ sig->gr_dport = inet->dport;
24559 -+ gr_add_to_task_ip_table_nolock(sig, newent);
24560 -+ spin_unlock(&gr_conn_table_lock);
24561 -+#endif
24562 -+ return;
24563 -+}
24564 -+
24565 -+void gr_del_task_from_ip_table(struct task_struct *task)
24566 -+{
24567 -+#ifdef CONFIG_GRKERNSEC
24568 -+ spin_lock(&gr_conn_table_lock);
24569 -+ gr_del_task_from_ip_table_nolock(task->signal);
24570 -+ spin_unlock(&gr_conn_table_lock);
24571 -+#endif
24572 -+ return;
24573 -+}
24574 -+
24575 -+void
24576 -+gr_attach_curr_ip(const struct sock *sk)
24577 -+{
24578 -+#ifdef CONFIG_GRKERNSEC
24579 -+ struct signal_struct *p, *set;
24580 -+ const struct inet_sock *inet = inet_sk(sk);
24581 -+
24582 -+ if (unlikely(sk->sk_protocol != IPPROTO_TCP))
24583 -+ return;
24584 -+
24585 -+ set = current->signal;
24586 -+
24587 -+ spin_lock_bh(&gr_conn_table_lock);
24588 -+ p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
24589 -+ inet->dport, inet->sport);
24590 -+ if (unlikely(p != NULL)) {
24591 -+ set->curr_ip = p->curr_ip;
24592 -+ set->used_accept = 1;
24593 -+ gr_del_task_from_ip_table_nolock(p);
24594 -+ spin_unlock_bh(&gr_conn_table_lock);
24595 -+ return;
24596 -+ }
24597 -+ spin_unlock_bh(&gr_conn_table_lock);
24598 -+
24599 -+ set->curr_ip = inet->daddr;
24600 -+ set->used_accept = 1;
24601 -+#endif
24602 -+ return;
24603 -+}
24604 -+
24605 -+int
24606 -+gr_handle_sock_all(const int family, const int type, const int protocol)
24607 -+{
24608 -+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
24609 -+ if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
24610 -+ (family != AF_UNIX) && (family != AF_LOCAL)) {
24611 -+ gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
24612 -+ return -EACCES;
24613 -+ }
24614 -+#endif
24615 -+ return 0;
24616 -+}
24617 -+
24618 -+int
24619 -+gr_handle_sock_server(const struct sockaddr *sck)
24620 -+{
24621 -+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
24622 -+ if (grsec_enable_socket_server &&
24623 -+ in_group_p(grsec_socket_server_gid) &&
24624 -+ sck && (sck->sa_family != AF_UNIX) &&
24625 -+ (sck->sa_family != AF_LOCAL)) {
24626 -+ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
24627 -+ return -EACCES;
24628 -+ }
24629 -+#endif
24630 -+ return 0;
24631 -+}
24632 -+
24633 -+int
24634 -+gr_handle_sock_server_other(const struct sock *sck)
24635 -+{
24636 -+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
24637 -+ if (grsec_enable_socket_server &&
24638 -+ in_group_p(grsec_socket_server_gid) &&
24639 -+ sck && (sck->sk_family != AF_UNIX) &&
24640 -+ (sck->sk_family != AF_LOCAL)) {
24641 -+ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
24642 -+ return -EACCES;
24643 -+ }
24644 -+#endif
24645 -+ return 0;
24646 -+}
24647 -+
24648 -+int
24649 -+gr_handle_sock_client(const struct sockaddr *sck)
24650 -+{
24651 -+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
24652 -+ if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
24653 -+ sck && (sck->sa_family != AF_UNIX) &&
24654 -+ (sck->sa_family != AF_LOCAL)) {
24655 -+ gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
24656 -+ return -EACCES;
24657 -+ }
24658 -+#endif
24659 -+ return 0;
24660 -+}
24661 -+
24662 -+kernel_cap_t
24663 -+gr_cap_rtnetlink(struct sock *sock)
24664 -+{
24665 -+#ifdef CONFIG_GRKERNSEC
24666 -+ if (!gr_acl_is_enabled())
24667 -+ return current->cap_effective;
24668 -+ else if (sock->sk_protocol == NETLINK_ISCSI &&
24669 -+ cap_raised(current->cap_effective, CAP_SYS_ADMIN) &&
24670 -+ gr_task_is_capable(current, CAP_SYS_ADMIN))
24671 -+ return current->cap_effective;
24672 -+ else if (sock->sk_protocol == NETLINK_AUDIT &&
24673 -+ cap_raised(current->cap_effective, CAP_AUDIT_WRITE) &&
24674 -+ gr_task_is_capable(current, CAP_AUDIT_WRITE) &&
24675 -+ cap_raised(current->cap_effective, CAP_AUDIT_CONTROL) &&
24676 -+ gr_task_is_capable(current, CAP_AUDIT_CONTROL))
24677 -+ return current->cap_effective;
24678 -+ else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
24679 -+ gr_task_is_capable(current, CAP_NET_ADMIN))
24680 -+ return current->cap_effective;
24681 -+ else
24682 -+ return __cap_empty_set;
24683 -+#else
24684 -+ return current->cap_effective;
24685 -+#endif
24686 -+}
24687 -diff -urNp linux-2.6.27.6/grsecurity/grsec_sysctl.c linux-2.6.27.6/grsecurity/grsec_sysctl.c
24688 ---- linux-2.6.27.6/grsecurity/grsec_sysctl.c 1969-12-31 19:00:00.000000000 -0500
24689 -+++ linux-2.6.27.6/grsecurity/grsec_sysctl.c 2008-11-18 03:38:45.000000000 -0500
24690 -@@ -0,0 +1,435 @@
24691 -+#include <linux/kernel.h>
24692 -+#include <linux/sched.h>
24693 -+#include <linux/sysctl.h>
24694 -+#include <linux/grsecurity.h>
24695 -+#include <linux/grinternal.h>
24696 -+
24697 -+#ifdef CONFIG_GRKERNSEC_MODSTOP
24698 -+int grsec_modstop;
24699 -+#endif
24700 -+
24701 -+int
24702 -+gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
24703 -+{
24704 -+#ifdef CONFIG_GRKERNSEC_SYSCTL
24705 -+ if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & MAY_WRITE)) {
24706 -+ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
24707 -+ return -EACCES;
24708 -+ }
24709 -+#endif
24710 -+#ifdef CONFIG_GRKERNSEC_MODSTOP
24711 -+ if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
24712 -+ grsec_modstop && (op & MAY_WRITE)) {
24713 -+ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
24714 -+ return -EACCES;
24715 -+ }
24716 -+#endif
24717 -+ return 0;
24718 -+}
24719 -+
24720 -+#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
24721 -+ctl_table grsecurity_table[] = {
24722 -+#ifdef CONFIG_GRKERNSEC_SYSCTL
24723 -+#ifdef CONFIG_GRKERNSEC_LINK
24724 -+ {
24725 -+ .ctl_name = CTL_UNNUMBERED,
24726 -+ .procname = "linking_restrictions",
24727 -+ .data = &grsec_enable_link,
24728 -+ .maxlen = sizeof(int),
24729 -+ .mode = 0600,
24730 -+ .proc_handler = &proc_dointvec,
24731 -+ },
24732 -+#endif
24733 -+#ifdef CONFIG_GRKERNSEC_FIFO
24734 -+ {
24735 -+ .ctl_name = CTL_UNNUMBERED,
24736 -+ .procname = "fifo_restrictions",
24737 -+ .data = &grsec_enable_fifo,
24738 -+ .maxlen = sizeof(int),
24739 -+ .mode = 0600,
24740 -+ .proc_handler = &proc_dointvec,
24741 -+ },
24742 -+#endif
24743 -+#ifdef CONFIG_GRKERNSEC_EXECVE
24744 -+ {
24745 -+ .ctl_name = CTL_UNNUMBERED,
24746 -+ .procname = "execve_limiting",
24747 -+ .data = &grsec_enable_execve,
24748 -+ .maxlen = sizeof(int),
24749 -+ .mode = 0600,
24750 -+ .proc_handler = &proc_dointvec,
24751 -+ },
24752 -+#endif
24753 -+#ifdef CONFIG_GRKERNSEC_EXECLOG
24754 -+ {
24755 -+ .ctl_name = CTL_UNNUMBERED,
24756 -+ .procname = "exec_logging",
24757 -+ .data = &grsec_enable_execlog,
24758 -+ .maxlen = sizeof(int),
24759 -+ .mode = 0600,
24760 -+ .proc_handler = &proc_dointvec,
24761 -+ },
24762 -+#endif
24763 -+#ifdef CONFIG_GRKERNSEC_SIGNAL
24764 -+ {
24765 -+ .ctl_name = CTL_UNNUMBERED,
24766 -+ .procname = "signal_logging",
24767 -+ .data = &grsec_enable_signal,
24768 -+ .maxlen = sizeof(int),
24769 -+ .mode = 0600,
24770 -+ .proc_handler = &proc_dointvec,
24771 -+ },
24772 -+#endif
24773 -+#ifdef CONFIG_GRKERNSEC_FORKFAIL
24774 -+ {
24775 -+ .ctl_name = CTL_UNNUMBERED,
24776 -+ .procname = "forkfail_logging",
24777 -+ .data = &grsec_enable_forkfail,
24778 -+ .maxlen = sizeof(int),
24779 -+ .mode = 0600,
24780 -+ .proc_handler = &proc_dointvec,
24781 -+ },
24782 -+#endif
24783 -+#ifdef CONFIG_GRKERNSEC_TIME
24784 -+ {
24785 -+ .ctl_name = CTL_UNNUMBERED,
24786 -+ .procname = "timechange_logging",
24787 -+ .data = &grsec_enable_time,
24788 -+ .maxlen = sizeof(int),
24789 -+ .mode = 0600,
24790 -+ .proc_handler = &proc_dointvec,
24791 -+ },
24792 -+#endif
24793 -+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
24794 -+ {
24795 -+ .ctl_name = CTL_UNNUMBERED,
24796 -+ .procname = "chroot_deny_shmat",
24797 -+ .data = &grsec_enable_chroot_shmat,
24798 -+ .maxlen = sizeof(int),
24799 -+ .mode = 0600,
24800 -+ .proc_handler = &proc_dointvec,
24801 -+ },
24802 -+#endif
24803 -+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
24804 -+ {
24805 -+ .ctl_name = CTL_UNNUMBERED,
24806 -+ .procname = "chroot_deny_unix",
24807 -+ .data = &grsec_enable_chroot_unix,
24808 -+ .maxlen = sizeof(int),
24809 -+ .mode = 0600,
24810 -+ .proc_handler = &proc_dointvec,
24811 -+ },
24812 -+#endif
24813 -+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
24814 -+ {
24815 -+ .ctl_name = CTL_UNNUMBERED,
24816 -+ .procname = "chroot_deny_mount",
24817 -+ .data = &grsec_enable_chroot_mount,
24818 -+ .maxlen = sizeof(int),
24819 -+ .mode = 0600,
24820 -+ .proc_handler = &proc_dointvec,
24821 -+ },
24822 -+#endif
24823 -+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
24824 -+ {
24825 -+ .ctl_name = CTL_UNNUMBERED,
24826 -+ .procname = "chroot_deny_fchdir",
24827 -+ .data = &grsec_enable_chroot_fchdir,
24828 -+ .maxlen = sizeof(int),
24829 -+ .mode = 0600,
24830 -+ .proc_handler = &proc_dointvec,
24831 -+ },
24832 -+#endif
24833 -+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
24834 -+ {
24835 -+ .ctl_name = CTL_UNNUMBERED,
24836 -+ .procname = "chroot_deny_chroot",
24837 -+ .data = &grsec_enable_chroot_double,
24838 -+ .maxlen = sizeof(int),
24839 -+ .mode = 0600,
24840 -+ .proc_handler = &proc_dointvec,
24841 -+ },
24842 -+#endif
24843 -+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
24844 -+ {
24845 -+ .ctl_name = CTL_UNNUMBERED,
24846 -+ .procname = "chroot_deny_pivot",
24847 -+ .data = &grsec_enable_chroot_pivot,
24848 -+ .maxlen = sizeof(int),
24849 -+ .mode = 0600,
24850 -+ .proc_handler = &proc_dointvec,
24851 -+ },
24852 -+#endif
24853 -+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
24854 -+ {
24855 -+ .ctl_name = CTL_UNNUMBERED,
24856 -+ .procname = "chroot_enforce_chdir",
24857 -+ .data = &grsec_enable_chroot_chdir,
24858 -+ .maxlen = sizeof(int),
24859 -+ .mode = 0600,
24860 -+ .proc_handler = &proc_dointvec,
24861 -+ },
24862 -+#endif
24863 -+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
24864 -+ {
24865 -+ .ctl_name = CTL_UNNUMBERED,
24866 -+ .procname = "chroot_deny_chmod",
24867 -+ .data = &grsec_enable_chroot_chmod,
24868 -+ .maxlen = sizeof(int),
24869 -+ .mode = 0600,
24870 -+ .proc_handler = &proc_dointvec,
24871 -+ },
24872 -+#endif
24873 -+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
24874 -+ {
24875 -+ .ctl_name = CTL_UNNUMBERED,
24876 -+ .procname = "chroot_deny_mknod",
24877 -+ .data = &grsec_enable_chroot_mknod,
24878 -+ .maxlen = sizeof(int),
24879 -+ .mode = 0600,
24880 -+ .proc_handler = &proc_dointvec,
24881 -+ },
24882 -+#endif
24883 -+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
24884 -+ {
24885 -+ .ctl_name = CTL_UNNUMBERED,
24886 -+ .procname = "chroot_restrict_nice",
24887 -+ .data = &grsec_enable_chroot_nice,
24888 -+ .maxlen = sizeof(int),
24889 -+ .mode = 0600,
24890 -+ .proc_handler = &proc_dointvec,
24891 -+ },
24892 -+#endif
24893 -+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
24894 -+ {
24895 -+ .ctl_name = CTL_UNNUMBERED,
24896 -+ .procname = "chroot_execlog",
24897 -+ .data = &grsec_enable_chroot_execlog,
24898 -+ .maxlen = sizeof(int),
24899 -+ .mode = 0600,
24900 -+ .proc_handler = &proc_dointvec,
24901 -+ },
24902 -+#endif
24903 -+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
24904 -+ {
24905 -+ .ctl_name = CTL_UNNUMBERED,
24906 -+ .procname = "chroot_caps",
24907 -+ .data = &grsec_enable_chroot_caps,
24908 -+ .maxlen = sizeof(int),
24909 -+ .mode = 0600,
24910 -+ .proc_handler = &proc_dointvec,
24911 -+ },
24912 -+#endif
24913 -+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
24914 -+ {
24915 -+ .ctl_name = CTL_UNNUMBERED,
24916 -+ .procname = "chroot_deny_sysctl",
24917 -+ .data = &grsec_enable_chroot_sysctl,
24918 -+ .maxlen = sizeof(int),
24919 -+ .mode = 0600,
24920 -+ .proc_handler = &proc_dointvec,
24921 -+ },
24922 -+#endif
24923 -+#ifdef CONFIG_GRKERNSEC_TPE
24924 -+ {
24925 -+ .ctl_name = CTL_UNNUMBERED,
24926 -+ .procname = "tpe",
24927 -+ .data = &grsec_enable_tpe,
24928 -+ .maxlen = sizeof(int),
24929 -+ .mode = 0600,
24930 -+ .proc_handler = &proc_dointvec,
24931 -+ },
24932 -+ {
24933 -+ .ctl_name = CTL_UNNUMBERED,
24934 -+ .procname = "tpe_gid",
24935 -+ .data = &grsec_tpe_gid,
24936 -+ .maxlen = sizeof(int),
24937 -+ .mode = 0600,
24938 -+ .proc_handler = &proc_dointvec,
24939 -+ },
24940 -+#endif
24941 -+#ifdef CONFIG_GRKERNSEC_TPE_ALL
24942 -+ {
24943 -+ .ctl_name = CTL_UNNUMBERED,
24944 -+ .procname = "tpe_restrict_all",
24945 -+ .data = &grsec_enable_tpe_all,
24946 -+ .maxlen = sizeof(int),
24947 -+ .mode = 0600,
24948 -+ .proc_handler = &proc_dointvec,
24949 -+ },
24950 -+#endif
24951 -+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
24952 -+ {
24953 -+ .ctl_name = CTL_UNNUMBERED,
24954 -+ .procname = "socket_all",
24955 -+ .data = &grsec_enable_socket_all,
24956 -+ .maxlen = sizeof(int),
24957 -+ .mode = 0600,
24958 -+ .proc_handler = &proc_dointvec,
24959 -+ },
24960 -+ {
24961 -+ .ctl_name = CTL_UNNUMBERED,
24962 -+ .procname = "socket_all_gid",
24963 -+ .data = &grsec_socket_all_gid,
24964 -+ .maxlen = sizeof(int),
24965 -+ .mode = 0600,
24966 -+ .proc_handler = &proc_dointvec,
24967 -+ },
24968 -+#endif
24969 -+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
24970 -+ {
24971 -+ .ctl_name = CTL_UNNUMBERED,
24972 -+ .procname = "socket_client",
24973 -+ .data = &grsec_enable_socket_client,
24974 -+ .maxlen = sizeof(int),
24975 -+ .mode = 0600,
24976 -+ .proc_handler = &proc_dointvec,
24977 -+ },
24978 -+ {
24979 -+ .ctl_name = CTL_UNNUMBERED,
24980 -+ .procname = "socket_client_gid",
24981 -+ .data = &grsec_socket_client_gid,
24982 -+ .maxlen = sizeof(int),
24983 -+ .mode = 0600,
24984 -+ .proc_handler = &proc_dointvec,
24985 -+ },
24986 -+#endif
24987 -+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
24988 -+ {
24989 -+ .ctl_name = CTL_UNNUMBERED,
24990 -+ .procname = "socket_server",
24991 -+ .data = &grsec_enable_socket_server,
24992 -+ .maxlen = sizeof(int),
24993 -+ .mode = 0600,
24994 -+ .proc_handler = &proc_dointvec,
24995 -+ },
24996 -+ {
24997 -+ .ctl_name = CTL_UNNUMBERED,
24998 -+ .procname = "socket_server_gid",
24999 -+ .data = &grsec_socket_server_gid,
25000 -+ .maxlen = sizeof(int),
25001 -+ .mode = 0600,
25002 -+ .proc_handler = &proc_dointvec,
25003 -+ },
25004 -+#endif
25005 -+#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
25006 -+ {
25007 -+ .ctl_name = CTL_UNNUMBERED,
25008 -+ .procname = "audit_group",
25009 -+ .data = &grsec_enable_group,
25010 -+ .maxlen = sizeof(int),
25011 -+ .mode = 0600,
25012 -+ .proc_handler = &proc_dointvec,
25013 -+ },
25014 -+ {
25015 -+ .ctl_name = CTL_UNNUMBERED,
25016 -+ .procname = "audit_gid",
25017 -+ .data = &grsec_audit_gid,
25018 -+ .maxlen = sizeof(int),
25019 -+ .mode = 0600,
25020 -+ .proc_handler = &proc_dointvec,
25021 -+ },
25022 -+#endif
25023 -+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
25024 -+ {
25025 -+ .ctl_name = CTL_UNNUMBERED,
25026 -+ .procname = "audit_chdir",
25027 -+ .data = &grsec_enable_chdir,
25028 -+ .maxlen = sizeof(int),
25029 -+ .mode = 0600,
25030 -+ .proc_handler = &proc_dointvec,
25031 -+ },
25032 -+#endif
25033 -+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
25034 -+ {
25035 -+ .ctl_name = CTL_UNNUMBERED,
25036 -+ .procname = "audit_mount",
25037 -+ .data = &grsec_enable_mount,
25038 -+ .maxlen = sizeof(int),
25039 -+ .mode = 0600,
25040 -+ .proc_handler = &proc_dointvec,
25041 -+ },
25042 -+#endif
25043 -+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
25044 -+ {
25045 -+ .ctl_name = CTL_UNNUMBERED,
25046 -+ .procname = "audit_ipc",
25047 -+ .data = &grsec_enable_audit_ipc,
25048 -+ .maxlen = sizeof(int),
25049 -+ .mode = 0600,
25050 -+ .proc_handler = &proc_dointvec,
25051 -+ },
25052 -+#endif
25053 -+#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
25054 -+ {
25055 -+ .ctl_name = CTL_UNNUMBERED,
25056 -+ .procname = "audit_textrel",
25057 -+ .data = &grsec_enable_audit_textrel,
25058 -+ .maxlen = sizeof(int),
25059 -+ .mode = 0600,
25060 -+ .proc_handler = &proc_dointvec,
25061 -+ },
25062 -+#endif
25063 -+#ifdef CONFIG_GRKERNSEC_DMESG
25064 -+ {
25065 -+ .ctl_name = CTL_UNNUMBERED,
25066 -+ .procname = "dmesg",
25067 -+ .data = &grsec_enable_dmesg,
25068 -+ .maxlen = sizeof(int),
25069 -+ .mode = 0600,
25070 -+ .proc_handler = &proc_dointvec,
25071 -+ },
25072 -+#endif
25073 -+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
25074 -+ {
25075 -+ .ctl_name = CTL_UNNUMBERED,
25076 -+ .procname = "chroot_findtask",
25077 -+ .data = &grsec_enable_chroot_findtask,
25078 -+ .maxlen = sizeof(int),
25079 -+ .mode = 0600,
25080 -+ .proc_handler = &proc_dointvec,
25081 -+ },
25082 -+#endif
25083 -+#ifdef CONFIG_GRKERNSEC_RESLOG
25084 -+ {
25085 -+ .ctl_name = CTL_UNNUMBERED,
25086 -+ .procname = "resource_logging",
25087 -+ .data = &grsec_resource_logging,
25088 -+ .maxlen = sizeof(int),
25089 -+ .mode = 0600,
25090 -+ .proc_handler = &proc_dointvec,
25091 -+ },
25092 -+#endif
25093 -+ {
25094 -+ .ctl_name = CTL_UNNUMBERED,
25095 -+ .procname = "grsec_lock",
25096 -+ .data = &grsec_lock,
25097 -+ .maxlen = sizeof(int),
25098 -+ .mode = 0600,
25099 -+ .proc_handler = &proc_dointvec,
25100 -+ },
25101 -+#endif
25102 -+#ifdef CONFIG_GRKERNSEC_MODSTOP
25103 -+ {
25104 -+ .ctl_name = CTL_UNNUMBERED,
25105 -+ .procname = "disable_modules",
25106 -+ .data = &grsec_modstop,
25107 -+ .maxlen = sizeof(int),
25108 -+ .mode = 0600,
25109 -+ .proc_handler = &proc_dointvec,
25110 -+ },
25111 -+#endif
25112 -+ { .ctl_name = 0 }
25113 -+};
25114 -+#endif
25115 -+
25116 -+int gr_check_modstop(void)
25117 -+{
25118 -+#ifdef CONFIG_GRKERNSEC_MODSTOP
25119 -+ if (grsec_modstop == 1) {
25120 -+ gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
25121 -+ return 1;
25122 -+ }
25123 -+#endif
25124 -+ return 0;
25125 -+}
25126 -diff -urNp linux-2.6.27.6/grsecurity/grsec_textrel.c linux-2.6.27.6/grsecurity/grsec_textrel.c
25127 ---- linux-2.6.27.6/grsecurity/grsec_textrel.c 1969-12-31 19:00:00.000000000 -0500
25128 -+++ linux-2.6.27.6/grsecurity/grsec_textrel.c 2008-11-18 03:38:45.000000000 -0500
25129 -@@ -0,0 +1,16 @@
25130 -+#include <linux/kernel.h>
25131 -+#include <linux/sched.h>
25132 -+#include <linux/mm.h>
25133 -+#include <linux/file.h>
25134 -+#include <linux/grinternal.h>
25135 -+#include <linux/grsecurity.h>
25136 -+
25137 -+void
25138 -+gr_log_textrel(struct vm_area_struct * vma)
25139 -+{
25140 -+#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
25141 -+ if (grsec_enable_audit_textrel)
25142 -+ gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
25143 -+#endif
25144 -+ return;
25145 -+}
25146 -diff -urNp linux-2.6.27.6/grsecurity/grsec_time.c linux-2.6.27.6/grsecurity/grsec_time.c
25147 ---- linux-2.6.27.6/grsecurity/grsec_time.c 1969-12-31 19:00:00.000000000 -0500
25148 -+++ linux-2.6.27.6/grsecurity/grsec_time.c 2008-11-18 03:38:45.000000000 -0500
25149 -@@ -0,0 +1,13 @@
25150 -+#include <linux/kernel.h>
25151 -+#include <linux/sched.h>
25152 -+#include <linux/grinternal.h>
25153 -+
25154 -+void
25155 -+gr_log_timechange(void)
25156 -+{
25157 -+#ifdef CONFIG_GRKERNSEC_TIME
25158 -+ if (grsec_enable_time)
25159 -+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
25160 -+#endif
25161 -+ return;
25162 -+}
25163 -diff -urNp linux-2.6.27.6/grsecurity/grsec_tpe.c linux-2.6.27.6/grsecurity/grsec_tpe.c
25164 ---- linux-2.6.27.6/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500
25165 -+++ linux-2.6.27.6/grsecurity/grsec_tpe.c 2008-11-18 03:38:45.000000000 -0500
25166 -@@ -0,0 +1,37 @@
25167 -+#include <linux/kernel.h>
25168 -+#include <linux/sched.h>
25169 -+#include <linux/file.h>
25170 -+#include <linux/fs.h>
25171 -+#include <linux/grinternal.h>
25172 -+
25173 -+extern int gr_acl_tpe_check(void);
25174 -+
25175 -+int
25176 -+gr_tpe_allow(const struct file *file)
25177 -+{
25178 -+#ifdef CONFIG_GRKERNSEC
25179 -+ struct inode *inode = file->f_path.dentry->d_parent->d_inode;
25180 -+
25181 -+ if (current->uid && ((grsec_enable_tpe &&
25182 -+#ifdef CONFIG_GRKERNSEC_TPE_INVERT
25183 -+ !in_group_p(grsec_tpe_gid)
25184 -+#else
25185 -+ in_group_p(grsec_tpe_gid)
25186 -+#endif
25187 -+ ) || gr_acl_tpe_check()) &&
25188 -+ (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
25189 -+ (inode->i_mode & S_IWOTH))))) {
25190 -+ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
25191 -+ return 0;
25192 -+ }
25193 -+#ifdef CONFIG_GRKERNSEC_TPE_ALL
25194 -+ if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
25195 -+ ((inode->i_uid && (inode->i_uid != current->uid)) ||
25196 -+ (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
25197 -+ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
25198 -+ return 0;
25199 -+ }
25200 -+#endif
25201 -+#endif
25202 -+ return 1;
25203 -+}
25204 -diff -urNp linux-2.6.27.6/grsecurity/grsum.c linux-2.6.27.6/grsecurity/grsum.c
25205 ---- linux-2.6.27.6/grsecurity/grsum.c 1969-12-31 19:00:00.000000000 -0500
25206 -+++ linux-2.6.27.6/grsecurity/grsum.c 2008-11-18 03:38:45.000000000 -0500
25207 -@@ -0,0 +1,59 @@
25208 -+#include <linux/err.h>
25209 -+#include <linux/kernel.h>
25210 -+#include <linux/sched.h>
25211 -+#include <linux/mm.h>
25212 -+#include <linux/scatterlist.h>
25213 -+#include <linux/crypto.h>
25214 -+#include <linux/gracl.h>
25215 -+
25216 -+
25217 -+#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
25218 -+#error "crypto and sha256 must be built into the kernel"
25219 -+#endif
25220 -+
25221 -+int
25222 -+chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
25223 -+{
25224 -+ char *p;
25225 -+ struct crypto_hash *tfm;
25226 -+ struct hash_desc desc;
25227 -+ struct scatterlist sg;
25228 -+ unsigned char temp_sum[GR_SHA_LEN];
25229 -+ volatile int retval = 0;
25230 -+ volatile int dummy = 0;
25231 -+ unsigned int i;
25232 -+
25233 -+ tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
25234 -+ if (IS_ERR(tfm)) {
25235 -+ /* should never happen, since sha256 should be built in */
25236 -+ return 1;
25237 -+ }
25238 -+
25239 -+ desc.tfm = tfm;
25240 -+ desc.flags = 0;
25241 -+
25242 -+ crypto_hash_init(&desc);
25243 -+
25244 -+ p = salt;
25245 -+ sg_set_buf(&sg, p, GR_SALT_LEN);
25246 -+ crypto_hash_update(&desc, &sg, sg.length);
25247 -+
25248 -+ p = entry->pw;
25249 -+ sg_set_buf(&sg, p, strlen(p));
25250 -+
25251 -+ crypto_hash_update(&desc, &sg, sg.length);
25252 -+
25253 -+ crypto_hash_final(&desc, temp_sum);
25254 -+
25255 -+ memset(entry->pw, 0, GR_PW_LEN);
25256 -+
25257 -+ for (i = 0; i < GR_SHA_LEN; i++)
25258 -+ if (sum[i] != temp_sum[i])
25259 -+ retval = 1;
25260 -+ else
25261 -+ dummy = 1; // waste a cycle
25262 -+
25263 -+ crypto_free_hash(tfm);
25264 -+
25265 -+ return retval;
25266 -+}
25267 -diff -urNp linux-2.6.27.6/grsecurity/Kconfig linux-2.6.27.6/grsecurity/Kconfig
25268 ---- linux-2.6.27.6/grsecurity/Kconfig 1969-12-31 19:00:00.000000000 -0500
25269 -+++ linux-2.6.27.6/grsecurity/Kconfig 2008-11-18 03:38:45.000000000 -0500
25270 -@@ -0,0 +1,863 @@
25271 -+#
25272 -+# grecurity configuration
25273 -+#
25274 -+
25275 -+menu "Grsecurity"
25276 -+
25277 -+config GRKERNSEC
25278 -+ bool "Grsecurity"
25279 -+ select CRYPTO
25280 -+ select CRYPTO_SHA256
25281 -+ select SECURITY
25282 -+ select SECURITY_CAPABILITIES
25283 -+ help
25284 -+ If you say Y here, you will be able to configure many features
25285 -+ that will enhance the security of your system. It is highly
25286 -+ recommended that you say Y here and read through the help
25287 -+ for each option so that you fully understand the features and
25288 -+ can evaluate their usefulness for your machine.
25289 -+
25290 -+choice
25291 -+ prompt "Security Level"
25292 -+ depends on GRKERNSEC
25293 -+ default GRKERNSEC_CUSTOM
25294 -+
25295 -+config GRKERNSEC_LOW
25296 -+ bool "Low"
25297 -+ select GRKERNSEC_LINK
25298 -+ select GRKERNSEC_FIFO
25299 -+ select GRKERNSEC_EXECVE
25300 -+ select GRKERNSEC_RANDNET
25301 -+ select GRKERNSEC_DMESG
25302 -+ select GRKERNSEC_CHROOT_CHDIR
25303 -+ select GRKERNSEC_MODSTOP if (MODULES)
25304 -+
25305 -+ help
25306 -+ If you choose this option, several of the grsecurity options will
25307 -+ be enabled that will give you greater protection against a number
25308 -+ of attacks, while assuring that none of your software will have any
25309 -+ conflicts with the additional security measures. If you run a lot
25310 -+ of unusual software, or you are having problems with the higher
25311 -+ security levels, you should say Y here. With this option, the
25312 -+ following features are enabled:
25313 -+
25314 -+ - Linking restrictions
25315 -+ - FIFO restrictions
25316 -+ - Enforcing RLIMIT_NPROC on execve
25317 -+ - Restricted dmesg
25318 -+ - Enforced chdir("/") on chroot
25319 -+ - Runtime module disabling
25320 -+
25321 -+config GRKERNSEC_MEDIUM
25322 -+ bool "Medium"
25323 -+ select PAX
25324 -+ select PAX_EI_PAX
25325 -+ select PAX_PT_PAX_FLAGS
25326 -+ select PAX_HAVE_ACL_FLAGS
25327 -+ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
25328 -+ select GRKERNSEC_CHROOT_SYSCTL
25329 -+ select GRKERNSEC_LINK
25330 -+ select GRKERNSEC_FIFO
25331 -+ select GRKERNSEC_EXECVE
25332 -+ select GRKERNSEC_DMESG
25333 -+ select GRKERNSEC_RANDNET
25334 -+ select GRKERNSEC_FORKFAIL
25335 -+ select GRKERNSEC_TIME
25336 -+ select GRKERNSEC_SIGNAL
25337 -+ select GRKERNSEC_CHROOT
25338 -+ select GRKERNSEC_CHROOT_UNIX
25339 -+ select GRKERNSEC_CHROOT_MOUNT
25340 -+ select GRKERNSEC_CHROOT_PIVOT
25341 -+ select GRKERNSEC_CHROOT_DOUBLE
25342 -+ select GRKERNSEC_CHROOT_CHDIR
25343 -+ select GRKERNSEC_CHROOT_MKNOD
25344 -+ select GRKERNSEC_PROC
25345 -+ select GRKERNSEC_PROC_USERGROUP
25346 -+ select GRKERNSEC_MODSTOP if (MODULES)
25347 -+ select PAX_RANDUSTACK
25348 -+ select PAX_ASLR
25349 -+ select PAX_RANDMMAP
25350 -+ select PAX_REFCOUNT
25351 -+
25352 -+ help
25353 -+ If you say Y here, several features in addition to those included
25354 -+ in the low additional security level will be enabled. These
25355 -+ features provide even more security to your system, though in rare
25356 -+ cases they may be incompatible with very old or poorly written
25357 -+ software. If you enable this option, make sure that your auth
25358 -+ service (identd) is running as gid 1001. With this option,
25359 -+ the following features (in addition to those provided in the
25360 -+ low additional security level) will be enabled:
25361 -+
25362 -+ - Failed fork logging
25363 -+ - Time change logging
25364 -+ - Signal logging
25365 -+ - Deny mounts in chroot
25366 -+ - Deny double chrooting
25367 -+ - Deny sysctl writes in chroot
25368 -+ - Deny mknod in chroot
25369 -+ - Deny access to abstract AF_UNIX sockets out of chroot
25370 -+ - Deny pivot_root in chroot
25371 -+ - Denied writes of /dev/kmem, /dev/mem, and /dev/port
25372 -+ - /proc restrictions with special GID set to 10 (usually wheel)
25373 -+ - Address Space Layout Randomization (ASLR)
25374 -+
25375 -+config GRKERNSEC_HIGH
25376 -+ bool "High"
25377 -+ select GRKERNSEC_LINK
25378 -+ select GRKERNSEC_FIFO
25379 -+ select GRKERNSEC_EXECVE
25380 -+ select GRKERNSEC_DMESG
25381 -+ select GRKERNSEC_FORKFAIL
25382 -+ select GRKERNSEC_TIME
25383 -+ select GRKERNSEC_SIGNAL
25384 -+ select GRKERNSEC_CHROOT_SHMAT
25385 -+ select GRKERNSEC_CHROOT_UNIX
25386 -+ select GRKERNSEC_CHROOT_MOUNT
25387 -+ select GRKERNSEC_CHROOT_FCHDIR
25388 -+ select GRKERNSEC_CHROOT_PIVOT
25389 -+ select GRKERNSEC_CHROOT_DOUBLE
25390 -+ select GRKERNSEC_CHROOT_CHDIR
25391 -+ select GRKERNSEC_CHROOT_MKNOD
25392 -+ select GRKERNSEC_CHROOT_CAPS
25393 -+ select GRKERNSEC_CHROOT_SYSCTL
25394 -+ select GRKERNSEC_CHROOT_FINDTASK
25395 -+ select GRKERNSEC_PROC
25396 -+ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
25397 -+ select GRKERNSEC_HIDESYM
25398 -+ select GRKERNSEC_BRUTE
25399 -+ select GRKERNSEC_PROC_USERGROUP
25400 -+ select GRKERNSEC_KMEM
25401 -+ select GRKERNSEC_RESLOG
25402 -+ select GRKERNSEC_RANDNET
25403 -+ select GRKERNSEC_PROC_ADD
25404 -+ select GRKERNSEC_CHROOT_CHMOD
25405 -+ select GRKERNSEC_CHROOT_NICE
25406 -+ select GRKERNSEC_AUDIT_MOUNT
25407 -+ select GRKERNSEC_MODSTOP if (MODULES)
25408 -+ select PAX
25409 -+ select PAX_RANDUSTACK
25410 -+ select PAX_ASLR
25411 -+ select PAX_RANDMMAP
25412 -+ select PAX_NOEXEC
25413 -+ select PAX_MPROTECT
25414 -+ select PAX_EI_PAX
25415 -+ select PAX_PT_PAX_FLAGS
25416 -+ select PAX_HAVE_ACL_FLAGS
25417 -+ select PAX_KERNEXEC if (X86 && !EFI && !COMPAT_VDSO && !PARAVIRT && (!X86_32 || X86_WP_WORKS_OK))
25418 -+ select PAX_MEMORY_UDEREF if (!X86_64 && !COMPAT_VDSO)
25419 -+ select PAX_RANDKSTACK if (X86_TSC && !X86_64)
25420 -+ select PAX_SEGMEXEC if (X86 && !X86_64)
25421 -+ select PAX_PAGEEXEC if (!X86)
25422 -+ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
25423 -+ select PAX_DLRESOLVE if (SPARC32 || SPARC64)
25424 -+ select PAX_SYSCALL if (PPC32)
25425 -+ select PAX_EMUTRAMP if (PARISC)
25426 -+ select PAX_EMUSIGRT if (PARISC)
25427 -+ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
25428 -+ select PAX_REFCOUNT
25429 -+ help
25430 -+ If you say Y here, many of the features of grsecurity will be
25431 -+ enabled, which will protect you against many kinds of attacks
25432 -+ against your system. The heightened security comes at a cost
25433 -+ of an increased chance of incompatibilities with rare software
25434 -+ on your machine. Since this security level enables PaX, you should
25435 -+ view <http://pax.grsecurity.net> and read about the PaX
25436 -+ project. While you are there, download chpax and run it on
25437 -+ binaries that cause problems with PaX. Also remember that
25438 -+ since the /proc restrictions are enabled, you must run your
25439 -+ identd as gid 1001. This security level enables the following
25440 -+ features in addition to those listed in the low and medium
25441 -+ security levels:
25442 -+
25443 -+ - Additional /proc restrictions
25444 -+ - Chmod restrictions in chroot
25445 -+ - No signals, ptrace, or viewing of processes outside of chroot
25446 -+ - Capability restrictions in chroot
25447 -+ - Deny fchdir out of chroot
25448 -+ - Priority restrictions in chroot
25449 -+ - Segmentation-based implementation of PaX
25450 -+ - Mprotect restrictions
25451 -+ - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
25452 -+ - Kernel stack randomization
25453 -+ - Mount/unmount/remount logging
25454 -+ - Kernel symbol hiding
25455 -+ - Prevention of memory exhaustion-based exploits
25456 -+config GRKERNSEC_CUSTOM
25457 -+ bool "Custom"
25458 -+ help
25459 -+ If you say Y here, you will be able to configure every grsecurity
25460 -+ option, which allows you to enable many more features that aren't
25461 -+ covered in the basic security levels. These additional features
25462 -+ include TPE, socket restrictions, and the sysctl system for
25463 -+ grsecurity. It is advised that you read through the help for
25464 -+ each option to determine its usefulness in your situation.
25465 -+
25466 -+endchoice
25467 -+
25468 -+menu "Address Space Protection"
25469 -+depends on GRKERNSEC
25470 -+
25471 -+config GRKERNSEC_KMEM
25472 -+ bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
25473 -+ help
25474 -+ If you say Y here, /dev/kmem and /dev/mem won't be allowed to
25475 -+ be written to via mmap or otherwise to modify the running kernel.
25476 -+ /dev/port will also not be allowed to be opened. If you have module
25477 -+ support disabled, enabling this will close up four ways that are
25478 -+ currently used to insert malicious code into the running kernel.
25479 -+ Even with all these features enabled, we still highly recommend that
25480 -+ you use the RBAC system, as it is still possible for an attacker to
25481 -+ modify the running kernel through privileged I/O granted by ioperm/iopl.
25482 -+ If you are not using XFree86, you may be able to stop this additional
25483 -+ case by enabling the 'Disable privileged I/O' option. Though nothing
25484 -+ legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
25485 -+ but only to video memory, which is the only writing we allow in this
25486 -+ case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
25487 -+ not be allowed to mprotect it with PROT_WRITE later.
25488 -+ It is highly recommended that you say Y here if you meet all the
25489 -+ conditions above.
25490 -+
25491 -+config GRKERNSEC_IO
25492 -+ bool "Disable privileged I/O"
25493 -+ depends on X86
25494 -+ select RTC
25495 -+ help
25496 -+ If you say Y here, all ioperm and iopl calls will return an error.
25497 -+ Ioperm and iopl can be used to modify the running kernel.
25498 -+ Unfortunately, some programs need this access to operate properly,
25499 -+ the most notable of which are XFree86 and hwclock. hwclock can be
25500 -+ remedied by having RTC support in the kernel, so CONFIG_RTC is
25501 -+ enabled if this option is enabled, to ensure that hwclock operates
25502 -+ correctly. XFree86 still will not operate correctly with this option
25503 -+ enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86
25504 -+ and you still want to protect your kernel against modification,
25505 -+ use the RBAC system.
25506 -+
25507 -+config GRKERNSEC_PROC_MEMMAP
25508 -+ bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
25509 -+ depends on PAX_NOEXEC || PAX_ASLR
25510 -+ help
25511 -+ If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
25512 -+ give no information about the addresses of its mappings if
25513 -+ PaX features that rely on random addresses are enabled on the task.
25514 -+ If you use PaX it is greatly recommended that you say Y here as it
25515 -+ closes up a hole that makes the full ASLR useless for suid
25516 -+ binaries.
25517 -+
25518 -+config GRKERNSEC_BRUTE
25519 -+ bool "Deter exploit bruteforcing"
25520 -+ help
25521 -+ If you say Y here, attempts to bruteforce exploits against forking
25522 -+ daemons such as apache or sshd will be deterred. When a child of a
25523 -+ forking daemon is killed by PaX or crashes due to an illegal
25524 -+ instruction, the parent process will be delayed 30 seconds upon every
25525 -+ subsequent fork until the administrator is able to assess the
25526 -+ situation and restart the daemon. It is recommended that you also
25527 -+ enable signal logging in the auditing section so that logs are
25528 -+ generated when a process performs an illegal instruction.
25529 -+
25530 -+config GRKERNSEC_MODSTOP
25531 -+ bool "Runtime module disabling"
25532 -+ depends on MODULES
25533 -+ help
25534 -+ If you say Y here, you will be able to disable the ability to (un)load
25535 -+ modules at runtime. This feature is useful if you need the ability
25536 -+ to load kernel modules at boot time, but do not want to allow an
25537 -+ attacker to load a rootkit kernel module into the system, or to remove
25538 -+ a loaded kernel module important to system functioning. You should
25539 -+ enable the /dev/mem protection feature as well, since rootkits can be
25540 -+ inserted into the kernel via other methods than kernel modules. Since
25541 -+ an untrusted module could still be loaded by modifying init scripts and
25542 -+ rebooting the system, it is also recommended that you enable the RBAC
25543 -+ system. If you enable this option, a sysctl option with name
25544 -+ "disable_modules" will be created. Setting this option to "1" disables
25545 -+ module loading. After this option is set, no further writes to it are
25546 -+ allowed until the system is rebooted.
25547 -+
25548 -+config GRKERNSEC_HIDESYM
25549 -+ bool "Hide kernel symbols"
25550 -+ help
25551 -+ If you say Y here, getting information on loaded modules, and
25552 -+ displaying all kernel symbols through a syscall will be restricted
25553 -+ to users with CAP_SYS_MODULE. This option is only effective
25554 -+ provided the following conditions are met:
25555 -+ 1) The kernel using grsecurity is not precompiled by some distribution
25556 -+ 2) You are using the RBAC system and hiding other files such as your
25557 -+ kernel image and System.map
25558 -+ 3) You have the additional /proc restrictions enabled, which removes
25559 -+ /proc/kcore
25560 -+ If the above conditions are met, this option will aid to provide a
25561 -+ useful protection against local and remote kernel exploitation of
25562 -+ overflows and arbitrary read/write vulnerabilities.
25563 -+
25564 -+endmenu
25565 -+menu "Role Based Access Control Options"
25566 -+depends on GRKERNSEC
25567 -+
25568 -+config GRKERNSEC_ACL_HIDEKERN
25569 -+ bool "Hide kernel processes"
25570 -+ help
25571 -+ If you say Y here, all kernel threads will be hidden to all
25572 -+ processes but those whose subject has the "view hidden processes"
25573 -+ flag.
25574 -+
25575 -+config GRKERNSEC_ACL_MAXTRIES
25576 -+ int "Maximum tries before password lockout"
25577 -+ default 3
25578 -+ help
25579 -+ This option enforces the maximum number of times a user can attempt
25580 -+ to authorize themselves with the grsecurity RBAC system before being
25581 -+ denied the ability to attempt authorization again for a specified time.
25582 -+ The lower the number, the harder it will be to brute-force a password.
25583 -+
25584 -+config GRKERNSEC_ACL_TIMEOUT
25585 -+ int "Time to wait after max password tries, in seconds"
25586 -+ default 30
25587 -+ help
25588 -+ This option specifies the time the user must wait after attempting to
25589 -+ authorize to the RBAC system with the maximum number of invalid
25590 -+ passwords. The higher the number, the harder it will be to brute-force
25591 -+ a password.
25592 -+
25593 -+endmenu
25594 -+menu "Filesystem Protections"
25595 -+depends on GRKERNSEC
25596 -+
25597 -+config GRKERNSEC_PROC
25598 -+ bool "Proc restrictions"
25599 -+ help
25600 -+ If you say Y here, the permissions of the /proc filesystem
25601 -+ will be altered to enhance system security and privacy. You MUST
25602 -+ choose either a user only restriction or a user and group restriction.
25603 -+ Depending upon the option you choose, you can either restrict users to
25604 -+ see only the processes they themselves run, or choose a group that can
25605 -+ view all processes and files normally restricted to root if you choose
25606 -+ the "restrict to user only" option. NOTE: If you're running identd as
25607 -+ a non-root user, you will have to run it as the group you specify here.
25608 -+
25609 -+config GRKERNSEC_PROC_USER
25610 -+ bool "Restrict /proc to user only"
25611 -+ depends on GRKERNSEC_PROC
25612 -+ help
25613 -+ If you say Y here, non-root users will only be able to view their own
25614 -+ processes, and restricts them from viewing network-related information,
25615 -+ and viewing kernel symbol and module information.
25616 -+
25617 -+config GRKERNSEC_PROC_USERGROUP
25618 -+ bool "Allow special group"
25619 -+ depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
25620 -+ help
25621 -+ If you say Y here, you will be able to select a group that will be
25622 -+ able to view all processes, network-related information, and
25623 -+ kernel and symbol information. This option is useful if you want
25624 -+ to run identd as a non-root user.
25625 -+
25626 -+config GRKERNSEC_PROC_GID
25627 -+ int "GID for special group"
25628 -+ depends on GRKERNSEC_PROC_USERGROUP
25629 -+ default 1001
25630 -+
25631 -+config GRKERNSEC_PROC_ADD
25632 -+ bool "Additional restrictions"
25633 -+ depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
25634 -+ help
25635 -+ If you say Y here, additional restrictions will be placed on
25636 -+ /proc that keep normal users from viewing device information and
25637 -+ slabinfo information that could be useful for exploits.
25638 -+
25639 -+config GRKERNSEC_LINK
25640 -+ bool "Linking restrictions"
25641 -+ help
25642 -+ If you say Y here, /tmp race exploits will be prevented, since users
25643 -+ will no longer be able to follow symlinks owned by other users in
25644 -+ world-writable +t directories (i.e. /tmp), unless the owner of the
25645 -+ symlink is the owner of the directory. users will also not be
25646 -+ able to hardlink to files they do not own. If the sysctl option is
25647 -+ enabled, a sysctl option with name "linking_restrictions" is created.
25648 -+
25649 -+config GRKERNSEC_FIFO
25650 -+ bool "FIFO restrictions"
25651 -+ help
25652 -+ If you say Y here, users will not be able to write to FIFOs they don't
25653 -+ own in world-writable +t directories (i.e. /tmp), unless the owner of
25654 -+ the FIFO is the same owner of the directory it's held in. If the sysctl
25655 -+ option is enabled, a sysctl option with name "fifo_restrictions" is
25656 -+ created.
25657 -+
25658 -+config GRKERNSEC_CHROOT
25659 -+ bool "Chroot jail restrictions"
25660 -+ help
25661 -+ If you say Y here, you will be able to choose several options that will
25662 -+ make breaking out of a chrooted jail much more difficult. If you
25663 -+ encounter no software incompatibilities with the following options, it
25664 -+ is recommended that you enable each one.
25665 -+
25666 -+config GRKERNSEC_CHROOT_MOUNT
25667 -+ bool "Deny mounts"
25668 -+ depends on GRKERNSEC_CHROOT
25669 -+ help
25670 -+ If you say Y here, processes inside a chroot will not be able to
25671 -+ mount or remount filesystems. If the sysctl option is enabled, a
25672 -+ sysctl option with name "chroot_deny_mount" is created.
25673 -+
25674 -+config GRKERNSEC_CHROOT_DOUBLE
25675 -+ bool "Deny double-chroots"
25676 -+ depends on GRKERNSEC_CHROOT
25677 -+ help
25678 -+ If you say Y here, processes inside a chroot will not be able to chroot
25679 -+ again outside the chroot. This is a widely used method of breaking
25680 -+ out of a chroot jail and should not be allowed. If the sysctl
25681 -+ option is enabled, a sysctl option with name
25682 -+ "chroot_deny_chroot" is created.
25683 -+
25684 -+config GRKERNSEC_CHROOT_PIVOT
25685 -+ bool "Deny pivot_root in chroot"
25686 -+ depends on GRKERNSEC_CHROOT
25687 -+ help
25688 -+ If you say Y here, processes inside a chroot will not be able to use
25689 -+ a function called pivot_root() that was introduced in Linux 2.3.41. It
25690 -+ works similar to chroot in that it changes the root filesystem. This
25691 -+ function could be misused in a chrooted process to attempt to break out
25692 -+ of the chroot, and therefore should not be allowed. If the sysctl
25693 -+ option is enabled, a sysctl option with name "chroot_deny_pivot" is
25694 -+ created.
25695 -+
25696 -+config GRKERNSEC_CHROOT_CHDIR
25697 -+ bool "Enforce chdir(\"/\") on all chroots"
25698 -+ depends on GRKERNSEC_CHROOT
25699 -+ help
25700 -+ If you say Y here, the current working directory of all newly-chrooted
25701 -+ applications will be set to the the root directory of the chroot.
25702 -+ The man page on chroot(2) states:
25703 -+ Note that this call does not change the current working
25704 -+ directory, so that `.' can be outside the tree rooted at
25705 -+ `/'. In particular, the super-user can escape from a
25706 -+ `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
25707 -+
25708 -+ It is recommended that you say Y here, since it's not known to break
25709 -+ any software. If the sysctl option is enabled, a sysctl option with
25710 -+ name "chroot_enforce_chdir" is created.
25711 -+
25712 -+config GRKERNSEC_CHROOT_CHMOD
25713 -+ bool "Deny (f)chmod +s"
25714 -+ depends on GRKERNSEC_CHROOT
25715 -+ help
25716 -+ If you say Y here, processes inside a chroot will not be able to chmod
25717 -+ or fchmod files to make them have suid or sgid bits. This protects
25718 -+ against another published method of breaking a chroot. If the sysctl
25719 -+ option is enabled, a sysctl option with name "chroot_deny_chmod" is
25720 -+ created.
25721 -+
25722 -+config GRKERNSEC_CHROOT_FCHDIR
25723 -+ bool "Deny fchdir out of chroot"
25724 -+ depends on GRKERNSEC_CHROOT
25725 -+ help
25726 -+ If you say Y here, a well-known method of breaking chroots by fchdir'ing
25727 -+ to a file descriptor of the chrooting process that points to a directory
25728 -+ outside the filesystem will be stopped. If the sysctl option
25729 -+ is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
25730 -+
25731 -+config GRKERNSEC_CHROOT_MKNOD
25732 -+ bool "Deny mknod"
25733 -+ depends on GRKERNSEC_CHROOT
25734 -+ help
25735 -+ If you say Y here, processes inside a chroot will not be allowed to
25736 -+ mknod. The problem with using mknod inside a chroot is that it
25737 -+ would allow an attacker to create a device entry that is the same
25738 -+ as one on the physical root of your system, which could range from
25739 -+ anything from the console device to a device for your harddrive (which
25740 -+ they could then use to wipe the drive or steal data). It is recommended
25741 -+ that you say Y here, unless you run into software incompatibilities.
25742 -+ If the sysctl option is enabled, a sysctl option with name
25743 -+ "chroot_deny_mknod" is created.
25744 -+
25745 -+config GRKERNSEC_CHROOT_SHMAT
25746 -+ bool "Deny shmat() out of chroot"
25747 -+ depends on GRKERNSEC_CHROOT
25748 -+ help
25749 -+ If you say Y here, processes inside a chroot will not be able to attach
25750 -+ to shared memory segments that were created outside of the chroot jail.
25751 -+ It is recommended that you say Y here. If the sysctl option is enabled,
25752 -+ a sysctl option with name "chroot_deny_shmat" is created.
25753 -+
25754 -+config GRKERNSEC_CHROOT_UNIX
25755 -+ bool "Deny access to abstract AF_UNIX sockets out of chroot"
25756 -+ depends on GRKERNSEC_CHROOT
25757 -+ help
25758 -+ If you say Y here, processes inside a chroot will not be able to
25759 -+ connect to abstract (meaning not belonging to a filesystem) Unix
25760 -+ domain sockets that were bound outside of a chroot. It is recommended
25761 -+ that you say Y here. If the sysctl option is enabled, a sysctl option
25762 -+ with name "chroot_deny_unix" is created.
25763 -+
25764 -+config GRKERNSEC_CHROOT_FINDTASK
25765 -+ bool "Protect outside processes"
25766 -+ depends on GRKERNSEC_CHROOT
25767 -+ help
25768 -+ If you say Y here, processes inside a chroot will not be able to
25769 -+ kill, send signals with fcntl, ptrace, capget, getpgid, getsid,
25770 -+ or view any process outside of the chroot. If the sysctl
25771 -+ option is enabled, a sysctl option with name "chroot_findtask" is
25772 -+ created.
25773 -+
25774 -+config GRKERNSEC_CHROOT_NICE
25775 -+ bool "Restrict priority changes"
25776 -+ depends on GRKERNSEC_CHROOT
25777 -+ help
25778 -+ If you say Y here, processes inside a chroot will not be able to raise
25779 -+ the priority of processes in the chroot, or alter the priority of
25780 -+ processes outside the chroot. This provides more security than simply
25781 -+ removing CAP_SYS_NICE from the process' capability set. If the
25782 -+ sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
25783 -+ is created.
25784 -+
25785 -+config GRKERNSEC_CHROOT_SYSCTL
25786 -+ bool "Deny sysctl writes"
25787 -+ depends on GRKERNSEC_CHROOT
25788 -+ help
25789 -+ If you say Y here, an attacker in a chroot will not be able to
25790 -+ write to sysctl entries, either by sysctl(2) or through a /proc
25791 -+ interface. It is strongly recommended that you say Y here. If the
25792 -+ sysctl option is enabled, a sysctl option with name
25793 -+ "chroot_deny_sysctl" is created.
25794 -+
25795 -+config GRKERNSEC_CHROOT_CAPS
25796 -+ bool "Capability restrictions"
25797 -+ depends on GRKERNSEC_CHROOT
25798 -+ help
25799 -+ If you say Y here, the capabilities on all root processes within a
25800 -+ chroot jail will be lowered to stop module insertion, raw i/o,
25801 -+ system and net admin tasks, rebooting the system, modifying immutable
25802 -+ files, modifying IPC owned by another, and changing the system time.
25803 -+ This is left an option because it can break some apps. Disable this
25804 -+ if your chrooted apps are having problems performing those kinds of
25805 -+ tasks. If the sysctl option is enabled, a sysctl option with
25806 -+ name "chroot_caps" is created.
25807 -+
25808 -+endmenu
25809 -+menu "Kernel Auditing"
25810 -+depends on GRKERNSEC
25811 -+
25812 -+config GRKERNSEC_AUDIT_GROUP
25813 -+ bool "Single group for auditing"
25814 -+ help
25815 -+ If you say Y here, the exec, chdir, (un)mount, and ipc logging features
25816 -+ will only operate on a group you specify. This option is recommended
25817 -+ if you only want to watch certain users instead of having a large
25818 -+ amount of logs from the entire system. If the sysctl option is enabled,
25819 -+ a sysctl option with name "audit_group" is created.
25820 -+
25821 -+config GRKERNSEC_AUDIT_GID
25822 -+ int "GID for auditing"
25823 -+ depends on GRKERNSEC_AUDIT_GROUP
25824 -+ default 1007
25825 -+
25826 -+config GRKERNSEC_EXECLOG
25827 -+ bool "Exec logging"
25828 -+ help
25829 -+ If you say Y here, all execve() calls will be logged (since the
25830 -+ other exec*() calls are frontends to execve(), all execution
25831 -+ will be logged). Useful for shell-servers that like to keep track
25832 -+ of their users. If the sysctl option is enabled, a sysctl option with
25833 -+ name "exec_logging" is created.
25834 -+ WARNING: This option when enabled will produce a LOT of logs, especially
25835 -+ on an active system.
25836 -+
25837 -+config GRKERNSEC_RESLOG
25838 -+ bool "Resource logging"
25839 -+ help
25840 -+ If you say Y here, all attempts to overstep resource limits will
25841 -+ be logged with the resource name, the requested size, and the current
25842 -+ limit. It is highly recommended that you say Y here. If the sysctl
25843 -+ option is enabled, a sysctl option with name "resource_logging" is
25844 -+ created. If the RBAC system is enabled, the sysctl value is ignored.
25845 -+
25846 -+config GRKERNSEC_CHROOT_EXECLOG
25847 -+ bool "Log execs within chroot"
25848 -+ help
25849 -+ If you say Y here, all executions inside a chroot jail will be logged
25850 -+ to syslog. This can cause a large amount of logs if certain
25851 -+ applications (eg. djb's daemontools) are installed on the system, and
25852 -+ is therefore left as an option. If the sysctl option is enabled, a
25853 -+ sysctl option with name "chroot_execlog" is created.
25854 -+
25855 -+config GRKERNSEC_AUDIT_CHDIR
25856 -+ bool "Chdir logging"
25857 -+ help
25858 -+ If you say Y here, all chdir() calls will be logged. If the sysctl
25859 -+ option is enabled, a sysctl option with name "audit_chdir" is created.
25860 -+
25861 -+config GRKERNSEC_AUDIT_MOUNT
25862 -+ bool "(Un)Mount logging"
25863 -+ help
25864 -+ If you say Y here, all mounts and unmounts will be logged. If the
25865 -+ sysctl option is enabled, a sysctl option with name "audit_mount" is
25866 -+ created.
25867 -+
25868 -+config GRKERNSEC_AUDIT_IPC
25869 -+ bool "IPC logging"
25870 -+ help
25871 -+ If you say Y here, creation and removal of message queues, semaphores,
25872 -+ and shared memory will be logged. If the sysctl option is enabled, a
25873 -+ sysctl option with name "audit_ipc" is created.
25874 -+
25875 -+config GRKERNSEC_SIGNAL
25876 -+ bool "Signal logging"
25877 -+ help
25878 -+ If you say Y here, certain important signals will be logged, such as
25879 -+ SIGSEGV, which will as a result inform you of when a error in a program
25880 -+ occurred, which in some cases could mean a possible exploit attempt.
25881 -+ If the sysctl option is enabled, a sysctl option with name
25882 -+ "signal_logging" is created.
25883 -+
25884 -+config GRKERNSEC_FORKFAIL
25885 -+ bool "Fork failure logging"
25886 -+ help
25887 -+ If you say Y here, all failed fork() attempts will be logged.
25888 -+ This could suggest a fork bomb, or someone attempting to overstep
25889 -+ their process limit. If the sysctl option is enabled, a sysctl option
25890 -+ with name "forkfail_logging" is created.
25891 -+
25892 -+config GRKERNSEC_TIME
25893 -+ bool "Time change logging"
25894 -+ help
25895 -+ If you say Y here, any changes of the system clock will be logged.
25896 -+ If the sysctl option is enabled, a sysctl option with name
25897 -+ "timechange_logging" is created.
25898 -+
25899 -+config GRKERNSEC_PROC_IPADDR
25900 -+ bool "/proc/<pid>/ipaddr support"
25901 -+ help
25902 -+ If you say Y here, a new entry will be added to each /proc/<pid>
25903 -+ directory that contains the IP address of the person using the task.
25904 -+ The IP is carried across local TCP and AF_UNIX stream sockets.
25905 -+ This information can be useful for IDS/IPSes to perform remote response
25906 -+ to a local attack. The entry is readable by only the owner of the
25907 -+ process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
25908 -+ the RBAC system), and thus does not create privacy concerns.
25909 -+
25910 -+config GRKERNSEC_AUDIT_TEXTREL
25911 -+ bool 'ELF text relocations logging (READ HELP)'
25912 -+ depends on PAX_MPROTECT
25913 -+ help
25914 -+ If you say Y here, text relocations will be logged with the filename
25915 -+ of the offending library or binary. The purpose of the feature is
25916 -+ to help Linux distribution developers get rid of libraries and
25917 -+ binaries that need text relocations which hinder the future progress
25918 -+ of PaX. Only Linux distribution developers should say Y here, and
25919 -+ never on a production machine, as this option creates an information
25920 -+ leak that could aid an attacker in defeating the randomization of
25921 -+ a single memory region. If the sysctl option is enabled, a sysctl
25922 -+ option with name "audit_textrel" is created.
25923 -+
25924 -+endmenu
25925 -+
25926 -+menu "Executable Protections"
25927 -+depends on GRKERNSEC
25928 -+
25929 -+config GRKERNSEC_EXECVE
25930 -+ bool "Enforce RLIMIT_NPROC on execs"
25931 -+ help
25932 -+ If you say Y here, users with a resource limit on processes will
25933 -+ have the value checked during execve() calls. The current system
25934 -+ only checks the system limit during fork() calls. If the sysctl option
25935 -+ is enabled, a sysctl option with name "execve_limiting" is created.
25936 -+
25937 -+config GRKERNSEC_DMESG
25938 -+ bool "Dmesg(8) restriction"
25939 -+ help
25940 -+ If you say Y here, non-root users will not be able to use dmesg(8)
25941 -+ to view up to the last 4kb of messages in the kernel's log buffer.
25942 -+ If the sysctl option is enabled, a sysctl option with name "dmesg" is
25943 -+ created.
25944 -+
25945 -+config GRKERNSEC_TPE
25946 -+ bool "Trusted Path Execution (TPE)"
25947 -+ help
25948 -+ If you say Y here, you will be able to choose a gid to add to the
25949 -+ supplementary groups of users you want to mark as "untrusted."
25950 -+ These users will not be able to execute any files that are not in
25951 -+ root-owned directories writable only by root. If the sysctl option
25952 -+ is enabled, a sysctl option with name "tpe" is created.
25953 -+
25954 -+config GRKERNSEC_TPE_ALL
25955 -+ bool "Partially restrict non-root users"
25956 -+ depends on GRKERNSEC_TPE
25957 -+ help
25958 -+ If you say Y here, All non-root users other than the ones in the
25959 -+ group specified in the main TPE option will only be allowed to
25960 -+ execute files in directories they own that are not group or
25961 -+ world-writable, or in directories owned by root and writable only by
25962 -+ root. If the sysctl option is enabled, a sysctl option with name
25963 -+ "tpe_restrict_all" is created.
25964 -+
25965 -+config GRKERNSEC_TPE_INVERT
25966 -+ bool "Invert GID option"
25967 -+ depends on GRKERNSEC_TPE
25968 -+ help
25969 -+ If you say Y here, the group you specify in the TPE configuration will
25970 -+ decide what group TPE restrictions will be *disabled* for. This
25971 -+ option is useful if you want TPE restrictions to be applied to most
25972 -+ users on the system.
25973 -+
25974 -+config GRKERNSEC_TPE_GID
25975 -+ int "GID for untrusted users"
25976 -+ depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
25977 -+ default 1005
25978 -+ help
25979 -+ If you have selected the "Invert GID option" above, setting this
25980 -+ GID determines what group TPE restrictions will be *disabled* for.
25981 -+ If you have not selected the "Invert GID option" above, setting this
25982 -+ GID determines what group TPE restrictions will be *enabled* for.
25983 -+ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
25984 -+ is created.
25985 -+
25986 -+config GRKERNSEC_TPE_GID
25987 -+ int "GID for trusted users"
25988 -+ depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
25989 -+ default 1005
25990 -+ help
25991 -+ If you have selected the "Invert GID option" above, setting this
25992 -+ GID determines what group TPE restrictions will be *disabled* for.
25993 -+ If you have not selected the "Invert GID option" above, setting this
25994 -+ GID determines what group TPE restrictions will be *enabled* for.
25995 -+ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
25996 -+ is created.
25997 -+
25998 -+endmenu
25999 -+menu "Network Protections"
26000 -+depends on GRKERNSEC
26001 -+
26002 -+config GRKERNSEC_RANDNET
26003 -+ bool "Larger entropy pools"
26004 -+ help
26005 -+ If you say Y here, the entropy pools used for many features of Linux
26006 -+ and grsecurity will be doubled in size. Since several grsecurity
26007 -+ features use additional randomness, it is recommended that you say Y
26008 -+ here. Saying Y here has a similar effect as modifying
26009 -+ /proc/sys/kernel/random/poolsize.
26010 -+
26011 -+config GRKERNSEC_SOCKET
26012 -+ bool "Socket restrictions"
26013 -+ help
26014 -+ If you say Y here, you will be able to choose from several options.
26015 -+ If you assign a GID on your system and add it to the supplementary
26016 -+ groups of users you want to restrict socket access to, this patch
26017 -+ will perform up to three things, based on the option(s) you choose.
26018 -+
26019 -+config GRKERNSEC_SOCKET_ALL
26020 -+ bool "Deny any sockets to group"
26021 -+ depends on GRKERNSEC_SOCKET
26022 -+ help
26023 -+ If you say Y here, you will be able to choose a GID of whose users will
26024 -+ be unable to connect to other hosts from your machine or run server
26025 -+ applications from your machine. If the sysctl option is enabled, a
26026 -+ sysctl option with name "socket_all" is created.
26027 -+
26028 -+config GRKERNSEC_SOCKET_ALL_GID
26029 -+ int "GID to deny all sockets for"
26030 -+ depends on GRKERNSEC_SOCKET_ALL
26031 -+ default 1004
26032 -+ help
26033 -+ Here you can choose the GID to disable socket access for. Remember to
26034 -+ add the users you want socket access disabled for to the GID
26035 -+ specified here. If the sysctl option is enabled, a sysctl option
26036 -+ with name "socket_all_gid" is created.
26037 -+
26038 -+config GRKERNSEC_SOCKET_CLIENT
26039 -+ bool "Deny client sockets to group"
26040 -+ depends on GRKERNSEC_SOCKET
26041 -+ help
26042 -+ If you say Y here, you will be able to choose a GID of whose users will
26043 -+ be unable to connect to other hosts from your machine, but will be
26044 -+ able to run servers. If this option is enabled, all users in the group
26045 -+ you specify will have to use passive mode when initiating ftp transfers
26046 -+ from the shell on your machine. If the sysctl option is enabled, a
26047 -+ sysctl option with name "socket_client" is created.
26048 -+
26049 -+config GRKERNSEC_SOCKET_CLIENT_GID
26050 -+ int "GID to deny client sockets for"
26051 -+ depends on GRKERNSEC_SOCKET_CLIENT
26052 -+ default 1003
26053 -+ help
26054 -+ Here you can choose the GID to disable client socket access for.
26055 -+ Remember to add the users you want client socket access disabled for to
26056 -+ the GID specified here. If the sysctl option is enabled, a sysctl
26057 -+ option with name "socket_client_gid" is created.
26058 -+
26059 -+config GRKERNSEC_SOCKET_SERVER
26060 -+ bool "Deny server sockets to group"
26061 -+ depends on GRKERNSEC_SOCKET
26062 -+ help
26063 -+ If you say Y here, you will be able to choose a GID of whose users will
26064 -+ be unable to run server applications from your machine. If the sysctl
26065 -+ option is enabled, a sysctl option with name "socket_server" is created.
26066 -+
26067 -+config GRKERNSEC_SOCKET_SERVER_GID
26068 -+ int "GID to deny server sockets for"
26069 -+ depends on GRKERNSEC_SOCKET_SERVER
26070 -+ default 1002
26071 -+ help
26072 -+ Here you can choose the GID to disable server socket access for.
26073 -+ Remember to add the users you want server socket access disabled for to
26074 -+ the GID specified here. If the sysctl option is enabled, a sysctl
26075 -+ option with name "socket_server_gid" is created.
26076 -+
26077 -+endmenu
26078 -+menu "Sysctl support"
26079 -+depends on GRKERNSEC && SYSCTL
26080 -+
26081 -+config GRKERNSEC_SYSCTL
26082 -+ bool "Sysctl support"
26083 -+ help
26084 -+ If you say Y here, you will be able to change the options that
26085 -+ grsecurity runs with at bootup, without having to recompile your
26086 -+ kernel. You can echo values to files in /proc/sys/kernel/grsecurity
26087 -+ to enable (1) or disable (0) various features. All the sysctl entries
26088 -+ are mutable until the "grsec_lock" entry is set to a non-zero value.
26089 -+ All features enabled in the kernel configuration are disabled at boot
26090 -+ if you do not say Y to the "Turn on features by default" option.
26091 -+ All options should be set at startup, and the grsec_lock entry should
26092 -+ be set to a non-zero value after all the options are set.
26093 -+ *THIS IS EXTREMELY IMPORTANT*
26094 -+
26095 -+config GRKERNSEC_SYSCTL_ON
26096 -+ bool "Turn on features by default"
26097 -+ depends on GRKERNSEC_SYSCTL
26098 -+ help
26099 -+ If you say Y here, instead of having all features enabled in the
26100 -+ kernel configuration disabled at boot time, the features will be
26101 -+ enabled at boot time. It is recommended you say Y here unless
26102 -+ there is some reason you would want all sysctl-tunable features to
26103 -+ be disabled by default. As mentioned elsewhere, it is important
26104 -+ to enable the grsec_lock entry once you have finished modifying
26105 -+ the sysctl entries.
26106 -+
26107 -+endmenu
26108 -+menu "Logging Options"
26109 -+depends on GRKERNSEC
26110 -+
26111 -+config GRKERNSEC_FLOODTIME
26112 -+ int "Seconds in between log messages (minimum)"
26113 -+ default 10
26114 -+ help
26115 -+ This option allows you to enforce the number of seconds between
26116 -+ grsecurity log messages. The default should be suitable for most
26117 -+ people, however, if you choose to change it, choose a value small enough
26118 -+ to allow informative logs to be produced, but large enough to
26119 -+ prevent flooding.
26120 -+
26121 -+config GRKERNSEC_FLOODBURST
26122 -+ int "Number of messages in a burst (maximum)"
26123 -+ default 4
26124 -+ help
26125 -+ This option allows you to choose the maximum number of messages allowed
26126 -+ within the flood time interval you chose in a separate option. The
26127 -+ default should be suitable for most people, however if you find that
26128 -+ many of your logs are being interpreted as flooding, you may want to
26129 -+ raise this value.
26130 -+
26131 -+endmenu
26132 -+
26133 -+endmenu
26134 -diff -urNp linux-2.6.27.6/grsecurity/Makefile linux-2.6.27.6/grsecurity/Makefile
26135 ---- linux-2.6.27.6/grsecurity/Makefile 1969-12-31 19:00:00.000000000 -0500
26136 -+++ linux-2.6.27.6/grsecurity/Makefile 2008-11-18 03:38:45.000000000 -0500
26137 -@@ -0,0 +1,20 @@
26138 -+# grsecurity's ACL system was originally written in 2001 by Michael Dalton
26139 -+# during 2001-2005 it has been completely redesigned by Brad Spengler
26140 -+# into an RBAC system
26141 -+#
26142 -+# All code in this directory and various hooks inserted throughout the kernel
26143 -+# are copyright Brad Spengler, and released under the GPL v2 or higher
26144 -+
26145 -+obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
26146 -+ grsec_mount.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
26147 -+ grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
26148 -+
26149 -+obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
26150 -+ gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
26151 -+ gracl_learn.o grsec_log.o
26152 -+obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
26153 -+
26154 -+ifndef CONFIG_GRKERNSEC
26155 -+obj-y += grsec_disabled.o
26156 -+endif
26157 -+
26158 -diff -urNp linux-2.6.27.6/include/asm-cris/kmap_types.h linux-2.6.27.6/include/asm-cris/kmap_types.h
26159 ---- linux-2.6.27.6/include/asm-cris/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
26160 -+++ linux-2.6.27.6/include/asm-cris/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
26161 -@@ -19,6 +19,7 @@ enum km_type {
26162 - KM_IRQ1,
26163 - KM_SOFTIRQ0,
26164 - KM_SOFTIRQ1,
26165 -+ KM_CLEARPAGE,
26166 - KM_TYPE_NR
26167 - };
26168 -
26169 -diff -urNp linux-2.6.27.6/include/asm-frv/kmap_types.h linux-2.6.27.6/include/asm-frv/kmap_types.h
26170 ---- linux-2.6.27.6/include/asm-frv/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
26171 -+++ linux-2.6.27.6/include/asm-frv/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
26172 -@@ -23,6 +23,7 @@ enum km_type {
26173 - KM_IRQ1,
26174 - KM_SOFTIRQ0,
26175 - KM_SOFTIRQ1,
26176 -+ KM_CLEARPAGE,
26177 - KM_TYPE_NR
26178 - };
26179 -
26180 -diff -urNp linux-2.6.27.6/include/asm-generic/futex.h linux-2.6.27.6/include/asm-generic/futex.h
26181 ---- linux-2.6.27.6/include/asm-generic/futex.h 2008-11-07 12:55:34.000000000 -0500
26182 -+++ linux-2.6.27.6/include/asm-generic/futex.h 2008-11-18 03:38:45.000000000 -0500
26183 -@@ -6,7 +6,7 @@
26184 - #include <asm/errno.h>
26185 -
26186 - static inline int
26187 --futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
26188 -+futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
26189 - {
26190 - int op = (encoded_op >> 28) & 7;
26191 - int cmp = (encoded_op >> 24) & 15;
26192 -@@ -48,7 +48,7 @@ futex_atomic_op_inuser (int encoded_op,
26193 - }
26194 -
26195 - static inline int
26196 --futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
26197 -+futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
26198 - {
26199 - return -ENOSYS;
26200 - }
26201 -diff -urNp linux-2.6.27.6/include/asm-generic/vmlinux.lds.h linux-2.6.27.6/include/asm-generic/vmlinux.lds.h
26202 ---- linux-2.6.27.6/include/asm-generic/vmlinux.lds.h 2008-11-07 12:55:34.000000000 -0500
26203 -+++ linux-2.6.27.6/include/asm-generic/vmlinux.lds.h 2008-11-18 03:38:45.000000000 -0500
26204 -@@ -59,6 +59,7 @@
26205 - .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
26206 - VMLINUX_SYMBOL(__start_rodata) = .; \
26207 - *(.rodata) *(.rodata.*) \
26208 -+ *(.data.read_only) \
26209 - *(__vermagic) /* Kernel version magic */ \
26210 - *(__markers_strings) /* Markers: strings */ \
26211 - } \
26212 -diff -urNp linux-2.6.27.6/include/asm-m32r/kmap_types.h linux-2.6.27.6/include/asm-m32r/kmap_types.h
26213 ---- linux-2.6.27.6/include/asm-m32r/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
26214 -+++ linux-2.6.27.6/include/asm-m32r/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
26215 -@@ -21,7 +21,8 @@ D(9) KM_IRQ0,
26216 - D(10) KM_IRQ1,
26217 - D(11) KM_SOFTIRQ0,
26218 - D(12) KM_SOFTIRQ1,
26219 --D(13) KM_TYPE_NR
26220 -+D(13) KM_CLEARPAGE,
26221 -+D(14) KM_TYPE_NR
26222 - };
26223 -
26224 - #undef D
26225 -diff -urNp linux-2.6.27.6/include/asm-m68k/kmap_types.h linux-2.6.27.6/include/asm-m68k/kmap_types.h
26226 ---- linux-2.6.27.6/include/asm-m68k/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
26227 -+++ linux-2.6.27.6/include/asm-m68k/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
26228 -@@ -15,6 +15,7 @@ enum km_type {
26229 - KM_IRQ1,
26230 - KM_SOFTIRQ0,
26231 - KM_SOFTIRQ1,
26232 -+ KM_CLEARPAGE,
26233 - KM_TYPE_NR
26234 - };
26235 -
26236 -diff -urNp linux-2.6.27.6/include/asm-mips/elf.h linux-2.6.27.6/include/asm-mips/elf.h
26237 ---- linux-2.6.27.6/include/asm-mips/elf.h 2008-11-07 12:55:34.000000000 -0500
26238 -+++ linux-2.6.27.6/include/asm-mips/elf.h 2008-11-18 03:38:45.000000000 -0500
26239 -@@ -368,4 +368,11 @@ extern int dump_task_fpu(struct task_str
26240 - #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
26241 - #endif
26242 -
26243 -+#ifdef CONFIG_PAX_ASLR
26244 -+#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
26245 -+
26246 -+#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
26247 -+#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
26248 -+#endif
26249 -+
26250 - #endif /* _ASM_ELF_H */
26251 -diff -urNp linux-2.6.27.6/include/asm-mips/kmap_types.h linux-2.6.27.6/include/asm-mips/kmap_types.h
26252 ---- linux-2.6.27.6/include/asm-mips/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
26253 -+++ linux-2.6.27.6/include/asm-mips/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
26254 -@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
26255 - D(10) KM_IRQ1,
26256 - D(11) KM_SOFTIRQ0,
26257 - D(12) KM_SOFTIRQ1,
26258 --D(13) KM_TYPE_NR
26259 -+D(13) KM_CLEARPAGE,
26260 -+D(14) KM_TYPE_NR
26261 - };
26262 -
26263 - #undef D
26264 -diff -urNp linux-2.6.27.6/include/asm-mips/page.h linux-2.6.27.6/include/asm-mips/page.h
26265 ---- linux-2.6.27.6/include/asm-mips/page.h 2008-11-07 12:55:34.000000000 -0500
26266 -+++ linux-2.6.27.6/include/asm-mips/page.h 2008-11-18 03:38:45.000000000 -0500
26267 -@@ -82,7 +82,7 @@ extern void copy_user_highpage(struct pa
26268 - #ifdef CONFIG_CPU_MIPS32
26269 - typedef struct { unsigned long pte_low, pte_high; } pte_t;
26270 - #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
26271 -- #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
26272 -+ #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
26273 - #else
26274 - typedef struct { unsigned long long pte; } pte_t;
26275 - #define pte_val(x) ((x).pte)
26276 -diff -urNp linux-2.6.27.6/include/asm-mips/system.h linux-2.6.27.6/include/asm-mips/system.h
26277 ---- linux-2.6.27.6/include/asm-mips/system.h 2008-11-07 12:55:34.000000000 -0500
26278 -+++ linux-2.6.27.6/include/asm-mips/system.h 2008-11-18 03:38:45.000000000 -0500
26279 -@@ -215,6 +215,6 @@ extern void per_cpu_trap_init(void);
26280 - */
26281 - #define __ARCH_WANT_UNLOCKED_CTXSW
26282 -
26283 --extern unsigned long arch_align_stack(unsigned long sp);
26284 -+#define arch_align_stack(x) ((x) & ALMASK)
26285 -
26286 - #endif /* _ASM_SYSTEM_H */
26287 -diff -urNp linux-2.6.27.6/include/asm-mn10300/kmap_types.h linux-2.6.27.6/include/asm-mn10300/kmap_types.h
26288 ---- linux-2.6.27.6/include/asm-mn10300/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
26289 -+++ linux-2.6.27.6/include/asm-mn10300/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
26290 -@@ -25,6 +25,7 @@ enum km_type {
26291 - KM_IRQ1,
26292 - KM_SOFTIRQ0,
26293 - KM_SOFTIRQ1,
26294 -+ KM_CLEARPAGE,
26295 - KM_TYPE_NR
26296 - };
26297 -
26298 -diff -urNp linux-2.6.27.6/include/asm-parisc/elf.h linux-2.6.27.6/include/asm-parisc/elf.h
26299 ---- linux-2.6.27.6/include/asm-parisc/elf.h 2008-11-07 12:55:34.000000000 -0500
26300 -+++ linux-2.6.27.6/include/asm-parisc/elf.h 2008-11-18 03:38:45.000000000 -0500
26301 -@@ -333,6 +333,13 @@ struct pt_regs; /* forward declaration..
26302 -
26303 - #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
26304 -
26305 -+#ifdef CONFIG_PAX_ASLR
26306 -+#define PAX_ELF_ET_DYN_BASE 0x10000UL
26307 -+
26308 -+#define PAX_DELTA_MMAP_LEN 16
26309 -+#define PAX_DELTA_STACK_LEN 16
26310 -+#endif
26311 -+
26312 - /* This yields a mask that user programs can use to figure out what
26313 - instruction set this CPU supports. This could be done in user space,
26314 - but it's not easy, and we've already done it here. */
26315 -diff -urNp linux-2.6.27.6/include/asm-parisc/kmap_types.h linux-2.6.27.6/include/asm-parisc/kmap_types.h
26316 ---- linux-2.6.27.6/include/asm-parisc/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
26317 -+++ linux-2.6.27.6/include/asm-parisc/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
26318 -@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
26319 - D(10) KM_IRQ1,
26320 - D(11) KM_SOFTIRQ0,
26321 - D(12) KM_SOFTIRQ1,
26322 --D(13) KM_TYPE_NR
26323 -+D(13) KM_CLEARPAGE,
26324 -+D(14) KM_TYPE_NR
26325 - };
26326 -
26327 - #undef D
26328 -diff -urNp linux-2.6.27.6/include/asm-parisc/pgtable.h linux-2.6.27.6/include/asm-parisc/pgtable.h
26329 ---- linux-2.6.27.6/include/asm-parisc/pgtable.h 2008-11-07 12:55:34.000000000 -0500
26330 -+++ linux-2.6.27.6/include/asm-parisc/pgtable.h 2008-11-18 03:38:45.000000000 -0500
26331 -@@ -202,6 +202,17 @@
26332 - #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
26333 - #define PAGE_COPY PAGE_EXECREAD
26334 - #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
26335 -+
26336 -+#ifdef CONFIG_PAX_PAGEEXEC
26337 -+# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
26338 -+# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
26339 -+# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
26340 -+#else
26341 -+# define PAGE_SHARED_NOEXEC PAGE_SHARED
26342 -+# define PAGE_COPY_NOEXEC PAGE_COPY
26343 -+# define PAGE_READONLY_NOEXEC PAGE_READONLY
26344 -+#endif
26345 -+
26346 - #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
26347 - #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
26348 - #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
26349 -diff -urNp linux-2.6.27.6/include/asm-um/kmap_types.h linux-2.6.27.6/include/asm-um/kmap_types.h
26350 ---- linux-2.6.27.6/include/asm-um/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
26351 -+++ linux-2.6.27.6/include/asm-um/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
26352 -@@ -23,6 +23,7 @@ enum km_type {
26353 - KM_IRQ1,
26354 - KM_SOFTIRQ0,
26355 - KM_SOFTIRQ1,
26356 -+ KM_CLEARPAGE,
26357 - KM_TYPE_NR
26358 - };
26359 -
26360 -diff -urNp linux-2.6.27.6/include/asm-um/page.h linux-2.6.27.6/include/asm-um/page.h
26361 ---- linux-2.6.27.6/include/asm-um/page.h 2008-11-07 12:55:34.000000000 -0500
26362 -+++ linux-2.6.27.6/include/asm-um/page.h 2008-11-18 03:38:45.000000000 -0500
26363 -@@ -14,6 +14,9 @@
26364 - #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
26365 - #define PAGE_MASK (~(PAGE_SIZE-1))
26366 -
26367 -+#define ktla_ktva(addr) (addr)
26368 -+#define ktva_ktla(addr) (addr)
26369 -+
26370 - #ifndef __ASSEMBLY__
26371 -
26372 - struct page;
26373 -diff -urNp linux-2.6.27.6/include/asm-x86/alternative.h linux-2.6.27.6/include/asm-x86/alternative.h
26374 ---- linux-2.6.27.6/include/asm-x86/alternative.h 2008-11-07 12:55:34.000000000 -0500
26375 -+++ linux-2.6.27.6/include/asm-x86/alternative.h 2008-11-18 03:38:45.000000000 -0500
26376 -@@ -96,7 +96,7 @@ const unsigned char *const *find_nop_tab
26377 - " .byte 662b-661b\n" /* sourcelen */ \
26378 - " .byte 664f-663f\n" /* replacementlen */ \
26379 - ".previous\n" \
26380 -- ".section .altinstr_replacement,\"ax\"\n" \
26381 -+ ".section .altinstr_replacement,\"a\"\n" \
26382 - "663:\n\t" newinstr "\n664:\n" /* replacement */ \
26383 - ".previous" :: "i" (feature) : "memory")
26384 -
26385 -@@ -120,7 +120,7 @@ const unsigned char *const *find_nop_tab
26386 - " .byte 662b-661b\n" /* sourcelen */ \
26387 - " .byte 664f-663f\n" /* replacementlen */ \
26388 - ".previous\n" \
26389 -- ".section .altinstr_replacement,\"ax\"\n" \
26390 -+ ".section .altinstr_replacement,\"a\"\n" \
26391 - "663:\n\t" newinstr "\n664:\n" /* replacement */ \
26392 - ".previous" :: "i" (feature), ##input)
26393 -
26394 -@@ -135,7 +135,7 @@ const unsigned char *const *find_nop_tab
26395 - " .byte 662b-661b\n" /* sourcelen */ \
26396 - " .byte 664f-663f\n" /* replacementlen */ \
26397 - ".previous\n" \
26398 -- ".section .altinstr_replacement,\"ax\"\n" \
26399 -+ ".section .altinstr_replacement,\"a\"\n" \
26400 - "663:\n\t" newinstr "\n664:\n" /* replacement */ \
26401 - ".previous" : output : [feat] "i" (feature), ##input)
26402 -
26403 -diff -urNp linux-2.6.27.6/include/asm-x86/atomic_32.h linux-2.6.27.6/include/asm-x86/atomic_32.h
26404 ---- linux-2.6.27.6/include/asm-x86/atomic_32.h 2008-11-07 12:55:34.000000000 -0500
26405 -+++ linux-2.6.27.6/include/asm-x86/atomic_32.h 2008-11-18 03:38:45.000000000 -0500
26406 -@@ -47,7 +47,15 @@ typedef struct {
26407 - */
26408 - static inline void atomic_add(int i, atomic_t *v)
26409 - {
26410 -- asm volatile(LOCK_PREFIX "addl %1,%0"
26411 -+ asm volatile(LOCK_PREFIX "addl %1,%0\n"
26412 -+
26413 -+#ifdef CONFIG_PAX_REFCOUNT
26414 -+ "jno 0f\n"
26415 -+ LOCK_PREFIX "subl %1,%0\n"
26416 -+ "into\n0:\n"
26417 -+ _ASM_EXTABLE(0b, 0b)
26418 -+#endif
26419 -+
26420 - : "+m" (v->counter)
26421 - : "ir" (i));
26422 - }
26423 -@@ -61,7 +69,15 @@ static inline void atomic_add(int i, ato
26424 - */
26425 - static inline void atomic_sub(int i, atomic_t *v)
26426 - {
26427 -- asm volatile(LOCK_PREFIX "subl %1,%0"
26428 -+ asm volatile(LOCK_PREFIX "subl %1,%0\n"
26429 -+
26430 -+#ifdef CONFIG_PAX_REFCOUNT
26431 -+ "jno 0f\n"
26432 -+ LOCK_PREFIX "addl %1,%0\n"
26433 -+ "into\n0:\n"
26434 -+ _ASM_EXTABLE(0b, 0b)
26435 -+#endif
26436 -+
26437 - : "+m" (v->counter)
26438 - : "ir" (i));
26439 - }
26440 -@@ -79,7 +95,16 @@ static inline int atomic_sub_and_test(in
26441 - {
26442 - unsigned char c;
26443 -
26444 -- asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
26445 -+ asm volatile(LOCK_PREFIX "subl %2,%0\n"
26446 -+
26447 -+#ifdef CONFIG_PAX_REFCOUNT
26448 -+ "jno 0f\n"
26449 -+ LOCK_PREFIX "addl %2,%0\n"
26450 -+ "into\n0:\n"
26451 -+ _ASM_EXTABLE(0b, 0b)
26452 -+#endif
26453 -+
26454 -+ "sete %1\n"
26455 - : "+m" (v->counter), "=qm" (c)
26456 - : "ir" (i) : "memory");
26457 - return c;
26458 -@@ -93,7 +118,18 @@ static inline int atomic_sub_and_test(in
26459 - */
26460 - static inline void atomic_inc(atomic_t *v)
26461 - {
26462 -- asm volatile(LOCK_PREFIX "incl %0"
26463 -+ asm volatile(LOCK_PREFIX "incl %0\n"
26464 -+
26465 -+#ifdef CONFIG_PAX_REFCOUNT
26466 -+ "into\n0:\n"
26467 -+ ".pushsection .fixup,\"ax\"\n"
26468 -+ "1:\n"
26469 -+ LOCK_PREFIX "decl %0\n"
26470 -+ "jmp 0b\n"
26471 -+ ".popsection\n"
26472 -+ _ASM_EXTABLE(0b, 1b)
26473 -+#endif
26474 -+
26475 - : "+m" (v->counter));
26476 - }
26477 -
26478 -@@ -105,7 +141,18 @@ static inline void atomic_inc(atomic_t *
26479 - */
26480 - static inline void atomic_dec(atomic_t *v)
26481 - {
26482 -- asm volatile(LOCK_PREFIX "decl %0"
26483 -+ asm volatile(LOCK_PREFIX "decl %0\n"
26484 -+
26485 -+#ifdef CONFIG_PAX_REFCOUNT
26486 -+ "into\n0:\n"
26487 -+ ".pushsection .fixup,\"ax\"\n"
26488 -+ "1: \n"
26489 -+ LOCK_PREFIX "incl %0\n"
26490 -+ "jmp 0b\n"
26491 -+ ".popsection\n"
26492 -+ _ASM_EXTABLE(0b, 1b)
26493 -+#endif
26494 -+
26495 - : "+m" (v->counter));
26496 - }
26497 -
26498 -@@ -121,7 +168,19 @@ static inline int atomic_dec_and_test(at
26499 - {
26500 - unsigned char c;
26501 -
26502 -- asm volatile(LOCK_PREFIX "decl %0; sete %1"
26503 -+ asm volatile(LOCK_PREFIX "decl %0\n"
26504 -+
26505 -+#ifdef CONFIG_PAX_REFCOUNT
26506 -+ "into\n0:\n"
26507 -+ ".pushsection .fixup,\"ax\"\n"
26508 -+ "1: \n"
26509 -+ LOCK_PREFIX "incl %0\n"
26510 -+ "jmp 0b\n"
26511 -+ ".popsection\n"
26512 -+ _ASM_EXTABLE(0b, 1b)
26513 -+#endif
26514 -+
26515 -+ "sete %1\n"
26516 - : "+m" (v->counter), "=qm" (c)
26517 - : : "memory");
26518 - return c != 0;
26519 -@@ -139,7 +198,19 @@ static inline int atomic_inc_and_test(at
26520 - {
26521 - unsigned char c;
26522 -
26523 -- asm volatile(LOCK_PREFIX "incl %0; sete %1"
26524 -+ asm volatile(LOCK_PREFIX "incl %0\n"
26525 -+
26526 -+#ifdef CONFIG_PAX_REFCOUNT
26527 -+ "into\n0:\n"
26528 -+ ".pushsection .fixup,\"ax\"\n"
26529 -+ "1: \n"
26530 -+ LOCK_PREFIX "decl %0\n"
26531 -+ "jmp 0b\n"
26532 -+ ".popsection\n"
26533 -+ _ASM_EXTABLE(0b, 1b)
26534 -+#endif
26535 -+
26536 -+ "sete %1\n"
26537 - : "+m" (v->counter), "=qm" (c)
26538 - : : "memory");
26539 - return c != 0;
26540 -@@ -158,7 +229,16 @@ static inline int atomic_add_negative(in
26541 - {
26542 - unsigned char c;
26543 -
26544 -- asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
26545 -+ asm volatile(LOCK_PREFIX "addl %2,%0\n"
26546 -+
26547 -+#ifdef CONFIG_PAX_REFCOUNT
26548 -+ "jno 0f\n"
26549 -+ LOCK_PREFIX "subl %2,%0\n"
26550 -+ "into\n0:\n"
26551 -+ _ASM_EXTABLE(0b, 0b)
26552 -+#endif
26553 -+
26554 -+ "sets %1\n"
26555 - : "+m" (v->counter), "=qm" (c)
26556 - : "ir" (i) : "memory");
26557 - return c;
26558 -@@ -181,7 +261,15 @@ static inline int atomic_add_return(int
26559 - #endif
26560 - /* Modern 486+ processor */
26561 - __i = i;
26562 -- asm volatile(LOCK_PREFIX "xaddl %0, %1"
26563 -+ asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
26564 -+
26565 -+#ifdef CONFIG_PAX_REFCOUNT
26566 -+ "jno 0f\n"
26567 -+ "movl %0, %1\n"
26568 -+ "into\n0:\n"
26569 -+ _ASM_EXTABLE(0b, 0b)
26570 -+#endif
26571 -+
26572 - : "+r" (i), "+m" (v->counter)
26573 - : : "memory");
26574 - return i + __i;
26575 -diff -urNp linux-2.6.27.6/include/asm-x86/atomic_64.h linux-2.6.27.6/include/asm-x86/atomic_64.h
26576 ---- linux-2.6.27.6/include/asm-x86/atomic_64.h 2008-11-07 12:55:34.000000000 -0500
26577 -+++ linux-2.6.27.6/include/asm-x86/atomic_64.h 2008-11-18 03:38:45.000000000 -0500
26578 -@@ -48,7 +48,15 @@ typedef struct {
26579 - */
26580 - static inline void atomic_add(int i, atomic_t *v)
26581 - {
26582 -- asm volatile(LOCK_PREFIX "addl %1,%0"
26583 -+ asm volatile(LOCK_PREFIX "addl %1,%0\n"
26584 -+
26585 -+#ifdef CONFIG_PAX_REFCOUNT
26586 -+ "jno 0f\n"
26587 -+ LOCK_PREFIX "subl %1,%0\n"
26588 -+ "int $4\n0:\n"
26589 -+ _ASM_EXTABLE(0b, 0b)
26590 -+#endif
26591 -+
26592 - : "=m" (v->counter)
26593 - : "ir" (i), "m" (v->counter));
26594 - }
26595 -@@ -62,7 +70,15 @@ static inline void atomic_add(int i, ato
26596 - */
26597 - static inline void atomic_sub(int i, atomic_t *v)
26598 - {
26599 -- asm volatile(LOCK_PREFIX "subl %1,%0"
26600 -+ asm volatile(LOCK_PREFIX "subl %1,%0\n"
26601 -+
26602 -+#ifdef CONFIG_PAX_REFCOUNT
26603 -+ "jno 0f\n"
26604 -+ LOCK_PREFIX "addl %1,%0\n"
26605 -+ "int $4\n0:\n"
26606 -+ _ASM_EXTABLE(0b, 0b)
26607 -+#endif
26608 -+
26609 - : "=m" (v->counter)
26610 - : "ir" (i), "m" (v->counter));
26611 - }
26612 -@@ -80,7 +96,16 @@ static inline int atomic_sub_and_test(in
26613 - {
26614 - unsigned char c;
26615 -
26616 -- asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
26617 -+ asm volatile(LOCK_PREFIX "subl %2,%0\n"
26618 -+
26619 -+#ifdef CONFIG_PAX_REFCOUNT
26620 -+ "jno 0f\n"
26621 -+ LOCK_PREFIX "addl %2,%0\n"
26622 -+ "int $4\n0:\n"
26623 -+ _ASM_EXTABLE(0b, 0b)
26624 -+#endif
26625 -+
26626 -+ "sete %1\n"
26627 - : "=m" (v->counter), "=qm" (c)
26628 - : "ir" (i), "m" (v->counter) : "memory");
26629 - return c;
26630 -@@ -94,7 +119,19 @@ static inline int atomic_sub_and_test(in
26631 - */
26632 - static inline void atomic_inc(atomic_t *v)
26633 - {
26634 -- asm volatile(LOCK_PREFIX "incl %0"
26635 -+ asm volatile(LOCK_PREFIX "incl %0\n"
26636 -+
26637 -+#ifdef CONFIG_PAX_REFCOUNT
26638 -+ "jno 0f\n"
26639 -+ "int $4\n0:\n"
26640 -+ ".pushsection .fixup,\"ax\"\n"
26641 -+ "1:\n"
26642 -+ LOCK_PREFIX "decl %0\n"
26643 -+ "jmp 0b\n"
26644 -+ ".popsection\n"
26645 -+ _ASM_EXTABLE(0b, 1b)
26646 -+#endif
26647 -+
26648 - : "=m" (v->counter)
26649 - : "m" (v->counter));
26650 - }
26651 -@@ -107,7 +144,19 @@ static inline void atomic_inc(atomic_t *
26652 - */
26653 - static inline void atomic_dec(atomic_t *v)
26654 - {
26655 -- asm volatile(LOCK_PREFIX "decl %0"
26656 -+ asm volatile(LOCK_PREFIX "decl %0\n"
26657 -+
26658 -+#ifdef CONFIG_PAX_REFCOUNT
26659 -+ "jno 0f\n"
26660 -+ "int $4\n0:\n"
26661 -+ ".pushsection .fixup,\"ax\"\n"
26662 -+ "1: \n"
26663 -+ LOCK_PREFIX "incl %0\n"
26664 -+ "jmp 0b\n"
26665 -+ ".popsection\n"
26666 -+ _ASM_EXTABLE(0b, 1b)
26667 -+#endif
26668 -+
26669 - : "=m" (v->counter)
26670 - : "m" (v->counter));
26671 - }
26672 -@@ -124,7 +173,20 @@ static inline int atomic_dec_and_test(at
26673 - {
26674 - unsigned char c;
26675 -
26676 -- asm volatile(LOCK_PREFIX "decl %0; sete %1"
26677 -+ asm volatile(LOCK_PREFIX "decl %0\n"
26678 -+
26679 -+#ifdef CONFIG_PAX_REFCOUNT
26680 -+ "jno 0f\n"
26681 -+ "int $4\n0:\n"
26682 -+ ".pushsection .fixup,\"ax\"\n"
26683 -+ "1: \n"
26684 -+ LOCK_PREFIX "incl %0\n"
26685 -+ "jmp 0b\n"
26686 -+ ".popsection\n"
26687 -+ _ASM_EXTABLE(0b, 1b)
26688 -+#endif
26689 -+
26690 -+ "sete %1\n"
26691 - : "=m" (v->counter), "=qm" (c)
26692 - : "m" (v->counter) : "memory");
26693 - return c != 0;
26694 -@@ -142,7 +204,20 @@ static inline int atomic_inc_and_test(at
26695 - {
26696 - unsigned char c;
26697 -
26698 -- asm volatile(LOCK_PREFIX "incl %0; sete %1"
26699 -+ asm volatile(LOCK_PREFIX "incl %0\n"
26700 -+
26701 -+#ifdef CONFIG_PAX_REFCOUNT
26702 -+ "jno 0f\n"
26703 -+ "int $4\n0:\n"
26704 -+ ".pushsection .fixup,\"ax\"\n"
26705 -+ "1: \n"
26706 -+ LOCK_PREFIX "decl %0\n"
26707 -+ "jmp 0b\n"
26708 -+ ".popsection\n"
26709 -+ _ASM_EXTABLE(0b, 1b)
26710 -+#endif
26711 -+
26712 -+ "sete %1\n"
26713 - : "=m" (v->counter), "=qm" (c)
26714 - : "m" (v->counter) : "memory");
26715 - return c != 0;
26716 -@@ -161,7 +236,16 @@ static inline int atomic_add_negative(in
26717 - {
26718 - unsigned char c;
26719 -
26720 -- asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
26721 -+ asm volatile(LOCK_PREFIX "addl %2,%0\n"
26722 -+
26723 -+#ifdef CONFIG_PAX_REFCOUNT
26724 -+ "jno 0f\n"
26725 -+ LOCK_PREFIX "subl %2,%0\n"
26726 -+ "int $4\n0:\n"
26727 -+ _ASM_EXTABLE(0b, 0b)
26728 -+#endif
26729 -+
26730 -+ "sets %1\n"
26731 - : "=m" (v->counter), "=qm" (c)
26732 - : "ir" (i), "m" (v->counter) : "memory");
26733 - return c;
26734 -@@ -177,7 +261,15 @@ static inline int atomic_add_negative(in
26735 - static inline int atomic_add_return(int i, atomic_t *v)
26736 - {
26737 - int __i = i;
26738 -- asm volatile(LOCK_PREFIX "xaddl %0, %1"
26739 -+ asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
26740 -+
26741 -+#ifdef CONFIG_PAX_REFCOUNT
26742 -+ "jno 0f\n"
26743 -+ "movl %0, %1\n"
26744 -+ "int $4\n0:\n"
26745 -+ _ASM_EXTABLE(0b, 0b)
26746 -+#endif
26747 -+
26748 - : "+r" (i), "+m" (v->counter)
26749 - : : "memory");
26750 - return i + __i;
26751 -@@ -226,7 +318,15 @@ typedef struct {
26752 - */
26753 - static inline void atomic64_add(long i, atomic64_t *v)
26754 - {
26755 -- asm volatile(LOCK_PREFIX "addq %1,%0"
26756 -+ asm volatile(LOCK_PREFIX "addq %1,%0\n"
26757 -+
26758 -+#ifdef CONFIG_PAX_REFCOUNT
26759 -+ "jno 0f\n"
26760 -+ LOCK_PREFIX "subq %1,%0\n"
26761 -+ "int $4\n0:\n"
26762 -+ _ASM_EXTABLE(0b, 0b)
26763 -+#endif
26764 -+
26765 - : "=m" (v->counter)
26766 - : "er" (i), "m" (v->counter));
26767 - }
26768 -@@ -240,7 +340,15 @@ static inline void atomic64_add(long i,
26769 - */
26770 - static inline void atomic64_sub(long i, atomic64_t *v)
26771 - {
26772 -- asm volatile(LOCK_PREFIX "subq %1,%0"
26773 -+ asm volatile(LOCK_PREFIX "subq %1,%0\n"
26774 -+
26775 -+#ifdef CONFIG_PAX_REFCOUNT
26776 -+ "jno 0f\n"
26777 -+ LOCK_PREFIX "addq %1,%0\n"
26778 -+ "int $4\n0:\n"
26779 -+ _ASM_EXTABLE(0b, 0b)
26780 -+#endif
26781 -+
26782 - : "=m" (v->counter)
26783 - : "er" (i), "m" (v->counter));
26784 - }
26785 -@@ -258,7 +366,16 @@ static inline int atomic64_sub_and_test(
26786 - {
26787 - unsigned char c;
26788 -
26789 -- asm volatile(LOCK_PREFIX "subq %2,%0; sete %1"
26790 -+ asm volatile(LOCK_PREFIX "subq %2,%0\n"
26791 -+
26792 -+#ifdef CONFIG_PAX_REFCOUNT
26793 -+ "jno 0f\n"
26794 -+ LOCK_PREFIX "addq %2,%0\n"
26795 -+ "int $4\n0:\n"
26796 -+ _ASM_EXTABLE(0b, 0b)
26797 -+#endif
26798 -+
26799 -+ "sete %1\n"
26800 - : "=m" (v->counter), "=qm" (c)
26801 - : "er" (i), "m" (v->counter) : "memory");
26802 - return c;
26803 -@@ -272,7 +389,19 @@ static inline int atomic64_sub_and_test(
26804 - */
26805 - static inline void atomic64_inc(atomic64_t *v)
26806 - {
26807 -- asm volatile(LOCK_PREFIX "incq %0"
26808 -+ asm volatile(LOCK_PREFIX "incq %0\n"
26809 -+
26810 -+#ifdef CONFIG_PAX_REFCOUNT
26811 -+ "jno 0f\n"
26812 -+ "int $4\n0:\n"
26813 -+ ".pushsection .fixup,\"ax\"\n"
26814 -+ "1:\n"
26815 -+ LOCK_PREFIX "decq %0\n"
26816 -+ "jmp 0b\n"
26817 -+ ".popsection\n"
26818 -+ _ASM_EXTABLE(0b, 1b)
26819 -+#endif
26820 -+
26821 - : "=m" (v->counter)
26822 - : "m" (v->counter));
26823 - }
26824 -@@ -285,7 +414,19 @@ static inline void atomic64_inc(atomic64
26825 - */
26826 - static inline void atomic64_dec(atomic64_t *v)
26827 - {
26828 -- asm volatile(LOCK_PREFIX "decq %0"
26829 -+ asm volatile(LOCK_PREFIX "decq %0\n"
26830 -+
26831 -+#ifdef CONFIG_PAX_REFCOUNT
26832 -+ "jno 0f\n"
26833 -+ "int $4\n0:\n"
26834 -+ ".pushsection .fixup,\"ax\"\n"
26835 -+ "1: \n"
26836 -+ LOCK_PREFIX "incq %0\n"
26837 -+ "jmp 0b\n"
26838 -+ ".popsection\n"
26839 -+ _ASM_EXTABLE(0b, 1b)
26840 -+#endif
26841 -+
26842 - : "=m" (v->counter)
26843 - : "m" (v->counter));
26844 - }
26845 -@@ -302,7 +443,20 @@ static inline int atomic64_dec_and_test(
26846 - {
26847 - unsigned char c;
26848 -
26849 -- asm volatile(LOCK_PREFIX "decq %0; sete %1"
26850 -+ asm volatile(LOCK_PREFIX "decq %0\n"
26851 -+
26852 -+#ifdef CONFIG_PAX_REFCOUNT
26853 -+ "jno 0f\n"
26854 -+ "int $4\n0:\n"
26855 -+ ".pushsection .fixup,\"ax\"\n"
26856 -+ "1: \n"
26857 -+ LOCK_PREFIX "incq %0\n"
26858 -+ "jmp 0b\n"
26859 -+ ".popsection\n"
26860 -+ _ASM_EXTABLE(0b, 1b)
26861 -+#endif
26862 -+
26863 -+ "sete %1\n"
26864 - : "=m" (v->counter), "=qm" (c)
26865 - : "m" (v->counter) : "memory");
26866 - return c != 0;
26867 -@@ -320,7 +474,20 @@ static inline int atomic64_inc_and_test(
26868 - {
26869 - unsigned char c;
26870 -
26871 -- asm volatile(LOCK_PREFIX "incq %0; sete %1"
26872 -+ asm volatile(LOCK_PREFIX "incq %0\n"
26873 -+
26874 -+#ifdef CONFIG_PAX_REFCOUNT
26875 -+ "jno 0f\n"
26876 -+ "int $4\n0:\n"
26877 -+ ".pushsection .fixup,\"ax\"\n"
26878 -+ "1: \n"
26879 -+ LOCK_PREFIX "decq %0\n"
26880 -+ "jmp 0b\n"
26881 -+ ".popsection\n"
26882 -+ _ASM_EXTABLE(0b, 1b)
26883 -+#endif
26884 -+
26885 -+ "sete %1\n"
26886 - : "=m" (v->counter), "=qm" (c)
26887 - : "m" (v->counter) : "memory");
26888 - return c != 0;
26889 -@@ -339,7 +506,16 @@ static inline int atomic64_add_negative(
26890 - {
26891 - unsigned char c;
26892 -
26893 -- asm volatile(LOCK_PREFIX "addq %2,%0; sets %1"
26894 -+ asm volatile(LOCK_PREFIX "addq %2,%0\n"
26895 -+
26896 -+#ifdef CONFIG_PAX_REFCOUNT
26897 -+ "jno 0f\n"
26898 -+ LOCK_PREFIX "subq %2,%0\n"
26899 -+ "int $4\n0:\n"
26900 -+ _ASM_EXTABLE(0b, 0b)
26901 -+#endif
26902 -+
26903 -+ "sets %1\n"
26904 - : "=m" (v->counter), "=qm" (c)
26905 - : "er" (i), "m" (v->counter) : "memory");
26906 - return c;
26907 -@@ -355,7 +531,15 @@ static inline int atomic64_add_negative(
26908 - static inline long atomic64_add_return(long i, atomic64_t *v)
26909 - {
26910 - long __i = i;
26911 -- asm volatile(LOCK_PREFIX "xaddq %0, %1;"
26912 -+ asm volatile(LOCK_PREFIX "xaddq %0, %1\n"
26913 -+
26914 -+#ifdef CONFIG_PAX_REFCOUNT
26915 -+ "jno 0f\n"
26916 -+ "movq %0, %1\n"
26917 -+ "int $4\n0:\n"
26918 -+ _ASM_EXTABLE(0b, 0b)
26919 -+#endif
26920 -+
26921 - : "+r" (i), "+m" (v->counter)
26922 - : : "memory");
26923 - return i + __i;
26924 -diff -urNp linux-2.6.27.6/include/asm-x86/boot.h linux-2.6.27.6/include/asm-x86/boot.h
26925 ---- linux-2.6.27.6/include/asm-x86/boot.h 2008-11-07 12:55:34.000000000 -0500
26926 -+++ linux-2.6.27.6/include/asm-x86/boot.h 2008-11-18 03:38:45.000000000 -0500
26927 -@@ -13,10 +13,15 @@
26928 - #define ASK_VGA 0xfffd /* ask for it at bootup */
26929 -
26930 - /* Physical address where kernel should be loaded. */
26931 --#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
26932 -+#define ____LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
26933 - + (CONFIG_PHYSICAL_ALIGN - 1)) \
26934 - & ~(CONFIG_PHYSICAL_ALIGN - 1))
26935 -
26936 -+#ifndef __ASSEMBLY__
26937 -+extern unsigned char __LOAD_PHYSICAL_ADDR[];
26938 -+#define LOAD_PHYSICAL_ADDR ((unsigned long)__LOAD_PHYSICAL_ADDR)
26939 -+#endif
26940 -+
26941 - #ifdef CONFIG_X86_64
26942 - #define BOOT_HEAP_SIZE 0x7000
26943 - #define BOOT_STACK_SIZE 0x4000
26944 -diff -urNp linux-2.6.27.6/include/asm-x86/cache.h linux-2.6.27.6/include/asm-x86/cache.h
26945 ---- linux-2.6.27.6/include/asm-x86/cache.h 2008-11-07 12:55:34.000000000 -0500
26946 -+++ linux-2.6.27.6/include/asm-x86/cache.h 2008-11-18 03:38:45.000000000 -0500
26947 -@@ -6,6 +6,7 @@
26948 - #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
26949 -
26950 - #define __read_mostly __attribute__((__section__(".data.read_mostly")))
26951 -+#define __read_only __attribute__((__section__(".data.read_only")))
26952 -
26953 - #ifdef CONFIG_X86_VSMP
26954 - /* vSMP Internode cacheline shift */
26955 -diff -urNp linux-2.6.27.6/include/asm-x86/checksum_32.h linux-2.6.27.6/include/asm-x86/checksum_32.h
26956 ---- linux-2.6.27.6/include/asm-x86/checksum_32.h 2008-11-07 12:55:34.000000000 -0500
26957 -+++ linux-2.6.27.6/include/asm-x86/checksum_32.h 2008-11-18 03:38:45.000000000 -0500
26958 -@@ -31,6 +31,14 @@ asmlinkage __wsum csum_partial_copy_gene
26959 - int len, __wsum sum,
26960 - int *src_err_ptr, int *dst_err_ptr);
26961 -
26962 -+asmlinkage __wsum csum_partial_copy_generic_to_user(const void *src, void *dst,
26963 -+ int len, __wsum sum,
26964 -+ int *src_err_ptr, int *dst_err_ptr);
26965 -+
26966 -+asmlinkage __wsum csum_partial_copy_generic_from_user(const void *src, void *dst,
26967 -+ int len, __wsum sum,
26968 -+ int *src_err_ptr, int *dst_err_ptr);
26969 -+
26970 - /*
26971 - * Note: when you get a NULL pointer exception here this means someone
26972 - * passed in an incorrect kernel address to one of these functions.
26973 -@@ -50,7 +58,7 @@ static inline __wsum csum_partial_copy_f
26974 - int *err_ptr)
26975 - {
26976 - might_sleep();
26977 -- return csum_partial_copy_generic((__force void *)src, dst,
26978 -+ return csum_partial_copy_generic_from_user((__force void *)src, dst,
26979 - len, sum, err_ptr, NULL);
26980 - }
26981 -
26982 -@@ -177,7 +185,7 @@ static inline __wsum csum_and_copy_to_us
26983 - {
26984 - might_sleep();
26985 - if (access_ok(VERIFY_WRITE, dst, len))
26986 -- return csum_partial_copy_generic(src, (__force void *)dst,
26987 -+ return csum_partial_copy_generic_to_user(src, (__force void *)dst,
26988 - len, sum, NULL, err_ptr);
26989 -
26990 - if (len)
26991 -diff -urNp linux-2.6.27.6/include/asm-x86/desc.h linux-2.6.27.6/include/asm-x86/desc.h
26992 ---- linux-2.6.27.6/include/asm-x86/desc.h 2008-11-07 12:55:34.000000000 -0500
26993 -+++ linux-2.6.27.6/include/asm-x86/desc.h 2008-11-18 03:38:45.000000000 -0500
26994 -@@ -16,6 +16,7 @@ static inline void fill_ldt(struct desc_
26995 - desc->base1 = (info->base_addr & 0x00ff0000) >> 16;
26996 - desc->type = (info->read_exec_only ^ 1) << 1;
26997 - desc->type |= info->contents << 2;
26998 -+ desc->type |= info->seg_not_present ^ 1;
26999 - desc->s = 1;
27000 - desc->dpl = 0x3;
27001 - desc->p = info->seg_not_present ^ 1;
27002 -@@ -27,16 +28,12 @@ static inline void fill_ldt(struct desc_
27003 - }
27004 -
27005 - extern struct desc_ptr idt_descr;
27006 --extern gate_desc idt_table[];
27007 --
27008 --struct gdt_page {
27009 -- struct desc_struct gdt[GDT_ENTRIES];
27010 --} __attribute__((aligned(PAGE_SIZE)));
27011 --DECLARE_PER_CPU(struct gdt_page, gdt_page);
27012 -+extern gate_desc idt_table[256];
27013 -
27014 -+extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
27015 - static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
27016 - {
27017 -- return per_cpu(gdt_page, cpu).gdt;
27018 -+ return cpu_gdt_table[cpu];
27019 - }
27020 -
27021 - #ifdef CONFIG_X86_64
27022 -@@ -65,7 +62,6 @@ static inline void pack_gate(gate_desc *
27023 - gate->b = (base & 0xffff0000) |
27024 - (((0x80 | type | (dpl << 5)) & 0xff) << 8);
27025 - }
27026 --
27027 - #endif
27028 -
27029 - static inline int desc_empty(const void *ptr)
27030 -@@ -102,19 +98,48 @@ static inline int desc_empty(const void
27031 - static inline void native_write_idt_entry(gate_desc *idt, int entry,
27032 - const gate_desc *gate)
27033 - {
27034 -+
27035 -+#ifdef CONFIG_PAX_KERNEXEC
27036 -+ unsigned long cr0;
27037 -+
27038 -+ pax_open_kernel(cr0);
27039 -+#endif
27040 -+
27041 - memcpy(&idt[entry], gate, sizeof(*gate));
27042 -+
27043 -+#ifdef CONFIG_PAX_KERNEXEC
27044 -+ pax_close_kernel(cr0);
27045 -+#endif
27046 -+
27047 - }
27048 -
27049 - static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry,
27050 - const void *desc)
27051 - {
27052 -+
27053 -+#ifdef CONFIG_PAX_KERNEXEC
27054 -+ unsigned long cr0;
27055 -+
27056 -+ pax_open_kernel(cr0);
27057 -+#endif
27058 -+
27059 - memcpy(&ldt[entry], desc, 8);
27060 -+
27061 -+#ifdef CONFIG_PAX_KERNEXEC
27062 -+ pax_close_kernel(cr0);
27063 -+#endif
27064 -+
27065 - }
27066 -
27067 - static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry,
27068 - const void *desc, int type)
27069 - {
27070 - unsigned int size;
27071 -+
27072 -+#ifdef CONFIG_PAX_KERNEXEC
27073 -+ unsigned long cr0;
27074 -+#endif
27075 -+
27076 - switch (type) {
27077 - case DESC_TSS:
27078 - size = sizeof(tss_desc);
27079 -@@ -126,7 +151,17 @@ static inline void native_write_gdt_entr
27080 - size = sizeof(struct desc_struct);
27081 - break;
27082 - }
27083 -+
27084 -+#ifdef CONFIG_PAX_KERNEXEC
27085 -+ pax_open_kernel(cr0);
27086 -+#endif
27087 -+
27088 - memcpy(&gdt[entry], desc, size);
27089 -+
27090 -+#ifdef CONFIG_PAX_KERNEXEC
27091 -+ pax_close_kernel(cr0);
27092 -+#endif
27093 -+
27094 - }
27095 -
27096 - static inline void pack_descriptor(struct desc_struct *desc, unsigned long base,
27097 -@@ -198,7 +233,19 @@ static inline void native_set_ldt(const
27098 -
27099 - static inline void native_load_tr_desc(void)
27100 - {
27101 -+
27102 -+#ifdef CONFIG_PAX_KERNEXEC
27103 -+ unsigned long cr0;
27104 -+
27105 -+ pax_open_kernel(cr0);
27106 -+#endif
27107 -+
27108 - asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
27109 -+
27110 -+#ifdef CONFIG_PAX_KERNEXEC
27111 -+ pax_close_kernel(cr0);
27112 -+#endif
27113 -+
27114 - }
27115 -
27116 - static inline void native_load_gdt(const struct desc_ptr *dtr)
27117 -@@ -233,8 +280,19 @@ static inline void native_load_tls(struc
27118 - unsigned int i;
27119 - struct desc_struct *gdt = get_cpu_gdt_table(cpu);
27120 -
27121 -+#ifdef CONFIG_PAX_KERNEXEC
27122 -+ unsigned long cr0;
27123 -+
27124 -+ pax_open_kernel(cr0);
27125 -+#endif
27126 -+
27127 - for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
27128 - gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
27129 -+
27130 -+#ifdef CONFIG_PAX_KERNEXEC
27131 -+ pax_close_kernel(cr0);
27132 -+#endif
27133 -+
27134 - }
27135 -
27136 - #define _LDT_empty(info) \
27137 -@@ -372,6 +430,18 @@ static inline void set_system_gate_ist(i
27138 - _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS);
27139 - }
27140 -
27141 -+#ifdef CONFIG_X86_32
27142 -+static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
27143 -+{
27144 -+ struct desc_struct d;
27145 -+
27146 -+ if (likely(limit))
27147 -+ limit = (limit - 1UL) >> PAGE_SHIFT;
27148 -+ pack_descriptor(&d, base, limit, 0xFB, 0xC);
27149 -+ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, &d, DESCTYPE_S);
27150 -+}
27151 -+#endif
27152 -+
27153 - #else
27154 - /*
27155 - * GET_DESC_BASE reads the descriptor base of the specified segment.
27156 -diff -urNp linux-2.6.27.6/include/asm-x86/e820.h linux-2.6.27.6/include/asm-x86/e820.h
27157 ---- linux-2.6.27.6/include/asm-x86/e820.h 2008-11-07 12:55:34.000000000 -0500
27158 -+++ linux-2.6.27.6/include/asm-x86/e820.h 2008-11-18 03:38:45.000000000 -0500
27159 -@@ -131,7 +131,7 @@ extern char *memory_setup(void);
27160 - #define ISA_END_ADDRESS 0x100000
27161 - #define is_ISA_range(s, e) ((s) >= ISA_START_ADDRESS && (e) < ISA_END_ADDRESS)
27162 -
27163 --#define BIOS_BEGIN 0x000a0000
27164 -+#define BIOS_BEGIN 0x000c0000
27165 - #define BIOS_END 0x00100000
27166 -
27167 - #ifdef __KERNEL__
27168 -diff -urNp linux-2.6.27.6/include/asm-x86/elf.h linux-2.6.27.6/include/asm-x86/elf.h
27169 ---- linux-2.6.27.6/include/asm-x86/elf.h 2008-11-07 12:55:34.000000000 -0500
27170 -+++ linux-2.6.27.6/include/asm-x86/elf.h 2008-11-18 03:38:45.000000000 -0500
27171 -@@ -251,7 +251,25 @@ extern int force_personality32;
27172 - the loader. We need to make sure that it is out of the way of the program
27173 - that it will "exec", and that there is sufficient room for the brk. */
27174 -
27175 -+#ifdef CONFIG_PAX_SEGMEXEC
27176 -+#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
27177 -+#else
27178 - #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
27179 -+#endif
27180 -+
27181 -+#ifdef CONFIG_PAX_ASLR
27182 -+#ifdef CONFIG_X86_32
27183 -+#define PAX_ELF_ET_DYN_BASE 0x10000000UL
27184 -+
27185 -+#define PAX_DELTA_MMAP_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
27186 -+#define PAX_DELTA_STACK_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
27187 -+#else
27188 -+#define PAX_ELF_ET_DYN_BASE 0x400000UL
27189 -+
27190 -+#define PAX_DELTA_MMAP_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
27191 -+#define PAX_DELTA_STACK_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
27192 -+#endif
27193 -+#endif
27194 -
27195 - /* This yields a mask that user programs can use to figure out what
27196 - instruction set this CPU supports. This could be done in user space,
27197 -@@ -303,8 +321,7 @@ do { \
27198 - #define ARCH_DLINFO \
27199 - do { \
27200 - if (vdso_enabled) \
27201 -- NEW_AUX_ENT(AT_SYSINFO_EHDR, \
27202 -- (unsigned long)current->mm->context.vdso); \
27203 -+ NEW_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso);\
27204 - } while (0)
27205 -
27206 - #define AT_SYSINFO 32
27207 -@@ -315,7 +332,7 @@ do { \
27208 -
27209 - #endif /* !CONFIG_X86_32 */
27210 -
27211 --#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
27212 -+#define VDSO_CURRENT_BASE (current->mm->context.vdso)
27213 -
27214 - #define VDSO_ENTRY \
27215 - ((unsigned long)VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall))
27216 -@@ -329,7 +346,4 @@ extern int arch_setup_additional_pages(s
27217 - extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
27218 - #define compat_arch_setup_additional_pages syscall32_setup_pages
27219 -
27220 --extern unsigned long arch_randomize_brk(struct mm_struct *mm);
27221 --#define arch_randomize_brk arch_randomize_brk
27222 --
27223 - #endif
27224 -diff -urNp linux-2.6.27.6/include/asm-x86/futex.h linux-2.6.27.6/include/asm-x86/futex.h
27225 ---- linux-2.6.27.6/include/asm-x86/futex.h 2008-11-07 12:55:34.000000000 -0500
27226 -+++ linux-2.6.27.6/include/asm-x86/futex.h 2008-11-18 03:38:45.000000000 -0500
27227 -@@ -11,6 +11,40 @@
27228 - #include <asm/processor.h>
27229 - #include <asm/system.h>
27230 -
27231 -+#ifdef CONFIG_X86_32
27232 -+#define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
27233 -+ asm volatile( \
27234 -+ "movw\t%w6, %%ds\n" \
27235 -+ "1:\t" insn "\n" \
27236 -+ "2:\tpushl\t%%ss\n" \
27237 -+ "\tpopl\t%%ds\n" \
27238 -+ "\t.section .fixup,\"ax\"\n" \
27239 -+ "3:\tmov\t%3, %1\n" \
27240 -+ "\tjmp\t2b\n" \
27241 -+ "\t.previous\n" \
27242 -+ _ASM_EXTABLE(1b, 3b) \
27243 -+ : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
27244 -+ : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS))
27245 -+
27246 -+#define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
27247 -+ asm volatile("movw\t%w7, %%es\n" \
27248 -+ "1:\tmovl\t%%es:%2, %0\n" \
27249 -+ "\tmovl\t%0, %3\n" \
27250 -+ "\t" insn "\n" \
27251 -+ "2:\tlock; cmpxchgl %3, %%es:%2\n" \
27252 -+ "\tjnz\t1b\n" \
27253 -+ "3:\tpushl\t%%ss\n" \
27254 -+ "\tpopl\t%%es\n" \
27255 -+ "\t.section .fixup,\"ax\"\n" \
27256 -+ "4:\tmov\t%5, %1\n" \
27257 -+ "\tjmp\t3b\n" \
27258 -+ "\t.previous\n" \
27259 -+ _ASM_EXTABLE(1b, 4b) \
27260 -+ _ASM_EXTABLE(2b, 4b) \
27261 -+ : "=&a" (oldval), "=&r" (ret), \
27262 -+ "+m" (*uaddr), "=&r" (tem) \
27263 -+ : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS))
27264 -+#else
27265 - #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
27266 - asm volatile("1:\t" insn "\n" \
27267 - "2:\t.section .fixup,\"ax\"\n" \
27268 -@@ -36,8 +70,9 @@
27269 - : "=&a" (oldval), "=&r" (ret), \
27270 - "+m" (*uaddr), "=&r" (tem) \
27271 - : "r" (oparg), "i" (-EFAULT), "1" (0))
27272 -+#endif
27273 -
27274 --static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
27275 -+static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
27276 - {
27277 - int op = (encoded_op >> 28) & 7;
27278 - int cmp = (encoded_op >> 24) & 15;
27279 -@@ -61,11 +96,20 @@ static inline int futex_atomic_op_inuser
27280 -
27281 - switch (op) {
27282 - case FUTEX_OP_SET:
27283 -+#ifdef CONFIG_X86_32
27284 -+ __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg);
27285 -+#else
27286 - __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
27287 -+#endif
27288 - break;
27289 - case FUTEX_OP_ADD:
27290 -+#ifdef CONFIG_X86_32
27291 -+ __futex_atomic_op1("lock ; xaddl %0, %%ds:%2", ret, oldval,
27292 -+ uaddr, oparg);
27293 -+#else
27294 - __futex_atomic_op1("lock; xaddl %0, %2", ret, oldval,
27295 - uaddr, oparg);
27296 -+#endif
27297 - break;
27298 - case FUTEX_OP_OR:
27299 - __futex_atomic_op2("orl %4, %3", ret, oldval, uaddr, oparg);
27300 -@@ -109,7 +153,7 @@ static inline int futex_atomic_op_inuser
27301 - return ret;
27302 - }
27303 -
27304 --static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval,
27305 -+static inline int futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval,
27306 - int newval)
27307 - {
27308 -
27309 -@@ -122,14 +166,27 @@ static inline int futex_atomic_cmpxchg_i
27310 - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
27311 - return -EFAULT;
27312 -
27313 -- asm volatile("1:\tlock; cmpxchgl %3, %1\n"
27314 -+ asm volatile(
27315 -+#ifdef CONFIG_X86_32
27316 -+ "\tmovw %w5, %%ds\n"
27317 -+ "1:\tlock; cmpxchgl %3, %1\n"
27318 -+ "2:\tpushl %%ss\n"
27319 -+ "\tpopl %%ds\n"
27320 -+ "\t.section .fixup, \"ax\"\n"
27321 -+#else
27322 -+ "1:\tlock; cmpxchgl %3, %1\n"
27323 - "2:\t.section .fixup, \"ax\"\n"
27324 -+#endif
27325 - "3:\tmov %2, %0\n"
27326 - "\tjmp 2b\n"
27327 - "\t.previous\n"
27328 - _ASM_EXTABLE(1b, 3b)
27329 - : "=a" (oldval), "+m" (*uaddr)
27330 -+#ifdef CONFIG_X86_32
27331 -+ : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS)
27332 -+#else
27333 - : "i" (-EFAULT), "r" (newval), "0" (oldval)
27334 -+#endif
27335 - : "memory"
27336 - );
27337 -
27338 -diff -urNp linux-2.6.27.6/include/asm-x86/i387.h linux-2.6.27.6/include/asm-x86/i387.h
27339 ---- linux-2.6.27.6/include/asm-x86/i387.h 2008-11-07 12:55:34.000000000 -0500
27340 -+++ linux-2.6.27.6/include/asm-x86/i387.h 2008-11-18 03:38:45.000000000 -0500
27341 -@@ -159,13 +159,8 @@ static inline void restore_fpu(struct ta
27342 - }
27343 -
27344 - /* We need a safe address that is cheap to find and that is already
27345 -- in L1 during context switch. The best choices are unfortunately
27346 -- different for UP and SMP */
27347 --#ifdef CONFIG_SMP
27348 --#define safe_address (__per_cpu_offset[0])
27349 --#else
27350 --#define safe_address (kstat_cpu(0).cpustat.user)
27351 --#endif
27352 -+ in L1 during context switch. */
27353 -+#define safe_address (init_tss[smp_processor_id()].x86_tss.sp0)
27354 -
27355 - /*
27356 - * These must be called with preempt disabled
27357 -diff -urNp linux-2.6.27.6/include/asm-x86/io_64.h linux-2.6.27.6/include/asm-x86/io_64.h
27358 ---- linux-2.6.27.6/include/asm-x86/io_64.h 2008-11-07 12:55:34.000000000 -0500
27359 -+++ linux-2.6.27.6/include/asm-x86/io_64.h 2008-11-18 03:38:45.000000000 -0500
27360 -@@ -158,6 +158,17 @@ static inline void *phys_to_virt(unsigne
27361 - }
27362 - #endif
27363 -
27364 -+#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
27365 -+static inline int valid_phys_addr_range (unsigned long addr, size_t count)
27366 -+{
27367 -+ return ((addr + count + PAGE_SIZE - 1) >> PAGE_SHIFT) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
27368 -+}
27369 -+
27370 -+static inline int valid_mmap_phys_addr_range (unsigned long pfn, size_t count)
27371 -+{
27372 -+ return (pfn + (count >> PAGE_SHIFT)) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
27373 -+}
27374 -+
27375 - /*
27376 - * Change "struct page" to physical address.
27377 - */
27378 -diff -urNp linux-2.6.27.6/include/asm-x86/irqflags.h linux-2.6.27.6/include/asm-x86/irqflags.h
27379 ---- linux-2.6.27.6/include/asm-x86/irqflags.h 2008-11-07 12:55:34.000000000 -0500
27380 -+++ linux-2.6.27.6/include/asm-x86/irqflags.h 2008-11-18 03:38:45.000000000 -0500
27381 -@@ -141,6 +141,8 @@ static inline unsigned long __raw_local_
27382 - #define INTERRUPT_RETURN iret
27383 - #define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit
27384 - #define GET_CR0_INTO_EAX movl %cr0, %eax
27385 -+#define GET_CR0_INTO_EDX movl %cr0, %edx
27386 -+#define SET_CR0_FROM_EDX movl %edx, %cr0
27387 - #endif
27388 -
27389 -
27390 -diff -urNp linux-2.6.27.6/include/asm-x86/kmap_types.h linux-2.6.27.6/include/asm-x86/kmap_types.h
27391 ---- linux-2.6.27.6/include/asm-x86/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
27392 -+++ linux-2.6.27.6/include/asm-x86/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
27393 -@@ -21,7 +21,8 @@ D(9) KM_IRQ0,
27394 - D(10) KM_IRQ1,
27395 - D(11) KM_SOFTIRQ0,
27396 - D(12) KM_SOFTIRQ1,
27397 --D(13) KM_TYPE_NR
27398 -+D(13) KM_CLEARPAGE,
27399 -+D(14) KM_TYPE_NR
27400 - };
27401 -
27402 - #undef D
27403 -diff -urNp linux-2.6.27.6/include/asm-x86/linkage.h linux-2.6.27.6/include/asm-x86/linkage.h
27404 ---- linux-2.6.27.6/include/asm-x86/linkage.h 2008-11-07 12:55:34.000000000 -0500
27405 -+++ linux-2.6.27.6/include/asm-x86/linkage.h 2008-11-18 03:38:45.000000000 -0500
27406 -@@ -7,6 +7,11 @@
27407 - #ifdef CONFIG_X86_64
27408 - #define __ALIGN .p2align 4,,15
27409 - #define __ALIGN_STR ".p2align 4,,15"
27410 -+#else
27411 -+#ifdef CONFIG_X86_ALIGNMENT_16
27412 -+#define __ALIGN .align 16,0x90
27413 -+#define __ALIGN_STR ".align 16,0x90"
27414 -+#endif
27415 - #endif
27416 -
27417 - #ifdef CONFIG_X86_32
27418 -@@ -52,10 +57,5 @@
27419 -
27420 - #endif
27421 -
27422 --#ifdef CONFIG_X86_ALIGNMENT_16
27423 --#define __ALIGN .align 16,0x90
27424 --#define __ALIGN_STR ".align 16,0x90"
27425 --#endif
27426 --
27427 - #endif
27428 -
27429 -diff -urNp linux-2.6.27.6/include/asm-x86/local.h linux-2.6.27.6/include/asm-x86/local.h
27430 ---- linux-2.6.27.6/include/asm-x86/local.h 2008-11-07 12:55:34.000000000 -0500
27431 -+++ linux-2.6.27.6/include/asm-x86/local.h 2008-11-18 03:38:45.000000000 -0500
27432 -@@ -18,26 +18,90 @@ typedef struct {
27433 -
27434 - static inline void local_inc(local_t *l)
27435 - {
27436 -- asm volatile(_ASM_INC "%0"
27437 -+ asm volatile(_ASM_INC "%0\n"
27438 -+
27439 -+#ifdef CONFIG_PAX_REFCOUNT
27440 -+#ifdef CONFIG_X86_32
27441 -+ "into\n0:\n"
27442 -+#else
27443 -+ "jno 0f\n"
27444 -+ "int $4\n0:\n"
27445 -+#endif
27446 -+ ".pushsection .fixup,\"ax\"\n"
27447 -+ "1:\n"
27448 -+ _ASM_DEC "%0\n"
27449 -+ "jmp 0b\n"
27450 -+ ".popsection\n"
27451 -+ _ASM_EXTABLE(0b, 1b)
27452 -+#endif
27453 -+
27454 - : "+m" (l->a.counter));
27455 - }
27456 -
27457 - static inline void local_dec(local_t *l)
27458 - {
27459 -- asm volatile(_ASM_DEC "%0"
27460 -+ asm volatile(_ASM_DEC "%0\n"
27461 -+
27462 -+#ifdef CONFIG_PAX_REFCOUNT
27463 -+#ifdef CONFIG_X86_32
27464 -+ "into\n0:\n"
27465 -+#else
27466 -+ "jno 0f\n"
27467 -+ "int $4\n0:\n"
27468 -+#endif
27469 -+ ".pushsection .fixup,\"ax\"\n"
27470 -+ "1:\n"
27471 -+ _ASM_INC "%0\n"
27472 -+ "jmp 0b\n"
27473 -+ ".popsection\n"
27474 -+ _ASM_EXTABLE(0b, 1b)
27475 -+#endif
27476 -+
27477 - : "+m" (l->a.counter));
27478 - }
27479 -
27480 - static inline void local_add(long i, local_t *l)
27481 - {
27482 -- asm volatile(_ASM_ADD "%1,%0"
27483 -+ asm volatile(_ASM_ADD "%1,%0\n"
27484 -+
27485 -+#ifdef CONFIG_PAX_REFCOUNT
27486 -+#ifdef CONFIG_X86_32
27487 -+ "into\n0:\n"
27488 -+#else
27489 -+ "jno 0f\n"
27490 -+ "int $4\n0:\n"
27491 -+#endif
27492 -+ ".pushsection .fixup,\"ax\"\n"
27493 -+ "1:\n"
27494 -+ _ASM_SUB "%1,%0\n"
27495 -+ "jmp 0b\n"
27496 -+ ".popsection\n"
27497 -+ _ASM_EXTABLE(0b, 1b)
27498 -+#endif
27499 -+
27500 - : "+m" (l->a.counter)
27501 - : "ir" (i));
27502 - }
27503 -
27504 - static inline void local_sub(long i, local_t *l)
27505 - {
27506 -- asm volatile(_ASM_SUB "%1,%0"
27507 -+ asm volatile(_ASM_SUB "%1,%0\n"
27508 -+
27509 -+#ifdef CONFIG_PAX_REFCOUNT
27510 -+#ifdef CONFIG_X86_32
27511 -+ "into\n0:\n"
27512 -+#else
27513 -+ "jno 0f\n"
27514 -+ "int $4\n0:\n"
27515 -+#endif
27516 -+ ".pushsection .fixup,\"ax\"\n"
27517 -+ "1:\n"
27518 -+ _ASM_ADD "%1,%0\n"
27519 -+ "jmp 0b\n"
27520 -+ ".popsection\n"
27521 -+ _ASM_EXTABLE(0b, 1b)
27522 -+#endif
27523 -+
27524 - : "+m" (l->a.counter)
27525 - : "ir" (i));
27526 - }
27527 -@@ -55,7 +119,24 @@ static inline int local_sub_and_test(lon
27528 - {
27529 - unsigned char c;
27530 -
27531 -- asm volatile(_ASM_SUB "%2,%0; sete %1"
27532 -+ asm volatile(_ASM_SUB "%2,%0\n"
27533 -+
27534 -+#ifdef CONFIG_PAX_REFCOUNT
27535 -+#ifdef CONFIG_X86_32
27536 -+ "into\n0:\n"
27537 -+#else
27538 -+ "jno 0f\n"
27539 -+ "int $4\n0:\n"
27540 -+#endif
27541 -+ ".pushsection .fixup,\"ax\"\n"
27542 -+ "1:\n"
27543 -+ _ASM_ADD "%2,%0\n"
27544 -+ "jmp 0b\n"
27545 -+ ".popsection\n"
27546 -+ _ASM_EXTABLE(0b, 1b)
27547 -+#endif
27548 -+
27549 -+ "sete %1\n"
27550 - : "+m" (l->a.counter), "=qm" (c)
27551 - : "ir" (i) : "memory");
27552 - return c;
27553 -@@ -73,7 +154,24 @@ static inline int local_dec_and_test(loc
27554 - {
27555 - unsigned char c;
27556 -
27557 -- asm volatile(_ASM_DEC "%0; sete %1"
27558 -+ asm volatile(_ASM_DEC "%0\n"
27559 -+
27560 -+#ifdef CONFIG_PAX_REFCOUNT
27561 -+#ifdef CONFIG_X86_32
27562 -+ "into\n0:\n"
27563 -+#else
27564 -+ "jno 0f\n"
27565 -+ "int $4\n0:\n"
27566 -+#endif
27567 -+ ".pushsection .fixup,\"ax\"\n"
27568 -+ "1:\n"
27569 -+ _ASM_INC "%0\n"
27570 -+ "jmp 0b\n"
27571 -+ ".popsection\n"
27572 -+ _ASM_EXTABLE(0b, 1b)
27573 -+#endif
27574 -+
27575 -+ "sete %1\n"
27576 - : "+m" (l->a.counter), "=qm" (c)
27577 - : : "memory");
27578 - return c != 0;
27579 -@@ -91,7 +189,24 @@ static inline int local_inc_and_test(loc
27580 - {
27581 - unsigned char c;
27582 -
27583 -- asm volatile(_ASM_INC "%0; sete %1"
27584 -+ asm volatile(_ASM_INC "%0\n"
27585 -+
27586 -+#ifdef CONFIG_PAX_REFCOUNT
27587 -+#ifdef CONFIG_X86_32
27588 -+ "into\n0:\n"
27589 -+#else
27590 -+ "jno 0f\n"
27591 -+ "int $4\n0:\n"
27592 -+#endif
27593 -+ ".pushsection .fixup,\"ax\"\n"
27594 -+ "1:\n"
27595 -+ _ASM_DEC "%0\n"
27596 -+ "jmp 0b\n"
27597 -+ ".popsection\n"
27598 -+ _ASM_EXTABLE(0b, 1b)
27599 -+#endif
27600 -+
27601 -+ "sete %1\n"
27602 - : "+m" (l->a.counter), "=qm" (c)
27603 - : : "memory");
27604 - return c != 0;
27605 -@@ -110,7 +225,24 @@ static inline int local_add_negative(lon
27606 - {
27607 - unsigned char c;
27608 -
27609 -- asm volatile(_ASM_ADD "%2,%0; sets %1"
27610 -+ asm volatile(_ASM_ADD "%2,%0\n"
27611 -+
27612 -+#ifdef CONFIG_PAX_REFCOUNT
27613 -+#ifdef CONFIG_X86_32
27614 -+ "into\n0:\n"
27615 -+#else
27616 -+ "jno 0f\n"
27617 -+ "int $4\n0:\n"
27618 -+#endif
27619 -+ ".pushsection .fixup,\"ax\"\n"
27620 -+ "1:\n"
27621 -+ _ASM_SUB "%2,%0\n"
27622 -+ "jmp 0b\n"
27623 -+ ".popsection\n"
27624 -+ _ASM_EXTABLE(0b, 1b)
27625 -+#endif
27626 -+
27627 -+ "sets %1\n"
27628 - : "+m" (l->a.counter), "=qm" (c)
27629 - : "ir" (i) : "memory");
27630 - return c;
27631 -@@ -133,7 +265,23 @@ static inline long local_add_return(long
27632 - #endif
27633 - /* Modern 486+ processor */
27634 - __i = i;
27635 -- asm volatile(_ASM_XADD "%0, %1;"
27636 -+ asm volatile(_ASM_XADD "%0, %1\n"
27637 -+
27638 -+#ifdef CONFIG_PAX_REFCOUNT
27639 -+#ifdef CONFIG_X86_32
27640 -+ "into\n0:\n"
27641 -+#else
27642 -+ "jno 0f\n"
27643 -+ "int $4\n0:\n"
27644 -+#endif
27645 -+ ".pushsection .fixup,\"ax\"\n"
27646 -+ "1:\n"
27647 -+ _ASM_MOV_UL "%0,%1\n"
27648 -+ "jmp 0b\n"
27649 -+ ".popsection\n"
27650 -+ _ASM_EXTABLE(0b, 1b)
27651 -+#endif
27652 -+
27653 - : "+r" (i), "+m" (l->a.counter)
27654 - : : "memory");
27655 - return i + __i;
27656 -diff -urNp linux-2.6.27.6/include/asm-x86/mach-default/apm.h linux-2.6.27.6/include/asm-x86/mach-default/apm.h
27657 ---- linux-2.6.27.6/include/asm-x86/mach-default/apm.h 2008-11-07 12:55:34.000000000 -0500
27658 -+++ linux-2.6.27.6/include/asm-x86/mach-default/apm.h 2008-11-18 03:38:45.000000000 -0500
27659 -@@ -34,7 +34,7 @@ static inline void apm_bios_call_asm(u32
27660 - __asm__ __volatile__(APM_DO_ZERO_SEGS
27661 - "pushl %%edi\n\t"
27662 - "pushl %%ebp\n\t"
27663 -- "lcall *%%cs:apm_bios_entry\n\t"
27664 -+ "lcall *%%ss:apm_bios_entry\n\t"
27665 - "setc %%al\n\t"
27666 - "popl %%ebp\n\t"
27667 - "popl %%edi\n\t"
27668 -@@ -58,7 +58,7 @@ static inline u8 apm_bios_call_simple_as
27669 - __asm__ __volatile__(APM_DO_ZERO_SEGS
27670 - "pushl %%edi\n\t"
27671 - "pushl %%ebp\n\t"
27672 -- "lcall *%%cs:apm_bios_entry\n\t"
27673 -+ "lcall *%%ss:apm_bios_entry\n\t"
27674 - "setc %%bl\n\t"
27675 - "popl %%ebp\n\t"
27676 - "popl %%edi\n\t"
27677 -diff -urNp linux-2.6.27.6/include/asm-x86/mman.h linux-2.6.27.6/include/asm-x86/mman.h
27678 ---- linux-2.6.27.6/include/asm-x86/mman.h 2008-11-07 12:55:34.000000000 -0500
27679 -+++ linux-2.6.27.6/include/asm-x86/mman.h 2008-11-18 03:38:45.000000000 -0500
27680 -@@ -17,4 +17,14 @@
27681 - #define MCL_CURRENT 1 /* lock all current mappings */
27682 - #define MCL_FUTURE 2 /* lock all future mappings */
27683 -
27684 -+#ifdef __KERNEL__
27685 -+#ifndef __ASSEMBLY__
27686 -+#ifdef CONFIG_X86_32
27687 -+#define arch_mmap_check i386_mmap_check
27688 -+int i386_mmap_check(unsigned long addr, unsigned long len,
27689 -+ unsigned long flags);
27690 -+#endif
27691 -+#endif
27692 -+#endif
27693 -+
27694 - #endif /* _ASM_X86_MMAN_H */
27695 -diff -urNp linux-2.6.27.6/include/asm-x86/mmu_context_32.h linux-2.6.27.6/include/asm-x86/mmu_context_32.h
27696 ---- linux-2.6.27.6/include/asm-x86/mmu_context_32.h 2008-11-07 12:55:34.000000000 -0500
27697 -+++ linux-2.6.27.6/include/asm-x86/mmu_context_32.h 2008-11-18 03:38:45.000000000 -0500
27698 -@@ -33,6 +33,22 @@ static inline void switch_mm(struct mm_s
27699 - */
27700 - if (unlikely(prev->context.ldt != next->context.ldt))
27701 - load_LDT_nolock(&next->context);
27702 -+
27703 -+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
27704 -+ if (!nx_enabled) {
27705 -+ smp_mb__before_clear_bit();
27706 -+ cpu_clear(cpu, prev->context.cpu_user_cs_mask);
27707 -+ smp_mb__after_clear_bit();
27708 -+ cpu_set(cpu, next->context.cpu_user_cs_mask);
27709 -+ }
27710 -+#endif
27711 -+
27712 -+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
27713 -+ if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
27714 -+ prev->context.user_cs_limit != next->context.user_cs_limit))
27715 -+ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
27716 -+#endif
27717 -+
27718 - }
27719 - #ifdef CONFIG_SMP
27720 - else {
27721 -@@ -45,6 +61,19 @@ static inline void switch_mm(struct mm_s
27722 - */
27723 - load_cr3(next->pgd);
27724 - load_LDT_nolock(&next->context);
27725 -+
27726 -+#ifdef CONFIG_PAX_PAGEEXEC
27727 -+ if (!nx_enabled)
27728 -+ cpu_set(cpu, next->context.cpu_user_cs_mask);
27729 -+#endif
27730 -+
27731 -+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
27732 -+#ifdef CONFIG_PAX_PAGEEXEC
27733 -+ if (!((next->pax_flags & MF_PAX_PAGEEXEC) && nx_enabled))
27734 -+#endif
27735 -+ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
27736 -+#endif
27737 -+
27738 - }
27739 - }
27740 - #endif
27741 -diff -urNp linux-2.6.27.6/include/asm-x86/mmu.h linux-2.6.27.6/include/asm-x86/mmu.h
27742 ---- linux-2.6.27.6/include/asm-x86/mmu.h 2008-11-07 12:55:34.000000000 -0500
27743 -+++ linux-2.6.27.6/include/asm-x86/mmu.h 2008-11-18 03:38:45.000000000 -0500
27744 -@@ -11,13 +11,26 @@
27745 - * cpu_vm_mask is used to optimize ldt flushing.
27746 - */
27747 - typedef struct {
27748 -- void *ldt;
27749 -+ struct desc_struct *ldt;
27750 - #ifdef CONFIG_X86_64
27751 - rwlock_t ldtlock;
27752 - #endif
27753 - int size;
27754 - struct mutex lock;
27755 -- void *vdso;
27756 -+ unsigned long vdso;
27757 -+
27758 -+#ifdef CONFIG_X86_32
27759 -+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
27760 -+ unsigned long user_cs_base;
27761 -+ unsigned long user_cs_limit;
27762 -+
27763 -+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
27764 -+ cpumask_t cpu_user_cs_mask;
27765 -+#endif
27766 -+
27767 -+#endif
27768 -+#endif
27769 -+
27770 - } mm_context_t;
27771 -
27772 - #ifdef CONFIG_SMP
27773 -diff -urNp linux-2.6.27.6/include/asm-x86/module.h linux-2.6.27.6/include/asm-x86/module.h
27774 ---- linux-2.6.27.6/include/asm-x86/module.h 2008-11-07 12:55:34.000000000 -0500
27775 -+++ linux-2.6.27.6/include/asm-x86/module.h 2008-11-18 03:38:45.000000000 -0500
27776 -@@ -76,7 +76,12 @@ struct mod_arch_specific {};
27777 - # else
27778 - # define MODULE_STACKSIZE ""
27779 - # endif
27780 --# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
27781 -+# ifdef CONFIG_GRKERNSEC
27782 -+# define MODULE_GRSEC "GRSECURITY "
27783 -+# else
27784 -+# define MODULE_GRSEC ""
27785 -+# endif
27786 -+# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE MODULE_GRSEC
27787 - #endif
27788 -
27789 - #endif /* _ASM_MODULE_H */
27790 -diff -urNp linux-2.6.27.6/include/asm-x86/page_32.h linux-2.6.27.6/include/asm-x86/page_32.h
27791 ---- linux-2.6.27.6/include/asm-x86/page_32.h 2008-11-07 12:55:34.000000000 -0500
27792 -+++ linux-2.6.27.6/include/asm-x86/page_32.h 2008-11-18 03:38:45.000000000 -0500
27793 -@@ -13,6 +13,23 @@
27794 - */
27795 - #define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL)
27796 -
27797 -+#ifdef CONFIG_PAX_KERNEXEC
27798 -+#ifndef __ASSEMBLY__
27799 -+extern unsigned char MODULES_VADDR[];
27800 -+extern unsigned char MODULES_END[];
27801 -+extern unsigned char KERNEL_TEXT_OFFSET[];
27802 -+#define ktla_ktva(addr) (addr + (unsigned long)KERNEL_TEXT_OFFSET)
27803 -+#define ktva_ktla(addr) (addr - (unsigned long)KERNEL_TEXT_OFFSET)
27804 -+#endif
27805 -+#else
27806 -+#define ktla_ktva(addr) (addr)
27807 -+#define ktva_ktla(addr) (addr)
27808 -+#endif
27809 -+
27810 -+#ifdef CONFIG_PAX_PAGEEXEC
27811 -+#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
27812 -+#endif
27813 -+
27814 - #ifdef CONFIG_4KSTACKS
27815 - #define THREAD_ORDER 0
27816 - #else
27817 -diff -urNp linux-2.6.27.6/include/asm-x86/page_64.h linux-2.6.27.6/include/asm-x86/page_64.h
27818 ---- linux-2.6.27.6/include/asm-x86/page_64.h 2008-11-07 12:55:34.000000000 -0500
27819 -+++ linux-2.6.27.6/include/asm-x86/page_64.h 2008-11-18 03:38:45.000000000 -0500
27820 -@@ -49,6 +49,9 @@
27821 - #define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START)
27822 - #define __START_KERNEL_map _AC(0xffffffff80000000, UL)
27823 -
27824 -+#define ktla_ktva(addr) (addr)
27825 -+#define ktva_ktla(addr) (addr)
27826 -+
27827 - /* See Documentation/x86_64/mm.txt for a description of the memory map. */
27828 - #define __PHYSICAL_MASK_SHIFT 46
27829 - #define __VIRTUAL_MASK_SHIFT 48
27830 -@@ -101,5 +104,6 @@ extern void init_extra_mapping_wb(unsign
27831 - #define pfn_valid(pfn) ((pfn) < max_pfn)
27832 - #endif
27833 -
27834 -+#define nx_enabled (1)
27835 -
27836 - #endif /* _X86_64_PAGE_H */
27837 -diff -urNp linux-2.6.27.6/include/asm-x86/paravirt.h linux-2.6.27.6/include/asm-x86/paravirt.h
27838 ---- linux-2.6.27.6/include/asm-x86/paravirt.h 2008-11-07 12:55:34.000000000 -0500
27839 -+++ linux-2.6.27.6/include/asm-x86/paravirt.h 2008-11-18 03:38:45.000000000 -0500
27840 -@@ -1557,7 +1557,7 @@ static inline unsigned long __raw_local_
27841 - #define PV_RESTORE_REGS popl %edx; popl %ecx; popl %edi; popl %eax
27842 - #define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 4)
27843 - #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .long, 4)
27844 --#define PARA_INDIRECT(addr) *%cs:addr
27845 -+#define PARA_INDIRECT(addr) *%ss:addr
27846 - #endif
27847 -
27848 - #define INTERRUPT_RETURN \
27849 -diff -urNp linux-2.6.27.6/include/asm-x86/pda.h linux-2.6.27.6/include/asm-x86/pda.h
27850 ---- linux-2.6.27.6/include/asm-x86/pda.h 2008-11-07 12:55:34.000000000 -0500
27851 -+++ linux-2.6.27.6/include/asm-x86/pda.h 2008-11-18 03:38:45.000000000 -0500
27852 -@@ -16,11 +16,9 @@ struct x8664_pda {
27853 - unsigned long oldrsp; /* 24 user rsp for system call */
27854 - int irqcount; /* 32 Irq nesting counter. Starts -1 */
27855 - unsigned int cpunumber; /* 36 Logical CPU number */
27856 --#ifdef CONFIG_CC_STACKPROTECTOR
27857 - unsigned long stack_canary; /* 40 stack canary value */
27858 - /* gcc-ABI: this canary MUST be at
27859 - offset 40!!! */
27860 --#endif
27861 - char *irqstackptr;
27862 - short nodenumber; /* number of current node (32k max) */
27863 - short in_bootmem; /* pda lives in bootmem */
27864 -diff -urNp linux-2.6.27.6/include/asm-x86/percpu.h linux-2.6.27.6/include/asm-x86/percpu.h
27865 ---- linux-2.6.27.6/include/asm-x86/percpu.h 2008-11-07 12:55:34.000000000 -0500
27866 -+++ linux-2.6.27.6/include/asm-x86/percpu.h 2008-11-18 03:38:45.000000000 -0500
27867 -@@ -93,6 +93,12 @@ DECLARE_PER_CPU(struct x8664_pda, pda);
27868 -
27869 - #define __my_cpu_offset x86_read_percpu(this_cpu_off)
27870 -
27871 -+#include <asm-generic/sections.h>
27872 -+#include <linux/threads.h>
27873 -+#define __per_cpu_offset __per_cpu_offset
27874 -+extern unsigned long __per_cpu_offset[NR_CPUS];
27875 -+#define per_cpu_offset(x) (__per_cpu_offset[x] + (unsigned long)__per_cpu_start)
27876 -+
27877 - /* fs segment starts at (positive) offset == __per_cpu_offset[cpu] */
27878 - #define __percpu_seg "%%fs:"
27879 -
27880 -diff -urNp linux-2.6.27.6/include/asm-x86/pgalloc.h linux-2.6.27.6/include/asm-x86/pgalloc.h
27881 ---- linux-2.6.27.6/include/asm-x86/pgalloc.h 2008-11-07 12:55:34.000000000 -0500
27882 -+++ linux-2.6.27.6/include/asm-x86/pgalloc.h 2008-11-18 03:38:45.000000000 -0500
27883 -@@ -51,7 +51,7 @@ static inline void pmd_populate_kernel(s
27884 - pmd_t *pmd, pte_t *pte)
27885 - {
27886 - paravirt_alloc_pte(mm, __pa(pte) >> PAGE_SHIFT);
27887 -- set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
27888 -+ set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE));
27889 - }
27890 -
27891 - static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
27892 -diff -urNp linux-2.6.27.6/include/asm-x86/pgtable-2level.h linux-2.6.27.6/include/asm-x86/pgtable-2level.h
27893 ---- linux-2.6.27.6/include/asm-x86/pgtable-2level.h 2008-11-07 12:55:34.000000000 -0500
27894 -+++ linux-2.6.27.6/include/asm-x86/pgtable-2level.h 2008-11-18 03:38:45.000000000 -0500
27895 -@@ -18,7 +18,19 @@ static inline void native_set_pte(pte_t
27896 -
27897 - static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
27898 - {
27899 -+
27900 -+#ifdef CONFIG_PAX_KERNEXEC
27901 -+ unsigned long cr0;
27902 -+
27903 -+ pax_open_kernel(cr0);
27904 -+#endif
27905 -+
27906 - *pmdp = pmd;
27907 -+
27908 -+#ifdef CONFIG_PAX_KERNEXEC
27909 -+ pax_close_kernel(cr0);
27910 -+#endif
27911 -+
27912 - }
27913 -
27914 - static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
27915 -diff -urNp linux-2.6.27.6/include/asm-x86/pgtable_32.h linux-2.6.27.6/include/asm-x86/pgtable_32.h
27916 ---- linux-2.6.27.6/include/asm-x86/pgtable_32.h 2008-11-07 12:55:34.000000000 -0500
27917 -+++ linux-2.6.27.6/include/asm-x86/pgtable_32.h 2008-11-18 03:38:45.000000000 -0500
27918 -@@ -25,8 +25,6 @@
27919 - struct mm_struct;
27920 - struct vm_area_struct;
27921 -
27922 --extern pgd_t swapper_pg_dir[1024];
27923 --
27924 - static inline void pgtable_cache_init(void) { }
27925 - static inline void check_pgt_cache(void) { }
27926 - void paging_init(void);
27927 -@@ -45,6 +43,11 @@ void paging_init(void);
27928 - # include <asm/pgtable-2level-defs.h>
27929 - #endif
27930 -
27931 -+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
27932 -+#ifdef CONFIG_X86_PAE
27933 -+extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
27934 -+#endif
27935 -+
27936 - #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
27937 - #define PGDIR_MASK (~(PGDIR_SIZE - 1))
27938 -
27939 -@@ -81,7 +84,7 @@ void paging_init(void);
27940 - #undef TEST_ACCESS_OK
27941 -
27942 - /* The boot page tables (all created as a single array) */
27943 --extern unsigned long pg0[];
27944 -+extern pte_t pg0[];
27945 -
27946 - #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
27947 -
27948 -@@ -173,6 +176,9 @@ do { \
27949 -
27950 - #endif /* !__ASSEMBLY__ */
27951 -
27952 -+#define HAVE_ARCH_UNMAPPED_AREA
27953 -+#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
27954 -+
27955 - /*
27956 - * kern_addr_valid() is (1) for FLATMEM and (0) for
27957 - * SPARSEMEM and DISCONTIGMEM
27958 -diff -urNp linux-2.6.27.6/include/asm-x86/pgtable-3level.h linux-2.6.27.6/include/asm-x86/pgtable-3level.h
27959 ---- linux-2.6.27.6/include/asm-x86/pgtable-3level.h 2008-11-07 12:55:34.000000000 -0500
27960 -+++ linux-2.6.27.6/include/asm-x86/pgtable-3level.h 2008-11-18 03:38:45.000000000 -0500
27961 -@@ -70,12 +70,36 @@ static inline void native_set_pte_atomic
27962 -
27963 - static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
27964 - {
27965 -+
27966 -+#ifdef CONFIG_PAX_KERNEXEC
27967 -+ unsigned long cr0;
27968 -+
27969 -+ pax_open_kernel(cr0);
27970 -+#endif
27971 -+
27972 - set_64bit((unsigned long long *)(pmdp), native_pmd_val(pmd));
27973 -+
27974 -+#ifdef CONFIG_PAX_KERNEXEC
27975 -+ pax_close_kernel(cr0);
27976 -+#endif
27977 -+
27978 - }
27979 -
27980 - static inline void native_set_pud(pud_t *pudp, pud_t pud)
27981 - {
27982 -+
27983 -+#ifdef CONFIG_PAX_KERNEXEC
27984 -+ unsigned long cr0;
27985 -+
27986 -+ pax_open_kernel(cr0);
27987 -+#endif
27988 -+
27989 - set_64bit((unsigned long long *)(pudp), native_pud_val(pud));
27990 -+
27991 -+#ifdef CONFIG_PAX_KERNEXEC
27992 -+ pax_close_kernel(cr0);
27993 -+#endif
27994 -+
27995 - }
27996 -
27997 - /*
27998 -diff -urNp linux-2.6.27.6/include/asm-x86/pgtable_64.h linux-2.6.27.6/include/asm-x86/pgtable_64.h
27999 ---- linux-2.6.27.6/include/asm-x86/pgtable_64.h 2008-11-07 12:55:34.000000000 -0500
28000 -+++ linux-2.6.27.6/include/asm-x86/pgtable_64.h 2008-11-18 03:38:45.000000000 -0500
28001 -@@ -15,9 +15,12 @@
28002 -
28003 - extern pud_t level3_kernel_pgt[512];
28004 - extern pud_t level3_ident_pgt[512];
28005 -+extern pud_t level3_vmalloc_pgt[512];
28006 -+extern pud_t level3_vmemmap_pgt[512];
28007 - extern pmd_t level2_kernel_pgt[512];
28008 - extern pmd_t level2_fixmap_pgt[512];
28009 - extern pmd_t level2_ident_pgt[512];
28010 -+extern pte_t level1_fixmap_pgt[512];
28011 - extern pgd_t init_level4_pgt[];
28012 -
28013 - #define swapper_pg_dir init_level4_pgt
28014 -@@ -106,7 +109,19 @@ static inline pte_t native_ptep_get_and_
28015 -
28016 - static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
28017 - {
28018 -+
28019 -+#ifdef CONFIG_PAX_KERNEXEC
28020 -+ unsigned long cr0;
28021 -+
28022 -+ pax_open_kernel(cr0);
28023 -+#endif
28024 -+
28025 - *pmdp = pmd;
28026 -+
28027 -+#ifdef CONFIG_PAX_KERNEXEC
28028 -+ pax_close_kernel(cr0);
28029 -+#endif
28030 -+
28031 - }
28032 -
28033 - static inline void native_pmd_clear(pmd_t *pmd)
28034 -@@ -158,17 +173,17 @@ static inline void native_pgd_clear(pgd_
28035 -
28036 - static inline int pgd_bad(pgd_t pgd)
28037 - {
28038 -- return (pgd_val(pgd) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
28039 -+ return (pgd_val(pgd) & ~(PTE_PFN_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
28040 - }
28041 -
28042 - static inline int pud_bad(pud_t pud)
28043 - {
28044 -- return (pud_val(pud) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
28045 -+ return (pud_val(pud) & ~(PTE_PFN_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
28046 - }
28047 -
28048 - static inline int pmd_bad(pmd_t pmd)
28049 - {
28050 -- return (pmd_val(pmd) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
28051 -+ return (pmd_val(pmd) & ~(PTE_PFN_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
28052 - }
28053 -
28054 - #define pte_none(x) (!pte_val((x)))
28055 -diff -urNp linux-2.6.27.6/include/asm-x86/pgtable.h linux-2.6.27.6/include/asm-x86/pgtable.h
28056 ---- linux-2.6.27.6/include/asm-x86/pgtable.h 2008-11-07 12:55:34.000000000 -0500
28057 -+++ linux-2.6.27.6/include/asm-x86/pgtable.h 2008-11-18 03:38:45.000000000 -0500
28058 -@@ -41,7 +41,7 @@
28059 - #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
28060 - #define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_NX)
28061 - #else
28062 --#define _PAGE_NX (_AT(pteval_t, 0))
28063 -+#define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED3)
28064 - #endif
28065 -
28066 - /* If _PAGE_PRESENT is clear, we use these: */
28067 -@@ -81,6 +81,9 @@
28068 - #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \
28069 - _PAGE_ACCESSED)
28070 -
28071 -+#define PAGE_READONLY_NOEXEC PAGE_READONLY
28072 -+#define PAGE_SHARED_NOEXEC PAGE_SHARED
28073 -+
28074 - #define __PAGE_KERNEL_EXEC \
28075 - (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL)
28076 - #define __PAGE_KERNEL (__PAGE_KERNEL_EXEC | _PAGE_NX)
28077 -@@ -92,7 +95,7 @@
28078 - #define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
28079 - #define __PAGE_KERNEL_UC_MINUS (__PAGE_KERNEL | _PAGE_PCD)
28080 - #define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER)
28081 --#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
28082 -+#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_RO | _PAGE_PCD | _PAGE_PWT | _PAGE_USER)
28083 - #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE)
28084 - #define __PAGE_KERNEL_LARGE_NOCACHE (__PAGE_KERNEL | _PAGE_CACHE_UC | _PAGE_PSE)
28085 - #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE)
28086 -@@ -142,10 +145,17 @@ extern unsigned long empty_zero_page[PAG
28087 - extern spinlock_t pgd_lock;
28088 - extern struct list_head pgd_list;
28089 -
28090 -+extern pteval_t __supported_pte_mask;
28091 -+
28092 - /*
28093 - * The following only work if pte_present() is true.
28094 - * Undefined behaviour if not..
28095 - */
28096 -+static inline int pte_user(pte_t pte)
28097 -+{
28098 -+ return pte_val(pte) & _PAGE_USER;
28099 -+}
28100 -+
28101 - static inline int pte_dirty(pte_t pte)
28102 - {
28103 - return pte_flags(pte) & _PAGE_DIRTY;
28104 -@@ -207,9 +217,29 @@ static inline pte_t pte_wrprotect(pte_t
28105 - return __pte(pte_val(pte) & ~_PAGE_RW);
28106 - }
28107 -
28108 -+static inline pte_t pte_mkread(pte_t pte)
28109 -+{
28110 -+ return __pte(pte_val(pte) | _PAGE_USER);
28111 -+}
28112 -+
28113 - static inline pte_t pte_mkexec(pte_t pte)
28114 - {
28115 -- return __pte(pte_val(pte) & ~_PAGE_NX);
28116 -+#ifdef CONFIG_X86_PAE
28117 -+ if (__supported_pte_mask & _PAGE_NX)
28118 -+ return __pte(pte_val(pte) & ~(pteval_t)_PAGE_NX);
28119 -+ else
28120 -+#endif
28121 -+ return __pte(pte_val(pte) | _PAGE_USER);
28122 -+}
28123 -+
28124 -+static inline pte_t pte_exprotect(pte_t pte)
28125 -+{
28126 -+#ifdef CONFIG_X86_PAE
28127 -+ if (__supported_pte_mask & _PAGE_NX)
28128 -+ return __pte(pte_val(pte) | _PAGE_NX);
28129 -+ else
28130 -+#endif
28131 -+ return __pte(pte_val(pte) & ~_PAGE_USER);
28132 - }
28133 -
28134 - static inline pte_t pte_mkdirty(pte_t pte)
28135 -@@ -252,8 +282,6 @@ static inline pte_t pte_mkspecial(pte_t
28136 - return __pte(pte_val(pte) | _PAGE_SPECIAL);
28137 - }
28138 -
28139 --extern pteval_t __supported_pte_mask;
28140 --
28141 - static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
28142 - {
28143 - return __pte((((phys_addr_t)page_nr << PAGE_SHIFT) |
28144 -@@ -514,7 +542,19 @@ static inline void ptep_set_wrprotect(st
28145 - */
28146 - static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
28147 - {
28148 -- memcpy(dst, src, count * sizeof(pgd_t));
28149 -+
28150 -+#ifdef CONFIG_PAX_KERNEXEC
28151 -+ unsigned long cr0;
28152 -+
28153 -+ pax_open_kernel(cr0);
28154 -+#endif
28155 -+
28156 -+ memcpy(dst, src, count * sizeof(pgd_t));
28157 -+
28158 -+#ifdef CONFIG_PAX_KERNEXEC
28159 -+ pax_close_kernel(cr0);
28160 -+#endif
28161 -+
28162 - }
28163 -
28164 -
28165 -diff -urNp linux-2.6.27.6/include/asm-x86/processor.h linux-2.6.27.6/include/asm-x86/processor.h
28166 ---- linux-2.6.27.6/include/asm-x86/processor.h 2008-11-07 12:55:34.000000000 -0500
28167 -+++ linux-2.6.27.6/include/asm-x86/processor.h 2008-11-18 03:38:45.000000000 -0500
28168 -@@ -269,7 +269,7 @@ struct tss_struct {
28169 -
28170 - } ____cacheline_aligned;
28171 -
28172 --DECLARE_PER_CPU(struct tss_struct, init_tss);
28173 -+extern struct tss_struct init_tss[NR_CPUS];
28174 -
28175 - /*
28176 - * Save the original ist values for checking stack pointers during debugging
28177 -@@ -832,11 +832,20 @@ static inline void spin_lock_prefetch(co
28178 - * User space process size: 3GB (default).
28179 - */
28180 - #define TASK_SIZE PAGE_OFFSET
28181 -+
28182 -+#ifdef CONFIG_PAX_SEGMEXEC
28183 -+#define SEGMEXEC_TASK_SIZE (TASK_SIZE / 2)
28184 -+#endif
28185 -+
28186 -+#ifdef CONFIG_PAX_SEGMEXEC
28187 -+#define STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE:TASK_SIZE)
28188 -+#else
28189 - #define STACK_TOP TASK_SIZE
28190 --#define STACK_TOP_MAX STACK_TOP
28191 -+#endif
28192 -+#define STACK_TOP_MAX TASK_SIZE
28193 -
28194 - #define INIT_THREAD { \
28195 -- .sp0 = sizeof(init_stack) + (long)&init_stack, \
28196 -+ .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
28197 - .vm86_info = NULL, \
28198 - .sysenter_cs = __KERNEL_CS, \
28199 - .io_bitmap_ptr = NULL, \
28200 -@@ -851,7 +860,7 @@ static inline void spin_lock_prefetch(co
28201 - */
28202 - #define INIT_TSS { \
28203 - .x86_tss = { \
28204 -- .sp0 = sizeof(init_stack) + (long)&init_stack, \
28205 -+ .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
28206 - .ss0 = __KERNEL_DS, \
28207 - .ss1 = __KERNEL_CS, \
28208 - .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
28209 -@@ -862,11 +871,7 @@ static inline void spin_lock_prefetch(co
28210 - extern unsigned long thread_saved_pc(struct task_struct *tsk);
28211 -
28212 - #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
28213 --#define KSTK_TOP(info) \
28214 --({ \
28215 -- unsigned long *__ptr = (unsigned long *)(info); \
28216 -- (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
28217 --})
28218 -+#define KSTK_TOP(info) ((info)->task.thread.sp0)
28219 -
28220 - /*
28221 - * The below -8 is to reserve 8 bytes on top of the ring0 stack.
28222 -@@ -881,7 +886,7 @@ extern unsigned long thread_saved_pc(str
28223 - #define task_pt_regs(task) \
28224 - ({ \
28225 - struct pt_regs *__regs__; \
28226 -- __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
28227 -+ __regs__ = (struct pt_regs *)((task)->thread.sp0); \
28228 - __regs__ - 1; \
28229 - })
28230 -
28231 -@@ -897,7 +902,7 @@ extern unsigned long thread_saved_pc(str
28232 - * space during mmap's.
28233 - */
28234 - #define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? \
28235 -- 0xc0000000 : 0xFFFFe000)
28236 -+ 0xc0000000 : 0xFFFFf000)
28237 -
28238 - #define TASK_SIZE (test_thread_flag(TIF_IA32) ? \
28239 - IA32_PAGE_OFFSET : TASK_SIZE64)
28240 -@@ -934,6 +939,10 @@ extern void start_thread(struct pt_regs
28241 - */
28242 - #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
28243 -
28244 -+#ifdef CONFIG_PAX_SEGMEXEC
28245 -+#define SEGMEXEC_TASK_UNMAPPED_BASE (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3))
28246 -+#endif
28247 -+
28248 - #define KSTK_EIP(task) (task_pt_regs(task)->ip)
28249 -
28250 - /* Get/set a process' ability to use the timestamp counter instruction */
28251 -diff -urNp linux-2.6.27.6/include/asm-x86/ptrace.h linux-2.6.27.6/include/asm-x86/ptrace.h
28252 ---- linux-2.6.27.6/include/asm-x86/ptrace.h 2008-11-07 12:55:34.000000000 -0500
28253 -+++ linux-2.6.27.6/include/asm-x86/ptrace.h 2008-11-18 03:38:45.000000000 -0500
28254 -@@ -131,6 +131,7 @@ struct pt_regs {
28255 -
28256 - /* the DS BTS struct is used for ptrace as well */
28257 - #include <asm/ds.h>
28258 -+#include <asm/segment.h>
28259 -
28260 - struct task_struct;
28261 -
28262 -@@ -154,28 +155,29 @@ static inline unsigned long regs_return_
28263 - }
28264 -
28265 - /*
28266 -- * user_mode_vm(regs) determines whether a register set came from user mode.
28267 -+ * user_mode(regs) determines whether a register set came from user mode.
28268 - * This is true if V8086 mode was enabled OR if the register set was from
28269 - * protected mode with RPL-3 CS value. This tricky test checks that with
28270 - * one comparison. Many places in the kernel can bypass this full check
28271 -- * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
28272 -+ * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
28273 -+ * be used.
28274 - */
28275 --static inline int user_mode(struct pt_regs *regs)
28276 -+static inline int user_mode_novm(struct pt_regs *regs)
28277 - {
28278 - #ifdef CONFIG_X86_32
28279 - return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL;
28280 - #else
28281 -- return !!(regs->cs & 3);
28282 -+ return !!(regs->cs & SEGMENT_RPL_MASK);
28283 - #endif
28284 - }
28285 -
28286 --static inline int user_mode_vm(struct pt_regs *regs)
28287 -+static inline int user_mode(struct pt_regs *regs)
28288 - {
28289 - #ifdef CONFIG_X86_32
28290 - return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >=
28291 - USER_RPL;
28292 - #else
28293 -- return user_mode(regs);
28294 -+ return user_mode_novm(regs);
28295 - #endif
28296 - }
28297 -
28298 -diff -urNp linux-2.6.27.6/include/asm-x86/reboot.h linux-2.6.27.6/include/asm-x86/reboot.h
28299 ---- linux-2.6.27.6/include/asm-x86/reboot.h 2008-11-07 12:55:34.000000000 -0500
28300 -+++ linux-2.6.27.6/include/asm-x86/reboot.h 2008-11-18 03:38:45.000000000 -0500
28301 -@@ -16,6 +16,6 @@ extern struct machine_ops machine_ops;
28302 -
28303 - void native_machine_crash_shutdown(struct pt_regs *regs);
28304 - void native_machine_shutdown(void);
28305 --void machine_real_restart(const unsigned char *code, int length);
28306 -+void machine_real_restart(const unsigned char *code, unsigned int length);
28307 -
28308 - #endif /* _ASM_REBOOT_H */
28309 -diff -urNp linux-2.6.27.6/include/asm-x86/rwsem.h linux-2.6.27.6/include/asm-x86/rwsem.h
28310 ---- linux-2.6.27.6/include/asm-x86/rwsem.h 2008-11-07 12:55:34.000000000 -0500
28311 -+++ linux-2.6.27.6/include/asm-x86/rwsem.h 2008-11-18 03:38:45.000000000 -0500
28312 -@@ -106,10 +106,26 @@ static inline void __down_read(struct rw
28313 - {
28314 - asm volatile("# beginning down_read\n\t"
28315 - LOCK_PREFIX " incl (%%eax)\n\t"
28316 -+
28317 -+#ifdef CONFIG_PAX_REFCOUNT
28318 -+#ifdef CONFIG_X86_32
28319 -+ "into\n0:\n"
28320 -+#else
28321 -+ "jno 0f\n"
28322 -+ "int $4\n0:\n"
28323 -+#endif
28324 -+ ".pushsection .fixup,\"ax\"\n"
28325 -+ "1:\n"
28326 -+ LOCK_PREFIX "decl (%%eax)\n"
28327 -+ "jmp 0b\n"
28328 -+ ".popsection\n"
28329 -+ _ASM_EXTABLE(0b, 1b)
28330 -+#endif
28331 -+
28332 - /* adds 0x00000001, returns the old value */
28333 -- " jns 1f\n"
28334 -+ " jns 2f\n"
28335 - " call call_rwsem_down_read_failed\n"
28336 -- "1:\n\t"
28337 -+ "2:\n\t"
28338 - "# ending down_read\n\t"
28339 - : "+m" (sem->count)
28340 - : "a" (sem)
28341 -@@ -124,13 +140,29 @@ static inline int __down_read_trylock(st
28342 - __s32 result, tmp;
28343 - asm volatile("# beginning __down_read_trylock\n\t"
28344 - " movl %0,%1\n\t"
28345 -- "1:\n\t"
28346 -+ "2:\n\t"
28347 - " movl %1,%2\n\t"
28348 - " addl %3,%2\n\t"
28349 -- " jle 2f\n\t"
28350 -+
28351 -+#ifdef CONFIG_PAX_REFCOUNT
28352 -+#ifdef CONFIG_X86_32
28353 -+ "into\n0:\n"
28354 -+#else
28355 -+ "jno 0f\n"
28356 -+ "int $4\n0:\n"
28357 -+#endif
28358 -+ ".pushsection .fixup,\"ax\"\n"
28359 -+ "1:\n"
28360 -+ "subl %3,%2\n"
28361 -+ "jmp 0b\n"
28362 -+ ".popsection\n"
28363 -+ _ASM_EXTABLE(0b, 1b)
28364 -+#endif
28365 -+
28366 -+ " jle 3f\n\t"
28367 - LOCK_PREFIX " cmpxchgl %2,%0\n\t"
28368 -- " jnz 1b\n\t"
28369 -- "2:\n\t"
28370 -+ " jnz 2b\n\t"
28371 -+ "3:\n\t"
28372 - "# ending __down_read_trylock\n\t"
28373 - : "+m" (sem->count), "=&a" (result), "=&r" (tmp)
28374 - : "i" (RWSEM_ACTIVE_READ_BIAS)
28375 -@@ -148,12 +180,28 @@ static inline void __down_write_nested(s
28376 - tmp = RWSEM_ACTIVE_WRITE_BIAS;
28377 - asm volatile("# beginning down_write\n\t"
28378 - LOCK_PREFIX " xadd %%edx,(%%eax)\n\t"
28379 -+
28380 -+#ifdef CONFIG_PAX_REFCOUNT
28381 -+#ifdef CONFIG_X86_32
28382 -+ "into\n0:\n"
28383 -+#else
28384 -+ "jno 0f\n"
28385 -+ "int $4\n0:\n"
28386 -+#endif
28387 -+ ".pushsection .fixup,\"ax\"\n"
28388 -+ "1:\n"
28389 -+ "movl %%edx,(%%eax)\n"
28390 -+ "jmp 0b\n"
28391 -+ ".popsection\n"
28392 -+ _ASM_EXTABLE(0b, 1b)
28393 -+#endif
28394 -+
28395 - /* subtract 0x0000ffff, returns the old value */
28396 - " testl %%edx,%%edx\n\t"
28397 - /* was the count 0 before? */
28398 -- " jz 1f\n"
28399 -+ " jz 2f\n"
28400 - " call call_rwsem_down_write_failed\n"
28401 -- "1:\n"
28402 -+ "2:\n"
28403 - "# ending down_write"
28404 - : "+m" (sem->count), "=d" (tmp)
28405 - : "a" (sem), "1" (tmp)
28406 -@@ -186,10 +234,26 @@ static inline void __up_read(struct rw_s
28407 - __s32 tmp = -RWSEM_ACTIVE_READ_BIAS;
28408 - asm volatile("# beginning __up_read\n\t"
28409 - LOCK_PREFIX " xadd %%edx,(%%eax)\n\t"
28410 -+
28411 -+#ifdef CONFIG_PAX_REFCOUNT
28412 -+#ifdef CONFIG_X86_32
28413 -+ "into\n0:\n"
28414 -+#else
28415 -+ "jno 0f\n"
28416 -+ "int $4\n0:\n"
28417 -+#endif
28418 -+ ".pushsection .fixup,\"ax\"\n"
28419 -+ "1:\n"
28420 -+ "movl %%edx,(%%eax)\n"
28421 -+ "jmp 0b\n"
28422 -+ ".popsection\n"
28423 -+ _ASM_EXTABLE(0b, 1b)
28424 -+#endif
28425 -+
28426 - /* subtracts 1, returns the old value */
28427 -- " jns 1f\n\t"
28428 -+ " jns 2f\n\t"
28429 - " call call_rwsem_wake\n"
28430 -- "1:\n"
28431 -+ "2:\n"
28432 - "# ending __up_read\n"
28433 - : "+m" (sem->count), "=d" (tmp)
28434 - : "a" (sem), "1" (tmp)
28435 -@@ -204,11 +268,27 @@ static inline void __up_write(struct rw_
28436 - asm volatile("# beginning __up_write\n\t"
28437 - " movl %2,%%edx\n\t"
28438 - LOCK_PREFIX " xaddl %%edx,(%%eax)\n\t"
28439 -+
28440 -+#ifdef CONFIG_PAX_REFCOUNT
28441 -+#ifdef CONFIG_X86_32
28442 -+ "into\n0:\n"
28443 -+#else
28444 -+ "jno 0f\n"
28445 -+ "int $4\n0:\n"
28446 -+#endif
28447 -+ ".pushsection .fixup,\"ax\"\n"
28448 -+ "1:\n"
28449 -+ "movl %%edx,(%%eax)\n"
28450 -+ "jmp 0b\n"
28451 -+ ".popsection\n"
28452 -+ _ASM_EXTABLE(0b, 1b)
28453 -+#endif
28454 -+
28455 - /* tries to transition
28456 - 0xffff0001 -> 0x00000000 */
28457 -- " jz 1f\n"
28458 -+ " jz 2f\n"
28459 - " call call_rwsem_wake\n"
28460 -- "1:\n\t"
28461 -+ "2:\n\t"
28462 - "# ending __up_write\n"
28463 - : "+m" (sem->count)
28464 - : "a" (sem), "i" (-RWSEM_ACTIVE_WRITE_BIAS)
28465 -@@ -222,10 +302,26 @@ static inline void __downgrade_write(str
28466 - {
28467 - asm volatile("# beginning __downgrade_write\n\t"
28468 - LOCK_PREFIX " addl %2,(%%eax)\n\t"
28469 -+
28470 -+#ifdef CONFIG_PAX_REFCOUNT
28471 -+#ifdef CONFIG_X86_32
28472 -+ "into\n0:\n"
28473 -+#else
28474 -+ "jno 0f\n"
28475 -+ "int $4\n0:\n"
28476 -+#endif
28477 -+ ".pushsection .fixup,\"ax\"\n"
28478 -+ "1:\n"
28479 -+ LOCK_PREFIX "subl %2,(%%eax)\n"
28480 -+ "jmp 0b\n"
28481 -+ ".popsection\n"
28482 -+ _ASM_EXTABLE(0b, 1b)
28483 -+#endif
28484 -+
28485 - /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
28486 -- " jns 1f\n\t"
28487 -+ " jns 2f\n\t"
28488 - " call call_rwsem_downgrade_wake\n"
28489 -- "1:\n\t"
28490 -+ "2:\n\t"
28491 - "# ending __downgrade_write\n"
28492 - : "+m" (sem->count)
28493 - : "a" (sem), "i" (-RWSEM_WAITING_BIAS)
28494 -@@ -237,7 +333,23 @@ static inline void __downgrade_write(str
28495 - */
28496 - static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
28497 - {
28498 -- asm volatile(LOCK_PREFIX "addl %1,%0"
28499 -+ asm volatile(LOCK_PREFIX "addl %1,%0\n"
28500 -+
28501 -+#ifdef CONFIG_PAX_REFCOUNT
28502 -+#ifdef CONFIG_X86_32
28503 -+ "into\n0:\n"
28504 -+#else
28505 -+ "jno 0f\n"
28506 -+ "int $4\n0:\n"
28507 -+#endif
28508 -+ ".pushsection .fixup,\"ax\"\n"
28509 -+ "1:\n"
28510 -+ LOCK_PREFIX "subl %1,%0\n"
28511 -+ "jmp 0b\n"
28512 -+ ".popsection\n"
28513 -+ _ASM_EXTABLE(0b, 1b)
28514 -+#endif
28515 -+
28516 - : "+m" (sem->count)
28517 - : "ir" (delta));
28518 - }
28519 -@@ -249,7 +361,23 @@ static inline int rwsem_atomic_update(in
28520 - {
28521 - int tmp = delta;
28522 -
28523 -- asm volatile(LOCK_PREFIX "xadd %0,%1"
28524 -+ asm volatile(LOCK_PREFIX "xadd %0,%1\n"
28525 -+
28526 -+#ifdef CONFIG_PAX_REFCOUNT
28527 -+#ifdef CONFIG_X86_32
28528 -+ "into\n0:\n"
28529 -+#else
28530 -+ "jno 0f\n"
28531 -+ "int $4\n0:\n"
28532 -+#endif
28533 -+ ".pushsection .fixup,\"ax\"\n"
28534 -+ "1:\n"
28535 -+ "movl %0,%1\n"
28536 -+ "jmp 0b\n"
28537 -+ ".popsection\n"
28538 -+ _ASM_EXTABLE(0b, 1b)
28539 -+#endif
28540 -+
28541 - : "+r" (tmp), "+m" (sem->count)
28542 - : : "memory");
28543 -
28544 -diff -urNp linux-2.6.27.6/include/asm-x86/segment.h linux-2.6.27.6/include/asm-x86/segment.h
28545 ---- linux-2.6.27.6/include/asm-x86/segment.h 2008-11-07 12:55:34.000000000 -0500
28546 -+++ linux-2.6.27.6/include/asm-x86/segment.h 2008-11-18 03:38:45.000000000 -0500
28547 -@@ -88,13 +88,19 @@
28548 - #define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14)
28549 - #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
28550 -
28551 --#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
28552 -+#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
28553 - #ifdef CONFIG_SMP
28554 - #define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
28555 - #else
28556 - #define __KERNEL_PERCPU 0
28557 - #endif
28558 -
28559 -+#define GDT_ENTRY_PCIBIOS_CS (GDT_ENTRY_KERNEL_BASE + 16)
28560 -+#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8)
28561 -+
28562 -+#define GDT_ENTRY_PCIBIOS_DS (GDT_ENTRY_KERNEL_BASE + 17)
28563 -+#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8)
28564 -+
28565 - #define GDT_ENTRY_DOUBLEFAULT_TSS 31
28566 -
28567 - /*
28568 -@@ -135,10 +141,10 @@
28569 - #define SEGMENT_IS_KERNEL_CODE(x) (((x) & 0xfc) == GDT_ENTRY_KERNEL_CS * 8)
28570 -
28571 - /* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */
28572 --#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8)
28573 -+#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xFFFCU) == __KERNEL_CS || ((x) & 0xFFFCU) == __USER_CS)
28574 -
28575 - /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
28576 --#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
28577 -+#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
28578 -
28579 -
28580 - #else
28581 -diff -urNp linux-2.6.27.6/include/asm-x86/spinlock.h linux-2.6.27.6/include/asm-x86/spinlock.h
28582 ---- linux-2.6.27.6/include/asm-x86/spinlock.h 2008-11-07 12:55:34.000000000 -0500
28583 -+++ linux-2.6.27.6/include/asm-x86/spinlock.h 2008-11-18 03:38:45.000000000 -0500
28584 -@@ -315,18 +315,50 @@ static inline int __raw_write_can_lock(r
28585 - static inline void __raw_read_lock(raw_rwlock_t *rw)
28586 - {
28587 - asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t"
28588 -- "jns 1f\n"
28589 -- "call __read_lock_failed\n\t"
28590 -+
28591 -+#ifdef CONFIG_PAX_REFCOUNT
28592 -+#ifdef CONFIG_X86_32
28593 -+ "into\n0:\n"
28594 -+#else
28595 -+ "jno 0f\n"
28596 -+ "int $4\n0:\n"
28597 -+#endif
28598 -+ ".pushsection .fixup,\"ax\"\n"
28599 - "1:\n"
28600 -+ LOCK_PREFIX " addl $1,(%0)\n"
28601 -+ "jmp 0b\n"
28602 -+ ".popsection\n"
28603 -+ _ASM_EXTABLE(0b, 1b)
28604 -+#endif
28605 -+
28606 -+ "jns 2f\n"
28607 -+ "call __read_lock_failed\n\t"
28608 -+ "2:\n"
28609 - ::LOCK_PTR_REG (rw) : "memory");
28610 - }
28611 -
28612 - static inline void __raw_write_lock(raw_rwlock_t *rw)
28613 - {
28614 - asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t"
28615 -- "jz 1f\n"
28616 -- "call __write_lock_failed\n\t"
28617 -+
28618 -+#ifdef CONFIG_PAX_REFCOUNT
28619 -+#ifdef CONFIG_X86_32
28620 -+ "into\n0:\n"
28621 -+#else
28622 -+ "jno 0f\n"
28623 -+ "int $4\n0:\n"
28624 -+#endif
28625 -+ ".pushsection .fixup,\"ax\"\n"
28626 - "1:\n"
28627 -+ LOCK_PREFIX " addl %1,(%0)\n"
28628 -+ "jmp 0b\n"
28629 -+ ".popsection\n"
28630 -+ _ASM_EXTABLE(0b, 1b)
28631 -+#endif
28632 -+
28633 -+ "jz 2f\n"
28634 -+ "call __write_lock_failed\n\t"
28635 -+ "2:\n"
28636 - ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory");
28637 - }
28638 -
28639 -@@ -353,12 +385,45 @@ static inline int __raw_write_trylock(ra
28640 -
28641 - static inline void __raw_read_unlock(raw_rwlock_t *rw)
28642 - {
28643 -- asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory");
28644 -+ asm volatile(LOCK_PREFIX "incl %0\n"
28645 -+
28646 -+#ifdef CONFIG_PAX_REFCOUNT
28647 -+#ifdef CONFIG_X86_32
28648 -+ "into\n0:\n"
28649 -+#else
28650 -+ "jno 0f\n"
28651 -+ "int $4\n0:\n"
28652 -+#endif
28653 -+ ".pushsection .fixup,\"ax\"\n"
28654 -+ "1:\n"
28655 -+ LOCK_PREFIX "decl %0\n"
28656 -+ "jmp 0b\n"
28657 -+ ".popsection\n"
28658 -+ _ASM_EXTABLE(0b, 1b)
28659 -+#endif
28660 -+
28661 -+ :"+m" (rw->lock) : : "memory");
28662 - }
28663 -
28664 - static inline void __raw_write_unlock(raw_rwlock_t *rw)
28665 - {
28666 -- asm volatile(LOCK_PREFIX "addl %1, %0"
28667 -+ asm volatile(LOCK_PREFIX "addl %1, %0\n"
28668 -+
28669 -+#ifdef CONFIG_PAX_REFCOUNT
28670 -+#ifdef CONFIG_X86_32
28671 -+ "into\n0:\n"
28672 -+#else
28673 -+ "jno 0f\n"
28674 -+ "int $4\n0:\n"
28675 -+#endif
28676 -+ ".pushsection .fixup,\"ax\"\n"
28677 -+ "1:\n"
28678 -+ LOCK_PREFIX "subl %1,%0\n"
28679 -+ "jmp 0b\n"
28680 -+ ".popsection\n"
28681 -+ _ASM_EXTABLE(0b, 1b)
28682 -+#endif
28683 -+
28684 - : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory");
28685 - }
28686 -
28687 -diff -urNp linux-2.6.27.6/include/asm-x86/system.h linux-2.6.27.6/include/asm-x86/system.h
28688 ---- linux-2.6.27.6/include/asm-x86/system.h 2008-11-07 12:55:34.000000000 -0500
28689 -+++ linux-2.6.27.6/include/asm-x86/system.h 2008-11-18 03:38:45.000000000 -0500
28690 -@@ -92,6 +92,8 @@ do { \
28691 - ".globl thread_return\n" \
28692 - "thread_return:\n\t" \
28693 - "movq %%gs:%P[pda_pcurrent],%%rsi\n\t" \
28694 -+ "movq %P[task_canary](%%rsi),%%r8\n\t" \
28695 -+ "movq %%r8,%%gs:%P[pda_canary]\n\t" \
28696 - "movq %P[thread_info](%%rsi),%%r8\n\t" \
28697 - LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \
28698 - "movq %%rax,%%rdi\n\t" \
28699 -@@ -103,7 +105,9 @@ do { \
28700 - [ti_flags] "i" (offsetof(struct thread_info, flags)), \
28701 - [tif_fork] "i" (TIF_FORK), \
28702 - [thread_info] "i" (offsetof(struct task_struct, stack)), \
28703 -- [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \
28704 -+ [task_canary] "i" (offsetof(struct task_struct, stack_canary)), \
28705 -+ [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)), \
28706 -+ [pda_canary] "i" (offsetof(struct x8664_pda, stack_canary))\
28707 - : "memory", "cc" __EXTRA_CLOBBER)
28708 - #endif
28709 -
28710 -@@ -166,7 +170,7 @@ static inline unsigned long get_limit(un
28711 - {
28712 - unsigned long __limit;
28713 - asm("lsll %1,%0" : "=r" (__limit) : "r" (segment));
28714 -- return __limit + 1;
28715 -+ return __limit;
28716 - }
28717 -
28718 - static inline void native_clts(void)
28719 -@@ -292,6 +296,21 @@ static inline void native_wbinvd(void)
28720 -
28721 - #define stts() write_cr0(read_cr0() | X86_CR0_TS)
28722 -
28723 -+#define pax_open_kernel(cr0) \
28724 -+do { \
28725 -+ typecheck(unsigned long, cr0); \
28726 -+ preempt_disable(); \
28727 -+ cr0 = read_cr0(); \
28728 -+ write_cr0(cr0 & ~X86_CR0_WP); \
28729 -+} while (0)
28730 -+
28731 -+#define pax_close_kernel(cr0) \
28732 -+do { \
28733 -+ typecheck(unsigned long, cr0); \
28734 -+ write_cr0(cr0); \
28735 -+ preempt_enable_no_resched(); \
28736 -+} while (0)
28737 -+
28738 - #endif /* __KERNEL__ */
28739 -
28740 - static inline void clflush(volatile void *__p)
28741 -@@ -306,7 +325,7 @@ void enable_hlt(void);
28742 -
28743 - void cpu_idle_wait(void);
28744 -
28745 --extern unsigned long arch_align_stack(unsigned long sp);
28746 -+#define arch_align_stack(x) ((x) & ~0xfUL)
28747 - extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
28748 -
28749 - void default_idle(void);
28750 -diff -urNp linux-2.6.27.6/include/asm-x86/uaccess_64.h linux-2.6.27.6/include/asm-x86/uaccess_64.h
28751 ---- linux-2.6.27.6/include/asm-x86/uaccess_64.h 2008-11-07 12:55:34.000000000 -0500
28752 -+++ linux-2.6.27.6/include/asm-x86/uaccess_64.h 2008-11-18 03:38:45.000000000 -0500
28753 -@@ -10,6 +10,8 @@
28754 - #include <linux/lockdep.h>
28755 - #include <asm/page.h>
28756 -
28757 -+#define set_fs(x) (current_thread_info()->addr_limit = (x))
28758 -+
28759 - /*
28760 - * Copy To/From Userspace
28761 - */
28762 -diff -urNp linux-2.6.27.6/include/asm-x86/uaccess.h linux-2.6.27.6/include/asm-x86/uaccess.h
28763 ---- linux-2.6.27.6/include/asm-x86/uaccess.h 2008-11-07 12:55:34.000000000 -0500
28764 -+++ linux-2.6.27.6/include/asm-x86/uaccess.h 2008-11-18 03:38:45.000000000 -0500
28765 -@@ -10,6 +10,7 @@
28766 - #include <linux/string.h>
28767 - #include <asm/asm.h>
28768 - #include <asm/page.h>
28769 -+#include <asm/segment.h>
28770 -
28771 - #define VERIFY_READ 0
28772 - #define VERIFY_WRITE 1
28773 -@@ -29,7 +30,12 @@
28774 -
28775 - #define get_ds() (KERNEL_DS)
28776 - #define get_fs() (current_thread_info()->addr_limit)
28777 -+#ifdef CONFIG_X86_32
28778 -+void __set_fs(mm_segment_t x, int cpu);
28779 -+void set_fs(mm_segment_t x);
28780 -+#else
28781 - #define set_fs(x) (current_thread_info()->addr_limit = (x))
28782 -+#endif
28783 -
28784 - #define segment_eq(a, b) ((a).seg == (b).seg)
28785 -
28786 -@@ -97,6 +103,7 @@ struct exception_table_entry {
28787 - };
28788 -
28789 - extern int fixup_exception(struct pt_regs *regs);
28790 -+#define ARCH_HAS_SORT_EXTABLE
28791 -
28792 - /*
28793 - * These are the main single-value transfer routines. They automatically
28794 -@@ -186,9 +193,12 @@ extern int __get_user_bad(void);
28795 -
28796 - #ifdef CONFIG_X86_32
28797 - #define __put_user_u64(x, addr, err) \
28798 -- asm volatile("1: movl %%eax,0(%2)\n" \
28799 -- "2: movl %%edx,4(%2)\n" \
28800 -+ asm volatile(" movw %w5,%%ds\n" \
28801 -+ "1: movl %%eax,%%ds:0(%2)\n" \
28802 -+ "2: movl %%edx,%%ds:4(%2)\n" \
28803 - "3:\n" \
28804 -+ " pushl %%ss\n" \
28805 -+ " popl %%ds\n" \
28806 - ".section .fixup,\"ax\"\n" \
28807 - "4: movl %3,%0\n" \
28808 - " jmp 3b\n" \
28809 -@@ -196,7 +206,8 @@ extern int __get_user_bad(void);
28810 - _ASM_EXTABLE(1b, 4b) \
28811 - _ASM_EXTABLE(2b, 4b) \
28812 - : "=r" (err) \
28813 -- : "A" (x), "r" (addr), "i" (-EFAULT), "0" (err))
28814 -+ : "A" (x), "r" (addr), "i" (-EFAULT), "0" (err), \
28815 -+ "r"(__USER_DS))
28816 -
28817 - #define __put_user_x8(x, ptr, __ret_pu) \
28818 - asm volatile("call __put_user_8" : "=a" (__ret_pu) \
28819 -@@ -336,6 +347,22 @@ do { \
28820 - } \
28821 - } while (0)
28822 -
28823 -+#ifdef CONFIG_X86_32
28824 -+#define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
28825 -+ asm volatile(" movw %w5,%%ds\n" \
28826 -+ "1: mov"itype" %%ds:%2,%"rtype"1\n" \
28827 -+ "2:\n" \
28828 -+ " pushl %%ss\n" \
28829 -+ " popl %%ds\n" \
28830 -+ ".section .fixup,\"ax\"\n" \
28831 -+ "3: movl %3,%0\n" \
28832 -+ " xor"itype" %"rtype"1,%"rtype"1\n" \
28833 -+ " jmp 2b\n" \
28834 -+ ".previous\n" \
28835 -+ _ASM_EXTABLE(1b, 3b) \
28836 -+ : "=r" (err), ltype (x) \
28837 -+ : "m" (__m(addr)), "i" (errret), "0" (err), "r"(__USER_DS))
28838 -+#else
28839 - #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
28840 - asm volatile("1: mov"itype" %2,%"rtype"1\n" \
28841 - "2:\n" \
28842 -@@ -347,6 +374,7 @@ do { \
28843 - _ASM_EXTABLE(1b, 3b) \
28844 - : "=r" (err), ltype(x) \
28845 - : "m" (__m(addr)), "i" (errret), "0" (err))
28846 -+#endif
28847 -
28848 - #define __put_user_nocheck(x, ptr, size) \
28849 - ({ \
28850 -@@ -373,6 +401,22 @@ struct __large_struct { unsigned long bu
28851 - * we do not write to any memory gcc knows about, so there are no
28852 - * aliasing issues.
28853 - */
28854 -+#ifdef CONFIG_X86_32
28855 -+#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
28856 -+ asm volatile(" movw %w5,%%ds\n" \
28857 -+ "1: mov"itype" %"rtype"1,%%ds:%2\n" \
28858 -+ "2:\n" \
28859 -+ " pushl %%ss\n" \
28860 -+ " popl %%ds\n" \
28861 -+ ".section .fixup,\"ax\"\n" \
28862 -+ "3: movl %3,%0\n" \
28863 -+ " jmp 2b\n" \
28864 -+ ".previous\n" \
28865 -+ _ASM_EXTABLE(1b, 3b) \
28866 -+ : "=r"(err) \
28867 -+ : ltype (x), "m" (__m(addr)), "i" (errret), "0" (err),\
28868 -+ "r"(__USER_DS))
28869 -+#else
28870 - #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
28871 - asm volatile("1: mov"itype" %"rtype"1,%2\n" \
28872 - "2:\n" \
28873 -@@ -383,6 +427,7 @@ struct __large_struct { unsigned long bu
28874 - _ASM_EXTABLE(1b, 3b) \
28875 - : "=r"(err) \
28876 - : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err))
28877 -+#endif
28878 - /**
28879 - * __get_user: - Get a simple variable from user space, with less checking.
28880 - * @x: Variable to store result.
28881 -@@ -447,6 +492,7 @@ extern struct movsl_mask {
28882 - # include "uaccess_32.h"
28883 - #else
28884 - # define ARCH_HAS_SEARCH_EXTABLE
28885 -+# define ARCH_HAS_SORT_EXTABLE
28886 - # include "uaccess_64.h"
28887 - #endif
28888 -
28889 -diff -urNp linux-2.6.27.6/include/asm-xtensa/kmap_types.h linux-2.6.27.6/include/asm-xtensa/kmap_types.h
28890 ---- linux-2.6.27.6/include/asm-xtensa/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
28891 -+++ linux-2.6.27.6/include/asm-xtensa/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
28892 -@@ -25,6 +25,7 @@ enum km_type {
28893 - KM_IRQ1,
28894 - KM_SOFTIRQ0,
28895 - KM_SOFTIRQ1,
28896 -+ KM_CLEARPAGE,
28897 - KM_TYPE_NR
28898 - };
28899 -
28900 -diff -urNp linux-2.6.27.6/include/drm/drm_pciids.h linux-2.6.27.6/include/drm/drm_pciids.h
28901 ---- linux-2.6.27.6/include/drm/drm_pciids.h 2008-11-07 12:55:34.000000000 -0500
28902 -+++ linux-2.6.27.6/include/drm/drm_pciids.h 2008-11-18 03:38:45.000000000 -0500
28903 -@@ -237,7 +237,7 @@
28904 - {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
28905 - {0x1002, 0x791e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
28906 - {0x1002, 0x791f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
28907 -- {0, 0, 0}
28908 -+ {0, 0, 0, 0, 0, 0}
28909 -
28910 - #define r128_PCI_IDS \
28911 - {0x1002, 0x4c45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28912 -@@ -277,14 +277,14 @@
28913 - {0x1002, 0x5446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28914 - {0x1002, 0x544C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28915 - {0x1002, 0x5452, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28916 -- {0, 0, 0}
28917 -+ {0, 0, 0, 0, 0, 0}
28918 -
28919 - #define mga_PCI_IDS \
28920 - {0x102b, 0x0520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \
28921 - {0x102b, 0x0521, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \
28922 - {0x102b, 0x0525, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G400}, \
28923 - {0x102b, 0x2527, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G550}, \
28924 -- {0, 0, 0}
28925 -+ {0, 0, 0, 0, 0, 0}
28926 -
28927 - #define mach64_PCI_IDS \
28928 - {0x1002, 0x4749, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28929 -@@ -307,7 +307,7 @@
28930 - {0x1002, 0x4c53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28931 - {0x1002, 0x4c4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28932 - {0x1002, 0x4c4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28933 -- {0, 0, 0}
28934 -+ {0, 0, 0, 0, 0, 0}
28935 -
28936 - #define sisdrv_PCI_IDS \
28937 - {0x1039, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28938 -@@ -318,7 +318,7 @@
28939 - {0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28940 - {0x18CA, 0x0040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
28941 - {0x18CA, 0x0042, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
28942 -- {0, 0, 0}
28943 -+ {0, 0, 0, 0, 0, 0}
28944 -
28945 - #define tdfx_PCI_IDS \
28946 - {0x121a, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28947 -@@ -327,7 +327,7 @@
28948 - {0x121a, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28949 - {0x121a, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28950 - {0x121a, 0x000b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28951 -- {0, 0, 0}
28952 -+ {0, 0, 0, 0, 0, 0}
28953 -
28954 - #define viadrv_PCI_IDS \
28955 - {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28956 -@@ -339,25 +339,25 @@
28957 - {0x1106, 0x3343, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28958 - {0x1106, 0x3230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_DX9_0}, \
28959 - {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \
28960 -- {0, 0, 0}
28961 -+ {0, 0, 0, 0, 0, 0}
28962 -
28963 - #define i810_PCI_IDS \
28964 - {0x8086, 0x7121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28965 - {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28966 - {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28967 - {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28968 -- {0, 0, 0}
28969 -+ {0, 0, 0, 0, 0, 0}
28970 -
28971 - #define i830_PCI_IDS \
28972 - {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28973 - {0x8086, 0x2562, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28974 - {0x8086, 0x3582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28975 - {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28976 -- {0, 0, 0}
28977 -+ {0, 0, 0, 0, 0, 0}
28978 -
28979 - #define gamma_PCI_IDS \
28980 - {0x3d3d, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28981 -- {0, 0, 0}
28982 -+ {0, 0, 0, 0, 0, 0}
28983 -
28984 - #define savage_PCI_IDS \
28985 - {0x5333, 0x8a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \
28986 -@@ -383,10 +383,10 @@
28987 - {0x5333, 0x8d02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_TWISTER}, \
28988 - {0x5333, 0x8d03, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \
28989 - {0x5333, 0x8d04, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \
28990 -- {0, 0, 0}
28991 -+ {0, 0, 0, 0, 0, 0}
28992 -
28993 - #define ffb_PCI_IDS \
28994 -- {0, 0, 0}
28995 -+ {0, 0, 0, 0, 0, 0}
28996 -
28997 - #define i915_PCI_IDS \
28998 - {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
28999 -@@ -412,4 +412,4 @@
29000 - {0x8086, 0x2e02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29001 - {0x8086, 0x2e12, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29002 - {0x8086, 0x2e22, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29003 -- {0, 0, 0}
29004 -+ {0, 0, 0, 0, 0, 0}
29005 -diff -urNp linux-2.6.27.6/include/linux/a.out.h linux-2.6.27.6/include/linux/a.out.h
29006 ---- linux-2.6.27.6/include/linux/a.out.h 2008-11-07 12:55:34.000000000 -0500
29007 -+++ linux-2.6.27.6/include/linux/a.out.h 2008-11-18 03:38:45.000000000 -0500
29008 -@@ -39,6 +39,14 @@ enum machine_type {
29009 - M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
29010 - };
29011 -
29012 -+/* Constants for the N_FLAGS field */
29013 -+#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
29014 -+#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
29015 -+#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
29016 -+#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
29017 -+/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
29018 -+#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
29019 -+
29020 - #if !defined (N_MAGIC)
29021 - #define N_MAGIC(exec) ((exec).a_info & 0xffff)
29022 - #endif
29023 -diff -urNp linux-2.6.27.6/include/linux/cache.h linux-2.6.27.6/include/linux/cache.h
29024 ---- linux-2.6.27.6/include/linux/cache.h 2008-11-07 12:55:34.000000000 -0500
29025 -+++ linux-2.6.27.6/include/linux/cache.h 2008-11-18 03:38:45.000000000 -0500
29026 -@@ -16,6 +16,10 @@
29027 - #define __read_mostly
29028 - #endif
29029 -
29030 -+#ifndef __read_only
29031 -+#define __read_only __read_mostly
29032 -+#endif
29033 -+
29034 - #ifndef ____cacheline_aligned
29035 - #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
29036 - #endif
29037 -diff -urNp linux-2.6.27.6/include/linux/capability.h linux-2.6.27.6/include/linux/capability.h
29038 ---- linux-2.6.27.6/include/linux/capability.h 2008-11-07 12:55:34.000000000 -0500
29039 -+++ linux-2.6.27.6/include/linux/capability.h 2008-11-18 03:38:45.000000000 -0500
29040 -@@ -516,6 +516,7 @@ kernel_cap_t cap_set_effective(const ker
29041 - #define has_capability(t, cap) (security_capable((t), (cap)) == 0)
29042 -
29043 - extern int capable(int cap);
29044 -+int capable_nolog(int cap);
29045 -
29046 - #endif /* __KERNEL__ */
29047 -
29048 -diff -urNp linux-2.6.27.6/include/linux/cpumask.h linux-2.6.27.6/include/linux/cpumask.h
29049 ---- linux-2.6.27.6/include/linux/cpumask.h 2008-11-07 12:55:34.000000000 -0500
29050 -+++ linux-2.6.27.6/include/linux/cpumask.h 2008-11-18 03:38:45.000000000 -0500
29051 -@@ -139,7 +139,6 @@
29052 - #include <linux/bitmap.h>
29053 -
29054 - typedef struct { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;
29055 --extern cpumask_t _unused_cpumask_arg_;
29056 -
29057 - #define cpu_set(cpu, dst) __cpu_set((cpu), &(dst))
29058 - static inline void __cpu_set(int cpu, volatile cpumask_t *dstp)
29059 -diff -urNp linux-2.6.27.6/include/linux/elf.h linux-2.6.27.6/include/linux/elf.h
29060 ---- linux-2.6.27.6/include/linux/elf.h 2008-11-07 12:55:34.000000000 -0500
29061 -+++ linux-2.6.27.6/include/linux/elf.h 2008-11-18 03:38:45.000000000 -0500
29062 -@@ -50,6 +50,16 @@ typedef __s64 Elf64_Sxword;
29063 -
29064 - #define PT_GNU_STACK (PT_LOOS + 0x474e551)
29065 -
29066 -+#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
29067 -+
29068 -+/* Constants for the e_flags field */
29069 -+#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
29070 -+#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
29071 -+#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
29072 -+#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
29073 -+/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
29074 -+#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
29075 -+
29076 - /* These constants define the different elf file types */
29077 - #define ET_NONE 0
29078 - #define ET_REL 1
29079 -@@ -84,6 +94,8 @@ typedef __s64 Elf64_Sxword;
29080 - #define DT_DEBUG 21
29081 - #define DT_TEXTREL 22
29082 - #define DT_JMPREL 23
29083 -+#define DT_FLAGS 30
29084 -+ #define DF_TEXTREL 0x00000004
29085 - #define DT_ENCODING 32
29086 - #define OLD_DT_LOOS 0x60000000
29087 - #define DT_LOOS 0x6000000d
29088 -@@ -230,6 +242,19 @@ typedef struct elf64_hdr {
29089 - #define PF_W 0x2
29090 - #define PF_X 0x1
29091 -
29092 -+#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */
29093 -+#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */
29094 -+#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */
29095 -+#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */
29096 -+#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */
29097 -+#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */
29098 -+/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */
29099 -+/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */
29100 -+#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */
29101 -+#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */
29102 -+#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */
29103 -+#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */
29104 -+
29105 - typedef struct elf32_phdr{
29106 - Elf32_Word p_type;
29107 - Elf32_Off p_offset;
29108 -@@ -322,6 +347,8 @@ typedef struct elf64_shdr {
29109 - #define EI_OSABI 7
29110 - #define EI_PAD 8
29111 -
29112 -+#define EI_PAX 14
29113 -+
29114 - #define ELFMAG0 0x7f /* EI_MAG */
29115 - #define ELFMAG1 'E'
29116 - #define ELFMAG2 'L'
29117 -@@ -383,6 +410,7 @@ extern Elf32_Dyn _DYNAMIC [];
29118 - #define elf_phdr elf32_phdr
29119 - #define elf_note elf32_note
29120 - #define elf_addr_t Elf32_Off
29121 -+#define elf_dyn Elf32_Dyn
29122 -
29123 - #else
29124 -
29125 -@@ -391,6 +419,7 @@ extern Elf64_Dyn _DYNAMIC [];
29126 - #define elf_phdr elf64_phdr
29127 - #define elf_note elf64_note
29128 - #define elf_addr_t Elf64_Off
29129 -+#define elf_dyn Elf64_Dyn
29130 -
29131 - #endif
29132 -
29133 -diff -urNp linux-2.6.27.6/include/linux/gracl.h linux-2.6.27.6/include/linux/gracl.h
29134 ---- linux-2.6.27.6/include/linux/gracl.h 1969-12-31 19:00:00.000000000 -0500
29135 -+++ linux-2.6.27.6/include/linux/gracl.h 2008-11-18 03:38:45.000000000 -0500
29136 -@@ -0,0 +1,318 @@
29137 -+#ifndef GR_ACL_H
29138 -+#define GR_ACL_H
29139 -+
29140 -+#include <linux/grdefs.h>
29141 -+#include <linux/resource.h>
29142 -+#include <linux/capability.h>
29143 -+#include <linux/dcache.h>
29144 -+#include <asm/resource.h>
29145 -+
29146 -+/* Major status information */
29147 -+
29148 -+#define GR_VERSION "grsecurity 2.1.12"
29149 -+#define GRSECURITY_VERSION 0x2112
29150 -+
29151 -+enum {
29152 -+
29153 -+ SHUTDOWN = 0,
29154 -+ ENABLE = 1,
29155 -+ SPROLE = 2,
29156 -+ RELOAD = 3,
29157 -+ SEGVMOD = 4,
29158 -+ STATUS = 5,
29159 -+ UNSPROLE = 6,
29160 -+ PASSSET = 7,
29161 -+ SPROLEPAM = 8
29162 -+};
29163 -+
29164 -+/* Password setup definitions
29165 -+ * kernel/grhash.c */
29166 -+enum {
29167 -+ GR_PW_LEN = 128,
29168 -+ GR_SALT_LEN = 16,
29169 -+ GR_SHA_LEN = 32,
29170 -+};
29171 -+
29172 -+enum {
29173 -+ GR_SPROLE_LEN = 64,
29174 -+};
29175 -+
29176 -+#define GR_NLIMITS (RLIMIT_LOCKS + 2)
29177 -+
29178 -+/* Begin Data Structures */
29179 -+
29180 -+struct sprole_pw {
29181 -+ unsigned char *rolename;
29182 -+ unsigned char salt[GR_SALT_LEN];
29183 -+ unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
29184 -+};
29185 -+
29186 -+struct name_entry {
29187 -+ __u32 key;
29188 -+ ino_t inode;
29189 -+ dev_t device;
29190 -+ char *name;
29191 -+ __u16 len;
29192 -+ __u8 deleted;
29193 -+ struct name_entry *prev;
29194 -+ struct name_entry *next;
29195 -+};
29196 -+
29197 -+struct inodev_entry {
29198 -+ struct name_entry *nentry;
29199 -+ struct inodev_entry *prev;
29200 -+ struct inodev_entry *next;
29201 -+};
29202 -+
29203 -+struct acl_role_db {
29204 -+ struct acl_role_label **r_hash;
29205 -+ __u32 r_size;
29206 -+};
29207 -+
29208 -+struct inodev_db {
29209 -+ struct inodev_entry **i_hash;
29210 -+ __u32 i_size;
29211 -+};
29212 -+
29213 -+struct name_db {
29214 -+ struct name_entry **n_hash;
29215 -+ __u32 n_size;
29216 -+};
29217 -+
29218 -+struct crash_uid {
29219 -+ uid_t uid;
29220 -+ unsigned long expires;
29221 -+};
29222 -+
29223 -+struct gr_hash_struct {
29224 -+ void **table;
29225 -+ void **nametable;
29226 -+ void *first;
29227 -+ __u32 table_size;
29228 -+ __u32 used_size;
29229 -+ int type;
29230 -+};
29231 -+
29232 -+/* Userspace Grsecurity ACL data structures */
29233 -+
29234 -+struct acl_subject_label {
29235 -+ char *filename;
29236 -+ ino_t inode;
29237 -+ dev_t device;
29238 -+ __u32 mode;
29239 -+ kernel_cap_t cap_mask;
29240 -+ kernel_cap_t cap_lower;
29241 -+
29242 -+ struct rlimit res[GR_NLIMITS];
29243 -+ __u16 resmask;
29244 -+
29245 -+ __u8 user_trans_type;
29246 -+ __u8 group_trans_type;
29247 -+ uid_t *user_transitions;
29248 -+ gid_t *group_transitions;
29249 -+ __u16 user_trans_num;
29250 -+ __u16 group_trans_num;
29251 -+
29252 -+ __u32 ip_proto[8];
29253 -+ __u32 ip_type;
29254 -+ struct acl_ip_label **ips;
29255 -+ __u32 ip_num;
29256 -+
29257 -+ __u32 crashes;
29258 -+ unsigned long expires;
29259 -+
29260 -+ struct acl_subject_label *parent_subject;
29261 -+ struct gr_hash_struct *hash;
29262 -+ struct acl_subject_label *prev;
29263 -+ struct acl_subject_label *next;
29264 -+
29265 -+ struct acl_object_label **obj_hash;
29266 -+ __u32 obj_hash_size;
29267 -+ __u16 pax_flags;
29268 -+};
29269 -+
29270 -+struct role_allowed_ip {
29271 -+ __u32 addr;
29272 -+ __u32 netmask;
29273 -+
29274 -+ struct role_allowed_ip *prev;
29275 -+ struct role_allowed_ip *next;
29276 -+};
29277 -+
29278 -+struct role_transition {
29279 -+ char *rolename;
29280 -+
29281 -+ struct role_transition *prev;
29282 -+ struct role_transition *next;
29283 -+};
29284 -+
29285 -+struct acl_role_label {
29286 -+ char *rolename;
29287 -+ uid_t uidgid;
29288 -+ __u16 roletype;
29289 -+
29290 -+ __u16 auth_attempts;
29291 -+ unsigned long expires;
29292 -+
29293 -+ struct acl_subject_label *root_label;
29294 -+ struct gr_hash_struct *hash;
29295 -+
29296 -+ struct acl_role_label *prev;
29297 -+ struct acl_role_label *next;
29298 -+
29299 -+ struct role_transition *transitions;
29300 -+ struct role_allowed_ip *allowed_ips;
29301 -+ uid_t *domain_children;
29302 -+ __u16 domain_child_num;
29303 -+
29304 -+ struct acl_subject_label **subj_hash;
29305 -+ __u32 subj_hash_size;
29306 -+};
29307 -+
29308 -+struct user_acl_role_db {
29309 -+ struct acl_role_label **r_table;
29310 -+ __u32 num_pointers; /* Number of allocations to track */
29311 -+ __u32 num_roles; /* Number of roles */
29312 -+ __u32 num_domain_children; /* Number of domain children */
29313 -+ __u32 num_subjects; /* Number of subjects */
29314 -+ __u32 num_objects; /* Number of objects */
29315 -+};
29316 -+
29317 -+struct acl_object_label {
29318 -+ char *filename;
29319 -+ ino_t inode;
29320 -+ dev_t device;
29321 -+ __u32 mode;
29322 -+
29323 -+ struct acl_subject_label *nested;
29324 -+ struct acl_object_label *globbed;
29325 -+
29326 -+ /* next two structures not used */
29327 -+
29328 -+ struct acl_object_label *prev;
29329 -+ struct acl_object_label *next;
29330 -+};
29331 -+
29332 -+struct acl_ip_label {
29333 -+ char *iface;
29334 -+ __u32 addr;
29335 -+ __u32 netmask;
29336 -+ __u16 low, high;
29337 -+ __u8 mode;
29338 -+ __u32 type;
29339 -+ __u32 proto[8];
29340 -+
29341 -+ /* next two structures not used */
29342 -+
29343 -+ struct acl_ip_label *prev;
29344 -+ struct acl_ip_label *next;
29345 -+};
29346 -+
29347 -+struct gr_arg {
29348 -+ struct user_acl_role_db role_db;
29349 -+ unsigned char pw[GR_PW_LEN];
29350 -+ unsigned char salt[GR_SALT_LEN];
29351 -+ unsigned char sum[GR_SHA_LEN];
29352 -+ unsigned char sp_role[GR_SPROLE_LEN];
29353 -+ struct sprole_pw *sprole_pws;
29354 -+ dev_t segv_device;
29355 -+ ino_t segv_inode;
29356 -+ uid_t segv_uid;
29357 -+ __u16 num_sprole_pws;
29358 -+ __u16 mode;
29359 -+};
29360 -+
29361 -+struct gr_arg_wrapper {
29362 -+ struct gr_arg *arg;
29363 -+ __u32 version;
29364 -+ __u32 size;
29365 -+};
29366 -+
29367 -+struct subject_map {
29368 -+ struct acl_subject_label *user;
29369 -+ struct acl_subject_label *kernel;
29370 -+ struct subject_map *prev;
29371 -+ struct subject_map *next;
29372 -+};
29373 -+
29374 -+struct acl_subj_map_db {
29375 -+ struct subject_map **s_hash;
29376 -+ __u32 s_size;
29377 -+};
29378 -+
29379 -+/* End Data Structures Section */
29380 -+
29381 -+/* Hash functions generated by empirical testing by Brad Spengler
29382 -+ Makes good use of the low bits of the inode. Generally 0-1 times
29383 -+ in loop for successful match. 0-3 for unsuccessful match.
29384 -+ Shift/add algorithm with modulus of table size and an XOR*/
29385 -+
29386 -+static __inline__ unsigned int
29387 -+rhash(const uid_t uid, const __u16 type, const unsigned int sz)
29388 -+{
29389 -+ return (((uid << type) + (uid ^ type)) % sz);
29390 -+}
29391 -+
29392 -+ static __inline__ unsigned int
29393 -+shash(const struct acl_subject_label *userp, const unsigned int sz)
29394 -+{
29395 -+ return ((const unsigned long)userp % sz);
29396 -+}
29397 -+
29398 -+static __inline__ unsigned int
29399 -+fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
29400 -+{
29401 -+ return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
29402 -+}
29403 -+
29404 -+static __inline__ unsigned int
29405 -+nhash(const char *name, const __u16 len, const unsigned int sz)
29406 -+{
29407 -+ return full_name_hash(name, len) % sz;
29408 -+}
29409 -+
29410 -+#define FOR_EACH_ROLE_START(role,iter) \
29411 -+ role = NULL; \
29412 -+ iter = 0; \
29413 -+ while (iter < acl_role_set.r_size) { \
29414 -+ if (role == NULL) \
29415 -+ role = acl_role_set.r_hash[iter]; \
29416 -+ if (role == NULL) { \
29417 -+ iter++; \
29418 -+ continue; \
29419 -+ }
29420 -+
29421 -+#define FOR_EACH_ROLE_END(role,iter) \
29422 -+ role = role->next; \
29423 -+ if (role == NULL) \
29424 -+ iter++; \
29425 -+ }
29426 -+
29427 -+#define FOR_EACH_SUBJECT_START(role,subj,iter) \
29428 -+ subj = NULL; \
29429 -+ iter = 0; \
29430 -+ while (iter < role->subj_hash_size) { \
29431 -+ if (subj == NULL) \
29432 -+ subj = role->subj_hash[iter]; \
29433 -+ if (subj == NULL) { \
29434 -+ iter++; \
29435 -+ continue; \
29436 -+ }
29437 -+
29438 -+#define FOR_EACH_SUBJECT_END(subj,iter) \
29439 -+ subj = subj->next; \
29440 -+ if (subj == NULL) \
29441 -+ iter++; \
29442 -+ }
29443 -+
29444 -+
29445 -+#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
29446 -+ subj = role->hash->first; \
29447 -+ while (subj != NULL) {
29448 -+
29449 -+#define FOR_EACH_NESTED_SUBJECT_END(subj) \
29450 -+ subj = subj->next; \
29451 -+ }
29452 -+
29453 -+#endif
29454 -+
29455 -diff -urNp linux-2.6.27.6/include/linux/gralloc.h linux-2.6.27.6/include/linux/gralloc.h
29456 ---- linux-2.6.27.6/include/linux/gralloc.h 1969-12-31 19:00:00.000000000 -0500
29457 -+++ linux-2.6.27.6/include/linux/gralloc.h 2008-11-18 03:38:45.000000000 -0500
29458 -@@ -0,0 +1,8 @@
29459 -+#ifndef __GRALLOC_H
29460 -+#define __GRALLOC_H
29461 -+
29462 -+void acl_free_all(void);
29463 -+int acl_alloc_stack_init(unsigned long size);
29464 -+void *acl_alloc(unsigned long len);
29465 -+
29466 -+#endif
29467 -diff -urNp linux-2.6.27.6/include/linux/grdefs.h linux-2.6.27.6/include/linux/grdefs.h
29468 ---- linux-2.6.27.6/include/linux/grdefs.h 1969-12-31 19:00:00.000000000 -0500
29469 -+++ linux-2.6.27.6/include/linux/grdefs.h 2008-11-18 03:38:45.000000000 -0500
29470 -@@ -0,0 +1,131 @@
29471 -+#ifndef GRDEFS_H
29472 -+#define GRDEFS_H
29473 -+
29474 -+/* Begin grsecurity status declarations */
29475 -+
29476 -+enum {
29477 -+ GR_READY = 0x01,
29478 -+ GR_STATUS_INIT = 0x00 // disabled state
29479 -+};
29480 -+
29481 -+/* Begin ACL declarations */
29482 -+
29483 -+/* Role flags */
29484 -+
29485 -+enum {
29486 -+ GR_ROLE_USER = 0x0001,
29487 -+ GR_ROLE_GROUP = 0x0002,
29488 -+ GR_ROLE_DEFAULT = 0x0004,
29489 -+ GR_ROLE_SPECIAL = 0x0008,
29490 -+ GR_ROLE_AUTH = 0x0010,
29491 -+ GR_ROLE_NOPW = 0x0020,
29492 -+ GR_ROLE_GOD = 0x0040,
29493 -+ GR_ROLE_LEARN = 0x0080,
29494 -+ GR_ROLE_TPE = 0x0100,
29495 -+ GR_ROLE_DOMAIN = 0x0200,
29496 -+ GR_ROLE_PAM = 0x0400
29497 -+};
29498 -+
29499 -+/* ACL Subject and Object mode flags */
29500 -+enum {
29501 -+ GR_DELETED = 0x80000000
29502 -+};
29503 -+
29504 -+/* ACL Object-only mode flags */
29505 -+enum {
29506 -+ GR_READ = 0x00000001,
29507 -+ GR_APPEND = 0x00000002,
29508 -+ GR_WRITE = 0x00000004,
29509 -+ GR_EXEC = 0x00000008,
29510 -+ GR_FIND = 0x00000010,
29511 -+ GR_INHERIT = 0x00000020,
29512 -+ GR_SETID = 0x00000040,
29513 -+ GR_CREATE = 0x00000080,
29514 -+ GR_DELETE = 0x00000100,
29515 -+ GR_LINK = 0x00000200,
29516 -+ GR_AUDIT_READ = 0x00000400,
29517 -+ GR_AUDIT_APPEND = 0x00000800,
29518 -+ GR_AUDIT_WRITE = 0x00001000,
29519 -+ GR_AUDIT_EXEC = 0x00002000,
29520 -+ GR_AUDIT_FIND = 0x00004000,
29521 -+ GR_AUDIT_INHERIT= 0x00008000,
29522 -+ GR_AUDIT_SETID = 0x00010000,
29523 -+ GR_AUDIT_CREATE = 0x00020000,
29524 -+ GR_AUDIT_DELETE = 0x00040000,
29525 -+ GR_AUDIT_LINK = 0x00080000,
29526 -+ GR_PTRACERD = 0x00100000,
29527 -+ GR_NOPTRACE = 0x00200000,
29528 -+ GR_SUPPRESS = 0x00400000,
29529 -+ GR_NOLEARN = 0x00800000
29530 -+};
29531 -+
29532 -+#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
29533 -+ GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
29534 -+ GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
29535 -+
29536 -+/* ACL subject-only mode flags */
29537 -+enum {
29538 -+ GR_KILL = 0x00000001,
29539 -+ GR_VIEW = 0x00000002,
29540 -+ GR_PROTECTED = 0x00000004,
29541 -+ GR_LEARN = 0x00000008,
29542 -+ GR_OVERRIDE = 0x00000010,
29543 -+ /* just a placeholder, this mode is only used in userspace */
29544 -+ GR_DUMMY = 0x00000020,
29545 -+ GR_PROTSHM = 0x00000040,
29546 -+ GR_KILLPROC = 0x00000080,
29547 -+ GR_KILLIPPROC = 0x00000100,
29548 -+ /* just a placeholder, this mode is only used in userspace */
29549 -+ GR_NOTROJAN = 0x00000200,
29550 -+ GR_PROTPROCFD = 0x00000400,
29551 -+ GR_PROCACCT = 0x00000800,
29552 -+ GR_RELAXPTRACE = 0x00001000,
29553 -+ GR_NESTED = 0x00002000,
29554 -+ GR_INHERITLEARN = 0x00004000,
29555 -+ GR_PROCFIND = 0x00008000,
29556 -+ GR_POVERRIDE = 0x00010000,
29557 -+ GR_KERNELAUTH = 0x00020000,
29558 -+};
29559 -+
29560 -+enum {
29561 -+ GR_PAX_ENABLE_SEGMEXEC = 0x0001,
29562 -+ GR_PAX_ENABLE_PAGEEXEC = 0x0002,
29563 -+ GR_PAX_ENABLE_MPROTECT = 0x0004,
29564 -+ GR_PAX_ENABLE_RANDMMAP = 0x0008,
29565 -+ GR_PAX_ENABLE_EMUTRAMP = 0x0010,
29566 -+ GR_PAX_DISABLE_SEGMEXEC = 0x0100,
29567 -+ GR_PAX_DISABLE_PAGEEXEC = 0x0200,
29568 -+ GR_PAX_DISABLE_MPROTECT = 0x0400,
29569 -+ GR_PAX_DISABLE_RANDMMAP = 0x0800,
29570 -+ GR_PAX_DISABLE_EMUTRAMP = 0x1000,
29571 -+};
29572 -+
29573 -+enum {
29574 -+ GR_ID_USER = 0x01,
29575 -+ GR_ID_GROUP = 0x02,
29576 -+};
29577 -+
29578 -+enum {
29579 -+ GR_ID_ALLOW = 0x01,
29580 -+ GR_ID_DENY = 0x02,
29581 -+};
29582 -+
29583 -+#define GR_CRASH_RES 11
29584 -+#define GR_UIDTABLE_MAX 500
29585 -+
29586 -+/* begin resource learning section */
29587 -+enum {
29588 -+ GR_RLIM_CPU_BUMP = 60,
29589 -+ GR_RLIM_FSIZE_BUMP = 50000,
29590 -+ GR_RLIM_DATA_BUMP = 10000,
29591 -+ GR_RLIM_STACK_BUMP = 1000,
29592 -+ GR_RLIM_CORE_BUMP = 10000,
29593 -+ GR_RLIM_RSS_BUMP = 500000,
29594 -+ GR_RLIM_NPROC_BUMP = 1,
29595 -+ GR_RLIM_NOFILE_BUMP = 5,
29596 -+ GR_RLIM_MEMLOCK_BUMP = 50000,
29597 -+ GR_RLIM_AS_BUMP = 500000,
29598 -+ GR_RLIM_LOCKS_BUMP = 2
29599 -+};
29600 -+
29601 -+#endif
29602 -diff -urNp linux-2.6.27.6/include/linux/grinternal.h linux-2.6.27.6/include/linux/grinternal.h
29603 ---- linux-2.6.27.6/include/linux/grinternal.h 1969-12-31 19:00:00.000000000 -0500
29604 -+++ linux-2.6.27.6/include/linux/grinternal.h 2008-11-18 03:38:45.000000000 -0500
29605 -@@ -0,0 +1,210 @@
29606 -+#ifndef __GRINTERNAL_H
29607 -+#define __GRINTERNAL_H
29608 -+
29609 -+#ifdef CONFIG_GRKERNSEC
29610 -+
29611 -+#include <linux/fs.h>
29612 -+#include <linux/gracl.h>
29613 -+#include <linux/grdefs.h>
29614 -+#include <linux/grmsg.h>
29615 -+
29616 -+void gr_add_learn_entry(const char *fmt, ...);
29617 -+__u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
29618 -+ const struct vfsmount *mnt);
29619 -+__u32 gr_check_create(const struct dentry *new_dentry,
29620 -+ const struct dentry *parent,
29621 -+ const struct vfsmount *mnt, const __u32 mode);
29622 -+int gr_check_protected_task(const struct task_struct *task);
29623 -+__u32 to_gr_audit(const __u32 reqmode);
29624 -+int gr_set_acls(const int type);
29625 -+
29626 -+int gr_acl_is_enabled(void);
29627 -+char gr_roletype_to_char(void);
29628 -+
29629 -+void gr_handle_alertkill(struct task_struct *task);
29630 -+char *gr_to_filename(const struct dentry *dentry,
29631 -+ const struct vfsmount *mnt);
29632 -+char *gr_to_filename1(const struct dentry *dentry,
29633 -+ const struct vfsmount *mnt);
29634 -+char *gr_to_filename2(const struct dentry *dentry,
29635 -+ const struct vfsmount *mnt);
29636 -+char *gr_to_filename3(const struct dentry *dentry,
29637 -+ const struct vfsmount *mnt);
29638 -+
29639 -+extern int grsec_enable_link;
29640 -+extern int grsec_enable_fifo;
29641 -+extern int grsec_enable_execve;
29642 -+extern int grsec_enable_shm;
29643 -+extern int grsec_enable_execlog;
29644 -+extern int grsec_enable_signal;
29645 -+extern int grsec_enable_forkfail;
29646 -+extern int grsec_enable_time;
29647 -+extern int grsec_enable_chroot_shmat;
29648 -+extern int grsec_enable_chroot_findtask;
29649 -+extern int grsec_enable_chroot_mount;
29650 -+extern int grsec_enable_chroot_double;
29651 -+extern int grsec_enable_chroot_pivot;
29652 -+extern int grsec_enable_chroot_chdir;
29653 -+extern int grsec_enable_chroot_chmod;
29654 -+extern int grsec_enable_chroot_mknod;
29655 -+extern int grsec_enable_chroot_fchdir;
29656 -+extern int grsec_enable_chroot_nice;
29657 -+extern int grsec_enable_chroot_execlog;
29658 -+extern int grsec_enable_chroot_caps;
29659 -+extern int grsec_enable_chroot_sysctl;
29660 -+extern int grsec_enable_chroot_unix;
29661 -+extern int grsec_enable_tpe;
29662 -+extern int grsec_tpe_gid;
29663 -+extern int grsec_enable_tpe_all;
29664 -+extern int grsec_enable_sidcaps;
29665 -+extern int grsec_enable_socket_all;
29666 -+extern int grsec_socket_all_gid;
29667 -+extern int grsec_enable_socket_client;
29668 -+extern int grsec_socket_client_gid;
29669 -+extern int grsec_enable_socket_server;
29670 -+extern int grsec_socket_server_gid;
29671 -+extern int grsec_audit_gid;
29672 -+extern int grsec_enable_group;
29673 -+extern int grsec_enable_audit_ipc;
29674 -+extern int grsec_enable_audit_textrel;
29675 -+extern int grsec_enable_mount;
29676 -+extern int grsec_enable_chdir;
29677 -+extern int grsec_resource_logging;
29678 -+extern int grsec_lock;
29679 -+
29680 -+extern spinlock_t grsec_alert_lock;
29681 -+extern unsigned long grsec_alert_wtime;
29682 -+extern unsigned long grsec_alert_fyet;
29683 -+
29684 -+extern spinlock_t grsec_audit_lock;
29685 -+
29686 -+extern rwlock_t grsec_exec_file_lock;
29687 -+
29688 -+#define gr_task_fullpath(tsk) (tsk->exec_file ? \
29689 -+ gr_to_filename2(tsk->exec_file->f_path.dentry, \
29690 -+ tsk->exec_file->f_vfsmnt) : "/")
29691 -+
29692 -+#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
29693 -+ gr_to_filename3(tsk->parent->exec_file->f_path.dentry, \
29694 -+ tsk->parent->exec_file->f_vfsmnt) : "/")
29695 -+
29696 -+#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
29697 -+ gr_to_filename(tsk->exec_file->f_path.dentry, \
29698 -+ tsk->exec_file->f_vfsmnt) : "/")
29699 -+
29700 -+#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
29701 -+ gr_to_filename1(tsk->parent->exec_file->f_path.dentry, \
29702 -+ tsk->parent->exec_file->f_vfsmnt) : "/")
29703 -+
29704 -+#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
29705 -+ ((tsk_a->fs->root.dentry->d_inode->i_sb->s_dev != \
29706 -+ tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_sb->s_dev) || \
29707 -+ (tsk_a->fs->root.dentry->d_inode->i_ino != \
29708 -+ tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_ino)))
29709 -+
29710 -+#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
29711 -+ (tsk_a->fs->root.dentry->d_inode->i_sb->s_dev == \
29712 -+ tsk_b->fs->root.dentry->d_inode->i_sb->s_dev) && \
29713 -+ (tsk_a->fs->root.dentry->d_inode->i_ino == \
29714 -+ tsk_b->fs->root.dentry->d_inode->i_ino))
29715 -+
29716 -+#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
29717 -+ task->pid, task->uid, \
29718 -+ task->euid, task->gid, task->egid, \
29719 -+ gr_parent_task_fullpath(task), \
29720 -+ task->parent->comm, task->parent->pid, \
29721 -+ task->parent->uid, task->parent->euid, \
29722 -+ task->parent->gid, task->parent->egid
29723 -+
29724 -+#define GR_CHROOT_CAPS {{ \
29725 -+ CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
29726 -+ CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
29727 -+ CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
29728 -+ CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
29729 -+ CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
29730 -+ CAP_TO_MASK(CAP_IPC_OWNER) , 0 }}
29731 -+
29732 -+#define security_learn(normal_msg,args...) \
29733 -+({ \
29734 -+ read_lock(&grsec_exec_file_lock); \
29735 -+ gr_add_learn_entry(normal_msg "\n", ## args); \
29736 -+ read_unlock(&grsec_exec_file_lock); \
29737 -+})
29738 -+
29739 -+enum {
29740 -+ GR_DO_AUDIT,
29741 -+ GR_DONT_AUDIT,
29742 -+ GR_DONT_AUDIT_GOOD
29743 -+};
29744 -+
29745 -+enum {
29746 -+ GR_TTYSNIFF,
29747 -+ GR_RBAC,
29748 -+ GR_RBAC_STR,
29749 -+ GR_STR_RBAC,
29750 -+ GR_RBAC_MODE2,
29751 -+ GR_RBAC_MODE3,
29752 -+ GR_FILENAME,
29753 -+ GR_SYSCTL_HIDDEN,
29754 -+ GR_NOARGS,
29755 -+ GR_ONE_INT,
29756 -+ GR_ONE_INT_TWO_STR,
29757 -+ GR_ONE_STR,
29758 -+ GR_STR_INT,
29759 -+ GR_TWO_INT,
29760 -+ GR_THREE_INT,
29761 -+ GR_FIVE_INT_TWO_STR,
29762 -+ GR_TWO_STR,
29763 -+ GR_THREE_STR,
29764 -+ GR_FOUR_STR,
29765 -+ GR_STR_FILENAME,
29766 -+ GR_FILENAME_STR,
29767 -+ GR_FILENAME_TWO_INT,
29768 -+ GR_FILENAME_TWO_INT_STR,
29769 -+ GR_TEXTREL,
29770 -+ GR_PTRACE,
29771 -+ GR_RESOURCE,
29772 -+ GR_CAP,
29773 -+ GR_SIG,
29774 -+ GR_CRASH1,
29775 -+ GR_CRASH2,
29776 -+ GR_PSACCT
29777 -+};
29778 -+
29779 -+#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str)
29780 -+#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
29781 -+#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
29782 -+#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
29783 -+#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
29784 -+#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
29785 -+#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)
29786 -+#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
29787 -+#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
29788 -+#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
29789 -+#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
29790 -+#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
29791 -+#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
29792 -+#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
29793 -+#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
29794 -+#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)
29795 -+#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
29796 -+#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
29797 -+#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
29798 -+#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
29799 -+#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
29800 -+#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
29801 -+#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)
29802 -+#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
29803 -+#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
29804 -+#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
29805 -+#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
29806 -+#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
29807 -+#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
29808 -+#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
29809 -+#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)
29810 -+
29811 -+void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
29812 -+
29813 -+#endif
29814 -+
29815 -+#endif
29816 -diff -urNp linux-2.6.27.6/include/linux/grmsg.h linux-2.6.27.6/include/linux/grmsg.h
29817 ---- linux-2.6.27.6/include/linux/grmsg.h 1969-12-31 19:00:00.000000000 -0500
29818 -+++ linux-2.6.27.6/include/linux/grmsg.h 2008-11-18 03:38:45.000000000 -0500
29819 -@@ -0,0 +1,108 @@
29820 -+#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"
29821 -+#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"
29822 -+#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
29823 -+#define GR_STOPMOD_MSG "denied modification of module state by "
29824 -+#define GR_IOPERM_MSG "denied use of ioperm() by "
29825 -+#define GR_IOPL_MSG "denied use of iopl() by "
29826 -+#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
29827 -+#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
29828 -+#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
29829 -+#define GR_KMEM_MSG "denied write of /dev/kmem by "
29830 -+#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
29831 -+#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
29832 -+#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
29833 -+#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
29834 -+#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"
29835 -+#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"
29836 -+#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
29837 -+#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
29838 -+#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
29839 -+#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
29840 -+#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
29841 -+#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
29842 -+#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
29843 -+#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
29844 -+#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
29845 -+#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
29846 -+#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
29847 -+#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
29848 -+#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
29849 -+#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
29850 -+#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
29851 -+#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
29852 -+#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
29853 -+#define GR_NPROC_MSG "denied overstep of process limit by "
29854 -+#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
29855 -+#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
29856 -+#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
29857 -+#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
29858 -+#define GR_MOUNT_CHROOT_MSG "denied mount of %.256s as %.930s from chroot by "
29859 -+#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
29860 -+#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
29861 -+#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
29862 -+#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
29863 -+#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
29864 -+#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
29865 -+#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
29866 -+#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
29867 -+#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
29868 -+#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
29869 -+#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
29870 -+#define GR_INITF_ACL_MSG "init_variables() failed %s by "
29871 -+#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"
29872 -+#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
29873 -+#define GR_SHUTS_ACL_MSG "shutdown auth success for "
29874 -+#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
29875 -+#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
29876 -+#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
29877 -+#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
29878 -+#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
29879 -+#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
29880 -+#define GR_ENABLEF_ACL_MSG "unable to load %s for "
29881 -+#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
29882 -+#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
29883 -+#define GR_RELOADF_ACL_MSG "failed reload of %s for "
29884 -+#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
29885 -+#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
29886 -+#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
29887 -+#define GR_SPROLEF_ACL_MSG "special role %s failure for "
29888 -+#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
29889 -+#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
29890 -+#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
29891 -+#define GR_INVMODE_ACL_MSG "invalid mode %d by "
29892 -+#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
29893 -+#define GR_FAILFORK_MSG "failed fork with errno %d by "
29894 -+#define GR_NICE_CHROOT_MSG "denied priority change by "
29895 -+#define GR_UNISIGLOG_MSG "signal %d sent to "
29896 -+#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
29897 -+#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
29898 -+#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
29899 -+#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
29900 -+#define GR_TIME_MSG "time set by "
29901 -+#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
29902 -+#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
29903 -+#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
29904 -+#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
29905 -+#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
29906 -+#define GR_BIND_MSG "denied bind() by "
29907 -+#define GR_CONNECT_MSG "denied connect() by "
29908 -+#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
29909 -+#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
29910 -+#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"
29911 -+#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
29912 -+#define GR_CAP_ACL_MSG "use of %s denied for "
29913 -+#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
29914 -+#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
29915 -+#define GR_REMOUNT_AUDIT_MSG "remount of %.256s by "
29916 -+#define GR_UNMOUNT_AUDIT_MSG "unmount of %.256s by "
29917 -+#define GR_MOUNT_AUDIT_MSG "mount of %.256s to %.256s by "
29918 -+#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
29919 -+#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
29920 -+#define GR_MSGQ_AUDIT_MSG "message queue created by "
29921 -+#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
29922 -+#define GR_SEM_AUDIT_MSG "semaphore created by "
29923 -+#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
29924 -+#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
29925 -+#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
29926 -+#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
29927 -+#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
29928 -diff -urNp linux-2.6.27.6/include/linux/grsecurity.h linux-2.6.27.6/include/linux/grsecurity.h
29929 ---- linux-2.6.27.6/include/linux/grsecurity.h 1969-12-31 19:00:00.000000000 -0500
29930 -+++ linux-2.6.27.6/include/linux/grsecurity.h 2008-11-18 03:38:45.000000000 -0500
29931 -@@ -0,0 +1,200 @@
29932 -+#ifndef GR_SECURITY_H
29933 -+#define GR_SECURITY_H
29934 -+#include <linux/fs.h>
29935 -+#include <linux/binfmts.h>
29936 -+#include <linux/gracl.h>
29937 -+
29938 -+/* notify of brain-dead configs */
29939 -+#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC)
29940 -+#error "CONFIG_PAX_NOEXEC enabled, but PAGEEXEC, SEGMEXEC, and KERNEXEC are disabled."
29941 -+#endif
29942 -+#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
29943 -+#error "CONFIG_PAX_NOEXEC enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
29944 -+#endif
29945 -+#if defined(CONFIG_PAX_ASLR) && (defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
29946 -+#error "CONFIG_PAX_ASLR enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
29947 -+#endif
29948 -+#if defined(CONFIG_PAX_ASLR) && !defined(CONFIG_PAX_RANDKSTACK) && !defined(CONFIG_PAX_RANDUSTACK) && !defined(CONFIG_PAX_RANDMMAP)
29949 -+#error "CONFIG_PAX_ASLR enabled, but RANDKSTACK, RANDUSTACK, and RANDMMAP are disabled."
29950 -+#endif
29951 -+#if defined(CONFIG_PAX) && !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_ASLR)
29952 -+#error "CONFIG_PAX enabled, but no PaX options are enabled."
29953 -+#endif
29954 -+
29955 -+void gr_handle_brute_attach(struct task_struct *p);
29956 -+void gr_handle_brute_check(void);
29957 -+
29958 -+char gr_roletype_to_char(void);
29959 -+
29960 -+int gr_check_user_change(int real, int effective, int fs);
29961 -+int gr_check_group_change(int real, int effective, int fs);
29962 -+
29963 -+void gr_del_task_from_ip_table(struct task_struct *p);
29964 -+
29965 -+int gr_pid_is_chrooted(struct task_struct *p);
29966 -+int gr_handle_chroot_nice(void);
29967 -+int gr_handle_chroot_sysctl(const int op);
29968 -+int gr_handle_chroot_setpriority(struct task_struct *p,
29969 -+ const int niceval);
29970 -+int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
29971 -+int gr_handle_chroot_chroot(const struct dentry *dentry,
29972 -+ const struct vfsmount *mnt);
29973 -+void gr_handle_chroot_caps(struct task_struct *task);
29974 -+void gr_handle_chroot_chdir(struct path *path);
29975 -+int gr_handle_chroot_chmod(const struct dentry *dentry,
29976 -+ const struct vfsmount *mnt, const int mode);
29977 -+int gr_handle_chroot_mknod(const struct dentry *dentry,
29978 -+ const struct vfsmount *mnt, const int mode);
29979 -+int gr_handle_chroot_mount(const struct dentry *dentry,
29980 -+ const struct vfsmount *mnt,
29981 -+ const char *dev_name);
29982 -+int gr_handle_chroot_pivot(void);
29983 -+int gr_handle_chroot_unix(const pid_t pid);
29984 -+
29985 -+int gr_handle_rawio(const struct inode *inode);
29986 -+int gr_handle_nproc(void);
29987 -+
29988 -+void gr_handle_ioperm(void);
29989 -+void gr_handle_iopl(void);
29990 -+
29991 -+int gr_tpe_allow(const struct file *file);
29992 -+
29993 -+int gr_random_pid(void);
29994 -+
29995 -+void gr_log_forkfail(const int retval);
29996 -+void gr_log_timechange(void);
29997 -+void gr_log_signal(const int sig, const struct task_struct *t);
29998 -+void gr_log_chdir(const struct dentry *dentry,
29999 -+ const struct vfsmount *mnt);
30000 -+void gr_log_chroot_exec(const struct dentry *dentry,
30001 -+ const struct vfsmount *mnt);
30002 -+void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
30003 -+void gr_log_remount(const char *devname, const int retval);
30004 -+void gr_log_unmount(const char *devname, const int retval);
30005 -+void gr_log_mount(const char *from, const char *to, const int retval);
30006 -+void gr_log_msgget(const int ret, const int msgflg);
30007 -+void gr_log_msgrm(const uid_t uid, const uid_t cuid);
30008 -+void gr_log_semget(const int err, const int semflg);
30009 -+void gr_log_semrm(const uid_t uid, const uid_t cuid);
30010 -+void gr_log_shmget(const int err, const int shmflg, const size_t size);
30011 -+void gr_log_shmrm(const uid_t uid, const uid_t cuid);
30012 -+void gr_log_textrel(struct vm_area_struct *vma);
30013 -+
30014 -+int gr_handle_follow_link(const struct inode *parent,
30015 -+ const struct inode *inode,
30016 -+ const struct dentry *dentry,
30017 -+ const struct vfsmount *mnt);
30018 -+int gr_handle_fifo(const struct dentry *dentry,
30019 -+ const struct vfsmount *mnt,
30020 -+ const struct dentry *dir, const int flag,
30021 -+ const int acc_mode);
30022 -+int gr_handle_hardlink(const struct dentry *dentry,
30023 -+ const struct vfsmount *mnt,
30024 -+ struct inode *inode,
30025 -+ const int mode, const char *to);
30026 -+
30027 -+int gr_task_is_capable(struct task_struct *task, const int cap);
30028 -+int gr_is_capable_nolog(const int cap);
30029 -+void gr_learn_resource(const struct task_struct *task, const int limit,
30030 -+ const unsigned long wanted, const int gt);
30031 -+void gr_copy_label(struct task_struct *tsk);
30032 -+void gr_handle_crash(struct task_struct *task, const int sig);
30033 -+int gr_handle_signal(const struct task_struct *p, const int sig);
30034 -+int gr_check_crash_uid(const uid_t uid);
30035 -+int gr_check_protected_task(const struct task_struct *task);
30036 -+int gr_acl_handle_mmap(const struct file *file,
30037 -+ const unsigned long prot);
30038 -+int gr_acl_handle_mprotect(const struct file *file,
30039 -+ const unsigned long prot);
30040 -+int gr_check_hidden_task(const struct task_struct *tsk);
30041 -+__u32 gr_acl_handle_truncate(const struct dentry *dentry,
30042 -+ const struct vfsmount *mnt);
30043 -+__u32 gr_acl_handle_utime(const struct dentry *dentry,
30044 -+ const struct vfsmount *mnt);
30045 -+__u32 gr_acl_handle_access(const struct dentry *dentry,
30046 -+ const struct vfsmount *mnt, const int fmode);
30047 -+__u32 gr_acl_handle_fchmod(const struct dentry *dentry,
30048 -+ const struct vfsmount *mnt, mode_t mode);
30049 -+__u32 gr_acl_handle_chmod(const struct dentry *dentry,
30050 -+ const struct vfsmount *mnt, mode_t mode);
30051 -+__u32 gr_acl_handle_chown(const struct dentry *dentry,
30052 -+ const struct vfsmount *mnt);
30053 -+int gr_handle_ptrace(struct task_struct *task, const long request);
30054 -+int gr_handle_proc_ptrace(struct task_struct *task);
30055 -+__u32 gr_acl_handle_execve(const struct dentry *dentry,
30056 -+ const struct vfsmount *mnt);
30057 -+int gr_check_crash_exec(const struct file *filp);
30058 -+int gr_acl_is_enabled(void);
30059 -+void gr_set_kernel_label(struct task_struct *task);
30060 -+void gr_set_role_label(struct task_struct *task, const uid_t uid,
30061 -+ const gid_t gid);
30062 -+int gr_set_proc_label(const struct dentry *dentry,
30063 -+ const struct vfsmount *mnt);
30064 -+__u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
30065 -+ const struct vfsmount *mnt);
30066 -+__u32 gr_acl_handle_open(const struct dentry *dentry,
30067 -+ const struct vfsmount *mnt, const int fmode);
30068 -+__u32 gr_acl_handle_creat(const struct dentry *dentry,
30069 -+ const struct dentry *p_dentry,
30070 -+ const struct vfsmount *p_mnt, const int fmode,
30071 -+ const int imode);
30072 -+void gr_handle_create(const struct dentry *dentry,
30073 -+ const struct vfsmount *mnt);
30074 -+__u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
30075 -+ const struct dentry *parent_dentry,
30076 -+ const struct vfsmount *parent_mnt,
30077 -+ const int mode);
30078 -+__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
30079 -+ const struct dentry *parent_dentry,
30080 -+ const struct vfsmount *parent_mnt);
30081 -+__u32 gr_acl_handle_rmdir(const struct dentry *dentry,
30082 -+ const struct vfsmount *mnt);
30083 -+void gr_handle_delete(const ino_t ino, const dev_t dev);
30084 -+__u32 gr_acl_handle_unlink(const struct dentry *dentry,
30085 -+ const struct vfsmount *mnt);
30086 -+__u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
30087 -+ const struct dentry *parent_dentry,
30088 -+ const struct vfsmount *parent_mnt,
30089 -+ const char *from);
30090 -+__u32 gr_acl_handle_link(const struct dentry *new_dentry,
30091 -+ const struct dentry *parent_dentry,
30092 -+ const struct vfsmount *parent_mnt,
30093 -+ const struct dentry *old_dentry,
30094 -+ const struct vfsmount *old_mnt, const char *to);
30095 -+int gr_acl_handle_rename(struct dentry *new_dentry,
30096 -+ struct dentry *parent_dentry,
30097 -+ const struct vfsmount *parent_mnt,
30098 -+ struct dentry *old_dentry,
30099 -+ struct inode *old_parent_inode,
30100 -+ struct vfsmount *old_mnt, const char *newname);
30101 -+void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
30102 -+ struct dentry *old_dentry,
30103 -+ struct dentry *new_dentry,
30104 -+ struct vfsmount *mnt, const __u8 replace);
30105 -+__u32 gr_check_link(const struct dentry *new_dentry,
30106 -+ const struct dentry *parent_dentry,
30107 -+ const struct vfsmount *parent_mnt,
30108 -+ const struct dentry *old_dentry,
30109 -+ const struct vfsmount *old_mnt);
30110 -+int gr_acl_handle_filldir(const struct file *file, const char *name,
30111 -+ const unsigned int namelen, const ino_t ino);
30112 -+
30113 -+__u32 gr_acl_handle_unix(const struct dentry *dentry,
30114 -+ const struct vfsmount *mnt);
30115 -+void gr_acl_handle_exit(void);
30116 -+void gr_acl_handle_psacct(struct task_struct *task, const long code);
30117 -+int gr_acl_handle_procpidmem(const struct task_struct *task);
30118 -+
30119 -+#ifdef CONFIG_GRKERNSEC
30120 -+void gr_handle_mem_write(void);
30121 -+void gr_handle_kmem_write(void);
30122 -+void gr_handle_open_port(void);
30123 -+int gr_handle_mem_mmap(const unsigned long offset,
30124 -+ struct vm_area_struct *vma);
30125 -+
30126 -+extern int grsec_enable_dmesg;
30127 -+extern int grsec_enable_randsrc;
30128 -+extern int grsec_enable_shm;
30129 -+#endif
30130 -+
30131 -+#endif
30132 -diff -urNp linux-2.6.27.6/include/linux/highmem.h linux-2.6.27.6/include/linux/highmem.h
30133 ---- linux-2.6.27.6/include/linux/highmem.h 2008-11-07 12:55:34.000000000 -0500
30134 -+++ linux-2.6.27.6/include/linux/highmem.h 2008-11-18 03:38:45.000000000 -0500
30135 -@@ -122,6 +122,13 @@ static inline void clear_highpage(struct
30136 - kunmap_atomic(kaddr, KM_USER0);
30137 - }
30138 -
30139 -+static inline void sanitize_highpage(struct page *page)
30140 -+{
30141 -+ void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
30142 -+ clear_page(kaddr);
30143 -+ kunmap_atomic(kaddr, KM_CLEARPAGE);
30144 -+}
30145 -+
30146 - static inline void zero_user_segments(struct page *page,
30147 - unsigned start1, unsigned end1,
30148 - unsigned start2, unsigned end2)
30149 -diff -urNp linux-2.6.27.6/include/linux/jbd2.h linux-2.6.27.6/include/linux/jbd2.h
30150 ---- linux-2.6.27.6/include/linux/jbd2.h 2008-11-07 12:55:34.000000000 -0500
30151 -+++ linux-2.6.27.6/include/linux/jbd2.h 2008-11-18 03:38:45.000000000 -0500
30152 -@@ -66,7 +66,7 @@ extern u8 jbd2_journal_enable_debug;
30153 - } \
30154 - } while (0)
30155 - #else
30156 --#define jbd_debug(f, a...) /**/
30157 -+#define jbd_debug(f, a...) do {} while (0)
30158 - #endif
30159 -
30160 - static inline void *jbd2_alloc(size_t size, gfp_t flags)
30161 -diff -urNp linux-2.6.27.6/include/linux/jbd.h linux-2.6.27.6/include/linux/jbd.h
30162 ---- linux-2.6.27.6/include/linux/jbd.h 2008-11-07 12:55:34.000000000 -0500
30163 -+++ linux-2.6.27.6/include/linux/jbd.h 2008-11-18 03:38:45.000000000 -0500
30164 -@@ -66,7 +66,7 @@ extern u8 journal_enable_debug;
30165 - } \
30166 - } while (0)
30167 - #else
30168 --#define jbd_debug(f, a...) /**/
30169 -+#define jbd_debug(f, a...) do {} while (0)
30170 - #endif
30171 -
30172 - static inline void *jbd_alloc(size_t size, gfp_t flags)
30173 -diff -urNp linux-2.6.27.6/include/linux/libata.h linux-2.6.27.6/include/linux/libata.h
30174 ---- linux-2.6.27.6/include/linux/libata.h 2008-11-07 12:55:34.000000000 -0500
30175 -+++ linux-2.6.27.6/include/linux/libata.h 2008-11-18 03:38:45.000000000 -0500
30176 -@@ -64,11 +64,11 @@
30177 - #ifdef ATA_VERBOSE_DEBUG
30178 - #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args)
30179 - #else
30180 --#define VPRINTK(fmt, args...)
30181 -+#define VPRINTK(fmt, args...) do {} while (0)
30182 - #endif /* ATA_VERBOSE_DEBUG */
30183 - #else
30184 --#define DPRINTK(fmt, args...)
30185 --#define VPRINTK(fmt, args...)
30186 -+#define DPRINTK(fmt, args...) do {} while (0)
30187 -+#define VPRINTK(fmt, args...) do {} while (0)
30188 - #endif /* ATA_DEBUG */
30189 -
30190 - #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __func__, ## args)
30191 -diff -urNp linux-2.6.27.6/include/linux/mm.h linux-2.6.27.6/include/linux/mm.h
30192 ---- linux-2.6.27.6/include/linux/mm.h 2008-11-07 12:55:34.000000000 -0500
30193 -+++ linux-2.6.27.6/include/linux/mm.h 2008-11-18 03:38:45.000000000 -0500
30194 -@@ -38,6 +38,7 @@ extern unsigned long mmap_min_addr;
30195 - #include <asm/page.h>
30196 - #include <asm/pgtable.h>
30197 - #include <asm/processor.h>
30198 -+#include <asm/mman.h>
30199 -
30200 - #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
30201 -
30202 -@@ -114,6 +115,14 @@ extern unsigned int kobjsize(const void
30203 - #define VM_MIXEDMAP 0x10000000 /* Can contain "struct page" and pure PFN pages */
30204 - #define VM_SAO 0x20000000 /* Strong Access Ordering (powerpc) */
30205 -
30206 -+#ifdef CONFIG_PAX_PAGEEXEC
30207 -+#define VM_PAGEEXEC 0x40000000 /* vma->vm_page_prot needs special handling */
30208 -+#endif
30209 -+
30210 -+#ifdef CONFIG_PAX_MPROTECT
30211 -+#define VM_MAYNOTWRITE 0x80000000 /* vma cannot be granted VM_WRITE any more */
30212 -+#endif
30213 -+
30214 - #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
30215 - #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
30216 - #endif
30217 -@@ -874,6 +883,8 @@ struct shrinker {
30218 - extern void register_shrinker(struct shrinker *);
30219 - extern void unregister_shrinker(struct shrinker *);
30220 -
30221 -+pgprot_t vm_get_page_prot(unsigned long vm_flags);
30222 -+
30223 - int vma_wants_writenotify(struct vm_area_struct *vma);
30224 -
30225 - extern pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl);
30226 -@@ -1129,6 +1140,7 @@ out:
30227 - }
30228 -
30229 - extern int do_munmap(struct mm_struct *, unsigned long, size_t);
30230 -+extern int __do_munmap(struct mm_struct *, unsigned long, size_t);
30231 -
30232 - extern unsigned long do_brk(unsigned long, unsigned long);
30233 -
30234 -@@ -1181,6 +1193,10 @@ extern struct vm_area_struct * find_vma(
30235 - extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
30236 - struct vm_area_struct **pprev);
30237 -
30238 -+extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma);
30239 -+extern void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma);
30240 -+extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl);
30241 -+
30242 - /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
30243 - NULL if none. Assume start_addr < end_addr. */
30244 - static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
30245 -@@ -1197,7 +1213,6 @@ static inline unsigned long vma_pages(st
30246 - return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
30247 - }
30248 -
30249 --pgprot_t vm_get_page_prot(unsigned long vm_flags);
30250 - struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
30251 - int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
30252 - unsigned long pfn, unsigned long size, pgprot_t);
30253 -@@ -1286,5 +1301,11 @@ int vmemmap_populate_basepages(struct pa
30254 - int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
30255 - void vmemmap_populate_print_last(void);
30256 -
30257 -+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
30258 -+extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
30259 -+#else
30260 -+static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
30261 -+#endif
30262 -+
30263 - #endif /* __KERNEL__ */
30264 - #endif /* _LINUX_MM_H */
30265 -diff -urNp linux-2.6.27.6/include/linux/mm_types.h linux-2.6.27.6/include/linux/mm_types.h
30266 ---- linux-2.6.27.6/include/linux/mm_types.h 2008-11-07 12:55:34.000000000 -0500
30267 -+++ linux-2.6.27.6/include/linux/mm_types.h 2008-11-18 03:38:45.000000000 -0500
30268 -@@ -158,6 +158,8 @@ struct vm_area_struct {
30269 - #ifdef CONFIG_NUMA
30270 - struct mempolicy *vm_policy; /* NUMA policy for the VMA */
30271 - #endif
30272 -+
30273 -+ struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */
30274 - };
30275 -
30276 - struct core_thread {
30277 -@@ -257,6 +259,24 @@ struct mm_struct {
30278 - #ifdef CONFIG_MMU_NOTIFIER
30279 - struct mmu_notifier_mm *mmu_notifier_mm;
30280 - #endif
30281 -+
30282 -+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
30283 -+ unsigned long pax_flags;
30284 -+#endif
30285 -+
30286 -+#ifdef CONFIG_PAX_DLRESOLVE
30287 -+ unsigned long call_dl_resolve;
30288 -+#endif
30289 -+
30290 -+#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
30291 -+ unsigned long call_syscall;
30292 -+#endif
30293 -+
30294 -+#ifdef CONFIG_PAX_ASLR
30295 -+ unsigned long delta_mmap; /* randomized offset */
30296 -+ unsigned long delta_stack; /* randomized offset */
30297 -+#endif
30298 -+
30299 - };
30300 -
30301 - #endif /* _LINUX_MM_TYPES_H */
30302 -diff -urNp linux-2.6.27.6/include/linux/module.h linux-2.6.27.6/include/linux/module.h
30303 ---- linux-2.6.27.6/include/linux/module.h 2008-11-07 12:55:34.000000000 -0500
30304 -+++ linux-2.6.27.6/include/linux/module.h 2008-11-18 03:38:45.000000000 -0500
30305 -@@ -282,16 +282,16 @@ struct module
30306 - int (*init)(void);
30307 -
30308 - /* If this is non-NULL, vfree after init() returns */
30309 -- void *module_init;
30310 -+ void *module_init_rx, *module_init_rw;
30311 -
30312 - /* Here is the actual code + data, vfree'd on unload. */
30313 -- void *module_core;
30314 -+ void *module_core_rx, *module_core_rw;
30315 -
30316 - /* Here are the sizes of the init and core sections */
30317 -- unsigned int init_size, core_size;
30318 -+ unsigned int init_size_rw, core_size_rw;
30319 -
30320 - /* The size of the executable code in each section. */
30321 -- unsigned int init_text_size, core_text_size;
30322 -+ unsigned int init_size_rx, core_size_rx;
30323 -
30324 - /* The handle returned from unwind_add_table. */
30325 - void *unwind_info;
30326 -diff -urNp linux-2.6.27.6/include/linux/moduleloader.h linux-2.6.27.6/include/linux/moduleloader.h
30327 ---- linux-2.6.27.6/include/linux/moduleloader.h 2008-11-07 12:55:34.000000000 -0500
30328 -+++ linux-2.6.27.6/include/linux/moduleloader.h 2008-11-18 03:38:45.000000000 -0500
30329 -@@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
30330 - sections. Returns NULL on failure. */
30331 - void *module_alloc(unsigned long size);
30332 -
30333 -+#ifdef CONFIG_PAX_KERNEXEC
30334 -+void *module_alloc_exec(unsigned long size);
30335 -+#else
30336 -+#define module_alloc_exec(x) module_alloc(x)
30337 -+#endif
30338 -+
30339 - /* Free memory returned from module_alloc. */
30340 - void module_free(struct module *mod, void *module_region);
30341 -
30342 -+#ifdef CONFIG_PAX_KERNEXEC
30343 -+void module_free_exec(struct module *mod, void *module_region);
30344 -+#else
30345 -+#define module_free_exec(x, y) module_free(x, y)
30346 -+#endif
30347 -+
30348 - /* Apply the given relocation to the (simplified) ELF. Return -error
30349 - or 0. */
30350 - int apply_relocate(Elf_Shdr *sechdrs,
30351 -diff -urNp linux-2.6.27.6/include/linux/namei.h linux-2.6.27.6/include/linux/namei.h
30352 ---- linux-2.6.27.6/include/linux/namei.h 2008-11-07 12:55:34.000000000 -0500
30353 -+++ linux-2.6.27.6/include/linux/namei.h 2008-11-18 03:38:45.000000000 -0500
30354 -@@ -21,7 +21,7 @@ struct nameidata {
30355 - unsigned int flags;
30356 - int last_type;
30357 - unsigned depth;
30358 -- char *saved_names[MAX_NESTED_LINKS + 1];
30359 -+ const char *saved_names[MAX_NESTED_LINKS + 1];
30360 -
30361 - /* Intent data */
30362 - union {
30363 -@@ -80,12 +80,12 @@ extern int follow_up(struct vfsmount **,
30364 - extern struct dentry *lock_rename(struct dentry *, struct dentry *);
30365 - extern void unlock_rename(struct dentry *, struct dentry *);
30366 -
30367 --static inline void nd_set_link(struct nameidata *nd, char *path)
30368 -+static inline void nd_set_link(struct nameidata *nd, const char *path)
30369 - {
30370 - nd->saved_names[nd->depth] = path;
30371 - }
30372 -
30373 --static inline char *nd_get_link(struct nameidata *nd)
30374 -+static inline const char *nd_get_link(struct nameidata *nd)
30375 - {
30376 - return nd->saved_names[nd->depth];
30377 - }
30378 -diff -urNp linux-2.6.27.6/include/linux/nodemask.h linux-2.6.27.6/include/linux/nodemask.h
30379 ---- linux-2.6.27.6/include/linux/nodemask.h 2008-11-07 12:55:34.000000000 -0500
30380 -+++ linux-2.6.27.6/include/linux/nodemask.h 2008-11-18 03:38:45.000000000 -0500
30381 -@@ -442,11 +442,11 @@ static inline int num_node_state(enum no
30382 -
30383 - #define any_online_node(mask) \
30384 - ({ \
30385 -- int node; \
30386 -- for_each_node_mask(node, (mask)) \
30387 -- if (node_online(node)) \
30388 -+ int __node; \
30389 -+ for_each_node_mask(__node, (mask)) \
30390 -+ if (node_online(__node)) \
30391 - break; \
30392 -- node; \
30393 -+ __node; \
30394 - })
30395 -
30396 - #define num_online_nodes() num_node_state(N_ONLINE)
30397 -diff -urNp linux-2.6.27.6/include/linux/percpu.h linux-2.6.27.6/include/linux/percpu.h
30398 ---- linux-2.6.27.6/include/linux/percpu.h 2008-11-07 12:55:34.000000000 -0500
30399 -+++ linux-2.6.27.6/include/linux/percpu.h 2008-11-18 03:38:45.000000000 -0500
30400 -@@ -43,7 +43,7 @@
30401 - #endif
30402 -
30403 - #define PERCPU_ENOUGH_ROOM \
30404 -- (__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE)
30405 -+ ((unsigned long)(__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE))
30406 - #endif /* PERCPU_ENOUGH_ROOM */
30407 -
30408 - /*
30409 -diff -urNp linux-2.6.27.6/include/linux/poison.h linux-2.6.27.6/include/linux/poison.h
30410 ---- linux-2.6.27.6/include/linux/poison.h 2008-11-07 12:55:34.000000000 -0500
30411 -+++ linux-2.6.27.6/include/linux/poison.h 2008-11-18 03:38:45.000000000 -0500
30412 -@@ -7,8 +7,8 @@
30413 - * under normal circumstances, used to verify that nobody uses
30414 - * non-initialized list entries.
30415 - */
30416 --#define LIST_POISON1 ((void *) 0x00100100)
30417 --#define LIST_POISON2 ((void *) 0x00200200)
30418 -+#define LIST_POISON1 ((void *) 0xFF1001FFFF1001FFULL)
30419 -+#define LIST_POISON2 ((void *) 0xFF2002FFFF2002FFULL)
30420 -
30421 - /********** include/linux/timer.h **********/
30422 - /*
30423 -diff -urNp linux-2.6.27.6/include/linux/random.h linux-2.6.27.6/include/linux/random.h
30424 ---- linux-2.6.27.6/include/linux/random.h 2008-11-07 12:55:34.000000000 -0500
30425 -+++ linux-2.6.27.6/include/linux/random.h 2008-11-18 03:38:45.000000000 -0500
30426 -@@ -72,6 +72,11 @@ unsigned long randomize_range(unsigned l
30427 - u32 random32(void);
30428 - void srandom32(u32 seed);
30429 -
30430 -+static inline unsigned long pax_get_random_long(void)
30431 -+{
30432 -+ return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0);
30433 -+}
30434 -+
30435 - #endif /* __KERNEL___ */
30436 -
30437 - #endif /* _LINUX_RANDOM_H */
30438 -diff -urNp linux-2.6.27.6/include/linux/sched.h linux-2.6.27.6/include/linux/sched.h
30439 ---- linux-2.6.27.6/include/linux/sched.h 2008-11-07 12:55:34.000000000 -0500
30440 -+++ linux-2.6.27.6/include/linux/sched.h 2008-11-18 03:38:45.000000000 -0500
30441 -@@ -96,6 +96,7 @@ struct exec_domain;
30442 - struct futex_pi_state;
30443 - struct robust_list_head;
30444 - struct bio;
30445 -+struct linux_binprm;
30446 -
30447 - /*
30448 - * List of flags we want to share for kernel threads,
30449 -@@ -545,6 +546,15 @@ struct signal_struct {
30450 - unsigned audit_tty;
30451 - struct tty_audit_buf *tty_audit_buf;
30452 - #endif
30453 -+
30454 -+#ifdef CONFIG_GRKERNSEC
30455 -+ u32 curr_ip;
30456 -+ u32 gr_saddr;
30457 -+ u32 gr_daddr;
30458 -+ u16 gr_sport;
30459 -+ u16 gr_dport;
30460 -+ u8 used_accept:1;
30461 -+#endif
30462 - };
30463 -
30464 - /* Context switch must be unlocked if interrupts are to be enabled */
30465 -@@ -1026,7 +1036,7 @@ struct sched_rt_entity {
30466 -
30467 - struct task_struct {
30468 - volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
30469 -- void *stack;
30470 -+ struct thread_info *stack;
30471 - atomic_t usage;
30472 - unsigned int flags; /* per process flags, defined below */
30473 - unsigned int ptrace;
30474 -@@ -1091,10 +1101,9 @@ struct task_struct {
30475 - pid_t pid;
30476 - pid_t tgid;
30477 -
30478 --#ifdef CONFIG_CC_STACKPROTECTOR
30479 - /* Canary value for the -fstack-protector gcc feature */
30480 - unsigned long stack_canary;
30481 --#endif
30482 -+
30483 - /*
30484 - * pointers to (original) parent process, youngest child, younger sibling,
30485 - * older sibling, respectively. (p->father can be replaced with
30486 -@@ -1122,8 +1131,8 @@ struct task_struct {
30487 - struct list_head thread_group;
30488 -
30489 - struct completion *vfork_done; /* for vfork() */
30490 -- int __user *set_child_tid; /* CLONE_CHILD_SETTID */
30491 -- int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
30492 -+ pid_t __user *set_child_tid; /* CLONE_CHILD_SETTID */
30493 -+ pid_t __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
30494 -
30495 - cputime_t utime, stime, utimescaled, stimescaled;
30496 - cputime_t gtime;
30497 -@@ -1303,8 +1312,64 @@ struct task_struct {
30498 - int latency_record_count;
30499 - struct latency_record latency_record[LT_SAVECOUNT];
30500 - #endif
30501 -+
30502 -+#ifdef CONFIG_GRKERNSEC
30503 -+ /* grsecurity */
30504 -+ struct acl_subject_label *acl;
30505 -+ struct acl_role_label *role;
30506 -+ struct file *exec_file;
30507 -+ u16 acl_role_id;
30508 -+ u8 acl_sp_role;
30509 -+ u8 is_writable;
30510 -+ u8 brute;
30511 -+#endif
30512 -+
30513 - };
30514 -
30515 -+#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
30516 -+#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
30517 -+#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
30518 -+#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
30519 -+/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */
30520 -+#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
30521 -+
30522 -+#ifdef CONFIG_PAX_SOFTMODE
30523 -+extern unsigned int pax_softmode;
30524 -+#endif
30525 -+
30526 -+extern int pax_check_flags(unsigned long *);
30527 -+
30528 -+/* if tsk != current then task_lock must be held on it */
30529 -+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
30530 -+static inline unsigned long pax_get_flags(struct task_struct *tsk)
30531 -+{
30532 -+ if (likely(tsk->mm))
30533 -+ return tsk->mm->pax_flags;
30534 -+ else
30535 -+ return 0UL;
30536 -+}
30537 -+
30538 -+/* if tsk != current then task_lock must be held on it */
30539 -+static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
30540 -+{
30541 -+ if (likely(tsk->mm)) {
30542 -+ tsk->mm->pax_flags = flags;
30543 -+ return 0;
30544 -+ }
30545 -+ return -EINVAL;
30546 -+}
30547 -+#endif
30548 -+
30549 -+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
30550 -+extern void pax_set_initial_flags(struct linux_binprm *bprm);
30551 -+#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
30552 -+extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
30553 -+#endif
30554 -+
30555 -+void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
30556 -+void pax_report_insns(void *pc, void *sp);
30557 -+void pax_report_refcount_overflow(struct pt_regs *regs);
30558 -+
30559 - /*
30560 - * Priority of a process goes from 0..MAX_PRIO-1, valid RT
30561 - * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
30562 -@@ -1845,7 +1910,7 @@ extern void __cleanup_sighand(struct sig
30563 - extern void exit_itimers(struct signal_struct *);
30564 - extern void flush_itimer_signals(void);
30565 -
30566 --extern NORET_TYPE void do_group_exit(int);
30567 -+extern NORET_TYPE void do_group_exit(int) ATTRIB_NORET;
30568 -
30569 - extern void daemonize(const char *, ...);
30570 - extern int allow_signal(int);
30571 -@@ -1948,8 +2013,8 @@ static inline void unlock_task_sighand(s
30572 -
30573 - #ifndef __HAVE_THREAD_FUNCTIONS
30574 -
30575 --#define task_thread_info(task) ((struct thread_info *)(task)->stack)
30576 --#define task_stack_page(task) ((task)->stack)
30577 -+#define task_thread_info(task) ((task)->stack)
30578 -+#define task_stack_page(task) ((void *)(task)->stack)
30579 -
30580 - static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
30581 - {
30582 -diff -urNp linux-2.6.27.6/include/linux/screen_info.h linux-2.6.27.6/include/linux/screen_info.h
30583 ---- linux-2.6.27.6/include/linux/screen_info.h 2008-11-07 12:55:34.000000000 -0500
30584 -+++ linux-2.6.27.6/include/linux/screen_info.h 2008-11-18 03:38:45.000000000 -0500
30585 -@@ -42,7 +42,8 @@ struct screen_info {
30586 - __u16 pages; /* 0x32 */
30587 - __u16 vesa_attributes; /* 0x34 */
30588 - __u32 capabilities; /* 0x36 */
30589 -- __u8 _reserved[6]; /* 0x3a */
30590 -+ __u16 vesapm_size; /* 0x3a */
30591 -+ __u8 _reserved[4]; /* 0x3c */
30592 - } __attribute__((packed));
30593 -
30594 - #define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
30595 -diff -urNp linux-2.6.27.6/include/linux/shm.h linux-2.6.27.6/include/linux/shm.h
30596 ---- linux-2.6.27.6/include/linux/shm.h 2008-11-07 12:55:34.000000000 -0500
30597 -+++ linux-2.6.27.6/include/linux/shm.h 2008-11-18 03:38:45.000000000 -0500
30598 -@@ -95,6 +95,10 @@ struct shmid_kernel /* private to the ke
30599 - pid_t shm_cprid;
30600 - pid_t shm_lprid;
30601 - struct user_struct *mlock_user;
30602 -+#ifdef CONFIG_GRKERNSEC
30603 -+ time_t shm_createtime;
30604 -+ pid_t shm_lapid;
30605 -+#endif
30606 - };
30607 -
30608 - /* shm_mode upper byte flags */
30609 -diff -urNp linux-2.6.27.6/include/linux/slab.h linux-2.6.27.6/include/linux/slab.h
30610 ---- linux-2.6.27.6/include/linux/slab.h 2008-11-07 12:55:34.000000000 -0500
30611 -+++ linux-2.6.27.6/include/linux/slab.h 2008-11-18 03:38:45.000000000 -0500
30612 -@@ -45,10 +45,9 @@
30613 - * ZERO_SIZE_PTR can be passed to kfree though in the same way that NULL can.
30614 - * Both make kfree a no-op.
30615 - */
30616 --#define ZERO_SIZE_PTR ((void *)16)
30617 -+#define ZERO_SIZE_PTR ((void *)-1024L)
30618 -
30619 --#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= \
30620 -- (unsigned long)ZERO_SIZE_PTR)
30621 -+#define ZERO_OR_NULL_PTR(x) (!(x) || (x) == ZERO_SIZE_PTR)
30622 -
30623 - /*
30624 - * struct kmem_cache related prototypes
30625 -diff -urNp linux-2.6.27.6/include/linux/sysctl.h linux-2.6.27.6/include/linux/sysctl.h
30626 ---- linux-2.6.27.6/include/linux/sysctl.h 2008-11-07 12:55:34.000000000 -0500
30627 -+++ linux-2.6.27.6/include/linux/sysctl.h 2008-11-18 03:38:45.000000000 -0500
30628 -@@ -165,7 +165,11 @@ enum
30629 - KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
30630 - };
30631 -
30632 --
30633 -+#ifdef CONFIG_PAX_SOFTMODE
30634 -+enum {
30635 -+ PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */
30636 -+};
30637 -+#endif
30638 -
30639 - /* CTL_VM names: */
30640 - enum
30641 -diff -urNp linux-2.6.27.6/include/linux/thread_info.h linux-2.6.27.6/include/linux/thread_info.h
30642 ---- linux-2.6.27.6/include/linux/thread_info.h 2008-11-07 12:55:34.000000000 -0500
30643 -+++ linux-2.6.27.6/include/linux/thread_info.h 2008-11-18 03:38:45.000000000 -0500
30644 -@@ -23,7 +23,7 @@ struct restart_block {
30645 - };
30646 - /* For futex_wait */
30647 - struct {
30648 -- u32 *uaddr;
30649 -+ u32 __user *uaddr;
30650 - u32 val;
30651 - u32 flags;
30652 - u32 bitset;
30653 -diff -urNp linux-2.6.27.6/include/linux/uaccess.h linux-2.6.27.6/include/linux/uaccess.h
30654 ---- linux-2.6.27.6/include/linux/uaccess.h 2008-11-07 12:55:34.000000000 -0500
30655 -+++ linux-2.6.27.6/include/linux/uaccess.h 2008-11-18 03:38:45.000000000 -0500
30656 -@@ -76,11 +76,11 @@ static inline unsigned long __copy_from_
30657 - long ret; \
30658 - mm_segment_t old_fs = get_fs(); \
30659 - \
30660 -- set_fs(KERNEL_DS); \
30661 - pagefault_disable(); \
30662 -+ set_fs(KERNEL_DS); \
30663 - ret = __get_user(retval, (__force typeof(retval) __user *)(addr)); \
30664 -- pagefault_enable(); \
30665 - set_fs(old_fs); \
30666 -+ pagefault_enable(); \
30667 - ret; \
30668 - })
30669 -
30670 -diff -urNp linux-2.6.27.6/include/linux/vmalloc.h linux-2.6.27.6/include/linux/vmalloc.h
30671 ---- linux-2.6.27.6/include/linux/vmalloc.h 2008-11-07 12:55:34.000000000 -0500
30672 -+++ linux-2.6.27.6/include/linux/vmalloc.h 2008-11-18 03:38:45.000000000 -0500
30673 -@@ -12,6 +12,11 @@ struct vm_area_struct; /* vma defining
30674 - #define VM_MAP 0x00000004 /* vmap()ed pages */
30675 - #define VM_USERMAP 0x00000008 /* suitable for remap_vmalloc_range */
30676 - #define VM_VPAGES 0x00000010 /* buffer for pages was vmalloc'ed */
30677 -+
30678 -+#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
30679 -+#define VM_KERNEXEC 0x00000020 /* allocate from executable kernel memory range */
30680 -+#endif
30681 -+
30682 - /* bits [20..32] reserved for arch specific ioremap internals */
30683 -
30684 - /*
30685 -diff -urNp linux-2.6.27.6/include/net/sctp/sctp.h linux-2.6.27.6/include/net/sctp/sctp.h
30686 ---- linux-2.6.27.6/include/net/sctp/sctp.h 2008-11-07 12:55:34.000000000 -0500
30687 -+++ linux-2.6.27.6/include/net/sctp/sctp.h 2008-11-18 03:38:45.000000000 -0500
30688 -@@ -309,8 +309,8 @@ extern int sctp_debug_flag;
30689 -
30690 - #else /* SCTP_DEBUG */
30691 -
30692 --#define SCTP_DEBUG_PRINTK(whatever...)
30693 --#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
30694 -+#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
30695 -+#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
30696 - #define SCTP_ENABLE_DEBUG
30697 - #define SCTP_DISABLE_DEBUG
30698 - #define SCTP_ASSERT(expr, str, func)
30699 -diff -urNp linux-2.6.27.6/include/sound/core.h linux-2.6.27.6/include/sound/core.h
30700 ---- linux-2.6.27.6/include/sound/core.h 2008-11-07 12:55:34.000000000 -0500
30701 -+++ linux-2.6.27.6/include/sound/core.h 2008-11-18 03:38:45.000000000 -0500
30702 -@@ -406,9 +406,9 @@ void snd_verbose_printd(const char *file
30703 -
30704 - #else /* !CONFIG_SND_DEBUG */
30705 -
30706 --#define snd_printd(fmt, args...) /* nothing */
30707 -+#define snd_printd(fmt, args...) do {} while (0)
30708 - #define snd_assert(expr, args...) (void)(expr)
30709 --#define snd_BUG() /* nothing */
30710 -+#define snd_BUG() do {} while (0)
30711 -
30712 - #endif /* CONFIG_SND_DEBUG */
30713 -
30714 -@@ -422,7 +422,7 @@ void snd_verbose_printd(const char *file
30715 - */
30716 - #define snd_printdd(format, args...) snd_printk(format, ##args)
30717 - #else
30718 --#define snd_printdd(format, args...) /* nothing */
30719 -+#define snd_printdd(format, args...) do {} while (0)
30720 - #endif
30721 -
30722 -
30723 -diff -urNp linux-2.6.27.6/include/video/uvesafb.h linux-2.6.27.6/include/video/uvesafb.h
30724 ---- linux-2.6.27.6/include/video/uvesafb.h 2008-11-07 12:55:34.000000000 -0500
30725 -+++ linux-2.6.27.6/include/video/uvesafb.h 2008-11-18 03:38:45.000000000 -0500
30726 -@@ -175,6 +175,7 @@ struct uvesafb_par {
30727 - u8 ypan; /* 0 - nothing, 1 - ypan, 2 - ywrap */
30728 - u8 pmi_setpal; /* PMI for palette changes */
30729 - u16 *pmi_base; /* protected mode interface location */
30730 -+ u8 *pmi_code; /* protected mode code location */
30731 - void *pmi_start;
30732 - void *pmi_pal;
30733 - u8 *vbe_state_orig; /*
30734 -diff -urNp linux-2.6.27.6/init/do_mounts.c linux-2.6.27.6/init/do_mounts.c
30735 ---- linux-2.6.27.6/init/do_mounts.c 2008-11-07 12:55:34.000000000 -0500
30736 -+++ linux-2.6.27.6/init/do_mounts.c 2008-11-18 03:38:45.000000000 -0500
30737 -@@ -214,11 +214,11 @@ static void __init get_fs_names(char *pa
30738 -
30739 - static int __init do_mount_root(char *name, char *fs, int flags, void *data)
30740 - {
30741 -- int err = sys_mount(name, "/root", fs, flags, data);
30742 -+ int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data);
30743 - if (err)
30744 - return err;
30745 -
30746 -- sys_chdir("/root");
30747 -+ sys_chdir((char __user *)"/root");
30748 - ROOT_DEV = current->fs->pwd.mnt->mnt_sb->s_dev;
30749 - printk("VFS: Mounted root (%s filesystem)%s.\n",
30750 - current->fs->pwd.mnt->mnt_sb->s_type->name,
30751 -@@ -304,18 +304,18 @@ void __init change_floppy(char *fmt, ...
30752 - va_start(args, fmt);
30753 - vsprintf(buf, fmt, args);
30754 - va_end(args);
30755 -- fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
30756 -+ fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
30757 - if (fd >= 0) {
30758 - sys_ioctl(fd, FDEJECT, 0);
30759 - sys_close(fd);
30760 - }
30761 - printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
30762 -- fd = sys_open("/dev/console", O_RDWR, 0);
30763 -+ fd = sys_open((char __user *)"/dev/console", O_RDWR, 0);
30764 - if (fd >= 0) {
30765 - sys_ioctl(fd, TCGETS, (long)&termios);
30766 - termios.c_lflag &= ~ICANON;
30767 - sys_ioctl(fd, TCSETSF, (long)&termios);
30768 -- sys_read(fd, &c, 1);
30769 -+ sys_read(fd, (char __user *)&c, 1);
30770 - termios.c_lflag |= ICANON;
30771 - sys_ioctl(fd, TCSETSF, (long)&termios);
30772 - sys_close(fd);
30773 -@@ -402,7 +402,7 @@ void __init prepare_namespace(void)
30774 -
30775 - mount_root();
30776 - out:
30777 -- sys_mount(".", "/", NULL, MS_MOVE, NULL);
30778 -- sys_chroot(".");
30779 -+ sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
30780 -+ sys_chroot((char __user *)".");
30781 - }
30782 -
30783 -diff -urNp linux-2.6.27.6/init/do_mounts.h linux-2.6.27.6/init/do_mounts.h
30784 ---- linux-2.6.27.6/init/do_mounts.h 2008-11-07 12:55:34.000000000 -0500
30785 -+++ linux-2.6.27.6/init/do_mounts.h 2008-11-18 03:38:45.000000000 -0500
30786 -@@ -14,15 +14,15 @@ extern int root_mountflags;
30787 -
30788 - static inline int create_dev(char *name, dev_t dev)
30789 - {
30790 -- sys_unlink(name);
30791 -- return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
30792 -+ sys_unlink((char __user *)name);
30793 -+ return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
30794 - }
30795 -
30796 - #if BITS_PER_LONG == 32
30797 - static inline u32 bstat(char *name)
30798 - {
30799 - struct stat64 stat;
30800 -- if (sys_stat64(name, &stat) != 0)
30801 -+ if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0)
30802 - return 0;
30803 - if (!S_ISBLK(stat.st_mode))
30804 - return 0;
30805 -diff -urNp linux-2.6.27.6/init/do_mounts_initrd.c linux-2.6.27.6/init/do_mounts_initrd.c
30806 ---- linux-2.6.27.6/init/do_mounts_initrd.c 2008-11-07 12:55:34.000000000 -0500
30807 -+++ linux-2.6.27.6/init/do_mounts_initrd.c 2008-11-18 03:38:45.000000000 -0500
30808 -@@ -32,7 +32,7 @@ static int __init do_linuxrc(void * shel
30809 - sys_close(old_fd);sys_close(root_fd);
30810 - sys_close(0);sys_close(1);sys_close(2);
30811 - sys_setsid();
30812 -- (void) sys_open("/dev/console",O_RDWR,0);
30813 -+ (void) sys_open((const char __user *)"/dev/console",O_RDWR,0);
30814 - (void) sys_dup(0);
30815 - (void) sys_dup(0);
30816 - return kernel_execve(shell, argv, envp_init);
30817 -@@ -47,13 +47,13 @@ static void __init handle_initrd(void)
30818 - create_dev("/dev/root.old", Root_RAM0);
30819 - /* mount initrd on rootfs' /root */
30820 - mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
30821 -- sys_mkdir("/old", 0700);
30822 -- root_fd = sys_open("/", 0, 0);
30823 -- old_fd = sys_open("/old", 0, 0);
30824 -+ sys_mkdir((const char __user *)"/old", 0700);
30825 -+ root_fd = sys_open((const char __user *)"/", 0, 0);
30826 -+ old_fd = sys_open((const char __user *)"/old", 0, 0);
30827 - /* move initrd over / and chdir/chroot in initrd root */
30828 -- sys_chdir("/root");
30829 -- sys_mount(".", "/", NULL, MS_MOVE, NULL);
30830 -- sys_chroot(".");
30831 -+ sys_chdir((const char __user *)"/root");
30832 -+ sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
30833 -+ sys_chroot((const char __user *)".");
30834 -
30835 - /*
30836 - * In case that a resume from disk is carried out by linuxrc or one of
30837 -@@ -70,15 +70,15 @@ static void __init handle_initrd(void)
30838 -
30839 - /* move initrd to rootfs' /old */
30840 - sys_fchdir(old_fd);
30841 -- sys_mount("/", ".", NULL, MS_MOVE, NULL);
30842 -+ sys_mount((char __user *)"/", (char __user *)".", NULL, MS_MOVE, NULL);
30843 - /* switch root and cwd back to / of rootfs */
30844 - sys_fchdir(root_fd);
30845 -- sys_chroot(".");
30846 -+ sys_chroot((const char __user *)".");
30847 - sys_close(old_fd);
30848 - sys_close(root_fd);
30849 -
30850 - if (new_decode_dev(real_root_dev) == Root_RAM0) {
30851 -- sys_chdir("/old");
30852 -+ sys_chdir((const char __user *)"/old");
30853 - return;
30854 - }
30855 -
30856 -@@ -86,17 +86,17 @@ static void __init handle_initrd(void)
30857 - mount_root();
30858 -
30859 - printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
30860 -- error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
30861 -+ error = sys_mount((char __user *)"/old", (char __user *)"/root/initrd", NULL, MS_MOVE, NULL);
30862 - if (!error)
30863 - printk("okay\n");
30864 - else {
30865 -- int fd = sys_open("/dev/root.old", O_RDWR, 0);
30866 -+ int fd = sys_open((const char __user *)"/dev/root.old", O_RDWR, 0);
30867 - if (error == -ENOENT)
30868 - printk("/initrd does not exist. Ignored.\n");
30869 - else
30870 - printk("failed\n");
30871 - printk(KERN_NOTICE "Unmounting old root\n");
30872 -- sys_umount("/old", MNT_DETACH);
30873 -+ sys_umount((char __user *)"/old", MNT_DETACH);
30874 - printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
30875 - if (fd < 0) {
30876 - error = fd;
30877 -@@ -119,11 +119,11 @@ int __init initrd_load(void)
30878 - * mounted in the normal path.
30879 - */
30880 - if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) {
30881 -- sys_unlink("/initrd.image");
30882 -+ sys_unlink((const char __user *)"/initrd.image");
30883 - handle_initrd();
30884 - return 1;
30885 - }
30886 - }
30887 -- sys_unlink("/initrd.image");
30888 -+ sys_unlink((const char __user *)"/initrd.image");
30889 - return 0;
30890 - }
30891 -diff -urNp linux-2.6.27.6/init/do_mounts_md.c linux-2.6.27.6/init/do_mounts_md.c
30892 ---- linux-2.6.27.6/init/do_mounts_md.c 2008-11-07 12:55:34.000000000 -0500
30893 -+++ linux-2.6.27.6/init/do_mounts_md.c 2008-11-18 03:38:45.000000000 -0500
30894 -@@ -166,7 +166,7 @@ static void __init md_setup_drive(void)
30895 - partitioned ? "_d" : "", minor,
30896 - md_setup_args[ent].device_names);
30897 -
30898 -- fd = sys_open(name, 0, 0);
30899 -+ fd = sys_open((char __user *)name, 0, 0);
30900 - if (fd < 0) {
30901 - printk(KERN_ERR "md: open failed - cannot start "
30902 - "array %s\n", name);
30903 -@@ -229,7 +229,7 @@ static void __init md_setup_drive(void)
30904 - * array without it
30905 - */
30906 - sys_close(fd);
30907 -- fd = sys_open(name, 0, 0);
30908 -+ fd = sys_open((char __user *)name, 0, 0);
30909 - sys_ioctl(fd, BLKRRPART, 0);
30910 - }
30911 - sys_close(fd);
30912 -@@ -270,7 +270,7 @@ void __init md_run_setup(void)
30913 - if (raid_noautodetect)
30914 - printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
30915 - else {
30916 -- int fd = sys_open("/dev/md0", 0, 0);
30917 -+ int fd = sys_open((char __user *)"/dev/md0", 0, 0);
30918 - if (fd >= 0) {
30919 - sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
30920 - sys_close(fd);
30921 -diff -urNp linux-2.6.27.6/init/initramfs.c linux-2.6.27.6/init/initramfs.c
30922 ---- linux-2.6.27.6/init/initramfs.c 2008-11-07 12:55:34.000000000 -0500
30923 -+++ linux-2.6.27.6/init/initramfs.c 2008-11-18 03:38:45.000000000 -0500
30924 -@@ -230,7 +230,7 @@ static int __init maybe_link(void)
30925 - if (nlink >= 2) {
30926 - char *old = find_link(major, minor, ino, mode, collected);
30927 - if (old)
30928 -- return (sys_link(old, collected) < 0) ? -1 : 1;
30929 -+ return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1;
30930 - }
30931 - return 0;
30932 - }
30933 -@@ -239,11 +239,11 @@ static void __init clean_path(char *path
30934 - {
30935 - struct stat st;
30936 -
30937 -- if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
30938 -+ if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
30939 - if (S_ISDIR(st.st_mode))
30940 -- sys_rmdir(path);
30941 -+ sys_rmdir((char __user *)path);
30942 - else
30943 -- sys_unlink(path);
30944 -+ sys_unlink((char __user *)path);
30945 - }
30946 - }
30947 -
30948 -@@ -266,7 +266,7 @@ static int __init do_name(void)
30949 - int openflags = O_WRONLY|O_CREAT;
30950 - if (ml != 1)
30951 - openflags |= O_TRUNC;
30952 -- wfd = sys_open(collected, openflags, mode);
30953 -+ wfd = sys_open((char __user *)collected, openflags, mode);
30954 -
30955 - if (wfd >= 0) {
30956 - sys_fchown(wfd, uid, gid);
30957 -@@ -275,15 +275,15 @@ static int __init do_name(void)
30958 - }
30959 - }
30960 - } else if (S_ISDIR(mode)) {
30961 -- sys_mkdir(collected, mode);
30962 -- sys_chown(collected, uid, gid);
30963 -- sys_chmod(collected, mode);
30964 -+ sys_mkdir((char __user *)collected, mode);
30965 -+ sys_chown((char __user *)collected, uid, gid);
30966 -+ sys_chmod((char __user *)collected, mode);
30967 - } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
30968 - S_ISFIFO(mode) || S_ISSOCK(mode)) {
30969 - if (maybe_link() == 0) {
30970 -- sys_mknod(collected, mode, rdev);
30971 -- sys_chown(collected, uid, gid);
30972 -- sys_chmod(collected, mode);
30973 -+ sys_mknod((char __user *)collected, mode, rdev);
30974 -+ sys_chown((char __user *)collected, uid, gid);
30975 -+ sys_chmod((char __user *)collected, mode);
30976 - }
30977 - }
30978 - return 0;
30979 -@@ -292,13 +292,13 @@ static int __init do_name(void)
30980 - static int __init do_copy(void)
30981 - {
30982 - if (count >= body_len) {
30983 -- sys_write(wfd, victim, body_len);
30984 -+ sys_write(wfd, (char __user *)victim, body_len);
30985 - sys_close(wfd);
30986 - eat(body_len);
30987 - state = SkipIt;
30988 - return 0;
30989 - } else {
30990 -- sys_write(wfd, victim, count);
30991 -+ sys_write(wfd, (char __user *)victim, count);
30992 - body_len -= count;
30993 - eat(count);
30994 - return 1;
30995 -@@ -309,8 +309,8 @@ static int __init do_symlink(void)
30996 - {
30997 - collected[N_ALIGN(name_len) + body_len] = '\0';
30998 - clean_path(collected, 0);
30999 -- sys_symlink(collected + N_ALIGN(name_len), collected);
31000 -- sys_lchown(collected, uid, gid);
31001 -+ sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected);
31002 -+ sys_lchown((char __user *)collected, uid, gid);
31003 - state = SkipIt;
31004 - next_state = Reset;
31005 - return 0;
31006 -diff -urNp linux-2.6.27.6/init/Kconfig linux-2.6.27.6/init/Kconfig
31007 ---- linux-2.6.27.6/init/Kconfig 2008-11-07 12:55:34.000000000 -0500
31008 -+++ linux-2.6.27.6/init/Kconfig 2008-11-18 03:38:45.000000000 -0500
31009 -@@ -561,6 +561,7 @@ config SYSCTL_SYSCALL
31010 - config KALLSYMS
31011 - bool "Load all symbols for debugging/ksymoops" if EMBEDDED
31012 - default y
31013 -+ depends on !GRKERNSEC_HIDESYM
31014 - help
31015 - Say Y here to let the kernel print out symbolic crash information and
31016 - symbolic stack backtraces. This increases the size of the kernel
31017 -@@ -780,8 +781,8 @@ config MARKERS
31018 - source "arch/Kconfig"
31019 -
31020 - config PROC_PAGE_MONITOR
31021 -- default y
31022 -- depends on PROC_FS && MMU
31023 -+ default n
31024 -+ depends on PROC_FS && MMU && !GRKERNSEC
31025 - bool "Enable /proc page monitoring" if EMBEDDED
31026 - help
31027 - Various /proc files exist to monitor process memory utilization:
31028 -@@ -797,9 +798,9 @@ config HAVE_GENERIC_DMA_COHERENT
31029 -
31030 - config SLABINFO
31031 - bool
31032 -- depends on PROC_FS
31033 -+ depends on PROC_FS && !GRKERNSEC_PROC_ADD
31034 - depends on SLAB || SLUB_DEBUG
31035 -- default y
31036 -+ default n
31037 -
31038 - config RT_MUTEXES
31039 - boolean
31040 -diff -urNp linux-2.6.27.6/init/main.c linux-2.6.27.6/init/main.c
31041 ---- linux-2.6.27.6/init/main.c 2008-11-07 12:55:34.000000000 -0500
31042 -+++ linux-2.6.27.6/init/main.c 2008-11-18 03:38:45.000000000 -0500
31043 -@@ -101,6 +101,7 @@ static inline void mark_rodata_ro(void)
31044 - #ifdef CONFIG_TC
31045 - extern void tc_init(void);
31046 - #endif
31047 -+extern void grsecurity_init(void);
31048 -
31049 - enum system_states system_state;
31050 - EXPORT_SYMBOL(system_state);
31051 -@@ -187,6 +188,40 @@ static int __init set_reset_devices(char
31052 -
31053 - __setup("reset_devices", set_reset_devices);
31054 -
31055 -+#if defined(CONFIG_PAX_MEMORY_UDEREF) && defined(CONFIG_X86_32)
31056 -+static int __init setup_pax_nouderef(char *str)
31057 -+{
31058 -+ unsigned int cpu;
31059 -+
31060 -+#ifdef CONFIG_PAX_KERNEXEC
31061 -+ unsigned long cr0;
31062 -+
31063 -+ pax_open_kernel(cr0);
31064 -+#endif
31065 -+
31066 -+ for (cpu = 0; cpu < NR_CPUS; cpu++)
31067 -+ get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_DS].b = 0x00cf9300;
31068 -+
31069 -+#ifdef CONFIG_PAX_KERNEXEC
31070 -+ pax_close_kernel(cr0);
31071 -+#endif
31072 -+
31073 -+ return 1;
31074 -+}
31075 -+__setup("pax_nouderef", setup_pax_nouderef);
31076 -+#endif
31077 -+
31078 -+#ifdef CONFIG_PAX_SOFTMODE
31079 -+unsigned int pax_softmode;
31080 -+
31081 -+static int __init setup_pax_softmode(char *str)
31082 -+{
31083 -+ get_option(&str, &pax_softmode);
31084 -+ return 1;
31085 -+}
31086 -+__setup("pax_softmode=", setup_pax_softmode);
31087 -+#endif
31088 -+
31089 - static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
31090 - char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
31091 - static const char *panic_later, *panic_param;
31092 -@@ -385,7 +420,7 @@ static void __init setup_nr_cpu_ids(void
31093 - }
31094 -
31095 - #ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
31096 --unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
31097 -+unsigned long __per_cpu_offset[NR_CPUS] __read_only;
31098 -
31099 - EXPORT_SYMBOL(__per_cpu_offset);
31100 -
31101 -@@ -704,6 +739,7 @@ int do_one_initcall(initcall_t fn)
31102 - {
31103 - int count = preempt_count();
31104 - ktime_t t0, t1, delta;
31105 -+ const char *msg1 = "", *msg2 = "";
31106 - char msgbuf[64];
31107 - int result;
31108 -
31109 -@@ -729,15 +765,15 @@ int do_one_initcall(initcall_t fn)
31110 - sprintf(msgbuf, "error code %d ", result);
31111 -
31112 - if (preempt_count() != count) {
31113 -- strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf));
31114 -+ msg1 = " preemption imbalance";
31115 - preempt_count() = count;
31116 - }
31117 - if (irqs_disabled()) {
31118 -- strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf));
31119 -+ msg2 = " disabled interrupts";
31120 - local_irq_enable();
31121 - }
31122 -- if (msgbuf[0]) {
31123 -- printk("initcall %pF returned with %s\n", fn, msgbuf);
31124 -+ if (msgbuf[0] || *msg1 || *msg2) {
31125 -+ printk("initcall %pF returned with %s%s%s\n", fn, msgbuf, msg1, msg2);
31126 - }
31127 -
31128 - return result;
31129 -@@ -876,6 +912,8 @@ static int __init kernel_init(void * unu
31130 - prepare_namespace();
31131 - }
31132 -
31133 -+ grsecurity_init();
31134 -+
31135 - /*
31136 - * Ok, we have completed the initial bootup, and
31137 - * we're essentially up and running. Get rid of the
31138 -diff -urNp linux-2.6.27.6/init/noinitramfs.c linux-2.6.27.6/init/noinitramfs.c
31139 ---- linux-2.6.27.6/init/noinitramfs.c 2008-11-07 12:55:34.000000000 -0500
31140 -+++ linux-2.6.27.6/init/noinitramfs.c 2008-11-18 03:38:45.000000000 -0500
31141 -@@ -29,7 +29,7 @@ static int __init default_rootfs(void)
31142 - {
31143 - int err;
31144 -
31145 -- err = sys_mkdir("/dev", 0755);
31146 -+ err = sys_mkdir((const char __user *)"/dev", 0755);
31147 - if (err < 0)
31148 - goto out;
31149 -
31150 -@@ -39,7 +39,7 @@ static int __init default_rootfs(void)
31151 - if (err < 0)
31152 - goto out;
31153 -
31154 -- err = sys_mkdir("/root", 0700);
31155 -+ err = sys_mkdir((const char __user *)"/root", 0700);
31156 - if (err < 0)
31157 - goto out;
31158 -
31159 -diff -urNp linux-2.6.27.6/ipc/ipc_sysctl.c linux-2.6.27.6/ipc/ipc_sysctl.c
31160 ---- linux-2.6.27.6/ipc/ipc_sysctl.c 2008-11-07 12:55:34.000000000 -0500
31161 -+++ linux-2.6.27.6/ipc/ipc_sysctl.c 2008-11-18 03:38:45.000000000 -0500
31162 -@@ -268,7 +268,7 @@ static struct ctl_table ipc_kern_table[]
31163 - .extra1 = &zero,
31164 - .extra2 = &one,
31165 - },
31166 -- {}
31167 -+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
31168 - };
31169 -
31170 - static struct ctl_table ipc_root_table[] = {
31171 -@@ -278,7 +278,7 @@ static struct ctl_table ipc_root_table[]
31172 - .mode = 0555,
31173 - .child = ipc_kern_table,
31174 - },
31175 -- {}
31176 -+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
31177 - };
31178 -
31179 - static int __init ipc_sysctl_init(void)
31180 -diff -urNp linux-2.6.27.6/ipc/msg.c linux-2.6.27.6/ipc/msg.c
31181 ---- linux-2.6.27.6/ipc/msg.c 2008-11-07 12:55:34.000000000 -0500
31182 -+++ linux-2.6.27.6/ipc/msg.c 2008-11-18 03:38:45.000000000 -0500
31183 -@@ -38,6 +38,7 @@
31184 - #include <linux/rwsem.h>
31185 - #include <linux/nsproxy.h>
31186 - #include <linux/ipc_namespace.h>
31187 -+#include <linux/grsecurity.h>
31188 -
31189 - #include <asm/current.h>
31190 - #include <asm/uaccess.h>
31191 -@@ -314,6 +315,7 @@ asmlinkage long sys_msgget(key_t key, in
31192 - struct ipc_namespace *ns;
31193 - struct ipc_ops msg_ops;
31194 - struct ipc_params msg_params;
31195 -+ long err;
31196 -
31197 - ns = current->nsproxy->ipc_ns;
31198 -
31199 -@@ -324,7 +326,11 @@ asmlinkage long sys_msgget(key_t key, in
31200 - msg_params.key = key;
31201 - msg_params.flg = msgflg;
31202 -
31203 -- return ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
31204 -+ err = ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
31205 -+
31206 -+ gr_log_msgget(err, msgflg);
31207 -+
31208 -+ return err;
31209 - }
31210 -
31211 - static inline unsigned long
31212 -@@ -434,6 +440,7 @@ static int msgctl_down(struct ipc_namesp
31213 -
31214 - switch (cmd) {
31215 - case IPC_RMID:
31216 -+ gr_log_msgrm(ipcp->uid, ipcp->cuid);
31217 - freeque(ns, ipcp);
31218 - goto out_up;
31219 - case IPC_SET:
31220 -diff -urNp linux-2.6.27.6/ipc/sem.c linux-2.6.27.6/ipc/sem.c
31221 ---- linux-2.6.27.6/ipc/sem.c 2008-11-07 12:55:34.000000000 -0500
31222 -+++ linux-2.6.27.6/ipc/sem.c 2008-11-18 03:38:45.000000000 -0500
31223 -@@ -83,6 +83,7 @@
31224 - #include <linux/rwsem.h>
31225 - #include <linux/nsproxy.h>
31226 - #include <linux/ipc_namespace.h>
31227 -+#include <linux/grsecurity.h>
31228 -
31229 - #include <asm/uaccess.h>
31230 - #include "util.h"
31231 -@@ -313,6 +314,7 @@ asmlinkage long sys_semget(key_t key, in
31232 - struct ipc_namespace *ns;
31233 - struct ipc_ops sem_ops;
31234 - struct ipc_params sem_params;
31235 -+ long err;
31236 -
31237 - ns = current->nsproxy->ipc_ns;
31238 -
31239 -@@ -327,7 +329,11 @@ asmlinkage long sys_semget(key_t key, in
31240 - sem_params.flg = semflg;
31241 - sem_params.u.nsems = nsems;
31242 -
31243 -- return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
31244 -+ err = ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
31245 -+
31246 -+ gr_log_semget(err, semflg);
31247 -+
31248 -+ return err;
31249 - }
31250 -
31251 - /*
31252 -@@ -870,6 +876,7 @@ static int semctl_down(struct ipc_namesp
31253 -
31254 - switch(cmd){
31255 - case IPC_RMID:
31256 -+ gr_log_semrm(ipcp->uid, ipcp->cuid);
31257 - freeary(ns, ipcp);
31258 - goto out_up;
31259 - case IPC_SET:
31260 -diff -urNp linux-2.6.27.6/ipc/shm.c linux-2.6.27.6/ipc/shm.c
31261 ---- linux-2.6.27.6/ipc/shm.c 2008-11-07 12:55:34.000000000 -0500
31262 -+++ linux-2.6.27.6/ipc/shm.c 2008-11-18 03:38:45.000000000 -0500
31263 -@@ -39,6 +39,7 @@
31264 - #include <linux/nsproxy.h>
31265 - #include <linux/mount.h>
31266 - #include <linux/ipc_namespace.h>
31267 -+#include <linux/grsecurity.h>
31268 -
31269 - #include <asm/uaccess.h>
31270 -
31271 -@@ -69,6 +70,14 @@ static void shm_destroy (struct ipc_name
31272 - static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
31273 - #endif
31274 -
31275 -+#ifdef CONFIG_GRKERNSEC
31276 -+extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
31277 -+ const time_t shm_createtime, const uid_t cuid,
31278 -+ const int shmid);
31279 -+extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
31280 -+ const time_t shm_createtime);
31281 -+#endif
31282 -+
31283 - void shm_init_ns(struct ipc_namespace *ns)
31284 - {
31285 - ns->shm_ctlmax = SHMMAX;
31286 -@@ -87,6 +96,8 @@ static void do_shm_rmid(struct ipc_names
31287 - struct shmid_kernel *shp;
31288 - shp = container_of(ipcp, struct shmid_kernel, shm_perm);
31289 -
31290 -+ gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
31291 -+
31292 - if (shp->shm_nattch){
31293 - shp->shm_perm.mode |= SHM_DEST;
31294 - /* Do not find it any more */
31295 -@@ -392,6 +403,14 @@ static int newseg(struct ipc_namespace *
31296 - shp->shm_lprid = 0;
31297 - shp->shm_atim = shp->shm_dtim = 0;
31298 - shp->shm_ctim = get_seconds();
31299 -+#ifdef CONFIG_GRKERNSEC
31300 -+ {
31301 -+ struct timespec timeval;
31302 -+ do_posix_clock_monotonic_gettime(&timeval);
31303 -+
31304 -+ shp->shm_createtime = timeval.tv_sec;
31305 -+ }
31306 -+#endif
31307 - shp->shm_segsz = size;
31308 - shp->shm_nattch = 0;
31309 - shp->shm_file = file;
31310 -@@ -445,6 +464,7 @@ asmlinkage long sys_shmget (key_t key, s
31311 - struct ipc_namespace *ns;
31312 - struct ipc_ops shm_ops;
31313 - struct ipc_params shm_params;
31314 -+ long err;
31315 -
31316 - ns = current->nsproxy->ipc_ns;
31317 -
31318 -@@ -456,7 +476,11 @@ asmlinkage long sys_shmget (key_t key, s
31319 - shm_params.flg = shmflg;
31320 - shm_params.u.size = size;
31321 -
31322 -- return ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
31323 -+ err = ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
31324 -+
31325 -+ gr_log_shmget(err, shmflg, size);
31326 -+
31327 -+ return err;
31328 - }
31329 -
31330 - static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version)
31331 -@@ -869,9 +893,21 @@ long do_shmat(int shmid, char __user *sh
31332 - if (err)
31333 - goto out_unlock;
31334 -
31335 -+#ifdef CONFIG_GRKERNSEC
31336 -+ if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
31337 -+ shp->shm_perm.cuid, shmid) ||
31338 -+ !gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
31339 -+ err = -EACCES;
31340 -+ goto out_unlock;
31341 -+ }
31342 -+#endif
31343 -+
31344 - path.dentry = dget(shp->shm_file->f_path.dentry);
31345 - path.mnt = shp->shm_file->f_path.mnt;
31346 - shp->shm_nattch++;
31347 -+#ifdef CONFIG_GRKERNSEC
31348 -+ shp->shm_lapid = current->pid;
31349 -+#endif
31350 - size = i_size_read(path.dentry->d_inode);
31351 - shm_unlock(shp);
31352 -
31353 -diff -urNp linux-2.6.27.6/kernel/acct.c linux-2.6.27.6/kernel/acct.c
31354 ---- linux-2.6.27.6/kernel/acct.c 2008-11-07 12:55:34.000000000 -0500
31355 -+++ linux-2.6.27.6/kernel/acct.c 2008-11-18 03:38:45.000000000 -0500
31356 -@@ -573,7 +573,7 @@ static void do_acct_process(struct bsd_a
31357 - */
31358 - flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
31359 - current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
31360 -- file->f_op->write(file, (char *)&ac,
31361 -+ file->f_op->write(file, (char __user *)&ac,
31362 - sizeof(acct_t), &file->f_pos);
31363 - current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
31364 - set_fs(fs);
31365 -diff -urNp linux-2.6.27.6/kernel/capability.c linux-2.6.27.6/kernel/capability.c
31366 ---- linux-2.6.27.6/kernel/capability.c 2008-11-07 12:55:34.000000000 -0500
31367 -+++ linux-2.6.27.6/kernel/capability.c 2008-11-18 03:38:45.000000000 -0500
31368 -@@ -13,6 +13,7 @@
31369 - #include <linux/security.h>
31370 - #include <linux/syscalls.h>
31371 - #include <linux/pid_namespace.h>
31372 -+#include <linux/grsecurity.h>
31373 - #include <asm/uaccess.h>
31374 -
31375 - /*
31376 -@@ -498,10 +499,21 @@ asmlinkage long sys_capset(cap_user_head
31377 - */
31378 - int capable(int cap)
31379 - {
31380 -- if (has_capability(current, cap)) {
31381 -+ if (has_capability(current, cap) && gr_task_is_capable(current, cap)) {
31382 - current->flags |= PF_SUPERPRIV;
31383 - return 1;
31384 - }
31385 - return 0;
31386 - }
31387 -+
31388 -+int capable_nolog(int cap)
31389 -+{
31390 -+ if (has_capability(current, cap) && gr_is_capable_nolog(cap)) {
31391 -+ current->flags |= PF_SUPERPRIV;
31392 -+ return 1;
31393 -+ }
31394 -+ return 0;
31395 -+}
31396 -+
31397 - EXPORT_SYMBOL(capable);
31398 -+EXPORT_SYMBOL(capable_nolog);
31399 -diff -urNp linux-2.6.27.6/kernel/configs.c linux-2.6.27.6/kernel/configs.c
31400 ---- linux-2.6.27.6/kernel/configs.c 2008-11-07 12:55:34.000000000 -0500
31401 -+++ linux-2.6.27.6/kernel/configs.c 2008-11-18 03:38:45.000000000 -0500
31402 -@@ -79,8 +79,19 @@ static int __init ikconfig_init(void)
31403 - struct proc_dir_entry *entry;
31404 -
31405 - /* create the current config file */
31406 -+#ifdef CONFIG_GRKERNSEC_PROC_ADD
31407 -+#ifdef CONFIG_GRKERNSEC_PROC_USER
31408 -+ entry = proc_create("config.gz", S_IFREG | S_IRUSR, NULL,
31409 -+ &ikconfig_file_ops);
31410 -+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
31411 -+ entry = proc_create("config.gz", S_IFREG | S_IRUSR | S_IRGRP, NULL,
31412 -+ &ikconfig_file_ops);
31413 -+#endif
31414 -+#else
31415 - entry = proc_create("config.gz", S_IFREG | S_IRUGO, NULL,
31416 - &ikconfig_file_ops);
31417 -+#endif
31418 -+
31419 - if (!entry)
31420 - return -ENOMEM;
31421 -
31422 -diff -urNp linux-2.6.27.6/kernel/cpu.c linux-2.6.27.6/kernel/cpu.c
31423 ---- linux-2.6.27.6/kernel/cpu.c 2008-11-07 12:55:34.000000000 -0500
31424 -+++ linux-2.6.27.6/kernel/cpu.c 2008-11-18 03:38:45.000000000 -0500
31425 -@@ -40,7 +40,7 @@ EXPORT_SYMBOL(cpu_possible_map);
31426 - /* Serializes the updates to cpu_online_map, cpu_present_map */
31427 - static DEFINE_MUTEX(cpu_add_remove_lock);
31428 -
31429 --static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain);
31430 -+static RAW_NOTIFIER_HEAD(cpu_chain);
31431 -
31432 - /* If set, cpu_up and cpu_down will return -EBUSY and do nothing.
31433 - * Should always be manipulated under cpu_add_remove_lock
31434 -diff -urNp linux-2.6.27.6/kernel/exit.c linux-2.6.27.6/kernel/exit.c
31435 ---- linux-2.6.27.6/kernel/exit.c 2008-11-07 12:55:34.000000000 -0500
31436 -+++ linux-2.6.27.6/kernel/exit.c 2008-11-18 03:38:45.000000000 -0500
31437 -@@ -47,6 +47,11 @@
31438 - #include <linux/blkdev.h>
31439 - #include <linux/task_io_accounting_ops.h>
31440 - #include <linux/tracehook.h>
31441 -+#include <linux/grsecurity.h>
31442 -+
31443 -+#ifdef CONFIG_GRKERNSEC
31444 -+extern rwlock_t grsec_exec_file_lock;
31445 -+#endif
31446 -
31447 - #include <asm/uaccess.h>
31448 - #include <asm/unistd.h>
31449 -@@ -134,6 +139,7 @@ static void __exit_signal(struct task_st
31450 - */
31451 - flush_sigqueue(&tsk->pending);
31452 -
31453 -+ gr_del_task_from_ip_table(tsk);
31454 - tsk->signal = NULL;
31455 - tsk->sighand = NULL;
31456 - spin_unlock(&sighand->siglock);
31457 -@@ -321,11 +327,22 @@ static void reparent_to_kthreadd(void)
31458 - {
31459 - write_lock_irq(&tasklist_lock);
31460 -
31461 -+#ifdef CONFIG_GRKERNSEC
31462 -+ write_lock(&grsec_exec_file_lock);
31463 -+ if (current->exec_file) {
31464 -+ fput(current->exec_file);
31465 -+ current->exec_file = NULL;
31466 -+ }
31467 -+ write_unlock(&grsec_exec_file_lock);
31468 -+#endif
31469 -+
31470 - ptrace_unlink(current);
31471 - /* Reparent to init */
31472 - current->real_parent = current->parent = kthreadd_task;
31473 - list_move_tail(&current->sibling, &current->real_parent->children);
31474 -
31475 -+ gr_set_kernel_label(current);
31476 -+
31477 - /* Set the exit signal to SIGCHLD so we signal init on exit */
31478 - current->exit_signal = SIGCHLD;
31479 -
31480 -@@ -419,6 +436,17 @@ void daemonize(const char *name, ...)
31481 - vsnprintf(current->comm, sizeof(current->comm), name, args);
31482 - va_end(args);
31483 -
31484 -+#ifdef CONFIG_GRKERNSEC
31485 -+ write_lock(&grsec_exec_file_lock);
31486 -+ if (current->exec_file) {
31487 -+ fput(current->exec_file);
31488 -+ current->exec_file = NULL;
31489 -+ }
31490 -+ write_unlock(&grsec_exec_file_lock);
31491 -+#endif
31492 -+
31493 -+ gr_set_kernel_label(current);
31494 -+
31495 - /*
31496 - * If we were started as result of loading a module, close all of the
31497 - * user space pages. We don't need them, and if we didn't close them
31498 -@@ -1070,6 +1098,9 @@ NORET_TYPE void do_exit(long code)
31499 - tsk->exit_code = code;
31500 - taskstats_exit(tsk, group_dead);
31501 -
31502 -+ gr_acl_handle_psacct(tsk, code);
31503 -+ gr_acl_handle_exit();
31504 -+
31505 - exit_mm(tsk);
31506 -
31507 - if (group_dead)
31508 -@@ -1272,7 +1303,7 @@ static int wait_task_zombie(struct task_
31509 - if (unlikely(options & WNOWAIT)) {
31510 - uid_t uid = p->uid;
31511 - int exit_code = p->exit_code;
31512 -- int why, status;
31513 -+ int why;
31514 -
31515 - get_task_struct(p);
31516 - read_unlock(&tasklist_lock);
31517 -diff -urNp linux-2.6.27.6/kernel/fork.c linux-2.6.27.6/kernel/fork.c
31518 ---- linux-2.6.27.6/kernel/fork.c 2008-11-07 12:55:34.000000000 -0500
31519 -+++ linux-2.6.27.6/kernel/fork.c 2008-11-18 03:38:45.000000000 -0500
31520 -@@ -58,6 +58,7 @@
31521 - #include <linux/tty.h>
31522 - #include <linux/proc_fs.h>
31523 - #include <linux/blkdev.h>
31524 -+#include <linux/grsecurity.h>
31525 -
31526 - #include <asm/pgtable.h>
31527 - #include <asm/pgalloc.h>
31528 -@@ -234,7 +235,7 @@ static struct task_struct *dup_task_stru
31529 - setup_thread_stack(tsk, orig);
31530 -
31531 - #ifdef CONFIG_CC_STACKPROTECTOR
31532 -- tsk->stack_canary = get_random_int();
31533 -+ tsk->stack_canary = pax_get_random_long();
31534 - #endif
31535 -
31536 - /* One for us, one for whoever does the "release_task()" (usually parent) */
31537 -@@ -271,8 +272,8 @@ static int dup_mmap(struct mm_struct *mm
31538 - mm->locked_vm = 0;
31539 - mm->mmap = NULL;
31540 - mm->mmap_cache = NULL;
31541 -- mm->free_area_cache = oldmm->mmap_base;
31542 -- mm->cached_hole_size = ~0UL;
31543 -+ mm->free_area_cache = oldmm->free_area_cache;
31544 -+ mm->cached_hole_size = oldmm->cached_hole_size;
31545 - mm->map_count = 0;
31546 - cpus_clear(mm->cpu_vm_mask);
31547 - mm->mm_rb = RB_ROOT;
31548 -@@ -309,6 +310,7 @@ static int dup_mmap(struct mm_struct *mm
31549 - tmp->vm_flags &= ~VM_LOCKED;
31550 - tmp->vm_mm = mm;
31551 - tmp->vm_next = NULL;
31552 -+ tmp->vm_mirror = NULL;
31553 - anon_vma_link(tmp);
31554 - file = tmp->vm_file;
31555 - if (file) {
31556 -@@ -353,6 +355,31 @@ static int dup_mmap(struct mm_struct *mm
31557 - if (retval)
31558 - goto out;
31559 - }
31560 -+
31561 -+#ifdef CONFIG_PAX_SEGMEXEC
31562 -+ if (oldmm->pax_flags & MF_PAX_SEGMEXEC) {
31563 -+ struct vm_area_struct *mpnt_m;
31564 -+
31565 -+ for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) {
31566 -+ BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm);
31567 -+
31568 -+ if (!mpnt->vm_mirror)
31569 -+ continue;
31570 -+
31571 -+ if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) {
31572 -+ BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt);
31573 -+ mpnt->vm_mirror = mpnt_m;
31574 -+ } else {
31575 -+ BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm);
31576 -+ mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror;
31577 -+ mpnt_m->vm_mirror->vm_mirror = mpnt_m;
31578 -+ mpnt->vm_mirror->vm_mirror = mpnt;
31579 -+ }
31580 -+ }
31581 -+ BUG_ON(mpnt_m);
31582 -+ }
31583 -+#endif
31584 -+
31585 - /* a new mm has just been created */
31586 - arch_dup_mmap(oldmm, mm);
31587 - retval = 0;
31588 -@@ -536,7 +563,7 @@ void mm_release(struct task_struct *tsk,
31589 - if (tsk->clear_child_tid
31590 - && !(tsk->flags & PF_SIGNALED)
31591 - && atomic_read(&mm->mm_users) > 1) {
31592 -- u32 __user * tidptr = tsk->clear_child_tid;
31593 -+ pid_t __user * tidptr = tsk->clear_child_tid;
31594 - tsk->clear_child_tid = NULL;
31595 -
31596 - /*
31597 -@@ -544,7 +571,7 @@ void mm_release(struct task_struct *tsk,
31598 - * not set up a proper pointer then tough luck.
31599 - */
31600 - put_user(0, tidptr);
31601 -- sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
31602 -+ sys_futex((u32 __user *)tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
31603 - }
31604 - }
31605 -
31606 -@@ -939,6 +966,9 @@ static struct task_struct *copy_process(
31607 - DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
31608 - #endif
31609 - retval = -EAGAIN;
31610 -+
31611 -+ gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
31612 -+
31613 - if (atomic_read(&p->user->processes) >=
31614 - p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
31615 - if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
31616 -@@ -1105,6 +1135,8 @@ static struct task_struct *copy_process(
31617 - goto bad_fork_free_pid;
31618 - }
31619 -
31620 -+ gr_copy_label(p);
31621 -+
31622 - p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
31623 - /*
31624 - * Clear TID on mm_release()?
31625 -@@ -1290,6 +1322,8 @@ bad_fork_cleanup_count:
31626 - bad_fork_free:
31627 - free_task(p);
31628 - fork_out:
31629 -+ gr_log_forkfail(retval);
31630 -+
31631 - return ERR_PTR(retval);
31632 - }
31633 -
31634 -@@ -1366,6 +1400,8 @@ long do_fork(unsigned long clone_flags,
31635 - if (clone_flags & CLONE_PARENT_SETTID)
31636 - put_user(nr, parent_tidptr);
31637 -
31638 -+ gr_handle_brute_check();
31639 -+
31640 - if (clone_flags & CLONE_VFORK) {
31641 - p->vfork_done = &vfork;
31642 - init_completion(&vfork);
31643 -diff -urNp linux-2.6.27.6/kernel/futex.c linux-2.6.27.6/kernel/futex.c
31644 ---- linux-2.6.27.6/kernel/futex.c 2008-11-07 12:55:34.000000000 -0500
31645 -+++ linux-2.6.27.6/kernel/futex.c 2008-11-18 03:38:45.000000000 -0500
31646 -@@ -188,6 +188,11 @@ static int get_futex_key(u32 __user *uad
31647 - struct page *page;
31648 - int err;
31649 -
31650 -+#ifdef CONFIG_PAX_SEGMEXEC
31651 -+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && address >= SEGMEXEC_TASK_SIZE)
31652 -+ return -EFAULT;
31653 -+#endif
31654 -+
31655 - /*
31656 - * The futex address must be "naturally" aligned.
31657 - */
31658 -@@ -214,8 +219,8 @@ static int get_futex_key(u32 __user *uad
31659 - * The futex is hashed differently depending on whether
31660 - * it's in a shared or private mapping. So check vma first.
31661 - */
31662 -- vma = find_extend_vma(mm, address);
31663 -- if (unlikely(!vma))
31664 -+ vma = find_vma(mm, address);
31665 -+ if (unlikely(!vma || address < vma->vm_start))
31666 - return -EFAULT;
31667 -
31668 - /*
31669 -@@ -1345,7 +1350,7 @@ static int futex_wait(u32 __user *uaddr,
31670 - struct restart_block *restart;
31671 - restart = &current_thread_info()->restart_block;
31672 - restart->fn = futex_wait_restart;
31673 -- restart->futex.uaddr = (u32 *)uaddr;
31674 -+ restart->futex.uaddr = uaddr;
31675 - restart->futex.val = val;
31676 - restart->futex.time = abs_time->tv64;
31677 - restart->futex.bitset = bitset;
31678 -@@ -1906,7 +1911,7 @@ retry:
31679 - */
31680 - static inline int fetch_robust_entry(struct robust_list __user **entry,
31681 - struct robust_list __user * __user *head,
31682 -- int *pi)
31683 -+ unsigned int *pi)
31684 - {
31685 - unsigned long uentry;
31686 -
31687 -diff -urNp linux-2.6.27.6/kernel/irq/handle.c linux-2.6.27.6/kernel/irq/handle.c
31688 ---- linux-2.6.27.6/kernel/irq/handle.c 2008-11-07 12:55:34.000000000 -0500
31689 -+++ linux-2.6.27.6/kernel/irq/handle.c 2008-11-18 03:38:45.000000000 -0500
31690 -@@ -55,7 +55,8 @@ struct irq_desc irq_desc[NR_IRQS] __cach
31691 - .depth = 1,
31692 - .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
31693 - #ifdef CONFIG_SMP
31694 -- .affinity = CPU_MASK_ALL
31695 -+ .affinity = CPU_MASK_ALL,
31696 -+ .cpu = 0,
31697 - #endif
31698 - }
31699 - };
31700 -diff -urNp linux-2.6.27.6/kernel/kallsyms.c linux-2.6.27.6/kernel/kallsyms.c
31701 ---- linux-2.6.27.6/kernel/kallsyms.c 2008-11-07 12:55:34.000000000 -0500
31702 -+++ linux-2.6.27.6/kernel/kallsyms.c 2008-11-18 03:38:45.000000000 -0500
31703 -@@ -62,6 +62,19 @@ static inline int is_kernel_text(unsigne
31704 -
31705 - static inline int is_kernel(unsigned long addr)
31706 - {
31707 -+
31708 -+#ifdef CONFIG_PAX_KERNEXEC
31709 -+
31710 -+#ifdef CONFIG_MODULES
31711 -+ if ((unsigned long)MODULES_VADDR <= ktla_ktva(addr) &&
31712 -+ ktla_ktva(addr) < (unsigned long)MODULES_END)
31713 -+ return 0;
31714 -+#endif
31715 -+
31716 -+ if (is_kernel_inittext(addr))
31717 -+ return 1;
31718 -+#endif
31719 -+
31720 - if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
31721 - return 1;
31722 - return in_gate_area_no_task(addr);
31723 -@@ -366,7 +379,6 @@ static unsigned long get_ksymbol_core(st
31724 -
31725 - static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
31726 - {
31727 -- iter->name[0] = '\0';
31728 - iter->nameoff = get_symbol_offset(new_pos);
31729 - iter->pos = new_pos;
31730 - }
31731 -@@ -450,7 +462,7 @@ static int kallsyms_open(struct inode *i
31732 - struct kallsym_iter *iter;
31733 - int ret;
31734 -
31735 -- iter = kmalloc(sizeof(*iter), GFP_KERNEL);
31736 -+ iter = kzalloc(sizeof(*iter), GFP_KERNEL);
31737 - if (!iter)
31738 - return -ENOMEM;
31739 - reset_iter(iter, 0);
31740 -@@ -472,7 +484,15 @@ static const struct file_operations kall
31741 -
31742 - static int __init kallsyms_init(void)
31743 - {
31744 -+#ifdef CONFIG_GRKERNSEC_PROC_ADD
31745 -+#ifdef CONFIG_GRKERNSEC_PROC_USER
31746 -+ proc_create("kallsyms", S_IFREG | S_IRUSR, NULL, &kallsyms_operations);
31747 -+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
31748 -+ proc_create("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL, &kallsyms_operations);
31749 -+#endif
31750 -+#else
31751 - proc_create("kallsyms", 0444, NULL, &kallsyms_operations);
31752 -+#endif
31753 - return 0;
31754 - }
31755 - __initcall(kallsyms_init);
31756 -diff -urNp linux-2.6.27.6/kernel/kmod.c linux-2.6.27.6/kernel/kmod.c
31757 ---- linux-2.6.27.6/kernel/kmod.c 2008-11-07 12:55:34.000000000 -0500
31758 -+++ linux-2.6.27.6/kernel/kmod.c 2008-11-18 03:38:45.000000000 -0500
31759 -@@ -108,7 +108,7 @@ int request_module(const char *fmt, ...)
31760 - return -ENOMEM;
31761 - }
31762 -
31763 -- ret = call_usermodehelper(modprobe_path, argv, envp, 1);
31764 -+ ret = call_usermodehelper(modprobe_path, argv, envp, UMH_WAIT_PROC);
31765 - atomic_dec(&kmod_concurrent);
31766 - return ret;
31767 - }
31768 -diff -urNp linux-2.6.27.6/kernel/kprobes.c linux-2.6.27.6/kernel/kprobes.c
31769 ---- linux-2.6.27.6/kernel/kprobes.c 2008-11-07 12:55:34.000000000 -0500
31770 -+++ linux-2.6.27.6/kernel/kprobes.c 2008-11-18 03:38:45.000000000 -0500
31771 -@@ -182,7 +182,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
31772 - * kernel image and loaded module images reside. This is required
31773 - * so x86_64 can correctly handle the %rip-relative fixups.
31774 - */
31775 -- kip->insns = module_alloc(PAGE_SIZE);
31776 -+ kip->insns = module_alloc_exec(PAGE_SIZE);
31777 - if (!kip->insns) {
31778 - kfree(kip);
31779 - return NULL;
31780 -@@ -214,7 +214,7 @@ static int __kprobes collect_one_slot(st
31781 - hlist_add_head(&kip->hlist,
31782 - &kprobe_insn_pages);
31783 - } else {
31784 -- module_free(NULL, kip->insns);
31785 -+ module_free_exec(NULL, kip->insns);
31786 - kfree(kip);
31787 - }
31788 - return 1;
31789 -diff -urNp linux-2.6.27.6/kernel/lockdep.c linux-2.6.27.6/kernel/lockdep.c
31790 ---- linux-2.6.27.6/kernel/lockdep.c 2008-11-07 12:55:34.000000000 -0500
31791 -+++ linux-2.6.27.6/kernel/lockdep.c 2008-11-18 03:38:45.000000000 -0500
31792 -@@ -627,6 +627,10 @@ static int static_obj(void *obj)
31793 - int i;
31794 - #endif
31795 -
31796 -+#ifdef CONFIG_PAX_KERNEXEC
31797 -+ start = (unsigned long )&_data;
31798 -+#endif
31799 -+
31800 - /*
31801 - * static variable?
31802 - */
31803 -@@ -638,9 +642,12 @@ static int static_obj(void *obj)
31804 - * percpu var?
31805 - */
31806 - for_each_possible_cpu(i) {
31807 -+#ifdef CONFIG_X86_32
31808 -+ start = per_cpu_offset(i);
31809 -+#else
31810 - start = (unsigned long) &__per_cpu_start + per_cpu_offset(i);
31811 -- end = (unsigned long) &__per_cpu_start + PERCPU_ENOUGH_ROOM
31812 -- + per_cpu_offset(i);
31813 -+#endif
31814 -+ end = start + PERCPU_ENOUGH_ROOM;
31815 -
31816 - if ((addr >= start) && (addr < end))
31817 - return 1;
31818 -diff -urNp linux-2.6.27.6/kernel/module.c linux-2.6.27.6/kernel/module.c
31819 ---- linux-2.6.27.6/kernel/module.c 2008-11-07 12:55:34.000000000 -0500
31820 -+++ linux-2.6.27.6/kernel/module.c 2008-11-18 04:48:35.000000000 -0500
31821 -@@ -44,6 +44,11 @@
31822 - #include <linux/unwind.h>
31823 - #include <asm/uaccess.h>
31824 - #include <asm/cacheflush.h>
31825 -+
31826 -+#ifdef CONFIG_PAX_KERNEXEC
31827 -+#include <asm/desc.h>
31828 -+#endif
31829 -+
31830 - #include <linux/license.h>
31831 - #include <asm/sections.h>
31832 -
31833 -@@ -71,7 +76,10 @@ static DECLARE_WAIT_QUEUE_HEAD(module_wq
31834 - static BLOCKING_NOTIFIER_HEAD(module_notify_list);
31835 -
31836 - /* Bounds of module allocation, for speeding __module_text_address */
31837 --static unsigned long module_addr_min = -1UL, module_addr_max = 0;
31838 -+static unsigned long module_addr_min_rw = -1UL, module_addr_max_rw = 0;
31839 -+static unsigned long module_addr_min_rx = -1UL, module_addr_max_rx = 0;
31840 -+
31841 -+extern int gr_check_modstop(void);
31842 -
31843 - int register_module_notifier(struct notifier_block * nb)
31844 - {
31845 -@@ -217,7 +225,7 @@ static bool each_symbol(bool (*fn)(const
31846 - return true;
31847 -
31848 - list_for_each_entry(mod, &modules, list) {
31849 -- struct symsearch arr[] = {
31850 -+ struct symsearch modarr[] = {
31851 - { mod->syms, mod->syms + mod->num_syms, mod->crcs,
31852 - NOT_GPL_ONLY, false },
31853 - { mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms,
31854 -@@ -239,7 +247,7 @@ static bool each_symbol(bool (*fn)(const
31855 - #endif
31856 - };
31857 -
31858 -- if (each_symbol_in_section(arr, ARRAY_SIZE(arr), mod, fn, data))
31859 -+ if (each_symbol_in_section(modarr, ARRAY_SIZE(modarr), mod, fn, data))
31860 - return true;
31861 - }
31862 - return false;
31863 -@@ -375,6 +383,8 @@ static inline unsigned int block_size(in
31864 - return val;
31865 - }
31866 -
31867 -+EXPORT_SYMBOL(__per_cpu_start);
31868 -+
31869 - static void *percpu_modalloc(unsigned long size, unsigned long align,
31870 - const char *name)
31871 - {
31872 -@@ -382,7 +392,7 @@ static void *percpu_modalloc(unsigned lo
31873 - unsigned int i;
31874 - void *ptr;
31875 -
31876 -- if (align > PAGE_SIZE) {
31877 -+ if (align-1 >= PAGE_SIZE) {
31878 - printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
31879 - name, align, PAGE_SIZE);
31880 - align = PAGE_SIZE;
31881 -@@ -464,7 +474,11 @@ static void percpu_modcopy(void *pcpudes
31882 - int cpu;
31883 -
31884 - for_each_possible_cpu(cpu)
31885 -+#ifdef CONFIG_X86_32
31886 -+ memcpy(pcpudest + __per_cpu_offset[cpu], from, size);
31887 -+#else
31888 - memcpy(pcpudest + per_cpu_offset(cpu), from, size);
31889 -+#endif
31890 - }
31891 -
31892 - static int percpu_modinit(void)
31893 -@@ -722,6 +736,9 @@ sys_delete_module(const char __user *nam
31894 - char name[MODULE_NAME_LEN];
31895 - int ret, forced = 0;
31896 -
31897 -+ if (gr_check_modstop())
31898 -+ return -EPERM;
31899 -+
31900 - if (!capable(CAP_SYS_MODULE))
31901 - return -EPERM;
31902 -
31903 -@@ -1430,16 +1447,19 @@ static void free_module(struct module *m
31904 - module_unload_free(mod);
31905 -
31906 - /* This may be NULL, but that's OK */
31907 -- module_free(mod, mod->module_init);
31908 -+ module_free(mod, mod->module_init_rw);
31909 -+ module_free_exec(mod, mod->module_init_rx);
31910 - kfree(mod->args);
31911 - if (mod->percpu)
31912 - percpu_modfree(mod->percpu);
31913 -
31914 - /* Free lock-classes: */
31915 -- lockdep_free_key_range(mod->module_core, mod->core_size);
31916 -+ lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
31917 -+ lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
31918 -
31919 - /* Finally, free the core (containing the module structure) */
31920 -- module_free(mod, mod->module_core);
31921 -+ module_free_exec(mod, mod->module_core_rx);
31922 -+ module_free(mod, mod->module_core_rw);
31923 - }
31924 -
31925 - void *__symbol_get(const char *symbol)
31926 -@@ -1505,10 +1525,14 @@ static int simplify_symbols(Elf_Shdr *se
31927 - struct module *mod)
31928 - {
31929 - Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
31930 -- unsigned long secbase;
31931 -+ unsigned long secbase, symbol;
31932 - unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
31933 - int ret = 0;
31934 -
31935 -+#ifdef CONFIG_PAX_KERNEXEC
31936 -+ unsigned long cr0;
31937 -+#endif
31938 -+
31939 - for (i = 1; i < n; i++) {
31940 - switch (sym[i].st_shndx) {
31941 - case SHN_COMMON:
31942 -@@ -1527,10 +1551,19 @@ static int simplify_symbols(Elf_Shdr *se
31943 - break;
31944 -
31945 - case SHN_UNDEF:
31946 -- sym[i].st_value
31947 -- = resolve_symbol(sechdrs, versindex,
31948 -+ symbol = resolve_symbol(sechdrs, versindex,
31949 - strtab + sym[i].st_name, mod);
31950 -
31951 -+#ifdef CONFIG_PAX_KERNEXEC
31952 -+ pax_open_kernel(cr0);
31953 -+#endif
31954 -+
31955 -+ sym[i].st_value = symbol;
31956 -+
31957 -+#ifdef CONFIG_PAX_KERNEXEC
31958 -+ pax_close_kernel(cr0);
31959 -+#endif
31960 -+
31961 - /* Ok if resolved. */
31962 - if (!IS_ERR_VALUE(sym[i].st_value))
31963 - break;
31964 -@@ -1545,11 +1578,27 @@ static int simplify_symbols(Elf_Shdr *se
31965 -
31966 - default:
31967 - /* Divert to percpu allocation if a percpu var. */
31968 -- if (sym[i].st_shndx == pcpuindex)
31969 -+ if (sym[i].st_shndx == pcpuindex) {
31970 -+
31971 -+#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
31972 -+ secbase = (unsigned long)mod->percpu - (unsigned long)__per_cpu_start;
31973 -+#else
31974 - secbase = (unsigned long)mod->percpu;
31975 -- else
31976 -+#endif
31977 -+
31978 -+ } else
31979 - secbase = sechdrs[sym[i].st_shndx].sh_addr;
31980 -+
31981 -+#ifdef CONFIG_PAX_KERNEXEC
31982 -+ pax_open_kernel(cr0);
31983 -+#endif
31984 -+
31985 - sym[i].st_value += secbase;
31986 -+
31987 -+#ifdef CONFIG_PAX_KERNEXEC
31988 -+ pax_close_kernel(cr0);
31989 -+#endif
31990 -+
31991 - break;
31992 - }
31993 - }
31994 -@@ -1601,11 +1650,12 @@ static void layout_sections(struct modul
31995 - || strncmp(secstrings + s->sh_name,
31996 - ".init", 5) == 0)
31997 - continue;
31998 -- s->sh_entsize = get_offset(&mod->core_size, s);
31999 -+ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
32000 -+ s->sh_entsize = get_offset(&mod->core_size_rw, s);
32001 -+ else
32002 -+ s->sh_entsize = get_offset(&mod->core_size_rx, s);
32003 - DEBUGP("\t%s\n", secstrings + s->sh_name);
32004 - }
32005 -- if (m == 0)
32006 -- mod->core_text_size = mod->core_size;
32007 - }
32008 -
32009 - DEBUGP("Init section allocation order:\n");
32010 -@@ -1619,12 +1669,13 @@ static void layout_sections(struct modul
32011 - || strncmp(secstrings + s->sh_name,
32012 - ".init", 5) != 0)
32013 - continue;
32014 -- s->sh_entsize = (get_offset(&mod->init_size, s)
32015 -- | INIT_OFFSET_MASK);
32016 -+ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
32017 -+ s->sh_entsize = get_offset(&mod->init_size_rw, s);
32018 -+ else
32019 -+ s->sh_entsize = get_offset(&mod->init_size_rx, s);
32020 -+ s->sh_entsize |= INIT_OFFSET_MASK;
32021 - DEBUGP("\t%s\n", secstrings + s->sh_name);
32022 - }
32023 -- if (m == 0)
32024 -- mod->init_text_size = mod->init_size;
32025 - }
32026 - }
32027 -
32028 -@@ -1764,14 +1815,31 @@ static void add_kallsyms(struct module *
32029 - {
32030 - unsigned int i;
32031 -
32032 -+#ifdef CONFIG_PAX_KERNEXEC
32033 -+ unsigned long cr0;
32034 -+#endif
32035 -+
32036 - mod->symtab = (void *)sechdrs[symindex].sh_addr;
32037 - mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
32038 - mod->strtab = (void *)sechdrs[strindex].sh_addr;
32039 -
32040 - /* Set types up while we still have access to sections. */
32041 -- for (i = 0; i < mod->num_symtab; i++)
32042 -- mod->symtab[i].st_info
32043 -- = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
32044 -+
32045 -+ for (i = 0; i < mod->num_symtab; i++) {
32046 -+ char type = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
32047 -+
32048 -+#ifdef CONFIG_PAX_KERNEXEC
32049 -+ pax_open_kernel(cr0);
32050 -+#endif
32051 -+
32052 -+ mod->symtab[i].st_info = type;
32053 -+
32054 -+#ifdef CONFIG_PAX_KERNEXEC
32055 -+ pax_close_kernel(cr0);
32056 -+#endif
32057 -+
32058 -+ }
32059 -+
32060 - }
32061 - #else
32062 - static inline void add_kallsyms(struct module *mod,
32063 -@@ -1783,16 +1851,30 @@ static inline void add_kallsyms(struct m
32064 - }
32065 - #endif /* CONFIG_KALLSYMS */
32066 -
32067 --static void *module_alloc_update_bounds(unsigned long size)
32068 -+static void *module_alloc_update_bounds_rw(unsigned long size)
32069 - {
32070 - void *ret = module_alloc(size);
32071 -
32072 - if (ret) {
32073 - /* Update module bounds. */
32074 -- if ((unsigned long)ret < module_addr_min)
32075 -- module_addr_min = (unsigned long)ret;
32076 -- if ((unsigned long)ret + size > module_addr_max)
32077 -- module_addr_max = (unsigned long)ret + size;
32078 -+ if ((unsigned long)ret < module_addr_min_rw)
32079 -+ module_addr_min_rw = (unsigned long)ret;
32080 -+ if ((unsigned long)ret + size > module_addr_max_rw)
32081 -+ module_addr_max_rw = (unsigned long)ret + size;
32082 -+ }
32083 -+ return ret;
32084 -+}
32085 -+
32086 -+static void *module_alloc_update_bounds_rx(unsigned long size)
32087 -+{
32088 -+ void *ret = module_alloc_exec(size);
32089 -+
32090 -+ if (ret) {
32091 -+ /* Update module bounds. */
32092 -+ if ((unsigned long)ret < module_addr_min_rx)
32093 -+ module_addr_min_rx = (unsigned long)ret;
32094 -+ if ((unsigned long)ret + size > module_addr_max_rx)
32095 -+ module_addr_max_rx = (unsigned long)ret + size;
32096 - }
32097 - return ret;
32098 - }
32099 -@@ -1837,6 +1919,10 @@ static noinline struct module *load_modu
32100 - struct exception_table_entry *extable;
32101 - mm_segment_t old_fs;
32102 -
32103 -+#ifdef CONFIG_PAX_KERNEXEC
32104 -+ unsigned long cr0;
32105 -+#endif
32106 -+
32107 - DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
32108 - umod, len, uargs);
32109 - if (len < sizeof(*hdr))
32110 -@@ -1998,22 +2084,57 @@ static noinline struct module *load_modu
32111 - layout_sections(mod, hdr, sechdrs, secstrings);
32112 -
32113 - /* Do the allocs. */
32114 -- ptr = module_alloc_update_bounds(mod->core_size);
32115 -+ ptr = module_alloc_update_bounds_rw(mod->core_size_rw);
32116 - if (!ptr) {
32117 - err = -ENOMEM;
32118 - goto free_percpu;
32119 - }
32120 -- memset(ptr, 0, mod->core_size);
32121 -- mod->module_core = ptr;
32122 -+ memset(ptr, 0, mod->core_size_rw);
32123 -+ mod->module_core_rw = ptr;
32124 -+
32125 -+ ptr = module_alloc_update_bounds_rw(mod->init_size_rw);
32126 -+ if (!ptr && mod->init_size_rw) {
32127 -+ err = -ENOMEM;
32128 -+ goto free_core_rw;
32129 -+ }
32130 -+ memset(ptr, 0, mod->init_size_rw);
32131 -+ mod->module_init_rw = ptr;
32132 -+
32133 -+ ptr = module_alloc_update_bounds_rx(mod->core_size_rx);
32134 -+ if (!ptr) {
32135 -+ err = -ENOMEM;
32136 -+ goto free_init_rw;
32137 -+ }
32138 -+
32139 -+#ifdef CONFIG_PAX_KERNEXEC
32140 -+ pax_open_kernel(cr0);
32141 -+#endif
32142 -+
32143 -+ memset(ptr, 0, mod->core_size_rx);
32144 -
32145 -- ptr = module_alloc_update_bounds(mod->init_size);
32146 -- if (!ptr && mod->init_size) {
32147 -+#ifdef CONFIG_PAX_KERNEXEC
32148 -+ pax_close_kernel(cr0);
32149 -+#endif
32150 -+
32151 -+ mod->module_core_rx = ptr;
32152 -+
32153 -+ ptr = module_alloc_update_bounds_rx(mod->init_size_rx);
32154 -+ if (!ptr && mod->init_size_rx) {
32155 - err = -ENOMEM;
32156 -- goto free_core;
32157 -+ goto free_core_rx;
32158 - }
32159 -- memset(ptr, 0, mod->init_size);
32160 -- mod->module_init = ptr;
32161 -
32162 -+#ifdef CONFIG_PAX_KERNEXEC
32163 -+ pax_open_kernel(cr0);
32164 -+#endif
32165 -+
32166 -+ memset(ptr, 0, mod->init_size_rx);
32167 -+
32168 -+#ifdef CONFIG_PAX_KERNEXEC
32169 -+ pax_close_kernel(cr0);
32170 -+#endif
32171 -+
32172 -+ mod->module_init_rx = ptr;
32173 - /* Transfer each section which specifies SHF_ALLOC */
32174 - DEBUGP("final section addresses:\n");
32175 - for (i = 0; i < hdr->e_shnum; i++) {
32176 -@@ -2022,17 +2143,41 @@ static noinline struct module *load_modu
32177 - if (!(sechdrs[i].sh_flags & SHF_ALLOC))
32178 - continue;
32179 -
32180 -- if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
32181 -- dest = mod->module_init
32182 -- + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
32183 -- else
32184 -- dest = mod->module_core + sechdrs[i].sh_entsize;
32185 -+ if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
32186 -+ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
32187 -+ dest = mod->module_init_rw
32188 -+ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
32189 -+ else
32190 -+ dest = mod->module_init_rx
32191 -+ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
32192 -+ } else {
32193 -+ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
32194 -+ dest = mod->module_core_rw + sechdrs[i].sh_entsize;
32195 -+ else
32196 -+ dest = mod->module_core_rx + sechdrs[i].sh_entsize;
32197 -+ }
32198 -+
32199 -+ if (sechdrs[i].sh_type != SHT_NOBITS) {
32200 -
32201 -- if (sechdrs[i].sh_type != SHT_NOBITS)
32202 -- memcpy(dest, (void *)sechdrs[i].sh_addr,
32203 -- sechdrs[i].sh_size);
32204 -+#ifdef CONFIG_PAX_KERNEXEC
32205 -+ if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC)) {
32206 -+ pax_open_kernel(cr0);
32207 -+ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
32208 -+ pax_close_kernel(cr0);
32209 -+ } else
32210 -+#endif
32211 -+
32212 -+ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
32213 -+ }
32214 - /* Update sh_addr to point to copy in image. */
32215 -- sechdrs[i].sh_addr = (unsigned long)dest;
32216 -+
32217 -+#ifdef CONFIG_PAX_KERNEXEC
32218 -+ if (sechdrs[i].sh_flags & SHF_EXECINSTR)
32219 -+ sechdrs[i].sh_addr = ktva_ktla((unsigned long)dest);
32220 -+ else
32221 -+#endif
32222 -+
32223 -+ sechdrs[i].sh_addr = (unsigned long)dest;
32224 - DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
32225 - }
32226 - /* Module has been moved. */
32227 -@@ -2120,8 +2265,8 @@ static noinline struct module *load_modu
32228 -
32229 - /* Now do relocations. */
32230 - for (i = 1; i < hdr->e_shnum; i++) {
32231 -- const char *strtab = (char *)sechdrs[strindex].sh_addr;
32232 - unsigned int info = sechdrs[i].sh_info;
32233 -+ strtab = (char *)sechdrs[strindex].sh_addr;
32234 -
32235 - /* Not a valid relocation section? */
32236 - if (info >= hdr->e_shnum)
32237 -@@ -2180,12 +2325,12 @@ static noinline struct module *load_modu
32238 - * Do it before processing of module parameters, so the module
32239 - * can provide parameter accessor functions of its own.
32240 - */
32241 -- if (mod->module_init)
32242 -- flush_icache_range((unsigned long)mod->module_init,
32243 -- (unsigned long)mod->module_init
32244 -- + mod->init_size);
32245 -- flush_icache_range((unsigned long)mod->module_core,
32246 -- (unsigned long)mod->module_core + mod->core_size);
32247 -+ if (mod->module_init_rx)
32248 -+ flush_icache_range((unsigned long)mod->module_init_rx,
32249 -+ (unsigned long)mod->module_init_rx
32250 -+ + mod->init_size_rx);
32251 -+ flush_icache_range((unsigned long)mod->module_core_rx,
32252 -+ (unsigned long)mod->module_core_rx + mod->core_size_rx);
32253 -
32254 - set_fs(old_fs);
32255 -
32256 -@@ -2238,9 +2383,13 @@ static noinline struct module *load_modu
32257 - kobject_put(&mod->mkobj.kobj);
32258 - free_unload:
32259 - module_unload_free(mod);
32260 -- module_free(mod, mod->module_init);
32261 -- free_core:
32262 -- module_free(mod, mod->module_core);
32263 -+ module_free_exec(mod, mod->module_init_rx);
32264 -+ free_core_rx:
32265 -+ module_free_exec(mod, mod->module_core_rx);
32266 -+ free_init_rw:
32267 -+ module_free(mod, mod->module_init_rw);
32268 -+ free_core_rw:
32269 -+ module_free(mod, mod->module_core_rw);
32270 - free_percpu:
32271 - if (percpu)
32272 - percpu_modfree(percpu);
32273 -@@ -2265,6 +2414,9 @@ sys_init_module(void __user *umod,
32274 - struct module *mod;
32275 - int ret = 0;
32276 -
32277 -+ if (gr_check_modstop())
32278 -+ return -EPERM;
32279 -+
32280 - /* Must have permission */
32281 - if (!capable(CAP_SYS_MODULE))
32282 - return -EPERM;
32283 -@@ -2320,10 +2472,12 @@ sys_init_module(void __user *umod,
32284 - /* Drop initial reference. */
32285 - module_put(mod);
32286 - unwind_remove_table(mod->unwind_info, 1);
32287 -- module_free(mod, mod->module_init);
32288 -- mod->module_init = NULL;
32289 -- mod->init_size = 0;
32290 -- mod->init_text_size = 0;
32291 -+ module_free(mod, mod->module_init_rw);
32292 -+ module_free_exec(mod, mod->module_init_rx);
32293 -+ mod->module_init_rw = NULL;
32294 -+ mod->module_init_rx = NULL;
32295 -+ mod->init_size_rw = 0;
32296 -+ mod->init_size_rx = 0;
32297 - mutex_unlock(&module_mutex);
32298 -
32299 - return 0;
32300 -@@ -2331,6 +2485,13 @@ sys_init_module(void __user *umod,
32301 -
32302 - static inline int within(unsigned long addr, void *start, unsigned long size)
32303 - {
32304 -+
32305 -+#ifdef CONFIG_PAX_KERNEXEC
32306 -+ if (ktla_ktva(addr) >= (unsigned long)start &&
32307 -+ ktla_ktva(addr) < (unsigned long)start + size)
32308 -+ return 1;
32309 -+#endif
32310 -+
32311 - return ((void *)addr >= start && (void *)addr < start + size);
32312 - }
32313 -
32314 -@@ -2354,10 +2515,14 @@ static const char *get_ksymbol(struct mo
32315 - unsigned long nextval;
32316 -
32317 - /* At worse, next value is at end of module */
32318 -- if (within(addr, mod->module_init, mod->init_size))
32319 -- nextval = (unsigned long)mod->module_init+mod->init_text_size;
32320 -+ if (within(addr, mod->module_init_rx, mod->init_size_rx))
32321 -+ nextval = (unsigned long)mod->module_init_rx+mod->init_size_rx;
32322 -+ else if (within(addr, mod->module_init_rw, mod->init_size_rw))
32323 -+ nextval = (unsigned long)mod->module_init_rw+mod->init_size_rw;
32324 -+ else if (within(addr, mod->module_core_rx, mod->core_size_rx))
32325 -+ nextval = (unsigned long)mod->module_core_rx+mod->core_size_rx;
32326 - else
32327 -- nextval = (unsigned long)mod->module_core+mod->core_text_size;
32328 -+ nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
32329 -
32330 - /* Scan for closest preceeding symbol, and next symbol. (ELF
32331 - starts real symbols at 1). */
32332 -@@ -2402,8 +2567,10 @@ const char *module_address_lookup(unsign
32333 -
32334 - preempt_disable();
32335 - list_for_each_entry(mod, &modules, list) {
32336 -- if (within(addr, mod->module_init, mod->init_size)
32337 -- || within(addr, mod->module_core, mod->core_size)) {
32338 -+ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
32339 -+ within(addr, mod->module_init_rw, mod->init_size_rw) ||
32340 -+ within(addr, mod->module_core_rx, mod->core_size_rx) ||
32341 -+ within(addr, mod->module_core_rw, mod->core_size_rw)) {
32342 - if (modname)
32343 - *modname = mod->name;
32344 - ret = get_ksymbol(mod, addr, size, offset);
32345 -@@ -2425,8 +2592,10 @@ int lookup_module_symbol_name(unsigned l
32346 -
32347 - preempt_disable();
32348 - list_for_each_entry(mod, &modules, list) {
32349 -- if (within(addr, mod->module_init, mod->init_size) ||
32350 -- within(addr, mod->module_core, mod->core_size)) {
32351 -+ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
32352 -+ within(addr, mod->module_init_rw, mod->init_size_rw) ||
32353 -+ within(addr, mod->module_core_rx, mod->core_size_rx) ||
32354 -+ within(addr, mod->module_core_rw, mod->core_size_rw)) {
32355 - const char *sym;
32356 -
32357 - sym = get_ksymbol(mod, addr, NULL, NULL);
32358 -@@ -2449,8 +2618,10 @@ int lookup_module_symbol_attrs(unsigned
32359 -
32360 - preempt_disable();
32361 - list_for_each_entry(mod, &modules, list) {
32362 -- if (within(addr, mod->module_init, mod->init_size) ||
32363 -- within(addr, mod->module_core, mod->core_size)) {
32364 -+ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
32365 -+ within(addr, mod->module_init_rw, mod->init_size_rw) ||
32366 -+ within(addr, mod->module_core_rx, mod->core_size_rx) ||
32367 -+ within(addr, mod->module_core_rw, mod->core_size_rw)) {
32368 - const char *sym;
32369 -
32370 - sym = get_ksymbol(mod, addr, size, offset);
32371 -@@ -2581,7 +2752,7 @@ static int m_show(struct seq_file *m, vo
32372 - char buf[8];
32373 -
32374 - seq_printf(m, "%s %u",
32375 -- mod->name, mod->init_size + mod->core_size);
32376 -+ mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
32377 - print_unload_info(m, mod);
32378 -
32379 - /* Informative for users. */
32380 -@@ -2590,7 +2761,7 @@ static int m_show(struct seq_file *m, vo
32381 - mod->state == MODULE_STATE_COMING ? "Loading":
32382 - "Live");
32383 - /* Used by oprofile and other similar tools. */
32384 -- seq_printf(m, " 0x%p", mod->module_core);
32385 -+ seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
32386 -
32387 - /* Taints info */
32388 - if (mod->taints)
32389 -@@ -2646,7 +2817,8 @@ int is_module_address(unsigned long addr
32390 - preempt_disable();
32391 -
32392 - list_for_each_entry(mod, &modules, list) {
32393 -- if (within(addr, mod->module_core, mod->core_size)) {
32394 -+ if (within(addr, mod->module_core_rx, mod->core_size_rx) ||
32395 -+ within(addr, mod->module_core_rw, mod->core_size_rw)) {
32396 - preempt_enable();
32397 - return 1;
32398 - }
32399 -@@ -2663,12 +2835,12 @@ struct module *__module_text_address(uns
32400 - {
32401 - struct module *mod;
32402 -
32403 -- if (addr < module_addr_min || addr > module_addr_max)
32404 -+ if (addr < module_addr_min_rx || addr > module_addr_max_rx)
32405 - return NULL;
32406 -
32407 - list_for_each_entry(mod, &modules, list)
32408 -- if (within(addr, mod->module_init, mod->init_text_size)
32409 -- || within(addr, mod->module_core, mod->core_text_size))
32410 -+ if (within(addr, mod->module_init_rx, mod->init_size_rx)
32411 -+ || within(addr, mod->module_core_rx, mod->core_size_rx))
32412 - return mod;
32413 - return NULL;
32414 - }
32415 -diff -urNp linux-2.6.27.6/kernel/mutex.c linux-2.6.27.6/kernel/mutex.c
32416 ---- linux-2.6.27.6/kernel/mutex.c 2008-11-07 12:55:34.000000000 -0500
32417 -+++ linux-2.6.27.6/kernel/mutex.c 2008-11-18 03:38:45.000000000 -0500
32418 -@@ -83,7 +83,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou
32419 - *
32420 - * This function is similar to (but not equivalent to) down().
32421 - */
32422 --void inline __sched mutex_lock(struct mutex *lock)
32423 -+inline void __sched mutex_lock(struct mutex *lock)
32424 - {
32425 - might_sleep();
32426 - /*
32427 -diff -urNp linux-2.6.27.6/kernel/panic.c linux-2.6.27.6/kernel/panic.c
32428 ---- linux-2.6.27.6/kernel/panic.c 2008-11-07 12:55:34.000000000 -0500
32429 -+++ linux-2.6.27.6/kernel/panic.c 2008-11-18 03:38:45.000000000 -0500
32430 -@@ -349,6 +349,8 @@ EXPORT_SYMBOL(warn_slowpath);
32431 - */
32432 - void __stack_chk_fail(void)
32433 - {
32434 -+ print_symbol("stack corrupted in: %s\n", (unsigned long)__builtin_return_address(0));
32435 -+ dump_stack();
32436 - panic("stack-protector: Kernel stack is corrupted");
32437 - }
32438 - EXPORT_SYMBOL(__stack_chk_fail);
32439 -diff -urNp linux-2.6.27.6/kernel/pid.c linux-2.6.27.6/kernel/pid.c
32440 ---- linux-2.6.27.6/kernel/pid.c 2008-11-07 12:55:34.000000000 -0500
32441 -+++ linux-2.6.27.6/kernel/pid.c 2008-11-18 03:38:45.000000000 -0500
32442 -@@ -36,6 +36,7 @@
32443 - #include <linux/pid_namespace.h>
32444 - #include <linux/init_task.h>
32445 - #include <linux/syscalls.h>
32446 -+#include <linux/grsecurity.h>
32447 -
32448 - #define pid_hashfn(nr, ns) \
32449 - hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
32450 -@@ -45,7 +46,7 @@ struct pid init_struct_pid = INIT_STRUCT
32451 -
32452 - int pid_max = PID_MAX_DEFAULT;
32453 -
32454 --#define RESERVED_PIDS 300
32455 -+#define RESERVED_PIDS 500
32456 -
32457 - int pid_max_min = RESERVED_PIDS + 1;
32458 - int pid_max_max = PID_MAX_LIMIT;
32459 -@@ -381,7 +382,14 @@ EXPORT_SYMBOL(pid_task);
32460 - struct task_struct *find_task_by_pid_type_ns(int type, int nr,
32461 - struct pid_namespace *ns)
32462 - {
32463 -- return pid_task(find_pid_ns(nr, ns), type);
32464 -+ struct task_struct *task;
32465 -+
32466 -+ task = pid_task(find_pid_ns(nr, ns), type);
32467 -+
32468 -+ if (gr_pid_is_chrooted(task))
32469 -+ return NULL;
32470 -+
32471 -+ return task;
32472 - }
32473 -
32474 - EXPORT_SYMBOL(find_task_by_pid_type_ns);
32475 -diff -urNp linux-2.6.27.6/kernel/posix-cpu-timers.c linux-2.6.27.6/kernel/posix-cpu-timers.c
32476 ---- linux-2.6.27.6/kernel/posix-cpu-timers.c 2008-11-07 12:55:34.000000000 -0500
32477 -+++ linux-2.6.27.6/kernel/posix-cpu-timers.c 2008-11-18 03:38:45.000000000 -0500
32478 -@@ -6,6 +6,7 @@
32479 - #include <linux/posix-timers.h>
32480 - #include <linux/errno.h>
32481 - #include <linux/math64.h>
32482 -+#include <linux/grsecurity.h>
32483 - #include <asm/uaccess.h>
32484 -
32485 - static int check_clock(const clockid_t which_clock)
32486 -@@ -1176,6 +1177,7 @@ static void check_process_timers(struct
32487 - __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
32488 - return;
32489 - }
32490 -+ gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1);
32491 - if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
32492 - /*
32493 - * At the soft limit, send a SIGXCPU every second.
32494 -@@ -1370,17 +1372,17 @@ void run_posix_cpu_timers(struct task_st
32495 - * timer call will interfere.
32496 - */
32497 - list_for_each_entry_safe(timer, next, &firing, it.cpu.entry) {
32498 -- int firing;
32499 -+ int __firing;
32500 - spin_lock(&timer->it_lock);
32501 - list_del_init(&timer->it.cpu.entry);
32502 -- firing = timer->it.cpu.firing;
32503 -+ __firing = timer->it.cpu.firing;
32504 - timer->it.cpu.firing = 0;
32505 - /*
32506 - * The firing flag is -1 if we collided with a reset
32507 - * of the timer, which already reported this
32508 - * almost-firing as an overrun. So don't generate an event.
32509 - */
32510 -- if (likely(firing >= 0)) {
32511 -+ if (likely(__firing >= 0)) {
32512 - cpu_timer_fire(timer);
32513 - }
32514 - spin_unlock(&timer->it_lock);
32515 -diff -urNp linux-2.6.27.6/kernel/power/poweroff.c linux-2.6.27.6/kernel/power/poweroff.c
32516 ---- linux-2.6.27.6/kernel/power/poweroff.c 2008-11-07 12:55:34.000000000 -0500
32517 -+++ linux-2.6.27.6/kernel/power/poweroff.c 2008-11-18 03:38:45.000000000 -0500
32518 -@@ -37,7 +37,7 @@ static struct sysrq_key_op sysrq_powerof
32519 - .enable_mask = SYSRQ_ENABLE_BOOT,
32520 - };
32521 -
32522 --static int pm_sysrq_init(void)
32523 -+static int __init pm_sysrq_init(void)
32524 - {
32525 - register_sysrq_key('o', &sysrq_poweroff_op);
32526 - return 0;
32527 -diff -urNp linux-2.6.27.6/kernel/printk.c linux-2.6.27.6/kernel/printk.c
32528 ---- linux-2.6.27.6/kernel/printk.c 2008-11-07 12:55:34.000000000 -0500
32529 -+++ linux-2.6.27.6/kernel/printk.c 2008-11-18 03:38:45.000000000 -0500
32530 -@@ -32,6 +32,7 @@
32531 - #include <linux/security.h>
32532 - #include <linux/bootmem.h>
32533 - #include <linux/syscalls.h>
32534 -+#include <linux/grsecurity.h>
32535 -
32536 - #include <asm/uaccess.h>
32537 -
32538 -@@ -293,6 +294,11 @@ int do_syslog(int type, char __user *buf
32539 - char c;
32540 - int error = 0;
32541 -
32542 -+#ifdef CONFIG_GRKERNSEC_DMESG
32543 -+ if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
32544 -+ return -EPERM;
32545 -+#endif
32546 -+
32547 - error = security_syslog(type);
32548 - if (error)
32549 - return error;
32550 -diff -urNp linux-2.6.27.6/kernel/ptrace.c linux-2.6.27.6/kernel/ptrace.c
32551 ---- linux-2.6.27.6/kernel/ptrace.c 2008-11-07 12:55:34.000000000 -0500
32552 -+++ linux-2.6.27.6/kernel/ptrace.c 2008-11-18 03:38:45.000000000 -0500
32553 -@@ -21,6 +21,7 @@
32554 - #include <linux/audit.h>
32555 - #include <linux/pid_namespace.h>
32556 - #include <linux/syscalls.h>
32557 -+#include <linux/grsecurity.h>
32558 -
32559 - #include <asm/pgtable.h>
32560 - #include <asm/uaccess.h>
32561 -@@ -132,12 +133,12 @@ int __ptrace_may_access(struct task_stru
32562 - (current->uid != task->uid) ||
32563 - (current->gid != task->egid) ||
32564 - (current->gid != task->sgid) ||
32565 -- (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
32566 -+ (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
32567 - return -EPERM;
32568 - smp_rmb();
32569 - if (task->mm)
32570 - dumpable = get_dumpable(task->mm);
32571 -- if (!dumpable && !capable(CAP_SYS_PTRACE))
32572 -+ if (!dumpable && !capable_nolog(CAP_SYS_PTRACE))
32573 - return -EPERM;
32574 -
32575 - return security_ptrace_may_access(task, mode);
32576 -@@ -193,7 +194,7 @@ repeat:
32577 -
32578 - /* Go */
32579 - task->ptrace |= PT_PTRACED;
32580 -- if (capable(CAP_SYS_PTRACE))
32581 -+ if (capable_nolog(CAP_SYS_PTRACE))
32582 - task->ptrace |= PT_PTRACE_CAP;
32583 -
32584 - __ptrace_link(task, current);
32585 -@@ -582,6 +583,11 @@ asmlinkage long sys_ptrace(long request,
32586 - if (ret < 0)
32587 - goto out_put_task_struct;
32588 -
32589 -+ if (gr_handle_ptrace(child, request)) {
32590 -+ ret = -EPERM;
32591 -+ goto out_put_task_struct;
32592 -+ }
32593 -+
32594 - ret = arch_ptrace(child, request, addr, data);
32595 - if (ret < 0)
32596 - goto out_put_task_struct;
32597 -diff -urNp linux-2.6.27.6/kernel/relay.c linux-2.6.27.6/kernel/relay.c
32598 ---- linux-2.6.27.6/kernel/relay.c 2008-11-07 12:55:34.000000000 -0500
32599 -+++ linux-2.6.27.6/kernel/relay.c 2008-11-18 03:38:45.000000000 -0500
32600 -@@ -1291,7 +1291,7 @@ static int subbuf_splice_actor(struct fi
32601 - return 0;
32602 -
32603 - ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
32604 -- if (ret < 0 || ret < total_len)
32605 -+ if ((int)ret < 0 || ret < total_len)
32606 - return ret;
32607 -
32608 - if (read_start + ret == nonpad_end)
32609 -diff -urNp linux-2.6.27.6/kernel/resource.c linux-2.6.27.6/kernel/resource.c
32610 ---- linux-2.6.27.6/kernel/resource.c 2008-11-07 12:55:34.000000000 -0500
32611 -+++ linux-2.6.27.6/kernel/resource.c 2008-11-18 03:38:45.000000000 -0500
32612 -@@ -131,8 +131,18 @@ static const struct file_operations proc
32613 -
32614 - static int __init ioresources_init(void)
32615 - {
32616 -+#ifdef CONFIG_GRKERNSEC_PROC_ADD
32617 -+#ifdef CONFIG_GRKERNSEC_PROC_USER
32618 -+ proc_create("ioports", S_IRUSR, NULL, &proc_ioports_operations);
32619 -+ proc_create("iomem", S_IRUSR, NULL, &proc_iomem_operations);
32620 -+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
32621 -+ proc_create("ioports", S_IRUSR | S_IRGRP, NULL, &proc_ioports_operations);
32622 -+ proc_create("iomem", S_IRUSR | S_IRGRP, NULL, &proc_iomem_operations);
32623 -+#endif
32624 -+#else
32625 - proc_create("ioports", 0, NULL, &proc_ioports_operations);
32626 - proc_create("iomem", 0, NULL, &proc_iomem_operations);
32627 -+#endif
32628 - return 0;
32629 - }
32630 - __initcall(ioresources_init);
32631 -diff -urNp linux-2.6.27.6/kernel/sched.c linux-2.6.27.6/kernel/sched.c
32632 ---- linux-2.6.27.6/kernel/sched.c 2008-11-07 12:55:34.000000000 -0500
32633 -+++ linux-2.6.27.6/kernel/sched.c 2008-11-18 03:38:45.000000000 -0500
32634 -@@ -71,6 +71,7 @@
32635 - #include <linux/debugfs.h>
32636 - #include <linux/ctype.h>
32637 - #include <linux/ftrace.h>
32638 -+#include <linux/grsecurity.h>
32639 -
32640 - #include <asm/tlb.h>
32641 - #include <asm/irq_regs.h>
32642 -@@ -4962,7 +4963,8 @@ asmlinkage long sys_nice(int increment)
32643 - if (nice > 19)
32644 - nice = 19;
32645 -
32646 -- if (increment < 0 && !can_nice(current, nice))
32647 -+ if (increment < 0 && (!can_nice(current, nice) ||
32648 -+ gr_handle_chroot_nice()))
32649 - return -EPERM;
32650 -
32651 - retval = security_task_setnice(current, nice);
32652 -@@ -6225,7 +6227,7 @@ static struct ctl_table sd_ctl_dir[] = {
32653 - .procname = "sched_domain",
32654 - .mode = 0555,
32655 - },
32656 -- {0, },
32657 -+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
32658 - };
32659 -
32660 - static struct ctl_table sd_ctl_root[] = {
32661 -@@ -6235,7 +6237,7 @@ static struct ctl_table sd_ctl_root[] =
32662 - .mode = 0555,
32663 - .child = sd_ctl_dir,
32664 - },
32665 -- {0, },
32666 -+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
32667 - };
32668 -
32669 - static struct ctl_table *sd_alloc_ctl_entry(int n)
32670 -diff -urNp linux-2.6.27.6/kernel/signal.c linux-2.6.27.6/kernel/signal.c
32671 ---- linux-2.6.27.6/kernel/signal.c 2008-11-07 12:55:34.000000000 -0500
32672 -+++ linux-2.6.27.6/kernel/signal.c 2008-11-18 03:38:45.000000000 -0500
32673 -@@ -26,6 +26,7 @@
32674 - #include <linux/capability.h>
32675 - #include <linux/freezer.h>
32676 - #include <linux/pid_namespace.h>
32677 -+#include <linux/grsecurity.h>
32678 - #include <linux/nsproxy.h>
32679 -
32680 - #include <asm/param.h>
32681 -@@ -595,6 +596,9 @@ static int check_kill_permission(int sig
32682 - }
32683 - }
32684 -
32685 -+ if (gr_handle_signal(t, sig))
32686 -+ return -EPERM;
32687 -+
32688 - return security_task_kill(t, info, sig, 0);
32689 - }
32690 -
32691 -@@ -884,8 +888,8 @@ static void print_fatal_signal(struct pt
32692 - for (i = 0; i < 16; i++) {
32693 - unsigned char insn;
32694 -
32695 -- __get_user(insn, (unsigned char *)(regs->ip + i));
32696 -- printk("%02x ", insn);
32697 -+ if (!get_user(insn, (unsigned char __user *)(regs->ip + i)))
32698 -+ printk("%02x ", insn);
32699 - }
32700 - }
32701 - #endif
32702 -@@ -908,7 +912,7 @@ __group_send_sig_info(int sig, struct si
32703 - return send_signal(sig, info, p, 1);
32704 - }
32705 -
32706 --static int
32707 -+int
32708 - specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
32709 - {
32710 - return send_signal(sig, info, t, 0);
32711 -@@ -946,8 +950,12 @@ force_sig_info(int sig, struct siginfo *
32712 - if (action->sa.sa_handler == SIG_DFL)
32713 - t->signal->flags &= ~SIGNAL_UNKILLABLE;
32714 - ret = specific_send_sig_info(sig, info, t);
32715 -+
32716 - spin_unlock_irqrestore(&t->sighand->siglock, flags);
32717 -
32718 -+ gr_log_signal(sig, t);
32719 -+ gr_handle_crash(t, sig);
32720 -+
32721 - return ret;
32722 - }
32723 -
32724 -@@ -1018,6 +1026,8 @@ int group_send_sig_info(int sig, struct
32725 - ret = __group_send_sig_info(sig, info, p);
32726 - unlock_task_sighand(p, &flags);
32727 - }
32728 -+ if (!ret)
32729 -+ gr_log_signal(sig, p);
32730 - }
32731 -
32732 - return ret;
32733 -diff -urNp linux-2.6.27.6/kernel/softirq.c linux-2.6.27.6/kernel/softirq.c
32734 ---- linux-2.6.27.6/kernel/softirq.c 2008-11-07 12:55:34.000000000 -0500
32735 -+++ linux-2.6.27.6/kernel/softirq.c 2008-11-18 03:38:45.000000000 -0500
32736 -@@ -453,9 +453,9 @@ void tasklet_kill(struct tasklet_struct
32737 - printk("Attempt to kill tasklet from interrupt\n");
32738 -
32739 - while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
32740 -- do
32741 -+ do {
32742 - yield();
32743 -- while (test_bit(TASKLET_STATE_SCHED, &t->state));
32744 -+ } while (test_bit(TASKLET_STATE_SCHED, &t->state));
32745 - }
32746 - tasklet_unlock_wait(t);
32747 - clear_bit(TASKLET_STATE_SCHED, &t->state);
32748 -diff -urNp linux-2.6.27.6/kernel/sys.c linux-2.6.27.6/kernel/sys.c
32749 ---- linux-2.6.27.6/kernel/sys.c 2008-11-07 12:55:34.000000000 -0500
32750 -+++ linux-2.6.27.6/kernel/sys.c 2008-11-18 03:38:45.000000000 -0500
32751 -@@ -33,6 +33,7 @@
32752 - #include <linux/task_io_accounting_ops.h>
32753 - #include <linux/seccomp.h>
32754 - #include <linux/cpu.h>
32755 -+#include <linux/grsecurity.h>
32756 -
32757 - #include <linux/compat.h>
32758 - #include <linux/syscalls.h>
32759 -@@ -125,6 +126,12 @@ static int set_one_prio(struct task_stru
32760 - error = -EACCES;
32761 - goto out;
32762 - }
32763 -+
32764 -+ if (gr_handle_chroot_setpriority(p, niceval)) {
32765 -+ error = -EACCES;
32766 -+ goto out;
32767 -+ }
32768 -+
32769 - no_nice = security_task_setnice(p, niceval);
32770 - if (no_nice) {
32771 - error = no_nice;
32772 -@@ -181,10 +188,10 @@ asmlinkage long sys_setpriority(int whic
32773 - if ((who != current->uid) && !(user = find_user(who)))
32774 - goto out_unlock; /* No processes for this user */
32775 -
32776 -- do_each_thread(g, p)
32777 -+ do_each_thread(g, p) {
32778 - if (p->uid == who)
32779 - error = set_one_prio(p, niceval, error);
32780 -- while_each_thread(g, p);
32781 -+ } while_each_thread(g, p);
32782 - if (who != current->uid)
32783 - free_uid(user); /* For find_user() */
32784 - break;
32785 -@@ -243,13 +250,13 @@ asmlinkage long sys_getpriority(int whic
32786 - if ((who != current->uid) && !(user = find_user(who)))
32787 - goto out_unlock; /* No processes for this user */
32788 -
32789 -- do_each_thread(g, p)
32790 -+ do_each_thread(g, p) {
32791 - if (p->uid == who) {
32792 - niceval = 20 - task_nice(p);
32793 - if (niceval > retval)
32794 - retval = niceval;
32795 - }
32796 -- while_each_thread(g, p);
32797 -+ } while_each_thread(g, p);
32798 - if (who != current->uid)
32799 - free_uid(user); /* for find_user() */
32800 - break;
32801 -@@ -499,6 +506,10 @@ asmlinkage long sys_setregid(gid_t rgid,
32802 - else
32803 - return -EPERM;
32804 - }
32805 -+
32806 -+ if (gr_check_group_change(new_rgid, new_egid, -1))
32807 -+ return -EPERM;
32808 -+
32809 - if (new_egid != old_egid) {
32810 - set_dumpable(current->mm, suid_dumpable);
32811 - smp_wmb();
32812 -@@ -506,6 +517,9 @@ asmlinkage long sys_setregid(gid_t rgid,
32813 - if (rgid != (gid_t) -1 ||
32814 - (egid != (gid_t) -1 && egid != old_rgid))
32815 - current->sgid = new_egid;
32816 -+
32817 -+ gr_set_role_label(current, current->uid, new_rgid);
32818 -+
32819 - current->fsgid = new_egid;
32820 - current->egid = new_egid;
32821 - current->gid = new_rgid;
32822 -@@ -528,11 +542,17 @@ asmlinkage long sys_setgid(gid_t gid)
32823 - if (retval)
32824 - return retval;
32825 -
32826 -+ if (gr_check_group_change(gid, gid, gid))
32827 -+ return -EPERM;
32828 -+
32829 - if (capable(CAP_SETGID)) {
32830 - if (old_egid != gid) {
32831 - set_dumpable(current->mm, suid_dumpable);
32832 - smp_wmb();
32833 - }
32834 -+
32835 -+ gr_set_role_label(current, current->uid, gid);
32836 -+
32837 - current->gid = current->egid = current->sgid = current->fsgid = gid;
32838 - } else if ((gid == current->gid) || (gid == current->sgid)) {
32839 - if (old_egid != gid) {
32840 -@@ -570,6 +590,9 @@ static int set_user(uid_t new_ruid, int
32841 - set_dumpable(current->mm, suid_dumpable);
32842 - smp_wmb();
32843 - }
32844 -+
32845 -+ gr_set_role_label(current, new_ruid, current->gid);
32846 -+
32847 - current->uid = new_ruid;
32848 - return 0;
32849 - }
32850 -@@ -619,6 +642,9 @@ asmlinkage long sys_setreuid(uid_t ruid,
32851 - return -EPERM;
32852 - }
32853 -
32854 -+ if (gr_check_user_change(new_ruid, new_euid, -1))
32855 -+ return -EPERM;
32856 -+
32857 - if (new_ruid != old_ruid && set_user(new_ruid, new_euid != old_euid) < 0)
32858 - return -EAGAIN;
32859 -
32860 -@@ -665,6 +691,12 @@ asmlinkage long sys_setuid(uid_t uid)
32861 - old_suid = current->suid;
32862 - new_suid = old_suid;
32863 -
32864 -+ if (gr_check_crash_uid(uid))
32865 -+ return -EPERM;
32866 -+
32867 -+ if (gr_check_user_change(uid, uid, uid))
32868 -+ return -EPERM;
32869 -+
32870 - if (capable(CAP_SETUID)) {
32871 - if (uid != old_ruid && set_user(uid, old_euid != uid) < 0)
32872 - return -EAGAIN;
32873 -@@ -712,6 +744,10 @@ asmlinkage long sys_setresuid(uid_t ruid
32874 - (suid != current->euid) && (suid != current->suid))
32875 - return -EPERM;
32876 - }
32877 -+
32878 -+ if (gr_check_user_change(ruid, euid, -1))
32879 -+ return -EPERM;
32880 -+
32881 - if (ruid != (uid_t) -1) {
32882 - if (ruid != current->uid && set_user(ruid, euid != current->euid) < 0)
32883 - return -EAGAIN;
32884 -@@ -766,6 +802,10 @@ asmlinkage long sys_setresgid(gid_t rgid
32885 - (sgid != current->egid) && (sgid != current->sgid))
32886 - return -EPERM;
32887 - }
32888 -+
32889 -+ if (gr_check_group_change(rgid, egid, -1))
32890 -+ return -EPERM;
32891 -+
32892 - if (egid != (gid_t) -1) {
32893 - if (egid != current->egid) {
32894 - set_dumpable(current->mm, suid_dumpable);
32895 -@@ -774,8 +814,10 @@ asmlinkage long sys_setresgid(gid_t rgid
32896 - current->egid = egid;
32897 - }
32898 - current->fsgid = current->egid;
32899 -- if (rgid != (gid_t) -1)
32900 -+ if (rgid != (gid_t) -1) {
32901 -+ gr_set_role_label(current, current->uid, rgid);
32902 - current->gid = rgid;
32903 -+ }
32904 - if (sgid != (gid_t) -1)
32905 - current->sgid = sgid;
32906 -
32907 -@@ -810,6 +852,9 @@ asmlinkage long sys_setfsuid(uid_t uid)
32908 - if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS))
32909 - return old_fsuid;
32910 -
32911 -+ if (gr_check_user_change(-1, -1, uid))
32912 -+ return old_fsuid;
32913 -+
32914 - if (uid == current->uid || uid == current->euid ||
32915 - uid == current->suid || uid == current->fsuid ||
32916 - capable(CAP_SETUID)) {
32917 -@@ -842,6 +887,9 @@ asmlinkage long sys_setfsgid(gid_t gid)
32918 - if (gid == current->gid || gid == current->egid ||
32919 - gid == current->sgid || gid == current->fsgid ||
32920 - capable(CAP_SETGID)) {
32921 -+ if (gr_check_group_change(-1, -1, gid))
32922 -+ return old_fsgid;
32923 -+
32924 - if (gid != old_fsgid) {
32925 - set_dumpable(current->mm, suid_dumpable);
32926 - smp_wmb();
32927 -@@ -923,7 +971,10 @@ asmlinkage long sys_setpgid(pid_t pid, p
32928 - write_lock_irq(&tasklist_lock);
32929 -
32930 - err = -ESRCH;
32931 -- p = find_task_by_vpid(pid);
32932 -+ /* grsec: replaced find_task_by_vpid with equivalent call which
32933 -+ lacks the chroot restriction
32934 -+ */
32935 -+ p = pid_task(find_pid_ns(pid, current->nsproxy->pid_ns), PIDTYPE_PID);
32936 - if (!p)
32937 - goto out;
32938 -
32939 -@@ -1655,7 +1706,7 @@ asmlinkage long sys_prctl(int option, un
32940 - error = get_dumpable(current->mm);
32941 - break;
32942 - case PR_SET_DUMPABLE:
32943 -- if (arg2 < 0 || arg2 > 1) {
32944 -+ if (arg2 > 1) {
32945 - error = -EINVAL;
32946 - break;
32947 - }
32948 -diff -urNp linux-2.6.27.6/kernel/sysctl.c linux-2.6.27.6/kernel/sysctl.c
32949 ---- linux-2.6.27.6/kernel/sysctl.c 2008-11-07 12:55:34.000000000 -0500
32950 -+++ linux-2.6.27.6/kernel/sysctl.c 2008-11-18 03:38:45.000000000 -0500
32951 -@@ -61,6 +61,13 @@
32952 - static int deprecated_sysctl_warning(struct __sysctl_args *args);
32953 -
32954 - #if defined(CONFIG_SYSCTL)
32955 -+#include <linux/grsecurity.h>
32956 -+#include <linux/grinternal.h>
32957 -+
32958 -+extern __u32 gr_handle_sysctl(const ctl_table *table, const int op);
32959 -+extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
32960 -+ const int op);
32961 -+extern int gr_handle_chroot_sysctl(const int op);
32962 -
32963 - /* External variables not in a header file. */
32964 - extern int C_A_D;
32965 -@@ -155,6 +162,7 @@ static int proc_do_cad_pid(struct ctl_ta
32966 - static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp,
32967 - void __user *buffer, size_t *lenp, loff_t *ppos);
32968 - #endif
32969 -+extern ctl_table grsecurity_table[];
32970 -
32971 - static struct ctl_table root_table[];
32972 - static struct ctl_table_root sysctl_table_root;
32973 -@@ -184,6 +192,21 @@ extern struct ctl_table inotify_table[];
32974 - int sysctl_legacy_va_layout;
32975 - #endif
32976 -
32977 -+#ifdef CONFIG_PAX_SOFTMODE
32978 -+static ctl_table pax_table[] = {
32979 -+ {
32980 -+ .ctl_name = CTL_UNNUMBERED,
32981 -+ .procname = "softmode",
32982 -+ .data = &pax_softmode,
32983 -+ .maxlen = sizeof(unsigned int),
32984 -+ .mode = 0600,
32985 -+ .proc_handler = &proc_dointvec,
32986 -+ },
32987 -+
32988 -+ { .ctl_name = 0 }
32989 -+};
32990 -+#endif
32991 -+
32992 - extern int prove_locking;
32993 - extern int lock_stat;
32994 -
32995 -@@ -220,6 +243,7 @@ static struct ctl_table root_table[] = {
32996 - .mode = 0555,
32997 - .child = dev_table,
32998 - },
32999 -+
33000 - /*
33001 - * NOTE: do not add new entries to this table unless you have read
33002 - * Documentation/sysctl/ctl_unnumbered.txt
33003 -@@ -847,6 +871,25 @@ static struct ctl_table kern_table[] = {
33004 - .proc_handler = &proc_dointvec,
33005 - },
33006 - #endif
33007 -+
33008 -+#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
33009 -+ {
33010 -+ .ctl_name = CTL_UNNUMBERED,
33011 -+ .procname = "grsecurity",
33012 -+ .mode = 0500,
33013 -+ .child = grsecurity_table,
33014 -+ },
33015 -+#endif
33016 -+
33017 -+#ifdef CONFIG_PAX_SOFTMODE
33018 -+ {
33019 -+ .ctl_name = CTL_UNNUMBERED,
33020 -+ .procname = "pax",
33021 -+ .mode = 0500,
33022 -+ .child = pax_table,
33023 -+ },
33024 -+#endif
33025 -+
33026 - /*
33027 - * NOTE: do not add new entries to this table unless you have read
33028 - * Documentation/sysctl/ctl_unnumbered.txt
33029 -@@ -1176,6 +1219,7 @@ static struct ctl_table vm_table[] = {
33030 - .extra2 = &one,
33031 - },
33032 - #endif
33033 -+
33034 - /*
33035 - * NOTE: do not add new entries to this table unless you have read
33036 - * Documentation/sysctl/ctl_unnumbered.txt
33037 -@@ -1543,6 +1587,8 @@ static int do_sysctl_strategy(struct ctl
33038 - return 0;
33039 - }
33040 -
33041 -+static int sysctl_perm_nochk(struct ctl_table_root *root, struct ctl_table *table, int op);
33042 -+
33043 - static int parse_table(int __user *name, int nlen,
33044 - void __user *oldval, size_t __user *oldlenp,
33045 - void __user *newval, size_t newlen,
33046 -@@ -1561,7 +1607,7 @@ repeat:
33047 - if (n == table->ctl_name) {
33048 - int error;
33049 - if (table->child) {
33050 -- if (sysctl_perm(root, table, MAY_EXEC))
33051 -+ if (sysctl_perm_nochk(root, table, MAY_EXEC))
33052 - return -EPERM;
33053 - name++;
33054 - nlen--;
33055 -@@ -1658,6 +1704,33 @@ int sysctl_perm(struct ctl_table_root *r
33056 - return test_perm(mode, op);
33057 - }
33058 -
33059 -+int sysctl_perm_nochk(struct ctl_table_root *root, struct ctl_table *table, int op)
33060 -+{
33061 -+ int error;
33062 -+ int mode;
33063 -+
33064 -+ if (table->parent != NULL && table->parent->procname != NULL &&
33065 -+ table->procname != NULL &&
33066 -+ gr_handle_sysctl_mod(table->parent->procname, table->procname, op))
33067 -+ return -EACCES;
33068 -+ if (gr_handle_chroot_sysctl(op))
33069 -+ return -EACCES;
33070 -+ error = gr_handle_sysctl(table, op);
33071 -+ if (error)
33072 -+ return error;
33073 -+
33074 -+ error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
33075 -+ if (error)
33076 -+ return error;
33077 -+
33078 -+ if (root->permissions)
33079 -+ mode = root->permissions(root, current->nsproxy, table);
33080 -+ else
33081 -+ mode = table->mode;
33082 -+
33083 -+ return test_perm(mode, op);
33084 -+}
33085 -+
33086 - static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table)
33087 - {
33088 - for (; table->ctl_name || table->procname; table++) {
33089 -diff -urNp linux-2.6.27.6/kernel/time/tick-broadcast.c linux-2.6.27.6/kernel/time/tick-broadcast.c
33090 ---- linux-2.6.27.6/kernel/time/tick-broadcast.c 2008-11-07 12:55:34.000000000 -0500
33091 -+++ linux-2.6.27.6/kernel/time/tick-broadcast.c 2008-11-18 03:38:45.000000000 -0500
33092 -@@ -114,7 +114,7 @@ int tick_device_uses_broadcast(struct cl
33093 - * then clear the broadcast bit.
33094 - */
33095 - if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) {
33096 -- int cpu = smp_processor_id();
33097 -+ cpu = smp_processor_id();
33098 -
33099 - cpu_clear(cpu, tick_broadcast_mask);
33100 - tick_broadcast_clear_oneshot(cpu);
33101 -diff -urNp linux-2.6.27.6/kernel/time.c linux-2.6.27.6/kernel/time.c
33102 ---- linux-2.6.27.6/kernel/time.c 2008-11-07 12:55:34.000000000 -0500
33103 -+++ linux-2.6.27.6/kernel/time.c 2008-11-18 03:38:45.000000000 -0500
33104 -@@ -37,6 +37,7 @@
33105 - #include <linux/fs.h>
33106 - #include <linux/slab.h>
33107 - #include <linux/math64.h>
33108 -+#include <linux/grsecurity.h>
33109 -
33110 - #include <asm/uaccess.h>
33111 - #include <asm/unistd.h>
33112 -@@ -92,6 +93,9 @@ asmlinkage long sys_stime(time_t __user
33113 - return err;
33114 -
33115 - do_settimeofday(&tv);
33116 -+
33117 -+ gr_log_timechange();
33118 -+
33119 - return 0;
33120 - }
33121 -
33122 -@@ -200,6 +204,8 @@ asmlinkage long sys_settimeofday(struct
33123 - return -EFAULT;
33124 - }
33125 -
33126 -+ gr_log_timechange();
33127 -+
33128 - return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
33129 - }
33130 -
33131 -@@ -238,7 +244,7 @@ EXPORT_SYMBOL(current_fs_time);
33132 - * Avoid unnecessary multiplications/divisions in the
33133 - * two most common HZ cases:
33134 - */
33135 --unsigned int inline jiffies_to_msecs(const unsigned long j)
33136 -+inline unsigned int jiffies_to_msecs(const unsigned long j)
33137 - {
33138 - #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
33139 - return (MSEC_PER_SEC / HZ) * j;
33140 -@@ -254,7 +260,7 @@ unsigned int inline jiffies_to_msecs(con
33141 - }
33142 - EXPORT_SYMBOL(jiffies_to_msecs);
33143 -
33144 --unsigned int inline jiffies_to_usecs(const unsigned long j)
33145 -+inline unsigned int jiffies_to_usecs(const unsigned long j)
33146 - {
33147 - #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
33148 - return (USEC_PER_SEC / HZ) * j;
33149 -diff -urNp linux-2.6.27.6/kernel/utsname_sysctl.c linux-2.6.27.6/kernel/utsname_sysctl.c
33150 ---- linux-2.6.27.6/kernel/utsname_sysctl.c 2008-11-07 12:55:34.000000000 -0500
33151 -+++ linux-2.6.27.6/kernel/utsname_sysctl.c 2008-11-18 03:38:45.000000000 -0500
33152 -@@ -124,7 +124,7 @@ static struct ctl_table uts_kern_table[]
33153 - .proc_handler = proc_do_uts_string,
33154 - .strategy = sysctl_uts_string,
33155 - },
33156 -- {}
33157 -+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
33158 - };
33159 -
33160 - static struct ctl_table uts_root_table[] = {
33161 -@@ -134,7 +134,7 @@ static struct ctl_table uts_root_table[]
33162 - .mode = 0555,
33163 - .child = uts_kern_table,
33164 - },
33165 -- {}
33166 -+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
33167 - };
33168 -
33169 - static int __init utsname_sysctl_init(void)
33170 -diff -urNp linux-2.6.27.6/lib/radix-tree.c linux-2.6.27.6/lib/radix-tree.c
33171 ---- linux-2.6.27.6/lib/radix-tree.c 2008-11-07 12:55:34.000000000 -0500
33172 -+++ linux-2.6.27.6/lib/radix-tree.c 2008-11-18 03:38:45.000000000 -0500
33173 -@@ -81,7 +81,7 @@ struct radix_tree_preload {
33174 - int nr;
33175 - struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
33176 - };
33177 --DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
33178 -+DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads);
33179 -
33180 - static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
33181 - {
33182 -diff -urNp linux-2.6.27.6/localversion-grsec linux-2.6.27.6/localversion-grsec
33183 ---- linux-2.6.27.6/localversion-grsec 1969-12-31 19:00:00.000000000 -0500
33184 -+++ linux-2.6.27.6/localversion-grsec 2008-11-18 03:38:45.000000000 -0500
33185 -@@ -0,0 +1 @@
33186 -+-grsec
33187 -diff -urNp linux-2.6.27.6/Makefile linux-2.6.27.6/Makefile
33188 ---- linux-2.6.27.6/Makefile 2008-11-17 20:03:30.000000000 -0500
33189 -+++ linux-2.6.27.6/Makefile 2008-11-18 03:38:45.000000000 -0500
33190 -@@ -221,7 +221,7 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH"
33191 -
33192 - HOSTCC = gcc
33193 - HOSTCXX = g++
33194 --HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
33195 -+HOSTCFLAGS = -Wall -W -Wno-unused -Wno-sign-compare -Wstrict-prototypes -O2 -fomit-frame-pointer
33196 - HOSTCXXFLAGS = -O2
33197 -
33198 - # Decide whether to build built-in, modular, or both.
33199 -@@ -619,7 +619,7 @@ export mod_strip_cmd
33200 -
33201 -
33202 - ifeq ($(KBUILD_EXTMOD),)
33203 --core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
33204 -+core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
33205 -
33206 - vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
33207 - $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
33208 -diff -urNp linux-2.6.27.6/mm/filemap.c linux-2.6.27.6/mm/filemap.c
33209 ---- linux-2.6.27.6/mm/filemap.c 2008-11-07 12:55:34.000000000 -0500
33210 -+++ linux-2.6.27.6/mm/filemap.c 2008-11-18 03:38:45.000000000 -0500
33211 -@@ -33,6 +33,7 @@
33212 - #include <linux/cpuset.h>
33213 - #include <linux/hardirq.h> /* for BUG_ON(!in_atomic()) only */
33214 - #include <linux/memcontrol.h>
33215 -+#include <linux/grsecurity.h>
33216 - #include "internal.h"
33217 -
33218 - /*
33219 -@@ -1588,7 +1589,7 @@ int generic_file_mmap(struct file * file
33220 - struct address_space *mapping = file->f_mapping;
33221 -
33222 - if (!mapping->a_ops->readpage)
33223 -- return -ENOEXEC;
33224 -+ return -ENODEV;
33225 - file_accessed(file);
33226 - vma->vm_ops = &generic_file_vm_ops;
33227 - vma->vm_flags |= VM_CAN_NONLINEAR;
33228 -@@ -1949,6 +1950,7 @@ inline int generic_write_checks(struct f
33229 - *pos = i_size_read(inode);
33230 -
33231 - if (limit != RLIM_INFINITY) {
33232 -+ gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
33233 - if (*pos >= limit) {
33234 - send_sig(SIGXFSZ, current, 0);
33235 - return -EFBIG;
33236 -diff -urNp linux-2.6.27.6/mm/fremap.c linux-2.6.27.6/mm/fremap.c
33237 ---- linux-2.6.27.6/mm/fremap.c 2008-11-07 12:55:34.000000000 -0500
33238 -+++ linux-2.6.27.6/mm/fremap.c 2008-11-18 03:38:45.000000000 -0500
33239 -@@ -151,6 +151,13 @@ asmlinkage long sys_remap_file_pages(uns
33240 - retry:
33241 - vma = find_vma(mm, start);
33242 -
33243 -+#ifdef CONFIG_PAX_SEGMEXEC
33244 -+ if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC)) {
33245 -+ up_read(&mm->mmap_sem);
33246 -+ return err;
33247 -+ }
33248 -+#endif
33249 -+
33250 - /*
33251 - * Make sure the vma is shared, that it supports prefaulting,
33252 - * and that the remapped range is valid and fully within
33253 -diff -urNp linux-2.6.27.6/mm/hugetlb.c linux-2.6.27.6/mm/hugetlb.c
33254 ---- linux-2.6.27.6/mm/hugetlb.c 2008-11-17 20:03:30.000000000 -0500
33255 -+++ linux-2.6.27.6/mm/hugetlb.c 2008-11-18 03:38:45.000000000 -0500
33256 -@@ -1832,6 +1832,26 @@ int unmap_ref_private(struct mm_struct *
33257 - return 1;
33258 - }
33259 -
33260 -+#ifdef CONFIG_PAX_SEGMEXEC
33261 -+static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m)
33262 -+{
33263 -+ struct mm_struct *mm = vma->vm_mm;
33264 -+ struct vm_area_struct *vma_m;
33265 -+ unsigned long address_m;
33266 -+ pte_t *ptep_m;
33267 -+
33268 -+ vma_m = pax_find_mirror_vma(vma);
33269 -+ if (!vma_m)
33270 -+ return;
33271 -+
33272 -+ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33273 -+ address_m = address + SEGMEXEC_TASK_SIZE;
33274 -+ ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK);
33275 -+ get_page(page_m);
33276 -+ set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0));
33277 -+}
33278 -+#endif
33279 -+
33280 - static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
33281 - unsigned long address, pte_t *ptep, pte_t pte,
33282 - struct page *pagecache_page)
33283 -@@ -1903,6 +1923,11 @@ retry_avoidcopy:
33284 - huge_ptep_clear_flush(vma, address, ptep);
33285 - set_huge_pte_at(mm, address, ptep,
33286 - make_huge_pte(vma, new_page, 1));
33287 -+
33288 -+#ifdef CONFIG_PAX_SEGMEXEC
33289 -+ pax_mirror_huge_pte(vma, address, new_page);
33290 -+#endif
33291 -+
33292 - /* Make the old page be freed below */
33293 - new_page = old_page;
33294 - }
33295 -@@ -2012,6 +2037,10 @@ retry:
33296 - && (vma->vm_flags & VM_SHARED)));
33297 - set_huge_pte_at(mm, address, ptep, new_pte);
33298 -
33299 -+#ifdef CONFIG_PAX_SEGMEXEC
33300 -+ pax_mirror_huge_pte(vma, address, page);
33301 -+#endif
33302 -+
33303 - if (write_access && !(vma->vm_flags & VM_SHARED)) {
33304 - /* Optimization, do the COW without a second fault */
33305 - ret = hugetlb_cow(mm, vma, address, ptep, new_pte, page);
33306 -@@ -2040,6 +2069,28 @@ int hugetlb_fault(struct mm_struct *mm,
33307 - static DEFINE_MUTEX(hugetlb_instantiation_mutex);
33308 - struct hstate *h = hstate_vma(vma);
33309 -
33310 -+#ifdef CONFIG_PAX_SEGMEXEC
33311 -+ struct vm_area_struct *vma_m;
33312 -+
33313 -+ vma_m = pax_find_mirror_vma(vma);
33314 -+ if (vma_m) {
33315 -+ unsigned long address_m;
33316 -+
33317 -+ if (vma->vm_start > vma_m->vm_start) {
33318 -+ address_m = address;
33319 -+ address -= SEGMEXEC_TASK_SIZE;
33320 -+ vma = vma_m;
33321 -+ h = hstate_vma(vma);
33322 -+ } else
33323 -+ address_m = address + SEGMEXEC_TASK_SIZE;
33324 -+
33325 -+ if (!huge_pte_alloc(mm, address_m, huge_page_size(h)))
33326 -+ return VM_FAULT_OOM;
33327 -+ address_m &= HPAGE_MASK;
33328 -+ unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE, NULL);
33329 -+ }
33330 -+#endif
33331 -+
33332 - ptep = huge_pte_alloc(mm, address, huge_page_size(h));
33333 - if (!ptep)
33334 - return VM_FAULT_OOM;
33335 -diff -urNp linux-2.6.27.6/mm/madvise.c linux-2.6.27.6/mm/madvise.c
33336 ---- linux-2.6.27.6/mm/madvise.c 2008-11-07 12:55:34.000000000 -0500
33337 -+++ linux-2.6.27.6/mm/madvise.c 2008-11-18 03:38:45.000000000 -0500
33338 -@@ -43,6 +43,10 @@ static long madvise_behavior(struct vm_a
33339 - pgoff_t pgoff;
33340 - int new_flags = vma->vm_flags;
33341 -
33342 -+#ifdef CONFIG_PAX_SEGMEXEC
33343 -+ struct vm_area_struct *vma_m;
33344 -+#endif
33345 -+
33346 - switch (behavior) {
33347 - case MADV_NORMAL:
33348 - new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
33349 -@@ -92,6 +96,13 @@ success:
33350 - /*
33351 - * vm_flags is protected by the mmap_sem held in write mode.
33352 - */
33353 -+
33354 -+#ifdef CONFIG_PAX_SEGMEXEC
33355 -+ vma_m = pax_find_mirror_vma(vma);
33356 -+ if (vma_m)
33357 -+ vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT);
33358 -+#endif
33359 -+
33360 - vma->vm_flags = new_flags;
33361 -
33362 - out:
33363 -@@ -236,6 +247,17 @@ madvise_vma(struct vm_area_struct *vma,
33364 -
33365 - case MADV_DONTNEED:
33366 - error = madvise_dontneed(vma, prev, start, end);
33367 -+
33368 -+#ifdef CONFIG_PAX_SEGMEXEC
33369 -+ if (!error) {
33370 -+ struct vm_area_struct *vma_m, *prev_m;
33371 -+
33372 -+ vma_m = pax_find_mirror_vma(vma);
33373 -+ if (vma_m)
33374 -+ error = madvise_dontneed(vma_m, &prev_m, start + SEGMEXEC_TASK_SIZE, end + SEGMEXEC_TASK_SIZE);
33375 -+ }
33376 -+#endif
33377 -+
33378 - break;
33379 -
33380 - default:
33381 -@@ -308,6 +330,16 @@ asmlinkage long sys_madvise(unsigned lon
33382 - if (end < start)
33383 - goto out;
33384 -
33385 -+#ifdef CONFIG_PAX_SEGMEXEC
33386 -+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
33387 -+ if (end > SEGMEXEC_TASK_SIZE)
33388 -+ goto out;
33389 -+ } else
33390 -+#endif
33391 -+
33392 -+ if (end > TASK_SIZE)
33393 -+ goto out;
33394 -+
33395 - error = 0;
33396 - if (end == start)
33397 - goto out;
33398 -diff -urNp linux-2.6.27.6/mm/memory.c linux-2.6.27.6/mm/memory.c
33399 ---- linux-2.6.27.6/mm/memory.c 2008-11-07 12:55:34.000000000 -0500
33400 -+++ linux-2.6.27.6/mm/memory.c 2008-11-18 03:38:45.000000000 -0500
33401 -@@ -52,6 +52,7 @@
33402 - #include <linux/writeback.h>
33403 - #include <linux/memcontrol.h>
33404 - #include <linux/mmu_notifier.h>
33405 -+#include <linux/grsecurity.h>
33406 -
33407 - #include <asm/pgalloc.h>
33408 - #include <asm/uaccess.h>
33409 -@@ -1146,11 +1147,11 @@ int get_user_pages(struct task_struct *t
33410 - vm_flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
33411 - i = 0;
33412 -
33413 -- do {
33414 -+ while (len) {
33415 - struct vm_area_struct *vma;
33416 - unsigned int foll_flags;
33417 -
33418 -- vma = find_extend_vma(mm, start);
33419 -+ vma = find_vma(mm, start);
33420 - if (!vma && in_gate_area(tsk, start)) {
33421 - unsigned long pg = start & PAGE_MASK;
33422 - struct vm_area_struct *gate_vma = get_gate_vma(tsk);
33423 -@@ -1190,7 +1191,7 @@ int get_user_pages(struct task_struct *t
33424 - continue;
33425 - }
33426 -
33427 -- if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP))
33428 -+ if (!vma || start < vma->vm_start || (vma->vm_flags & (VM_IO | VM_PFNMAP))
33429 - || !(vm_flags & vma->vm_flags))
33430 - return i ? : -EFAULT;
33431 -
33432 -@@ -1263,7 +1264,7 @@ int get_user_pages(struct task_struct *t
33433 - start += PAGE_SIZE;
33434 - len--;
33435 - } while (len && start < vma->vm_end);
33436 -- } while (len);
33437 -+ }
33438 - return i;
33439 - }
33440 - EXPORT_SYMBOL(get_user_pages);
33441 -@@ -1741,6 +1742,186 @@ static inline void cow_user_page(struct
33442 - copy_user_highpage(dst, src, va, vma);
33443 - }
33444 -
33445 -+#ifdef CONFIG_PAX_SEGMEXEC
33446 -+static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd)
33447 -+{
33448 -+ struct mm_struct *mm = vma->vm_mm;
33449 -+ spinlock_t *ptl;
33450 -+ pte_t *pte, entry;
33451 -+
33452 -+ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
33453 -+ entry = *pte;
33454 -+ if (!pte_present(entry)) {
33455 -+ if (!pte_none(entry)) {
33456 -+ BUG_ON(pte_file(entry));
33457 -+ free_swap_and_cache(pte_to_swp_entry(entry));
33458 -+ pte_clear_not_present_full(mm, address, pte, 0);
33459 -+ }
33460 -+ } else {
33461 -+ struct page *page;
33462 -+
33463 -+ flush_cache_page(vma, address, pte_pfn(entry));
33464 -+ entry = ptep_clear_flush(vma, address, pte);
33465 -+ BUG_ON(pte_dirty(entry));
33466 -+ page = vm_normal_page(vma, address, entry);
33467 -+ if (page) {
33468 -+ update_hiwater_rss(mm);
33469 -+ if (PageAnon(page))
33470 -+ dec_mm_counter(mm, anon_rss);
33471 -+ else
33472 -+ dec_mm_counter(mm, file_rss);
33473 -+ page_remove_rmap(page, vma);
33474 -+ page_cache_release(page);
33475 -+ }
33476 -+ }
33477 -+ pte_unmap_unlock(pte, ptl);
33478 -+}
33479 -+
33480 -+/* PaX: if vma is mirrored, synchronize the mirror's PTE
33481 -+ *
33482 -+ * the ptl of the lower mapped page is held on entry and is not released on exit
33483 -+ * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
33484 -+ */
33485 -+static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
33486 -+{
33487 -+ struct mm_struct *mm = vma->vm_mm;
33488 -+ unsigned long address_m;
33489 -+ spinlock_t *ptl_m;
33490 -+ struct vm_area_struct *vma_m;
33491 -+ pmd_t *pmd_m;
33492 -+ pte_t *pte_m, entry_m;
33493 -+
33494 -+ BUG_ON(!page_m || !PageAnon(page_m));
33495 -+
33496 -+ vma_m = pax_find_mirror_vma(vma);
33497 -+ if (!vma_m)
33498 -+ return;
33499 -+
33500 -+ BUG_ON(!PageLocked(page_m));
33501 -+ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33502 -+ address_m = address + SEGMEXEC_TASK_SIZE;
33503 -+ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
33504 -+ pte_m = pte_offset_map_nested(pmd_m, address_m);
33505 -+ ptl_m = pte_lockptr(mm, pmd_m);
33506 -+ if (ptl != ptl_m) {
33507 -+ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
33508 -+ if (!pte_none(*pte_m))
33509 -+ goto out;
33510 -+ }
33511 -+
33512 -+ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
33513 -+ page_cache_get(page_m);
33514 -+ page_add_anon_rmap(page_m, vma_m, address_m);
33515 -+ inc_mm_counter(mm, anon_rss);
33516 -+ set_pte_at(mm, address_m, pte_m, entry_m);
33517 -+ update_mmu_cache(vma_m, address_m, entry_m);
33518 -+out:
33519 -+ if (ptl != ptl_m)
33520 -+ spin_unlock(ptl_m);
33521 -+ pte_unmap_nested(pte_m);
33522 -+ unlock_page(page_m);
33523 -+}
33524 -+
33525 -+void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
33526 -+{
33527 -+ struct mm_struct *mm = vma->vm_mm;
33528 -+ unsigned long address_m;
33529 -+ spinlock_t *ptl_m;
33530 -+ struct vm_area_struct *vma_m;
33531 -+ pmd_t *pmd_m;
33532 -+ pte_t *pte_m, entry_m;
33533 -+
33534 -+ BUG_ON(!page_m || PageAnon(page_m));
33535 -+
33536 -+ vma_m = pax_find_mirror_vma(vma);
33537 -+ if (!vma_m)
33538 -+ return;
33539 -+
33540 -+ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33541 -+ address_m = address + SEGMEXEC_TASK_SIZE;
33542 -+ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
33543 -+ pte_m = pte_offset_map_nested(pmd_m, address_m);
33544 -+ ptl_m = pte_lockptr(mm, pmd_m);
33545 -+ if (ptl != ptl_m) {
33546 -+ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
33547 -+ if (!pte_none(*pte_m))
33548 -+ goto out;
33549 -+ }
33550 -+
33551 -+ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
33552 -+ page_cache_get(page_m);
33553 -+ page_add_file_rmap(page_m);
33554 -+ inc_mm_counter(mm, file_rss);
33555 -+ set_pte_at(mm, address_m, pte_m, entry_m);
33556 -+ update_mmu_cache(vma_m, address_m, entry_m);
33557 -+out:
33558 -+ if (ptl != ptl_m)
33559 -+ spin_unlock(ptl_m);
33560 -+ pte_unmap_nested(pte_m);
33561 -+}
33562 -+
33563 -+static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl)
33564 -+{
33565 -+ struct mm_struct *mm = vma->vm_mm;
33566 -+ unsigned long address_m;
33567 -+ spinlock_t *ptl_m;
33568 -+ struct vm_area_struct *vma_m;
33569 -+ pmd_t *pmd_m;
33570 -+ pte_t *pte_m, entry_m;
33571 -+
33572 -+ vma_m = pax_find_mirror_vma(vma);
33573 -+ if (!vma_m)
33574 -+ return;
33575 -+
33576 -+ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33577 -+ address_m = address + SEGMEXEC_TASK_SIZE;
33578 -+ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
33579 -+ pte_m = pte_offset_map_nested(pmd_m, address_m);
33580 -+ ptl_m = pte_lockptr(mm, pmd_m);
33581 -+ if (ptl != ptl_m) {
33582 -+ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
33583 -+ if (!pte_none(*pte_m))
33584 -+ goto out;
33585 -+ }
33586 -+
33587 -+ entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
33588 -+ set_pte_at(mm, address_m, pte_m, entry_m);
33589 -+out:
33590 -+ if (ptl != ptl_m)
33591 -+ spin_unlock(ptl_m);
33592 -+ pte_unmap_nested(pte_m);
33593 -+}
33594 -+
33595 -+static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, pmd_t *pmd, spinlock_t *ptl)
33596 -+{
33597 -+ struct page *page_m;
33598 -+ pte_t entry;
33599 -+
33600 -+ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC))
33601 -+ goto out;
33602 -+
33603 -+ entry = *pte;
33604 -+ page_m = vm_normal_page(vma, address, entry);
33605 -+ if (!page_m)
33606 -+ pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl);
33607 -+ else if (PageAnon(page_m)) {
33608 -+ if (pax_find_mirror_vma(vma)) {
33609 -+ pte_unmap_unlock(pte, ptl);
33610 -+ lock_page(page_m);
33611 -+ pte = pte_offset_map_lock(vma->vm_mm, pmd, address, &ptl);
33612 -+ if (pte_same(entry, *pte))
33613 -+ pax_mirror_anon_pte(vma, address, page_m, ptl);
33614 -+ else
33615 -+ unlock_page(page_m);
33616 -+ }
33617 -+ } else
33618 -+ pax_mirror_file_pte(vma, address, page_m, ptl);
33619 -+
33620 -+out:
33621 -+ pte_unmap_unlock(pte, ptl);
33622 -+}
33623 -+#endif
33624 -+
33625 - /*
33626 - * This routine handles present pages, when users try to write
33627 - * to a shared page. It is done by copying the page to a new address
33628 -@@ -1869,6 +2050,12 @@ gotten:
33629 - */
33630 - page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
33631 - if (likely(pte_same(*page_table, orig_pte))) {
33632 -+
33633 -+#ifdef CONFIG_PAX_SEGMEXEC
33634 -+ if (pax_find_mirror_vma(vma))
33635 -+ BUG_ON(!trylock_page(new_page));
33636 -+#endif
33637 -+
33638 - if (old_page) {
33639 - if (!PageAnon(old_page)) {
33640 - dec_mm_counter(mm, file_rss);
33641 -@@ -1917,6 +2104,10 @@ gotten:
33642 - page_remove_rmap(old_page, vma);
33643 - }
33644 -
33645 -+#ifdef CONFIG_PAX_SEGMEXEC
33646 -+ pax_mirror_anon_pte(vma, address, new_page, ptl);
33647 -+#endif
33648 -+
33649 - /* Free the old page.. */
33650 - new_page = old_page;
33651 - ret |= VM_FAULT_WRITE;
33652 -@@ -2176,6 +2367,7 @@ int vmtruncate(struct inode * inode, lof
33653 - unsigned long limit;
33654 -
33655 - limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
33656 -+ gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
33657 - if (limit != RLIM_INFINITY && offset > limit)
33658 - goto out_sig;
33659 - if (offset > inode->i_sb->s_maxbytes)
33660 -@@ -2326,6 +2518,11 @@ static int do_swap_page(struct mm_struct
33661 - swap_free(entry);
33662 - if (vm_swap_full())
33663 - remove_exclusive_swap_page(page);
33664 -+
33665 -+#ifdef CONFIG_PAX_SEGMEXEC
33666 -+ if (write_access || !pax_find_mirror_vma(vma))
33667 -+#endif
33668 -+
33669 - unlock_page(page);
33670 -
33671 - if (write_access) {
33672 -@@ -2337,6 +2534,11 @@ static int do_swap_page(struct mm_struct
33673 -
33674 - /* No need to invalidate - it was non-present before */
33675 - update_mmu_cache(vma, address, pte);
33676 -+
33677 -+#ifdef CONFIG_PAX_SEGMEXEC
33678 -+ pax_mirror_anon_pte(vma, address, page, ptl);
33679 -+#endif
33680 -+
33681 - unlock:
33682 - pte_unmap_unlock(page_table, ptl);
33683 - out:
33684 -@@ -2381,6 +2583,12 @@ static int do_anonymous_page(struct mm_s
33685 - page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
33686 - if (!pte_none(*page_table))
33687 - goto release;
33688 -+
33689 -+#ifdef CONFIG_PAX_SEGMEXEC
33690 -+ if (pax_find_mirror_vma(vma))
33691 -+ BUG_ON(!trylock_page(page));
33692 -+#endif
33693 -+
33694 - inc_mm_counter(mm, anon_rss);
33695 - lru_cache_add_active(page);
33696 - page_add_new_anon_rmap(page, vma, address);
33697 -@@ -2388,6 +2596,11 @@ static int do_anonymous_page(struct mm_s
33698 -
33699 - /* No need to invalidate - it was non-present before */
33700 - update_mmu_cache(vma, address, entry);
33701 -+
33702 -+#ifdef CONFIG_PAX_SEGMEXEC
33703 -+ pax_mirror_anon_pte(vma, address, page, ptl);
33704 -+#endif
33705 -+
33706 - unlock:
33707 - pte_unmap_unlock(page_table, ptl);
33708 - return 0;
33709 -@@ -2516,6 +2729,12 @@ static int __do_fault(struct mm_struct *
33710 - */
33711 - /* Only go through if we didn't race with anybody else... */
33712 - if (likely(pte_same(*page_table, orig_pte))) {
33713 -+
33714 -+#ifdef CONFIG_PAX_SEGMEXEC
33715 -+ if (anon && pax_find_mirror_vma(vma))
33716 -+ BUG_ON(!trylock_page(page));
33717 -+#endif
33718 -+
33719 - flush_icache_page(vma, page);
33720 - entry = mk_pte(page, vma->vm_page_prot);
33721 - if (flags & FAULT_FLAG_WRITE)
33722 -@@ -2536,6 +2755,14 @@ static int __do_fault(struct mm_struct *
33723 -
33724 - /* no need to invalidate: a not-present page won't be cached */
33725 - update_mmu_cache(vma, address, entry);
33726 -+
33727 -+#ifdef CONFIG_PAX_SEGMEXEC
33728 -+ if (anon)
33729 -+ pax_mirror_anon_pte(vma, address, page, ptl);
33730 -+ else
33731 -+ pax_mirror_file_pte(vma, address, page, ptl);
33732 -+#endif
33733 -+
33734 - } else {
33735 - mem_cgroup_uncharge_page(page);
33736 - if (anon)
33737 -@@ -2668,6 +2895,12 @@ static inline int handle_pte_fault(struc
33738 - if (write_access)
33739 - flush_tlb_page(vma, address);
33740 - }
33741 -+
33742 -+#ifdef CONFIG_PAX_SEGMEXEC
33743 -+ pax_mirror_pte(vma, address, pte, pmd, ptl);
33744 -+ return 0;
33745 -+#endif
33746 -+
33747 - unlock:
33748 - pte_unmap_unlock(pte, ptl);
33749 - return 0;
33750 -@@ -2684,6 +2917,10 @@ int handle_mm_fault(struct mm_struct *mm
33751 - pmd_t *pmd;
33752 - pte_t *pte;
33753 -
33754 -+#ifdef CONFIG_PAX_SEGMEXEC
33755 -+ struct vm_area_struct *vma_m;
33756 -+#endif
33757 -+
33758 - __set_current_state(TASK_RUNNING);
33759 -
33760 - count_vm_event(PGFAULT);
33761 -@@ -2691,6 +2928,34 @@ int handle_mm_fault(struct mm_struct *mm
33762 - if (unlikely(is_vm_hugetlb_page(vma)))
33763 - return hugetlb_fault(mm, vma, address, write_access);
33764 -
33765 -+#ifdef CONFIG_PAX_SEGMEXEC
33766 -+ vma_m = pax_find_mirror_vma(vma);
33767 -+ if (vma_m) {
33768 -+ unsigned long address_m;
33769 -+ pgd_t *pgd_m;
33770 -+ pud_t *pud_m;
33771 -+ pmd_t *pmd_m;
33772 -+
33773 -+ if (vma->vm_start > vma_m->vm_start) {
33774 -+ address_m = address;
33775 -+ address -= SEGMEXEC_TASK_SIZE;
33776 -+ vma = vma_m;
33777 -+ } else
33778 -+ address_m = address + SEGMEXEC_TASK_SIZE;
33779 -+
33780 -+ pgd_m = pgd_offset(mm, address_m);
33781 -+ pud_m = pud_alloc(mm, pgd_m, address_m);
33782 -+ if (!pud_m)
33783 -+ return VM_FAULT_OOM;
33784 -+ pmd_m = pmd_alloc(mm, pud_m, address_m);
33785 -+ if (!pmd_m)
33786 -+ return VM_FAULT_OOM;
33787 -+ if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
33788 -+ return VM_FAULT_OOM;
33789 -+ pax_unmap_mirror_pte(vma_m, address_m, pmd_m);
33790 -+ }
33791 -+#endif
33792 -+
33793 - pgd = pgd_offset(mm, address);
33794 - pud = pud_alloc(mm, pgd, address);
33795 - if (!pud)
33796 -@@ -2798,7 +3063,7 @@ static int __init gate_vma_init(void)
33797 - gate_vma.vm_start = FIXADDR_USER_START;
33798 - gate_vma.vm_end = FIXADDR_USER_END;
33799 - gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
33800 -- gate_vma.vm_page_prot = __P101;
33801 -+ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
33802 - /*
33803 - * Make sure the vDSO gets into every core dump.
33804 - * Dumping its contents makes post-mortem fully interpretable later
33805 -diff -urNp linux-2.6.27.6/mm/mempolicy.c linux-2.6.27.6/mm/mempolicy.c
33806 ---- linux-2.6.27.6/mm/mempolicy.c 2008-11-07 12:55:34.000000000 -0500
33807 -+++ linux-2.6.27.6/mm/mempolicy.c 2008-11-18 03:38:45.000000000 -0500
33808 -@@ -555,6 +555,10 @@ static int mbind_range(struct vm_area_st
33809 - struct vm_area_struct *next;
33810 - int err;
33811 -
33812 -+#ifdef CONFIG_PAX_SEGMEXEC
33813 -+ struct vm_area_struct *vma_m;
33814 -+#endif
33815 -+
33816 - err = 0;
33817 - for (; vma && vma->vm_start < end; vma = next) {
33818 - next = vma->vm_next;
33819 -@@ -566,6 +570,16 @@ static int mbind_range(struct vm_area_st
33820 - err = policy_vma(vma, new);
33821 - if (err)
33822 - break;
33823 -+
33824 -+#ifdef CONFIG_PAX_SEGMEXEC
33825 -+ vma_m = pax_find_mirror_vma(vma);
33826 -+ if (vma_m) {
33827 -+ err = policy_vma(vma_m, new);
33828 -+ if (err)
33829 -+ break;
33830 -+ }
33831 -+#endif
33832 -+
33833 - }
33834 - return err;
33835 - }
33836 -@@ -951,6 +965,17 @@ static long do_mbind(unsigned long start
33837 -
33838 - if (end < start)
33839 - return -EINVAL;
33840 -+
33841 -+#ifdef CONFIG_PAX_SEGMEXEC
33842 -+ if (mm->pax_flags & MF_PAX_SEGMEXEC) {
33843 -+ if (end > SEGMEXEC_TASK_SIZE)
33844 -+ return -EINVAL;
33845 -+ } else
33846 -+#endif
33847 -+
33848 -+ if (end > TASK_SIZE)
33849 -+ return -EINVAL;
33850 -+
33851 - if (end == start)
33852 - return 0;
33853 -
33854 -diff -urNp linux-2.6.27.6/mm/mlock.c linux-2.6.27.6/mm/mlock.c
33855 ---- linux-2.6.27.6/mm/mlock.c 2008-11-07 12:55:34.000000000 -0500
33856 -+++ linux-2.6.27.6/mm/mlock.c 2008-11-18 03:38:45.000000000 -0500
33857 -@@ -12,6 +12,7 @@
33858 - #include <linux/syscalls.h>
33859 - #include <linux/sched.h>
33860 - #include <linux/module.h>
33861 -+#include <linux/grsecurity.h>
33862 -
33863 - int can_do_mlock(void)
33864 - {
33865 -@@ -93,6 +94,17 @@ static int do_mlock(unsigned long start,
33866 - return -EINVAL;
33867 - if (end == start)
33868 - return 0;
33869 -+
33870 -+#ifdef CONFIG_PAX_SEGMEXEC
33871 -+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
33872 -+ if (end > SEGMEXEC_TASK_SIZE)
33873 -+ return -EINVAL;
33874 -+ } else
33875 -+#endif
33876 -+
33877 -+ if (end > TASK_SIZE)
33878 -+ return -EINVAL;
33879 -+
33880 - vma = find_vma_prev(current->mm, start, &prev);
33881 - if (!vma || vma->vm_start > start)
33882 - return -ENOMEM;
33883 -@@ -150,6 +162,7 @@ asmlinkage long sys_mlock(unsigned long
33884 - lock_limit >>= PAGE_SHIFT;
33885 -
33886 - /* check against resource limits */
33887 -+ gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
33888 - if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
33889 - error = do_mlock(start, len, 1);
33890 - up_write(&current->mm->mmap_sem);
33891 -@@ -171,10 +184,10 @@ asmlinkage long sys_munlock(unsigned lon
33892 - static int do_mlockall(int flags)
33893 - {
33894 - struct vm_area_struct * vma, * prev = NULL;
33895 -- unsigned int def_flags = 0;
33896 -+ unsigned int def_flags = current->mm->def_flags & ~VM_LOCKED;
33897 -
33898 - if (flags & MCL_FUTURE)
33899 -- def_flags = VM_LOCKED;
33900 -+ def_flags |= VM_LOCKED;
33901 - current->mm->def_flags = def_flags;
33902 - if (flags == MCL_FUTURE)
33903 - goto out;
33904 -@@ -182,6 +195,12 @@ static int do_mlockall(int flags)
33905 - for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
33906 - unsigned int newflags;
33907 -
33908 -+#ifdef CONFIG_PAX_SEGMEXEC
33909 -+ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
33910 -+ break;
33911 -+#endif
33912 -+
33913 -+ BUG_ON(vma->vm_end > TASK_SIZE);
33914 - newflags = vma->vm_flags | VM_LOCKED;
33915 - if (!(flags & MCL_CURRENT))
33916 - newflags &= ~VM_LOCKED;
33917 -@@ -211,6 +230,7 @@ asmlinkage long sys_mlockall(int flags)
33918 - lock_limit >>= PAGE_SHIFT;
33919 -
33920 - ret = -ENOMEM;
33921 -+ gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
33922 - if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
33923 - capable(CAP_IPC_LOCK))
33924 - ret = do_mlockall(flags);
33925 -diff -urNp linux-2.6.27.6/mm/mmap.c linux-2.6.27.6/mm/mmap.c
33926 ---- linux-2.6.27.6/mm/mmap.c 2008-11-07 12:55:34.000000000 -0500
33927 -+++ linux-2.6.27.6/mm/mmap.c 2008-11-18 03:38:45.000000000 -0500
33928 -@@ -27,6 +27,7 @@
33929 - #include <linux/mempolicy.h>
33930 - #include <linux/rmap.h>
33931 - #include <linux/mmu_notifier.h>
33932 -+#include <linux/grsecurity.h>
33933 -
33934 - #include <asm/uaccess.h>
33935 - #include <asm/cacheflush.h>
33936 -@@ -43,6 +44,16 @@
33937 - #define arch_rebalance_pgtables(addr, len) (addr)
33938 - #endif
33939 -
33940 -+static inline void verify_mm_writelocked(struct mm_struct *mm)
33941 -+{
33942 -+#if defined(CONFIG_DEBUG_VM) || defined(CONFIG_PAX)
33943 -+ if (unlikely(down_read_trylock(&mm->mmap_sem))) {
33944 -+ up_read(&mm->mmap_sem);
33945 -+ BUG();
33946 -+ }
33947 -+#endif
33948 -+}
33949 -+
33950 - static void unmap_region(struct mm_struct *mm,
33951 - struct vm_area_struct *vma, struct vm_area_struct *prev,
33952 - unsigned long start, unsigned long end);
33953 -@@ -68,16 +79,25 @@ static void unmap_region(struct mm_struc
33954 - * x: (no) no x: (no) yes x: (no) yes x: (yes) yes
33955 - *
33956 - */
33957 --pgprot_t protection_map[16] = {
33958 -+pgprot_t protection_map[16] __read_only = {
33959 - __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
33960 - __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
33961 - };
33962 -
33963 - pgprot_t vm_get_page_prot(unsigned long vm_flags)
33964 - {
33965 -- return __pgprot(pgprot_val(protection_map[vm_flags &
33966 -+ pgprot_t prot = __pgprot(pgprot_val(protection_map[vm_flags &
33967 - (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]) |
33968 - pgprot_val(arch_vm_get_page_prot(vm_flags)));
33969 -+
33970 -+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
33971 -+ if (!nx_enabled &&
33972 -+ (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC &&
33973 -+ (vm_flags & (VM_READ | VM_WRITE)))
33974 -+ prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot)))));
33975 -+#endif
33976 -+
33977 -+ return prot;
33978 - }
33979 - EXPORT_SYMBOL(vm_get_page_prot);
33980 -
33981 -@@ -232,6 +252,7 @@ static struct vm_area_struct *remove_vma
33982 - struct vm_area_struct *next = vma->vm_next;
33983 -
33984 - might_sleep();
33985 -+ BUG_ON(vma->vm_mirror);
33986 - if (vma->vm_ops && vma->vm_ops->close)
33987 - vma->vm_ops->close(vma);
33988 - if (vma->vm_file) {
33989 -@@ -268,6 +289,7 @@ asmlinkage unsigned long sys_brk(unsigne
33990 - * not page aligned -Ram Gupta
33991 - */
33992 - rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
33993 -+ gr_learn_resource(current, RLIMIT_DATA, (brk - mm->start_brk) + (mm->end_data - mm->start_data), 1);
33994 - if (rlim < RLIM_INFINITY && (brk - mm->start_brk) +
33995 - (mm->end_data - mm->start_data) > rlim)
33996 - goto out;
33997 -@@ -697,6 +719,12 @@ static int
33998 - can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
33999 - struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
34000 - {
34001 -+
34002 -+#ifdef CONFIG_PAX_SEGMEXEC
34003 -+ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE)
34004 -+ return 0;
34005 -+#endif
34006 -+
34007 - if (is_mergeable_vma(vma, file, vm_flags) &&
34008 - is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
34009 - if (vma->vm_pgoff == vm_pgoff)
34010 -@@ -716,6 +744,12 @@ static int
34011 - can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
34012 - struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
34013 - {
34014 -+
34015 -+#ifdef CONFIG_PAX_SEGMEXEC
34016 -+ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE)
34017 -+ return 0;
34018 -+#endif
34019 -+
34020 - if (is_mergeable_vma(vma, file, vm_flags) &&
34021 - is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
34022 - pgoff_t vm_pglen;
34023 -@@ -758,12 +792,19 @@ can_vma_merge_after(struct vm_area_struc
34024 - struct vm_area_struct *vma_merge(struct mm_struct *mm,
34025 - struct vm_area_struct *prev, unsigned long addr,
34026 - unsigned long end, unsigned long vm_flags,
34027 -- struct anon_vma *anon_vma, struct file *file,
34028 -+ struct anon_vma *anon_vma, struct file *file,
34029 - pgoff_t pgoff, struct mempolicy *policy)
34030 - {
34031 - pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
34032 - struct vm_area_struct *area, *next;
34033 -
34034 -+#ifdef CONFIG_PAX_SEGMEXEC
34035 -+ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE;
34036 -+ struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL;
34037 -+
34038 -+ BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end);
34039 -+#endif
34040 -+
34041 - /*
34042 - * We later require that vma->vm_flags == vm_flags,
34043 - * so this tests vma->vm_flags & VM_SPECIAL, too.
34044 -@@ -779,6 +820,15 @@ struct vm_area_struct *vma_merge(struct
34045 - if (next && next->vm_end == end) /* cases 6, 7, 8 */
34046 - next = next->vm_next;
34047 -
34048 -+#ifdef CONFIG_PAX_SEGMEXEC
34049 -+ if (prev)
34050 -+ prev_m = pax_find_mirror_vma(prev);
34051 -+ if (area)
34052 -+ area_m = pax_find_mirror_vma(area);
34053 -+ if (next)
34054 -+ next_m = pax_find_mirror_vma(next);
34055 -+#endif
34056 -+
34057 - /*
34058 - * Can it merge with the predecessor?
34059 - */
34060 -@@ -798,9 +848,24 @@ struct vm_area_struct *vma_merge(struct
34061 - /* cases 1, 6 */
34062 - vma_adjust(prev, prev->vm_start,
34063 - next->vm_end, prev->vm_pgoff, NULL);
34064 -- } else /* cases 2, 5, 7 */
34065 -+
34066 -+#ifdef CONFIG_PAX_SEGMEXEC
34067 -+ if (prev_m)
34068 -+ vma_adjust(prev_m, prev_m->vm_start,
34069 -+ next_m->vm_end, prev_m->vm_pgoff, NULL);
34070 -+#endif
34071 -+
34072 -+ } else { /* cases 2, 5, 7 */
34073 - vma_adjust(prev, prev->vm_start,
34074 - end, prev->vm_pgoff, NULL);
34075 -+
34076 -+#ifdef CONFIG_PAX_SEGMEXEC
34077 -+ if (prev_m)
34078 -+ vma_adjust(prev_m, prev_m->vm_start,
34079 -+ end_m, prev_m->vm_pgoff, NULL);
34080 -+#endif
34081 -+
34082 -+ }
34083 - return prev;
34084 - }
34085 -
34086 -@@ -811,12 +876,27 @@ struct vm_area_struct *vma_merge(struct
34087 - mpol_equal(policy, vma_policy(next)) &&
34088 - can_vma_merge_before(next, vm_flags,
34089 - anon_vma, file, pgoff+pglen)) {
34090 -- if (prev && addr < prev->vm_end) /* case 4 */
34091 -+ if (prev && addr < prev->vm_end) { /* case 4 */
34092 - vma_adjust(prev, prev->vm_start,
34093 - addr, prev->vm_pgoff, NULL);
34094 -- else /* cases 3, 8 */
34095 -+
34096 -+#ifdef CONFIG_PAX_SEGMEXEC
34097 -+ if (prev_m)
34098 -+ vma_adjust(prev_m, prev_m->vm_start,
34099 -+ addr_m, prev_m->vm_pgoff, NULL);
34100 -+#endif
34101 -+
34102 -+ } else { /* cases 3, 8 */
34103 - vma_adjust(area, addr, next->vm_end,
34104 - next->vm_pgoff - pglen, NULL);
34105 -+
34106 -+#ifdef CONFIG_PAX_SEGMEXEC
34107 -+ if (area_m)
34108 -+ vma_adjust(area_m, addr_m, next_m->vm_end,
34109 -+ next_m->vm_pgoff - pglen, NULL);
34110 -+#endif
34111 -+
34112 -+ }
34113 - return area;
34114 - }
34115 -
34116 -@@ -891,14 +971,11 @@ none:
34117 - void vm_stat_account(struct mm_struct *mm, unsigned long flags,
34118 - struct file *file, long pages)
34119 - {
34120 -- const unsigned long stack_flags
34121 -- = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
34122 --
34123 - if (file) {
34124 - mm->shared_vm += pages;
34125 - if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
34126 - mm->exec_vm += pages;
34127 -- } else if (flags & stack_flags)
34128 -+ } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
34129 - mm->stack_vm += pages;
34130 - if (flags & (VM_RESERVED|VM_IO))
34131 - mm->reserved_vm += pages;
34132 -@@ -926,7 +1003,7 @@ unsigned long do_mmap_pgoff(struct file
34133 - * (the exception is when the underlying filesystem is noexec
34134 - * mounted, in which case we dont add PROT_EXEC.)
34135 - */
34136 -- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
34137 -+ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
34138 - if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
34139 - prot |= PROT_EXEC;
34140 -
34141 -@@ -936,15 +1013,15 @@ unsigned long do_mmap_pgoff(struct file
34142 - if (!(flags & MAP_FIXED))
34143 - addr = round_hint_to_min(addr);
34144 -
34145 -- error = arch_mmap_check(addr, len, flags);
34146 -- if (error)
34147 -- return error;
34148 --
34149 - /* Careful about overflows.. */
34150 - len = PAGE_ALIGN(len);
34151 - if (!len || len > TASK_SIZE)
34152 - return -ENOMEM;
34153 -
34154 -+ error = arch_mmap_check(addr, len, flags);
34155 -+ if (error)
34156 -+ return error;
34157 -+
34158 - /* offset overflow? */
34159 - if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
34160 - return -EOVERFLOW;
34161 -@@ -956,7 +1033,7 @@ unsigned long do_mmap_pgoff(struct file
34162 - /* Obtain the address to map to. we verify (or select) it and ensure
34163 - * that it represents a valid section of the address space.
34164 - */
34165 -- addr = get_unmapped_area(file, addr, len, pgoff, flags);
34166 -+ addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
34167 - if (addr & ~PAGE_MASK)
34168 - return addr;
34169 -
34170 -@@ -967,6 +1044,26 @@ unsigned long do_mmap_pgoff(struct file
34171 - vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
34172 - mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
34173 -
34174 -+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
34175 -+ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
34176 -+
34177 -+#ifdef CONFIG_PAX_MPROTECT
34178 -+ if (mm->pax_flags & MF_PAX_MPROTECT) {
34179 -+ if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
34180 -+ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
34181 -+ else
34182 -+ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
34183 -+ }
34184 -+#endif
34185 -+
34186 -+ }
34187 -+#endif
34188 -+
34189 -+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
34190 -+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file)
34191 -+ vm_flags &= ~VM_PAGEEXEC;
34192 -+#endif
34193 -+
34194 - if (flags & MAP_LOCKED) {
34195 - if (!can_do_mlock())
34196 - return -EPERM;
34197 -@@ -979,6 +1076,7 @@ unsigned long do_mmap_pgoff(struct file
34198 - locked += mm->locked_vm;
34199 - lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
34200 - lock_limit >>= PAGE_SHIFT;
34201 -+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
34202 - if (locked > lock_limit && !capable(CAP_IPC_LOCK))
34203 - return -EAGAIN;
34204 - }
34205 -@@ -1051,6 +1149,9 @@ unsigned long do_mmap_pgoff(struct file
34206 - if (error)
34207 - return error;
34208 -
34209 -+ if (!gr_acl_handle_mmap(file, prot))
34210 -+ return -EACCES;
34211 -+
34212 - return mmap_region(file, addr, len, flags, vm_flags, pgoff,
34213 - accountable);
34214 - }
34215 -@@ -1064,10 +1165,10 @@ EXPORT_SYMBOL(do_mmap_pgoff);
34216 - */
34217 - int vma_wants_writenotify(struct vm_area_struct *vma)
34218 - {
34219 -- unsigned int vm_flags = vma->vm_flags;
34220 -+ unsigned long vm_flags = vma->vm_flags;
34221 -
34222 - /* If it was private or non-writable, the write bit is already clear */
34223 -- if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED)))
34224 -+ if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED))
34225 - return 0;
34226 -
34227 - /* The backer wishes to know when pages are first written to? */
34228 -@@ -1101,14 +1202,24 @@ unsigned long mmap_region(struct file *f
34229 - unsigned long charged = 0;
34230 - struct inode *inode = file ? file->f_path.dentry->d_inode : NULL;
34231 -
34232 -+#ifdef CONFIG_PAX_SEGMEXEC
34233 -+ struct vm_area_struct *vma_m = NULL;
34234 -+#endif
34235 -+
34236 -+ /*
34237 -+ * mm->mmap_sem is required to protect against another thread
34238 -+ * changing the mappings in case we sleep.
34239 -+ */
34240 -+ verify_mm_writelocked(mm);
34241 -+
34242 - /* Clear old maps */
34243 - error = -ENOMEM;
34244 --munmap_back:
34245 - vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
34246 - if (vma && vma->vm_start < addr + len) {
34247 - if (do_munmap(mm, addr, len))
34248 - return -ENOMEM;
34249 -- goto munmap_back;
34250 -+ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
34251 -+ BUG_ON(vma && vma->vm_start < addr + len);
34252 - }
34253 -
34254 - /* Check against address space limit. */
34255 -@@ -1155,6 +1266,16 @@ munmap_back:
34256 - goto unacct_error;
34257 - }
34258 -
34259 -+#ifdef CONFIG_PAX_SEGMEXEC
34260 -+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) {
34261 -+ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
34262 -+ if (!vma_m) {
34263 -+ error = -ENOMEM;
34264 -+ goto free_vma;
34265 -+ }
34266 -+ }
34267 -+#endif
34268 -+
34269 - vma->vm_mm = mm;
34270 - vma->vm_start = addr;
34271 - vma->vm_end = addr + len;
34272 -@@ -1177,6 +1298,19 @@ munmap_back:
34273 - error = file->f_op->mmap(file, vma);
34274 - if (error)
34275 - goto unmap_and_free_vma;
34276 -+
34277 -+#ifdef CONFIG_PAX_SEGMEXEC
34278 -+ if (vma_m && (vm_flags & VM_EXECUTABLE))
34279 -+ added_exe_file_vma(mm);
34280 -+#endif
34281 -+
34282 -+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
34283 -+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) {
34284 -+ vma->vm_flags |= VM_PAGEEXEC;
34285 -+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
34286 -+ }
34287 -+#endif
34288 -+
34289 - if (vm_flags & VM_EXECUTABLE)
34290 - added_exe_file_vma(mm);
34291 - } else if (vm_flags & VM_SHARED) {
34292 -@@ -1209,12 +1343,29 @@ munmap_back:
34293 - vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) {
34294 - mpol_put(vma_policy(vma));
34295 - kmem_cache_free(vm_area_cachep, vma);
34296 -+ vma = NULL;
34297 - fput(file);
34298 -+
34299 -+#ifdef CONFIG_PAX_SEGMEXEC
34300 -+ if (vma_m) {
34301 -+ kmem_cache_free(vm_area_cachep, vma_m);
34302 -+
34303 -+ if (vm_flags & VM_EXECUTABLE)
34304 -+ removed_exe_file_vma(mm);
34305 -+ }
34306 -+#endif
34307 -+
34308 - if (vm_flags & VM_EXECUTABLE)
34309 - removed_exe_file_vma(mm);
34310 - } else {
34311 - vma_link(mm, vma, prev, rb_link, rb_parent);
34312 - file = vma->vm_file;
34313 -+
34314 -+#ifdef CONFIG_PAX_SEGMEXEC
34315 -+ if (vma_m)
34316 -+ pax_mirror_vma(vma_m, vma);
34317 -+#endif
34318 -+
34319 - }
34320 -
34321 - /* Once vma denies write, undo our temporary denial count */
34322 -@@ -1223,6 +1374,7 @@ munmap_back:
34323 - out:
34324 - mm->total_vm += len >> PAGE_SHIFT;
34325 - vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
34326 -+ track_exec_limit(mm, addr, addr + len, vm_flags);
34327 - if (vm_flags & VM_LOCKED) {
34328 - mm->locked_vm += len >> PAGE_SHIFT;
34329 - make_pages_present(addr, addr + len);
34330 -@@ -1241,6 +1393,12 @@ unmap_and_free_vma:
34331 - unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
34332 - charged = 0;
34333 - free_vma:
34334 -+
34335 -+#ifdef CONFIG_PAX_SEGMEXEC
34336 -+ if (vma_m)
34337 -+ kmem_cache_free(vm_area_cachep, vma_m);
34338 -+#endif
34339 -+
34340 - kmem_cache_free(vm_area_cachep, vma);
34341 - unacct_error:
34342 - if (charged)
34343 -@@ -1274,6 +1432,10 @@ arch_get_unmapped_area(struct file *filp
34344 - if (flags & MAP_FIXED)
34345 - return addr;
34346 -
34347 -+#ifdef CONFIG_PAX_RANDMMAP
34348 -+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
34349 -+#endif
34350 -+
34351 - if (addr) {
34352 - addr = PAGE_ALIGN(addr);
34353 - vma = find_vma(mm, addr);
34354 -@@ -1282,10 +1444,10 @@ arch_get_unmapped_area(struct file *filp
34355 - return addr;
34356 - }
34357 - if (len > mm->cached_hole_size) {
34358 -- start_addr = addr = mm->free_area_cache;
34359 -+ start_addr = addr = mm->free_area_cache;
34360 - } else {
34361 -- start_addr = addr = TASK_UNMAPPED_BASE;
34362 -- mm->cached_hole_size = 0;
34363 -+ start_addr = addr = mm->mmap_base;
34364 -+ mm->cached_hole_size = 0;
34365 - }
34366 -
34367 - full_search:
34368 -@@ -1296,9 +1458,8 @@ full_search:
34369 - * Start a new search - just in case we missed
34370 - * some holes.
34371 - */
34372 -- if (start_addr != TASK_UNMAPPED_BASE) {
34373 -- addr = TASK_UNMAPPED_BASE;
34374 -- start_addr = addr;
34375 -+ if (start_addr != mm->mmap_base) {
34376 -+ start_addr = addr = mm->mmap_base;
34377 - mm->cached_hole_size = 0;
34378 - goto full_search;
34379 - }
34380 -@@ -1320,10 +1481,16 @@ full_search:
34381 -
34382 - void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
34383 - {
34384 -+
34385 -+#ifdef CONFIG_PAX_SEGMEXEC
34386 -+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
34387 -+ return;
34388 -+#endif
34389 -+
34390 - /*
34391 - * Is this a new hole at the lowest possible address?
34392 - */
34393 -- if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
34394 -+ if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
34395 - mm->free_area_cache = addr;
34396 - mm->cached_hole_size = ~0UL;
34397 - }
34398 -@@ -1341,7 +1508,7 @@ arch_get_unmapped_area_topdown(struct fi
34399 - {
34400 - struct vm_area_struct *vma;
34401 - struct mm_struct *mm = current->mm;
34402 -- unsigned long addr = addr0;
34403 -+ unsigned long base = mm->mmap_base, addr = addr0;
34404 -
34405 - /* requested length too big for entire address space */
34406 - if (len > TASK_SIZE)
34407 -@@ -1350,6 +1517,10 @@ arch_get_unmapped_area_topdown(struct fi
34408 - if (flags & MAP_FIXED)
34409 - return addr;
34410 -
34411 -+#ifdef CONFIG_PAX_RANDMMAP
34412 -+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
34413 -+#endif
34414 -+
34415 - /* requesting a specific address */
34416 - if (addr) {
34417 - addr = PAGE_ALIGN(addr);
34418 -@@ -1407,13 +1578,21 @@ bottomup:
34419 - * can happen with large stack limits and large mmap()
34420 - * allocations.
34421 - */
34422 -+ mm->mmap_base = TASK_UNMAPPED_BASE;
34423 -+
34424 -+#ifdef CONFIG_PAX_RANDMMAP
34425 -+ if (mm->pax_flags & MF_PAX_RANDMMAP)
34426 -+ mm->mmap_base += mm->delta_mmap;
34427 -+#endif
34428 -+
34429 -+ mm->free_area_cache = mm->mmap_base;
34430 - mm->cached_hole_size = ~0UL;
34431 -- mm->free_area_cache = TASK_UNMAPPED_BASE;
34432 - addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
34433 - /*
34434 - * Restore the topdown base:
34435 - */
34436 -- mm->free_area_cache = mm->mmap_base;
34437 -+ mm->mmap_base = base;
34438 -+ mm->free_area_cache = base;
34439 - mm->cached_hole_size = ~0UL;
34440 -
34441 - return addr;
34442 -@@ -1422,6 +1601,12 @@ bottomup:
34443 -
34444 - void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
34445 - {
34446 -+
34447 -+#ifdef CONFIG_PAX_SEGMEXEC
34448 -+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
34449 -+ return;
34450 -+#endif
34451 -+
34452 - /*
34453 - * Is this a new hole at the highest possible address?
34454 - */
34455 -@@ -1429,8 +1614,10 @@ void arch_unmap_area_topdown(struct mm_s
34456 - mm->free_area_cache = addr;
34457 -
34458 - /* dont allow allocations above current base */
34459 -- if (mm->free_area_cache > mm->mmap_base)
34460 -+ if (mm->free_area_cache > mm->mmap_base) {
34461 - mm->free_area_cache = mm->mmap_base;
34462 -+ mm->cached_hole_size = ~0UL;
34463 -+ }
34464 - }
34465 -
34466 - unsigned long
34467 -@@ -1530,6 +1717,33 @@ out:
34468 - return prev ? prev->vm_next : vma;
34469 - }
34470 -
34471 -+#ifdef CONFIG_PAX_SEGMEXEC
34472 -+struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
34473 -+{
34474 -+ struct vm_area_struct *vma_m;
34475 -+
34476 -+ BUG_ON(!vma || vma->vm_start >= vma->vm_end);
34477 -+ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) {
34478 -+ BUG_ON(vma->vm_mirror);
34479 -+ return NULL;
34480 -+ }
34481 -+ BUG_ON(vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < vma->vm_start - SEGMEXEC_TASK_SIZE - 1);
34482 -+ vma_m = vma->vm_mirror;
34483 -+ BUG_ON(!vma_m || vma_m->vm_mirror != vma);
34484 -+ BUG_ON(vma->vm_file != vma_m->vm_file);
34485 -+ BUG_ON(vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start);
34486 -+ BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff || vma->anon_vma != vma_m->anon_vma);
34487 -+
34488 -+#ifdef CONFIG_PAX_MPROTECT
34489 -+ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED | VM_MAYNOTWRITE));
34490 -+#else
34491 -+ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED));
34492 -+#endif
34493 -+
34494 -+ return vma_m;
34495 -+}
34496 -+#endif
34497 -+
34498 - /*
34499 - * Verify that the stack growth is acceptable and
34500 - * update accounting. This is shared with both the
34501 -@@ -1546,6 +1760,7 @@ static int acct_stack_growth(struct vm_a
34502 - return -ENOMEM;
34503 -
34504 - /* Stack limit test */
34505 -+ gr_learn_resource(current, RLIMIT_STACK, size, 1);
34506 - if (size > rlim[RLIMIT_STACK].rlim_cur)
34507 - return -ENOMEM;
34508 -
34509 -@@ -1555,6 +1770,7 @@ static int acct_stack_growth(struct vm_a
34510 - unsigned long limit;
34511 - locked = mm->locked_vm + grow;
34512 - limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
34513 -+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
34514 - if (locked > limit && !capable(CAP_IPC_LOCK))
34515 - return -ENOMEM;
34516 - }
34517 -@@ -1569,7 +1785,7 @@ static int acct_stack_growth(struct vm_a
34518 - * Overcommit.. This must be the final test, as it will
34519 - * update security statistics.
34520 - */
34521 -- if (security_vm_enough_memory(grow))
34522 -+ if (security_vm_enough_memory_mm(mm, grow))
34523 - return -ENOMEM;
34524 -
34525 - /* Ok, everything looks good - let it rip */
34526 -@@ -1590,35 +1806,40 @@ static inline
34527 - #endif
34528 - int expand_upwards(struct vm_area_struct *vma, unsigned long address)
34529 - {
34530 -- int error;
34531 -+ int error, locknext;
34532 -
34533 - if (!(vma->vm_flags & VM_GROWSUP))
34534 - return -EFAULT;
34535 -
34536 -+ /* Also guard against wrapping around to address 0. */
34537 -+ if (address < PAGE_ALIGN(address+1))
34538 -+ address = PAGE_ALIGN(address+1);
34539 -+ else
34540 -+ return -ENOMEM;
34541 -+
34542 - /*
34543 - * We must make sure the anon_vma is allocated
34544 - * so that the anon_vma locking is not a noop.
34545 - */
34546 - if (unlikely(anon_vma_prepare(vma)))
34547 - return -ENOMEM;
34548 -+ locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN);
34549 -+ if (locknext && unlikely(anon_vma_prepare(vma->vm_next)))
34550 -+ return -ENOMEM;
34551 - anon_vma_lock(vma);
34552 -+ if (locknext)
34553 -+ anon_vma_lock(vma->vm_next);
34554 -
34555 - /*
34556 - * vma->vm_start/vm_end cannot change under us because the caller
34557 - * is required to hold the mmap_sem in read mode. We need the
34558 -- * anon_vma lock to serialize against concurrent expand_stacks.
34559 -- * Also guard against wrapping around to address 0.
34560 -+ * anon_vma locks to serialize against concurrent expand_stacks
34561 -+ * and expand_upwards.
34562 - */
34563 -- if (address < PAGE_ALIGN(address+4))
34564 -- address = PAGE_ALIGN(address+4);
34565 -- else {
34566 -- anon_vma_unlock(vma);
34567 -- return -ENOMEM;
34568 -- }
34569 - error = 0;
34570 -
34571 - /* Somebody else might have raced and expanded it already */
34572 -- if (address > vma->vm_end) {
34573 -+ if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) {
34574 - unsigned long size, grow;
34575 -
34576 - size = address - vma->vm_start;
34577 -@@ -1628,6 +1849,8 @@ int expand_upwards(struct vm_area_struct
34578 - if (!error)
34579 - vma->vm_end = address;
34580 - }
34581 -+ if (locknext)
34582 -+ anon_vma_unlock(vma->vm_next);
34583 - anon_vma_unlock(vma);
34584 - return error;
34585 - }
34586 -@@ -1639,7 +1862,8 @@ int expand_upwards(struct vm_area_struct
34587 - static inline int expand_downwards(struct vm_area_struct *vma,
34588 - unsigned long address)
34589 - {
34590 -- int error;
34591 -+ int error, lockprev = 0;
34592 -+ struct vm_area_struct *prev = NULL;
34593 -
34594 - /*
34595 - * We must make sure the anon_vma is allocated
34596 -@@ -1653,6 +1877,15 @@ static inline int expand_downwards(struc
34597 - if (error)
34598 - return error;
34599 -
34600 -+#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
34601 -+ find_vma_prev(vma->vm_mm, address, &prev);
34602 -+ lockprev = prev && (prev->vm_flags & VM_GROWSUP);
34603 -+#endif
34604 -+ if (lockprev && unlikely(anon_vma_prepare(prev)))
34605 -+ return -ENOMEM;
34606 -+ if (lockprev)
34607 -+ anon_vma_lock(prev);
34608 -+
34609 - anon_vma_lock(vma);
34610 -
34611 - /*
34612 -@@ -1662,9 +1895,15 @@ static inline int expand_downwards(struc
34613 - */
34614 -
34615 - /* Somebody else might have raced and expanded it already */
34616 -- if (address < vma->vm_start) {
34617 -+ if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) {
34618 - unsigned long size, grow;
34619 -
34620 -+#ifdef CONFIG_PAX_SEGMEXEC
34621 -+ struct vm_area_struct *vma_m;
34622 -+
34623 -+ vma_m = pax_find_mirror_vma(vma);
34624 -+#endif
34625 -+
34626 - size = vma->vm_end - address;
34627 - grow = (vma->vm_start - address) >> PAGE_SHIFT;
34628 -
34629 -@@ -1672,9 +1911,20 @@ static inline int expand_downwards(struc
34630 - if (!error) {
34631 - vma->vm_start = address;
34632 - vma->vm_pgoff -= grow;
34633 -+ track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
34634 -+
34635 -+#ifdef CONFIG_PAX_SEGMEXEC
34636 -+ if (vma_m) {
34637 -+ vma_m->vm_start -= grow << PAGE_SHIFT;
34638 -+ vma_m->vm_pgoff -= grow;
34639 -+ }
34640 -+#endif
34641 -+
34642 - }
34643 - }
34644 - anon_vma_unlock(vma);
34645 -+ if (lockprev)
34646 -+ anon_vma_unlock(prev);
34647 - return error;
34648 - }
34649 -
34650 -@@ -1746,6 +1996,13 @@ static void remove_vma_list(struct mm_st
34651 - do {
34652 - long nrpages = vma_pages(vma);
34653 -
34654 -+#ifdef CONFIG_PAX_SEGMEXEC
34655 -+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) {
34656 -+ vma = remove_vma(vma);
34657 -+ continue;
34658 -+ }
34659 -+#endif
34660 -+
34661 - mm->total_vm -= nrpages;
34662 - if (vma->vm_flags & VM_LOCKED)
34663 - mm->locked_vm -= nrpages;
34664 -@@ -1792,6 +2049,16 @@ detach_vmas_to_be_unmapped(struct mm_str
34665 -
34666 - insertion_point = (prev ? &prev->vm_next : &mm->mmap);
34667 - do {
34668 -+
34669 -+#ifdef CONFIG_PAX_SEGMEXEC
34670 -+ if (vma->vm_mirror) {
34671 -+ BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma);
34672 -+ vma->vm_mirror->vm_mirror = NULL;
34673 -+ vma->vm_mirror->vm_flags &= ~VM_EXEC;
34674 -+ vma->vm_mirror = NULL;
34675 -+ }
34676 -+#endif
34677 -+
34678 - rb_erase(&vma->vm_rb, &mm->mm_rb);
34679 - mm->map_count--;
34680 - tail_vma = vma;
34681 -@@ -1811,6 +2078,108 @@ detach_vmas_to_be_unmapped(struct mm_str
34682 - * Split a vma into two pieces at address 'addr', a new vma is allocated
34683 - * either for the first part or the tail.
34684 - */
34685 -+
34686 -+#ifdef CONFIG_PAX_SEGMEXEC
34687 -+int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
34688 -+ unsigned long addr, int new_below)
34689 -+{
34690 -+ struct mempolicy *pol;
34691 -+ struct vm_area_struct *new, *vma_m, *new_m = NULL;
34692 -+ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE;
34693 -+
34694 -+ if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK))
34695 -+ return -EINVAL;
34696 -+
34697 -+ vma_m = pax_find_mirror_vma(vma);
34698 -+ if (vma_m) {
34699 -+ BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE);
34700 -+ if (mm->map_count >= sysctl_max_map_count-1)
34701 -+ return -ENOMEM;
34702 -+ } else if (mm->map_count >= sysctl_max_map_count)
34703 -+ return -ENOMEM;
34704 -+
34705 -+ new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
34706 -+ if (!new)
34707 -+ return -ENOMEM;
34708 -+
34709 -+ if (vma_m) {
34710 -+ new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
34711 -+ if (!new_m) {
34712 -+ kmem_cache_free(vm_area_cachep, new);
34713 -+ return -ENOMEM;
34714 -+ }
34715 -+ }
34716 -+
34717 -+ /* most fields are the same, copy all, and then fixup */
34718 -+ *new = *vma;
34719 -+
34720 -+ if (new_below)
34721 -+ new->vm_end = addr;
34722 -+ else {
34723 -+ new->vm_start = addr;
34724 -+ new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
34725 -+ }
34726 -+
34727 -+ if (vma_m) {
34728 -+ *new_m = *vma_m;
34729 -+ new_m->vm_mirror = new;
34730 -+ new->vm_mirror = new_m;
34731 -+
34732 -+ if (new_below)
34733 -+ new_m->vm_end = addr_m;
34734 -+ else {
34735 -+ new_m->vm_start = addr_m;
34736 -+ new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT);
34737 -+ }
34738 -+ }
34739 -+
34740 -+ pol = mpol_dup(vma_policy(vma));
34741 -+ if (IS_ERR(pol)) {
34742 -+ if (new_m)
34743 -+ kmem_cache_free(vm_area_cachep, new_m);
34744 -+ kmem_cache_free(vm_area_cachep, new);
34745 -+ return PTR_ERR(pol);
34746 -+ }
34747 -+ vma_set_policy(new, pol);
34748 -+
34749 -+ if (new->vm_file) {
34750 -+ get_file(new->vm_file);
34751 -+ if (vma->vm_flags & VM_EXECUTABLE)
34752 -+ added_exe_file_vma(mm);
34753 -+ }
34754 -+
34755 -+ if (new->vm_ops && new->vm_ops->open)
34756 -+ new->vm_ops->open(new);
34757 -+
34758 -+ if (new_below)
34759 -+ vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
34760 -+ ((addr - new->vm_start) >> PAGE_SHIFT), new);
34761 -+ else
34762 -+ vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
34763 -+
34764 -+ if (vma_m) {
34765 -+ mpol_get(pol);
34766 -+ vma_set_policy(new_m, pol);
34767 -+
34768 -+ if (new_m->vm_file) {
34769 -+ get_file(new_m->vm_file);
34770 -+ if (vma_m->vm_flags & VM_EXECUTABLE)
34771 -+ added_exe_file_vma(mm);
34772 -+ }
34773 -+
34774 -+ if (new_m->vm_ops && new_m->vm_ops->open)
34775 -+ new_m->vm_ops->open(new_m);
34776 -+
34777 -+ if (new_below)
34778 -+ vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff +
34779 -+ ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m);
34780 -+ else
34781 -+ vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m);
34782 -+ }
34783 -+
34784 -+ return 0;
34785 -+}
34786 -+#else
34787 - int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
34788 - unsigned long addr, int new_below)
34789 - {
34790 -@@ -1862,17 +2231,37 @@ int split_vma(struct mm_struct * mm, str
34791 -
34792 - return 0;
34793 - }
34794 -+#endif
34795 -
34796 - /* Munmap is split into 2 main parts -- this part which finds
34797 - * what needs doing, and the areas themselves, which do the
34798 - * work. This now handles partial unmappings.
34799 - * Jeremy Fitzhardinge <jeremy@××××.org>
34800 - */
34801 -+#ifdef CONFIG_PAX_SEGMEXEC
34802 - int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
34803 - {
34804 -+ int ret = __do_munmap(mm, start, len);
34805 -+ if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC))
34806 -+ return ret;
34807 -+
34808 -+ return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
34809 -+}
34810 -+
34811 -+int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
34812 -+#else
34813 -+int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
34814 -+#endif
34815 -+{
34816 - unsigned long end;
34817 - struct vm_area_struct *vma, *prev, *last;
34818 -
34819 -+ /*
34820 -+ * mm->mmap_sem is required to protect against another thread
34821 -+ * changing the mappings in case we sleep.
34822 -+ */
34823 -+ verify_mm_writelocked(mm);
34824 -+
34825 - if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
34826 - return -EINVAL;
34827 -
34828 -@@ -1922,6 +2311,8 @@ int do_munmap(struct mm_struct *mm, unsi
34829 - /* Fix up all other VM information */
34830 - remove_vma_list(mm, vma);
34831 -
34832 -+ track_exec_limit(mm, start, end, 0UL);
34833 -+
34834 - return 0;
34835 - }
34836 -
34837 -@@ -1934,22 +2325,18 @@ asmlinkage long sys_munmap(unsigned long
34838 -
34839 - profile_munmap(addr);
34840 -
34841 -+#ifdef CONFIG_PAX_SEGMEXEC
34842 -+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
34843 -+ (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
34844 -+ return -EINVAL;
34845 -+#endif
34846 -+
34847 - down_write(&mm->mmap_sem);
34848 - ret = do_munmap(mm, addr, len);
34849 - up_write(&mm->mmap_sem);
34850 - return ret;
34851 - }
34852 -
34853 --static inline void verify_mm_writelocked(struct mm_struct *mm)
34854 --{
34855 --#ifdef CONFIG_DEBUG_VM
34856 -- if (unlikely(down_read_trylock(&mm->mmap_sem))) {
34857 -- WARN_ON(1);
34858 -- up_read(&mm->mmap_sem);
34859 -- }
34860 --#endif
34861 --}
34862 --
34863 - /*
34864 - * this is really a simplified "do_mmap". it only handles
34865 - * anonymous maps. eventually we may be able to do some
34866 -@@ -1963,6 +2350,11 @@ unsigned long do_brk(unsigned long addr,
34867 - struct rb_node ** rb_link, * rb_parent;
34868 - pgoff_t pgoff = addr >> PAGE_SHIFT;
34869 - int error;
34870 -+ unsigned long charged;
34871 -+
34872 -+#ifdef CONFIG_PAX_SEGMEXEC
34873 -+ struct vm_area_struct *vma_m = NULL;
34874 -+#endif
34875 -
34876 - len = PAGE_ALIGN(len);
34877 - if (!len)
34878 -@@ -1980,19 +2372,34 @@ unsigned long do_brk(unsigned long addr,
34879 -
34880 - flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
34881 -
34882 -+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
34883 -+ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
34884 -+ flags &= ~VM_EXEC;
34885 -+
34886 -+#ifdef CONFIG_PAX_MPROTECT
34887 -+ if (mm->pax_flags & MF_PAX_MPROTECT)
34888 -+ flags &= ~VM_MAYEXEC;
34889 -+#endif
34890 -+
34891 -+ }
34892 -+#endif
34893 -+
34894 - error = arch_mmap_check(addr, len, flags);
34895 - if (error)
34896 - return error;
34897 -
34898 -+ charged = len >> PAGE_SHIFT;
34899 -+
34900 - /*
34901 - * mlock MCL_FUTURE?
34902 - */
34903 - if (mm->def_flags & VM_LOCKED) {
34904 - unsigned long locked, lock_limit;
34905 -- locked = len >> PAGE_SHIFT;
34906 -+ locked = charged;
34907 - locked += mm->locked_vm;
34908 - lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
34909 - lock_limit >>= PAGE_SHIFT;
34910 -+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
34911 - if (locked > lock_limit && !capable(CAP_IPC_LOCK))
34912 - return -EAGAIN;
34913 - }
34914 -@@ -2006,22 +2413,22 @@ unsigned long do_brk(unsigned long addr,
34915 - /*
34916 - * Clear old maps. this also does some error checking for us
34917 - */
34918 -- munmap_back:
34919 - vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
34920 - if (vma && vma->vm_start < addr + len) {
34921 - if (do_munmap(mm, addr, len))
34922 - return -ENOMEM;
34923 -- goto munmap_back;
34924 -+ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
34925 -+ BUG_ON(vma && vma->vm_start < addr + len);
34926 - }
34927 -
34928 - /* Check against address space limits *after* clearing old maps... */
34929 -- if (!may_expand_vm(mm, len >> PAGE_SHIFT))
34930 -+ if (!may_expand_vm(mm, charged))
34931 - return -ENOMEM;
34932 -
34933 - if (mm->map_count > sysctl_max_map_count)
34934 - return -ENOMEM;
34935 -
34936 -- if (security_vm_enough_memory(len >> PAGE_SHIFT))
34937 -+ if (security_vm_enough_memory(charged))
34938 - return -ENOMEM;
34939 -
34940 - /* Can we just expand an old private anonymous mapping? */
34941 -@@ -2034,10 +2441,21 @@ unsigned long do_brk(unsigned long addr,
34942 - */
34943 - vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
34944 - if (!vma) {
34945 -- vm_unacct_memory(len >> PAGE_SHIFT);
34946 -+ vm_unacct_memory(charged);
34947 - return -ENOMEM;
34948 - }
34949 -
34950 -+#ifdef CONFIG_PAX_SEGMEXEC
34951 -+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (flags & VM_EXEC)) {
34952 -+ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
34953 -+ if (!vma_m) {
34954 -+ kmem_cache_free(vm_area_cachep, vma);
34955 -+ vm_unacct_memory(charged);
34956 -+ return -ENOMEM;
34957 -+ }
34958 -+ }
34959 -+#endif
34960 -+
34961 - vma->vm_mm = mm;
34962 - vma->vm_start = addr;
34963 - vma->vm_end = addr + len;
34964 -@@ -2045,12 +2463,19 @@ unsigned long do_brk(unsigned long addr,
34965 - vma->vm_flags = flags;
34966 - vma->vm_page_prot = vm_get_page_prot(flags);
34967 - vma_link(mm, vma, prev, rb_link, rb_parent);
34968 -+
34969 -+#ifdef CONFIG_PAX_SEGMEXEC
34970 -+ if (vma_m)
34971 -+ pax_mirror_vma(vma_m, vma);
34972 -+#endif
34973 -+
34974 - out:
34975 -- mm->total_vm += len >> PAGE_SHIFT;
34976 -+ mm->total_vm += charged;
34977 - if (flags & VM_LOCKED) {
34978 -- mm->locked_vm += len >> PAGE_SHIFT;
34979 -+ mm->locked_vm += charged;
34980 - make_pages_present(addr, addr + len);
34981 - }
34982 -+ track_exec_limit(mm, addr, addr + len, flags);
34983 - return addr;
34984 - }
34985 -
34986 -@@ -2082,8 +2507,10 @@ void exit_mmap(struct mm_struct *mm)
34987 - * Walk the list again, actually closing and freeing it,
34988 - * with preemption enabled, without holding any MM locks.
34989 - */
34990 -- while (vma)
34991 -+ while (vma) {
34992 -+ vma->vm_mirror = NULL;
34993 - vma = remove_vma(vma);
34994 -+ }
34995 -
34996 - BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
34997 - }
34998 -@@ -2097,6 +2524,10 @@ int insert_vm_struct(struct mm_struct *
34999 - struct vm_area_struct * __vma, * prev;
35000 - struct rb_node ** rb_link, * rb_parent;
35001 -
35002 -+#ifdef CONFIG_PAX_SEGMEXEC
35003 -+ struct vm_area_struct *vma_m = NULL;
35004 -+#endif
35005 -+
35006 - /*
35007 - * The vm_pgoff of a purely anonymous vma should be irrelevant
35008 - * until its first write fault, when page's anon_vma and index
35009 -@@ -2119,7 +2550,22 @@ int insert_vm_struct(struct mm_struct *
35010 - if ((vma->vm_flags & VM_ACCOUNT) &&
35011 - security_vm_enough_memory_mm(mm, vma_pages(vma)))
35012 - return -ENOMEM;
35013 -+
35014 -+#ifdef CONFIG_PAX_SEGMEXEC
35015 -+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) {
35016 -+ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
35017 -+ if (!vma_m)
35018 -+ return -ENOMEM;
35019 -+ }
35020 -+#endif
35021 -+
35022 - vma_link(mm, vma, prev, rb_link, rb_parent);
35023 -+
35024 -+#ifdef CONFIG_PAX_SEGMEXEC
35025 -+ if (vma_m)
35026 -+ pax_mirror_vma(vma_m, vma);
35027 -+#endif
35028 -+
35029 - return 0;
35030 - }
35031 -
35032 -@@ -2137,6 +2583,8 @@ struct vm_area_struct *copy_vma(struct v
35033 - struct rb_node **rb_link, *rb_parent;
35034 - struct mempolicy *pol;
35035 -
35036 -+ BUG_ON(vma->vm_mirror);
35037 -+
35038 - /*
35039 - * If anonymous vma has not yet been faulted, update new pgoff
35040 - * to match new location, to increase its chance of merging.
35041 -@@ -2180,6 +2628,35 @@ struct vm_area_struct *copy_vma(struct v
35042 - return new_vma;
35043 - }
35044 -
35045 -+#ifdef CONFIG_PAX_SEGMEXEC
35046 -+void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma)
35047 -+{
35048 -+ struct vm_area_struct *prev_m;
35049 -+ struct rb_node **rb_link_m, *rb_parent_m;
35050 -+ struct mempolicy *pol_m;
35051 -+
35052 -+ BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC));
35053 -+ BUG_ON(vma->vm_mirror || vma_m->vm_mirror);
35054 -+ BUG_ON(!mpol_equal(vma_policy(vma), vma_policy(vma_m)));
35055 -+ *vma_m = *vma;
35056 -+ pol_m = vma_policy(vma_m);
35057 -+ mpol_get(pol_m);
35058 -+ vma_set_policy(vma_m, pol_m);
35059 -+ vma_m->vm_start += SEGMEXEC_TASK_SIZE;
35060 -+ vma_m->vm_end += SEGMEXEC_TASK_SIZE;
35061 -+ vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED);
35062 -+ vma_m->vm_page_prot = vm_get_page_prot(vma_m->vm_flags);
35063 -+ if (vma_m->vm_file)
35064 -+ get_file(vma_m->vm_file);
35065 -+ if (vma_m->vm_ops && vma_m->vm_ops->open)
35066 -+ vma_m->vm_ops->open(vma_m);
35067 -+ find_vma_prepare(vma->vm_mm, vma_m->vm_start, &prev_m, &rb_link_m, &rb_parent_m);
35068 -+ vma_link(vma->vm_mm, vma_m, prev_m, rb_link_m, rb_parent_m);
35069 -+ vma_m->vm_mirror = vma;
35070 -+ vma->vm_mirror = vma_m;
35071 -+}
35072 -+#endif
35073 -+
35074 - /*
35075 - * Return true if the calling process may expand its vm space by the passed
35076 - * number of pages
35077 -@@ -2190,7 +2667,7 @@ int may_expand_vm(struct mm_struct *mm,
35078 - unsigned long lim;
35079 -
35080 - lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
35081 --
35082 -+ gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
35083 - if (cur + npages > lim)
35084 - return 0;
35085 - return 1;
35086 -@@ -2259,6 +2736,15 @@ int install_special_mapping(struct mm_st
35087 - vma->vm_start = addr;
35088 - vma->vm_end = addr + len;
35089 -
35090 -+#ifdef CONFIG_PAX_MPROTECT
35091 -+ if (mm->pax_flags & MF_PAX_MPROTECT) {
35092 -+ if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC)
35093 -+ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
35094 -+ else
35095 -+ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
35096 -+ }
35097 -+#endif
35098 -+
35099 - vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
35100 - vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
35101 -
35102 -diff -urNp linux-2.6.27.6/mm/mprotect.c linux-2.6.27.6/mm/mprotect.c
35103 ---- linux-2.6.27.6/mm/mprotect.c 2008-11-07 12:55:34.000000000 -0500
35104 -+++ linux-2.6.27.6/mm/mprotect.c 2008-11-18 03:38:45.000000000 -0500
35105 -@@ -22,10 +22,17 @@
35106 - #include <linux/swap.h>
35107 - #include <linux/swapops.h>
35108 - #include <linux/mmu_notifier.h>
35109 -+#include <linux/grsecurity.h>
35110 -+
35111 -+#ifdef CONFIG_PAX_MPROTECT
35112 -+#include <linux/elf.h>
35113 -+#endif
35114 -+
35115 - #include <asm/uaccess.h>
35116 - #include <asm/pgtable.h>
35117 - #include <asm/cacheflush.h>
35118 - #include <asm/tlbflush.h>
35119 -+#include <asm/mmu_context.h>
35120 -
35121 - #ifndef pgprot_modify
35122 - static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
35123 -@@ -133,6 +140,48 @@ static void change_protection(struct vm_
35124 - flush_tlb_range(vma, start, end);
35125 - }
35126 -
35127 -+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
35128 -+/* called while holding the mmap semaphor for writing except stack expansion */
35129 -+void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
35130 -+{
35131 -+ unsigned long oldlimit, newlimit = 0UL;
35132 -+
35133 -+ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || nx_enabled)
35134 -+ return;
35135 -+
35136 -+ spin_lock(&mm->page_table_lock);
35137 -+ oldlimit = mm->context.user_cs_limit;
35138 -+ if ((prot & VM_EXEC) && oldlimit < end)
35139 -+ /* USER_CS limit moved up */
35140 -+ newlimit = end;
35141 -+ else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
35142 -+ /* USER_CS limit moved down */
35143 -+ newlimit = start;
35144 -+
35145 -+ if (newlimit) {
35146 -+ mm->context.user_cs_limit = newlimit;
35147 -+
35148 -+#ifdef CONFIG_SMP
35149 -+ wmb();
35150 -+ cpus_clear(mm->context.cpu_user_cs_mask);
35151 -+ cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
35152 -+#endif
35153 -+
35154 -+ set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
35155 -+ }
35156 -+ spin_unlock(&mm->page_table_lock);
35157 -+ if (newlimit == end) {
35158 -+ struct vm_area_struct *vma = find_vma(mm, oldlimit);
35159 -+
35160 -+ for (; vma && vma->vm_start < end; vma = vma->vm_next)
35161 -+ if (is_vm_hugetlb_page(vma))
35162 -+ hugetlb_change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
35163 -+ else
35164 -+ change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
35165 -+ }
35166 -+}
35167 -+#endif
35168 -+
35169 - int
35170 - mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
35171 - unsigned long start, unsigned long end, unsigned long newflags)
35172 -@@ -145,6 +194,14 @@ mprotect_fixup(struct vm_area_struct *vm
35173 - int error;
35174 - int dirty_accountable = 0;
35175 -
35176 -+#ifdef CONFIG_PAX_SEGMEXEC
35177 -+ struct vm_area_struct *vma_m = NULL;
35178 -+ unsigned long start_m, end_m;
35179 -+
35180 -+ start_m = start + SEGMEXEC_TASK_SIZE;
35181 -+ end_m = end + SEGMEXEC_TASK_SIZE;
35182 -+#endif
35183 -+
35184 - if (newflags == oldflags) {
35185 - *pprev = vma;
35186 - return 0;
35187 -@@ -165,6 +222,38 @@ mprotect_fixup(struct vm_area_struct *vm
35188 - }
35189 - }
35190 -
35191 -+#ifdef CONFIG_PAX_SEGMEXEC
35192 -+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && ((oldflags ^ newflags) & VM_EXEC)) {
35193 -+ if (start != vma->vm_start) {
35194 -+ error = split_vma(mm, vma, start, 1);
35195 -+ if (error)
35196 -+ goto fail;
35197 -+ BUG_ON(!*pprev || (*pprev)->vm_next == vma);
35198 -+ *pprev = (*pprev)->vm_next;
35199 -+ }
35200 -+
35201 -+ if (end != vma->vm_end) {
35202 -+ error = split_vma(mm, vma, end, 0);
35203 -+ if (error)
35204 -+ goto fail;
35205 -+ }
35206 -+
35207 -+ if (pax_find_mirror_vma(vma)) {
35208 -+ error = __do_munmap(mm, start_m, end_m - start_m);
35209 -+ if (error)
35210 -+ goto fail;
35211 -+ } else {
35212 -+ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
35213 -+ if (!vma_m) {
35214 -+ error = -ENOMEM;
35215 -+ goto fail;
35216 -+ }
35217 -+ vma->vm_flags = newflags;
35218 -+ pax_mirror_vma(vma_m, vma);
35219 -+ }
35220 -+ }
35221 -+#endif
35222 -+
35223 - /*
35224 - * First try to merge with previous and/or next vma.
35225 - */
35226 -@@ -219,6 +308,70 @@ fail:
35227 - return error;
35228 - }
35229 -
35230 -+#ifdef CONFIG_PAX_MPROTECT
35231 -+/* PaX: non-PIC ELF libraries need relocations on their executable segments
35232 -+ * therefore we'll grant them VM_MAYWRITE once during their life.
35233 -+ *
35234 -+ * The checks favour ld-linux.so behaviour which operates on a per ELF segment
35235 -+ * basis because we want to allow the common case and not the special ones.
35236 -+ */
35237 -+static inline void pax_handle_maywrite(struct vm_area_struct *vma, unsigned long start)
35238 -+{
35239 -+ struct elfhdr elf_h;
35240 -+ struct elf_phdr elf_p;
35241 -+ elf_addr_t dyn_offset = 0UL;
35242 -+ elf_dyn dyn;
35243 -+ unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
35244 -+
35245 -+#ifndef CONFIG_PAX_NOELFRELOCS
35246 -+ if ((vma->vm_start != start) ||
35247 -+ !vma->vm_file ||
35248 -+ !(vma->vm_flags & VM_MAYEXEC) ||
35249 -+ (vma->vm_flags & VM_MAYNOTWRITE))
35250 -+#endif
35251 -+
35252 -+ return;
35253 -+
35254 -+ if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) ||
35255 -+ memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
35256 -+
35257 -+#ifdef CONFIG_PAX_ETEXECRELOCS
35258 -+ (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
35259 -+#else
35260 -+ elf_h.e_type != ET_DYN ||
35261 -+#endif
35262 -+
35263 -+ !elf_check_arch(&elf_h) ||
35264 -+ elf_h.e_phentsize != sizeof(struct elf_phdr) ||
35265 -+ elf_h.e_phnum > j)
35266 -+ return;
35267 -+
35268 -+ for (i = 0UL; i < elf_h.e_phnum; i++) {
35269 -+ if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p)))
35270 -+ return;
35271 -+ if (elf_p.p_type == PT_DYNAMIC) {
35272 -+ dyn_offset = elf_p.p_offset;
35273 -+ j = i;
35274 -+ }
35275 -+ }
35276 -+ if (elf_h.e_phnum <= j)
35277 -+ return;
35278 -+
35279 -+ i = 0UL;
35280 -+ do {
35281 -+ if (sizeof(dyn) != kernel_read(vma->vm_file, dyn_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn)))
35282 -+ return;
35283 -+ if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
35284 -+ vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
35285 -+ gr_log_textrel(vma);
35286 -+ return;
35287 -+ }
35288 -+ i++;
35289 -+ } while (dyn.d_tag != DT_NULL);
35290 -+ return;
35291 -+}
35292 -+#endif
35293 -+
35294 - asmlinkage long
35295 - sys_mprotect(unsigned long start, size_t len, unsigned long prot)
35296 - {
35297 -@@ -238,6 +391,17 @@ sys_mprotect(unsigned long start, size_t
35298 - end = start + len;
35299 - if (end <= start)
35300 - return -ENOMEM;
35301 -+
35302 -+#ifdef CONFIG_PAX_SEGMEXEC
35303 -+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
35304 -+ if (end > SEGMEXEC_TASK_SIZE)
35305 -+ return -EINVAL;
35306 -+ } else
35307 -+#endif
35308 -+
35309 -+ if (end > TASK_SIZE)
35310 -+ return -EINVAL;
35311 -+
35312 - if (!arch_validate_prot(prot))
35313 - return -EINVAL;
35314 -
35315 -@@ -245,7 +409,7 @@ sys_mprotect(unsigned long start, size_t
35316 - /*
35317 - * Does the application expect PROT_READ to imply PROT_EXEC:
35318 - */
35319 -- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
35320 -+ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
35321 - prot |= PROT_EXEC;
35322 -
35323 - vm_flags = calc_vm_prot_bits(prot);
35324 -@@ -277,6 +441,16 @@ sys_mprotect(unsigned long start, size_t
35325 - if (start > vma->vm_start)
35326 - prev = vma;
35327 -
35328 -+ if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
35329 -+ error = -EACCES;
35330 -+ goto out;
35331 -+ }
35332 -+
35333 -+#ifdef CONFIG_PAX_MPROTECT
35334 -+ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
35335 -+ pax_handle_maywrite(vma, start);
35336 -+#endif
35337 -+
35338 - for (nstart = start ; ; ) {
35339 - unsigned long newflags;
35340 -
35341 -@@ -290,6 +464,12 @@ sys_mprotect(unsigned long start, size_t
35342 - goto out;
35343 - }
35344 -
35345 -+#ifdef CONFIG_PAX_MPROTECT
35346 -+ /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
35347 -+ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
35348 -+ newflags &= ~VM_MAYWRITE;
35349 -+#endif
35350 -+
35351 - error = security_file_mprotect(vma, reqprot, prot);
35352 - if (error)
35353 - goto out;
35354 -@@ -300,6 +480,9 @@ sys_mprotect(unsigned long start, size_t
35355 - error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
35356 - if (error)
35357 - goto out;
35358 -+
35359 -+ track_exec_limit(current->mm, nstart, tmp, vm_flags);
35360 -+
35361 - nstart = tmp;
35362 -
35363 - if (nstart < prev->vm_end)
35364 -diff -urNp linux-2.6.27.6/mm/mremap.c linux-2.6.27.6/mm/mremap.c
35365 ---- linux-2.6.27.6/mm/mremap.c 2008-11-07 12:55:34.000000000 -0500
35366 -+++ linux-2.6.27.6/mm/mremap.c 2008-11-18 03:38:45.000000000 -0500
35367 -@@ -111,6 +111,12 @@ static void move_ptes(struct vm_area_str
35368 - continue;
35369 - pte = ptep_clear_flush(vma, old_addr, old_pte);
35370 - pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
35371 -+
35372 -+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
35373 -+ if (!nx_enabled && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC)
35374 -+ pte = pte_exprotect(pte);
35375 -+#endif
35376 -+
35377 - set_pte_at(mm, new_addr, new_pte, pte);
35378 - }
35379 -
35380 -@@ -260,6 +266,7 @@ unsigned long do_mremap(unsigned long ad
35381 - struct vm_area_struct *vma;
35382 - unsigned long ret = -EINVAL;
35383 - unsigned long charged = 0;
35384 -+ unsigned long pax_task_size = TASK_SIZE;
35385 -
35386 - if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
35387 - goto out;
35388 -@@ -278,6 +285,15 @@ unsigned long do_mremap(unsigned long ad
35389 - if (!new_len)
35390 - goto out;
35391 -
35392 -+#ifdef CONFIG_PAX_SEGMEXEC
35393 -+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
35394 -+ pax_task_size = SEGMEXEC_TASK_SIZE;
35395 -+#endif
35396 -+
35397 -+ if (new_len > pax_task_size || addr > pax_task_size-new_len ||
35398 -+ old_len > pax_task_size || addr > pax_task_size-old_len)
35399 -+ goto out;
35400 -+
35401 - /* new_addr is only valid if MREMAP_FIXED is specified */
35402 - if (flags & MREMAP_FIXED) {
35403 - if (new_addr & ~PAGE_MASK)
35404 -@@ -285,16 +301,13 @@ unsigned long do_mremap(unsigned long ad
35405 - if (!(flags & MREMAP_MAYMOVE))
35406 - goto out;
35407 -
35408 -- if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
35409 -+ if (new_addr > pax_task_size - new_len)
35410 - goto out;
35411 -
35412 - /* Check if the location we're moving into overlaps the
35413 - * old location at all, and fail if it does.
35414 - */
35415 -- if ((new_addr <= addr) && (new_addr+new_len) > addr)
35416 -- goto out;
35417 --
35418 -- if ((addr <= new_addr) && (addr+old_len) > new_addr)
35419 -+ if (addr + old_len > new_addr && new_addr + new_len > addr)
35420 - goto out;
35421 -
35422 - ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
35423 -@@ -332,6 +345,14 @@ unsigned long do_mremap(unsigned long ad
35424 - ret = -EINVAL;
35425 - goto out;
35426 - }
35427 -+
35428 -+#ifdef CONFIG_PAX_SEGMEXEC
35429 -+ if (pax_find_mirror_vma(vma)) {
35430 -+ ret = -EINVAL;
35431 -+ goto out;
35432 -+ }
35433 -+#endif
35434 -+
35435 - /* We can't remap across vm area boundaries */
35436 - if (old_len > vma->vm_end - addr)
35437 - goto out;
35438 -@@ -365,7 +386,7 @@ unsigned long do_mremap(unsigned long ad
35439 - if (old_len == vma->vm_end - addr &&
35440 - !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
35441 - (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
35442 -- unsigned long max_addr = TASK_SIZE;
35443 -+ unsigned long max_addr = pax_task_size;
35444 - if (vma->vm_next)
35445 - max_addr = vma->vm_next->vm_start;
35446 - /* can we just expand the current mapping? */
35447 -@@ -383,6 +404,7 @@ unsigned long do_mremap(unsigned long ad
35448 - addr + new_len);
35449 - }
35450 - ret = addr;
35451 -+ track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
35452 - goto out;
35453 - }
35454 - }
35455 -@@ -393,8 +415,8 @@ unsigned long do_mremap(unsigned long ad
35456 - */
35457 - ret = -ENOMEM;
35458 - if (flags & MREMAP_MAYMOVE) {
35459 -+ unsigned long map_flags = 0;
35460 - if (!(flags & MREMAP_FIXED)) {
35461 -- unsigned long map_flags = 0;
35462 - if (vma->vm_flags & VM_MAYSHARE)
35463 - map_flags |= MAP_SHARED;
35464 -
35465 -@@ -409,7 +431,12 @@ unsigned long do_mremap(unsigned long ad
35466 - if (ret)
35467 - goto out;
35468 - }
35469 -+ map_flags = vma->vm_flags;
35470 - ret = move_vma(vma, addr, old_len, new_len, new_addr);
35471 -+ if (!(ret & ~PAGE_MASK)) {
35472 -+ track_exec_limit(current->mm, addr, addr + old_len, 0UL);
35473 -+ track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
35474 -+ }
35475 - }
35476 - out:
35477 - if (ret & ~PAGE_MASK)
35478 -diff -urNp linux-2.6.27.6/mm/nommu.c linux-2.6.27.6/mm/nommu.c
35479 ---- linux-2.6.27.6/mm/nommu.c 2008-11-07 12:55:34.000000000 -0500
35480 -+++ linux-2.6.27.6/mm/nommu.c 2008-11-18 03:38:45.000000000 -0500
35481 -@@ -437,15 +437,6 @@ struct vm_area_struct *find_vma(struct m
35482 - }
35483 - EXPORT_SYMBOL(find_vma);
35484 -
35485 --/*
35486 -- * find a VMA
35487 -- * - we don't extend stack VMAs under NOMMU conditions
35488 -- */
35489 --struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
35490 --{
35491 -- return find_vma(mm, addr);
35492 --}
35493 --
35494 - int expand_stack(struct vm_area_struct *vma, unsigned long address)
35495 - {
35496 - return -ENOMEM;
35497 -diff -urNp linux-2.6.27.6/mm/page_alloc.c linux-2.6.27.6/mm/page_alloc.c
35498 ---- linux-2.6.27.6/mm/page_alloc.c 2008-11-17 20:03:30.000000000 -0500
35499 -+++ linux-2.6.27.6/mm/page_alloc.c 2008-11-18 03:38:45.000000000 -0500
35500 -@@ -515,9 +515,20 @@ static void free_pages_bulk(struct zone
35501 -
35502 - static void free_one_page(struct zone *zone, struct page *page, int order)
35503 - {
35504 -+
35505 -+#ifdef CONFIG_PAX_MEMORY_SANITIZE
35506 -+ unsigned long index = 1UL << order;
35507 -+#endif
35508 -+
35509 - spin_lock(&zone->lock);
35510 - zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE);
35511 - zone->pages_scanned = 0;
35512 -+
35513 -+#ifdef CONFIG_PAX_MEMORY_SANITIZE
35514 -+ for (; index; --index)
35515 -+ sanitize_highpage(page + index - 1);
35516 -+#endif
35517 -+
35518 - __free_one_page(page, zone, order);
35519 - spin_unlock(&zone->lock);
35520 - }
35521 -@@ -635,8 +646,10 @@ static int prep_new_page(struct page *pa
35522 - arch_alloc_page(page, order);
35523 - kernel_map_pages(page, 1 << order, 1);
35524 -
35525 -+#ifndef CONFIG_PAX_MEMORY_SANITIZE
35526 - if (gfp_flags & __GFP_ZERO)
35527 - prep_zero_page(page, order, gfp_flags);
35528 -+#endif
35529 -
35530 - if (order && (gfp_flags & __GFP_COMP))
35531 - prep_compound_page(page, order);
35532 -@@ -1009,6 +1022,11 @@ static void free_hot_cold_page(struct pa
35533 - list_add(&page->lru, &pcp->list);
35534 - set_page_private(page, get_pageblock_migratetype(page));
35535 - pcp->count++;
35536 -+
35537 -+#ifdef CONFIG_PAX_MEMORY_SANITIZE
35538 -+ sanitize_highpage(page);
35539 -+#endif
35540 -+
35541 - if (pcp->count >= pcp->high) {
35542 - free_pages_bulk(zone, pcp->batch, &pcp->list, 0);
35543 - pcp->count -= pcp->batch;
35544 -diff -urNp linux-2.6.27.6/mm/rmap.c linux-2.6.27.6/mm/rmap.c
35545 ---- linux-2.6.27.6/mm/rmap.c 2008-11-07 12:55:34.000000000 -0500
35546 -+++ linux-2.6.27.6/mm/rmap.c 2008-11-18 03:38:45.000000000 -0500
35547 -@@ -91,6 +91,10 @@ int anon_vma_prepare(struct vm_area_stru
35548 - struct mm_struct *mm = vma->vm_mm;
35549 - struct anon_vma *allocated;
35550 -
35551 -+#ifdef CONFIG_PAX_SEGMEXEC
35552 -+ struct vm_area_struct *vma_m;
35553 -+#endif
35554 -+
35555 - anon_vma = find_mergeable_anon_vma(vma);
35556 - allocated = NULL;
35557 - if (!anon_vma) {
35558 -@@ -104,6 +108,15 @@ int anon_vma_prepare(struct vm_area_stru
35559 - /* page_table_lock to protect against threads */
35560 - spin_lock(&mm->page_table_lock);
35561 - if (likely(!vma->anon_vma)) {
35562 -+
35563 -+#ifdef CONFIG_PAX_SEGMEXEC
35564 -+ vma_m = pax_find_mirror_vma(vma);
35565 -+ if (vma_m) {
35566 -+ vma_m->anon_vma = anon_vma;
35567 -+ __anon_vma_link(vma_m);
35568 -+ }
35569 -+#endif
35570 -+
35571 - vma->anon_vma = anon_vma;
35572 - list_add_tail(&vma->anon_vma_node, &anon_vma->head);
35573 - allocated = NULL;
35574 -diff -urNp linux-2.6.27.6/mm/shmem.c linux-2.6.27.6/mm/shmem.c
35575 ---- linux-2.6.27.6/mm/shmem.c 2008-11-07 12:55:34.000000000 -0500
35576 -+++ linux-2.6.27.6/mm/shmem.c 2008-11-18 03:38:45.000000000 -0500
35577 -@@ -2483,7 +2483,7 @@ static struct file_system_type tmpfs_fs_
35578 - .get_sb = shmem_get_sb,
35579 - .kill_sb = kill_litter_super,
35580 - };
35581 --static struct vfsmount *shm_mnt;
35582 -+struct vfsmount *shm_mnt;
35583 -
35584 - static int __init init_tmpfs(void)
35585 - {
35586 -diff -urNp linux-2.6.27.6/mm/slab.c linux-2.6.27.6/mm/slab.c
35587 ---- linux-2.6.27.6/mm/slab.c 2008-11-07 12:55:34.000000000 -0500
35588 -+++ linux-2.6.27.6/mm/slab.c 2008-11-18 03:38:45.000000000 -0500
35589 -@@ -304,7 +304,7 @@ struct kmem_list3 {
35590 - * Need this for bootstrapping a per node allocator.
35591 - */
35592 - #define NUM_INIT_LISTS (3 * MAX_NUMNODES)
35593 --struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
35594 -+struct kmem_list3 initkmem_list3[NUM_INIT_LISTS];
35595 - #define CACHE_CACHE 0
35596 - #define SIZE_AC MAX_NUMNODES
35597 - #define SIZE_L3 (2 * MAX_NUMNODES)
35598 -@@ -653,14 +653,14 @@ struct cache_names {
35599 - static struct cache_names __initdata cache_names[] = {
35600 - #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
35601 - #include <linux/kmalloc_sizes.h>
35602 -- {NULL,}
35603 -+ {NULL, NULL}
35604 - #undef CACHE
35605 - };
35606 -
35607 - static struct arraycache_init initarray_cache __initdata =
35608 -- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
35609 -+ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
35610 - static struct arraycache_init initarray_generic =
35611 -- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
35612 -+ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
35613 -
35614 - /* internal cache of cache description objs */
35615 - static struct kmem_cache cache_cache = {
35616 -@@ -2996,7 +2996,7 @@ retry:
35617 - * there must be at least one object available for
35618 - * allocation.
35619 - */
35620 -- BUG_ON(slabp->inuse < 0 || slabp->inuse >= cachep->num);
35621 -+ BUG_ON(slabp->inuse >= cachep->num);
35622 -
35623 - while (slabp->inuse < cachep->num && batchcount--) {
35624 - STATS_INC_ALLOCED(cachep);
35625 -diff -urNp linux-2.6.27.6/mm/tiny-shmem.c linux-2.6.27.6/mm/tiny-shmem.c
35626 ---- linux-2.6.27.6/mm/tiny-shmem.c 2008-11-07 12:55:34.000000000 -0500
35627 -+++ linux-2.6.27.6/mm/tiny-shmem.c 2008-11-18 03:38:45.000000000 -0500
35628 -@@ -26,7 +26,7 @@ static struct file_system_type tmpfs_fs_
35629 - .kill_sb = kill_litter_super,
35630 - };
35631 -
35632 --static struct vfsmount *shm_mnt;
35633 -+struct vfsmount *shm_mnt;
35634 -
35635 - static int __init init_tmpfs(void)
35636 - {
35637 -diff -urNp linux-2.6.27.6/mm/util.c linux-2.6.27.6/mm/util.c
35638 ---- linux-2.6.27.6/mm/util.c 2008-11-07 12:55:34.000000000 -0500
35639 -+++ linux-2.6.27.6/mm/util.c 2008-11-18 03:38:45.000000000 -0500
35640 -@@ -167,6 +167,12 @@ EXPORT_SYMBOL(strndup_user);
35641 - void arch_pick_mmap_layout(struct mm_struct *mm)
35642 - {
35643 - mm->mmap_base = TASK_UNMAPPED_BASE;
35644 -+
35645 -+#ifdef CONFIG_PAX_RANDMMAP
35646 -+ if (mm->pax_flags & MF_PAX_RANDMMAP)
35647 -+ mm->mmap_base += mm->delta_mmap;
35648 -+#endif
35649 -+
35650 - mm->get_unmapped_area = arch_get_unmapped_area;
35651 - mm->unmap_area = arch_unmap_area;
35652 - }
35653 -diff -urNp linux-2.6.27.6/mm/vmalloc.c linux-2.6.27.6/mm/vmalloc.c
35654 ---- linux-2.6.27.6/mm/vmalloc.c 2008-11-07 12:55:34.000000000 -0500
35655 -+++ linux-2.6.27.6/mm/vmalloc.c 2008-11-18 03:38:45.000000000 -0500
35656 -@@ -98,19 +98,36 @@ static int vmap_pte_range(pmd_t *pmd, un
35657 - unsigned long end, pgprot_t prot, struct page ***pages)
35658 - {
35659 - pte_t *pte;
35660 -+ int ret = -ENOMEM;
35661 -+
35662 -+#ifdef CONFIG_PAX_KERNEXEC
35663 -+ unsigned long cr0;
35664 -+#endif
35665 -
35666 - pte = pte_alloc_kernel(pmd, addr);
35667 - if (!pte)
35668 - return -ENOMEM;
35669 -+
35670 -+#ifdef CONFIG_PAX_KERNEXEC
35671 -+ pax_open_kernel(cr0);
35672 -+#endif
35673 -+
35674 - do {
35675 - struct page *page = **pages;
35676 - WARN_ON(!pte_none(*pte));
35677 - if (!page)
35678 -- return -ENOMEM;
35679 -+ goto out;
35680 - set_pte_at(&init_mm, addr, pte, mk_pte(page, prot));
35681 - (*pages)++;
35682 - } while (pte++, addr += PAGE_SIZE, addr != end);
35683 -- return 0;
35684 -+ ret = 0;
35685 -+out:
35686 -+
35687 -+#ifdef CONFIG_PAX_KERNEXEC
35688 -+ pax_close_kernel(cr0);
35689 -+#endif
35690 -+
35691 -+ return ret;
35692 - }
35693 -
35694 - static inline int vmap_pmd_range(pud_t *pud, unsigned long addr,
35695 -@@ -215,6 +232,16 @@ __get_vm_area_node(unsigned long size, u
35696 - unsigned long addr;
35697 -
35698 - BUG_ON(in_interrupt());
35699 -+
35700 -+#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
35701 -+ if (flags & VM_KERNEXEC) {
35702 -+ if (start != VMALLOC_START || end != VMALLOC_END)
35703 -+ return NULL;
35704 -+ start = (unsigned long)MODULES_VADDR;
35705 -+ end = (unsigned long)MODULES_END;
35706 -+ }
35707 -+#endif
35708 -+
35709 - if (flags & VM_IOREMAP) {
35710 - int bit = fls(size);
35711 -
35712 -@@ -248,20 +275,15 @@ __get_vm_area_node(unsigned long size, u
35713 - (unsigned long)tmp->addr, align);
35714 - continue;
35715 - }
35716 -- if ((size + addr) < addr)
35717 -- goto out;
35718 - if (size + addr <= (unsigned long)tmp->addr)
35719 -- goto found;
35720 -+ break;
35721 - addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
35722 -- if (addr > end - size)
35723 -- goto out;
35724 - }
35725 - if ((size + addr) < addr)
35726 - goto out;
35727 - if (addr > end - size)
35728 - goto out;
35729 -
35730 --found:
35731 - area->next = *p;
35732 - *p = area;
35733 -
35734 -@@ -466,6 +488,11 @@ void *vmap(struct page **pages, unsigned
35735 - if (count > num_physpages)
35736 - return NULL;
35737 -
35738 -+#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
35739 -+ if (!(pgprot_val(prot) & _PAGE_NX))
35740 -+ flags |= VM_KERNEXEC;
35741 -+#endif
35742 -+
35743 - area = get_vm_area_caller((count << PAGE_SHIFT), flags,
35744 - __builtin_return_address(0));
35745 - if (!area)
35746 -@@ -560,6 +587,13 @@ static void *__vmalloc_node(unsigned lon
35747 - if (!size || (size >> PAGE_SHIFT) > num_physpages)
35748 - return NULL;
35749 -
35750 -+#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
35751 -+ if (!(pgprot_val(prot) & _PAGE_NX))
35752 -+ area = __get_vm_area_node(size, VM_ALLOC | VM_KERNEXEC, VMALLOC_START, VMALLOC_END,
35753 -+ node, gfp_mask, caller);
35754 -+ else
35755 -+#endif
35756 -+
35757 - area = __get_vm_area_node(size, VM_ALLOC, VMALLOC_START, VMALLOC_END,
35758 - node, gfp_mask, caller);
35759 -
35760 -@@ -651,7 +685,7 @@ EXPORT_SYMBOL(vmalloc_node);
35761 -
35762 - void *vmalloc_exec(unsigned long size)
35763 - {
35764 -- return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC);
35765 -+ return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL_EXEC);
35766 - }
35767 -
35768 - #if defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA32)
35769 -diff -urNp linux-2.6.27.6/net/bridge/br_stp_if.c linux-2.6.27.6/net/bridge/br_stp_if.c
35770 ---- linux-2.6.27.6/net/bridge/br_stp_if.c 2008-11-07 12:55:34.000000000 -0500
35771 -+++ linux-2.6.27.6/net/bridge/br_stp_if.c 2008-11-18 03:38:45.000000000 -0500
35772 -@@ -146,7 +146,7 @@ static void br_stp_stop(struct net_bridg
35773 - char *envp[] = { NULL };
35774 -
35775 - if (br->stp_enabled == BR_USER_STP) {
35776 -- r = call_usermodehelper(BR_STP_PROG, argv, envp, 1);
35777 -+ r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
35778 - printk(KERN_INFO "%s: userspace STP stopped, return code %d\n",
35779 - br->dev->name, r);
35780 -
35781 -diff -urNp linux-2.6.27.6/net/core/flow.c linux-2.6.27.6/net/core/flow.c
35782 ---- linux-2.6.27.6/net/core/flow.c 2008-11-07 12:55:34.000000000 -0500
35783 -+++ linux-2.6.27.6/net/core/flow.c 2008-11-18 03:38:45.000000000 -0500
35784 -@@ -39,7 +39,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT(
35785 -
35786 - static u32 flow_hash_shift;
35787 - #define flow_hash_size (1 << flow_hash_shift)
35788 --static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL };
35789 -+static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables);
35790 -
35791 - #define flow_table(cpu) (per_cpu(flow_tables, cpu))
35792 -
35793 -@@ -52,7 +52,7 @@ struct flow_percpu_info {
35794 - u32 hash_rnd;
35795 - int count;
35796 - };
35797 --static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 };
35798 -+static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info);
35799 -
35800 - #define flow_hash_rnd_recalc(cpu) \
35801 - (per_cpu(flow_hash_info, cpu).hash_rnd_recalc)
35802 -@@ -69,7 +69,7 @@ struct flow_flush_info {
35803 - atomic_t cpuleft;
35804 - struct completion completion;
35805 - };
35806 --static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL };
35807 -+static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets);
35808 -
35809 - #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu))
35810 -
35811 -diff -urNp linux-2.6.27.6/net/dccp/ccids/ccid3.c linux-2.6.27.6/net/dccp/ccids/ccid3.c
35812 ---- linux-2.6.27.6/net/dccp/ccids/ccid3.c 2008-11-07 12:55:34.000000000 -0500
35813 -+++ linux-2.6.27.6/net/dccp/ccids/ccid3.c 2008-11-18 03:38:45.000000000 -0500
35814 -@@ -43,7 +43,7 @@
35815 - static int ccid3_debug;
35816 - #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
35817 - #else
35818 --#define ccid3_pr_debug(format, a...)
35819 -+#define ccid3_pr_debug(format, a...) do {} while (0)
35820 - #endif
35821 -
35822 - /*
35823 -diff -urNp linux-2.6.27.6/net/dccp/dccp.h linux-2.6.27.6/net/dccp/dccp.h
35824 ---- linux-2.6.27.6/net/dccp/dccp.h 2008-11-07 12:55:34.000000000 -0500
35825 -+++ linux-2.6.27.6/net/dccp/dccp.h 2008-11-18 03:38:45.000000000 -0500
35826 -@@ -43,8 +43,8 @@ extern int dccp_debug;
35827 - #define dccp_pr_debug(format, a...) DCCP_PR_DEBUG(dccp_debug, format, ##a)
35828 - #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a)
35829 - #else
35830 --#define dccp_pr_debug(format, a...)
35831 --#define dccp_pr_debug_cat(format, a...)
35832 -+#define dccp_pr_debug(format, a...) do {} while (0)
35833 -+#define dccp_pr_debug_cat(format, a...) do {} while (0)
35834 - #endif
35835 -
35836 - extern struct inet_hashinfo dccp_hashinfo;
35837 -diff -urNp linux-2.6.27.6/net/ipv4/inet_connection_sock.c linux-2.6.27.6/net/ipv4/inet_connection_sock.c
35838 ---- linux-2.6.27.6/net/ipv4/inet_connection_sock.c 2008-11-07 12:55:34.000000000 -0500
35839 -+++ linux-2.6.27.6/net/ipv4/inet_connection_sock.c 2008-11-18 03:38:45.000000000 -0500
35840 -@@ -15,6 +15,7 @@
35841 -
35842 - #include <linux/module.h>
35843 - #include <linux/jhash.h>
35844 -+#include <linux/grsecurity.h>
35845 -
35846 - #include <net/inet_connection_sock.h>
35847 - #include <net/inet_hashtables.h>
35848 -diff -urNp linux-2.6.27.6/net/ipv4/inet_hashtables.c linux-2.6.27.6/net/ipv4/inet_hashtables.c
35849 ---- linux-2.6.27.6/net/ipv4/inet_hashtables.c 2008-11-07 12:55:34.000000000 -0500
35850 -+++ linux-2.6.27.6/net/ipv4/inet_hashtables.c 2008-11-18 03:38:45.000000000 -0500
35851 -@@ -18,11 +18,14 @@
35852 - #include <linux/sched.h>
35853 - #include <linux/slab.h>
35854 - #include <linux/wait.h>
35855 -+#include <linux/grsecurity.h>
35856 -
35857 - #include <net/inet_connection_sock.h>
35858 - #include <net/inet_hashtables.h>
35859 - #include <net/ip.h>
35860 -
35861 -+extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
35862 -+
35863 - /*
35864 - * Allocate and initialize a new local port bind bucket.
35865 - * The bindhash mutex for snum's hash chain must be held here.
35866 -@@ -487,6 +490,8 @@ ok:
35867 - }
35868 - spin_unlock(&head->lock);
35869 -
35870 -+ gr_update_task_in_ip_table(current, inet_sk(sk));
35871 -+
35872 - if (tw) {
35873 - inet_twsk_deschedule(tw, death_row);
35874 - inet_twsk_put(tw);
35875 -diff -urNp linux-2.6.27.6/net/ipv4/netfilter/ipt_stealth.c linux-2.6.27.6/net/ipv4/netfilter/ipt_stealth.c
35876 ---- linux-2.6.27.6/net/ipv4/netfilter/ipt_stealth.c 1969-12-31 19:00:00.000000000 -0500
35877 -+++ linux-2.6.27.6/net/ipv4/netfilter/ipt_stealth.c 2008-11-18 03:38:45.000000000 -0500
35878 -@@ -0,0 +1,114 @@
35879 -+/* Kernel module to add stealth support.
35880 -+ *
35881 -+ * Copyright (C) 2002-2006 Brad Spengler <spender@××××××××××.net>
35882 -+ *
35883 -+ */
35884 -+
35885 -+#include <linux/kernel.h>
35886 -+#include <linux/module.h>
35887 -+#include <linux/skbuff.h>
35888 -+#include <linux/net.h>
35889 -+#include <linux/sched.h>
35890 -+#include <linux/inet.h>
35891 -+#include <linux/stddef.h>
35892 -+
35893 -+#include <net/ip.h>
35894 -+#include <net/sock.h>
35895 -+#include <net/tcp.h>
35896 -+#include <net/udp.h>
35897 -+#include <net/route.h>
35898 -+#include <net/inet_common.h>
35899 -+
35900 -+#include <linux/netfilter_ipv4/ip_tables.h>
35901 -+
35902 -+MODULE_LICENSE("GPL");
35903 -+
35904 -+extern struct sock *udp_v4_lookup(struct net *net, u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
35905 -+
35906 -+static bool
35907 -+match(const struct sk_buff *skb,
35908 -+ const struct net_device *in,
35909 -+ const struct net_device *out,
35910 -+ const struct xt_match *match,
35911 -+ const void *matchinfo,
35912 -+ int offset,
35913 -+ unsigned int protoff,
35914 -+ bool *hotdrop)
35915 -+{
35916 -+ struct iphdr *ip = ip_hdr(skb);
35917 -+ struct tcphdr th;
35918 -+ struct udphdr uh;
35919 -+ struct sock *sk = NULL;
35920 -+
35921 -+ if (!ip || offset) return false;
35922 -+
35923 -+ switch(ip->protocol) {
35924 -+ case IPPROTO_TCP:
35925 -+ if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &th, sizeof(th)) < 0) {
35926 -+ *hotdrop = true;
35927 -+ return false;
35928 -+ }
35929 -+ if (!(th.syn && !th.ack)) return false;
35930 -+ sk = inet_lookup_listener(dev_net(skb->dev), &tcp_hashinfo, ip->daddr, th.dest, inet_iif(skb));
35931 -+ break;
35932 -+ case IPPROTO_UDP:
35933 -+ if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &uh, sizeof(uh)) < 0) {
35934 -+ *hotdrop = true;
35935 -+ return false;
35936 -+ }
35937 -+ sk = udp_v4_lookup(dev_net(skb->dev), ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
35938 -+ break;
35939 -+ default:
35940 -+ return false;
35941 -+ }
35942 -+
35943 -+ if(!sk) // port is being listened on, match this
35944 -+ return true;
35945 -+ else {
35946 -+ sock_put(sk);
35947 -+ return false;
35948 -+ }
35949 -+}
35950 -+
35951 -+/* Called when user tries to insert an entry of this type. */
35952 -+static bool
35953 -+checkentry(const char *tablename,
35954 -+ const void *nip,
35955 -+ const struct xt_match *match,
35956 -+ void *matchinfo,
35957 -+ unsigned int hook_mask)
35958 -+{
35959 -+ const struct ipt_ip *ip = (const struct ipt_ip *)nip;
35960 -+
35961 -+ if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
35962 -+ ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
35963 -+ && (hook_mask & (1 << NF_INET_LOCAL_IN)))
35964 -+ return true;
35965 -+
35966 -+ printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
35967 -+
35968 -+ return false;
35969 -+}
35970 -+
35971 -+
35972 -+static struct xt_match stealth_match __read_mostly = {
35973 -+ .name = "stealth",
35974 -+ .family = AF_INET,
35975 -+ .match = match,
35976 -+ .checkentry = checkentry,
35977 -+ .destroy = NULL,
35978 -+ .me = THIS_MODULE
35979 -+};
35980 -+
35981 -+static int __init init(void)
35982 -+{
35983 -+ return xt_register_match(&stealth_match);
35984 -+}
35985 -+
35986 -+static void __exit fini(void)
35987 -+{
35988 -+ xt_unregister_match(&stealth_match);
35989 -+}
35990 -+
35991 -+module_init(init);
35992 -+module_exit(fini);
35993 -diff -urNp linux-2.6.27.6/net/ipv4/netfilter/Kconfig linux-2.6.27.6/net/ipv4/netfilter/Kconfig
35994 ---- linux-2.6.27.6/net/ipv4/netfilter/Kconfig 2008-11-07 12:55:34.000000000 -0500
35995 -+++ linux-2.6.27.6/net/ipv4/netfilter/Kconfig 2008-11-18 03:38:45.000000000 -0500
35996 -@@ -111,6 +111,21 @@ config IP_NF_MATCH_ADDRTYPE
35997 - If you want to compile it as a module, say M here and read
35998 - <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
35999 -
36000 -+config IP_NF_MATCH_STEALTH
36001 -+ tristate "stealth match support"
36002 -+ depends on IP_NF_IPTABLES
36003 -+ help
36004 -+ Enabling this option will drop all syn packets coming to unserved tcp
36005 -+ ports as well as all packets coming to unserved udp ports. If you
36006 -+ are using your system to route any type of packets (ie. via NAT)
36007 -+ you should put this module at the end of your ruleset, since it will
36008 -+ drop packets that aren't going to ports that are listening on your
36009 -+ machine itself, it doesn't take into account that the packet might be
36010 -+ destined for someone on your internal network if you're using NAT for
36011 -+ instance.
36012 -+
36013 -+ To compile it as a module, choose M here. If unsure, say N.
36014 -+
36015 - # `filter', generic and specific targets
36016 - config IP_NF_FILTER
36017 - tristate "Packet filtering"
36018 -@@ -407,4 +422,3 @@ config IP_NF_ARP_MANGLE
36019 - hardware and network addresses.
36020 -
36021 - endmenu
36022 --
36023 -diff -urNp linux-2.6.27.6/net/ipv4/netfilter/Makefile linux-2.6.27.6/net/ipv4/netfilter/Makefile
36024 ---- linux-2.6.27.6/net/ipv4/netfilter/Makefile 2008-11-07 12:55:34.000000000 -0500
36025 -+++ linux-2.6.27.6/net/ipv4/netfilter/Makefile 2008-11-18 03:38:45.000000000 -0500
36026 -@@ -59,6 +59,7 @@ obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) +=
36027 - obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
36028 - obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
36029 - obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
36030 -+obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
36031 - obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
36032 - obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
36033 -
36034 -diff -urNp linux-2.6.27.6/net/ipv4/tcp_ipv4.c linux-2.6.27.6/net/ipv4/tcp_ipv4.c
36035 ---- linux-2.6.27.6/net/ipv4/tcp_ipv4.c 2008-11-07 12:55:34.000000000 -0500
36036 -+++ linux-2.6.27.6/net/ipv4/tcp_ipv4.c 2008-11-18 03:38:45.000000000 -0500
36037 -@@ -59,6 +59,7 @@
36038 - #include <linux/jhash.h>
36039 - #include <linux/init.h>
36040 - #include <linux/times.h>
36041 -+#include <linux/grsecurity.h>
36042 -
36043 - #include <net/net_namespace.h>
36044 - #include <net/icmp.h>
36045 -diff -urNp linux-2.6.27.6/net/ipv4/udp.c linux-2.6.27.6/net/ipv4/udp.c
36046 ---- linux-2.6.27.6/net/ipv4/udp.c 2008-11-07 12:55:34.000000000 -0500
36047 -+++ linux-2.6.27.6/net/ipv4/udp.c 2008-11-18 03:38:45.000000000 -0500
36048 -@@ -97,6 +97,7 @@
36049 - #include <linux/skbuff.h>
36050 - #include <linux/proc_fs.h>
36051 - #include <linux/seq_file.h>
36052 -+#include <linux/grsecurity.h>
36053 - #include <net/net_namespace.h>
36054 - #include <net/icmp.h>
36055 - #include <net/route.h>
36056 -@@ -104,6 +105,11 @@
36057 - #include <net/xfrm.h>
36058 - #include "udp_impl.h"
36059 -
36060 -+extern int gr_search_udp_recvmsg(const struct sock *sk,
36061 -+ const struct sk_buff *skb);
36062 -+extern int gr_search_udp_sendmsg(const struct sock *sk,
36063 -+ const struct sockaddr_in *addr);
36064 -+
36065 - /*
36066 - * Snmp MIB for the UDP layer
36067 - */
36068 -@@ -302,6 +308,13 @@ static struct sock *__udp4_lib_lookup(st
36069 - return result;
36070 - }
36071 -
36072 -+struct sock *udp_v4_lookup(struct net *net, __be32 saddr, __be16 sport,
36073 -+ __be32 daddr, __be16 dport, int dif)
36074 -+{
36075 -+ return __udp4_lib_lookup(net, saddr, sport, daddr, dport, dif, udp_hash);
36076 -+}
36077 -+
36078 -+
36079 - static inline struct sock *udp_v4_mcast_next(struct sock *sk,
36080 - __be16 loc_port, __be32 loc_addr,
36081 - __be16 rmt_port, __be32 rmt_addr,
36082 -@@ -591,9 +604,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
36083 - dport = usin->sin_port;
36084 - if (dport == 0)
36085 - return -EINVAL;
36086 -+
36087 -+ if (!gr_search_udp_sendmsg(sk, usin))
36088 -+ return -EPERM;
36089 - } else {
36090 - if (sk->sk_state != TCP_ESTABLISHED)
36091 - return -EDESTADDRREQ;
36092 -+
36093 -+ if (!gr_search_udp_sendmsg(sk, NULL))
36094 -+ return -EPERM;
36095 -+
36096 - daddr = inet->daddr;
36097 - dport = inet->dport;
36098 - /* Open fast path for connected socket.
36099 -@@ -858,6 +878,11 @@ try_again:
36100 - if (!skb)
36101 - goto out;
36102 -
36103 -+ if (!gr_search_udp_recvmsg(sk, skb)) {
36104 -+ err = -EPERM;
36105 -+ goto out_free;
36106 -+ }
36107 -+
36108 - ulen = skb->len - sizeof(struct udphdr);
36109 - copied = len;
36110 - if (copied > ulen)
36111 -diff -urNp linux-2.6.27.6/net/ipv6/exthdrs.c linux-2.6.27.6/net/ipv6/exthdrs.c
36112 ---- linux-2.6.27.6/net/ipv6/exthdrs.c 2008-11-07 12:55:34.000000000 -0500
36113 -+++ linux-2.6.27.6/net/ipv6/exthdrs.c 2008-11-18 03:38:45.000000000 -0500
36114 -@@ -624,7 +624,7 @@ static struct tlvtype_proc tlvprochopopt
36115 - .type = IPV6_TLV_JUMBO,
36116 - .func = ipv6_hop_jumbo,
36117 - },
36118 -- { -1, }
36119 -+ { -1, NULL }
36120 - };
36121 -
36122 - int ipv6_parse_hopopts(struct sk_buff *skb)
36123 -diff -urNp linux-2.6.27.6/net/ipv6/raw.c linux-2.6.27.6/net/ipv6/raw.c
36124 ---- linux-2.6.27.6/net/ipv6/raw.c 2008-11-07 12:55:34.000000000 -0500
36125 -+++ linux-2.6.27.6/net/ipv6/raw.c 2008-11-18 03:38:45.000000000 -0500
36126 -@@ -600,7 +600,7 @@ out:
36127 - return err;
36128 - }
36129 -
36130 --static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
36131 -+static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
36132 - struct flowi *fl, struct rt6_info *rt,
36133 - unsigned int flags)
36134 - {
36135 -diff -urNp linux-2.6.27.6/net/irda/ircomm/ircomm_tty.c linux-2.6.27.6/net/irda/ircomm/ircomm_tty.c
36136 ---- linux-2.6.27.6/net/irda/ircomm/ircomm_tty.c 2008-11-07 12:55:34.000000000 -0500
36137 -+++ linux-2.6.27.6/net/irda/ircomm/ircomm_tty.c 2008-11-18 03:38:45.000000000 -0500
36138 -@@ -371,7 +371,7 @@ static int ircomm_tty_open(struct tty_st
36139 - IRDA_DEBUG(2, "%s()\n", __func__ );
36140 -
36141 - line = tty->index;
36142 -- if ((line < 0) || (line >= IRCOMM_TTY_PORTS)) {
36143 -+ if (line >= IRCOMM_TTY_PORTS) {
36144 - return -ENODEV;
36145 - }
36146 -
36147 -diff -urNp linux-2.6.27.6/net/sctp/socket.c linux-2.6.27.6/net/sctp/socket.c
36148 ---- linux-2.6.27.6/net/sctp/socket.c 2008-11-07 12:55:34.000000000 -0500
36149 -+++ linux-2.6.27.6/net/sctp/socket.c 2008-11-18 03:38:45.000000000 -0500
36150 -@@ -1434,7 +1434,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
36151 - struct sctp_sndrcvinfo *sinfo;
36152 - struct sctp_initmsg *sinit;
36153 - sctp_assoc_t associd = 0;
36154 -- sctp_cmsgs_t cmsgs = { NULL };
36155 -+ sctp_cmsgs_t cmsgs = { NULL, NULL };
36156 - int err;
36157 - sctp_scope_t scope;
36158 - long timeo;
36159 -@@ -5616,7 +5616,6 @@ pp_found:
36160 - */
36161 - int reuse = sk->sk_reuse;
36162 - struct sock *sk2;
36163 -- struct hlist_node *node;
36164 -
36165 - SCTP_DEBUG_PRINTK("sctp_get_port() found a possible match\n");
36166 - if (pp->fastreuse && sk->sk_reuse &&
36167 -diff -urNp linux-2.6.27.6/net/socket.c linux-2.6.27.6/net/socket.c
36168 ---- linux-2.6.27.6/net/socket.c 2008-11-07 12:55:34.000000000 -0500
36169 -+++ linux-2.6.27.6/net/socket.c 2008-11-18 03:38:45.000000000 -0500
36170 -@@ -87,6 +87,7 @@
36171 - #include <linux/audit.h>
36172 - #include <linux/wireless.h>
36173 - #include <linux/nsproxy.h>
36174 -+#include <linux/in.h>
36175 -
36176 - #include <asm/uaccess.h>
36177 - #include <asm/unistd.h>
36178 -@@ -97,6 +98,21 @@
36179 - #include <net/sock.h>
36180 - #include <linux/netfilter.h>
36181 -
36182 -+extern void gr_attach_curr_ip(const struct sock *sk);
36183 -+extern int gr_handle_sock_all(const int family, const int type,
36184 -+ const int protocol);
36185 -+extern int gr_handle_sock_server(const struct sockaddr *sck);
36186 -+extern int gr_handle_sock_server_other(const struct socket *sck);
36187 -+extern int gr_handle_sock_client(const struct sockaddr *sck);
36188 -+extern int gr_search_connect(const struct socket * sock,
36189 -+ const struct sockaddr_in * addr);
36190 -+extern int gr_search_bind(const struct socket * sock,
36191 -+ const struct sockaddr_in * addr);
36192 -+extern int gr_search_listen(const struct socket * sock);
36193 -+extern int gr_search_accept(const struct socket * sock);
36194 -+extern int gr_search_socket(const int domain, const int type,
36195 -+ const int protocol);
36196 -+
36197 - static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
36198 - static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
36199 - unsigned long nr_segs, loff_t pos);
36200 -@@ -300,7 +316,7 @@ static int sockfs_get_sb(struct file_sys
36201 - mnt);
36202 - }
36203 -
36204 --static struct vfsmount *sock_mnt __read_mostly;
36205 -+struct vfsmount *sock_mnt __read_mostly;
36206 -
36207 - static struct file_system_type sock_fs_type = {
36208 - .name = "sockfs",
36209 -@@ -1236,6 +1252,16 @@ asmlinkage long sys_socket(int family, i
36210 - if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
36211 - flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
36212 -
36213 -+ if(!gr_search_socket(family, type, protocol)) {
36214 -+ retval = -EACCES;
36215 -+ goto out;
36216 -+ }
36217 -+
36218 -+ if (gr_handle_sock_all(family, type, protocol)) {
36219 -+ retval = -EACCES;
36220 -+ goto out;
36221 -+ }
36222 -+
36223 - retval = sock_create(family, type, protocol, &sock);
36224 - if (retval < 0)
36225 - goto out;
36226 -@@ -1375,6 +1401,12 @@ asmlinkage long sys_bind(int fd, struct
36227 - if (sock) {
36228 - err = move_addr_to_kernel(umyaddr, addrlen, (struct sockaddr *)&address);
36229 - if (err >= 0) {
36230 -+ if (!gr_search_bind(sock, (struct sockaddr_in *)&address) ||
36231 -+ gr_handle_sock_server((struct sockaddr *)&address)) {
36232 -+ err = -EACCES;
36233 -+ goto error;
36234 -+ }
36235 -+
36236 - err = security_socket_bind(sock,
36237 - (struct sockaddr *)&address,
36238 - addrlen);
36239 -@@ -1383,6 +1415,7 @@ asmlinkage long sys_bind(int fd, struct
36240 - (struct sockaddr *)
36241 - &address, addrlen);
36242 - }
36243 -+error:
36244 - fput_light(sock->file, fput_needed);
36245 - }
36246 - return err;
36247 -@@ -1406,10 +1439,17 @@ asmlinkage long sys_listen(int fd, int b
36248 - if ((unsigned)backlog > somaxconn)
36249 - backlog = somaxconn;
36250 -
36251 -+ if (gr_handle_sock_server_other(sock) ||
36252 -+ !gr_search_listen(sock)) {
36253 -+ err = -EPERM;
36254 -+ goto error;
36255 -+ }
36256 -+
36257 - err = security_socket_listen(sock, backlog);
36258 - if (!err)
36259 - err = sock->ops->listen(sock, backlog);
36260 -
36261 -+error:
36262 - fput_light(sock->file, fput_needed);
36263 - }
36264 - return err;
36265 -@@ -1452,6 +1492,13 @@ long do_accept(int fd, struct sockaddr _
36266 - newsock->type = sock->type;
36267 - newsock->ops = sock->ops;
36268 -
36269 -+ if (gr_handle_sock_server_other(sock) ||
36270 -+ !gr_search_accept(sock)) {
36271 -+ err = -EPERM;
36272 -+ sock_release(newsock);
36273 -+ goto out_put;
36274 -+ }
36275 -+
36276 - /*
36277 - * We don't need try_module_get here, as the listening socket (sock)
36278 - * has the protocol module (sock->ops->owner) held.
36279 -@@ -1495,6 +1542,7 @@ long do_accept(int fd, struct sockaddr _
36280 - err = newfd;
36281 -
36282 - security_socket_post_accept(sock, newsock);
36283 -+ gr_attach_curr_ip(newsock->sk);
36284 -
36285 - out_put:
36286 - fput_light(sock->file, fput_needed);
36287 -@@ -1589,6 +1637,7 @@ asmlinkage long sys_connect(int fd, stru
36288 - int addrlen)
36289 - {
36290 - struct socket *sock;
36291 -+ struct sockaddr *sck;
36292 - struct sockaddr_storage address;
36293 - int err, fput_needed;
36294 -
36295 -@@ -1599,6 +1648,13 @@ asmlinkage long sys_connect(int fd, stru
36296 - if (err < 0)
36297 - goto out_put;
36298 -
36299 -+ sck = (struct sockaddr *)&address;
36300 -+ if (!gr_search_connect(sock, (struct sockaddr_in *)sck) ||
36301 -+ gr_handle_sock_client(sck)) {
36302 -+ err = -EACCES;
36303 -+ goto out_put;
36304 -+ }
36305 -+
36306 - err =
36307 - security_socket_connect(sock, (struct sockaddr *)&address, addrlen);
36308 - if (err)
36309 -@@ -1866,6 +1922,7 @@ asmlinkage long sys_shutdown(int fd, int
36310 - err = sock->ops->shutdown(sock, how);
36311 - fput_light(sock->file, fput_needed);
36312 - }
36313 -+
36314 - return err;
36315 - }
36316 -
36317 -diff -urNp linux-2.6.27.6/net/unix/af_unix.c linux-2.6.27.6/net/unix/af_unix.c
36318 ---- linux-2.6.27.6/net/unix/af_unix.c 2008-11-17 20:03:30.000000000 -0500
36319 -+++ linux-2.6.27.6/net/unix/af_unix.c 2008-11-18 03:38:45.000000000 -0500
36320 -@@ -114,6 +114,7 @@
36321 - #include <linux/mount.h>
36322 - #include <net/checksum.h>
36323 - #include <linux/security.h>
36324 -+#include <linux/grsecurity.h>
36325 -
36326 - static struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
36327 - static DEFINE_SPINLOCK(unix_table_lock);
36328 -@@ -725,6 +726,12 @@ static struct sock *unix_find_other(stru
36329 - err = -ECONNREFUSED;
36330 - if (!S_ISSOCK(nd.path.dentry->d_inode->i_mode))
36331 - goto put_fail;
36332 -+
36333 -+ if (!gr_acl_handle_unix(nd.path.dentry, nd.path.mnt)) {
36334 -+ err = -EACCES;
36335 -+ goto put_fail;
36336 -+ }
36337 -+
36338 - u = unix_find_socket_byinode(net, nd.path.dentry->d_inode);
36339 - if (!u)
36340 - goto put_fail;
36341 -@@ -745,6 +752,13 @@ static struct sock *unix_find_other(stru
36342 - if (u) {
36343 - struct dentry *dentry;
36344 - dentry = unix_sk(u)->dentry;
36345 -+
36346 -+ if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
36347 -+ err = -EPERM;
36348 -+ sock_put(u);
36349 -+ goto fail;
36350 -+ }
36351 -+
36352 - if (dentry)
36353 - touch_atime(unix_sk(u)->mnt, dentry);
36354 - } else
36355 -@@ -827,10 +841,20 @@ static int unix_bind(struct socket *sock
36356 - err = mnt_want_write(nd.path.mnt);
36357 - if (err)
36358 - goto out_mknod_dput;
36359 -+
36360 -+ if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
36361 -+ err = -EACCES;
36362 -+ mnt_drop_write(nd.path.mnt);
36363 -+ goto out_mknod_dput;
36364 -+ }
36365 -+
36366 - err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0);
36367 - mnt_drop_write(nd.path.mnt);
36368 - if (err)
36369 - goto out_mknod_dput;
36370 -+
36371 -+ gr_handle_create(dentry, nd.path.mnt);
36372 -+
36373 - mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
36374 - dput(nd.path.dentry);
36375 - nd.path.dentry = dentry;
36376 -@@ -848,6 +872,10 @@ static int unix_bind(struct socket *sock
36377 - goto out_unlock;
36378 - }
36379 -
36380 -+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
36381 -+ sk->sk_peercred.pid = current->pid;
36382 -+#endif
36383 -+
36384 - list = &unix_socket_table[addr->hash];
36385 - } else {
36386 - list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
36387 -diff -urNp linux-2.6.27.6/scripts/pnmtologo.c linux-2.6.27.6/scripts/pnmtologo.c
36388 ---- linux-2.6.27.6/scripts/pnmtologo.c 2008-11-07 12:55:34.000000000 -0500
36389 -+++ linux-2.6.27.6/scripts/pnmtologo.c 2008-11-18 03:38:45.000000000 -0500
36390 -@@ -237,14 +237,14 @@ static void write_header(void)
36391 - fprintf(out, " * Linux logo %s\n", logoname);
36392 - fputs(" */\n\n", out);
36393 - fputs("#include <linux/linux_logo.h>\n\n", out);
36394 -- fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
36395 -+ fprintf(out, "static unsigned char %s_data[] = {\n",
36396 - logoname);
36397 - }
36398 -
36399 - static void write_footer(void)
36400 - {
36401 - fputs("\n};\n\n", out);
36402 -- fprintf(out, "struct linux_logo %s __initdata = {\n", logoname);
36403 -+ fprintf(out, "struct linux_logo %s = {\n", logoname);
36404 - fprintf(out, " .type\t= %s,\n", logo_types[logo_type]);
36405 - fprintf(out, " .width\t= %d,\n", logo_width);
36406 - fprintf(out, " .height\t= %d,\n", logo_height);
36407 -@@ -374,7 +374,7 @@ static void write_logo_clut224(void)
36408 - fputs("\n};\n\n", out);
36409 -
36410 - /* write logo clut */
36411 -- fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
36412 -+ fprintf(out, "static unsigned char %s_clut[] = {\n",
36413 - logoname);
36414 - write_hex_cnt = 0;
36415 - for (i = 0; i < logo_clutsize; i++) {
36416 -diff -urNp linux-2.6.27.6/security/commoncap.c linux-2.6.27.6/security/commoncap.c
36417 ---- linux-2.6.27.6/security/commoncap.c 2008-11-07 12:55:34.000000000 -0500
36418 -+++ linux-2.6.27.6/security/commoncap.c 2008-11-18 03:38:45.000000000 -0500
36419 -@@ -26,10 +26,13 @@
36420 - #include <linux/sched.h>
36421 - #include <linux/prctl.h>
36422 - #include <linux/securebits.h>
36423 -+#include <linux/grsecurity.h>
36424 -+
36425 -+extern kernel_cap_t gr_cap_rtnetlink(struct sock *sk);
36426 -
36427 - int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
36428 - {
36429 -- NETLINK_CB(skb).eff_cap = current->cap_effective;
36430 -+ NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink(sk);
36431 - return 0;
36432 - }
36433 -
36434 -@@ -51,7 +54,15 @@ EXPORT_SYMBOL(cap_netlink_recv);
36435 - int cap_capable (struct task_struct *tsk, int cap)
36436 - {
36437 - /* Derived from include/linux/sched.h:capable. */
36438 -- if (cap_raised(tsk->cap_effective, cap))
36439 -+ if (cap_raised (tsk->cap_effective, cap))
36440 -+ return 0;
36441 -+ return -EPERM;
36442 -+}
36443 -+
36444 -+int cap_capable_nolog (struct task_struct *tsk, int cap)
36445 -+{
36446 -+ /* tsk = current for all callers */
36447 -+ if (cap_raised(tsk->cap_effective, cap) && gr_is_capable_nolog(cap))
36448 - return 0;
36449 - return -EPERM;
36450 - }
36451 -@@ -379,8 +390,11 @@ void cap_bprm_apply_creds (struct linux_
36452 - }
36453 - }
36454 -
36455 -- current->suid = current->euid = current->fsuid = bprm->e_uid;
36456 -- current->sgid = current->egid = current->fsgid = bprm->e_gid;
36457 -+ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
36458 -+ current->suid = current->euid = current->fsuid = bprm->e_uid;
36459 -+
36460 -+ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
36461 -+ current->sgid = current->egid = current->fsgid = bprm->e_gid;
36462 -
36463 - /* For init, we want to retain the capabilities set
36464 - * in the init_task struct. Thus we skip the usual
36465 -@@ -393,6 +407,8 @@ void cap_bprm_apply_creds (struct linux_
36466 - cap_clear(current->cap_effective);
36467 - }
36468 -
36469 -+ gr_handle_chroot_caps(current);
36470 -+
36471 - /* AUD: Audit candidate if current->cap_effective is set */
36472 -
36473 - current->securebits &= ~issecure_mask(SECURE_KEEP_CAPS);
36474 -@@ -705,7 +721,7 @@ int cap_vm_enough_memory(struct mm_struc
36475 - {
36476 - int cap_sys_admin = 0;
36477 -
36478 -- if (cap_capable(current, CAP_SYS_ADMIN) == 0)
36479 -+ if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
36480 - cap_sys_admin = 1;
36481 - return __vm_enough_memory(mm, pages, cap_sys_admin);
36482 - }
36483 -diff -urNp linux-2.6.27.6/security/Kconfig linux-2.6.27.6/security/Kconfig
36484 ---- linux-2.6.27.6/security/Kconfig 2008-11-07 12:55:34.000000000 -0500
36485 -+++ linux-2.6.27.6/security/Kconfig 2008-11-18 03:38:45.000000000 -0500
36486 -@@ -4,6 +4,447 @@
36487 -
36488 - menu "Security options"
36489 -
36490 -+source grsecurity/Kconfig
36491 -+
36492 -+menu "PaX"
36493 -+
36494 -+config PAX
36495 -+ bool "Enable various PaX features"
36496 -+ depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86)
36497 -+ help
36498 -+ This allows you to enable various PaX features. PaX adds
36499 -+ intrusion prevention mechanisms to the kernel that reduce
36500 -+ the risks posed by exploitable memory corruption bugs.
36501 -+
36502 -+menu "PaX Control"
36503 -+ depends on PAX
36504 -+
36505 -+config PAX_SOFTMODE
36506 -+ bool 'Support soft mode'
36507 -+ help
36508 -+ Enabling this option will allow you to run PaX in soft mode, that
36509 -+ is, PaX features will not be enforced by default, only on executables
36510 -+ marked explicitly. You must also enable PT_PAX_FLAGS support as it
36511 -+ is the only way to mark executables for soft mode use.
36512 -+
36513 -+ Soft mode can be activated by using the "pax_softmode=1" kernel command
36514 -+ line option on boot. Furthermore you can control various PaX features
36515 -+ at runtime via the entries in /proc/sys/kernel/pax.
36516 -+
36517 -+config PAX_EI_PAX
36518 -+ bool 'Use legacy ELF header marking'
36519 -+ help
36520 -+ Enabling this option will allow you to control PaX features on
36521 -+ a per executable basis via the 'chpax' utility available at
36522 -+ http://pax.grsecurity.net/. The control flags will be read from
36523 -+ an otherwise reserved part of the ELF header. This marking has
36524 -+ numerous drawbacks (no support for soft-mode, toolchain does not
36525 -+ know about the non-standard use of the ELF header) therefore it
36526 -+ has been deprecated in favour of PT_PAX_FLAGS support.
36527 -+
36528 -+ If you have applications not marked by the PT_PAX_FLAGS ELF
36529 -+ program header then you MUST enable this option otherwise they
36530 -+ will not get any protection.
36531 -+
36532 -+ Note that if you enable PT_PAX_FLAGS marking support as well,
36533 -+ the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
36534 -+
36535 -+config PAX_PT_PAX_FLAGS
36536 -+ bool 'Use ELF program header marking'
36537 -+ help
36538 -+ Enabling this option will allow you to control PaX features on
36539 -+ a per executable basis via the 'paxctl' utility available at
36540 -+ http://pax.grsecurity.net/. The control flags will be read from
36541 -+ a PaX specific ELF program header (PT_PAX_FLAGS). This marking
36542 -+ has the benefits of supporting both soft mode and being fully
36543 -+ integrated into the toolchain (the binutils patch is available
36544 -+ from http://pax.grsecurity.net).
36545 -+
36546 -+ If you have applications not marked by the PT_PAX_FLAGS ELF
36547 -+ program header then you MUST enable the EI_PAX marking support
36548 -+ otherwise they will not get any protection.
36549 -+
36550 -+ Note that if you enable the legacy EI_PAX marking support as well,
36551 -+ the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
36552 -+
36553 -+choice
36554 -+ prompt 'MAC system integration'
36555 -+ default PAX_HAVE_ACL_FLAGS
36556 -+ help
36557 -+ Mandatory Access Control systems have the option of controlling
36558 -+ PaX flags on a per executable basis, choose the method supported
36559 -+ by your particular system.
36560 -+
36561 -+ - "none": if your MAC system does not interact with PaX,
36562 -+ - "direct": if your MAC system defines pax_set_initial_flags() itself,
36563 -+ - "hook": if your MAC system uses the pax_set_initial_flags_func callback.
36564 -+
36565 -+ NOTE: this option is for developers/integrators only.
36566 -+
36567 -+ config PAX_NO_ACL_FLAGS
36568 -+ bool 'none'
36569 -+
36570 -+ config PAX_HAVE_ACL_FLAGS
36571 -+ bool 'direct'
36572 -+
36573 -+ config PAX_HOOK_ACL_FLAGS
36574 -+ bool 'hook'
36575 -+endchoice
36576 -+
36577 -+endmenu
36578 -+
36579 -+menu "Non-executable pages"
36580 -+ depends on PAX
36581 -+
36582 -+config PAX_NOEXEC
36583 -+ bool "Enforce non-executable pages"
36584 -+ 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)
36585 -+ help
36586 -+ By design some architectures do not allow for protecting memory
36587 -+ pages against execution or even if they do, Linux does not make
36588 -+ use of this feature. In practice this means that if a page is
36589 -+ readable (such as the stack or heap) it is also executable.
36590 -+
36591 -+ There is a well known exploit technique that makes use of this
36592 -+ fact and a common programming mistake where an attacker can
36593 -+ introduce code of his choice somewhere in the attacked program's
36594 -+ memory (typically the stack or the heap) and then execute it.
36595 -+
36596 -+ If the attacked program was running with different (typically
36597 -+ higher) privileges than that of the attacker, then he can elevate
36598 -+ his own privilege level (e.g. get a root shell, write to files for
36599 -+ which he does not have write access to, etc).
36600 -+
36601 -+ Enabling this option will let you choose from various features
36602 -+ that prevent the injection and execution of 'foreign' code in
36603 -+ a program.
36604 -+
36605 -+ This will also break programs that rely on the old behaviour and
36606 -+ expect that dynamically allocated memory via the malloc() family
36607 -+ of functions is executable (which it is not). Notable examples
36608 -+ are the XFree86 4.x server, the java runtime and wine.
36609 -+
36610 -+config PAX_PAGEEXEC
36611 -+ bool "Paging based non-executable pages"
36612 -+ 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)
36613 -+ help
36614 -+ This implementation is based on the paging feature of the CPU.
36615 -+ On i386 without hardware non-executable bit support there is a
36616 -+ variable but usually low performance impact, however on Intel's
36617 -+ P4 core based CPUs it is very high so you should not enable this
36618 -+ for kernels meant to be used on such CPUs.
36619 -+
36620 -+ On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386
36621 -+ with hardware non-executable bit support there is no performance
36622 -+ impact, on ppc the impact is negligible.
36623 -+
36624 -+ Note that several architectures require various emulations due to
36625 -+ badly designed userland ABIs, this will cause a performance impact
36626 -+ but will disappear as soon as userland is fixed (e.g., ppc users
36627 -+ can make use of the secure-plt feature found in binutils).
36628 -+
36629 -+config PAX_SEGMEXEC
36630 -+ bool "Segmentation based non-executable pages"
36631 -+ depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32
36632 -+ help
36633 -+ This implementation is based on the segmentation feature of the
36634 -+ CPU and has a very small performance impact, however applications
36635 -+ will be limited to a 1.5 GB address space instead of the normal
36636 -+ 3 GB.
36637 -+
36638 -+config PAX_EMUTRAMP
36639 -+ bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86)
36640 -+ default y if PARISC || PPC32
36641 -+ help
36642 -+ There are some programs and libraries that for one reason or
36643 -+ another attempt to execute special small code snippets from
36644 -+ non-executable memory pages. Most notable examples are the
36645 -+ signal handler return code generated by the kernel itself and
36646 -+ the GCC trampolines.
36647 -+
36648 -+ If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
36649 -+ such programs will no longer work under your kernel.
36650 -+
36651 -+ As a remedy you can say Y here and use the 'chpax' or 'paxctl'
36652 -+ utilities to enable trampoline emulation for the affected programs
36653 -+ yet still have the protection provided by the non-executable pages.
36654 -+
36655 -+ On parisc and ppc you MUST enable this option and EMUSIGRT as
36656 -+ well, otherwise your system will not even boot.
36657 -+
36658 -+ Alternatively you can say N here and use the 'chpax' or 'paxctl'
36659 -+ utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
36660 -+ for the affected files.
36661 -+
36662 -+ NOTE: enabling this feature *may* open up a loophole in the
36663 -+ protection provided by non-executable pages that an attacker
36664 -+ could abuse. Therefore the best solution is to not have any
36665 -+ files on your system that would require this option. This can
36666 -+ be achieved by not using libc5 (which relies on the kernel
36667 -+ signal handler return code) and not using or rewriting programs
36668 -+ that make use of the nested function implementation of GCC.
36669 -+ Skilled users can just fix GCC itself so that it implements
36670 -+ nested function calls in a way that does not interfere with PaX.
36671 -+
36672 -+config PAX_EMUSIGRT
36673 -+ bool "Automatically emulate sigreturn trampolines"
36674 -+ depends on PAX_EMUTRAMP && (PARISC || PPC32)
36675 -+ default y
36676 -+ help
36677 -+ Enabling this option will have the kernel automatically detect
36678 -+ and emulate signal return trampolines executing on the stack
36679 -+ that would otherwise lead to task termination.
36680 -+
36681 -+ This solution is intended as a temporary one for users with
36682 -+ legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
36683 -+ Modula-3 runtime, etc) or executables linked to such, basically
36684 -+ everything that does not specify its own SA_RESTORER function in
36685 -+ normal executable memory like glibc 2.1+ does.
36686 -+
36687 -+ On parisc and ppc you MUST enable this option, otherwise your
36688 -+ system will not even boot.
36689 -+
36690 -+ NOTE: this feature cannot be disabled on a per executable basis
36691 -+ and since it *does* open up a loophole in the protection provided
36692 -+ by non-executable pages, the best solution is to not have any
36693 -+ files on your system that would require this option.
36694 -+
36695 -+config PAX_MPROTECT
36696 -+ bool "Restrict mprotect()"
36697 -+ depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
36698 -+ help
36699 -+ Enabling this option will prevent programs from
36700 -+ - changing the executable status of memory pages that were
36701 -+ not originally created as executable,
36702 -+ - making read-only executable pages writable again,
36703 -+ - creating executable pages from anonymous memory.
36704 -+
36705 -+ You should say Y here to complete the protection provided by
36706 -+ the enforcement of non-executable pages.
36707 -+
36708 -+ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
36709 -+ this feature on a per file basis.
36710 -+
36711 -+config PAX_NOELFRELOCS
36712 -+ bool "Disallow ELF text relocations"
36713 -+ depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86)
36714 -+ help
36715 -+ Non-executable pages and mprotect() restrictions are effective
36716 -+ in preventing the introduction of new executable code into an
36717 -+ attacked task's address space. There remain only two venues
36718 -+ for this kind of attack: if the attacker can execute already
36719 -+ existing code in the attacked task then he can either have it
36720 -+ create and mmap() a file containing his code or have it mmap()
36721 -+ an already existing ELF library that does not have position
36722 -+ independent code in it and use mprotect() on it to make it
36723 -+ writable and copy his code there. While protecting against
36724 -+ the former approach is beyond PaX, the latter can be prevented
36725 -+ by having only PIC ELF libraries on one's system (which do not
36726 -+ need to relocate their code). If you are sure this is your case,
36727 -+ then enable this option otherwise be careful as you may not even
36728 -+ be able to boot or log on your system (for example, some PAM
36729 -+ modules are erroneously compiled as non-PIC by default).
36730 -+
36731 -+ NOTE: if you are using dynamic ELF executables (as suggested
36732 -+ when using ASLR) then you must have made sure that you linked
36733 -+ your files using the PIC version of crt1 (the et_dyn.tar.gz package
36734 -+ referenced there has already been updated to support this).
36735 -+
36736 -+config PAX_ETEXECRELOCS
36737 -+ bool "Allow ELF ET_EXEC text relocations"
36738 -+ depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
36739 -+ default y
36740 -+ help
36741 -+ On some architectures there are incorrectly created applications
36742 -+ that require text relocations and would not work without enabling
36743 -+ this option. If you are an alpha, ia64 or parisc user, you should
36744 -+ enable this option and disable it once you have made sure that
36745 -+ none of your applications need it.
36746 -+
36747 -+config PAX_EMUPLT
36748 -+ bool "Automatically emulate ELF PLT"
36749 -+ depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
36750 -+ default y
36751 -+ help
36752 -+ Enabling this option will have the kernel automatically detect
36753 -+ and emulate the Procedure Linkage Table entries in ELF files.
36754 -+ On some architectures such entries are in writable memory, and
36755 -+ become non-executable leading to task termination. Therefore
36756 -+ it is mandatory that you enable this option on alpha, parisc,
36757 -+ ppc (if secure-plt is not used throughout in userland), sparc
36758 -+ and sparc64, otherwise your system would not even boot.
36759 -+
36760 -+ NOTE: this feature *does* open up a loophole in the protection
36761 -+ provided by the non-executable pages, therefore the proper
36762 -+ solution is to modify the toolchain to produce a PLT that does
36763 -+ not need to be writable.
36764 -+
36765 -+config PAX_DLRESOLVE
36766 -+ bool
36767 -+ depends on PAX_EMUPLT && (SPARC32 || SPARC64)
36768 -+ default y
36769 -+
36770 -+config PAX_SYSCALL
36771 -+ bool
36772 -+ depends on PAX_PAGEEXEC && PPC32
36773 -+ default y
36774 -+
36775 -+config PAX_KERNEXEC
36776 -+ bool "Enforce non-executable kernel pages"
36777 -+ depends on PAX_NOEXEC && X86 && !EFI && !COMPAT_VDSO && (!X86_32 || X86_WP_WORKS_OK) && !PARAVIRT
36778 -+ help
36779 -+ This is the kernel land equivalent of PAGEEXEC and MPROTECT,
36780 -+ that is, enabling this option will make it harder to inject
36781 -+ and execute 'foreign' code in kernel memory itself.
36782 -+
36783 -+endmenu
36784 -+
36785 -+menu "Address Space Layout Randomization"
36786 -+ depends on PAX
36787 -+
36788 -+config PAX_ASLR
36789 -+ bool "Address Space Layout Randomization"
36790 -+ depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
36791 -+ help
36792 -+ Many if not most exploit techniques rely on the knowledge of
36793 -+ certain addresses in the attacked program. The following options
36794 -+ will allow the kernel to apply a certain amount of randomization
36795 -+ to specific parts of the program thereby forcing an attacker to
36796 -+ guess them in most cases. Any failed guess will most likely crash
36797 -+ the attacked program which allows the kernel to detect such attempts
36798 -+ and react on them. PaX itself provides no reaction mechanisms,
36799 -+ instead it is strongly encouraged that you make use of Nergal's
36800 -+ segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
36801 -+ (http://www.grsecurity.net/) built-in crash detection features or
36802 -+ develop one yourself.
36803 -+
36804 -+ By saying Y here you can choose to randomize the following areas:
36805 -+ - top of the task's kernel stack
36806 -+ - top of the task's userland stack
36807 -+ - base address for mmap() requests that do not specify one
36808 -+ (this includes all libraries)
36809 -+ - base address of the main executable
36810 -+
36811 -+ It is strongly recommended to say Y here as address space layout
36812 -+ randomization has negligible impact on performance yet it provides
36813 -+ a very effective protection.
36814 -+
36815 -+ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
36816 -+ this feature on a per file basis.
36817 -+
36818 -+config PAX_RANDKSTACK
36819 -+ bool "Randomize kernel stack base"
36820 -+ depends on PAX_ASLR && X86_TSC && X86_32
36821 -+ help
36822 -+ By saying Y here the kernel will randomize every task's kernel
36823 -+ stack on every system call. This will not only force an attacker
36824 -+ to guess it but also prevent him from making use of possible
36825 -+ leaked information about it.
36826 -+
36827 -+ Since the kernel stack is a rather scarce resource, randomization
36828 -+ may cause unexpected stack overflows, therefore you should very
36829 -+ carefully test your system. Note that once enabled in the kernel
36830 -+ configuration, this feature cannot be disabled on a per file basis.
36831 -+
36832 -+config PAX_RANDUSTACK
36833 -+ bool "Randomize user stack base"
36834 -+ depends on PAX_ASLR
36835 -+ help
36836 -+ By saying Y here the kernel will randomize every task's userland
36837 -+ stack. The randomization is done in two steps where the second
36838 -+ one may apply a big amount of shift to the top of the stack and
36839 -+ cause problems for programs that want to use lots of memory (more
36840 -+ than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
36841 -+ For this reason the second step can be controlled by 'chpax' or
36842 -+ 'paxctl' on a per file basis.
36843 -+
36844 -+config PAX_RANDMMAP
36845 -+ bool "Randomize mmap() base"
36846 -+ depends on PAX_ASLR
36847 -+ help
36848 -+ By saying Y here the kernel will use a randomized base address for
36849 -+ mmap() requests that do not specify one themselves. As a result
36850 -+ all dynamically loaded libraries will appear at random addresses
36851 -+ and therefore be harder to exploit by a technique where an attacker
36852 -+ attempts to execute library code for his purposes (e.g. spawn a
36853 -+ shell from an exploited program that is running at an elevated
36854 -+ privilege level).
36855 -+
36856 -+ Furthermore, if a program is relinked as a dynamic ELF file, its
36857 -+ base address will be randomized as well, completing the full
36858 -+ randomization of the address space layout. Attacking such programs
36859 -+ becomes a guess game. You can find an example of doing this at
36860 -+ http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
36861 -+ http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
36862 -+
36863 -+ NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
36864 -+ feature on a per file basis.
36865 -+
36866 -+endmenu
36867 -+
36868 -+menu "Miscellaneous hardening features"
36869 -+
36870 -+config PAX_MEMORY_SANITIZE
36871 -+ bool "Sanitize all freed memory"
36872 -+ help
36873 -+ By saying Y here the kernel will erase memory pages as soon as they
36874 -+ are freed. This in turn reduces the lifetime of data stored in the
36875 -+ pages, making it less likely that sensitive information such as
36876 -+ passwords, cryptographic secrets, etc stay in memory for too long.
36877 -+
36878 -+ This is especially useful for programs whose runtime is short, long
36879 -+ lived processes and the kernel itself benefit from this as long as
36880 -+ they operate on whole memory pages and ensure timely freeing of pages
36881 -+ that may hold sensitive information.
36882 -+
36883 -+ The tradeoff is performance impact, on a single CPU system kernel
36884 -+ compilation sees a 3% slowdown, other systems and workloads may vary
36885 -+ and you are advised to test this feature on your expected workload
36886 -+ before deploying it.
36887 -+
36888 -+ Note that this feature does not protect data stored in live pages,
36889 -+ e.g., process memory swapped to disk may stay there for a long time.
36890 -+
36891 -+config PAX_MEMORY_UDEREF
36892 -+ bool "Prevent invalid userland pointer dereference"
36893 -+ depends on X86_32 && !COMPAT_VDSO && !UML_X86
36894 -+ help
36895 -+ By saying Y here the kernel will be prevented from dereferencing
36896 -+ userland pointers in contexts where the kernel expects only kernel
36897 -+ pointers. This is both a useful runtime debugging feature and a
36898 -+ security measure that prevents exploiting a class of kernel bugs.
36899 -+
36900 -+ The tradeoff is that some virtualization solutions may experience
36901 -+ a huge slowdown and therefore you should not enable this feature
36902 -+ for kernels meant to run in such environments. Whether a given VM
36903 -+ solution is affected or not is best determined by simply trying it
36904 -+ out, the performance impact will be obvious right on boot as this
36905 -+ mechanism engages from very early on. A good rule of thumb is that
36906 -+ VMs running on CPUs without hardware virtualization support (i.e.,
36907 -+ the majority of IA-32 CPUs) will likely experience the slowdown.
36908 -+
36909 -+config PAX_REFCOUNT
36910 -+ bool "Prevent various kernel object reference counter overflows"
36911 -+ depends on X86
36912 -+ help
36913 -+ By saying Y here the kernel will detect and prevent overflowing
36914 -+ various (but not all) kinds of object reference counters. Such
36915 -+ overflows can normally occur due to bugs only and are often, if
36916 -+ not always, exploitable.
36917 -+
36918 -+ The tradeoff is that data structures protected by an oveflowed
36919 -+ refcount will never be freed and therefore will leak memory. Note
36920 -+ that this leak also happens even without this protection but in
36921 -+ that case the overflow can eventually trigger the freeing of the
36922 -+ data structure while it is still being used elsewhere, resulting
36923 -+ in the exploitable situation that this feature prevents.
36924 -+
36925 -+ Since this has a negligible performance impact, you should enable
36926 -+ this feature.
36927 -+endmenu
36928 -+
36929 -+endmenu
36930 -+
36931 - config KEYS
36932 - bool "Enable access key retention support"
36933 - help
36934 -diff -urNp linux-2.6.27.6/sound/core/oss/pcm_oss.c linux-2.6.27.6/sound/core/oss/pcm_oss.c
36935 ---- linux-2.6.27.6/sound/core/oss/pcm_oss.c 2008-11-07 12:55:34.000000000 -0500
36936 -+++ linux-2.6.27.6/sound/core/oss/pcm_oss.c 2008-11-18 03:38:45.000000000 -0500
36937 -@@ -2911,8 +2911,8 @@ static void snd_pcm_oss_proc_done(struct
36938 - }
36939 - }
36940 - #else /* !CONFIG_SND_VERBOSE_PROCFS */
36941 --#define snd_pcm_oss_proc_init(pcm)
36942 --#define snd_pcm_oss_proc_done(pcm)
36943 -+#define snd_pcm_oss_proc_init(pcm) do {} while (0)
36944 -+#define snd_pcm_oss_proc_done(pcm) do {} while (0)
36945 - #endif /* CONFIG_SND_VERBOSE_PROCFS */
36946 -
36947 - /*
36948 -diff -urNp linux-2.6.27.6/sound/core/seq/seq_lock.h linux-2.6.27.6/sound/core/seq/seq_lock.h
36949 ---- linux-2.6.27.6/sound/core/seq/seq_lock.h 2008-11-07 12:55:34.000000000 -0500
36950 -+++ linux-2.6.27.6/sound/core/seq/seq_lock.h 2008-11-18 03:38:45.000000000 -0500
36951 -@@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo
36952 - #else /* SMP || CONFIG_SND_DEBUG */
36953 -
36954 - typedef spinlock_t snd_use_lock_t; /* dummy */
36955 --#define snd_use_lock_init(lockp) /**/
36956 --#define snd_use_lock_use(lockp) /**/
36957 --#define snd_use_lock_free(lockp) /**/
36958 --#define snd_use_lock_sync(lockp) /**/
36959 -+#define snd_use_lock_init(lockp) do {} while (0)
36960 -+#define snd_use_lock_use(lockp) do {} while (0)
36961 -+#define snd_use_lock_free(lockp) do {} while (0)
36962 -+#define snd_use_lock_sync(lockp) do {} while (0)
36963 -
36964 - #endif /* SMP || CONFIG_SND_DEBUG */
36965 -
36966 -diff -urNp linux-2.6.27.6/sound/pci/ac97/ac97_patch.c linux-2.6.27.6/sound/pci/ac97/ac97_patch.c
36967 ---- linux-2.6.27.6/sound/pci/ac97/ac97_patch.c 2008-11-07 12:55:34.000000000 -0500
36968 -+++ linux-2.6.27.6/sound/pci/ac97/ac97_patch.c 2008-11-18 03:38:45.000000000 -0500
36969 -@@ -1498,7 +1498,7 @@ static const struct snd_ac97_res_table a
36970 - { AC97_VIDEO, 0x9f1f },
36971 - { AC97_AUX, 0x9f1f },
36972 - { AC97_PCM, 0x9f1f },
36973 -- { } /* terminator */
36974 -+ { 0, 0 } /* terminator */
36975 - };
36976 -
36977 - static int patch_ad1819(struct snd_ac97 * ac97)
36978 -@@ -3668,7 +3668,7 @@ static struct snd_ac97_res_table lm4550_
36979 - { AC97_AUX, 0x1f1f },
36980 - { AC97_PCM, 0x1f1f },
36981 - { AC97_REC_GAIN, 0x0f0f },
36982 -- { } /* terminator */
36983 -+ { 0, 0 } /* terminator */
36984 - };
36985 -
36986 - static int patch_lm4550(struct snd_ac97 *ac97)
36987 -diff -urNp linux-2.6.27.6/sound/pci/ens1370.c linux-2.6.27.6/sound/pci/ens1370.c
36988 ---- linux-2.6.27.6/sound/pci/ens1370.c 2008-11-07 12:55:34.000000000 -0500
36989 -+++ linux-2.6.27.6/sound/pci/ens1370.c 2008-11-18 03:38:45.000000000 -0500
36990 -@@ -452,7 +452,7 @@ static struct pci_device_id snd_audiopci
36991 - { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1373 - CT5880 */
36992 - { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ectiva EV1938 */
36993 - #endif
36994 -- { 0, }
36995 -+ { 0, 0, 0, 0, 0, 0, 0 }
36996 - };
36997 -
36998 - MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
36999 -diff -urNp linux-2.6.27.6/sound/pci/intel8x0.c linux-2.6.27.6/sound/pci/intel8x0.c
37000 ---- linux-2.6.27.6/sound/pci/intel8x0.c 2008-11-07 12:55:34.000000000 -0500
37001 -+++ linux-2.6.27.6/sound/pci/intel8x0.c 2008-11-18 03:38:45.000000000 -0500
37002 -@@ -437,7 +437,7 @@ static struct pci_device_id snd_intel8x0
37003 - { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
37004 - { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
37005 - { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
37006 -- { 0, }
37007 -+ { 0, 0, 0, 0, 0, 0, 0 }
37008 - };
37009 -
37010 - MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
37011 -@@ -2076,7 +2076,7 @@ static struct ac97_quirk ac97_quirks[] _
37012 - .type = AC97_TUNE_HP_ONLY
37013 - },
37014 - #endif
37015 -- { } /* terminator */
37016 -+ { 0, 0, 0, 0, NULL, 0 } /* terminator */
37017 - };
37018 -
37019 - static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
37020 -diff -urNp linux-2.6.27.6/sound/pci/intel8x0m.c linux-2.6.27.6/sound/pci/intel8x0m.c
37021 ---- linux-2.6.27.6/sound/pci/intel8x0m.c 2008-11-07 12:55:34.000000000 -0500
37022 -+++ linux-2.6.27.6/sound/pci/intel8x0m.c 2008-11-18 03:38:45.000000000 -0500
37023 -@@ -239,7 +239,7 @@ static struct pci_device_id snd_intel8x0
37024 - { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
37025 - { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
37026 - #endif
37027 -- { 0, }
37028 -+ { 0, 0, 0, 0, 0, 0, 0 }
37029 - };
37030 -
37031 - MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
37032 -@@ -1257,7 +1257,7 @@ static struct shortname_table {
37033 - { 0x5455, "ALi M5455" },
37034 - { 0x746d, "AMD AMD8111" },
37035 - #endif
37036 -- { 0 },
37037 -+ { 0, NULL },
37038 - };
37039 -
37040 - static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
37041 -diff -urNp linux-2.6.27.6/virt/kvm/kvm_main.c linux-2.6.27.6/virt/kvm/kvm_main.c
37042 ---- linux-2.6.27.6/virt/kvm/kvm_main.c 2008-11-07 12:55:34.000000000 -0500
37043 -+++ linux-2.6.27.6/virt/kvm/kvm_main.c 2008-11-18 03:38:45.000000000 -0500
37044 -@@ -1469,6 +1469,9 @@ static struct miscdevice kvm_dev = {
37045 - KVM_MINOR,
37046 - "kvm",
37047 - &kvm_chardev_ops,
37048 -+ {NULL, NULL},
37049 -+ NULL,
37050 -+ NULL
37051 - };
37052 -
37053 - static void hardware_enable(void *junk)
37054
37055 Added: hardened/2.6/trunk/2.6.27/4420_grsec-2.1.12-2.6.27.7-200811201849.patch
37056 ===================================================================
37057 --- hardened/2.6/trunk/2.6.27/4420_grsec-2.1.12-2.6.27.7-200811201849.patch (rev 0)
37058 +++ hardened/2.6/trunk/2.6.27/4420_grsec-2.1.12-2.6.27.7-200811201849.patch 2008-11-24 01:39:52 UTC (rev 1404)
37059 @@ -0,0 +1,37046 @@
37060 +diff -urNp linux-2.6.27.7/arch/alpha/include/asm/elf.h linux-2.6.27.7/arch/alpha/include/asm/elf.h
37061 +--- linux-2.6.27.7/arch/alpha/include/asm/elf.h 2008-11-07 12:55:34.000000000 -0500
37062 ++++ linux-2.6.27.7/arch/alpha/include/asm/elf.h 2008-11-18 03:39:50.000000000 -0500
37063 +@@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
37064 +
37065 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
37066 +
37067 ++#ifdef CONFIG_PAX_ASLR
37068 ++#define PAX_ELF_ET_DYN_BASE (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
37069 ++
37070 ++#define PAX_DELTA_MMAP_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 28)
37071 ++#define PAX_DELTA_STACK_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 19)
37072 ++#endif
37073 ++
37074 + /* $0 is set by ld.so to a pointer to a function which might be
37075 + registered using atexit. This provides a mean for the dynamic
37076 + linker to call DT_FINI functions for shared libraries that have
37077 +diff -urNp linux-2.6.27.7/arch/alpha/include/asm/kmap_types.h linux-2.6.27.7/arch/alpha/include/asm/kmap_types.h
37078 +--- linux-2.6.27.7/arch/alpha/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
37079 ++++ linux-2.6.27.7/arch/alpha/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
37080 +@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
37081 + D(10) KM_IRQ1,
37082 + D(11) KM_SOFTIRQ0,
37083 + D(12) KM_SOFTIRQ1,
37084 +-D(13) KM_TYPE_NR
37085 ++D(13) KM_CLEARPAGE,
37086 ++D(14) KM_TYPE_NR
37087 + };
37088 +
37089 + #undef D
37090 +diff -urNp linux-2.6.27.7/arch/alpha/include/asm/pgtable.h linux-2.6.27.7/arch/alpha/include/asm/pgtable.h
37091 +--- linux-2.6.27.7/arch/alpha/include/asm/pgtable.h 2008-11-07 12:55:34.000000000 -0500
37092 ++++ linux-2.6.27.7/arch/alpha/include/asm/pgtable.h 2008-11-18 03:39:50.000000000 -0500
37093 +@@ -101,6 +101,17 @@ struct vm_area_struct;
37094 + #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
37095 + #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
37096 + #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
37097 ++
37098 ++#ifdef CONFIG_PAX_PAGEEXEC
37099 ++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
37100 ++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
37101 ++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
37102 ++#else
37103 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
37104 ++# define PAGE_COPY_NOEXEC PAGE_COPY
37105 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
37106 ++#endif
37107 ++
37108 + #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
37109 +
37110 + #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
37111 +diff -urNp linux-2.6.27.7/arch/alpha/kernel/module.c linux-2.6.27.7/arch/alpha/kernel/module.c
37112 +--- linux-2.6.27.7/arch/alpha/kernel/module.c 2008-11-07 12:55:34.000000000 -0500
37113 ++++ linux-2.6.27.7/arch/alpha/kernel/module.c 2008-11-18 03:38:43.000000000 -0500
37114 +@@ -182,7 +182,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
37115 +
37116 + /* The small sections were sorted to the end of the segment.
37117 + The following should definitely cover them. */
37118 +- gp = (u64)me->module_core + me->core_size - 0x8000;
37119 ++ gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
37120 + got = sechdrs[me->arch.gotsecindex].sh_addr;
37121 +
37122 + for (i = 0; i < n; i++) {
37123 +diff -urNp linux-2.6.27.7/arch/alpha/kernel/osf_sys.c linux-2.6.27.7/arch/alpha/kernel/osf_sys.c
37124 +--- linux-2.6.27.7/arch/alpha/kernel/osf_sys.c 2008-11-07 12:55:34.000000000 -0500
37125 ++++ linux-2.6.27.7/arch/alpha/kernel/osf_sys.c 2008-11-18 03:38:43.000000000 -0500
37126 +@@ -1232,6 +1232,10 @@ arch_get_unmapped_area(struct file *filp
37127 + merely specific addresses, but regions of memory -- perhaps
37128 + this feature should be incorporated into all ports? */
37129 +
37130 ++#ifdef CONFIG_PAX_RANDMMAP
37131 ++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
37132 ++#endif
37133 ++
37134 + if (addr) {
37135 + addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
37136 + if (addr != (unsigned long) -ENOMEM)
37137 +@@ -1239,8 +1243,8 @@ arch_get_unmapped_area(struct file *filp
37138 + }
37139 +
37140 + /* Next, try allocating at TASK_UNMAPPED_BASE. */
37141 +- addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
37142 +- len, limit);
37143 ++ addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
37144 ++
37145 + if (addr != (unsigned long) -ENOMEM)
37146 + return addr;
37147 +
37148 +diff -urNp linux-2.6.27.7/arch/alpha/kernel/ptrace.c linux-2.6.27.7/arch/alpha/kernel/ptrace.c
37149 +--- linux-2.6.27.7/arch/alpha/kernel/ptrace.c 2008-11-07 12:55:34.000000000 -0500
37150 ++++ linux-2.6.27.7/arch/alpha/kernel/ptrace.c 2008-11-18 03:38:43.000000000 -0500
37151 +@@ -15,6 +15,7 @@
37152 + #include <linux/slab.h>
37153 + #include <linux/security.h>
37154 + #include <linux/signal.h>
37155 ++#include <linux/grsecurity.h>
37156 +
37157 + #include <asm/uaccess.h>
37158 + #include <asm/pgtable.h>
37159 +@@ -266,6 +267,9 @@ long arch_ptrace(struct task_struct *chi
37160 + size_t copied;
37161 + long ret;
37162 +
37163 ++ if (gr_handle_ptrace(child, request))
37164 ++ return -EPERM;
37165 ++
37166 + switch (request) {
37167 + /* When I and D space are separate, these will need to be fixed. */
37168 + case PTRACE_PEEKTEXT: /* read word at location addr. */
37169 +diff -urNp linux-2.6.27.7/arch/alpha/mm/fault.c linux-2.6.27.7/arch/alpha/mm/fault.c
37170 +--- linux-2.6.27.7/arch/alpha/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
37171 ++++ linux-2.6.27.7/arch/alpha/mm/fault.c 2008-11-18 03:38:43.000000000 -0500
37172 +@@ -54,6 +54,124 @@ __load_new_mm_context(struct mm_struct *
37173 + __reload_thread(pcb);
37174 + }
37175 +
37176 ++#ifdef CONFIG_PAX_PAGEEXEC
37177 ++/*
37178 ++ * PaX: decide what to do with offenders (regs->pc = fault address)
37179 ++ *
37180 ++ * returns 1 when task should be killed
37181 ++ * 2 when patched PLT trampoline was detected
37182 ++ * 3 when unpatched PLT trampoline was detected
37183 ++ */
37184 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
37185 ++{
37186 ++
37187 ++#ifdef CONFIG_PAX_EMUPLT
37188 ++ int err;
37189 ++
37190 ++ do { /* PaX: patched PLT emulation #1 */
37191 ++ unsigned int ldah, ldq, jmp;
37192 ++
37193 ++ err = get_user(ldah, (unsigned int *)regs->pc);
37194 ++ err |= get_user(ldq, (unsigned int *)(regs->pc+4));
37195 ++ err |= get_user(jmp, (unsigned int *)(regs->pc+8));
37196 ++
37197 ++ if (err)
37198 ++ break;
37199 ++
37200 ++ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
37201 ++ (ldq & 0xFFFF0000U) == 0xA77B0000U &&
37202 ++ jmp == 0x6BFB0000U)
37203 ++ {
37204 ++ unsigned long r27, addr;
37205 ++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
37206 ++ unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
37207 ++
37208 ++ addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
37209 ++ err = get_user(r27, (unsigned long *)addr);
37210 ++ if (err)
37211 ++ break;
37212 ++
37213 ++ regs->r27 = r27;
37214 ++ regs->pc = r27;
37215 ++ return 2;
37216 ++ }
37217 ++ } while (0);
37218 ++
37219 ++ do { /* PaX: patched PLT emulation #2 */
37220 ++ unsigned int ldah, lda, br;
37221 ++
37222 ++ err = get_user(ldah, (unsigned int *)regs->pc);
37223 ++ err |= get_user(lda, (unsigned int *)(regs->pc+4));
37224 ++ err |= get_user(br, (unsigned int *)(regs->pc+8));
37225 ++
37226 ++ if (err)
37227 ++ break;
37228 ++
37229 ++ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
37230 ++ (lda & 0xFFFF0000U) == 0xA77B0000U &&
37231 ++ (br & 0xFFE00000U) == 0xC3E00000U)
37232 ++ {
37233 ++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
37234 ++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
37235 ++ unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
37236 ++
37237 ++ regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
37238 ++ regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
37239 ++ return 2;
37240 ++ }
37241 ++ } while (0);
37242 ++
37243 ++ do { /* PaX: unpatched PLT emulation */
37244 ++ unsigned int br;
37245 ++
37246 ++ err = get_user(br, (unsigned int *)regs->pc);
37247 ++
37248 ++ if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
37249 ++ unsigned int br2, ldq, nop, jmp;
37250 ++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
37251 ++
37252 ++ addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
37253 ++ err = get_user(br2, (unsigned int *)addr);
37254 ++ err |= get_user(ldq, (unsigned int *)(addr+4));
37255 ++ err |= get_user(nop, (unsigned int *)(addr+8));
37256 ++ err |= get_user(jmp, (unsigned int *)(addr+12));
37257 ++ err |= get_user(resolver, (unsigned long *)(addr+16));
37258 ++
37259 ++ if (err)
37260 ++ break;
37261 ++
37262 ++ if (br2 == 0xC3600000U &&
37263 ++ ldq == 0xA77B000CU &&
37264 ++ nop == 0x47FF041FU &&
37265 ++ jmp == 0x6B7B0000U)
37266 ++ {
37267 ++ regs->r28 = regs->pc+4;
37268 ++ regs->r27 = addr+16;
37269 ++ regs->pc = resolver;
37270 ++ return 3;
37271 ++ }
37272 ++ }
37273 ++ } while (0);
37274 ++#endif
37275 ++
37276 ++ return 1;
37277 ++}
37278 ++
37279 ++void pax_report_insns(void *pc, void *sp)
37280 ++{
37281 ++ unsigned long i;
37282 ++
37283 ++ printk(KERN_ERR "PAX: bytes at PC: ");
37284 ++ for (i = 0; i < 5; i++) {
37285 ++ unsigned int c;
37286 ++ if (get_user(c, (unsigned int *)pc+i))
37287 ++ printk(KERN_CONT "???????? ");
37288 ++ else
37289 ++ printk(KERN_CONT "%08x ", c);
37290 ++ }
37291 ++ printk("\n");
37292 ++}
37293 ++#endif
37294 +
37295 + /*
37296 + * This routine handles page faults. It determines the address,
37297 +@@ -131,8 +249,29 @@ do_page_fault(unsigned long address, uns
37298 + good_area:
37299 + si_code = SEGV_ACCERR;
37300 + if (cause < 0) {
37301 +- if (!(vma->vm_flags & VM_EXEC))
37302 ++ if (!(vma->vm_flags & VM_EXEC)) {
37303 ++
37304 ++#ifdef CONFIG_PAX_PAGEEXEC
37305 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
37306 ++ goto bad_area;
37307 ++
37308 ++ up_read(&mm->mmap_sem);
37309 ++ switch (pax_handle_fetch_fault(regs)) {
37310 ++
37311 ++#ifdef CONFIG_PAX_EMUPLT
37312 ++ case 2:
37313 ++ case 3:
37314 ++ return;
37315 ++#endif
37316 ++
37317 ++ }
37318 ++ pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
37319 ++ do_group_exit(SIGKILL);
37320 ++#else
37321 + goto bad_area;
37322 ++#endif
37323 ++
37324 ++ }
37325 + } else if (!cause) {
37326 + /* Allow reads even for write-only mappings */
37327 + if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
37328 +diff -urNp linux-2.6.27.7/arch/arm/include/asm/elf.h linux-2.6.27.7/arch/arm/include/asm/elf.h
37329 +--- linux-2.6.27.7/arch/arm/include/asm/elf.h 2008-11-07 12:55:34.000000000 -0500
37330 ++++ linux-2.6.27.7/arch/arm/include/asm/elf.h 2008-11-18 03:39:50.000000000 -0500
37331 +@@ -87,7 +87,14 @@ extern char elf_platform[];
37332 + the loader. We need to make sure that it is out of the way of the program
37333 + that it will "exec", and that there is sufficient room for the brk. */
37334 +
37335 +-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
37336 ++#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
37337 ++
37338 ++#ifdef CONFIG_PAX_ASLR
37339 ++#define PAX_ELF_ET_DYN_BASE 0x00008000UL
37340 ++
37341 ++#define PAX_DELTA_MMAP_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
37342 ++#define PAX_DELTA_STACK_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
37343 ++#endif
37344 +
37345 + /* When the program starts, a1 contains a pointer to a function to be
37346 + registered with atexit, as per the SVR4 ABI. A value of 0 means we
37347 +diff -urNp linux-2.6.27.7/arch/arm/include/asm/kmap_types.h linux-2.6.27.7/arch/arm/include/asm/kmap_types.h
37348 +--- linux-2.6.27.7/arch/arm/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
37349 ++++ linux-2.6.27.7/arch/arm/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
37350 +@@ -18,6 +18,7 @@ enum km_type {
37351 + KM_IRQ1,
37352 + KM_SOFTIRQ0,
37353 + KM_SOFTIRQ1,
37354 ++ KM_CLEARPAGE,
37355 + KM_TYPE_NR
37356 + };
37357 +
37358 +diff -urNp linux-2.6.27.7/arch/arm/mm/mmap.c linux-2.6.27.7/arch/arm/mm/mmap.c
37359 +--- linux-2.6.27.7/arch/arm/mm/mmap.c 2008-11-07 12:55:34.000000000 -0500
37360 ++++ linux-2.6.27.7/arch/arm/mm/mmap.c 2008-11-18 03:38:43.000000000 -0500
37361 +@@ -60,6 +60,10 @@ arch_get_unmapped_area(struct file *filp
37362 + if (len > TASK_SIZE)
37363 + return -ENOMEM;
37364 +
37365 ++#ifdef CONFIG_PAX_RANDMMAP
37366 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
37367 ++#endif
37368 ++
37369 + if (addr) {
37370 + if (do_align)
37371 + addr = COLOUR_ALIGN(addr, pgoff);
37372 +@@ -72,10 +76,10 @@ arch_get_unmapped_area(struct file *filp
37373 + return addr;
37374 + }
37375 + if (len > mm->cached_hole_size) {
37376 +- start_addr = addr = mm->free_area_cache;
37377 ++ start_addr = addr = mm->free_area_cache;
37378 + } else {
37379 +- start_addr = addr = TASK_UNMAPPED_BASE;
37380 +- mm->cached_hole_size = 0;
37381 ++ start_addr = addr = mm->mmap_base;
37382 ++ mm->cached_hole_size = 0;
37383 + }
37384 +
37385 + full_search:
37386 +@@ -91,8 +95,8 @@ full_search:
37387 + * Start a new search - just in case we missed
37388 + * some holes.
37389 + */
37390 +- if (start_addr != TASK_UNMAPPED_BASE) {
37391 +- start_addr = addr = TASK_UNMAPPED_BASE;
37392 ++ if (start_addr != mm->mmap_base) {
37393 ++ start_addr = addr = mm->mmap_base;
37394 + mm->cached_hole_size = 0;
37395 + goto full_search;
37396 + }
37397 +diff -urNp linux-2.6.27.7/arch/avr32/include/asm/elf.h linux-2.6.27.7/arch/avr32/include/asm/elf.h
37398 +--- linux-2.6.27.7/arch/avr32/include/asm/elf.h 2008-11-07 12:55:34.000000000 -0500
37399 ++++ linux-2.6.27.7/arch/avr32/include/asm/elf.h 2008-11-18 03:39:50.000000000 -0500
37400 +@@ -85,8 +85,14 @@ typedef struct user_fpu_struct elf_fpreg
37401 + the loader. We need to make sure that it is out of the way of the program
37402 + that it will "exec", and that there is sufficient room for the brk. */
37403 +
37404 +-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
37405 ++#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
37406 +
37407 ++#ifdef CONFIG_PAX_ASLR
37408 ++#define PAX_ELF_ET_DYN_BASE 0x00001000UL
37409 ++
37410 ++#define PAX_DELTA_MMAP_LEN 15
37411 ++#define PAX_DELTA_STACK_LEN 15
37412 ++#endif
37413 +
37414 + /* This yields a mask that user programs can use to figure out what
37415 + instruction set this CPU supports. This could be done in user space,
37416 +diff -urNp linux-2.6.27.7/arch/avr32/include/asm/kmap_types.h linux-2.6.27.7/arch/avr32/include/asm/kmap_types.h
37417 +--- linux-2.6.27.7/arch/avr32/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
37418 ++++ linux-2.6.27.7/arch/avr32/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
37419 +@@ -22,7 +22,8 @@ D(10) KM_IRQ0,
37420 + D(11) KM_IRQ1,
37421 + D(12) KM_SOFTIRQ0,
37422 + D(13) KM_SOFTIRQ1,
37423 +-D(14) KM_TYPE_NR
37424 ++D(14) KM_CLEARPAGE,
37425 ++D(15) KM_TYPE_NR
37426 + };
37427 +
37428 + #undef D
37429 +diff -urNp linux-2.6.27.7/arch/avr32/mm/fault.c linux-2.6.27.7/arch/avr32/mm/fault.c
37430 +--- linux-2.6.27.7/arch/avr32/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
37431 ++++ linux-2.6.27.7/arch/avr32/mm/fault.c 2008-11-18 03:38:43.000000000 -0500
37432 +@@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
37433 +
37434 + int exception_trace = 1;
37435 +
37436 ++#ifdef CONFIG_PAX_PAGEEXEC
37437 ++void pax_report_insns(void *pc, void *sp)
37438 ++{
37439 ++ unsigned long i;
37440 ++
37441 ++ printk(KERN_ERR "PAX: bytes at PC: ");
37442 ++ for (i = 0; i < 20; i++) {
37443 ++ unsigned char c;
37444 ++ if (get_user(c, (unsigned char *)pc+i))
37445 ++ printk(KERN_CONT "???????? ");
37446 ++ else
37447 ++ printk(KERN_CONT "%02x ", c);
37448 ++ }
37449 ++ printk("\n");
37450 ++}
37451 ++#endif
37452 ++
37453 + /*
37454 + * This routine handles page faults. It determines the address and the
37455 + * problem, and then passes it off to one of the appropriate routines.
37456 +@@ -157,6 +174,16 @@ bad_area:
37457 + up_read(&mm->mmap_sem);
37458 +
37459 + if (user_mode(regs)) {
37460 ++
37461 ++#ifdef CONFIG_PAX_PAGEEXEC
37462 ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
37463 ++ if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
37464 ++ pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
37465 ++ do_group_exit(SIGKILL);
37466 ++ }
37467 ++ }
37468 ++#endif
37469 ++
37470 + if (exception_trace && printk_ratelimit())
37471 + printk("%s%s[%d]: segfault at %08lx pc %08lx "
37472 + "sp %08lx ecr %lu\n",
37473 +diff -urNp linux-2.6.27.7/arch/blackfin/include/asm/kmap_types.h linux-2.6.27.7/arch/blackfin/include/asm/kmap_types.h
37474 +--- linux-2.6.27.7/arch/blackfin/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
37475 ++++ linux-2.6.27.7/arch/blackfin/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
37476 +@@ -15,6 +15,7 @@ enum km_type {
37477 + KM_IRQ1,
37478 + KM_SOFTIRQ0,
37479 + KM_SOFTIRQ1,
37480 ++ KM_CLEARPAGE,
37481 + KM_TYPE_NR
37482 + };
37483 +
37484 +diff -urNp linux-2.6.27.7/arch/h8300/include/asm/kmap_types.h linux-2.6.27.7/arch/h8300/include/asm/kmap_types.h
37485 +--- linux-2.6.27.7/arch/h8300/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
37486 ++++ linux-2.6.27.7/arch/h8300/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
37487 +@@ -15,6 +15,7 @@ enum km_type {
37488 + KM_IRQ1,
37489 + KM_SOFTIRQ0,
37490 + KM_SOFTIRQ1,
37491 ++ KM_CLEARPAGE,
37492 + KM_TYPE_NR
37493 + };
37494 +
37495 +diff -urNp linux-2.6.27.7/arch/ia64/ia32/binfmt_elf32.c linux-2.6.27.7/arch/ia64/ia32/binfmt_elf32.c
37496 +--- linux-2.6.27.7/arch/ia64/ia32/binfmt_elf32.c 2008-11-07 12:55:34.000000000 -0500
37497 ++++ linux-2.6.27.7/arch/ia64/ia32/binfmt_elf32.c 2008-11-18 03:38:43.000000000 -0500
37498 +@@ -45,6 +45,13 @@ randomize_stack_top(unsigned long stack_
37499 +
37500 + #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
37501 +
37502 ++#ifdef CONFIG_PAX_ASLR
37503 ++#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
37504 ++
37505 ++#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
37506 ++#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
37507 ++#endif
37508 ++
37509 + /* Ugly but avoids duplication */
37510 + #include "../../../fs/binfmt_elf.c"
37511 +
37512 +diff -urNp linux-2.6.27.7/arch/ia64/ia32/ia32priv.h linux-2.6.27.7/arch/ia64/ia32/ia32priv.h
37513 +--- linux-2.6.27.7/arch/ia64/ia32/ia32priv.h 2008-11-07 12:55:34.000000000 -0500
37514 ++++ linux-2.6.27.7/arch/ia64/ia32/ia32priv.h 2008-11-18 03:38:43.000000000 -0500
37515 +@@ -296,7 +296,14 @@ typedef struct compat_siginfo {
37516 + #define ELF_DATA ELFDATA2LSB
37517 + #define ELF_ARCH EM_386
37518 +
37519 +-#define IA32_STACK_TOP IA32_PAGE_OFFSET
37520 ++#ifdef CONFIG_PAX_RANDUSTACK
37521 ++#define __IA32_DELTA_STACK (current->mm->delta_stack)
37522 ++#else
37523 ++#define __IA32_DELTA_STACK 0UL
37524 ++#endif
37525 ++
37526 ++#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
37527 ++
37528 + #define IA32_GATE_OFFSET IA32_PAGE_OFFSET
37529 + #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
37530 +
37531 +diff -urNp linux-2.6.27.7/arch/ia64/include/asm/elf.h linux-2.6.27.7/arch/ia64/include/asm/elf.h
37532 +--- linux-2.6.27.7/arch/ia64/include/asm/elf.h 2008-11-07 12:55:34.000000000 -0500
37533 ++++ linux-2.6.27.7/arch/ia64/include/asm/elf.h 2008-11-18 03:39:50.000000000 -0500
37534 +@@ -43,6 +43,13 @@
37535 + */
37536 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x800000000UL)
37537 +
37538 ++#ifdef CONFIG_PAX_ASLR
37539 ++#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
37540 ++
37541 ++#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
37542 ++#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
37543 ++#endif
37544 ++
37545 + #define PT_IA_64_UNWIND 0x70000001
37546 +
37547 + /* IA-64 relocations: */
37548 +diff -urNp linux-2.6.27.7/arch/ia64/include/asm/kmap_types.h linux-2.6.27.7/arch/ia64/include/asm/kmap_types.h
37549 +--- linux-2.6.27.7/arch/ia64/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
37550 ++++ linux-2.6.27.7/arch/ia64/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
37551 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
37552 + D(10) KM_IRQ1,
37553 + D(11) KM_SOFTIRQ0,
37554 + D(12) KM_SOFTIRQ1,
37555 +-D(13) KM_TYPE_NR
37556 ++D(13) KM_CLEARPAGE,
37557 ++D(14) KM_TYPE_NR
37558 + };
37559 +
37560 + #undef D
37561 +diff -urNp linux-2.6.27.7/arch/ia64/include/asm/pgtable.h linux-2.6.27.7/arch/ia64/include/asm/pgtable.h
37562 +--- linux-2.6.27.7/arch/ia64/include/asm/pgtable.h 2008-11-07 12:55:34.000000000 -0500
37563 ++++ linux-2.6.27.7/arch/ia64/include/asm/pgtable.h 2008-11-18 03:39:50.000000000 -0500
37564 +@@ -143,6 +143,17 @@
37565 + #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
37566 + #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
37567 + #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
37568 ++
37569 ++#ifdef CONFIG_PAX_PAGEEXEC
37570 ++# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
37571 ++# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
37572 ++# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
37573 ++#else
37574 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
37575 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
37576 ++# define PAGE_COPY_NOEXEC PAGE_COPY
37577 ++#endif
37578 ++
37579 + #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
37580 + #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
37581 + #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
37582 +diff -urNp linux-2.6.27.7/arch/ia64/kernel/module.c linux-2.6.27.7/arch/ia64/kernel/module.c
37583 +--- linux-2.6.27.7/arch/ia64/kernel/module.c 2008-11-07 12:55:34.000000000 -0500
37584 ++++ linux-2.6.27.7/arch/ia64/kernel/module.c 2008-11-18 03:38:43.000000000 -0500
37585 +@@ -312,8 +312,7 @@ module_alloc (unsigned long size)
37586 + void
37587 + module_free (struct module *mod, void *module_region)
37588 + {
37589 +- if (mod && mod->arch.init_unw_table &&
37590 +- module_region == mod->module_init) {
37591 ++ if (mod && mod->arch.init_unw_table && module_region == mod->module_init_rx) {
37592 + unw_remove_unwind_table(mod->arch.init_unw_table);
37593 + mod->arch.init_unw_table = NULL;
37594 + }
37595 +@@ -491,15 +490,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
37596 + }
37597 +
37598 + static inline int
37599 ++in_init_rx (const struct module *mod, uint64_t addr)
37600 ++{
37601 ++ return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
37602 ++}
37603 ++
37604 ++static inline int
37605 ++in_init_rw (const struct module *mod, uint64_t addr)
37606 ++{
37607 ++ return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
37608 ++}
37609 ++
37610 ++static inline int
37611 + in_init (const struct module *mod, uint64_t addr)
37612 + {
37613 +- return addr - (uint64_t) mod->module_init < mod->init_size;
37614 ++ return in_init_rx(mod, addr) || in_init_rw(mod, addr);
37615 ++}
37616 ++
37617 ++static inline int
37618 ++in_core_rx (const struct module *mod, uint64_t addr)
37619 ++{
37620 ++ return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
37621 ++}
37622 ++
37623 ++static inline int
37624 ++in_core_rw (const struct module *mod, uint64_t addr)
37625 ++{
37626 ++ return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
37627 + }
37628 +
37629 + static inline int
37630 + in_core (const struct module *mod, uint64_t addr)
37631 + {
37632 +- return addr - (uint64_t) mod->module_core < mod->core_size;
37633 ++ return in_core_rx(mod, addr) || in_core_rw(mod, addr);
37634 + }
37635 +
37636 + static inline int
37637 +@@ -683,7 +706,14 @@ do_reloc (struct module *mod, uint8_t r_
37638 + break;
37639 +
37640 + case RV_BDREL:
37641 +- val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
37642 ++ if (in_init_rx(mod, val))
37643 ++ val -= (uint64_t) mod->module_init_rx;
37644 ++ else if (in_init_rw(mod, val))
37645 ++ val -= (uint64_t) mod->module_init_rw;
37646 ++ else if (in_core_rx(mod, val))
37647 ++ val -= (uint64_t) mod->module_core_rx;
37648 ++ else if (in_core_rw(mod, val))
37649 ++ val -= (uint64_t) mod->module_core_rw;
37650 + break;
37651 +
37652 + case RV_LTV:
37653 +@@ -817,15 +847,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
37654 + * addresses have been selected...
37655 + */
37656 + uint64_t gp;
37657 +- if (mod->core_size > MAX_LTOFF)
37658 ++ if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
37659 + /*
37660 + * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
37661 + * at the end of the module.
37662 + */
37663 +- gp = mod->core_size - MAX_LTOFF / 2;
37664 ++ gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
37665 + else
37666 +- gp = mod->core_size / 2;
37667 +- gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
37668 ++ gp = (mod->core_size_rx + mod->core_size_rw) / 2;
37669 ++ gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
37670 + mod->arch.gp = gp;
37671 + DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
37672 + }
37673 +diff -urNp linux-2.6.27.7/arch/ia64/kernel/sys_ia64.c linux-2.6.27.7/arch/ia64/kernel/sys_ia64.c
37674 +--- linux-2.6.27.7/arch/ia64/kernel/sys_ia64.c 2008-11-07 12:55:34.000000000 -0500
37675 ++++ linux-2.6.27.7/arch/ia64/kernel/sys_ia64.c 2008-11-18 03:38:43.000000000 -0500
37676 +@@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
37677 + if (REGION_NUMBER(addr) == RGN_HPAGE)
37678 + addr = 0;
37679 + #endif
37680 ++
37681 ++#ifdef CONFIG_PAX_RANDMMAP
37682 ++ if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
37683 ++ addr = mm->free_area_cache;
37684 ++ else
37685 ++#endif
37686 ++
37687 + if (!addr)
37688 + addr = mm->free_area_cache;
37689 +
37690 +@@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil
37691 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
37692 + /* At this point: (!vma || addr < vma->vm_end). */
37693 + if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
37694 +- if (start_addr != TASK_UNMAPPED_BASE) {
37695 ++ if (start_addr != mm->mmap_base) {
37696 + /* Start a new search --- just in case we missed some holes. */
37697 +- addr = TASK_UNMAPPED_BASE;
37698 ++ addr = mm->mmap_base;
37699 + goto full_search;
37700 + }
37701 + return -ENOMEM;
37702 +diff -urNp linux-2.6.27.7/arch/ia64/mm/fault.c linux-2.6.27.7/arch/ia64/mm/fault.c
37703 +--- linux-2.6.27.7/arch/ia64/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
37704 ++++ linux-2.6.27.7/arch/ia64/mm/fault.c 2008-11-18 03:38:43.000000000 -0500
37705 +@@ -72,6 +72,23 @@ mapped_kernel_page_is_present (unsigned
37706 + return pte_present(pte);
37707 + }
37708 +
37709 ++#ifdef CONFIG_PAX_PAGEEXEC
37710 ++void pax_report_insns(void *pc, void *sp)
37711 ++{
37712 ++ unsigned long i;
37713 ++
37714 ++ printk(KERN_ERR "PAX: bytes at PC: ");
37715 ++ for (i = 0; i < 8; i++) {
37716 ++ unsigned int c;
37717 ++ if (get_user(c, (unsigned int *)pc+i))
37718 ++ printk(KERN_CONT "???????? ");
37719 ++ else
37720 ++ printk(KERN_CONT "%08x ", c);
37721 ++ }
37722 ++ printk("\n");
37723 ++}
37724 ++#endif
37725 ++
37726 + void __kprobes
37727 + ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
37728 + {
37729 +@@ -145,9 +162,23 @@ ia64_do_page_fault (unsigned long addres
37730 + mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
37731 + | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
37732 +
37733 +- if ((vma->vm_flags & mask) != mask)
37734 ++ if ((vma->vm_flags & mask) != mask) {
37735 ++
37736 ++#ifdef CONFIG_PAX_PAGEEXEC
37737 ++ if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
37738 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
37739 ++ goto bad_area;
37740 ++
37741 ++ up_read(&mm->mmap_sem);
37742 ++ pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
37743 ++ do_group_exit(SIGKILL);
37744 ++ }
37745 ++#endif
37746 ++
37747 + goto bad_area;
37748 +
37749 ++ }
37750 ++
37751 + survive:
37752 + /*
37753 + * If for any reason at all we couldn't handle the fault, make
37754 +diff -urNp linux-2.6.27.7/arch/ia64/mm/init.c linux-2.6.27.7/arch/ia64/mm/init.c
37755 +--- linux-2.6.27.7/arch/ia64/mm/init.c 2008-11-07 12:55:34.000000000 -0500
37756 ++++ linux-2.6.27.7/arch/ia64/mm/init.c 2008-11-18 03:38:43.000000000 -0500
37757 +@@ -122,6 +122,19 @@ ia64_init_addr_space (void)
37758 + vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
37759 + vma->vm_end = vma->vm_start + PAGE_SIZE;
37760 + vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
37761 ++
37762 ++#ifdef CONFIG_PAX_PAGEEXEC
37763 ++ if (current->mm->pax_flags & MF_PAX_PAGEEXEC) {
37764 ++ vma->vm_flags &= ~VM_EXEC;
37765 ++
37766 ++#ifdef CONFIG_PAX_MPROTECT
37767 ++ if (current->mm->pax_flags & MF_PAX_MPROTECT)
37768 ++ vma->vm_flags &= ~VM_MAYEXEC;
37769 ++#endif
37770 ++
37771 ++ }
37772 ++#endif
37773 ++
37774 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
37775 + down_write(&current->mm->mmap_sem);
37776 + if (insert_vm_struct(current->mm, vma)) {
37777 +diff -urNp linux-2.6.27.7/arch/m68knommu/include/asm/kmap_types.h linux-2.6.27.7/arch/m68knommu/include/asm/kmap_types.h
37778 +--- linux-2.6.27.7/arch/m68knommu/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
37779 ++++ linux-2.6.27.7/arch/m68knommu/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
37780 +@@ -15,6 +15,7 @@ enum km_type {
37781 + KM_IRQ1,
37782 + KM_SOFTIRQ0,
37783 + KM_SOFTIRQ1,
37784 ++ KM_CLEARPAGE,
37785 + KM_TYPE_NR
37786 + };
37787 +
37788 +diff -urNp linux-2.6.27.7/arch/mips/kernel/binfmt_elfn32.c linux-2.6.27.7/arch/mips/kernel/binfmt_elfn32.c
37789 +--- linux-2.6.27.7/arch/mips/kernel/binfmt_elfn32.c 2008-11-07 12:55:34.000000000 -0500
37790 ++++ linux-2.6.27.7/arch/mips/kernel/binfmt_elfn32.c 2008-11-18 03:38:43.000000000 -0500
37791 +@@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
37792 + #undef ELF_ET_DYN_BASE
37793 + #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
37794 +
37795 ++#ifdef CONFIG_PAX_ASLR
37796 ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
37797 ++
37798 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
37799 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
37800 ++#endif
37801 ++
37802 + #include <asm/processor.h>
37803 + #include <linux/module.h>
37804 + #include <linux/elfcore.h>
37805 +diff -urNp linux-2.6.27.7/arch/mips/kernel/binfmt_elfo32.c linux-2.6.27.7/arch/mips/kernel/binfmt_elfo32.c
37806 +--- linux-2.6.27.7/arch/mips/kernel/binfmt_elfo32.c 2008-11-07 12:55:34.000000000 -0500
37807 ++++ linux-2.6.27.7/arch/mips/kernel/binfmt_elfo32.c 2008-11-18 03:38:43.000000000 -0500
37808 +@@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
37809 + #undef ELF_ET_DYN_BASE
37810 + #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
37811 +
37812 ++#ifdef CONFIG_PAX_ASLR
37813 ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
37814 ++
37815 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
37816 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
37817 ++#endif
37818 ++
37819 + #include <asm/processor.h>
37820 + #include <linux/module.h>
37821 + #include <linux/elfcore.h>
37822 +diff -urNp linux-2.6.27.7/arch/mips/kernel/process.c linux-2.6.27.7/arch/mips/kernel/process.c
37823 +--- linux-2.6.27.7/arch/mips/kernel/process.c 2008-11-07 12:55:34.000000000 -0500
37824 ++++ linux-2.6.27.7/arch/mips/kernel/process.c 2008-11-18 03:38:43.000000000 -0500
37825 +@@ -458,15 +458,3 @@ unsigned long get_wchan(struct task_stru
37826 + out:
37827 + return pc;
37828 + }
37829 +-
37830 +-/*
37831 +- * Don't forget that the stack pointer must be aligned on a 8 bytes
37832 +- * boundary for 32-bits ABI and 16 bytes for 64-bits ABI.
37833 +- */
37834 +-unsigned long arch_align_stack(unsigned long sp)
37835 +-{
37836 +- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
37837 +- sp -= get_random_int() & ~PAGE_MASK;
37838 +-
37839 +- return sp & ALMASK;
37840 +-}
37841 +diff -urNp linux-2.6.27.7/arch/mips/kernel/syscall.c linux-2.6.27.7/arch/mips/kernel/syscall.c
37842 +--- linux-2.6.27.7/arch/mips/kernel/syscall.c 2008-11-07 12:55:34.000000000 -0500
37843 ++++ linux-2.6.27.7/arch/mips/kernel/syscall.c 2008-11-18 03:38:43.000000000 -0500
37844 +@@ -100,6 +100,11 @@ unsigned long arch_get_unmapped_area(str
37845 + do_color_align = 0;
37846 + if (filp || (flags & MAP_SHARED))
37847 + do_color_align = 1;
37848 ++
37849 ++#ifdef CONFIG_PAX_RANDMMAP
37850 ++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
37851 ++#endif
37852 ++
37853 + if (addr) {
37854 + if (do_color_align)
37855 + addr = COLOUR_ALIGN(addr, pgoff);
37856 +@@ -110,7 +115,7 @@ unsigned long arch_get_unmapped_area(str
37857 + (!vmm || addr + len <= vmm->vm_start))
37858 + return addr;
37859 + }
37860 +- addr = TASK_UNMAPPED_BASE;
37861 ++ addr = current->mm->mmap_base;
37862 + if (do_color_align)
37863 + addr = COLOUR_ALIGN(addr, pgoff);
37864 + else
37865 +diff -urNp linux-2.6.27.7/arch/mips/mm/fault.c linux-2.6.27.7/arch/mips/mm/fault.c
37866 +--- linux-2.6.27.7/arch/mips/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
37867 ++++ linux-2.6.27.7/arch/mips/mm/fault.c 2008-11-18 03:38:43.000000000 -0500
37868 +@@ -26,6 +26,23 @@
37869 + #include <asm/ptrace.h>
37870 + #include <asm/highmem.h> /* For VMALLOC_END */
37871 +
37872 ++#ifdef CONFIG_PAX_PAGEEXEC
37873 ++void pax_report_insns(void *pc)
37874 ++{
37875 ++ unsigned long i;
37876 ++
37877 ++ printk(KERN_ERR "PAX: bytes at PC: ");
37878 ++ for (i = 0; i < 5; i++) {
37879 ++ unsigned int c;
37880 ++ if (get_user(c, (unsigned int *)pc+i))
37881 ++ printk(KERN_CONT "???????? ");
37882 ++ else
37883 ++ printk(KERN_CONT "%08x ", c);
37884 ++ }
37885 ++ printk("\n");
37886 ++}
37887 ++#endif
37888 ++
37889 + /*
37890 + * This routine handles page faults. It determines the address,
37891 + * and the problem, and then passes it off to one of the appropriate
37892 +diff -urNp linux-2.6.27.7/arch/parisc/kernel/module.c linux-2.6.27.7/arch/parisc/kernel/module.c
37893 +--- linux-2.6.27.7/arch/parisc/kernel/module.c 2008-11-07 12:55:34.000000000 -0500
37894 ++++ linux-2.6.27.7/arch/parisc/kernel/module.c 2008-11-18 03:38:43.000000000 -0500
37895 +@@ -75,16 +75,38 @@
37896 +
37897 + /* three functions to determine where in the module core
37898 + * or init pieces the location is */
37899 ++static inline int in_init_rx(struct module *me, void *loc)
37900 ++{
37901 ++ return (loc >= me->module_init_rx &&
37902 ++ loc < (me->module_init_rx + me->init_size_rx));
37903 ++}
37904 ++
37905 ++static inline int in_init_rw(struct module *me, void *loc)
37906 ++{
37907 ++ return (loc >= me->module_init_rw &&
37908 ++ loc < (me->module_init_rw + me->init_size_rw));
37909 ++}
37910 ++
37911 + static inline int in_init(struct module *me, void *loc)
37912 + {
37913 +- return (loc >= me->module_init &&
37914 +- loc <= (me->module_init + me->init_size));
37915 ++ return in_init_rx(me, loc) || in_init_rw(me, loc);
37916 ++}
37917 ++
37918 ++static inline int in_core_rx(struct module *me, void *loc)
37919 ++{
37920 ++ return (loc >= me->module_core_rx &&
37921 ++ loc < (me->module_core_rx + me->core_size_rx));
37922 ++}
37923 ++
37924 ++static inline int in_core_rw(struct module *me, void *loc)
37925 ++{
37926 ++ return (loc >= me->module_core_rw &&
37927 ++ loc < (me->module_core_rw + me->core_size_rw));
37928 + }
37929 +
37930 + static inline int in_core(struct module *me, void *loc)
37931 + {
37932 +- return (loc >= me->module_core &&
37933 +- loc <= (me->module_core + me->core_size));
37934 ++ return in_core_rx(me, loc) || in_core_rw(me, loc);
37935 + }
37936 +
37937 + static inline int in_local(struct module *me, void *loc)
37938 +@@ -298,21 +320,21 @@ int module_frob_arch_sections(CONST Elf_
37939 + }
37940 +
37941 + /* align things a bit */
37942 +- me->core_size = ALIGN(me->core_size, 16);
37943 +- me->arch.got_offset = me->core_size;
37944 +- me->core_size += gots * sizeof(struct got_entry);
37945 +-
37946 +- me->core_size = ALIGN(me->core_size, 16);
37947 +- me->arch.fdesc_offset = me->core_size;
37948 +- me->core_size += fdescs * sizeof(Elf_Fdesc);
37949 +-
37950 +- me->core_size = ALIGN(me->core_size, 16);
37951 +- me->arch.stub_offset = me->core_size;
37952 +- me->core_size += stubs * sizeof(struct stub_entry);
37953 +-
37954 +- me->init_size = ALIGN(me->init_size, 16);
37955 +- me->arch.init_stub_offset = me->init_size;
37956 +- me->init_size += init_stubs * sizeof(struct stub_entry);
37957 ++ me->core_size_rw = ALIGN(me->core_size_rw, 16);
37958 ++ me->arch.got_offset = me->core_size_rw;
37959 ++ me->core_size_rw += gots * sizeof(struct got_entry);
37960 ++
37961 ++ me->core_size_rw = ALIGN(me->core_size_rw, 16);
37962 ++ me->arch.fdesc_offset = me->core_size_rw;
37963 ++ me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
37964 ++
37965 ++ me->core_size_rx = ALIGN(me->core_size_rx, 16);
37966 ++ me->arch.stub_offset = me->core_size_rx;
37967 ++ me->core_size_rx += stubs * sizeof(struct stub_entry);
37968 ++
37969 ++ me->init_size_rx = ALIGN(me->init_size_rx, 16);
37970 ++ me->arch.init_stub_offset = me->init_size_rx;
37971 ++ me->init_size_rx += init_stubs * sizeof(struct stub_entry);
37972 +
37973 + me->arch.got_max = gots;
37974 + me->arch.fdesc_max = fdescs;
37975 +@@ -332,7 +354,7 @@ static Elf64_Word get_got(struct module
37976 +
37977 + BUG_ON(value == 0);
37978 +
37979 +- got = me->module_core + me->arch.got_offset;
37980 ++ got = me->module_core_rw + me->arch.got_offset;
37981 + for (i = 0; got[i].addr; i++)
37982 + if (got[i].addr == value)
37983 + goto out;
37984 +@@ -350,7 +372,7 @@ static Elf64_Word get_got(struct module
37985 + #ifdef CONFIG_64BIT
37986 + static Elf_Addr get_fdesc(struct module *me, unsigned long value)
37987 + {
37988 +- Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
37989 ++ Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
37990 +
37991 + if (!value) {
37992 + printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
37993 +@@ -368,7 +390,7 @@ static Elf_Addr get_fdesc(struct module
37994 +
37995 + /* Create new one */
37996 + fdesc->addr = value;
37997 +- fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
37998 ++ fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
37999 + return (Elf_Addr)fdesc;
38000 + }
38001 + #endif /* CONFIG_64BIT */
38002 +@@ -388,12 +410,12 @@ static Elf_Addr get_stub(struct module *
38003 + if(init_section) {
38004 + i = me->arch.init_stub_count++;
38005 + BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
38006 +- stub = me->module_init + me->arch.init_stub_offset +
38007 ++ stub = me->module_init_rx + me->arch.init_stub_offset +
38008 + i * sizeof(struct stub_entry);
38009 + } else {
38010 + i = me->arch.stub_count++;
38011 + BUG_ON(me->arch.stub_count > me->arch.stub_max);
38012 +- stub = me->module_core + me->arch.stub_offset +
38013 ++ stub = me->module_core_rx + me->arch.stub_offset +
38014 + i * sizeof(struct stub_entry);
38015 + }
38016 +
38017 +@@ -761,7 +783,7 @@ register_unwind_table(struct module *me,
38018 +
38019 + table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
38020 + end = table + sechdrs[me->arch.unwind_section].sh_size;
38021 +- gp = (Elf_Addr)me->module_core + me->arch.got_offset;
38022 ++ gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
38023 +
38024 + DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
38025 + me->arch.unwind_section, table, end, gp);
38026 +diff -urNp linux-2.6.27.7/arch/parisc/kernel/sys_parisc.c linux-2.6.27.7/arch/parisc/kernel/sys_parisc.c
38027 +--- linux-2.6.27.7/arch/parisc/kernel/sys_parisc.c 2008-11-07 12:55:34.000000000 -0500
38028 ++++ linux-2.6.27.7/arch/parisc/kernel/sys_parisc.c 2008-11-18 03:38:43.000000000 -0500
38029 +@@ -98,7 +98,7 @@ unsigned long arch_get_unmapped_area(str
38030 + if (flags & MAP_FIXED)
38031 + return addr;
38032 + if (!addr)
38033 +- addr = TASK_UNMAPPED_BASE;
38034 ++ addr = current->mm->mmap_base;
38035 +
38036 + if (filp) {
38037 + addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
38038 +diff -urNp linux-2.6.27.7/arch/parisc/kernel/traps.c linux-2.6.27.7/arch/parisc/kernel/traps.c
38039 +--- linux-2.6.27.7/arch/parisc/kernel/traps.c 2008-11-07 12:55:34.000000000 -0500
38040 ++++ linux-2.6.27.7/arch/parisc/kernel/traps.c 2008-11-18 03:38:43.000000000 -0500
38041 +@@ -732,9 +732,7 @@ void handle_interruption(int code, struc
38042 +
38043 + down_read(&current->mm->mmap_sem);
38044 + vma = find_vma(current->mm,regs->iaoq[0]);
38045 +- if (vma && (regs->iaoq[0] >= vma->vm_start)
38046 +- && (vma->vm_flags & VM_EXEC)) {
38047 +-
38048 ++ if (vma && (regs->iaoq[0] >= vma->vm_start)) {
38049 + fault_address = regs->iaoq[0];
38050 + fault_space = regs->iasq[0];
38051 +
38052 +diff -urNp linux-2.6.27.7/arch/parisc/mm/fault.c linux-2.6.27.7/arch/parisc/mm/fault.c
38053 +--- linux-2.6.27.7/arch/parisc/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
38054 ++++ linux-2.6.27.7/arch/parisc/mm/fault.c 2008-11-18 03:38:43.000000000 -0500
38055 +@@ -16,6 +16,7 @@
38056 + #include <linux/sched.h>
38057 + #include <linux/interrupt.h>
38058 + #include <linux/module.h>
38059 ++#include <linux/unistd.h>
38060 +
38061 + #include <asm/uaccess.h>
38062 + #include <asm/traps.h>
38063 +@@ -53,7 +54,7 @@ DEFINE_PER_CPU(struct exception_data, ex
38064 + static unsigned long
38065 + parisc_acctyp(unsigned long code, unsigned int inst)
38066 + {
38067 +- if (code == 6 || code == 16)
38068 ++ if (code == 6 || code == 7 || code == 16)
38069 + return VM_EXEC;
38070 +
38071 + switch (inst & 0xf0000000) {
38072 +@@ -139,6 +140,116 @@ parisc_acctyp(unsigned long code, unsign
38073 + }
38074 + #endif
38075 +
38076 ++#ifdef CONFIG_PAX_PAGEEXEC
38077 ++/*
38078 ++ * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
38079 ++ *
38080 ++ * returns 1 when task should be killed
38081 ++ * 2 when rt_sigreturn trampoline was detected
38082 ++ * 3 when unpatched PLT trampoline was detected
38083 ++ */
38084 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
38085 ++{
38086 ++
38087 ++#ifdef CONFIG_PAX_EMUPLT
38088 ++ int err;
38089 ++
38090 ++ do { /* PaX: unpatched PLT emulation */
38091 ++ unsigned int bl, depwi;
38092 ++
38093 ++ err = get_user(bl, (unsigned int *)instruction_pointer(regs));
38094 ++ err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
38095 ++
38096 ++ if (err)
38097 ++ break;
38098 ++
38099 ++ if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
38100 ++ unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
38101 ++
38102 ++ err = get_user(ldw, (unsigned int *)addr);
38103 ++ err |= get_user(bv, (unsigned int *)(addr+4));
38104 ++ err |= get_user(ldw2, (unsigned int *)(addr+8));
38105 ++
38106 ++ if (err)
38107 ++ break;
38108 ++
38109 ++ if (ldw == 0x0E801096U &&
38110 ++ bv == 0xEAC0C000U &&
38111 ++ ldw2 == 0x0E881095U)
38112 ++ {
38113 ++ unsigned int resolver, map;
38114 ++
38115 ++ err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
38116 ++ err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
38117 ++ if (err)
38118 ++ break;
38119 ++
38120 ++ regs->gr[20] = instruction_pointer(regs)+8;
38121 ++ regs->gr[21] = map;
38122 ++ regs->gr[22] = resolver;
38123 ++ regs->iaoq[0] = resolver | 3UL;
38124 ++ regs->iaoq[1] = regs->iaoq[0] + 4;
38125 ++ return 3;
38126 ++ }
38127 ++ }
38128 ++ } while (0);
38129 ++#endif
38130 ++
38131 ++#ifdef CONFIG_PAX_EMUTRAMP
38132 ++
38133 ++#ifndef CONFIG_PAX_EMUSIGRT
38134 ++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
38135 ++ return 1;
38136 ++#endif
38137 ++
38138 ++ do { /* PaX: rt_sigreturn emulation */
38139 ++ unsigned int ldi1, ldi2, bel, nop;
38140 ++
38141 ++ err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
38142 ++ err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
38143 ++ err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
38144 ++ err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
38145 ++
38146 ++ if (err)
38147 ++ break;
38148 ++
38149 ++ if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
38150 ++ ldi2 == 0x3414015AU &&
38151 ++ bel == 0xE4008200U &&
38152 ++ nop == 0x08000240U)
38153 ++ {
38154 ++ regs->gr[25] = (ldi1 & 2) >> 1;
38155 ++ regs->gr[20] = __NR_rt_sigreturn;
38156 ++ regs->gr[31] = regs->iaoq[1] + 16;
38157 ++ regs->sr[0] = regs->iasq[1];
38158 ++ regs->iaoq[0] = 0x100UL;
38159 ++ regs->iaoq[1] = regs->iaoq[0] + 4;
38160 ++ regs->iasq[0] = regs->sr[2];
38161 ++ regs->iasq[1] = regs->sr[2];
38162 ++ return 2;
38163 ++ }
38164 ++ } while (0);
38165 ++#endif
38166 ++
38167 ++ return 1;
38168 ++}
38169 ++
38170 ++void pax_report_insns(void *pc, void *sp)
38171 ++{
38172 ++ unsigned long i;
38173 ++
38174 ++ printk(KERN_ERR "PAX: bytes at PC: ");
38175 ++ for (i = 0; i < 5; i++) {
38176 ++ unsigned int c;
38177 ++ if (get_user(c, (unsigned int *)pc+i))
38178 ++ printk(KERN_CONT "???????? ");
38179 ++ else
38180 ++ printk(KERN_CONT "%08x ", c);
38181 ++ }
38182 ++ printk("\n");
38183 ++}
38184 ++#endif
38185 ++
38186 + void do_page_fault(struct pt_regs *regs, unsigned long code,
38187 + unsigned long address)
38188 + {
38189 +@@ -165,8 +276,33 @@ good_area:
38190 +
38191 + acc_type = parisc_acctyp(code,regs->iir);
38192 +
38193 +- if ((vma->vm_flags & acc_type) != acc_type)
38194 ++ if ((vma->vm_flags & acc_type) != acc_type) {
38195 ++
38196 ++#ifdef CONFIG_PAX_PAGEEXEC
38197 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
38198 ++ (address & ~3UL) == instruction_pointer(regs))
38199 ++ {
38200 ++ up_read(&mm->mmap_sem);
38201 ++ switch (pax_handle_fetch_fault(regs)) {
38202 ++
38203 ++#ifdef CONFIG_PAX_EMUPLT
38204 ++ case 3:
38205 ++ return;
38206 ++#endif
38207 ++
38208 ++#ifdef CONFIG_PAX_EMUTRAMP
38209 ++ case 2:
38210 ++ return;
38211 ++#endif
38212 ++
38213 ++ }
38214 ++ pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
38215 ++ do_group_exit(SIGKILL);
38216 ++ }
38217 ++#endif
38218 ++
38219 + goto bad_area;
38220 ++ }
38221 +
38222 + /*
38223 + * If for any reason at all we couldn't handle the fault, make
38224 +diff -urNp linux-2.6.27.7/arch/powerpc/include/asm/elf.h linux-2.6.27.7/arch/powerpc/include/asm/elf.h
38225 +--- linux-2.6.27.7/arch/powerpc/include/asm/elf.h 2008-11-07 12:55:34.000000000 -0500
38226 ++++ linux-2.6.27.7/arch/powerpc/include/asm/elf.h 2008-11-18 03:39:50.000000000 -0500
38227 +@@ -180,6 +180,18 @@ typedef elf_fpreg_t elf_vsrreghalf_t32[E
38228 +
38229 + #define ELF_ET_DYN_BASE (0x20000000)
38230 +
38231 ++#ifdef CONFIG_PAX_ASLR
38232 ++#define PAX_ELF_ET_DYN_BASE (0x10000000UL)
38233 ++
38234 ++#ifdef __powerpc64__
38235 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
38236 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
38237 ++#else
38238 ++#define PAX_DELTA_MMAP_LEN 15
38239 ++#define PAX_DELTA_STACK_LEN 15
38240 ++#endif
38241 ++#endif
38242 ++
38243 + /*
38244 + * Our registers are always unsigned longs, whether we're a 32 bit
38245 + * process or 64 bit, on either a 64 bit or 32 bit kernel.
38246 +diff -urNp linux-2.6.27.7/arch/powerpc/include/asm/kmap_types.h linux-2.6.27.7/arch/powerpc/include/asm/kmap_types.h
38247 +--- linux-2.6.27.7/arch/powerpc/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
38248 ++++ linux-2.6.27.7/arch/powerpc/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
38249 +@@ -26,6 +26,7 @@ enum km_type {
38250 + KM_SOFTIRQ1,
38251 + KM_PPC_SYNC_PAGE,
38252 + KM_PPC_SYNC_ICACHE,
38253 ++ KM_CLEARPAGE,
38254 + KM_TYPE_NR
38255 + };
38256 +
38257 +diff -urNp linux-2.6.27.7/arch/powerpc/include/asm/page_64.h linux-2.6.27.7/arch/powerpc/include/asm/page_64.h
38258 +--- linux-2.6.27.7/arch/powerpc/include/asm/page_64.h 2008-11-07 12:55:34.000000000 -0500
38259 ++++ linux-2.6.27.7/arch/powerpc/include/asm/page_64.h 2008-11-18 03:39:50.000000000 -0500
38260 +@@ -170,15 +170,18 @@ do { \
38261 + * stack by default, so in the absense of a PT_GNU_STACK program header
38262 + * we turn execute permission off.
38263 + */
38264 +-#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
38265 +- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
38266 ++#define VM_STACK_DEFAULT_FLAGS32 \
38267 ++ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
38268 ++ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
38269 +
38270 + #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
38271 + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
38272 +
38273 ++#ifndef CONFIG_PAX_PAGEEXEC
38274 + #define VM_STACK_DEFAULT_FLAGS \
38275 + (test_thread_flag(TIF_32BIT) ? \
38276 + VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
38277 ++#endif
38278 +
38279 + #include <asm-generic/page.h>
38280 +
38281 +diff -urNp linux-2.6.27.7/arch/powerpc/include/asm/page.h linux-2.6.27.7/arch/powerpc/include/asm/page.h
38282 +--- linux-2.6.27.7/arch/powerpc/include/asm/page.h 2008-11-07 12:55:34.000000000 -0500
38283 ++++ linux-2.6.27.7/arch/powerpc/include/asm/page.h 2008-11-18 03:39:50.000000000 -0500
38284 +@@ -100,8 +100,9 @@ extern phys_addr_t kernstart_addr;
38285 + * and needs to be executable. This means the whole heap ends
38286 + * up being executable.
38287 + */
38288 +-#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
38289 +- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
38290 ++#define VM_DATA_DEFAULT_FLAGS32 \
38291 ++ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
38292 ++ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
38293 +
38294 + #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
38295 + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
38296 +diff -urNp linux-2.6.27.7/arch/powerpc/kernel/module_32.c linux-2.6.27.7/arch/powerpc/kernel/module_32.c
38297 +--- linux-2.6.27.7/arch/powerpc/kernel/module_32.c 2008-11-07 12:55:34.000000000 -0500
38298 ++++ linux-2.6.27.7/arch/powerpc/kernel/module_32.c 2008-11-18 03:38:43.000000000 -0500
38299 +@@ -158,7 +158,7 @@ int module_frob_arch_sections(Elf32_Ehdr
38300 + me->arch.core_plt_section = i;
38301 + }
38302 + if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
38303 +- printk("Module doesn't contain .plt or .init.plt sections.\n");
38304 ++ printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
38305 + return -ENOEXEC;
38306 + }
38307 +
38308 +@@ -199,11 +199,16 @@ static uint32_t do_plt_call(void *locati
38309 +
38310 + DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
38311 + /* Init, or core PLT? */
38312 +- if (location >= mod->module_core
38313 +- && location < mod->module_core + mod->core_size)
38314 ++ if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
38315 ++ (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
38316 + entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
38317 +- else
38318 ++ else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
38319 ++ (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
38320 + entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
38321 ++ else {
38322 ++ printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
38323 ++ return ~0UL;
38324 ++ }
38325 +
38326 + /* Find this entry, or if that fails, the next avail. entry */
38327 + while (entry->jump[0]) {
38328 +diff -urNp linux-2.6.27.7/arch/powerpc/kernel/signal_32.c linux-2.6.27.7/arch/powerpc/kernel/signal_32.c
38329 +--- linux-2.6.27.7/arch/powerpc/kernel/signal_32.c 2008-11-07 12:55:34.000000000 -0500
38330 ++++ linux-2.6.27.7/arch/powerpc/kernel/signal_32.c 2008-11-18 03:38:43.000000000 -0500
38331 +@@ -857,7 +857,7 @@ int handle_rt_signal32(unsigned long sig
38332 + /* Save user registers on the stack */
38333 + frame = &rt_sf->uc.uc_mcontext;
38334 + addr = frame;
38335 +- if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
38336 ++ if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
38337 + if (save_user_regs(regs, frame, 0))
38338 + goto badframe;
38339 + regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
38340 +diff -urNp linux-2.6.27.7/arch/powerpc/kernel/signal_64.c linux-2.6.27.7/arch/powerpc/kernel/signal_64.c
38341 +--- linux-2.6.27.7/arch/powerpc/kernel/signal_64.c 2008-11-07 12:55:34.000000000 -0500
38342 ++++ linux-2.6.27.7/arch/powerpc/kernel/signal_64.c 2008-11-18 03:38:43.000000000 -0500
38343 +@@ -434,7 +434,7 @@ int handle_rt_signal64(int signr, struct
38344 + current->thread.fpscr.val = 0;
38345 +
38346 + /* Set up to return from userspace. */
38347 +- if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
38348 ++ if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
38349 + regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
38350 + } else {
38351 + err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
38352 +diff -urNp linux-2.6.27.7/arch/powerpc/kernel/vdso.c linux-2.6.27.7/arch/powerpc/kernel/vdso.c
38353 +--- linux-2.6.27.7/arch/powerpc/kernel/vdso.c 2008-11-07 12:55:34.000000000 -0500
38354 ++++ linux-2.6.27.7/arch/powerpc/kernel/vdso.c 2008-11-18 03:38:43.000000000 -0500
38355 +@@ -212,7 +212,7 @@ int arch_setup_additional_pages(struct l
38356 + vdso_base = VDSO32_MBASE;
38357 + #endif
38358 +
38359 +- current->mm->context.vdso_base = 0;
38360 ++ current->mm->context.vdso_base = ~0UL;
38361 +
38362 + /* vDSO has a problem and was disabled, just don't "enable" it for the
38363 + * process
38364 +@@ -229,7 +229,7 @@ int arch_setup_additional_pages(struct l
38365 + */
38366 + down_write(&mm->mmap_sem);
38367 + vdso_base = get_unmapped_area(NULL, vdso_base,
38368 +- vdso_pages << PAGE_SHIFT, 0, 0);
38369 ++ vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
38370 + if (IS_ERR_VALUE(vdso_base)) {
38371 + rc = vdso_base;
38372 + goto fail_mmapsem;
38373 +diff -urNp linux-2.6.27.7/arch/powerpc/mm/fault.c linux-2.6.27.7/arch/powerpc/mm/fault.c
38374 +--- linux-2.6.27.7/arch/powerpc/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
38375 ++++ linux-2.6.27.7/arch/powerpc/mm/fault.c 2008-11-18 03:38:43.000000000 -0500
38376 +@@ -29,6 +29,10 @@
38377 + #include <linux/module.h>
38378 + #include <linux/kprobes.h>
38379 + #include <linux/kdebug.h>
38380 ++#include <linux/slab.h>
38381 ++#include <linux/pagemap.h>
38382 ++#include <linux/compiler.h>
38383 ++#include <linux/unistd.h>
38384 +
38385 + #include <asm/page.h>
38386 + #include <asm/pgtable.h>
38387 +@@ -62,6 +66,363 @@ static inline int notify_page_fault(stru
38388 + }
38389 + #endif
38390 +
38391 ++#ifdef CONFIG_PAX_EMUSIGRT
38392 ++void pax_syscall_close(struct vm_area_struct *vma)
38393 ++{
38394 ++ vma->vm_mm->call_syscall = 0UL;
38395 ++}
38396 ++
38397 ++static int pax_syscall_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
38398 ++{
38399 ++ unsigned int *kaddr;
38400 ++
38401 ++ vmf->page = alloc_page(GFP_HIGHUSER);
38402 ++ if (!vmf->page)
38403 ++ return VM_FAULT_OOM;
38404 ++
38405 ++ kaddr = kmap(vmf->page);
38406 ++ memset(kaddr, 0, PAGE_SIZE);
38407 ++ kaddr[0] = 0x44000002U; /* sc */
38408 ++ __flush_dcache_icache(kaddr);
38409 ++ kunmap(vmf->page);
38410 ++ return VM_FAULT_MAJOR;
38411 ++}
38412 ++
38413 ++static struct vm_operations_struct pax_vm_ops = {
38414 ++ .close = pax_syscall_close,
38415 ++ .fault = pax_syscall_fault
38416 ++};
38417 ++
38418 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
38419 ++{
38420 ++ int ret;
38421 ++
38422 ++ vma->vm_mm = current->mm;
38423 ++ vma->vm_start = addr;
38424 ++ vma->vm_end = addr + PAGE_SIZE;
38425 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
38426 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
38427 ++ vma->vm_ops = &pax_vm_ops;
38428 ++
38429 ++ ret = insert_vm_struct(current->mm, vma);
38430 ++ if (ret)
38431 ++ return ret;
38432 ++
38433 ++ ++current->mm->total_vm;
38434 ++ return 0;
38435 ++}
38436 ++#endif
38437 ++
38438 ++#ifdef CONFIG_PAX_PAGEEXEC
38439 ++/*
38440 ++ * PaX: decide what to do with offenders (regs->nip = fault address)
38441 ++ *
38442 ++ * returns 1 when task should be killed
38443 ++ * 2 when patched GOT trampoline was detected
38444 ++ * 3 when patched PLT trampoline was detected
38445 ++ * 4 when unpatched PLT trampoline was detected
38446 ++ * 5 when sigreturn trampoline was detected
38447 ++ * 6 when rt_sigreturn trampoline was detected
38448 ++ */
38449 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
38450 ++{
38451 ++
38452 ++#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
38453 ++ int err;
38454 ++#endif
38455 ++
38456 ++#ifdef CONFIG_PAX_EMUPLT
38457 ++ do { /* PaX: patched GOT emulation */
38458 ++ unsigned int blrl;
38459 ++
38460 ++ err = get_user(blrl, (unsigned int *)regs->nip);
38461 ++
38462 ++ if (!err && blrl == 0x4E800021U) {
38463 ++ unsigned long temp = regs->nip;
38464 ++
38465 ++ regs->nip = regs->link & 0xFFFFFFFCUL;
38466 ++ regs->link = temp + 4UL;
38467 ++ return 2;
38468 ++ }
38469 ++ } while (0);
38470 ++
38471 ++ do { /* PaX: patched PLT emulation #1 */
38472 ++ unsigned int b;
38473 ++
38474 ++ err = get_user(b, (unsigned int *)regs->nip);
38475 ++
38476 ++ if (!err && (b & 0xFC000003U) == 0x48000000U) {
38477 ++ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
38478 ++ return 3;
38479 ++ }
38480 ++ } while (0);
38481 ++
38482 ++ do { /* PaX: unpatched PLT emulation #1 */
38483 ++ unsigned int li, b;
38484 ++
38485 ++ err = get_user(li, (unsigned int *)regs->nip);
38486 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
38487 ++
38488 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
38489 ++ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
38490 ++ unsigned long addr = b | 0xFC000000UL;
38491 ++
38492 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
38493 ++ err = get_user(rlwinm, (unsigned int *)addr);
38494 ++ err |= get_user(add, (unsigned int *)(addr+4));
38495 ++ err |= get_user(li2, (unsigned int *)(addr+8));
38496 ++ err |= get_user(addis2, (unsigned int *)(addr+12));
38497 ++ err |= get_user(mtctr, (unsigned int *)(addr+16));
38498 ++ err |= get_user(li3, (unsigned int *)(addr+20));
38499 ++ err |= get_user(addis3, (unsigned int *)(addr+24));
38500 ++ err |= get_user(bctr, (unsigned int *)(addr+28));
38501 ++
38502 ++ if (err)
38503 ++ break;
38504 ++
38505 ++ if (rlwinm == 0x556C083CU &&
38506 ++ add == 0x7D6C5A14U &&
38507 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
38508 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
38509 ++ mtctr == 0x7D8903A6U &&
38510 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
38511 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
38512 ++ bctr == 0x4E800420U)
38513 ++ {
38514 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
38515 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
38516 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
38517 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
38518 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
38519 ++ regs->nip = regs->ctr;
38520 ++ return 4;
38521 ++ }
38522 ++ }
38523 ++ } while (0);
38524 ++
38525 ++#if 0
38526 ++ do { /* PaX: unpatched PLT emulation #2 */
38527 ++ unsigned int lis, lwzu, b, bctr;
38528 ++
38529 ++ err = get_user(lis, (unsigned int *)regs->nip);
38530 ++ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
38531 ++ err |= get_user(b, (unsigned int *)(regs->nip+8));
38532 ++ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
38533 ++
38534 ++ if (err)
38535 ++ break;
38536 ++
38537 ++ if ((lis & 0xFFFF0000U) == 0x39600000U &&
38538 ++ (lwzu & 0xU) == 0xU &&
38539 ++ (b & 0xFC000003U) == 0x48000000U &&
38540 ++ bctr == 0x4E800420U)
38541 ++ {
38542 ++ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
38543 ++ unsigned long addr = b | 0xFC000000UL;
38544 ++
38545 ++ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
38546 ++ err = get_user(addis, (unsigned int *)addr);
38547 ++ err |= get_user(addi, (unsigned int *)(addr+4));
38548 ++ err |= get_user(rlwinm, (unsigned int *)(addr+8));
38549 ++ err |= get_user(add, (unsigned int *)(addr+12));
38550 ++ err |= get_user(li2, (unsigned int *)(addr+16));
38551 ++ err |= get_user(addis2, (unsigned int *)(addr+20));
38552 ++ err |= get_user(mtctr, (unsigned int *)(addr+24));
38553 ++ err |= get_user(li3, (unsigned int *)(addr+28));
38554 ++ err |= get_user(addis3, (unsigned int *)(addr+32));
38555 ++ err |= get_user(bctr, (unsigned int *)(addr+36));
38556 ++
38557 ++ if (err)
38558 ++ break;
38559 ++
38560 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
38561 ++ (addi & 0xFFFF0000U) == 0x396B0000U &&
38562 ++ rlwinm == 0x556C083CU &&
38563 ++ add == 0x7D6C5A14U &&
38564 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
38565 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
38566 ++ mtctr == 0x7D8903A6U &&
38567 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
38568 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
38569 ++ bctr == 0x4E800420U)
38570 ++ {
38571 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
38572 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
38573 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
38574 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
38575 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
38576 ++ regs->nip = regs->ctr;
38577 ++ return 4;
38578 ++ }
38579 ++ }
38580 ++ } while (0);
38581 ++#endif
38582 ++
38583 ++ do { /* PaX: unpatched PLT emulation #3 */
38584 ++ unsigned int li, b;
38585 ++
38586 ++ err = get_user(li, (unsigned int *)regs->nip);
38587 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
38588 ++
38589 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
38590 ++ unsigned int addis, lwz, mtctr, bctr;
38591 ++ unsigned long addr = b | 0xFC000000UL;
38592 ++
38593 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
38594 ++ err = get_user(addis, (unsigned int *)addr);
38595 ++ err |= get_user(lwz, (unsigned int *)(addr+4));
38596 ++ err |= get_user(mtctr, (unsigned int *)(addr+8));
38597 ++ err |= get_user(bctr, (unsigned int *)(addr+12));
38598 ++
38599 ++ if (err)
38600 ++ break;
38601 ++
38602 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
38603 ++ (lwz & 0xFFFF0000U) == 0x816B0000U &&
38604 ++ mtctr == 0x7D6903A6U &&
38605 ++ bctr == 0x4E800420U)
38606 ++ {
38607 ++ unsigned int r11;
38608 ++
38609 ++ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
38610 ++ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
38611 ++
38612 ++ err = get_user(r11, (unsigned int *)addr);
38613 ++ if (err)
38614 ++ break;
38615 ++
38616 ++ regs->gpr[PT_R11] = r11;
38617 ++ regs->ctr = r11;
38618 ++ regs->nip = r11;
38619 ++ return 4;
38620 ++ }
38621 ++ }
38622 ++ } while (0);
38623 ++#endif
38624 ++
38625 ++#ifdef CONFIG_PAX_EMUSIGRT
38626 ++ do { /* PaX: sigreturn emulation */
38627 ++ unsigned int li, sc;
38628 ++
38629 ++ err = get_user(li, (unsigned int *)regs->nip);
38630 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
38631 ++
38632 ++ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
38633 ++ struct vm_area_struct *vma;
38634 ++ unsigned long call_syscall;
38635 ++
38636 ++ down_read(&current->mm->mmap_sem);
38637 ++ call_syscall = current->mm->call_syscall;
38638 ++ up_read(&current->mm->mmap_sem);
38639 ++ if (likely(call_syscall))
38640 ++ goto emulate;
38641 ++
38642 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
38643 ++
38644 ++ down_write(&current->mm->mmap_sem);
38645 ++ if (current->mm->call_syscall) {
38646 ++ call_syscall = current->mm->call_syscall;
38647 ++ up_write(&current->mm->mmap_sem);
38648 ++ if (vma)
38649 ++ kmem_cache_free(vm_area_cachep, vma);
38650 ++ goto emulate;
38651 ++ }
38652 ++
38653 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
38654 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
38655 ++ up_write(&current->mm->mmap_sem);
38656 ++ if (vma)
38657 ++ kmem_cache_free(vm_area_cachep, vma);
38658 ++ return 1;
38659 ++ }
38660 ++
38661 ++ if (pax_insert_vma(vma, call_syscall)) {
38662 ++ up_write(&current->mm->mmap_sem);
38663 ++ kmem_cache_free(vm_area_cachep, vma);
38664 ++ return 1;
38665 ++ }
38666 ++
38667 ++ current->mm->call_syscall = call_syscall;
38668 ++ up_write(&current->mm->mmap_sem);
38669 ++
38670 ++emulate:
38671 ++ regs->gpr[PT_R0] = __NR_sigreturn;
38672 ++ regs->nip = call_syscall;
38673 ++ return 5;
38674 ++ }
38675 ++ } while (0);
38676 ++
38677 ++ do { /* PaX: rt_sigreturn emulation */
38678 ++ unsigned int li, sc;
38679 ++
38680 ++ err = get_user(li, (unsigned int *)regs->nip);
38681 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
38682 ++
38683 ++ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
38684 ++ struct vm_area_struct *vma;
38685 ++ unsigned int call_syscall;
38686 ++
38687 ++ down_read(&current->mm->mmap_sem);
38688 ++ call_syscall = current->mm->call_syscall;
38689 ++ up_read(&current->mm->mmap_sem);
38690 ++ if (likely(call_syscall))
38691 ++ goto rt_emulate;
38692 ++
38693 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
38694 ++
38695 ++ down_write(&current->mm->mmap_sem);
38696 ++ if (current->mm->call_syscall) {
38697 ++ call_syscall = current->mm->call_syscall;
38698 ++ up_write(&current->mm->mmap_sem);
38699 ++ if (vma)
38700 ++ kmem_cache_free(vm_area_cachep, vma);
38701 ++ goto rt_emulate;
38702 ++ }
38703 ++
38704 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
38705 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
38706 ++ up_write(&current->mm->mmap_sem);
38707 ++ if (vma)
38708 ++ kmem_cache_free(vm_area_cachep, vma);
38709 ++ return 1;
38710 ++ }
38711 ++
38712 ++ if (pax_insert_vma(vma, call_syscall)) {
38713 ++ up_write(&current->mm->mmap_sem);
38714 ++ kmem_cache_free(vm_area_cachep, vma);
38715 ++ return 1;
38716 ++ }
38717 ++
38718 ++ current->mm->call_syscall = call_syscall;
38719 ++ up_write(&current->mm->mmap_sem);
38720 ++
38721 ++rt_emulate:
38722 ++ regs->gpr[PT_R0] = __NR_rt_sigreturn;
38723 ++ regs->nip = call_syscall;
38724 ++ return 6;
38725 ++ }
38726 ++ } while (0);
38727 ++#endif
38728 ++
38729 ++ return 1;
38730 ++}
38731 ++
38732 ++void pax_report_insns(void *pc, void *sp)
38733 ++{
38734 ++ unsigned long i;
38735 ++
38736 ++ printk(KERN_ERR "PAX: bytes at PC: ");
38737 ++ for (i = 0; i < 5; i++) {
38738 ++ unsigned int c;
38739 ++ if (get_user(c, (unsigned int *)pc+i))
38740 ++ printk(KERN_CONT "???????? ");
38741 ++ else
38742 ++ printk(KERN_CONT "%08x ", c);
38743 ++ }
38744 ++ printk("\n");
38745 ++}
38746 ++#endif
38747 ++
38748 + /*
38749 + * Check whether the instruction at regs->nip is a store using
38750 + * an update addressing form which will update r1.
38751 +@@ -132,7 +493,7 @@ int __kprobes do_page_fault(struct pt_re
38752 + * indicate errors in DSISR but can validly be set in SRR1.
38753 + */
38754 + if (trap == 0x400)
38755 +- error_code &= 0x48200000;
38756 ++ error_code &= 0x58200000;
38757 + else
38758 + is_write = error_code & DSISR_ISSTORE;
38759 + #else
38760 +@@ -331,6 +692,37 @@ bad_area:
38761 + bad_area_nosemaphore:
38762 + /* User mode accesses cause a SIGSEGV */
38763 + if (user_mode(regs)) {
38764 ++
38765 ++#ifdef CONFIG_PAX_PAGEEXEC
38766 ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
38767 ++#ifdef CONFIG_PPC64
38768 ++ if (is_exec && (error_code & DSISR_PROTFAULT)) {
38769 ++#else
38770 ++ if (is_exec && regs->nip == address) {
38771 ++#endif
38772 ++ switch (pax_handle_fetch_fault(regs)) {
38773 ++
38774 ++#ifdef CONFIG_PAX_EMUPLT
38775 ++ case 2:
38776 ++ case 3:
38777 ++ case 4:
38778 ++ return 0;
38779 ++#endif
38780 ++
38781 ++#ifdef CONFIG_PAX_EMUSIGRT
38782 ++ case 5:
38783 ++ case 6:
38784 ++ return 0;
38785 ++#endif
38786 ++
38787 ++ }
38788 ++
38789 ++ pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[PT_R1]);
38790 ++ do_group_exit(SIGKILL);
38791 ++ }
38792 ++ }
38793 ++#endif
38794 ++
38795 + _exception(SIGSEGV, regs, code, address);
38796 + return 0;
38797 + }
38798 +diff -urNp linux-2.6.27.7/arch/powerpc/mm/mmap.c linux-2.6.27.7/arch/powerpc/mm/mmap.c
38799 +--- linux-2.6.27.7/arch/powerpc/mm/mmap.c 2008-11-07 12:55:34.000000000 -0500
38800 ++++ linux-2.6.27.7/arch/powerpc/mm/mmap.c 2008-11-18 03:38:43.000000000 -0500
38801 +@@ -75,10 +75,22 @@ void arch_pick_mmap_layout(struct mm_str
38802 + */
38803 + if (mmap_is_legacy()) {
38804 + mm->mmap_base = TASK_UNMAPPED_BASE;
38805 ++
38806 ++#ifdef CONFIG_PAX_RANDMMAP
38807 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
38808 ++ mm->mmap_base += mm->delta_mmap;
38809 ++#endif
38810 ++
38811 + mm->get_unmapped_area = arch_get_unmapped_area;
38812 + mm->unmap_area = arch_unmap_area;
38813 + } else {
38814 + mm->mmap_base = mmap_base();
38815 ++
38816 ++#ifdef CONFIG_PAX_RANDMMAP
38817 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
38818 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
38819 ++#endif
38820 ++
38821 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
38822 + mm->unmap_area = arch_unmap_area_topdown;
38823 + }
38824 +diff -urNp linux-2.6.27.7/arch/s390/include/asm/kmap_types.h linux-2.6.27.7/arch/s390/include/asm/kmap_types.h
38825 +--- linux-2.6.27.7/arch/s390/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
38826 ++++ linux-2.6.27.7/arch/s390/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
38827 +@@ -16,6 +16,7 @@ enum km_type {
38828 + KM_IRQ1,
38829 + KM_SOFTIRQ0,
38830 + KM_SOFTIRQ1,
38831 ++ KM_CLEARPAGE,
38832 + KM_TYPE_NR
38833 + };
38834 +
38835 +diff -urNp linux-2.6.27.7/arch/s390/kernel/module.c linux-2.6.27.7/arch/s390/kernel/module.c
38836 +--- linux-2.6.27.7/arch/s390/kernel/module.c 2008-11-07 12:55:34.000000000 -0500
38837 ++++ linux-2.6.27.7/arch/s390/kernel/module.c 2008-11-18 03:38:43.000000000 -0500
38838 +@@ -166,11 +166,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
38839 +
38840 + /* Increase core size by size of got & plt and set start
38841 + offsets for got and plt. */
38842 +- me->core_size = ALIGN(me->core_size, 4);
38843 +- me->arch.got_offset = me->core_size;
38844 +- me->core_size += me->arch.got_size;
38845 +- me->arch.plt_offset = me->core_size;
38846 +- me->core_size += me->arch.plt_size;
38847 ++ me->core_size_rw = ALIGN(me->core_size_rw, 4);
38848 ++ me->arch.got_offset = me->core_size_rw;
38849 ++ me->core_size_rw += me->arch.got_size;
38850 ++ me->arch.plt_offset = me->core_size_rx;
38851 ++ me->core_size_rx += me->arch.plt_size;
38852 + return 0;
38853 + }
38854 +
38855 +@@ -256,7 +256,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
38856 + if (info->got_initialized == 0) {
38857 + Elf_Addr *gotent;
38858 +
38859 +- gotent = me->module_core + me->arch.got_offset +
38860 ++ gotent = me->module_core_rw + me->arch.got_offset +
38861 + info->got_offset;
38862 + *gotent = val;
38863 + info->got_initialized = 1;
38864 +@@ -280,7 +280,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
38865 + else if (r_type == R_390_GOTENT ||
38866 + r_type == R_390_GOTPLTENT)
38867 + *(unsigned int *) loc =
38868 +- (val + (Elf_Addr) me->module_core - loc) >> 1;
38869 ++ (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
38870 + else if (r_type == R_390_GOT64 ||
38871 + r_type == R_390_GOTPLT64)
38872 + *(unsigned long *) loc = val;
38873 +@@ -294,7 +294,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
38874 + case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
38875 + if (info->plt_initialized == 0) {
38876 + unsigned int *ip;
38877 +- ip = me->module_core + me->arch.plt_offset +
38878 ++ ip = me->module_core_rx + me->arch.plt_offset +
38879 + info->plt_offset;
38880 + #ifndef CONFIG_64BIT
38881 + ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
38882 +@@ -316,7 +316,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
38883 + val = me->arch.plt_offset - me->arch.got_offset +
38884 + info->plt_offset + rela->r_addend;
38885 + else
38886 +- val = (Elf_Addr) me->module_core +
38887 ++ val = (Elf_Addr) me->module_core_rx +
38888 + me->arch.plt_offset + info->plt_offset +
38889 + rela->r_addend - loc;
38890 + if (r_type == R_390_PLT16DBL)
38891 +@@ -336,7 +336,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
38892 + case R_390_GOTOFF32: /* 32 bit offset to GOT. */
38893 + case R_390_GOTOFF64: /* 64 bit offset to GOT. */
38894 + val = val + rela->r_addend -
38895 +- ((Elf_Addr) me->module_core + me->arch.got_offset);
38896 ++ ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
38897 + if (r_type == R_390_GOTOFF16)
38898 + *(unsigned short *) loc = val;
38899 + else if (r_type == R_390_GOTOFF32)
38900 +@@ -346,7 +346,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
38901 + break;
38902 + case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
38903 + case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
38904 +- val = (Elf_Addr) me->module_core + me->arch.got_offset +
38905 ++ val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
38906 + rela->r_addend - loc;
38907 + if (r_type == R_390_GOTPC)
38908 + *(unsigned int *) loc = val;
38909 +diff -urNp linux-2.6.27.7/arch/sh/include/asm/kmap_types.h linux-2.6.27.7/arch/sh/include/asm/kmap_types.h
38910 +--- linux-2.6.27.7/arch/sh/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
38911 ++++ linux-2.6.27.7/arch/sh/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
38912 +@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
38913 + D(10) KM_IRQ1,
38914 + D(11) KM_SOFTIRQ0,
38915 + D(12) KM_SOFTIRQ1,
38916 +-D(13) KM_TYPE_NR
38917 ++D(13) KM_CLEARPAGE,
38918 ++D(14) KM_TYPE_NR
38919 + };
38920 +
38921 + #undef D
38922 +diff -urNp linux-2.6.27.7/arch/sparc/include/asm/elf_32.h linux-2.6.27.7/arch/sparc/include/asm/elf_32.h
38923 +--- linux-2.6.27.7/arch/sparc/include/asm/elf_32.h 2008-11-07 12:55:34.000000000 -0500
38924 ++++ linux-2.6.27.7/arch/sparc/include/asm/elf_32.h 2008-11-18 03:39:50.000000000 -0500
38925 +@@ -119,6 +119,13 @@ typedef struct {
38926 +
38927 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
38928 +
38929 ++#ifdef CONFIG_PAX_ASLR
38930 ++#define PAX_ELF_ET_DYN_BASE 0x10000UL
38931 ++
38932 ++#define PAX_DELTA_MMAP_LEN 16
38933 ++#define PAX_DELTA_STACK_LEN 16
38934 ++#endif
38935 ++
38936 + /* This yields a mask that user programs can use to figure out what
38937 + instruction set this cpu supports. This can NOT be done in userspace
38938 + on Sparc. */
38939 +diff -urNp linux-2.6.27.7/arch/sparc/include/asm/elf_64.h linux-2.6.27.7/arch/sparc/include/asm/elf_64.h
38940 +--- linux-2.6.27.7/arch/sparc/include/asm/elf_64.h 2008-11-07 12:55:34.000000000 -0500
38941 ++++ linux-2.6.27.7/arch/sparc/include/asm/elf_64.h 2008-11-18 03:39:50.000000000 -0500
38942 +@@ -163,6 +163,12 @@ typedef struct {
38943 + #define ELF_ET_DYN_BASE 0x0000010000000000UL
38944 + #define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL
38945 +
38946 ++#ifdef CONFIG_PAX_ASLR
38947 ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
38948 ++
38949 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 14 : 28 )
38950 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 15 : 29 )
38951 ++#endif
38952 +
38953 + /* This yields a mask that user programs can use to figure out what
38954 + instruction set this cpu supports. */
38955 +diff -urNp linux-2.6.27.7/arch/sparc/include/asm/kmap_types.h linux-2.6.27.7/arch/sparc/include/asm/kmap_types.h
38956 +--- linux-2.6.27.7/arch/sparc/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
38957 ++++ linux-2.6.27.7/arch/sparc/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
38958 +@@ -19,6 +19,7 @@ enum km_type {
38959 + KM_IRQ1,
38960 + KM_SOFTIRQ0,
38961 + KM_SOFTIRQ1,
38962 ++ KM_CLEARPAGE,
38963 + KM_TYPE_NR
38964 + };
38965 +
38966 +diff -urNp linux-2.6.27.7/arch/sparc/include/asm/pgtable_32.h linux-2.6.27.7/arch/sparc/include/asm/pgtable_32.h
38967 +--- linux-2.6.27.7/arch/sparc/include/asm/pgtable_32.h 2008-11-07 12:55:34.000000000 -0500
38968 ++++ linux-2.6.27.7/arch/sparc/include/asm/pgtable_32.h 2008-11-18 03:39:50.000000000 -0500
38969 +@@ -47,6 +47,13 @@ BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
38970 + BTFIXUPDEF_INT(page_none)
38971 + BTFIXUPDEF_INT(page_copy)
38972 + BTFIXUPDEF_INT(page_readonly)
38973 ++
38974 ++#ifdef CONFIG_PAX_PAGEEXEC
38975 ++BTFIXUPDEF_INT(page_shared_noexec)
38976 ++BTFIXUPDEF_INT(page_copy_noexec)
38977 ++BTFIXUPDEF_INT(page_readonly_noexec)
38978 ++#endif
38979 ++
38980 + BTFIXUPDEF_INT(page_kernel)
38981 +
38982 + #define PMD_SHIFT SUN4C_PMD_SHIFT
38983 +@@ -68,6 +75,16 @@ extern pgprot_t PAGE_SHARED;
38984 + #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
38985 + #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
38986 +
38987 ++#ifdef CONFIG_PAX_PAGEEXEC
38988 ++extern pgprot_t PAGE_SHARED_NOEXEC;
38989 ++# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec))
38990 ++# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec))
38991 ++#else
38992 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
38993 ++# define PAGE_COPY_NOEXEC PAGE_COPY
38994 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
38995 ++#endif
38996 ++
38997 + extern unsigned long page_kernel;
38998 +
38999 + #ifdef MODULE
39000 +diff -urNp linux-2.6.27.7/arch/sparc/include/asm/pgtsrmmu.h linux-2.6.27.7/arch/sparc/include/asm/pgtsrmmu.h
39001 +--- linux-2.6.27.7/arch/sparc/include/asm/pgtsrmmu.h 2008-11-07 12:55:34.000000000 -0500
39002 ++++ linux-2.6.27.7/arch/sparc/include/asm/pgtsrmmu.h 2008-11-18 03:39:50.000000000 -0500
39003 +@@ -115,6 +115,13 @@
39004 + SRMMU_EXEC | SRMMU_REF)
39005 + #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
39006 + SRMMU_EXEC | SRMMU_REF)
39007 ++
39008 ++#ifdef CONFIG_PAX_PAGEEXEC
39009 ++#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_WRITE | SRMMU_REF)
39010 ++#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_REF)
39011 ++#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_REF)
39012 ++#endif
39013 ++
39014 + #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
39015 + SRMMU_DIRTY | SRMMU_REF)
39016 +
39017 +diff -urNp linux-2.6.27.7/arch/sparc/kernel/sys_sparc.c linux-2.6.27.7/arch/sparc/kernel/sys_sparc.c
39018 +--- linux-2.6.27.7/arch/sparc/kernel/sys_sparc.c 2008-11-07 12:55:34.000000000 -0500
39019 ++++ linux-2.6.27.7/arch/sparc/kernel/sys_sparc.c 2008-11-18 03:38:43.000000000 -0500
39020 +@@ -56,7 +56,7 @@ unsigned long arch_get_unmapped_area(str
39021 + if (ARCH_SUN4C_SUN4 && len > 0x20000000)
39022 + return -ENOMEM;
39023 + if (!addr)
39024 +- addr = TASK_UNMAPPED_BASE;
39025 ++ addr = current->mm->mmap_base;
39026 +
39027 + if (flags & MAP_SHARED)
39028 + addr = COLOUR_ALIGN(addr);
39029 +diff -urNp linux-2.6.27.7/arch/sparc/Makefile linux-2.6.27.7/arch/sparc/Makefile
39030 +--- linux-2.6.27.7/arch/sparc/Makefile 2008-11-07 12:55:34.000000000 -0500
39031 ++++ linux-2.6.27.7/arch/sparc/Makefile 2008-11-18 03:38:43.000000000 -0500
39032 +@@ -37,7 +37,7 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc
39033 + # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
39034 + INIT_Y := $(patsubst %/, %/built-in.o, $(init-y))
39035 + CORE_Y := $(core-y)
39036 +-CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
39037 ++CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
39038 + CORE_Y := $(patsubst %/, %/built-in.o, $(CORE_Y))
39039 + DRIVERS_Y := $(patsubst %/, %/built-in.o, $(drivers-y))
39040 + NET_Y := $(patsubst %/, %/built-in.o, $(net-y))
39041 +diff -urNp linux-2.6.27.7/arch/sparc/mm/fault.c linux-2.6.27.7/arch/sparc/mm/fault.c
39042 +--- linux-2.6.27.7/arch/sparc/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
39043 ++++ linux-2.6.27.7/arch/sparc/mm/fault.c 2008-11-18 03:38:43.000000000 -0500
39044 +@@ -21,6 +21,9 @@
39045 + #include <linux/interrupt.h>
39046 + #include <linux/module.h>
39047 + #include <linux/kdebug.h>
39048 ++#include <linux/slab.h>
39049 ++#include <linux/pagemap.h>
39050 ++#include <linux/compiler.h>
39051 +
39052 + #include <asm/system.h>
39053 + #include <asm/page.h>
39054 +@@ -167,6 +170,249 @@ static unsigned long compute_si_addr(str
39055 + return safe_compute_effective_address(regs, insn);
39056 + }
39057 +
39058 ++#ifdef CONFIG_PAX_PAGEEXEC
39059 ++void pax_emuplt_close(struct vm_area_struct *vma)
39060 ++{
39061 ++ vma->vm_mm->call_dl_resolve = 0UL;
39062 ++}
39063 ++
39064 ++static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
39065 ++{
39066 ++ unsigned int *kaddr;
39067 ++
39068 ++ vmf->page = alloc_page(GFP_HIGHUSER);
39069 ++ if (!vmf->page)
39070 ++ return VM_FAULT_OOM;
39071 ++
39072 ++ kaddr = kmap(vmf->page);
39073 ++ memset(kaddr, 0, PAGE_SIZE);
39074 ++ kaddr[0] = 0x9DE3BFA8U; /* save */
39075 ++ flush_dcache_page(vmf->page);
39076 ++ kunmap(vmf->page);
39077 ++ return VM_FAULT_MAJOR;
39078 ++}
39079 ++
39080 ++static struct vm_operations_struct pax_vm_ops = {
39081 ++ .close = pax_emuplt_close,
39082 ++ .fault = pax_emuplt_fault
39083 ++};
39084 ++
39085 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
39086 ++{
39087 ++ int ret;
39088 ++
39089 ++ vma->vm_mm = current->mm;
39090 ++ vma->vm_start = addr;
39091 ++ vma->vm_end = addr + PAGE_SIZE;
39092 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
39093 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
39094 ++ vma->vm_ops = &pax_vm_ops;
39095 ++
39096 ++ ret = insert_vm_struct(current->mm, vma);
39097 ++ if (ret)
39098 ++ return ret;
39099 ++
39100 ++ ++current->mm->total_vm;
39101 ++ return 0;
39102 ++}
39103 ++
39104 ++/*
39105 ++ * PaX: decide what to do with offenders (regs->pc = fault address)
39106 ++ *
39107 ++ * returns 1 when task should be killed
39108 ++ * 2 when patched PLT trampoline was detected
39109 ++ * 3 when unpatched PLT trampoline was detected
39110 ++ */
39111 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
39112 ++{
39113 ++
39114 ++#ifdef CONFIG_PAX_EMUPLT
39115 ++ int err;
39116 ++
39117 ++ do { /* PaX: patched PLT emulation #1 */
39118 ++ unsigned int sethi1, sethi2, jmpl;
39119 ++
39120 ++ err = get_user(sethi1, (unsigned int *)regs->pc);
39121 ++ err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
39122 ++ err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
39123 ++
39124 ++ if (err)
39125 ++ break;
39126 ++
39127 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
39128 ++ (sethi2 & 0xFFC00000U) == 0x03000000U &&
39129 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U)
39130 ++ {
39131 ++ unsigned int addr;
39132 ++
39133 ++ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
39134 ++ addr = regs->u_regs[UREG_G1];
39135 ++ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
39136 ++ regs->pc = addr;
39137 ++ regs->npc = addr+4;
39138 ++ return 2;
39139 ++ }
39140 ++ } while (0);
39141 ++
39142 ++ { /* PaX: patched PLT emulation #2 */
39143 ++ unsigned int ba;
39144 ++
39145 ++ err = get_user(ba, (unsigned int *)regs->pc);
39146 ++
39147 ++ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
39148 ++ unsigned int addr;
39149 ++
39150 ++ addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
39151 ++ regs->pc = addr;
39152 ++ regs->npc = addr+4;
39153 ++ return 2;
39154 ++ }
39155 ++ }
39156 ++
39157 ++ do { /* PaX: patched PLT emulation #3 */
39158 ++ unsigned int sethi, jmpl, nop;
39159 ++
39160 ++ err = get_user(sethi, (unsigned int *)regs->pc);
39161 ++ err |= get_user(jmpl, (unsigned int *)(regs->pc+4));
39162 ++ err |= get_user(nop, (unsigned int *)(regs->pc+8));
39163 ++
39164 ++ if (err)
39165 ++ break;
39166 ++
39167 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
39168 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
39169 ++ nop == 0x01000000U)
39170 ++ {
39171 ++ unsigned int addr;
39172 ++
39173 ++ addr = (sethi & 0x003FFFFFU) << 10;
39174 ++ regs->u_regs[UREG_G1] = addr;
39175 ++ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
39176 ++ regs->pc = addr;
39177 ++ regs->npc = addr+4;
39178 ++ return 2;
39179 ++ }
39180 ++ } while (0);
39181 ++
39182 ++ do { /* PaX: unpatched PLT emulation step 1 */
39183 ++ unsigned int sethi, ba, nop;
39184 ++
39185 ++ err = get_user(sethi, (unsigned int *)regs->pc);
39186 ++ err |= get_user(ba, (unsigned int *)(regs->pc+4));
39187 ++ err |= get_user(nop, (unsigned int *)(regs->pc+8));
39188 ++
39189 ++ if (err)
39190 ++ break;
39191 ++
39192 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
39193 ++ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
39194 ++ nop == 0x01000000U)
39195 ++ {
39196 ++ unsigned int addr, save, call;
39197 ++
39198 ++ if ((ba & 0xFFC00000U) == 0x30800000U)
39199 ++ addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
39200 ++ else
39201 ++ addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
39202 ++
39203 ++ err = get_user(save, (unsigned int *)addr);
39204 ++ err |= get_user(call, (unsigned int *)(addr+4));
39205 ++ err |= get_user(nop, (unsigned int *)(addr+8));
39206 ++ if (err)
39207 ++ break;
39208 ++
39209 ++ if (save == 0x9DE3BFA8U &&
39210 ++ (call & 0xC0000000U) == 0x40000000U &&
39211 ++ nop == 0x01000000U)
39212 ++ {
39213 ++ struct vm_area_struct *vma;
39214 ++ unsigned long call_dl_resolve;
39215 ++
39216 ++ down_read(&current->mm->mmap_sem);
39217 ++ call_dl_resolve = current->mm->call_dl_resolve;
39218 ++ up_read(&current->mm->mmap_sem);
39219 ++ if (likely(call_dl_resolve))
39220 ++ goto emulate;
39221 ++
39222 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
39223 ++
39224 ++ down_write(&current->mm->mmap_sem);
39225 ++ if (current->mm->call_dl_resolve) {
39226 ++ call_dl_resolve = current->mm->call_dl_resolve;
39227 ++ up_write(&current->mm->mmap_sem);
39228 ++ if (vma)
39229 ++ kmem_cache_free(vm_area_cachep, vma);
39230 ++ goto emulate;
39231 ++ }
39232 ++
39233 ++ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
39234 ++ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
39235 ++ up_write(&current->mm->mmap_sem);
39236 ++ if (vma)
39237 ++ kmem_cache_free(vm_area_cachep, vma);
39238 ++ return 1;
39239 ++ }
39240 ++
39241 ++ if (pax_insert_vma(vma, call_dl_resolve)) {
39242 ++ up_write(&current->mm->mmap_sem);
39243 ++ kmem_cache_free(vm_area_cachep, vma);
39244 ++ return 1;
39245 ++ }
39246 ++
39247 ++ current->mm->call_dl_resolve = call_dl_resolve;
39248 ++ up_write(&current->mm->mmap_sem);
39249 ++
39250 ++emulate:
39251 ++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
39252 ++ regs->pc = call_dl_resolve;
39253 ++ regs->npc = addr+4;
39254 ++ return 3;
39255 ++ }
39256 ++ }
39257 ++ } while (0);
39258 ++
39259 ++ do { /* PaX: unpatched PLT emulation step 2 */
39260 ++ unsigned int save, call, nop;
39261 ++
39262 ++ err = get_user(save, (unsigned int *)(regs->pc-4));
39263 ++ err |= get_user(call, (unsigned int *)regs->pc);
39264 ++ err |= get_user(nop, (unsigned int *)(regs->pc+4));
39265 ++ if (err)
39266 ++ break;
39267 ++
39268 ++ if (save == 0x9DE3BFA8U &&
39269 ++ (call & 0xC0000000U) == 0x40000000U &&
39270 ++ nop == 0x01000000U)
39271 ++ {
39272 ++ unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
39273 ++
39274 ++ regs->u_regs[UREG_RETPC] = regs->pc;
39275 ++ regs->pc = dl_resolve;
39276 ++ regs->npc = dl_resolve+4;
39277 ++ return 3;
39278 ++ }
39279 ++ } while (0);
39280 ++#endif
39281 ++
39282 ++ return 1;
39283 ++}
39284 ++
39285 ++void pax_report_insns(void *pc, void *sp)
39286 ++{
39287 ++ unsigned long i;
39288 ++
39289 ++ printk(KERN_ERR "PAX: bytes at PC: ");
39290 ++ for (i = 0; i < 5; i++) {
39291 ++ unsigned int c;
39292 ++ if (get_user(c, (unsigned int *)pc+i))
39293 ++ printk(KERN_CONT "???????? ");
39294 ++ else
39295 ++ printk(KERN_CONT "%08x ", c);
39296 ++ }
39297 ++ printk("\n");
39298 ++}
39299 ++#endif
39300 ++
39301 + asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
39302 + unsigned long address)
39303 + {
39304 +@@ -231,6 +477,24 @@ good_area:
39305 + if(!(vma->vm_flags & VM_WRITE))
39306 + goto bad_area;
39307 + } else {
39308 ++
39309 ++#ifdef CONFIG_PAX_PAGEEXEC
39310 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
39311 ++ up_read(&mm->mmap_sem);
39312 ++ switch (pax_handle_fetch_fault(regs)) {
39313 ++
39314 ++#ifdef CONFIG_PAX_EMUPLT
39315 ++ case 2:
39316 ++ case 3:
39317 ++ return;
39318 ++#endif
39319 ++
39320 ++ }
39321 ++ pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]);
39322 ++ do_group_exit(SIGKILL);
39323 ++ }
39324 ++#endif
39325 ++
39326 + /* Allow reads even for write-only mappings */
39327 + if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
39328 + goto bad_area;
39329 +diff -urNp linux-2.6.27.7/arch/sparc/mm/init.c linux-2.6.27.7/arch/sparc/mm/init.c
39330 +--- linux-2.6.27.7/arch/sparc/mm/init.c 2008-11-07 12:55:34.000000000 -0500
39331 ++++ linux-2.6.27.7/arch/sparc/mm/init.c 2008-11-18 03:38:43.000000000 -0500
39332 +@@ -312,6 +312,9 @@ extern void device_scan(void);
39333 + pgprot_t PAGE_SHARED __read_mostly;
39334 + EXPORT_SYMBOL(PAGE_SHARED);
39335 +
39336 ++pgprot_t PAGE_SHARED_NOEXEC __read_mostly;
39337 ++EXPORT_SYMBOL(PAGE_SHARED_NOEXEC);
39338 ++
39339 + void __init paging_init(void)
39340 + {
39341 + switch(sparc_cpu_model) {
39342 +@@ -337,17 +340,17 @@ void __init paging_init(void)
39343 +
39344 + /* Initialize the protection map with non-constant, MMU dependent values. */
39345 + protection_map[0] = PAGE_NONE;
39346 +- protection_map[1] = PAGE_READONLY;
39347 +- protection_map[2] = PAGE_COPY;
39348 +- protection_map[3] = PAGE_COPY;
39349 ++ protection_map[1] = PAGE_READONLY_NOEXEC;
39350 ++ protection_map[2] = PAGE_COPY_NOEXEC;
39351 ++ protection_map[3] = PAGE_COPY_NOEXEC;
39352 + protection_map[4] = PAGE_READONLY;
39353 + protection_map[5] = PAGE_READONLY;
39354 + protection_map[6] = PAGE_COPY;
39355 + protection_map[7] = PAGE_COPY;
39356 + protection_map[8] = PAGE_NONE;
39357 +- protection_map[9] = PAGE_READONLY;
39358 +- protection_map[10] = PAGE_SHARED;
39359 +- protection_map[11] = PAGE_SHARED;
39360 ++ protection_map[9] = PAGE_READONLY_NOEXEC;
39361 ++ protection_map[10] = PAGE_SHARED_NOEXEC;
39362 ++ protection_map[11] = PAGE_SHARED_NOEXEC;
39363 + protection_map[12] = PAGE_READONLY;
39364 + protection_map[13] = PAGE_READONLY;
39365 + protection_map[14] = PAGE_SHARED;
39366 +diff -urNp linux-2.6.27.7/arch/sparc/mm/srmmu.c linux-2.6.27.7/arch/sparc/mm/srmmu.c
39367 +--- linux-2.6.27.7/arch/sparc/mm/srmmu.c 2008-11-07 12:55:34.000000000 -0500
39368 ++++ linux-2.6.27.7/arch/sparc/mm/srmmu.c 2008-11-18 03:38:43.000000000 -0500
39369 +@@ -2163,6 +2163,13 @@ void __init ld_mmu_srmmu(void)
39370 + PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED);
39371 + BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
39372 + BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
39373 ++
39374 ++#ifdef CONFIG_PAX_PAGEEXEC
39375 ++ PAGE_SHARED_NOEXEC = pgprot_val(SRMMU_PAGE_SHARED_NOEXEC);
39376 ++ BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
39377 ++ BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
39378 ++#endif
39379 ++
39380 + BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
39381 + page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
39382 +
39383 +diff -urNp linux-2.6.27.7/arch/sparc64/kernel/Makefile linux-2.6.27.7/arch/sparc64/kernel/Makefile
39384 +--- linux-2.6.27.7/arch/sparc64/kernel/Makefile 2008-11-07 12:55:34.000000000 -0500
39385 ++++ linux-2.6.27.7/arch/sparc64/kernel/Makefile 2008-11-18 03:38:43.000000000 -0500
39386 +@@ -3,7 +3,7 @@
39387 + #
39388 +
39389 + EXTRA_AFLAGS := -ansi
39390 +-EXTRA_CFLAGS := -Werror
39391 ++#EXTRA_CFLAGS := -Werror
39392 +
39393 + extra-y := head.o init_task.o vmlinux.lds
39394 +
39395 +diff -urNp linux-2.6.27.7/arch/sparc64/kernel/sys_sparc.c linux-2.6.27.7/arch/sparc64/kernel/sys_sparc.c
39396 +--- linux-2.6.27.7/arch/sparc64/kernel/sys_sparc.c 2008-11-07 12:55:34.000000000 -0500
39397 ++++ linux-2.6.27.7/arch/sparc64/kernel/sys_sparc.c 2008-11-18 03:38:43.000000000 -0500
39398 +@@ -124,7 +124,7 @@ unsigned long arch_get_unmapped_area(str
39399 + /* We do not accept a shared mapping if it would violate
39400 + * cache aliasing constraints.
39401 + */
39402 +- if ((flags & MAP_SHARED) &&
39403 ++ if ((filp || (flags & MAP_SHARED)) &&
39404 + ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
39405 + return -EINVAL;
39406 + return addr;
39407 +@@ -139,6 +139,10 @@ unsigned long arch_get_unmapped_area(str
39408 + if (filp || (flags & MAP_SHARED))
39409 + do_color_align = 1;
39410 +
39411 ++#ifdef CONFIG_PAX_RANDMMAP
39412 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
39413 ++#endif
39414 ++
39415 + if (addr) {
39416 + if (do_color_align)
39417 + addr = COLOUR_ALIGN(addr, pgoff);
39418 +@@ -152,9 +156,9 @@ unsigned long arch_get_unmapped_area(str
39419 + }
39420 +
39421 + if (len > mm->cached_hole_size) {
39422 +- start_addr = addr = mm->free_area_cache;
39423 ++ start_addr = addr = mm->free_area_cache;
39424 + } else {
39425 +- start_addr = addr = TASK_UNMAPPED_BASE;
39426 ++ start_addr = addr = mm->mmap_base;
39427 + mm->cached_hole_size = 0;
39428 + }
39429 +
39430 +@@ -174,8 +178,8 @@ full_search:
39431 + vma = find_vma(mm, VA_EXCLUDE_END);
39432 + }
39433 + if (unlikely(task_size < addr)) {
39434 +- if (start_addr != TASK_UNMAPPED_BASE) {
39435 +- start_addr = addr = TASK_UNMAPPED_BASE;
39436 ++ if (start_addr != mm->mmap_base) {
39437 ++ start_addr = addr = mm->mmap_base;
39438 + mm->cached_hole_size = 0;
39439 + goto full_search;
39440 + }
39441 +@@ -215,7 +219,7 @@ arch_get_unmapped_area_topdown(struct fi
39442 + /* We do not accept a shared mapping if it would violate
39443 + * cache aliasing constraints.
39444 + */
39445 +- if ((flags & MAP_SHARED) &&
39446 ++ if ((filp || (flags & MAP_SHARED)) &&
39447 + ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
39448 + return -EINVAL;
39449 + return addr;
39450 +@@ -378,6 +382,12 @@ void arch_pick_mmap_layout(struct mm_str
39451 + current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
39452 + sysctl_legacy_va_layout) {
39453 + mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
39454 ++
39455 ++#ifdef CONFIG_PAX_RANDMMAP
39456 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
39457 ++ mm->mmap_base += mm->delta_mmap;
39458 ++#endif
39459 ++
39460 + mm->get_unmapped_area = arch_get_unmapped_area;
39461 + mm->unmap_area = arch_unmap_area;
39462 + } else {
39463 +@@ -392,6 +402,12 @@ void arch_pick_mmap_layout(struct mm_str
39464 + gap = (task_size / 6 * 5);
39465 +
39466 + mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
39467 ++
39468 ++#ifdef CONFIG_PAX_RANDMMAP
39469 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
39470 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
39471 ++#endif
39472 ++
39473 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
39474 + mm->unmap_area = arch_unmap_area_topdown;
39475 + }
39476 +diff -urNp linux-2.6.27.7/arch/sparc64/mm/fault.c linux-2.6.27.7/arch/sparc64/mm/fault.c
39477 +--- linux-2.6.27.7/arch/sparc64/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
39478 ++++ linux-2.6.27.7/arch/sparc64/mm/fault.c 2008-11-18 03:38:43.000000000 -0500
39479 +@@ -19,6 +19,9 @@
39480 + #include <linux/interrupt.h>
39481 + #include <linux/kprobes.h>
39482 + #include <linux/kdebug.h>
39483 ++#include <linux/slab.h>
39484 ++#include <linux/pagemap.h>
39485 ++#include <linux/compiler.h>
39486 +
39487 + #include <asm/page.h>
39488 + #include <asm/pgtable.h>
39489 +@@ -261,6 +264,367 @@ cannot_handle:
39490 + unhandled_fault (address, current, regs);
39491 + }
39492 +
39493 ++#ifdef CONFIG_PAX_PAGEEXEC
39494 ++#ifdef CONFIG_PAX_EMUPLT
39495 ++static void pax_emuplt_close(struct vm_area_struct *vma)
39496 ++{
39497 ++ vma->vm_mm->call_dl_resolve = 0UL;
39498 ++}
39499 ++
39500 ++static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
39501 ++{
39502 ++ unsigned int *kaddr;
39503 ++
39504 ++ vmf->page = alloc_page(GFP_HIGHUSER);
39505 ++ if (!vmf->page)
39506 ++ return VM_FAULT_OOM;
39507 ++
39508 ++ kaddr = kmap(vmf->page);
39509 ++ memset(kaddr, 0, PAGE_SIZE);
39510 ++ kaddr[0] = 0x9DE3BFA8U; /* save */
39511 ++ flush_dcache_page(vmf->page);
39512 ++ kunmap(vmf->page);
39513 ++ return VM_FAULT_MAJOR;
39514 ++}
39515 ++
39516 ++static struct vm_operations_struct pax_vm_ops = {
39517 ++ .close = pax_emuplt_close,
39518 ++ .fault = pax_emuplt_fault
39519 ++};
39520 ++
39521 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
39522 ++{
39523 ++ int ret;
39524 ++
39525 ++ vma->vm_mm = current->mm;
39526 ++ vma->vm_start = addr;
39527 ++ vma->vm_end = addr + PAGE_SIZE;
39528 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
39529 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
39530 ++ vma->vm_ops = &pax_vm_ops;
39531 ++
39532 ++ ret = insert_vm_struct(current->mm, vma);
39533 ++ if (ret)
39534 ++ return ret;
39535 ++
39536 ++ ++current->mm->total_vm;
39537 ++ return 0;
39538 ++}
39539 ++#endif
39540 ++
39541 ++/*
39542 ++ * PaX: decide what to do with offenders (regs->tpc = fault address)
39543 ++ *
39544 ++ * returns 1 when task should be killed
39545 ++ * 2 when patched PLT trampoline was detected
39546 ++ * 3 when unpatched PLT trampoline was detected
39547 ++ */
39548 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
39549 ++{
39550 ++
39551 ++#ifdef CONFIG_PAX_EMUPLT
39552 ++ int err;
39553 ++
39554 ++ do { /* PaX: patched PLT emulation #1 */
39555 ++ unsigned int sethi1, sethi2, jmpl;
39556 ++
39557 ++ err = get_user(sethi1, (unsigned int *)regs->tpc);
39558 ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
39559 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+8));
39560 ++
39561 ++ if (err)
39562 ++ break;
39563 ++
39564 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
39565 ++ (sethi2 & 0xFFC00000U) == 0x03000000U &&
39566 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U)
39567 ++ {
39568 ++ unsigned long addr;
39569 ++
39570 ++ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
39571 ++ addr = regs->u_regs[UREG_G1];
39572 ++ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
39573 ++ regs->tpc = addr;
39574 ++ regs->tnpc = addr+4;
39575 ++ return 2;
39576 ++ }
39577 ++ } while (0);
39578 ++
39579 ++ { /* PaX: patched PLT emulation #2 */
39580 ++ unsigned int ba;
39581 ++
39582 ++ err = get_user(ba, (unsigned int *)regs->tpc);
39583 ++
39584 ++ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
39585 ++ unsigned long addr;
39586 ++
39587 ++ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
39588 ++ regs->tpc = addr;
39589 ++ regs->tnpc = addr+4;
39590 ++ return 2;
39591 ++ }
39592 ++ }
39593 ++
39594 ++ do { /* PaX: patched PLT emulation #3 */
39595 ++ unsigned int sethi, jmpl, nop;
39596 ++
39597 ++ err = get_user(sethi, (unsigned int *)regs->tpc);
39598 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+4));
39599 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
39600 ++
39601 ++ if (err)
39602 ++ break;
39603 ++
39604 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
39605 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
39606 ++ nop == 0x01000000U)
39607 ++ {
39608 ++ unsigned long addr;
39609 ++
39610 ++ addr = (sethi & 0x003FFFFFU) << 10;
39611 ++ regs->u_regs[UREG_G1] = addr;
39612 ++ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
39613 ++ regs->tpc = addr;
39614 ++ regs->tnpc = addr+4;
39615 ++ return 2;
39616 ++ }
39617 ++ } while (0);
39618 ++
39619 ++ do { /* PaX: patched PLT emulation #4 */
39620 ++ unsigned int mov1, call, mov2;
39621 ++
39622 ++ err = get_user(mov1, (unsigned int *)regs->tpc);
39623 ++ err |= get_user(call, (unsigned int *)(regs->tpc+4));
39624 ++ err |= get_user(mov2, (unsigned int *)(regs->tpc+8));
39625 ++
39626 ++ if (err)
39627 ++ break;
39628 ++
39629 ++ if (mov1 == 0x8210000FU &&
39630 ++ (call & 0xC0000000U) == 0x40000000U &&
39631 ++ mov2 == 0x9E100001U)
39632 ++ {
39633 ++ unsigned long addr;
39634 ++
39635 ++ regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
39636 ++ addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
39637 ++ regs->tpc = addr;
39638 ++ regs->tnpc = addr+4;
39639 ++ return 2;
39640 ++ }
39641 ++ } while (0);
39642 ++
39643 ++ do { /* PaX: patched PLT emulation #5 */
39644 ++ unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
39645 ++
39646 ++ err = get_user(sethi1, (unsigned int *)regs->tpc);
39647 ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
39648 ++ err |= get_user(or1, (unsigned int *)(regs->tpc+8));
39649 ++ err |= get_user(or2, (unsigned int *)(regs->tpc+12));
39650 ++ err |= get_user(sllx, (unsigned int *)(regs->tpc+16));
39651 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+20));
39652 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+24));
39653 ++
39654 ++ if (err)
39655 ++ break;
39656 ++
39657 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
39658 ++ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
39659 ++ (or1 & 0xFFFFE000U) == 0x82106000U &&
39660 ++ (or2 & 0xFFFFE000U) == 0x8A116000U &&
39661 ++ sllx == 0x83287020 &&
39662 ++ jmpl == 0x81C04005U &&
39663 ++ nop == 0x01000000U)
39664 ++ {
39665 ++ unsigned long addr;
39666 ++
39667 ++ regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
39668 ++ regs->u_regs[UREG_G1] <<= 32;
39669 ++ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
39670 ++ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
39671 ++ regs->tpc = addr;
39672 ++ regs->tnpc = addr+4;
39673 ++ return 2;
39674 ++ }
39675 ++ } while (0);
39676 ++
39677 ++ do { /* PaX: patched PLT emulation #6 */
39678 ++ unsigned int sethi1, sethi2, sllx, or, jmpl, nop;
39679 ++
39680 ++ err = get_user(sethi1, (unsigned int *)regs->tpc);
39681 ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
39682 ++ err |= get_user(sllx, (unsigned int *)(regs->tpc+8));
39683 ++ err |= get_user(or, (unsigned int *)(regs->tpc+12));
39684 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+16));
39685 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+20));
39686 ++
39687 ++ if (err)
39688 ++ break;
39689 ++
39690 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
39691 ++ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
39692 ++ sllx == 0x83287020 &&
39693 ++ (or & 0xFFFFE000U) == 0x8A116000U &&
39694 ++ jmpl == 0x81C04005U &&
39695 ++ nop == 0x01000000U)
39696 ++ {
39697 ++ unsigned long addr;
39698 ++
39699 ++ regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
39700 ++ regs->u_regs[UREG_G1] <<= 32;
39701 ++ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
39702 ++ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
39703 ++ regs->tpc = addr;
39704 ++ regs->tnpc = addr+4;
39705 ++ return 2;
39706 ++ }
39707 ++ } while (0);
39708 ++
39709 ++ do { /* PaX: patched PLT emulation #7 */
39710 ++ unsigned int sethi, ba, nop;
39711 ++
39712 ++ err = get_user(sethi, (unsigned int *)regs->tpc);
39713 ++ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
39714 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
39715 ++
39716 ++ if (err)
39717 ++ break;
39718 ++
39719 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
39720 ++ (ba & 0xFFF00000U) == 0x30600000U &&
39721 ++ nop == 0x01000000U)
39722 ++ {
39723 ++ unsigned long addr;
39724 ++
39725 ++ addr = (sethi & 0x003FFFFFU) << 10;
39726 ++ regs->u_regs[UREG_G1] = addr;
39727 ++ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
39728 ++ regs->tpc = addr;
39729 ++ regs->tnpc = addr+4;
39730 ++ return 2;
39731 ++ }
39732 ++ } while (0);
39733 ++
39734 ++ do { /* PaX: unpatched PLT emulation step 1 */
39735 ++ unsigned int sethi, ba, nop;
39736 ++
39737 ++ err = get_user(sethi, (unsigned int *)regs->tpc);
39738 ++ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
39739 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
39740 ++
39741 ++ if (err)
39742 ++ break;
39743 ++
39744 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
39745 ++ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
39746 ++ nop == 0x01000000U)
39747 ++ {
39748 ++ unsigned long addr;
39749 ++ unsigned int save, call;
39750 ++
39751 ++ if ((ba & 0xFFC00000U) == 0x30800000U)
39752 ++ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
39753 ++ else
39754 ++ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
39755 ++
39756 ++ err = get_user(save, (unsigned int *)addr);
39757 ++ err |= get_user(call, (unsigned int *)(addr+4));
39758 ++ err |= get_user(nop, (unsigned int *)(addr+8));
39759 ++ if (err)
39760 ++ break;
39761 ++
39762 ++ if (save == 0x9DE3BFA8U &&
39763 ++ (call & 0xC0000000U) == 0x40000000U &&
39764 ++ nop == 0x01000000U)
39765 ++ {
39766 ++ struct vm_area_struct *vma;
39767 ++ unsigned long call_dl_resolve;
39768 ++
39769 ++ down_read(&current->mm->mmap_sem);
39770 ++ call_dl_resolve = current->mm->call_dl_resolve;
39771 ++ up_read(&current->mm->mmap_sem);
39772 ++ if (likely(call_dl_resolve))
39773 ++ goto emulate;
39774 ++
39775 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
39776 ++
39777 ++ down_write(&current->mm->mmap_sem);
39778 ++ if (current->mm->call_dl_resolve) {
39779 ++ call_dl_resolve = current->mm->call_dl_resolve;
39780 ++ up_write(&current->mm->mmap_sem);
39781 ++ if (vma)
39782 ++ kmem_cache_free(vm_area_cachep, vma);
39783 ++ goto emulate;
39784 ++ }
39785 ++
39786 ++ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
39787 ++ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
39788 ++ up_write(&current->mm->mmap_sem);
39789 ++ if (vma)
39790 ++ kmem_cache_free(vm_area_cachep, vma);
39791 ++ return 1;
39792 ++ }
39793 ++
39794 ++ if (pax_insert_vma(vma, call_dl_resolve)) {
39795 ++ up_write(&current->mm->mmap_sem);
39796 ++ kmem_cache_free(vm_area_cachep, vma);
39797 ++ return 1;
39798 ++ }
39799 ++
39800 ++ current->mm->call_dl_resolve = call_dl_resolve;
39801 ++ up_write(&current->mm->mmap_sem);
39802 ++
39803 ++emulate:
39804 ++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
39805 ++ regs->tpc = call_dl_resolve;
39806 ++ regs->tnpc = addr+4;
39807 ++ return 3;
39808 ++ }
39809 ++ }
39810 ++ } while (0);
39811 ++
39812 ++ do { /* PaX: unpatched PLT emulation step 2 */
39813 ++ unsigned int save, call, nop;
39814 ++
39815 ++ err = get_user(save, (unsigned int *)(regs->tpc-4));
39816 ++ err |= get_user(call, (unsigned int *)regs->tpc);
39817 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+4));
39818 ++ if (err)
39819 ++ break;
39820 ++
39821 ++ if (save == 0x9DE3BFA8U &&
39822 ++ (call & 0xC0000000U) == 0x40000000U &&
39823 ++ nop == 0x01000000U)
39824 ++ {
39825 ++ unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
39826 ++
39827 ++ regs->u_regs[UREG_RETPC] = regs->tpc;
39828 ++ regs->tpc = dl_resolve;
39829 ++ regs->tnpc = dl_resolve+4;
39830 ++ return 3;
39831 ++ }
39832 ++ } while (0);
39833 ++#endif
39834 ++
39835 ++ return 1;
39836 ++}
39837 ++
39838 ++void pax_report_insns(void *pc, void *sp)
39839 ++{
39840 ++ unsigned long i;
39841 ++
39842 ++ printk(KERN_ERR "PAX: bytes at PC: ");
39843 ++ for (i = 0; i < 5; i++) {
39844 ++ unsigned int c;
39845 ++ if (get_user(c, (unsigned int *)pc+i))
39846 ++ printk(KERN_CONT "???????? ");
39847 ++ else
39848 ++ printk(KERN_CONT "%08x ", c);
39849 ++ }
39850 ++ printk("\n");
39851 ++}
39852 ++#endif
39853 ++
39854 + asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
39855 + {
39856 + struct mm_struct *mm = current->mm;
39857 +@@ -302,8 +666,10 @@ asmlinkage void __kprobes do_sparc64_fau
39858 + goto intr_or_no_mm;
39859 +
39860 + if (test_thread_flag(TIF_32BIT)) {
39861 +- if (!(regs->tstate & TSTATE_PRIV))
39862 ++ if (!(regs->tstate & TSTATE_PRIV)) {
39863 + regs->tpc &= 0xffffffff;
39864 ++ regs->tnpc &= 0xffffffff;
39865 ++ }
39866 + address &= 0xffffffff;
39867 + }
39868 +
39869 +@@ -320,6 +686,29 @@ asmlinkage void __kprobes do_sparc64_fau
39870 + if (!vma)
39871 + goto bad_area;
39872 +
39873 ++#ifdef CONFIG_PAX_PAGEEXEC
39874 ++ /* PaX: detect ITLB misses on non-exec pages */
39875 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
39876 ++ !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
39877 ++ {
39878 ++ if (address != regs->tpc)
39879 ++ goto good_area;
39880 ++
39881 ++ up_read(&mm->mmap_sem);
39882 ++ switch (pax_handle_fetch_fault(regs)) {
39883 ++
39884 ++#ifdef CONFIG_PAX_EMUPLT
39885 ++ case 2:
39886 ++ case 3:
39887 ++ return;
39888 ++#endif
39889 ++
39890 ++ }
39891 ++ pax_report_fault(regs, (void *)regs->tpc, (void *)(regs->u_regs[UREG_FP] + STACK_BIAS));
39892 ++ do_group_exit(SIGKILL);
39893 ++ }
39894 ++#endif
39895 ++
39896 + /* Pure DTLB misses do not tell us whether the fault causing
39897 + * load/store/atomic was a write or not, it only says that there
39898 + * was no match. So in such a case we (carefully) read the
39899 +diff -urNp linux-2.6.27.7/arch/sparc64/mm/Makefile linux-2.6.27.7/arch/sparc64/mm/Makefile
39900 +--- linux-2.6.27.7/arch/sparc64/mm/Makefile 2008-11-07 12:55:34.000000000 -0500
39901 ++++ linux-2.6.27.7/arch/sparc64/mm/Makefile 2008-11-18 03:38:43.000000000 -0500
39902 +@@ -2,7 +2,7 @@
39903 + #
39904 +
39905 + EXTRA_AFLAGS := -ansi
39906 +-EXTRA_CFLAGS := -Werror
39907 ++#EXTRA_CFLAGS := -Werror
39908 +
39909 + obj-y := ultra.o tlb.o tsb.o fault.o init.o generic.o
39910 +
39911 +diff -urNp linux-2.6.27.7/arch/um/sys-i386/syscalls.c linux-2.6.27.7/arch/um/sys-i386/syscalls.c
39912 +--- linux-2.6.27.7/arch/um/sys-i386/syscalls.c 2008-11-07 12:55:34.000000000 -0500
39913 ++++ linux-2.6.27.7/arch/um/sys-i386/syscalls.c 2008-11-18 03:38:43.000000000 -0500
39914 +@@ -10,6 +10,21 @@
39915 + #include "asm/uaccess.h"
39916 + #include "asm/unistd.h"
39917 +
39918 ++int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
39919 ++{
39920 ++ unsigned long pax_task_size = TASK_SIZE;
39921 ++
39922 ++#ifdef CONFIG_PAX_SEGMEXEC
39923 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
39924 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
39925 ++#endif
39926 ++
39927 ++ if (len > pax_task_size || addr > pax_task_size - len)
39928 ++ return -EINVAL;
39929 ++
39930 ++ return 0;
39931 ++}
39932 ++
39933 + /*
39934 + * Perform the select(nd, in, out, ex, tv) and mmap() system
39935 + * calls. Linux/i386 didn't use to be able to handle more than
39936 +diff -urNp linux-2.6.27.7/arch/x86/boot/bitops.h linux-2.6.27.7/arch/x86/boot/bitops.h
39937 +--- linux-2.6.27.7/arch/x86/boot/bitops.h 2008-11-07 12:55:34.000000000 -0500
39938 ++++ linux-2.6.27.7/arch/x86/boot/bitops.h 2008-11-18 03:38:44.000000000 -0500
39939 +@@ -26,7 +26,7 @@ static inline int variable_test_bit(int
39940 + u8 v;
39941 + const u32 *p = (const u32 *)addr;
39942 +
39943 +- asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
39944 ++ asm volatile("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
39945 + return v;
39946 + }
39947 +
39948 +@@ -37,7 +37,7 @@ static inline int variable_test_bit(int
39949 +
39950 + static inline void set_bit(int nr, void *addr)
39951 + {
39952 +- asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
39953 ++ asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
39954 + }
39955 +
39956 + #endif /* BOOT_BITOPS_H */
39957 +diff -urNp linux-2.6.27.7/arch/x86/boot/boot.h linux-2.6.27.7/arch/x86/boot/boot.h
39958 +--- linux-2.6.27.7/arch/x86/boot/boot.h 2008-11-07 12:55:34.000000000 -0500
39959 ++++ linux-2.6.27.7/arch/x86/boot/boot.h 2008-11-18 03:38:44.000000000 -0500
39960 +@@ -80,7 +80,7 @@ static inline void io_delay(void)
39961 + static inline u16 ds(void)
39962 + {
39963 + u16 seg;
39964 +- asm("movw %%ds,%0" : "=rm" (seg));
39965 ++ asm volatile("movw %%ds,%0" : "=rm" (seg));
39966 + return seg;
39967 + }
39968 +
39969 +@@ -176,7 +176,7 @@ static inline void wrgs32(u32 v, addr_t
39970 + static inline int memcmp(const void *s1, const void *s2, size_t len)
39971 + {
39972 + u8 diff;
39973 +- asm("repe; cmpsb; setnz %0"
39974 ++ asm volatile("repe; cmpsb; setnz %0"
39975 + : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
39976 + return diff;
39977 + }
39978 +diff -urNp linux-2.6.27.7/arch/x86/boot/compressed/head_32.S linux-2.6.27.7/arch/x86/boot/compressed/head_32.S
39979 +--- linux-2.6.27.7/arch/x86/boot/compressed/head_32.S 2008-11-07 12:55:34.000000000 -0500
39980 ++++ linux-2.6.27.7/arch/x86/boot/compressed/head_32.S 2008-11-18 03:38:44.000000000 -0500
39981 +@@ -70,7 +70,7 @@ startup_32:
39982 + addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebx
39983 + andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebx
39984 + #else
39985 +- movl $LOAD_PHYSICAL_ADDR, %ebx
39986 ++ movl $____LOAD_PHYSICAL_ADDR, %ebx
39987 + #endif
39988 +
39989 + /* Replace the compressed data size with the uncompressed size */
39990 +@@ -105,7 +105,7 @@ startup_32:
39991 + addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebp
39992 + andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebp
39993 + #else
39994 +- movl $LOAD_PHYSICAL_ADDR, %ebp
39995 ++ movl $____LOAD_PHYSICAL_ADDR, %ebp
39996 + #endif
39997 +
39998 + /*
39999 +@@ -159,16 +159,15 @@ relocated:
40000 + * and where it was actually loaded.
40001 + */
40002 + movl %ebp, %ebx
40003 +- subl $LOAD_PHYSICAL_ADDR, %ebx
40004 ++ subl $____LOAD_PHYSICAL_ADDR, %ebx
40005 + jz 2f /* Nothing to be done if loaded at compiled addr. */
40006 + /*
40007 + * Process relocations.
40008 + */
40009 +
40010 + 1: subl $4, %edi
40011 +- movl 0(%edi), %ecx
40012 +- testl %ecx, %ecx
40013 +- jz 2f
40014 ++ movl (%edi), %ecx
40015 ++ jecxz 2f
40016 + addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
40017 + jmp 1b
40018 + 2:
40019 +diff -urNp linux-2.6.27.7/arch/x86/boot/compressed/misc.c linux-2.6.27.7/arch/x86/boot/compressed/misc.c
40020 +--- linux-2.6.27.7/arch/x86/boot/compressed/misc.c 2008-11-07 12:55:34.000000000 -0500
40021 ++++ linux-2.6.27.7/arch/x86/boot/compressed/misc.c 2008-11-18 03:38:44.000000000 -0500
40022 +@@ -371,7 +371,7 @@ static void parse_elf(void *output)
40023 + case PT_LOAD:
40024 + #ifdef CONFIG_RELOCATABLE
40025 + dest = output;
40026 +- dest += (phdr->p_paddr - LOAD_PHYSICAL_ADDR);
40027 ++ dest += (phdr->p_paddr - ____LOAD_PHYSICAL_ADDR);
40028 + #else
40029 + dest = (void *)(phdr->p_paddr);
40030 + #endif
40031 +@@ -423,7 +423,7 @@ asmlinkage void decompress_kernel(void *
40032 + if (heap > ((-__PAGE_OFFSET-(512<<20)-1) & 0x7fffffff))
40033 + error("Destination address too large");
40034 + #ifndef CONFIG_RELOCATABLE
40035 +- if ((u32)output != LOAD_PHYSICAL_ADDR)
40036 ++ if ((u32)output != ____LOAD_PHYSICAL_ADDR)
40037 + error("Wrong destination address");
40038 + #endif
40039 + #endif
40040 +diff -urNp linux-2.6.27.7/arch/x86/boot/compressed/relocs.c linux-2.6.27.7/arch/x86/boot/compressed/relocs.c
40041 +--- linux-2.6.27.7/arch/x86/boot/compressed/relocs.c 2008-11-07 12:55:34.000000000 -0500
40042 ++++ linux-2.6.27.7/arch/x86/boot/compressed/relocs.c 2008-11-18 03:38:44.000000000 -0500
40043 +@@ -10,8 +10,11 @@
40044 + #define USE_BSD
40045 + #include <endian.h>
40046 +
40047 ++#include "../../../../include/linux/autoconf.h"
40048 ++
40049 + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
40050 + static Elf32_Ehdr ehdr;
40051 ++static Elf32_Phdr *phdr;
40052 + static unsigned long reloc_count, reloc_idx;
40053 + static unsigned long *relocs;
40054 +
40055 +@@ -245,6 +248,36 @@ static void read_ehdr(FILE *fp)
40056 + }
40057 + }
40058 +
40059 ++static void read_phdrs(FILE *fp)
40060 ++{
40061 ++ int i;
40062 ++
40063 ++ phdr = calloc(ehdr.e_phnum, sizeof(Elf32_Phdr));
40064 ++ if (!phdr) {
40065 ++ die("Unable to allocate %d program headers\n",
40066 ++ ehdr.e_phnum);
40067 ++ }
40068 ++ if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) {
40069 ++ die("Seek to %d failed: %s\n",
40070 ++ ehdr.e_phoff, strerror(errno));
40071 ++ }
40072 ++ if (fread(phdr, sizeof(*phdr), ehdr.e_phnum, fp) != ehdr.e_phnum) {
40073 ++ die("Cannot read ELF program headers: %s\n",
40074 ++ strerror(errno));
40075 ++ }
40076 ++ for(i = 0; i < ehdr.e_phnum; i++) {
40077 ++ phdr[i].p_type = elf32_to_cpu(phdr[i].p_type);
40078 ++ phdr[i].p_offset = elf32_to_cpu(phdr[i].p_offset);
40079 ++ phdr[i].p_vaddr = elf32_to_cpu(phdr[i].p_vaddr);
40080 ++ phdr[i].p_paddr = elf32_to_cpu(phdr[i].p_paddr);
40081 ++ phdr[i].p_filesz = elf32_to_cpu(phdr[i].p_filesz);
40082 ++ phdr[i].p_memsz = elf32_to_cpu(phdr[i].p_memsz);
40083 ++ phdr[i].p_flags = elf32_to_cpu(phdr[i].p_flags);
40084 ++ phdr[i].p_align = elf32_to_cpu(phdr[i].p_align);
40085 ++ }
40086 ++
40087 ++}
40088 ++
40089 + static void read_shdrs(FILE *fp)
40090 + {
40091 + int i;
40092 +@@ -341,6 +374,8 @@ static void read_symtabs(FILE *fp)
40093 + static void read_relocs(FILE *fp)
40094 + {
40095 + int i,j;
40096 ++ uint32_t base;
40097 ++
40098 + for (i = 0; i < ehdr.e_shnum; i++) {
40099 + struct section *sec = &secs[i];
40100 + if (sec->shdr.sh_type != SHT_REL) {
40101 +@@ -360,9 +395,18 @@ static void read_relocs(FILE *fp)
40102 + die("Cannot read symbol table: %s\n",
40103 + strerror(errno));
40104 + }
40105 ++ base = 0;
40106 ++ for (j = 0; j < ehdr.e_phnum; j++) {
40107 ++ if (phdr[j].p_type != PT_LOAD )
40108 ++ continue;
40109 ++ 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)
40110 ++ continue;
40111 ++ base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr;
40112 ++ break;
40113 ++ }
40114 + for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) {
40115 + Elf32_Rel *rel = &sec->reltab[j];
40116 +- rel->r_offset = elf32_to_cpu(rel->r_offset);
40117 ++ rel->r_offset = elf32_to_cpu(rel->r_offset) + base;
40118 + rel->r_info = elf32_to_cpu(rel->r_info);
40119 + }
40120 + }
40121 +@@ -504,6 +548,23 @@ static void walk_relocs(void (*visit)(El
40122 + if (sym->st_shndx == SHN_ABS) {
40123 + continue;
40124 + }
40125 ++ /* Don't relocate actual per-cpu variables, they are absolute indices, not addresses */
40126 ++ if (!strcmp(sec_name(sym->st_shndx), ".data.percpu") && strncmp(sym_name(sym_strtab, sym), "__per_cpu_", 10))
40127 ++ continue;
40128 ++#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32)
40129 ++ /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */
40130 ++ if (!strcmp(sec_name(sym->st_shndx), ".init.text"))
40131 ++ continue;
40132 ++ if (!strcmp(sec_name(sym->st_shndx), ".exit.text"))
40133 ++ continue;
40134 ++ if (!strcmp(sec_name(sym->st_shndx), ".text.head")) {
40135 ++ if (strcmp(sym_name(sym_strtab, sym), "__init_end") &&
40136 ++ strcmp(sym_name(sym_strtab, sym), "KERNEL_TEXT_OFFSET"))
40137 ++ continue;
40138 ++ }
40139 ++ if (!strcmp(sec_name(sym->st_shndx), ".text"))
40140 ++ continue;
40141 ++#endif
40142 + if (r_type == R_386_PC32) {
40143 + /* PC relative relocations don't need to be adjusted */
40144 + }
40145 +@@ -631,6 +692,7 @@ int main(int argc, char **argv)
40146 + fname, strerror(errno));
40147 + }
40148 + read_ehdr(fp);
40149 ++ read_phdrs(fp);
40150 + read_shdrs(fp);
40151 + read_strtabs(fp);
40152 + read_symtabs(fp);
40153 +diff -urNp linux-2.6.27.7/arch/x86/boot/cpucheck.c linux-2.6.27.7/arch/x86/boot/cpucheck.c
40154 +--- linux-2.6.27.7/arch/x86/boot/cpucheck.c 2008-11-07 12:55:34.000000000 -0500
40155 ++++ linux-2.6.27.7/arch/x86/boot/cpucheck.c 2008-11-18 03:38:44.000000000 -0500
40156 +@@ -74,7 +74,7 @@ static int has_fpu(void)
40157 + u16 fcw = -1, fsw = -1;
40158 + u32 cr0;
40159 +
40160 +- asm("movl %%cr0,%0" : "=r" (cr0));
40161 ++ asm volatile("movl %%cr0,%0" : "=r" (cr0));
40162 + if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
40163 + cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
40164 + asm volatile("movl %0,%%cr0" : : "r" (cr0));
40165 +@@ -90,7 +90,7 @@ static int has_eflag(u32 mask)
40166 + {
40167 + u32 f0, f1;
40168 +
40169 +- asm("pushfl ; "
40170 ++ asm volatile("pushfl ; "
40171 + "pushfl ; "
40172 + "popl %0 ; "
40173 + "movl %0,%1 ; "
40174 +@@ -115,7 +115,7 @@ static void get_flags(void)
40175 + set_bit(X86_FEATURE_FPU, cpu.flags);
40176 +
40177 + if (has_eflag(X86_EFLAGS_ID)) {
40178 +- asm("cpuid"
40179 ++ asm volatile("cpuid"
40180 + : "=a" (max_intel_level),
40181 + "=b" (cpu_vendor[0]),
40182 + "=d" (cpu_vendor[1]),
40183 +@@ -124,7 +124,7 @@ static void get_flags(void)
40184 +
40185 + if (max_intel_level >= 0x00000001 &&
40186 + max_intel_level <= 0x0000ffff) {
40187 +- asm("cpuid"
40188 ++ asm volatile("cpuid"
40189 + : "=a" (tfms),
40190 + "=c" (cpu.flags[4]),
40191 + "=d" (cpu.flags[0])
40192 +@@ -136,7 +136,7 @@ static void get_flags(void)
40193 + cpu.model += ((tfms >> 16) & 0xf) << 4;
40194 + }
40195 +
40196 +- asm("cpuid"
40197 ++ asm volatile("cpuid"
40198 + : "=a" (max_amd_level)
40199 + : "a" (0x80000000)
40200 + : "ebx", "ecx", "edx");
40201 +@@ -144,7 +144,7 @@ static void get_flags(void)
40202 + if (max_amd_level >= 0x80000001 &&
40203 + max_amd_level <= 0x8000ffff) {
40204 + u32 eax = 0x80000001;
40205 +- asm("cpuid"
40206 ++ asm volatile("cpuid"
40207 + : "+a" (eax),
40208 + "=c" (cpu.flags[6]),
40209 + "=d" (cpu.flags[1])
40210 +@@ -203,9 +203,9 @@ int check_cpu(int *cpu_level_ptr, int *r
40211 + u32 ecx = MSR_K7_HWCR;
40212 + u32 eax, edx;
40213 +
40214 +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
40215 ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
40216 + eax &= ~(1 << 15);
40217 +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
40218 ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
40219 +
40220 + get_flags(); /* Make sure it really did something */
40221 + err = check_flags();
40222 +@@ -218,9 +218,9 @@ int check_cpu(int *cpu_level_ptr, int *r
40223 + u32 ecx = MSR_VIA_FCR;
40224 + u32 eax, edx;
40225 +
40226 +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
40227 ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
40228 + eax |= (1<<1)|(1<<7);
40229 +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
40230 ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
40231 +
40232 + set_bit(X86_FEATURE_CX8, cpu.flags);
40233 + err = check_flags();
40234 +@@ -231,12 +231,12 @@ int check_cpu(int *cpu_level_ptr, int *r
40235 + u32 eax, edx;
40236 + u32 level = 1;
40237 +
40238 +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
40239 +- asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
40240 +- asm("cpuid"
40241 ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
40242 ++ asm volatile("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
40243 ++ asm volatile("cpuid"
40244 + : "+a" (level), "=d" (cpu.flags[0])
40245 + : : "ecx", "ebx");
40246 +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
40247 ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
40248 +
40249 + err = check_flags();
40250 + }
40251 +diff -urNp linux-2.6.27.7/arch/x86/boot/edd.c linux-2.6.27.7/arch/x86/boot/edd.c
40252 +--- linux-2.6.27.7/arch/x86/boot/edd.c 2008-11-07 12:55:34.000000000 -0500
40253 ++++ linux-2.6.27.7/arch/x86/boot/edd.c 2008-11-18 03:38:44.000000000 -0500
40254 +@@ -76,7 +76,7 @@ static int get_edd_info(u8 devno, struct
40255 + ax = 0x4100;
40256 + bx = EDDMAGIC1;
40257 + dx = devno;
40258 +- asm("pushfl; stc; int $0x13; setc %%al; popfl"
40259 ++ asm volatile("pushfl; stc; int $0x13; setc %%al; popfl"
40260 + : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
40261 + : : "esi", "edi");
40262 +
40263 +@@ -95,7 +95,7 @@ static int get_edd_info(u8 devno, struct
40264 + ei->params.length = sizeof(ei->params);
40265 + ax = 0x4800;
40266 + dx = devno;
40267 +- asm("pushfl; int $0x13; popfl"
40268 ++ asm volatile("pushfl; int $0x13; popfl"
40269 + : "+a" (ax), "+d" (dx), "=m" (ei->params)
40270 + : "S" (&ei->params)
40271 + : "ebx", "ecx", "edi");
40272 +@@ -106,7 +106,7 @@ static int get_edd_info(u8 devno, struct
40273 + ax = 0x0800;
40274 + dx = devno;
40275 + di = 0;
40276 +- asm("pushw %%es; "
40277 ++ asm volatile("pushw %%es; "
40278 + "movw %%di,%%es; "
40279 + "pushfl; stc; int $0x13; setc %%al; popfl; "
40280 + "popw %%es"
40281 +diff -urNp linux-2.6.27.7/arch/x86/boot/main.c linux-2.6.27.7/arch/x86/boot/main.c
40282 +--- linux-2.6.27.7/arch/x86/boot/main.c 2008-11-07 12:55:34.000000000 -0500
40283 ++++ linux-2.6.27.7/arch/x86/boot/main.c 2008-11-18 03:38:44.000000000 -0500
40284 +@@ -78,7 +78,7 @@ static void query_ist(void)
40285 + if (cpu.level < 6)
40286 + return;
40287 +
40288 +- asm("int $0x15"
40289 ++ asm volatile("int $0x15"
40290 + : "=a" (boot_params.ist_info.signature),
40291 + "=b" (boot_params.ist_info.command),
40292 + "=c" (boot_params.ist_info.event),
40293 +diff -urNp linux-2.6.27.7/arch/x86/boot/mca.c linux-2.6.27.7/arch/x86/boot/mca.c
40294 +--- linux-2.6.27.7/arch/x86/boot/mca.c 2008-11-07 12:55:34.000000000 -0500
40295 ++++ linux-2.6.27.7/arch/x86/boot/mca.c 2008-11-18 03:38:44.000000000 -0500
40296 +@@ -19,7 +19,7 @@ int query_mca(void)
40297 + u8 err;
40298 + u16 es, bx, len;
40299 +
40300 +- asm("pushw %%es ; "
40301 ++ asm volatile("pushw %%es ; "
40302 + "int $0x15 ; "
40303 + "setc %0 ; "
40304 + "movw %%es, %1 ; "
40305 +diff -urNp linux-2.6.27.7/arch/x86/boot/memory.c linux-2.6.27.7/arch/x86/boot/memory.c
40306 +--- linux-2.6.27.7/arch/x86/boot/memory.c 2008-11-07 12:55:34.000000000 -0500
40307 ++++ linux-2.6.27.7/arch/x86/boot/memory.c 2008-11-18 03:38:44.000000000 -0500
40308 +@@ -30,7 +30,7 @@ static int detect_memory_e820(void)
40309 + /* Important: %edx is clobbered by some BIOSes,
40310 + so it must be either used for the error output
40311 + or explicitly marked clobbered. */
40312 +- asm("int $0x15; setc %0"
40313 ++ asm volatile("int $0x15; setc %0"
40314 + : "=d" (err), "+b" (next), "=a" (id), "+c" (size),
40315 + "=m" (*desc)
40316 + : "D" (desc), "d" (SMAP), "a" (0xe820));
40317 +@@ -65,7 +65,7 @@ static int detect_memory_e801(void)
40318 +
40319 + bx = cx = dx = 0;
40320 + ax = 0xe801;
40321 +- asm("stc; int $0x15; setc %0"
40322 ++ asm volatile("stc; int $0x15; setc %0"
40323 + : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
40324 +
40325 + if (err)
40326 +@@ -95,7 +95,7 @@ static int detect_memory_88(void)
40327 + u8 err;
40328 +
40329 + ax = 0x8800;
40330 +- asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
40331 ++ asm volatile("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
40332 +
40333 + boot_params.screen_info.ext_mem_k = ax;
40334 +
40335 +diff -urNp linux-2.6.27.7/arch/x86/boot/video.c linux-2.6.27.7/arch/x86/boot/video.c
40336 +--- linux-2.6.27.7/arch/x86/boot/video.c 2008-11-07 12:55:34.000000000 -0500
40337 ++++ linux-2.6.27.7/arch/x86/boot/video.c 2008-11-18 03:38:44.000000000 -0500
40338 +@@ -23,7 +23,7 @@ static void store_cursor_position(void)
40339 +
40340 + ax = 0x0300;
40341 + bx = 0;
40342 +- asm(INT10
40343 ++ asm volatile(INT10
40344 + : "=d" (curpos), "+a" (ax), "+b" (bx)
40345 + : : "ecx", "esi", "edi");
40346 +
40347 +@@ -38,7 +38,7 @@ static void store_video_mode(void)
40348 + /* N.B.: the saving of the video page here is a bit silly,
40349 + since we pretty much assume page 0 everywhere. */
40350 + ax = 0x0f00;
40351 +- asm(INT10
40352 ++ asm volatile(INT10
40353 + : "+a" (ax), "=b" (page)
40354 + : : "ecx", "edx", "esi", "edi");
40355 +
40356 +diff -urNp linux-2.6.27.7/arch/x86/boot/video-vesa.c linux-2.6.27.7/arch/x86/boot/video-vesa.c
40357 +--- linux-2.6.27.7/arch/x86/boot/video-vesa.c 2008-11-07 12:55:34.000000000 -0500
40358 ++++ linux-2.6.27.7/arch/x86/boot/video-vesa.c 2008-11-18 03:38:44.000000000 -0500
40359 +@@ -41,7 +41,7 @@ static int vesa_probe(void)
40360 +
40361 + ax = 0x4f00;
40362 + di = (size_t)&vginfo;
40363 +- asm(INT10
40364 ++ asm volatile(INT10
40365 + : "+a" (ax), "+D" (di), "=m" (vginfo)
40366 + : : "ebx", "ecx", "edx", "esi");
40367 +
40368 +@@ -68,7 +68,7 @@ static int vesa_probe(void)
40369 + ax = 0x4f01;
40370 + cx = mode;
40371 + di = (size_t)&vminfo;
40372 +- asm(INT10
40373 ++ asm volatile(INT10
40374 + : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
40375 + : : "ebx", "edx", "esi");
40376 +
40377 +@@ -123,7 +123,7 @@ static int vesa_set_mode(struct mode_inf
40378 + ax = 0x4f01;
40379 + cx = vesa_mode;
40380 + di = (size_t)&vminfo;
40381 +- asm(INT10
40382 ++ asm volatile(INT10
40383 + : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
40384 + : : "ebx", "edx", "esi");
40385 +
40386 +@@ -203,19 +203,20 @@ static void vesa_dac_set_8bits(void)
40387 + /* Save the VESA protected mode info */
40388 + static void vesa_store_pm_info(void)
40389 + {
40390 +- u16 ax, bx, di, es;
40391 ++ u16 ax, bx, cx, di, es;
40392 +
40393 + ax = 0x4f0a;
40394 +- bx = di = 0;
40395 +- asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
40396 +- : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
40397 +- : : "ecx", "esi");
40398 ++ bx = cx = di = 0;
40399 ++ asm volatile("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
40400 ++ : "=d" (es), "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di)
40401 ++ : : "esi");
40402 +
40403 + if (ax != 0x004f)
40404 + return;
40405 +
40406 + boot_params.screen_info.vesapm_seg = es;
40407 + boot_params.screen_info.vesapm_off = di;
40408 ++ boot_params.screen_info.vesapm_size = cx;
40409 + }
40410 +
40411 + /*
40412 +@@ -269,7 +270,7 @@ void vesa_store_edid(void)
40413 + /* Note: The VBE DDC spec is different from the main VESA spec;
40414 + we genuinely have to assume all registers are destroyed here. */
40415 +
40416 +- asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
40417 ++ asm volatile("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
40418 + : "+a" (ax), "+b" (bx)
40419 + : "c" (cx), "D" (di)
40420 + : "esi");
40421 +@@ -285,7 +286,7 @@ void vesa_store_edid(void)
40422 + cx = 0; /* Controller 0 */
40423 + dx = 0; /* EDID block number */
40424 + di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
40425 +- asm(INT10
40426 ++ asm volatile(INT10
40427 + : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info)
40428 + : "c" (cx), "D" (di)
40429 + : "esi");
40430 +diff -urNp linux-2.6.27.7/arch/x86/boot/video-vga.c linux-2.6.27.7/arch/x86/boot/video-vga.c
40431 +--- linux-2.6.27.7/arch/x86/boot/video-vga.c 2008-11-07 12:55:34.000000000 -0500
40432 ++++ linux-2.6.27.7/arch/x86/boot/video-vga.c 2008-11-18 03:38:44.000000000 -0500
40433 +@@ -225,7 +225,7 @@ static int vga_probe(void)
40434 + };
40435 + u8 vga_flag;
40436 +
40437 +- asm(INT10
40438 ++ asm volatile(INT10
40439 + : "=b" (ega_bx)
40440 + : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
40441 + : "ecx", "edx", "esi", "edi");
40442 +@@ -237,7 +237,7 @@ static int vga_probe(void)
40443 + /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
40444 + if ((u8)ega_bx != 0x10) {
40445 + /* EGA/VGA */
40446 +- asm(INT10
40447 ++ asm volatile(INT10
40448 + : "=a" (vga_flag)
40449 + : "a" (0x1a00)
40450 + : "ebx", "ecx", "edx", "esi", "edi");
40451 +diff -urNp linux-2.6.27.7/arch/x86/boot/voyager.c linux-2.6.27.7/arch/x86/boot/voyager.c
40452 +--- linux-2.6.27.7/arch/x86/boot/voyager.c 2008-11-07 12:55:34.000000000 -0500
40453 ++++ linux-2.6.27.7/arch/x86/boot/voyager.c 2008-11-18 03:38:44.000000000 -0500
40454 +@@ -23,7 +23,7 @@ int query_voyager(void)
40455 +
40456 + data_ptr[0] = 0xff; /* Flag on config not found(?) */
40457 +
40458 +- asm("pushw %%es ; "
40459 ++ asm volatile("pushw %%es ; "
40460 + "int $0x15 ; "
40461 + "setc %0 ; "
40462 + "movw %%es, %1 ; "
40463 +diff -urNp linux-2.6.27.7/arch/x86/ia32/ia32_signal.c linux-2.6.27.7/arch/x86/ia32/ia32_signal.c
40464 +--- linux-2.6.27.7/arch/x86/ia32/ia32_signal.c 2008-11-07 12:55:34.000000000 -0500
40465 ++++ linux-2.6.27.7/arch/x86/ia32/ia32_signal.c 2008-11-18 03:38:44.000000000 -0500
40466 +@@ -535,6 +535,7 @@ int ia32_setup_rt_frame(int sig, struct
40467 + __NR_ia32_rt_sigreturn,
40468 + 0x80cd,
40469 + 0,
40470 ++ 0
40471 + };
40472 +
40473 + frame = get_sigframe(ka, regs, sizeof(*frame));
40474 +diff -urNp linux-2.6.27.7/arch/x86/Kconfig linux-2.6.27.7/arch/x86/Kconfig
40475 +--- linux-2.6.27.7/arch/x86/Kconfig 2008-11-17 20:03:30.000000000 -0500
40476 ++++ linux-2.6.27.7/arch/x86/Kconfig 2008-11-18 03:38:44.000000000 -0500
40477 +@@ -912,7 +912,7 @@ config PAGE_OFFSET
40478 + hex
40479 + default 0xB0000000 if VMSPLIT_3G_OPT
40480 + default 0x80000000 if VMSPLIT_2G
40481 +- default 0x78000000 if VMSPLIT_2G_OPT
40482 ++ default 0x70000000 if VMSPLIT_2G_OPT
40483 + default 0x40000000 if VMSPLIT_1G
40484 + default 0xC0000000
40485 + depends on X86_32
40486 +@@ -1293,8 +1293,7 @@ config KEXEC_JUMP
40487 + config PHYSICAL_START
40488 + hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
40489 + default "0x1000000" if X86_NUMAQ
40490 +- default "0x200000" if X86_64
40491 +- default "0x100000"
40492 ++ default "0x200000"
40493 + help
40494 + This gives the physical address where the kernel is loaded.
40495 +
40496 +@@ -1386,9 +1385,9 @@ config HOTPLUG_CPU
40497 + suspend.
40498 +
40499 + config COMPAT_VDSO
40500 +- def_bool y
40501 ++ def_bool n
40502 + prompt "Compat VDSO support"
40503 +- depends on X86_32 || IA32_EMULATION
40504 ++ depends on (X86_32 || IA32_EMULATION) && !PAX_NOEXEC
40505 + help
40506 + Map the 32-bit VDSO to the predictable old-style address too.
40507 + ---help---
40508 +diff -urNp linux-2.6.27.7/arch/x86/Kconfig.cpu linux-2.6.27.7/arch/x86/Kconfig.cpu
40509 +--- linux-2.6.27.7/arch/x86/Kconfig.cpu 2008-11-07 12:55:34.000000000 -0500
40510 ++++ linux-2.6.27.7/arch/x86/Kconfig.cpu 2008-11-18 03:38:44.000000000 -0500
40511 +@@ -340,7 +340,7 @@ config X86_PPRO_FENCE
40512 +
40513 + config X86_F00F_BUG
40514 + def_bool y
40515 +- depends on M586MMX || M586TSC || M586 || M486 || M386
40516 ++ depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
40517 +
40518 + config X86_WP_WORKS_OK
40519 + def_bool y
40520 +@@ -360,7 +360,7 @@ config X86_POPAD_OK
40521 +
40522 + config X86_ALIGNMENT_16
40523 + def_bool y
40524 +- depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
40525 ++ depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MCORE2 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
40526 +
40527 + config X86_INTEL_USERCOPY
40528 + def_bool y
40529 +@@ -406,7 +406,7 @@ config X86_CMPXCHG64
40530 + # generates cmov.
40531 + config X86_CMOV
40532 + def_bool y
40533 +- depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || X86_64)
40534 ++ depends on (MK8 || MK7 || MCORE2 || MPSC || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || X86_64)
40535 +
40536 + config X86_MINIMUM_CPU_FAMILY
40537 + int
40538 +diff -urNp linux-2.6.27.7/arch/x86/Kconfig.debug linux-2.6.27.7/arch/x86/Kconfig.debug
40539 +--- linux-2.6.27.7/arch/x86/Kconfig.debug 2008-11-07 12:55:34.000000000 -0500
40540 ++++ linux-2.6.27.7/arch/x86/Kconfig.debug 2008-11-18 03:38:44.000000000 -0500
40541 +@@ -94,7 +94,7 @@ config X86_PTDUMP
40542 + config DEBUG_RODATA
40543 + bool "Write protect kernel read-only data structures"
40544 + default y
40545 +- depends on DEBUG_KERNEL
40546 ++ depends on DEBUG_KERNEL && BROKEN
40547 + help
40548 + Mark the kernel read-only data as write-protected in the pagetables,
40549 + in order to catch accidental (and incorrect) writes to such const
40550 +diff -urNp linux-2.6.27.7/arch/x86/kernel/acpi/boot.c linux-2.6.27.7/arch/x86/kernel/acpi/boot.c
40551 +--- linux-2.6.27.7/arch/x86/kernel/acpi/boot.c 2008-11-07 12:55:34.000000000 -0500
40552 ++++ linux-2.6.27.7/arch/x86/kernel/acpi/boot.c 2008-11-18 03:38:44.000000000 -0500
40553 +@@ -1635,7 +1635,7 @@ static struct dmi_system_id __initdata a
40554 + DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6715b"),
40555 + },
40556 + },
40557 +- {}
40558 ++ { NULL, NULL, {{0, NULL}}, NULL}
40559 + };
40560 +
40561 + /*
40562 +diff -urNp linux-2.6.27.7/arch/x86/kernel/acpi/realmode/wakeup.S linux-2.6.27.7/arch/x86/kernel/acpi/realmode/wakeup.S
40563 +--- linux-2.6.27.7/arch/x86/kernel/acpi/realmode/wakeup.S 2008-11-07 12:55:34.000000000 -0500
40564 ++++ linux-2.6.27.7/arch/x86/kernel/acpi/realmode/wakeup.S 2008-11-18 03:38:44.000000000 -0500
40565 +@@ -104,7 +104,7 @@ _start:
40566 + movl %eax, %ecx
40567 + orl %edx, %ecx
40568 + jz 1f
40569 +- movl $0xc0000080, %ecx
40570 ++ mov $MSR_EFER, %ecx
40571 + wrmsr
40572 + 1:
40573 +
40574 +diff -urNp linux-2.6.27.7/arch/x86/kernel/acpi/sleep.c linux-2.6.27.7/arch/x86/kernel/acpi/sleep.c
40575 +--- linux-2.6.27.7/arch/x86/kernel/acpi/sleep.c 2008-11-07 12:55:34.000000000 -0500
40576 ++++ linux-2.6.27.7/arch/x86/kernel/acpi/sleep.c 2008-11-18 11:45:34.000000000 -0500
40577 +@@ -37,6 +37,10 @@ int acpi_save_state_mem(void)
40578 + {
40579 + struct wakeup_header *header;
40580 +
40581 ++#if defined(CONFIG_64BIT) && defined(CONFIG_SMP) && defined(CONFIG_PAX_KERNEXEC)
40582 ++ unsigned long cr0;
40583 ++#endif
40584 ++
40585 + if (!acpi_realmode) {
40586 + printk(KERN_ERR "Could not allocate memory during boot, "
40587 + "S3 disabled\n");
40588 +@@ -99,8 +103,18 @@ int acpi_save_state_mem(void)
40589 + header->trampoline_segment = setup_trampoline() >> 4;
40590 + #ifdef CONFIG_SMP
40591 + stack_start.sp = temp_stack + 4096;
40592 ++
40593 ++#ifdef CONFIG_PAX_KERNEXEC
40594 ++ pax_open_kernel(cr0);
40595 ++#endif
40596 ++
40597 + early_gdt_descr.address =
40598 + (unsigned long)get_cpu_gdt_table(smp_processor_id());
40599 ++
40600 ++#ifdef CONFIG_PAX_KERNEXEC
40601 ++ pax_close_kernel(cr0);
40602 ++#endif
40603 ++
40604 + #endif
40605 + initial_code = (unsigned long)wakeup_long64;
40606 + saved_magic = 0x123456789abcdef0;
40607 +diff -urNp linux-2.6.27.7/arch/x86/kernel/acpi/wakeup_32.S linux-2.6.27.7/arch/x86/kernel/acpi/wakeup_32.S
40608 +--- linux-2.6.27.7/arch/x86/kernel/acpi/wakeup_32.S 2008-11-07 12:55:34.000000000 -0500
40609 ++++ linux-2.6.27.7/arch/x86/kernel/acpi/wakeup_32.S 2008-11-18 03:38:44.000000000 -0500
40610 +@@ -30,13 +30,11 @@ wakeup_pmode_return:
40611 + # and restore the stack ... but you need gdt for this to work
40612 + movl saved_context_esp, %esp
40613 +
40614 +- movl %cs:saved_magic, %eax
40615 +- cmpl $0x12345678, %eax
40616 ++ cmpl $0x12345678, saved_magic
40617 + jne bogus_magic
40618 +
40619 + # jump to place where we left off
40620 +- movl saved_eip, %eax
40621 +- jmp *%eax
40622 ++ jmp *(saved_eip)
40623 +
40624 + bogus_magic:
40625 + jmp bogus_magic
40626 +diff -urNp linux-2.6.27.7/arch/x86/kernel/alternative.c linux-2.6.27.7/arch/x86/kernel/alternative.c
40627 +--- linux-2.6.27.7/arch/x86/kernel/alternative.c 2008-11-07 12:55:34.000000000 -0500
40628 ++++ linux-2.6.27.7/arch/x86/kernel/alternative.c 2008-11-18 03:38:44.000000000 -0500
40629 +@@ -393,7 +393,7 @@ void apply_paravirt(struct paravirt_patc
40630 +
40631 + BUG_ON(p->len > MAX_PATCH_LEN);
40632 + /* prep the buffer with the original instructions */
40633 +- memcpy(insnbuf, p->instr, p->len);
40634 ++ memcpy(insnbuf, ktla_ktva(p->instr), p->len);
40635 + used = pv_init_ops.patch(p->instrtype, p->clobbers, insnbuf,
40636 + (unsigned long)p->instr, p->len);
40637 +
40638 +@@ -473,11 +473,26 @@ void __init alternative_instructions(voi
40639 + * instructions. And on the local CPU you need to be protected again NMI or MCE
40640 + * handlers seeing an inconsistent instruction while you patch.
40641 + */
40642 +-void *text_poke_early(void *addr, const void *opcode, size_t len)
40643 ++void *__kprobes text_poke_early(void *addr, const void *opcode, size_t len)
40644 + {
40645 + unsigned long flags;
40646 ++
40647 ++#ifdef CONFIG_PAX_KERNEXEC
40648 ++ unsigned long cr0;
40649 ++#endif
40650 ++
40651 + local_irq_save(flags);
40652 +- memcpy(addr, opcode, len);
40653 ++
40654 ++#ifdef CONFIG_PAX_KERNEXEC
40655 ++ pax_open_kernel(cr0);
40656 ++#endif
40657 ++
40658 ++ memcpy(ktla_ktva(addr), opcode, len);
40659 ++
40660 ++#ifdef CONFIG_PAX_KERNEXEC
40661 ++ pax_close_kernel(cr0);
40662 ++#endif
40663 ++
40664 + local_irq_restore(flags);
40665 + sync_core();
40666 + /* Could also do a CLFLUSH here to speed up CPU recovery; but
40667 +@@ -498,33 +513,27 @@ void *text_poke_early(void *addr, const
40668 + */
40669 + void *__kprobes text_poke(void *addr, const void *opcode, size_t len)
40670 + {
40671 +- unsigned long flags;
40672 +- char *vaddr;
40673 +- int nr_pages = 2;
40674 ++ unsigned char *vaddr = ktla_ktva(addr);
40675 + struct page *pages[2];
40676 +- int i;
40677 ++ size_t i;
40678 ++
40679 ++ if (!core_kernel_text((unsigned long)addr)
40680 +
40681 +- if (!core_kernel_text((unsigned long)addr)) {
40682 +- pages[0] = vmalloc_to_page(addr);
40683 +- pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
40684 ++#if defined(CONFIG_X86_32) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
40685 ++ && (vaddr < MODULES_VADDR || MODULES_END < vaddr)
40686 ++#endif
40687 ++
40688 ++ ) {
40689 ++ pages[0] = vmalloc_to_page(vaddr);
40690 ++ pages[1] = vmalloc_to_page(vaddr + PAGE_SIZE);
40691 + } else {
40692 +- pages[0] = virt_to_page(addr);
40693 ++ pages[0] = virt_to_page(vaddr);
40694 + WARN_ON(!PageReserved(pages[0]));
40695 +- pages[1] = virt_to_page(addr + PAGE_SIZE);
40696 ++ pages[1] = virt_to_page(vaddr + PAGE_SIZE);
40697 + }
40698 + BUG_ON(!pages[0]);
40699 +- if (!pages[1])
40700 +- nr_pages = 1;
40701 +- vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL);
40702 +- BUG_ON(!vaddr);
40703 +- local_irq_save(flags);
40704 +- memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len);
40705 +- local_irq_restore(flags);
40706 +- vunmap(vaddr);
40707 +- sync_core();
40708 +- /* Could also do a CLFLUSH here to speed up CPU recovery; but
40709 +- that causes hangs on some VIA CPUs. */
40710 ++ text_poke_early(addr, opcode, len);
40711 + for (i = 0; i < len; i++)
40712 +- BUG_ON(((char *)addr)[i] != ((char *)opcode)[i]);
40713 ++ BUG_ON((vaddr)[i] != ((unsigned char *)opcode)[i]);
40714 + return addr;
40715 + }
40716 +diff -urNp linux-2.6.27.7/arch/x86/kernel/apm_32.c linux-2.6.27.7/arch/x86/kernel/apm_32.c
40717 +--- linux-2.6.27.7/arch/x86/kernel/apm_32.c 2008-11-07 12:55:34.000000000 -0500
40718 ++++ linux-2.6.27.7/arch/x86/kernel/apm_32.c 2008-11-18 03:38:44.000000000 -0500
40719 +@@ -408,7 +408,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitq
40720 + static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
40721 + static struct apm_user *user_list;
40722 + static DEFINE_SPINLOCK(user_list_lock);
40723 +-static const struct desc_struct bad_bios_desc = { { { 0, 0x00409200 } } };
40724 ++static const struct desc_struct bad_bios_desc = { { { 0, 0x00409300 } } };
40725 +
40726 + static const char driver_version[] = "1.16ac"; /* no spaces */
40727 +
40728 +@@ -603,19 +603,42 @@ static u8 apm_bios_call(u32 func, u32 eb
40729 + struct desc_struct save_desc_40;
40730 + struct desc_struct *gdt;
40731 +
40732 ++#ifdef CONFIG_PAX_KERNEXEC
40733 ++ unsigned long cr0;
40734 ++#endif
40735 ++
40736 + cpus = apm_save_cpus();
40737 +
40738 + cpu = get_cpu();
40739 + gdt = get_cpu_gdt_table(cpu);
40740 + save_desc_40 = gdt[0x40 / 8];
40741 ++
40742 ++#ifdef CONFIG_PAX_KERNEXEC
40743 ++ pax_open_kernel(cr0);
40744 ++#endif
40745 ++
40746 + gdt[0x40 / 8] = bad_bios_desc;
40747 +
40748 ++#ifdef CONFIG_PAX_KERNEXEC
40749 ++ pax_close_kernel(cr0);
40750 ++#endif
40751 ++
40752 + apm_irq_save(flags);
40753 + APM_DO_SAVE_SEGS;
40754 + apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
40755 + APM_DO_RESTORE_SEGS;
40756 + apm_irq_restore(flags);
40757 ++
40758 ++#ifdef CONFIG_PAX_KERNEXEC
40759 ++ pax_open_kernel(cr0);
40760 ++#endif
40761 ++
40762 + gdt[0x40 / 8] = save_desc_40;
40763 ++
40764 ++#ifdef CONFIG_PAX_KERNEXEC
40765 ++ pax_close_kernel(cr0);
40766 ++#endif
40767 ++
40768 + put_cpu();
40769 + apm_restore_cpus(cpus);
40770 +
40771 +@@ -646,19 +669,42 @@ static u8 apm_bios_call_simple(u32 func,
40772 + struct desc_struct save_desc_40;
40773 + struct desc_struct *gdt;
40774 +
40775 ++#ifdef CONFIG_PAX_KERNEXEC
40776 ++ unsigned long cr0;
40777 ++#endif
40778 ++
40779 + cpus = apm_save_cpus();
40780 +
40781 + cpu = get_cpu();
40782 + gdt = get_cpu_gdt_table(cpu);
40783 + save_desc_40 = gdt[0x40 / 8];
40784 ++
40785 ++#ifdef CONFIG_PAX_KERNEXEC
40786 ++ pax_open_kernel(cr0);
40787 ++#endif
40788 ++
40789 + gdt[0x40 / 8] = bad_bios_desc;
40790 +
40791 ++#ifdef CONFIG_PAX_KERNEXEC
40792 ++ pax_close_kernel(cr0);
40793 ++#endif
40794 ++
40795 + apm_irq_save(flags);
40796 + APM_DO_SAVE_SEGS;
40797 + error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
40798 + APM_DO_RESTORE_SEGS;
40799 + apm_irq_restore(flags);
40800 ++
40801 ++#ifdef CONFIG_PAX_KERNEXEC
40802 ++ pax_open_kernel(cr0);
40803 ++#endif
40804 ++
40805 + gdt[0x40 / 8] = save_desc_40;
40806 ++
40807 ++#ifdef CONFIG_PAX_KERNEXEC
40808 ++ pax_close_kernel(cr0);
40809 ++#endif
40810 ++
40811 + put_cpu();
40812 + apm_restore_cpus(cpus);
40813 + return error;
40814 +@@ -930,7 +976,7 @@ recalc:
40815 +
40816 + static void apm_power_off(void)
40817 + {
40818 +- unsigned char po_bios_call[] = {
40819 ++ const unsigned char po_bios_call[] = {
40820 + 0xb8, 0x00, 0x10, /* movw $0x1000,ax */
40821 + 0x8e, 0xd0, /* movw ax,ss */
40822 + 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */
40823 +@@ -1877,7 +1923,10 @@ static const struct file_operations apm_
40824 + static struct miscdevice apm_device = {
40825 + APM_MINOR_DEV,
40826 + "apm_bios",
40827 +- &apm_bios_fops
40828 ++ &apm_bios_fops,
40829 ++ {NULL, NULL},
40830 ++ NULL,
40831 ++ NULL
40832 + };
40833 +
40834 +
40835 +@@ -2198,7 +2247,7 @@ static struct dmi_system_id __initdata a
40836 + { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
40837 + },
40838 +
40839 +- { }
40840 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
40841 + };
40842 +
40843 + /*
40844 +@@ -2216,6 +2265,10 @@ static int __init apm_init(void)
40845 + struct desc_struct *gdt;
40846 + int err;
40847 +
40848 ++#ifdef CONFIG_PAX_KERNEXEC
40849 ++ unsigned long cr0;
40850 ++#endif
40851 ++
40852 + dmi_check_system(apm_dmi_table);
40853 +
40854 + if (apm_info.bios.version == 0 || paravirt_enabled() || machine_is_olpc()) {
40855 +@@ -2289,9 +2342,18 @@ static int __init apm_init(void)
40856 + * This is for buggy BIOS's that refer to (real mode) segment 0x40
40857 + * even though they are called in protected mode.
40858 + */
40859 ++
40860 ++#ifdef CONFIG_PAX_KERNEXEC
40861 ++ pax_open_kernel(cr0);
40862 ++#endif
40863 ++
40864 + set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
40865 + _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
40866 +
40867 ++#ifdef CONFIG_PAX_KERNEXEC
40868 ++ pax_close_kernel(cr0);
40869 ++#endif
40870 ++
40871 + /*
40872 + * Set up the long jump entry point to the APM BIOS, which is called
40873 + * from inline assembly.
40874 +@@ -2310,6 +2372,11 @@ static int __init apm_init(void)
40875 + * code to that CPU.
40876 + */
40877 + gdt = get_cpu_gdt_table(0);
40878 ++
40879 ++#ifdef CONFIG_PAX_KERNEXEC
40880 ++ pax_open_kernel(cr0);
40881 ++#endif
40882 ++
40883 + set_base(gdt[APM_CS >> 3],
40884 + __va((unsigned long)apm_info.bios.cseg << 4));
40885 + set_base(gdt[APM_CS_16 >> 3],
40886 +@@ -2317,6 +2384,10 @@ static int __init apm_init(void)
40887 + set_base(gdt[APM_DS >> 3],
40888 + __va((unsigned long)apm_info.bios.dseg << 4));
40889 +
40890 ++#ifdef CONFIG_PAX_KERNEXEC
40891 ++ pax_close_kernel(cr0);
40892 ++#endif
40893 ++
40894 + proc_create("apm", 0, NULL, &apm_file_ops);
40895 +
40896 + kapmd_task = kthread_create(apm, NULL, "kapmd");
40897 +diff -urNp linux-2.6.27.7/arch/x86/kernel/asm-offsets_32.c linux-2.6.27.7/arch/x86/kernel/asm-offsets_32.c
40898 +--- linux-2.6.27.7/arch/x86/kernel/asm-offsets_32.c 2008-11-07 12:55:34.000000000 -0500
40899 ++++ linux-2.6.27.7/arch/x86/kernel/asm-offsets_32.c 2008-11-18 03:38:44.000000000 -0500
40900 +@@ -100,6 +100,7 @@ void foo(void)
40901 + DEFINE(PTRS_PER_PTE, PTRS_PER_PTE);
40902 + DEFINE(PTRS_PER_PMD, PTRS_PER_PMD);
40903 + DEFINE(PTRS_PER_PGD, PTRS_PER_PGD);
40904 ++ DEFINE(PERCPU_MODULE_RESERVE, PERCPU_MODULE_RESERVE);
40905 +
40906 + OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
40907 +
40908 +@@ -113,6 +114,7 @@ void foo(void)
40909 + OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
40910 + OFFSET(PV_CPU_irq_enable_sysexit, pv_cpu_ops, irq_enable_sysexit);
40911 + OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
40912 ++ OFFSET(PV_CPU_write_cr0, pv_cpu_ops, write_cr0);
40913 + #endif
40914 +
40915 + #ifdef CONFIG_XEN
40916 +diff -urNp linux-2.6.27.7/arch/x86/kernel/asm-offsets_64.c linux-2.6.27.7/arch/x86/kernel/asm-offsets_64.c
40917 +--- linux-2.6.27.7/arch/x86/kernel/asm-offsets_64.c 2008-11-07 12:55:34.000000000 -0500
40918 ++++ linux-2.6.27.7/arch/x86/kernel/asm-offsets_64.c 2008-11-18 03:38:44.000000000 -0500
40919 +@@ -122,6 +122,7 @@ int main(void)
40920 + ENTRY(cr8);
40921 + BLANK();
40922 + #undef ENTRY
40923 ++ DEFINE(TSS_size, sizeof(struct tss_struct));
40924 + DEFINE(TSS_ist, offsetof(struct tss_struct, x86_tss.ist));
40925 + BLANK();
40926 + DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
40927 +diff -urNp linux-2.6.27.7/arch/x86/kernel/cpu/common_64.c linux-2.6.27.7/arch/x86/kernel/cpu/common_64.c
40928 +--- linux-2.6.27.7/arch/x86/kernel/cpu/common_64.c 2008-11-07 12:55:34.000000000 -0500
40929 ++++ linux-2.6.27.7/arch/x86/kernel/cpu/common_64.c 2008-11-18 03:38:44.000000000 -0500
40930 +@@ -37,22 +37,6 @@
40931 +
40932 + #include "cpu.h"
40933 +
40934 +-/* We need valid kernel segments for data and code in long mode too
40935 +- * IRET will check the segment types kkeil 2000/10/28
40936 +- * Also sysret mandates a special GDT layout
40937 +- */
40938 +-/* The TLS descriptors are currently at a different place compared to i386.
40939 +- Hopefully nobody expects them at a fixed place (Wine?) */
40940 +-DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
40941 +- [GDT_ENTRY_KERNEL32_CS] = { { { 0x0000ffff, 0x00cf9b00 } } },
40942 +- [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00af9b00 } } },
40943 +- [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9300 } } },
40944 +- [GDT_ENTRY_DEFAULT_USER32_CS] = { { { 0x0000ffff, 0x00cffb00 } } },
40945 +- [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff300 } } },
40946 +- [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00affb00 } } },
40947 +-} };
40948 +-EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
40949 +-
40950 + __u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
40951 +
40952 + /* Current gdt points %fs at the "master" per-cpu area: after this,
40953 +@@ -457,15 +441,13 @@ cpumask_t cpu_initialized __cpuinitdata
40954 + struct x8664_pda **_cpu_pda __read_mostly;
40955 + EXPORT_SYMBOL(_cpu_pda);
40956 +
40957 +-struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
40958 ++struct desc_ptr idt_descr __read_only = { 256 * 16 - 1, (unsigned long) idt_table };
40959 +
40960 + char boot_cpu_stack[IRQSTACKSIZE] __page_aligned_bss;
40961 +
40962 + unsigned long __supported_pte_mask __read_mostly = ~0UL;
40963 + EXPORT_SYMBOL_GPL(__supported_pte_mask);
40964 +
40965 +-static int do_not_nx __cpuinitdata;
40966 +-
40967 + /* noexec=on|off
40968 + Control non executable mappings for 64bit processes.
40969 +
40970 +@@ -478,9 +460,7 @@ static int __init nonx_setup(char *str)
40971 + return -EINVAL;
40972 + if (!strncmp(str, "on", 2)) {
40973 + __supported_pte_mask |= _PAGE_NX;
40974 +- do_not_nx = 0;
40975 + } else if (!strncmp(str, "off", 3)) {
40976 +- do_not_nx = 1;
40977 + __supported_pte_mask &= ~_PAGE_NX;
40978 + }
40979 + return 0;
40980 +@@ -576,7 +556,7 @@ void __cpuinit check_efer(void)
40981 + unsigned long efer;
40982 +
40983 + rdmsrl(MSR_EFER, efer);
40984 +- if (!(efer & EFER_NX) || do_not_nx)
40985 ++ if (!(efer & EFER_NX))
40986 + __supported_pte_mask &= ~_PAGE_NX;
40987 + }
40988 +
40989 +@@ -598,7 +578,7 @@ DEFINE_PER_CPU(struct orig_ist, orig_ist
40990 + void __cpuinit cpu_init(void)
40991 + {
40992 + int cpu = stack_smp_processor_id();
40993 +- struct tss_struct *t = &per_cpu(init_tss, cpu);
40994 ++ struct tss_struct *t = init_tss + cpu;
40995 + struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu);
40996 + unsigned long v;
40997 + char *estacks = NULL;
40998 +diff -urNp linux-2.6.27.7/arch/x86/kernel/cpu/common.c linux-2.6.27.7/arch/x86/kernel/cpu/common.c
40999 +--- linux-2.6.27.7/arch/x86/kernel/cpu/common.c 2008-11-07 12:55:34.000000000 -0500
41000 ++++ linux-2.6.27.7/arch/x86/kernel/cpu/common.c 2008-11-18 03:38:44.000000000 -0500
41001 +@@ -4,7 +4,6 @@
41002 + #include <linux/smp.h>
41003 + #include <linux/module.h>
41004 + #include <linux/percpu.h>
41005 +-#include <linux/bootmem.h>
41006 + #include <asm/processor.h>
41007 + #include <asm/i387.h>
41008 + #include <asm/msr.h>
41009 +@@ -22,42 +21,6 @@
41010 +
41011 + #include "cpu.h"
41012 +
41013 +-DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
41014 +- [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } },
41015 +- [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } },
41016 +- [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } },
41017 +- [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } },
41018 +- /*
41019 +- * Segments used for calling PnP BIOS have byte granularity.
41020 +- * They code segments and data segments have fixed 64k limits,
41021 +- * the transfer segment sizes are set at run time.
41022 +- */
41023 +- /* 32-bit code */
41024 +- [GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } },
41025 +- /* 16-bit code */
41026 +- [GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } },
41027 +- /* 16-bit data */
41028 +- [GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } },
41029 +- /* 16-bit data */
41030 +- [GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } },
41031 +- /* 16-bit data */
41032 +- [GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } },
41033 +- /*
41034 +- * The APM segments have byte granularity and their bases
41035 +- * are set at run time. All have 64k limits.
41036 +- */
41037 +- /* 32-bit code */
41038 +- [GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } },
41039 +- /* 16-bit code */
41040 +- [GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } },
41041 +- /* data */
41042 +- [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } },
41043 +-
41044 +- [GDT_ENTRY_ESPFIX_SS] = { { { 0x00000000, 0x00c09200 } } },
41045 +- [GDT_ENTRY_PERCPU] = { { { 0x00000000, 0x00000000 } } },
41046 +-} };
41047 +-EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
41048 +-
41049 + __u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
41050 +
41051 + static int cachesize_override __cpuinitdata = -1;
41052 +@@ -493,6 +456,10 @@ static void __cpuinit identify_cpu(struc
41053 + * we do "generic changes."
41054 + */
41055 +
41056 ++#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
41057 ++ setup_clear_cpu_cap(X86_FEATURE_SEP);
41058 ++#endif
41059 ++
41060 + /* If the model name is still unset, do table lookup. */
41061 + if (!c->x86_model_id[0]) {
41062 + char *p;
41063 +@@ -629,7 +596,7 @@ static __init int setup_disablecpuid(cha
41064 + }
41065 + __setup("clearcpuid=", setup_disablecpuid);
41066 +
41067 +-cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
41068 ++cpumask_t cpu_initialized = CPU_MASK_NONE;
41069 +
41070 + void __init early_cpu_init(void)
41071 + {
41072 +@@ -658,7 +625,7 @@ void switch_to_new_gdt(void)
41073 + {
41074 + struct desc_ptr gdt_descr;
41075 +
41076 +- gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
41077 ++ gdt_descr.address = (unsigned long)get_cpu_gdt_table(smp_processor_id());
41078 + gdt_descr.size = GDT_SIZE - 1;
41079 + load_gdt(&gdt_descr);
41080 + asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory");
41081 +@@ -674,7 +641,7 @@ void __cpuinit cpu_init(void)
41082 + {
41083 + int cpu = smp_processor_id();
41084 + struct task_struct *curr = current;
41085 +- struct tss_struct *t = &per_cpu(init_tss, cpu);
41086 ++ struct tss_struct *t = init_tss + cpu;
41087 + struct thread_struct *thread = &curr->thread;
41088 +
41089 + if (cpu_test_and_set(cpu, cpu_initialized)) {
41090 +@@ -729,7 +696,7 @@ void __cpuinit cpu_init(void)
41091 + }
41092 +
41093 + #ifdef CONFIG_HOTPLUG_CPU
41094 +-void __cpuinit cpu_uninit(void)
41095 ++void cpu_uninit(void)
41096 + {
41097 + int cpu = raw_smp_processor_id();
41098 + cpu_clear(cpu, cpu_initialized);
41099 +diff -urNp linux-2.6.27.7/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c linux-2.6.27.7/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
41100 +--- linux-2.6.27.7/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-11-07 12:55:34.000000000 -0500
41101 ++++ linux-2.6.27.7/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-11-18 03:38:44.000000000 -0500
41102 +@@ -560,7 +560,7 @@ static const struct dmi_system_id sw_any
41103 + DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
41104 + },
41105 + },
41106 +- { }
41107 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
41108 + };
41109 + #endif
41110 +
41111 +diff -urNp linux-2.6.27.7/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c linux-2.6.27.7/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
41112 +--- linux-2.6.27.7/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2008-11-07 12:55:34.000000000 -0500
41113 ++++ linux-2.6.27.7/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2008-11-18 03:38:44.000000000 -0500
41114 +@@ -225,7 +225,7 @@ static struct cpu_model models[] =
41115 + { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
41116 + { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
41117 +
41118 +- { NULL, }
41119 ++ { NULL, NULL, 0, NULL}
41120 + };
41121 + #undef _BANIAS
41122 + #undef BANIAS
41123 +diff -urNp linux-2.6.27.7/arch/x86/kernel/cpu/intel.c linux-2.6.27.7/arch/x86/kernel/cpu/intel.c
41124 +--- linux-2.6.27.7/arch/x86/kernel/cpu/intel.c 2008-11-07 12:55:34.000000000 -0500
41125 ++++ linux-2.6.27.7/arch/x86/kernel/cpu/intel.c 2008-11-18 03:38:44.000000000 -0500
41126 +@@ -107,7 +107,7 @@ static void __cpuinit trap_init_f00f_bug
41127 + * Update the IDT descriptor and reload the IDT so that
41128 + * it uses the read-only mapped virtual address.
41129 + */
41130 +- idt_descr.address = fix_to_virt(FIX_F00F_IDT);
41131 ++ idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
41132 + load_idt(&idt_descr);
41133 + }
41134 + #endif
41135 +diff -urNp linux-2.6.27.7/arch/x86/kernel/cpu/mcheck/mce_64.c linux-2.6.27.7/arch/x86/kernel/cpu/mcheck/mce_64.c
41136 +--- linux-2.6.27.7/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-11-07 12:55:34.000000000 -0500
41137 ++++ linux-2.6.27.7/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-11-18 03:38:44.000000000 -0500
41138 +@@ -681,6 +681,7 @@ static struct miscdevice mce_log_device
41139 + MISC_MCELOG_MINOR,
41140 + "mcelog",
41141 + &mce_chrdev_ops,
41142 ++ {NULL, NULL}, NULL, NULL
41143 + };
41144 +
41145 + static unsigned long old_cr4 __initdata;
41146 +diff -urNp linux-2.6.27.7/arch/x86/kernel/cpu/mtrr/generic.c linux-2.6.27.7/arch/x86/kernel/cpu/mtrr/generic.c
41147 +--- linux-2.6.27.7/arch/x86/kernel/cpu/mtrr/generic.c 2008-11-07 12:55:34.000000000 -0500
41148 ++++ linux-2.6.27.7/arch/x86/kernel/cpu/mtrr/generic.c 2008-11-18 03:38:44.000000000 -0500
41149 +@@ -31,11 +31,11 @@ static struct fixed_range_block fixed_ra
41150 + { MTRRfix64K_00000_MSR, 1 }, /* one 64k MTRR */
41151 + { MTRRfix16K_80000_MSR, 2 }, /* two 16k MTRRs */
41152 + { MTRRfix4K_C0000_MSR, 8 }, /* eight 4k MTRRs */
41153 +- {}
41154 ++ { 0, 0 }
41155 + };
41156 +
41157 + static unsigned long smp_changes_mask;
41158 +-static struct mtrr_state mtrr_state = {};
41159 ++static struct mtrr_state mtrr_state;
41160 + static int mtrr_state_set;
41161 + u64 mtrr_tom2;
41162 +
41163 +diff -urNp linux-2.6.27.7/arch/x86/kernel/crash.c linux-2.6.27.7/arch/x86/kernel/crash.c
41164 +--- linux-2.6.27.7/arch/x86/kernel/crash.c 2008-11-07 12:55:34.000000000 -0500
41165 ++++ linux-2.6.27.7/arch/x86/kernel/crash.c 2008-11-18 03:38:44.000000000 -0500
41166 +@@ -59,7 +59,7 @@ static int crash_nmi_callback(struct not
41167 + local_irq_disable();
41168 +
41169 + #ifdef CONFIG_X86_32
41170 +- if (!user_mode_vm(regs)) {
41171 ++ if (!user_mode(regs)) {
41172 + crash_fixup_ss_esp(&fixed_regs, regs);
41173 + regs = &fixed_regs;
41174 + }
41175 +diff -urNp linux-2.6.27.7/arch/x86/kernel/doublefault_32.c linux-2.6.27.7/arch/x86/kernel/doublefault_32.c
41176 +--- linux-2.6.27.7/arch/x86/kernel/doublefault_32.c 2008-11-07 12:55:34.000000000 -0500
41177 ++++ linux-2.6.27.7/arch/x86/kernel/doublefault_32.c 2008-11-18 03:38:44.000000000 -0500
41178 +@@ -11,7 +11,7 @@
41179 +
41180 + #define DOUBLEFAULT_STACKSIZE (1024)
41181 + static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
41182 +-#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
41183 ++#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
41184 +
41185 + #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
41186 +
41187 +@@ -21,7 +21,7 @@ static void doublefault_fn(void)
41188 + unsigned long gdt, tss;
41189 +
41190 + store_gdt(&gdt_desc);
41191 +- gdt = gdt_desc.address;
41192 ++ gdt = (unsigned long)gdt_desc.address;
41193 +
41194 + printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
41195 +
41196 +@@ -60,10 +60,10 @@ struct tss_struct doublefault_tss __cach
41197 + /* 0x2 bit is always set */
41198 + .flags = X86_EFLAGS_SF | 0x2,
41199 + .sp = STACK_START,
41200 +- .es = __USER_DS,
41201 ++ .es = __KERNEL_DS,
41202 + .cs = __KERNEL_CS,
41203 + .ss = __KERNEL_DS,
41204 +- .ds = __USER_DS,
41205 ++ .ds = __KERNEL_DS,
41206 + .fs = __KERNEL_PERCPU,
41207 +
41208 + .__cr3 = __pa(swapper_pg_dir)
41209 +diff -urNp linux-2.6.27.7/arch/x86/kernel/efi_32.c linux-2.6.27.7/arch/x86/kernel/efi_32.c
41210 +--- linux-2.6.27.7/arch/x86/kernel/efi_32.c 2008-11-07 12:55:34.000000000 -0500
41211 ++++ linux-2.6.27.7/arch/x86/kernel/efi_32.c 2008-11-18 03:38:44.000000000 -0500
41212 +@@ -38,70 +38,38 @@
41213 + */
41214 +
41215 + static unsigned long efi_rt_eflags;
41216 +-static pgd_t efi_bak_pg_dir_pointer[2];
41217 ++static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS];
41218 +
41219 +-void efi_call_phys_prelog(void)
41220 ++void __init efi_call_phys_prelog(void)
41221 + {
41222 +- unsigned long cr4;
41223 +- unsigned long temp;
41224 + struct desc_ptr gdt_descr;
41225 +
41226 + local_irq_save(efi_rt_eflags);
41227 +
41228 +- /*
41229 +- * If I don't have PAE, I should just duplicate two entries in page
41230 +- * directory. If I have PAE, I just need to duplicate one entry in
41231 +- * page directory.
41232 +- */
41233 +- cr4 = read_cr4_safe();
41234 +
41235 +- if (cr4 & X86_CR4_PAE) {
41236 +- efi_bak_pg_dir_pointer[0].pgd =
41237 +- swapper_pg_dir[pgd_index(0)].pgd;
41238 +- swapper_pg_dir[0].pgd =
41239 +- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
41240 +- } else {
41241 +- efi_bak_pg_dir_pointer[0].pgd =
41242 +- swapper_pg_dir[pgd_index(0)].pgd;
41243 +- efi_bak_pg_dir_pointer[1].pgd =
41244 +- swapper_pg_dir[pgd_index(0x400000)].pgd;
41245 +- swapper_pg_dir[pgd_index(0)].pgd =
41246 +- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
41247 +- temp = PAGE_OFFSET + 0x400000;
41248 +- swapper_pg_dir[pgd_index(0x400000)].pgd =
41249 +- swapper_pg_dir[pgd_index(temp)].pgd;
41250 +- }
41251 ++ clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
41252 ++ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
41253 ++ min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
41254 +
41255 + /*
41256 + * After the lock is released, the original page table is restored.
41257 + */
41258 + __flush_tlb_all();
41259 +
41260 +- gdt_descr.address = __pa(get_cpu_gdt_table(0));
41261 ++ gdt_descr.address = (struct desc_struct *)__pa(get_cpu_gdt_table(0));
41262 + gdt_descr.size = GDT_SIZE - 1;
41263 + load_gdt(&gdt_descr);
41264 + }
41265 +
41266 +-void efi_call_phys_epilog(void)
41267 ++void __init efi_call_phys_epilog(void)
41268 + {
41269 +- unsigned long cr4;
41270 + struct desc_ptr gdt_descr;
41271 +
41272 +- gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
41273 ++ gdt_descr.address = get_cpu_gdt_table(0);
41274 + gdt_descr.size = GDT_SIZE - 1;
41275 + load_gdt(&gdt_descr);
41276 +
41277 +- cr4 = read_cr4_safe();
41278 +-
41279 +- if (cr4 & X86_CR4_PAE) {
41280 +- swapper_pg_dir[pgd_index(0)].pgd =
41281 +- efi_bak_pg_dir_pointer[0].pgd;
41282 +- } else {
41283 +- swapper_pg_dir[pgd_index(0)].pgd =
41284 +- efi_bak_pg_dir_pointer[0].pgd;
41285 +- swapper_pg_dir[pgd_index(0x400000)].pgd =
41286 +- efi_bak_pg_dir_pointer[1].pgd;
41287 +- }
41288 ++ clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
41289 +
41290 + /*
41291 + * After the lock is released, the original page table is restored.
41292 +diff -urNp linux-2.6.27.7/arch/x86/kernel/efi_stub_32.S linux-2.6.27.7/arch/x86/kernel/efi_stub_32.S
41293 +--- linux-2.6.27.7/arch/x86/kernel/efi_stub_32.S 2008-11-07 12:55:34.000000000 -0500
41294 ++++ linux-2.6.27.7/arch/x86/kernel/efi_stub_32.S 2008-11-18 03:38:44.000000000 -0500
41295 +@@ -6,6 +6,7 @@
41296 + */
41297 +
41298 + #include <linux/linkage.h>
41299 ++#include <linux/init.h>
41300 + #include <asm/page.h>
41301 +
41302 + /*
41303 +@@ -20,7 +21,7 @@
41304 + * service functions will comply with gcc calling convention, too.
41305 + */
41306 +
41307 +-.text
41308 ++__INIT
41309 + ENTRY(efi_call_phys)
41310 + /*
41311 + * 0. The function can only be called in Linux kernel. So CS has been
41312 +@@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
41313 + * The mapping of lower virtual memory has been created in prelog and
41314 + * epilog.
41315 + */
41316 +- movl $1f, %edx
41317 +- subl $__PAGE_OFFSET, %edx
41318 +- jmp *%edx
41319 ++ jmp 1f-__PAGE_OFFSET
41320 + 1:
41321 +
41322 + /*
41323 +@@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
41324 + * parameter 2, ..., param n. To make things easy, we save the return
41325 + * address of efi_call_phys in a global variable.
41326 + */
41327 +- popl %edx
41328 +- movl %edx, saved_return_addr
41329 +- /* get the function pointer into ECX*/
41330 +- popl %ecx
41331 +- movl %ecx, efi_rt_function_ptr
41332 +- movl $2f, %edx
41333 +- subl $__PAGE_OFFSET, %edx
41334 +- pushl %edx
41335 ++ popl (saved_return_addr)
41336 ++ popl (efi_rt_function_ptr)
41337 +
41338 + /*
41339 + * 3. Clear PG bit in %CR0.
41340 +@@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
41341 + /*
41342 + * 5. Call the physical function.
41343 + */
41344 +- jmp *%ecx
41345 ++ call *(efi_rt_function_ptr-__PAGE_OFFSET)
41346 +
41347 +-2:
41348 + /*
41349 + * 6. After EFI runtime service returns, control will return to
41350 + * following instruction. We'd better readjust stack pointer first.
41351 +@@ -88,34 +80,27 @@ ENTRY(efi_call_phys)
41352 + movl %cr0, %edx
41353 + orl $0x80000000, %edx
41354 + movl %edx, %cr0
41355 +- jmp 1f
41356 +-1:
41357 ++
41358 + /*
41359 + * 8. Now restore the virtual mode from flat mode by
41360 + * adding EIP with PAGE_OFFSET.
41361 + */
41362 +- movl $1f, %edx
41363 +- jmp *%edx
41364 ++ jmp 1f+__PAGE_OFFSET
41365 + 1:
41366 +
41367 + /*
41368 + * 9. Balance the stack. And because EAX contain the return value,
41369 + * we'd better not clobber it.
41370 + */
41371 +- leal efi_rt_function_ptr, %edx
41372 +- movl (%edx), %ecx
41373 +- pushl %ecx
41374 ++ pushl (efi_rt_function_ptr)
41375 +
41376 + /*
41377 +- * 10. Push the saved return address onto the stack and return.
41378 ++ * 10. Return to the saved return address.
41379 + */
41380 +- leal saved_return_addr, %edx
41381 +- movl (%edx), %ecx
41382 +- pushl %ecx
41383 +- ret
41384 ++ jmpl *(saved_return_addr)
41385 + .previous
41386 +
41387 +-.data
41388 ++__INITDATA
41389 + saved_return_addr:
41390 + .long 0
41391 + efi_rt_function_ptr:
41392 +diff -urNp linux-2.6.27.7/arch/x86/kernel/entry_32.S linux-2.6.27.7/arch/x86/kernel/entry_32.S
41393 +--- linux-2.6.27.7/arch/x86/kernel/entry_32.S 2008-11-07 12:55:34.000000000 -0500
41394 ++++ linux-2.6.27.7/arch/x86/kernel/entry_32.S 2008-11-18 03:38:44.000000000 -0500
41395 +@@ -101,7 +101,7 @@
41396 + #define resume_userspace_sig resume_userspace
41397 + #endif
41398 +
41399 +-#define SAVE_ALL \
41400 ++#define __SAVE_ALL(_DS) \
41401 + cld; \
41402 + pushl %fs; \
41403 + CFI_ADJUST_CFA_OFFSET 4;\
41404 +@@ -133,12 +133,26 @@
41405 + pushl %ebx; \
41406 + CFI_ADJUST_CFA_OFFSET 4;\
41407 + CFI_REL_OFFSET ebx, 0;\
41408 +- movl $(__USER_DS), %edx; \
41409 ++ movl $(_DS), %edx; \
41410 + movl %edx, %ds; \
41411 + movl %edx, %es; \
41412 + movl $(__KERNEL_PERCPU), %edx; \
41413 + movl %edx, %fs
41414 +
41415 ++#ifdef CONFIG_PAX_KERNEXEC
41416 ++#define SAVE_ALL \
41417 ++ __SAVE_ALL(__KERNEL_DS); \
41418 ++ GET_CR0_INTO_EDX; \
41419 ++ movl %edx, %esi; \
41420 ++ orl $X86_CR0_WP, %edx; \
41421 ++ xorl %edx, %esi; \
41422 ++ SET_CR0_FROM_EDX
41423 ++#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
41424 ++#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
41425 ++#else
41426 ++#define SAVE_ALL __SAVE_ALL(__USER_DS)
41427 ++#endif
41428 ++
41429 + #define RESTORE_INT_REGS \
41430 + popl %ebx; \
41431 + CFI_ADJUST_CFA_OFFSET -4;\
41432 +@@ -229,6 +243,11 @@ ENTRY(ret_from_fork)
41433 + CFI_ADJUST_CFA_OFFSET 4
41434 + popfl
41435 + CFI_ADJUST_CFA_OFFSET -4
41436 ++
41437 ++#ifdef CONFIG_PAX_KERNEXEC
41438 ++ xorl %esi, %esi
41439 ++#endif
41440 ++
41441 + jmp syscall_exit
41442 + CFI_ENDPROC
41443 + END(ret_from_fork)
41444 +@@ -252,7 +271,17 @@ check_userspace:
41445 + movb PT_CS(%esp), %al
41446 + andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax
41447 + cmpl $USER_RPL, %eax
41448 ++
41449 ++#ifdef CONFIG_PAX_KERNEXEC
41450 ++ jae resume_userspace
41451 ++
41452 ++ GET_CR0_INTO_EDX
41453 ++ xorl %esi, %edx
41454 ++ SET_CR0_FROM_EDX
41455 ++ jmp resume_kernel
41456 ++#else
41457 + jb resume_kernel # not returning to v8086 or userspace
41458 ++#endif
41459 +
41460 + ENTRY(resume_userspace)
41461 + LOCKDEP_SYS_EXIT
41462 +@@ -314,10 +343,9 @@ sysenter_past_esp:
41463 + /*CFI_REL_OFFSET cs, 0*/
41464 + /*
41465 + * Push current_thread_info()->sysenter_return to the stack.
41466 +- * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
41467 +- * pushed above; +8 corresponds to copy_thread's esp0 setting.
41468 + */
41469 +- pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
41470 ++ GET_THREAD_INFO(%ebp)
41471 ++ pushl TI_sysenter_return(%ebp)
41472 + CFI_ADJUST_CFA_OFFSET 4
41473 + CFI_REL_OFFSET eip, 0
41474 +
41475 +@@ -330,9 +358,17 @@ sysenter_past_esp:
41476 + * Load the potential sixth argument from user stack.
41477 + * Careful about security.
41478 + */
41479 ++ movl PT_OLDESP(%esp),%ebp
41480 ++
41481 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
41482 ++ mov PT_OLDSS(%esp),%ds
41483 ++1: movl %ds:(%ebp),%ebp
41484 ++#else
41485 + cmpl $__PAGE_OFFSET-3,%ebp
41486 + jae syscall_fault
41487 + 1: movl (%ebp),%ebp
41488 ++#endif
41489 ++
41490 + movl %ebp,PT_EBP(%esp)
41491 + .section __ex_table,"a"
41492 + .align 4
41493 +@@ -356,12 +392,23 @@ sysenter_do_call:
41494 + testw $_TIF_ALLWORK_MASK, %cx
41495 + jne sysexit_audit
41496 + sysenter_exit:
41497 ++
41498 ++#ifdef CONFIG_PAX_RANDKSTACK
41499 ++ pushl %eax
41500 ++ CFI_ADJUST_CFA_OFFSET 4
41501 ++ call pax_randomize_kstack
41502 ++ popl %eax
41503 ++ CFI_ADJUST_CFA_OFFSET -4
41504 ++#endif
41505 ++
41506 + /* if something modifies registers it must also disable sysexit */
41507 + movl PT_EIP(%esp), %edx
41508 + movl PT_OLDESP(%esp), %ecx
41509 + xorl %ebp,%ebp
41510 + TRACE_IRQS_ON
41511 + 1: mov PT_FS(%esp), %fs
41512 ++2: mov PT_DS(%esp), %ds
41513 ++3: mov PT_ES(%esp), %es
41514 + ENABLE_INTERRUPTS_SYSEXIT
41515 +
41516 + #ifdef CONFIG_AUDITSYSCALL
41517 +@@ -404,11 +451,17 @@ sysexit_audit:
41518 +
41519 + CFI_ENDPROC
41520 + .pushsection .fixup,"ax"
41521 +-2: movl $0,PT_FS(%esp)
41522 ++4: movl $0,PT_FS(%esp)
41523 ++ jmp 1b
41524 ++5: movl $0,PT_DS(%esp)
41525 ++ jmp 1b
41526 ++6: movl $0,PT_ES(%esp)
41527 + jmp 1b
41528 + .section __ex_table,"a"
41529 + .align 4
41530 +- .long 1b,2b
41531 ++ .long 1b,4b
41532 ++ .long 2b,5b
41533 ++ .long 3b,6b
41534 + .popsection
41535 + ENDPROC(ia32_sysenter_target)
41536 +
41537 +@@ -438,6 +491,10 @@ syscall_exit:
41538 + testw $_TIF_ALLWORK_MASK, %cx # current->work
41539 + jne syscall_exit_work
41540 +
41541 ++#ifdef CONFIG_PAX_RANDKSTACK
41542 ++ call pax_randomize_kstack
41543 ++#endif
41544 ++
41545 + restore_all:
41546 + movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
41547 + # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
41548 +@@ -531,25 +588,19 @@ work_resched:
41549 +
41550 + work_notifysig: # deal with pending signals and
41551 + # notify-resume requests
41552 ++ movl %esp, %eax
41553 + #ifdef CONFIG_VM86
41554 + testl $X86_EFLAGS_VM, PT_EFLAGS(%esp)
41555 +- movl %esp, %eax
41556 +- jne work_notifysig_v86 # returning to kernel-space or
41557 ++ jz 1f # returning to kernel-space or
41558 + # vm86-space
41559 +- xorl %edx, %edx
41560 +- call do_notify_resume
41561 +- jmp resume_userspace_sig
41562 +
41563 +- ALIGN
41564 +-work_notifysig_v86:
41565 + pushl %ecx # save ti_flags for do_notify_resume
41566 + CFI_ADJUST_CFA_OFFSET 4
41567 + call save_v86_state # %eax contains pt_regs pointer
41568 + popl %ecx
41569 + CFI_ADJUST_CFA_OFFSET -4
41570 + movl %eax, %esp
41571 +-#else
41572 +- movl %esp, %eax
41573 ++1:
41574 + #endif
41575 + xorl %edx, %edx
41576 + call do_notify_resume
41577 +@@ -595,17 +646,24 @@ syscall_badsys:
41578 + END(syscall_badsys)
41579 + CFI_ENDPROC
41580 +
41581 +-#define FIXUP_ESPFIX_STACK \
41582 +- /* since we are on a wrong stack, we cant make it a C code :( */ \
41583 +- PER_CPU(gdt_page, %ebx); \
41584 +- GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \
41585 +- addl %esp, %eax; \
41586 +- pushl $__KERNEL_DS; \
41587 +- CFI_ADJUST_CFA_OFFSET 4; \
41588 +- pushl %eax; \
41589 +- CFI_ADJUST_CFA_OFFSET 4; \
41590 +- lss (%esp), %esp; \
41591 ++.macro FIXUP_ESPFIX_STACK
41592 ++ /* since we are on a wrong stack, we cant make it a C code :( */
41593 ++#ifdef CONFIG_SMP
41594 ++ movl PER_CPU_VAR(cpu_number), %ebx;
41595 ++ shll $PAGE_SHIFT_asm, %ebx;
41596 ++ addl $cpu_gdt_table, %ebx;
41597 ++#else
41598 ++ movl $cpu_gdt_table, %ebx;
41599 ++#endif
41600 ++ GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah);
41601 ++ addl %esp, %eax;
41602 ++ pushl $__KERNEL_DS;
41603 ++ CFI_ADJUST_CFA_OFFSET 4;
41604 ++ pushl %eax;
41605 ++ CFI_ADJUST_CFA_OFFSET 4;
41606 ++ lss (%esp), %esp;
41607 + CFI_ADJUST_CFA_OFFSET -8;
41608 ++.endm
41609 + #define UNWIND_ESPFIX_STACK \
41610 + movl %ss, %eax; \
41611 + /* see if on espfix stack */ \
41612 +@@ -622,7 +680,7 @@ END(syscall_badsys)
41613 + * Build the entry stubs and pointer table with
41614 + * some assembler magic.
41615 + */
41616 +-.section .rodata,"a"
41617 ++.section .rodata,"a",@progbits
41618 + ENTRY(interrupt)
41619 + .text
41620 +
41621 +@@ -722,12 +780,21 @@ error_code:
41622 + popl %ecx
41623 + CFI_ADJUST_CFA_OFFSET -4
41624 + /*CFI_REGISTER es, ecx*/
41625 ++
41626 ++#ifdef CONFIG_PAX_KERNEXEC
41627 ++ GET_CR0_INTO_EDX
41628 ++ movl %edx, %esi
41629 ++ orl $X86_CR0_WP, %edx
41630 ++ xorl %edx, %esi
41631 ++ SET_CR0_FROM_EDX
41632 ++#endif
41633 ++
41634 + movl PT_FS(%esp), %edi # get the function address
41635 + movl PT_ORIG_EAX(%esp), %edx # get the error code
41636 + movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
41637 + mov %ecx, PT_FS(%esp)
41638 + /*CFI_REL_OFFSET fs, ES*/
41639 +- movl $(__USER_DS), %ecx
41640 ++ movl $(__KERNEL_DS), %ecx
41641 + movl %ecx, %ds
41642 + movl %ecx, %es
41643 + movl %esp,%eax # pt_regs pointer
41644 +@@ -861,6 +928,13 @@ nmi_stack_correct:
41645 + xorl %edx,%edx # zero error code
41646 + movl %esp,%eax # pt_regs pointer
41647 + call do_nmi
41648 ++
41649 ++#ifdef CONFIG_PAX_KERNEXEC
41650 ++ GET_CR0_INTO_EDX
41651 ++ xorl %esi, %edx
41652 ++ SET_CR0_FROM_EDX
41653 ++#endif
41654 ++
41655 + jmp restore_nocheck_notrace
41656 + CFI_ENDPROC
41657 +
41658 +@@ -901,6 +975,13 @@ nmi_espfix_stack:
41659 + FIXUP_ESPFIX_STACK # %eax == %esp
41660 + xorl %edx,%edx # zero error code
41661 + call do_nmi
41662 ++
41663 ++#ifdef CONFIG_PAX_KERNEXEC
41664 ++ GET_CR0_INTO_EDX
41665 ++ xorl %esi, %edx
41666 ++ SET_CR0_FROM_EDX
41667 ++#endif
41668 ++
41669 + RESTORE_REGS
41670 + lss 12+4(%esp), %esp # back to espfix stack
41671 + CFI_ADJUST_CFA_OFFSET -24
41672 +@@ -1226,7 +1307,6 @@ END(mcount)
41673 + #endif /* CONFIG_DYNAMIC_FTRACE */
41674 + #endif /* CONFIG_FTRACE */
41675 +
41676 +-.section .rodata,"a"
41677 + #include "syscall_table_32.S"
41678 +
41679 + syscall_table_size=(.-sys_call_table)
41680 +diff -urNp linux-2.6.27.7/arch/x86/kernel/entry_64.S linux-2.6.27.7/arch/x86/kernel/entry_64.S
41681 +--- linux-2.6.27.7/arch/x86/kernel/entry_64.S 2008-11-07 12:55:34.000000000 -0500
41682 ++++ linux-2.6.27.7/arch/x86/kernel/entry_64.S 2008-11-18 03:38:44.000000000 -0500
41683 +@@ -930,17 +930,18 @@ END(spurious_interrupt)
41684 + xorl %ebx,%ebx
41685 + 1:
41686 + .if \ist
41687 +- movq %gs:pda_data_offset, %rbp
41688 ++ imul $TSS_size, %gs:pda_cpunumber, %ebp
41689 ++ lea init_tss(%rbp), %rbp
41690 + .endif
41691 + movq %rsp,%rdi
41692 + movq ORIG_RAX(%rsp),%rsi
41693 + movq $-1,ORIG_RAX(%rsp)
41694 + .if \ist
41695 +- subq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
41696 ++ subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
41697 + .endif
41698 + call \sym
41699 + .if \ist
41700 +- addq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
41701 ++ addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
41702 + .endif
41703 + DISABLE_INTERRUPTS(CLBR_NONE)
41704 + .if \irqtrace
41705 +diff -urNp linux-2.6.27.7/arch/x86/kernel/ftrace.c linux-2.6.27.7/arch/x86/kernel/ftrace.c
41706 +--- linux-2.6.27.7/arch/x86/kernel/ftrace.c 2008-11-07 12:55:34.000000000 -0500
41707 ++++ linux-2.6.27.7/arch/x86/kernel/ftrace.c 2008-11-18 03:38:44.000000000 -0500
41708 +@@ -103,7 +103,7 @@ notrace int ftrace_update_ftrace_func(ft
41709 + unsigned char old[MCOUNT_INSN_SIZE], *new;
41710 + int ret;
41711 +
41712 +- memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE);
41713 ++ memcpy(old, (void *)ktla_ktva((unsigned long)ftrace_call), MCOUNT_INSN_SIZE);
41714 + new = ftrace_call_replace(ip, (unsigned long)func);
41715 + ret = ftrace_modify_code(ip, old, new);
41716 +
41717 +@@ -120,7 +120,7 @@ notrace int ftrace_mcount_set(unsigned l
41718 + * Replace the mcount stub with a pointer to the
41719 + * ip recorder function.
41720 + */
41721 +- memcpy(old, &mcount_call, MCOUNT_INSN_SIZE);
41722 ++ memcpy(old, ktla_ktva(mcount_call), MCOUNT_INSN_SIZE);
41723 + new = ftrace_call_replace(ip, *addr);
41724 + *addr = ftrace_modify_code(ip, old, new);
41725 +
41726 +diff -urNp linux-2.6.27.7/arch/x86/kernel/head32.c linux-2.6.27.7/arch/x86/kernel/head32.c
41727 +--- linux-2.6.27.7/arch/x86/kernel/head32.c 2008-11-07 12:55:34.000000000 -0500
41728 ++++ linux-2.6.27.7/arch/x86/kernel/head32.c 2008-11-18 03:38:44.000000000 -0500
41729 +@@ -12,10 +12,11 @@
41730 + #include <asm/sections.h>
41731 + #include <asm/e820.h>
41732 + #include <asm/bios_ebda.h>
41733 ++#include <asm/boot.h>
41734 +
41735 + void __init i386_start_kernel(void)
41736 + {
41737 +- reserve_early(__pa_symbol(&_text), __pa_symbol(&_end), "TEXT DATA BSS");
41738 ++ reserve_early(LOAD_PHYSICAL_ADDR, __pa_symbol(&_end), "TEXT DATA BSS");
41739 +
41740 + #ifdef CONFIG_BLK_DEV_INITRD
41741 + /* Reserve INITRD */
41742 +diff -urNp linux-2.6.27.7/arch/x86/kernel/head_32.S linux-2.6.27.7/arch/x86/kernel/head_32.S
41743 +--- linux-2.6.27.7/arch/x86/kernel/head_32.S 2008-11-07 12:55:34.000000000 -0500
41744 ++++ linux-2.6.27.7/arch/x86/kernel/head_32.S 2008-11-18 03:38:44.000000000 -0500
41745 +@@ -19,6 +19,7 @@
41746 + #include <asm/asm-offsets.h>
41747 + #include <asm/setup.h>
41748 + #include <asm/processor-flags.h>
41749 ++#include <asm/msr-index.h>
41750 +
41751 + /* Physical address */
41752 + #define pa(X) ((X) - __PAGE_OFFSET)
41753 +@@ -64,17 +65,22 @@ LOW_PAGES = 1<<(32-PAGE_SHIFT_asm)
41754 + LOW_PAGES = LOW_PAGES + 0x1000000
41755 + #endif
41756 +
41757 +-#if PTRS_PER_PMD > 1
41758 +-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD
41759 +-#else
41760 +-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD)
41761 +-#endif
41762 ++PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PTE)
41763 + BOOTBITMAP_SIZE = LOW_PAGES / 8
41764 + ALLOCATOR_SLOP = 4
41765 +
41766 + INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
41767 +
41768 + /*
41769 ++ * Real beginning of normal "text" segment
41770 ++ */
41771 ++ENTRY(stext)
41772 ++ENTRY(_stext)
41773 ++
41774 ++.section .text.startup,"ax",@progbits
41775 ++ ljmp $(__BOOT_CS),$phys_startup_32
41776 ++
41777 ++/*
41778 + * 32-bit kernel entrypoint; only used by the boot CPU. On entry,
41779 + * %esi points to the real-mode code as a 32-bit pointer.
41780 + * CS and DS must be 4 GB flat segments, but we don't depend on
41781 +@@ -82,6 +88,12 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE +
41782 + * can.
41783 + */
41784 + .section .text.head,"ax",@progbits
41785 ++
41786 ++#ifdef CONFIG_PAX_KERNEXEC
41787 ++/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
41788 ++.fill 4096,1,0xcc
41789 ++#endif
41790 ++
41791 + ENTRY(startup_32)
41792 + /* test KEEP_SEGMENTS flag to see if the bootloader is asking
41793 + us to not reload segments */
41794 +@@ -99,6 +111,56 @@ ENTRY(startup_32)
41795 + movl %eax,%gs
41796 + 2:
41797 +
41798 ++ movl $pa(cpu_gdt_table),%edi
41799 ++ movl $__per_cpu_start,%eax
41800 ++ movw %ax,__KERNEL_PERCPU + 2(%edi)
41801 ++ rorl $16,%eax
41802 ++ movb %al,__KERNEL_PERCPU + 4(%edi)
41803 ++ movb %ah,__KERNEL_PERCPU + 7(%edi)
41804 ++ movl $__per_cpu_end + PERCPU_MODULE_RESERVE - 1,%eax
41805 ++ subl $__per_cpu_start,%eax
41806 ++ movw %ax,__KERNEL_PERCPU + 0(%edi)
41807 ++
41808 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
41809 ++ /* check for VMware */
41810 ++ movl $0x564d5868,%eax
41811 ++ xorl %ebx,%ebx
41812 ++ movl $0xa,%ecx
41813 ++ movl $0x5658,%edx
41814 ++ in (%dx),%eax
41815 ++ cmpl $0x564d5868,%ebx
41816 ++ jz 2f
41817 ++
41818 ++ movl $NR_CPUS,%ecx
41819 ++ movl $pa(cpu_gdt_table),%edi
41820 ++1:
41821 ++ movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),GDT_ENTRY_KERNEL_DS * 8 + 4(%edi)
41822 ++ addl $PAGE_SIZE_asm,%edi
41823 ++ loop 1b
41824 ++2:
41825 ++#endif
41826 ++
41827 ++#ifdef CONFIG_PAX_KERNEXEC
41828 ++ movl $pa(boot_gdt),%edi
41829 ++ movl $KERNEL_TEXT_OFFSET,%eax
41830 ++ movw %ax,__BOOT_CS + 2(%edi)
41831 ++ rorl $16,%eax
41832 ++ movb %al,__BOOT_CS + 4(%edi)
41833 ++ movb %ah,__BOOT_CS + 7(%edi)
41834 ++ rorl $16,%eax
41835 ++
41836 ++ movl $NR_CPUS,%ecx
41837 ++ movl $pa(cpu_gdt_table),%edi
41838 ++1:
41839 ++ movw %ax,__KERNEL_CS + 2(%edi)
41840 ++ rorl $16,%eax
41841 ++ movb %al,__KERNEL_CS + 4(%edi)
41842 ++ movb %ah,__KERNEL_CS + 7(%edi)
41843 ++ rorl $16,%eax
41844 ++ addl $PAGE_SIZE_asm,%edi
41845 ++ loop 1b
41846 ++#endif
41847 ++
41848 + /*
41849 + * Clear BSS first so that there are no surprises...
41850 + */
41851 +@@ -142,9 +204,7 @@ ENTRY(startup_32)
41852 + cmpl $num_subarch_entries, %eax
41853 + jae bad_subarch
41854 +
41855 +- movl pa(subarch_entries)(,%eax,4), %eax
41856 +- subl $__PAGE_OFFSET, %eax
41857 +- jmp *%eax
41858 ++ jmp *pa(subarch_entries)(,%eax,4)
41859 +
41860 + bad_subarch:
41861 + WEAK(lguest_entry)
41862 +@@ -156,9 +216,9 @@ WEAK(xen_entry)
41863 + __INITDATA
41864 +
41865 + subarch_entries:
41866 +- .long default_entry /* normal x86/PC */
41867 +- .long lguest_entry /* lguest hypervisor */
41868 +- .long xen_entry /* Xen hypervisor */
41869 ++ .long pa(default_entry) /* normal x86/PC */
41870 ++ .long pa(lguest_entry) /* lguest hypervisor */
41871 ++ .long pa(xen_entry) /* Xen hypervisor */
41872 + num_subarch_entries = (. - subarch_entries) / 4
41873 + .previous
41874 + #endif /* CONFIG_PARAVIRT */
41875 +@@ -172,7 +232,7 @@ num_subarch_entries = (. - subarch_entri
41876 + *
41877 + * Note that the stack is not yet set up!
41878 + */
41879 +-#define PTE_ATTR 0x007 /* PRESENT+RW+USER */
41880 ++#define PTE_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
41881 + #define PDE_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
41882 + #define PGD_ATTR 0x001 /* PRESENT (no other attributes) */
41883 +
41884 +@@ -224,8 +284,7 @@ default_entry:
41885 + movl %eax, pa(max_pfn_mapped)
41886 +
41887 + /* Do early initialization of the fixmap area */
41888 +- movl $pa(swapper_pg_fixmap)+PDE_ATTR,%eax
41889 +- movl %eax,pa(swapper_pg_pmd+0x1000*KPMDS-8)
41890 ++ movl $pa(swapper_pg_fixmap)+PDE_ATTR,pa(swapper_pg_pmd+0x1000*KPMDS-8)
41891 + #else /* Not PAE */
41892 +
41893 + page_pde_offset = (__PAGE_OFFSET >> 20);
41894 +@@ -257,8 +316,7 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
41895 + movl %eax, pa(max_pfn_mapped)
41896 +
41897 + /* Do early initialization of the fixmap area */
41898 +- movl $pa(swapper_pg_fixmap)+PDE_ATTR,%eax
41899 +- movl %eax,pa(swapper_pg_dir+0xffc)
41900 ++ movl $pa(swapper_pg_fixmap)+PDE_ATTR,pa(swapper_pg_dir+0xffc)
41901 + #endif
41902 + jmp 3f
41903 + /*
41904 +@@ -322,13 +380,16 @@ ENTRY(startup_32_smp)
41905 + jnc 6f
41906 +
41907 + /* Setup EFER (Extended Feature Enable Register) */
41908 +- movl $0xc0000080, %ecx
41909 ++ movl $MSR_EFER, %ecx
41910 + rdmsr
41911 +
41912 + btsl $11, %eax
41913 + /* Make changes effective */
41914 + wrmsr
41915 +
41916 ++ btsl $63-32,pa(__supported_pte_mask+4)
41917 ++ movl $1,pa(nx_enabled)
41918 ++
41919 + 6:
41920 +
41921 + /*
41922 +@@ -354,9 +415,7 @@ ENTRY(startup_32_smp)
41923 +
41924 + #ifdef CONFIG_SMP
41925 + cmpb $0, ready
41926 +- jz 1f /* Initial CPU cleans BSS */
41927 +- jmp checkCPUtype
41928 +-1:
41929 ++ jnz checkCPUtype /* Initial CPU cleans BSS */
41930 + #endif /* CONFIG_SMP */
41931 +
41932 + /*
41933 +@@ -433,12 +492,12 @@ is386: movl $2,%ecx # set MP
41934 + ljmp $(__KERNEL_CS),$1f
41935 + 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
41936 + movl %eax,%ss # after changing gdt.
41937 +- movl %eax,%fs # gets reset once there's real percpu
41938 +-
41939 +- movl $(__USER_DS),%eax # DS/ES contains default USER segment
41940 + movl %eax,%ds
41941 + movl %eax,%es
41942 +
41943 ++ movl $(__KERNEL_PERCPU), %eax
41944 ++ movl %eax,%fs # set this cpu's percpu
41945 ++
41946 + xorl %eax,%eax # Clear GS and LDT
41947 + movl %eax,%gs
41948 + lldt %ax
41949 +@@ -448,12 +507,6 @@ is386: movl $2,%ecx # set MP
41950 + #ifdef CONFIG_SMP
41951 + movb ready, %cl
41952 + movb $1, ready
41953 +- cmpb $0,%cl # the first CPU calls start_kernel
41954 +- je 1f
41955 +- movl $(__KERNEL_PERCPU), %eax
41956 +- movl %eax,%fs # set this cpu's percpu
41957 +- movl (stack_start), %esp
41958 +-1:
41959 + #endif /* CONFIG_SMP */
41960 + jmp *(initial_code)
41961 +
41962 +@@ -539,15 +592,15 @@ early_page_fault:
41963 + jmp early_fault
41964 +
41965 + early_fault:
41966 +- cld
41967 + #ifdef CONFIG_PRINTK
41968 ++ cmpl $2,%ss:early_recursion_flag
41969 ++ je hlt_loop
41970 ++ incl %ss:early_recursion_flag
41971 ++ cld
41972 + pusha
41973 + movl $(__KERNEL_DS),%eax
41974 + movl %eax,%ds
41975 + movl %eax,%es
41976 +- cmpl $2,early_recursion_flag
41977 +- je hlt_loop
41978 +- incl early_recursion_flag
41979 + movl %cr2,%eax
41980 + pushl %eax
41981 + pushl %edx /* trapno */
41982 +@@ -557,8 +610,8 @@ early_fault:
41983 + #else
41984 + call printk
41985 + #endif
41986 +-#endif
41987 + call dump_stack
41988 ++#endif
41989 + hlt_loop:
41990 + hlt
41991 + jmp hlt_loop
41992 +@@ -566,8 +619,11 @@ hlt_loop:
41993 + /* This is the default interrupt "handler" :-) */
41994 + ALIGN
41995 + ignore_int:
41996 +- cld
41997 + #ifdef CONFIG_PRINTK
41998 ++ cmpl $2,%ss:early_recursion_flag
41999 ++ je hlt_loop
42000 ++ incl %ss:early_recursion_flag
42001 ++ cld
42002 + pushl %eax
42003 + pushl %ecx
42004 + pushl %edx
42005 +@@ -576,9 +632,6 @@ ignore_int:
42006 + movl $(__KERNEL_DS),%eax
42007 + movl %eax,%ds
42008 + movl %eax,%es
42009 +- cmpl $2,early_recursion_flag
42010 +- je hlt_loop
42011 +- incl early_recursion_flag
42012 + pushl 16(%esp)
42013 + pushl 24(%esp)
42014 + pushl 32(%esp)
42015 +@@ -603,36 +656,41 @@ ignore_int:
42016 + ENTRY(initial_code)
42017 + .long i386_start_kernel
42018 +
42019 +-.section .text
42020 +-/*
42021 +- * Real beginning of normal "text" segment
42022 +- */
42023 +-ENTRY(stext)
42024 +-ENTRY(_stext)
42025 +-
42026 + /*
42027 + * BSS section
42028 + */
42029 +-.section ".bss.page_aligned","wa"
42030 +- .align PAGE_SIZE_asm
42031 + #ifdef CONFIG_X86_PAE
42032 ++.section .swapper_pg_pmd,"a",@progbits
42033 + swapper_pg_pmd:
42034 + .fill 1024*KPMDS,4,0
42035 + #else
42036 ++.section .swapper_pg_dir,"a",@progbits
42037 + ENTRY(swapper_pg_dir)
42038 + .fill 1024,4,0
42039 + #endif
42040 + swapper_pg_fixmap:
42041 + .fill 1024,4,0
42042 ++
42043 ++.section .empty_zero_page,"a",@progbits
42044 + ENTRY(empty_zero_page)
42045 + .fill 4096,1,0
42046 ++
42047 ++/*
42048 ++ * The IDT has to be page-aligned to simplify the Pentium
42049 ++ * F0 0F bug workaround.. We have a special link segment
42050 ++ * for this.
42051 ++ */
42052 ++.section .idt,"a",@progbits
42053 ++ENTRY(idt_table)
42054 ++ .fill 256,8,0
42055 ++
42056 + /*
42057 + * This starts the data section.
42058 + */
42059 ++.data
42060 ++
42061 + #ifdef CONFIG_X86_PAE
42062 +-.section ".data.page_aligned","wa"
42063 +- /* Page-aligned for the benefit of paravirt? */
42064 +- .align PAGE_SIZE_asm
42065 ++.section .swapper_pg_dir,"a",@progbits
42066 + ENTRY(swapper_pg_dir)
42067 + .long pa(swapper_pg_pmd+PGD_ATTR),0 /* low identity map */
42068 + # if KPMDS == 3
42069 +@@ -655,11 +713,12 @@ ENTRY(swapper_pg_dir)
42070 +
42071 + .data
42072 + ENTRY(stack_start)
42073 +- .long init_thread_union+THREAD_SIZE
42074 ++ .long init_thread_union+THREAD_SIZE-8
42075 + .long __BOOT_DS
42076 +
42077 + ready: .byte 0
42078 +
42079 ++.section .rodata,"a",@progbits
42080 + early_recursion_flag:
42081 + .long 0
42082 +
42083 +@@ -695,7 +754,7 @@ fault_msg:
42084 + .word 0 # 32 bit align gdt_desc.address
42085 + boot_gdt_descr:
42086 + .word __BOOT_DS+7
42087 +- .long boot_gdt - __PAGE_OFFSET
42088 ++ .long pa(boot_gdt)
42089 +
42090 + .word 0 # 32-bit align idt_desc.address
42091 + idt_descr:
42092 +@@ -706,7 +765,7 @@ idt_descr:
42093 + .word 0 # 32 bit align gdt_desc.address
42094 + ENTRY(early_gdt_descr)
42095 + .word GDT_ENTRIES*8-1
42096 +- .long per_cpu__gdt_page /* Overwritten for secondary CPUs */
42097 ++ .long cpu_gdt_table /* Overwritten for secondary CPUs */
42098 +
42099 + /*
42100 + * The boot_gdt must mirror the equivalent in setup.S and is
42101 +@@ -715,5 +774,59 @@ ENTRY(early_gdt_descr)
42102 + .align L1_CACHE_BYTES
42103 + ENTRY(boot_gdt)
42104 + .fill GDT_ENTRY_BOOT_CS,8,0
42105 +- .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
42106 +- .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
42107 ++ .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */
42108 ++ .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */
42109 ++
42110 ++ .align PAGE_SIZE_asm
42111 ++ENTRY(cpu_gdt_table)
42112 ++ .rept NR_CPUS
42113 ++ .quad 0x0000000000000000 /* NULL descriptor */
42114 ++ .quad 0x0000000000000000 /* 0x0b reserved */
42115 ++ .quad 0x0000000000000000 /* 0x13 reserved */
42116 ++ .quad 0x0000000000000000 /* 0x1b reserved */
42117 ++ .quad 0x0000000000000000 /* 0x20 unused */
42118 ++ .quad 0x0000000000000000 /* 0x28 unused */
42119 ++ .quad 0x0000000000000000 /* 0x33 TLS entry 1 */
42120 ++ .quad 0x0000000000000000 /* 0x3b TLS entry 2 */
42121 ++ .quad 0x0000000000000000 /* 0x43 TLS entry 3 */
42122 ++ .quad 0x0000000000000000 /* 0x4b reserved */
42123 ++ .quad 0x0000000000000000 /* 0x53 reserved */
42124 ++ .quad 0x0000000000000000 /* 0x5b reserved */
42125 ++
42126 ++ .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
42127 ++ .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
42128 ++ .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */
42129 ++ .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */
42130 ++
42131 ++ .quad 0x0000000000000000 /* 0x80 TSS descriptor */
42132 ++ .quad 0x0000000000000000 /* 0x88 LDT descriptor */
42133 ++
42134 ++ /*
42135 ++ * Segments used for calling PnP BIOS have byte granularity.
42136 ++ * The code segments and data segments have fixed 64k limits,
42137 ++ * the transfer segment sizes are set at run time.
42138 ++ */
42139 ++ .quad 0x00409b000000ffff /* 0x90 32-bit code */
42140 ++ .quad 0x00009b000000ffff /* 0x98 16-bit code */
42141 ++ .quad 0x000093000000ffff /* 0xa0 16-bit data */
42142 ++ .quad 0x0000930000000000 /* 0xa8 16-bit data */
42143 ++ .quad 0x0000930000000000 /* 0xb0 16-bit data */
42144 ++
42145 ++ /*
42146 ++ * The APM segments have byte granularity and their bases
42147 ++ * are set at run time. All have 64k limits.
42148 ++ */
42149 ++ .quad 0x00409b000000ffff /* 0xb8 APM CS code */
42150 ++ .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */
42151 ++ .quad 0x004093000000ffff /* 0xc8 APM DS data */
42152 ++
42153 ++ .quad 0x00c0930000000000 /* 0xd0 - ESPFIX SS */
42154 ++ .quad 0x0040930000000000 /* 0xd8 - PERCPU */
42155 ++ .quad 0x0000000000000000 /* 0xe0 - PCIBIOS_CS */
42156 ++ .quad 0x0000000000000000 /* 0xe8 - PCIBIOS_DS */
42157 ++ .quad 0x0000000000000000 /* 0xf0 - unused */
42158 ++ .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
42159 ++
42160 ++ /* Be sure this is zeroed to avoid false validations in Xen */
42161 ++ .fill PAGE_SIZE_asm - GDT_SIZE,1,0
42162 ++ .endr
42163 +diff -urNp linux-2.6.27.7/arch/x86/kernel/head64.c linux-2.6.27.7/arch/x86/kernel/head64.c
42164 +--- linux-2.6.27.7/arch/x86/kernel/head64.c 2008-11-07 12:55:34.000000000 -0500
42165 ++++ linux-2.6.27.7/arch/x86/kernel/head64.c 2008-11-18 03:38:44.000000000 -0500
42166 +@@ -93,6 +93,8 @@ void __init x86_64_start_kernel(char * r
42167 + /* clear bss before set_intr_gate with early_idt_handler */
42168 + clear_bss();
42169 +
42170 ++ x86_64_init_pda();
42171 ++
42172 + /* Make NULL pointers segfault */
42173 + zap_identity_mappings();
42174 +
42175 +@@ -110,8 +112,6 @@ void __init x86_64_start_kernel(char * r
42176 +
42177 + early_printk("Kernel alive\n");
42178 +
42179 +- x86_64_init_pda();
42180 +-
42181 + early_printk("Kernel really alive\n");
42182 +
42183 + x86_64_start_reservations(real_mode_data);
42184 +diff -urNp linux-2.6.27.7/arch/x86/kernel/head_64.S linux-2.6.27.7/arch/x86/kernel/head_64.S
42185 +--- linux-2.6.27.7/arch/x86/kernel/head_64.S 2008-11-07 12:55:34.000000000 -0500
42186 ++++ linux-2.6.27.7/arch/x86/kernel/head_64.S 2008-11-18 03:38:44.000000000 -0500
42187 +@@ -38,6 +38,10 @@ L4_PAGE_OFFSET = pgd_index(__PAGE_OFFSET
42188 + L3_PAGE_OFFSET = pud_index(__PAGE_OFFSET)
42189 + L4_START_KERNEL = pgd_index(__START_KERNEL_map)
42190 + L3_START_KERNEL = pud_index(__START_KERNEL_map)
42191 ++L4_VMALLOC_START = pgd_index(VMALLOC_START)
42192 ++L3_VMALLOC_START = pud_index(VMALLOC_START)
42193 ++L4_VMEMMAP_START = pgd_index(VMEMMAP_START)
42194 ++L3_VMEMMAP_START = pud_index(VMEMMAP_START)
42195 +
42196 + .text
42197 + .section .text.head
42198 +@@ -85,14 +89,17 @@ startup_64:
42199 + */
42200 + addq %rbp, init_level4_pgt + 0(%rip)
42201 + addq %rbp, init_level4_pgt + (L4_PAGE_OFFSET*8)(%rip)
42202 ++ addq %rbp, init_level4_pgt + (L4_VMALLOC_START*8)(%rip)
42203 ++ addq %rbp, init_level4_pgt + (L4_VMEMMAP_START*8)(%rip)
42204 + addq %rbp, init_level4_pgt + (L4_START_KERNEL*8)(%rip)
42205 +
42206 + addq %rbp, level3_ident_pgt + 0(%rip)
42207 +
42208 +- addq %rbp, level3_kernel_pgt + (510*8)(%rip)
42209 +- addq %rbp, level3_kernel_pgt + (511*8)(%rip)
42210 ++ addq %rbp, level3_kernel_pgt + (L3_START_KERNEL*8)(%rip)
42211 ++ addq %rbp, level3_kernel_pgt + (L3_START_KERNEL*8+8)(%rip)
42212 +
42213 + addq %rbp, level2_fixmap_pgt + (506*8)(%rip)
42214 ++ addq %rbp, level2_fixmap_pgt + (507*8)(%rip)
42215 +
42216 + /* Add an Identity mapping if I am above 1G */
42217 + leaq _text(%rip), %rdi
42218 +@@ -187,6 +194,10 @@ ENTRY(secondary_startup_64)
42219 + btl $20,%edi /* No Execute supported? */
42220 + jnc 1f
42221 + btsl $_EFER_NX, %eax
42222 ++ leaq init_level4_pgt(%rip), %rdi
42223 ++ btsq $_PAGE_BIT_NX, 8*L4_PAGE_OFFSET(%rdi)
42224 ++ btsq $_PAGE_BIT_NX, 8*L4_VMALLOC_START(%rdi)
42225 ++ btsq $_PAGE_BIT_NX, 8*L4_VMEMMAP_START(%rdi)
42226 + 1: wrmsr /* Make changes effective */
42227 +
42228 + /* Setup cr0 */
42229 +@@ -257,16 +268,16 @@ ENTRY(secondary_startup_64)
42230 + .align 8
42231 + ENTRY(initial_code)
42232 + .quad x86_64_start_kernel
42233 +- __FINITDATA
42234 +
42235 + ENTRY(stack_start)
42236 + .quad init_thread_union+THREAD_SIZE-8
42237 + .word 0
42238 ++ __FINITDATA
42239 +
42240 + bad_address:
42241 + jmp bad_address
42242 +
42243 +- .section ".init.text","ax"
42244 ++ __INIT
42245 + #ifdef CONFIG_EARLY_PRINTK
42246 + .globl early_idt_handlers
42247 + early_idt_handlers:
42248 +@@ -311,18 +322,23 @@ ENTRY(early_idt_handler)
42249 + #endif /* EARLY_PRINTK */
42250 + 1: hlt
42251 + jmp 1b
42252 ++ .previous
42253 +
42254 + #ifdef CONFIG_EARLY_PRINTK
42255 ++ __INITDATA
42256 + early_recursion_flag:
42257 + .long 0
42258 ++ .previous
42259 +
42260 ++ .section .rodata,"a",@progbits
42261 + early_idt_msg:
42262 + .asciz "PANIC: early exception %02lx rip %lx:%lx error %lx cr2 %lx\n"
42263 + early_idt_ripmsg:
42264 + .asciz "RIP %s\n"
42265 +-#endif /* CONFIG_EARLY_PRINTK */
42266 + .previous
42267 ++#endif /* CONFIG_EARLY_PRINTK */
42268 +
42269 ++ .section .rodata,"a",@progbits
42270 + .balign PAGE_SIZE
42271 +
42272 + #define NEXT_PAGE(name) \
42273 +@@ -347,6 +363,10 @@ NEXT_PAGE(init_level4_pgt)
42274 + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
42275 + .org init_level4_pgt + L4_PAGE_OFFSET*8, 0
42276 + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
42277 ++ .org init_level4_pgt + L4_VMALLOC_START*8, 0
42278 ++ .quad level3_vmalloc_pgt - __START_KERNEL_map + _KERNPG_TABLE
42279 ++ .org init_level4_pgt + L4_VMEMMAP_START*8, 0
42280 ++ .quad level3_vmemmap_pgt - __START_KERNEL_map + _KERNPG_TABLE
42281 + .org init_level4_pgt + L4_START_KERNEL*8, 0
42282 + /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
42283 + .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE
42284 +@@ -355,6 +375,12 @@ NEXT_PAGE(level3_ident_pgt)
42285 + .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
42286 + .fill 511,8,0
42287 +
42288 ++NEXT_PAGE(level3_vmalloc_pgt)
42289 ++ .fill 512,8,0
42290 ++
42291 ++NEXT_PAGE(level3_vmemmap_pgt)
42292 ++ .fill 512,8,0
42293 ++
42294 + NEXT_PAGE(level3_kernel_pgt)
42295 + .fill L3_START_KERNEL,8,0
42296 + /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */
42297 +@@ -364,12 +390,16 @@ NEXT_PAGE(level3_kernel_pgt)
42298 + NEXT_PAGE(level2_fixmap_pgt)
42299 + .fill 506,8,0
42300 + .quad level1_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE
42301 +- /* 8MB reserved for vsyscalls + a 2MB hole = 4 + 1 entries */
42302 +- .fill 5,8,0
42303 ++ .quad level1_vsyscall_pgt - __START_KERNEL_map + _PAGE_TABLE
42304 ++ /* 6MB reserved for vsyscalls + a 2MB hole = 3 + 1 entries */
42305 ++ .fill 4,8,0
42306 +
42307 + NEXT_PAGE(level1_fixmap_pgt)
42308 + .fill 512,8,0
42309 +
42310 ++NEXT_PAGE(level1_vsyscall_pgt)
42311 ++ .fill 512,8,0
42312 ++
42313 + NEXT_PAGE(level2_ident_pgt)
42314 + /* Since I easily can, map the first 1G.
42315 + * Don't set NX because code runs from these pages.
42316 +@@ -396,19 +426,39 @@ NEXT_PAGE(level2_spare_pgt)
42317 + #undef PMDS
42318 + #undef NEXT_PAGE
42319 +
42320 +- .data
42321 ++ .align PAGE_SIZE
42322 ++ENTRY(cpu_gdt_table)
42323 ++ .rept NR_CPUS
42324 ++ .quad 0x0000000000000000 /* NULL descriptor */
42325 ++ .quad 0x00cf9b000000ffff /* __KERNEL32_CS */
42326 ++ .quad 0x00af9b000000ffff /* __KERNEL_CS */
42327 ++ .quad 0x00cf93000000ffff /* __KERNEL_DS */
42328 ++ .quad 0x00cffb000000ffff /* __USER32_CS */
42329 ++ .quad 0x00cff3000000ffff /* __USER_DS, __USER32_DS */
42330 ++ .quad 0x00affb000000ffff /* __USER_CS */
42331 ++ .quad 0x0 /* unused */
42332 ++ .quad 0,0 /* TSS */
42333 ++ .quad 0,0 /* LDT */
42334 ++ .quad 0,0,0 /* three TLS descriptors */
42335 ++ .quad 0x0000f40000000000 /* node/CPU stored in limit */
42336 ++ /* asm/segment.h:GDT_ENTRIES must match this */
42337 ++
42338 ++ /* zero the remaining page */
42339 ++ .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
42340 ++ .endr
42341 ++
42342 + .align 16
42343 + .globl early_gdt_descr
42344 + early_gdt_descr:
42345 + .word GDT_ENTRIES*8-1
42346 +- .quad per_cpu__gdt_page
42347 ++ .quad cpu_gdt_table
42348 +
42349 + ENTRY(phys_base)
42350 + /* This must match the first entry in level2_kernel_pgt */
42351 + .quad 0x0000000000000000
42352 +
42353 + #include "../../x86/xen/xen-head.S"
42354 +-
42355 ++
42356 + .section .bss, "aw", @nobits
42357 + .align L1_CACHE_BYTES
42358 + ENTRY(idt_table)
42359 +diff -urNp linux-2.6.27.7/arch/x86/kernel/i386_ksyms_32.c linux-2.6.27.7/arch/x86/kernel/i386_ksyms_32.c
42360 +--- linux-2.6.27.7/arch/x86/kernel/i386_ksyms_32.c 2008-11-07 12:55:34.000000000 -0500
42361 ++++ linux-2.6.27.7/arch/x86/kernel/i386_ksyms_32.c 2008-11-18 03:38:44.000000000 -0500
42362 +@@ -10,8 +10,12 @@
42363 + EXPORT_SYMBOL(mcount);
42364 + #endif
42365 +
42366 ++EXPORT_SYMBOL_GPL(cpu_gdt_table);
42367 ++
42368 + /* Networking helper routines. */
42369 + EXPORT_SYMBOL(csum_partial_copy_generic);
42370 ++EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
42371 ++EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
42372 +
42373 + EXPORT_SYMBOL(__get_user_1);
42374 + EXPORT_SYMBOL(__get_user_2);
42375 +@@ -26,3 +30,7 @@ EXPORT_SYMBOL(strstr);
42376 +
42377 + EXPORT_SYMBOL(csum_partial);
42378 + EXPORT_SYMBOL(empty_zero_page);
42379 ++
42380 ++#ifdef CONFIG_PAX_KERNEXEC
42381 ++EXPORT_SYMBOL(KERNEL_TEXT_OFFSET);
42382 ++#endif
42383 +diff -urNp linux-2.6.27.7/arch/x86/kernel/init_task.c linux-2.6.27.7/arch/x86/kernel/init_task.c
42384 +--- linux-2.6.27.7/arch/x86/kernel/init_task.c 2008-11-07 12:55:34.000000000 -0500
42385 ++++ linux-2.6.27.7/arch/x86/kernel/init_task.c 2008-11-18 03:38:44.000000000 -0500
42386 +@@ -42,5 +42,5 @@ EXPORT_SYMBOL(init_task);
42387 + * section. Since TSS's are completely CPU-local, we want them
42388 + * on exact cacheline boundaries, to eliminate cacheline ping-pong.
42389 + */
42390 +-DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
42391 +-
42392 ++struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
42393 ++EXPORT_SYMBOL(init_tss);
42394 +diff -urNp linux-2.6.27.7/arch/x86/kernel/ioport.c linux-2.6.27.7/arch/x86/kernel/ioport.c
42395 +--- linux-2.6.27.7/arch/x86/kernel/ioport.c 2008-11-07 12:55:34.000000000 -0500
42396 ++++ linux-2.6.27.7/arch/x86/kernel/ioport.c 2008-11-18 03:38:44.000000000 -0500
42397 +@@ -14,6 +14,7 @@
42398 + #include <linux/slab.h>
42399 + #include <linux/thread_info.h>
42400 + #include <linux/syscalls.h>
42401 ++#include <linux/grsecurity.h>
42402 +
42403 + /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
42404 + static void set_bitmap(unsigned long *bitmap, unsigned int base,
42405 +@@ -40,6 +41,12 @@ asmlinkage long sys_ioperm(unsigned long
42406 +
42407 + if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
42408 + return -EINVAL;
42409 ++#ifdef CONFIG_GRKERNSEC_IO
42410 ++ if (turn_on) {
42411 ++ gr_handle_ioperm();
42412 ++ return -EPERM;
42413 ++ }
42414 ++#endif
42415 + if (turn_on && !capable(CAP_SYS_RAWIO))
42416 + return -EPERM;
42417 +
42418 +@@ -66,7 +73,7 @@ asmlinkage long sys_ioperm(unsigned long
42419 + * because the ->io_bitmap_max value must match the bitmap
42420 + * contents:
42421 + */
42422 +- tss = &per_cpu(init_tss, get_cpu());
42423 ++ tss = init_tss + get_cpu();
42424 +
42425 + set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
42426 +
42427 +@@ -121,8 +128,13 @@ static int do_iopl(unsigned int level, s
42428 + return -EINVAL;
42429 + /* Trying to gain more privileges? */
42430 + if (level > old) {
42431 ++#ifdef CONFIG_GRKERNSEC_IO
42432 ++ gr_handle_iopl();
42433 ++ return -EPERM;
42434 ++#else
42435 + if (!capable(CAP_SYS_RAWIO))
42436 + return -EPERM;
42437 ++#endif
42438 + }
42439 + regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
42440 +
42441 +diff -urNp linux-2.6.27.7/arch/x86/kernel/irq_32.c linux-2.6.27.7/arch/x86/kernel/irq_32.c
42442 +--- linux-2.6.27.7/arch/x86/kernel/irq_32.c 2008-11-07 12:55:34.000000000 -0500
42443 ++++ linux-2.6.27.7/arch/x86/kernel/irq_32.c 2008-11-18 03:38:44.000000000 -0500
42444 +@@ -116,7 +116,7 @@ execute_on_irq_stack(int overflow, struc
42445 + return 0;
42446 +
42447 + /* build the stack frame on the IRQ stack */
42448 +- isp = (u32 *) ((char*)irqctx + sizeof(*irqctx));
42449 ++ isp = (u32 *) ((char*)irqctx + sizeof(*irqctx) - 8);
42450 + irqctx->tinfo.task = curctx->tinfo.task;
42451 + irqctx->tinfo.previous_esp = current_stack_pointer;
42452 +
42453 +@@ -197,7 +197,7 @@ asmlinkage void do_softirq(void)
42454 + irqctx->tinfo.previous_esp = current_stack_pointer;
42455 +
42456 + /* build the stack frame on the softirq stack */
42457 +- isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
42458 ++ isp = (u32*) ((char*)irqctx + sizeof(*irqctx) - 8);
42459 +
42460 + call_on_stack(__do_softirq, isp);
42461 + /*
42462 +diff -urNp linux-2.6.27.7/arch/x86/kernel/kprobes.c linux-2.6.27.7/arch/x86/kernel/kprobes.c
42463 +--- linux-2.6.27.7/arch/x86/kernel/kprobes.c 2008-11-07 12:55:34.000000000 -0500
42464 ++++ linux-2.6.27.7/arch/x86/kernel/kprobes.c 2008-11-18 04:48:35.000000000 -0500
42465 +@@ -166,9 +166,24 @@ static void __kprobes set_jmp_op(void *f
42466 + char op;
42467 + s32 raddr;
42468 + } __attribute__((packed)) * jop;
42469 +- jop = (struct __arch_jmp_op *)from;
42470 ++
42471 ++#ifdef CONFIG_PAX_KERNEXEC
42472 ++ unsigned long cr0;
42473 ++#endif
42474 ++
42475 ++ jop = (struct __arch_jmp_op *)(ktla_ktva(from));
42476 ++
42477 ++#ifdef CONFIG_PAX_KERNEXEC
42478 ++ pax_open_kernel(cr0);
42479 ++#endif
42480 ++
42481 + jop->raddr = (s32)((long)(to) - ((long)(from) + 5));
42482 + jop->op = RELATIVEJUMP_INSTRUCTION;
42483 ++
42484 ++#ifdef CONFIG_PAX_KERNEXEC
42485 ++ pax_close_kernel(cr0);
42486 ++#endif
42487 ++
42488 + }
42489 +
42490 + /*
42491 +@@ -342,16 +357,29 @@ static void __kprobes fix_riprel(struct
42492 +
42493 + static void __kprobes arch_copy_kprobe(struct kprobe *p)
42494 + {
42495 +- memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
42496 ++
42497 ++#ifdef CONFIG_PAX_KERNEXEC
42498 ++ unsigned long cr0;
42499 ++#endif
42500 ++
42501 ++#ifdef CONFIG_PAX_KERNEXEC
42502 ++ pax_open_kernel(cr0);
42503 ++#endif
42504 ++
42505 ++ memcpy(p->ainsn.insn, ktla_ktva(p->addr), MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
42506 ++
42507 ++#ifdef CONFIG_PAX_KERNEXEC
42508 ++ pax_close_kernel(cr0);
42509 ++#endif
42510 +
42511 + fix_riprel(p);
42512 +
42513 +- if (can_boost(p->addr))
42514 ++ if (can_boost(ktla_ktva(p->addr)))
42515 + p->ainsn.boostable = 0;
42516 + else
42517 + p->ainsn.boostable = -1;
42518 +
42519 +- p->opcode = *p->addr;
42520 ++ p->opcode = *(ktla_ktva(p->addr));
42521 + }
42522 +
42523 + int __kprobes arch_prepare_kprobe(struct kprobe *p)
42524 +@@ -428,7 +456,7 @@ static void __kprobes prepare_singlestep
42525 + if (p->opcode == BREAKPOINT_INSTRUCTION)
42526 + regs->ip = (unsigned long)p->addr;
42527 + else
42528 +- regs->ip = (unsigned long)p->ainsn.insn;
42529 ++ regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
42530 + }
42531 +
42532 + void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
42533 +@@ -449,7 +477,7 @@ static void __kprobes setup_singlestep(s
42534 + if (p->ainsn.boostable == 1 && !p->post_handler) {
42535 + /* Boost up -- we can execute copied instructions directly */
42536 + reset_current_kprobe();
42537 +- regs->ip = (unsigned long)p->ainsn.insn;
42538 ++ regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
42539 + preempt_enable_no_resched();
42540 + return;
42541 + }
42542 +@@ -519,7 +547,7 @@ static int __kprobes kprobe_handler(stru
42543 + struct kprobe_ctlblk *kcb;
42544 +
42545 + addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t));
42546 +- if (*addr != BREAKPOINT_INSTRUCTION) {
42547 ++ if (*(kprobe_opcode_t *)ktla_ktva((unsigned long)addr) != BREAKPOINT_INSTRUCTION) {
42548 + /*
42549 + * The breakpoint instruction was removed right
42550 + * after we hit it. Another cpu has removed
42551 +@@ -770,7 +798,7 @@ static void __kprobes resume_execution(s
42552 + struct pt_regs *regs, struct kprobe_ctlblk *kcb)
42553 + {
42554 + unsigned long *tos = stack_addr(regs);
42555 +- unsigned long copy_ip = (unsigned long)p->ainsn.insn;
42556 ++ unsigned long copy_ip = ktva_ktla((unsigned long)p->ainsn.insn);
42557 + unsigned long orig_ip = (unsigned long)p->addr;
42558 + kprobe_opcode_t *insn = p->ainsn.insn;
42559 +
42560 +@@ -953,7 +981,7 @@ int __kprobes kprobe_exceptions_notify(s
42561 + struct die_args *args = data;
42562 + int ret = NOTIFY_DONE;
42563 +
42564 +- if (args->regs && user_mode_vm(args->regs))
42565 ++ if (args->regs && user_mode(args->regs))
42566 + return ret;
42567 +
42568 + switch (val) {
42569 +diff -urNp linux-2.6.27.7/arch/x86/kernel/ldt.c linux-2.6.27.7/arch/x86/kernel/ldt.c
42570 +--- linux-2.6.27.7/arch/x86/kernel/ldt.c 2008-11-07 12:55:34.000000000 -0500
42571 ++++ linux-2.6.27.7/arch/x86/kernel/ldt.c 2008-11-18 03:38:44.000000000 -0500
42572 +@@ -63,13 +63,13 @@ static int alloc_ldt(mm_context_t *pc, i
42573 + if (reload) {
42574 + #ifdef CONFIG_SMP
42575 + preempt_disable();
42576 +- load_LDT(pc);
42577 ++ load_LDT_nolock(pc);
42578 + if (!cpus_equal(current->mm->cpu_vm_mask,
42579 + cpumask_of_cpu(smp_processor_id())))
42580 + smp_call_function(flush_ldt, current->mm, 1);
42581 + preempt_enable();
42582 + #else
42583 +- load_LDT(pc);
42584 ++ load_LDT_nolock(pc);
42585 + #endif
42586 + }
42587 + if (oldsize) {
42588 +@@ -108,6 +108,24 @@ int init_new_context(struct task_struct
42589 + retval = copy_ldt(&mm->context, &old_mm->context);
42590 + mutex_unlock(&old_mm->context.lock);
42591 + }
42592 ++
42593 ++ if (tsk == current) {
42594 ++ mm->context.vdso = ~0UL;
42595 ++
42596 ++#ifdef CONFIG_X86_32
42597 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
42598 ++ mm->context.user_cs_base = 0UL;
42599 ++ mm->context.user_cs_limit = ~0UL;
42600 ++
42601 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
42602 ++ cpus_clear(mm->context.cpu_user_cs_mask);
42603 ++#endif
42604 ++
42605 ++#endif
42606 ++#endif
42607 ++
42608 ++ }
42609 ++
42610 + return retval;
42611 + }
42612 +
42613 +@@ -221,6 +239,13 @@ static int write_ldt(void __user *ptr, u
42614 + }
42615 + }
42616 +
42617 ++#ifdef CONFIG_PAX_SEGMEXEC
42618 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
42619 ++ error = -EINVAL;
42620 ++ goto out_unlock;
42621 ++ }
42622 ++#endif
42623 ++
42624 + fill_ldt(&ldt, &ldt_info);
42625 + if (oldmode)
42626 + ldt.avl = 0;
42627 +diff -urNp linux-2.6.27.7/arch/x86/kernel/machine_kexec_32.c linux-2.6.27.7/arch/x86/kernel/machine_kexec_32.c
42628 +--- linux-2.6.27.7/arch/x86/kernel/machine_kexec_32.c 2008-11-07 12:55:34.000000000 -0500
42629 ++++ linux-2.6.27.7/arch/x86/kernel/machine_kexec_32.c 2008-11-18 03:38:44.000000000 -0500
42630 +@@ -34,7 +34,7 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED
42631 + static u32 kexec_pte0[1024] PAGE_ALIGNED;
42632 + static u32 kexec_pte1[1024] PAGE_ALIGNED;
42633 +
42634 +-static void set_idt(void *newidt, __u16 limit)
42635 ++static void set_idt(struct desc_struct *newidt, __u16 limit)
42636 + {
42637 + struct desc_ptr curidt;
42638 +
42639 +@@ -46,7 +46,7 @@ static void set_idt(void *newidt, __u16
42640 + }
42641 +
42642 +
42643 +-static void set_gdt(void *newgdt, __u16 limit)
42644 ++static void set_gdt(struct desc_struct *newgdt, __u16 limit)
42645 + {
42646 + struct desc_ptr curgdt;
42647 +
42648 +@@ -145,7 +145,7 @@ void machine_kexec(struct kimage *image)
42649 + }
42650 +
42651 + control_page = page_address(image->control_code_page);
42652 +- memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE);
42653 ++ memcpy(control_page, (void *)ktla_ktva((unsigned long)relocate_kernel), KEXEC_CONTROL_CODE_MAX_SIZE);
42654 +
42655 + relocate_kernel_ptr = control_page;
42656 + page_list[PA_CONTROL_PAGE] = __pa(control_page);
42657 +diff -urNp linux-2.6.27.7/arch/x86/kernel/module_32.c linux-2.6.27.7/arch/x86/kernel/module_32.c
42658 +--- linux-2.6.27.7/arch/x86/kernel/module_32.c 2008-11-07 12:55:34.000000000 -0500
42659 ++++ linux-2.6.27.7/arch/x86/kernel/module_32.c 2008-11-18 03:38:44.000000000 -0500
42660 +@@ -23,6 +23,9 @@
42661 + #include <linux/kernel.h>
42662 + #include <linux/bug.h>
42663 +
42664 ++#include <asm/desc.h>
42665 ++#include <asm/pgtable.h>
42666 ++
42667 + #if 0
42668 + #define DEBUGP printk
42669 + #else
42670 +@@ -33,9 +36,31 @@ void *module_alloc(unsigned long size)
42671 + {
42672 + if (size == 0)
42673 + return NULL;
42674 ++
42675 ++#ifdef CONFIG_PAX_KERNEXEC
42676 ++ return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
42677 ++#else
42678 + return vmalloc_exec(size);
42679 ++#endif
42680 ++
42681 + }
42682 +
42683 ++#ifdef CONFIG_PAX_KERNEXEC
42684 ++void *module_alloc_exec(unsigned long size)
42685 ++{
42686 ++ struct vm_struct *area;
42687 ++
42688 ++ if (size == 0)
42689 ++ return NULL;
42690 ++
42691 ++ area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
42692 ++ if (area)
42693 ++ return area->addr;
42694 ++
42695 ++ return NULL;
42696 ++}
42697 ++EXPORT_SYMBOL(module_alloc_exec);
42698 ++#endif
42699 +
42700 + /* Free memory returned from module_alloc */
42701 + void module_free(struct module *mod, void *module_region)
42702 +@@ -45,6 +70,45 @@ void module_free(struct module *mod, voi
42703 + table entries. */
42704 + }
42705 +
42706 ++#ifdef CONFIG_PAX_KERNEXEC
42707 ++void module_free_exec(struct module *mod, void *module_region)
42708 ++{
42709 ++ struct vm_struct **p, *tmp;
42710 ++
42711 ++ if (!module_region)
42712 ++ return;
42713 ++
42714 ++ if ((PAGE_SIZE-1) & (unsigned long)module_region) {
42715 ++ printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
42716 ++ WARN_ON(1);
42717 ++ return;
42718 ++ }
42719 ++
42720 ++ write_lock(&vmlist_lock);
42721 ++ for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next)
42722 ++ if (tmp->addr == module_region)
42723 ++ break;
42724 ++
42725 ++ if (tmp) {
42726 ++ unsigned long cr0;
42727 ++
42728 ++ pax_open_kernel(cr0);
42729 ++ memset(tmp->addr, 0xCC, tmp->size);
42730 ++ pax_close_kernel(cr0);
42731 ++
42732 ++ *p = tmp->next;
42733 ++ kfree(tmp);
42734 ++ }
42735 ++ write_unlock(&vmlist_lock);
42736 ++
42737 ++ if (!tmp) {
42738 ++ printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
42739 ++ module_region);
42740 ++ WARN_ON(1);
42741 ++ }
42742 ++}
42743 ++#endif
42744 ++
42745 + /* We don't need anything special. */
42746 + int module_frob_arch_sections(Elf_Ehdr *hdr,
42747 + Elf_Shdr *sechdrs,
42748 +@@ -63,14 +127,20 @@ int apply_relocate(Elf32_Shdr *sechdrs,
42749 + unsigned int i;
42750 + Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
42751 + Elf32_Sym *sym;
42752 +- uint32_t *location;
42753 ++ uint32_t *plocation, location;
42754 ++
42755 ++#ifdef CONFIG_PAX_KERNEXEC
42756 ++ unsigned long cr0;
42757 ++#endif
42758 +
42759 + DEBUGP("Applying relocate section %u to %u\n", relsec,
42760 + sechdrs[relsec].sh_info);
42761 + for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
42762 + /* This is where to make the change */
42763 +- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
42764 +- + rel[i].r_offset;
42765 ++ plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
42766 ++ location = (uint32_t)plocation;
42767 ++ if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
42768 ++ plocation = ktla_ktva((void *)plocation);
42769 + /* This is the symbol it is referring to. Note that all
42770 + undefined symbols have been resolved. */
42771 + sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
42772 +@@ -78,12 +148,32 @@ int apply_relocate(Elf32_Shdr *sechdrs,
42773 +
42774 + switch (ELF32_R_TYPE(rel[i].r_info)) {
42775 + case R_386_32:
42776 ++
42777 ++#ifdef CONFIG_PAX_KERNEXEC
42778 ++ pax_open_kernel(cr0);
42779 ++#endif
42780 ++
42781 + /* We add the value into the location given */
42782 +- *location += sym->st_value;
42783 ++ *plocation += sym->st_value;
42784 ++
42785 ++#ifdef CONFIG_PAX_KERNEXEC
42786 ++ pax_close_kernel(cr0);
42787 ++#endif
42788 ++
42789 + break;
42790 + case R_386_PC32:
42791 ++
42792 ++#ifdef CONFIG_PAX_KERNEXEC
42793 ++ pax_open_kernel(cr0);
42794 ++#endif
42795 ++
42796 + /* Add the value, subtract its postition */
42797 +- *location += sym->st_value - (uint32_t)location;
42798 ++ *plocation += sym->st_value - location;
42799 ++
42800 ++#ifdef CONFIG_PAX_KERNEXEC
42801 ++ pax_close_kernel(cr0);
42802 ++#endif
42803 ++
42804 + break;
42805 + default:
42806 + printk(KERN_ERR "module %s: Unknown relocation: %u\n",
42807 +diff -urNp linux-2.6.27.7/arch/x86/kernel/module_64.c linux-2.6.27.7/arch/x86/kernel/module_64.c
42808 +--- linux-2.6.27.7/arch/x86/kernel/module_64.c 2008-11-07 12:55:34.000000000 -0500
42809 ++++ linux-2.6.27.7/arch/x86/kernel/module_64.c 2008-11-18 03:38:44.000000000 -0500
42810 +@@ -40,7 +40,7 @@ void module_free(struct module *mod, voi
42811 + table entries. */
42812 + }
42813 +
42814 +-void *module_alloc(unsigned long size)
42815 ++static void *__module_alloc(unsigned long size, pgprot_t prot)
42816 + {
42817 + struct vm_struct *area;
42818 +
42819 +@@ -54,8 +54,31 @@ void *module_alloc(unsigned long size)
42820 + if (!area)
42821 + return NULL;
42822 +
42823 +- return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
42824 ++ return __vmalloc_area(area, GFP_KERNEL | __GFP_ZERO, prot);
42825 ++}
42826 ++
42827 ++#ifdef CONFIG_PAX_KERNEXEC
42828 ++void *module_alloc(unsigned long size)
42829 ++{
42830 ++ return __module_alloc(size, PAGE_KERNEL);
42831 ++}
42832 ++
42833 ++void module_free_exec(struct module *mod, void *module_region)
42834 ++{
42835 ++ module_free(mod, module_region);
42836 ++}
42837 ++
42838 ++void *module_alloc_exec(unsigned long size)
42839 ++{
42840 ++ return __module_alloc(size, PAGE_KERNEL_RX);
42841 + }
42842 ++#else
42843 ++void *module_alloc(unsigned long size)
42844 ++{
42845 ++ return __module_alloc(size, PAGE_KERNEL_EXEC);
42846 ++}
42847 ++#endif
42848 ++
42849 + #endif
42850 +
42851 + /* We don't need anything special. */
42852 +@@ -77,7 +100,11 @@ int apply_relocate_add(Elf64_Shdr *sechd
42853 + Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
42854 + Elf64_Sym *sym;
42855 + void *loc;
42856 +- u64 val;
42857 ++ u64 val;
42858 ++
42859 ++#ifdef CONFIG_PAX_KERNEXEC
42860 ++ unsigned long cr0;
42861 ++#endif
42862 +
42863 + DEBUGP("Applying relocate section %u to %u\n", relsec,
42864 + sechdrs[relsec].sh_info);
42865 +@@ -101,21 +128,61 @@ int apply_relocate_add(Elf64_Shdr *sechd
42866 + case R_X86_64_NONE:
42867 + break;
42868 + case R_X86_64_64:
42869 ++
42870 ++#ifdef CONFIG_PAX_KERNEXEC
42871 ++ pax_open_kernel(cr0);
42872 ++#endif
42873 ++
42874 + *(u64 *)loc = val;
42875 ++
42876 ++#ifdef CONFIG_PAX_KERNEXEC
42877 ++ pax_close_kernel(cr0);
42878 ++#endif
42879 ++
42880 + break;
42881 + case R_X86_64_32:
42882 ++
42883 ++#ifdef CONFIG_PAX_KERNEXEC
42884 ++ pax_open_kernel(cr0);
42885 ++#endif
42886 ++
42887 + *(u32 *)loc = val;
42888 ++
42889 ++#ifdef CONFIG_PAX_KERNEXEC
42890 ++ pax_close_kernel(cr0);
42891 ++#endif
42892 ++
42893 + if (val != *(u32 *)loc)
42894 + goto overflow;
42895 + break;
42896 + case R_X86_64_32S:
42897 ++
42898 ++#ifdef CONFIG_PAX_KERNEXEC
42899 ++ pax_open_kernel(cr0);
42900 ++#endif
42901 ++
42902 + *(s32 *)loc = val;
42903 ++
42904 ++#ifdef CONFIG_PAX_KERNEXEC
42905 ++ pax_close_kernel(cr0);
42906 ++#endif
42907 ++
42908 + if ((s64)val != *(s32 *)loc)
42909 + goto overflow;
42910 + break;
42911 + case R_X86_64_PC32:
42912 + val -= (u64)loc;
42913 ++
42914 ++#ifdef CONFIG_PAX_KERNEXEC
42915 ++ pax_open_kernel(cr0);
42916 ++#endif
42917 ++
42918 + *(u32 *)loc = val;
42919 ++
42920 ++#ifdef CONFIG_PAX_KERNEXEC
42921 ++ pax_close_kernel(cr0);
42922 ++#endif
42923 ++
42924 + #if 0
42925 + if ((s64)val != *(s32 *)loc)
42926 + goto overflow;
42927 +diff -urNp linux-2.6.27.7/arch/x86/kernel/paravirt.c linux-2.6.27.7/arch/x86/kernel/paravirt.c
42928 +--- linux-2.6.27.7/arch/x86/kernel/paravirt.c 2008-11-07 12:55:34.000000000 -0500
42929 ++++ linux-2.6.27.7/arch/x86/kernel/paravirt.c 2008-11-18 03:38:44.000000000 -0500
42930 +@@ -44,7 +44,7 @@ void _paravirt_nop(void)
42931 + {
42932 + }
42933 +
42934 +-static void __init default_banner(void)
42935 ++static void default_banner(void)
42936 + {
42937 + printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
42938 + pv_info.name);
42939 +@@ -164,7 +164,7 @@ unsigned paravirt_patch_insns(void *insn
42940 + if (insn_len > len || start == NULL)
42941 + insn_len = len;
42942 + else
42943 +- memcpy(insnbuf, start, insn_len);
42944 ++ memcpy(insnbuf, ktla_ktva(start), insn_len);
42945 +
42946 + return insn_len;
42947 + }
42948 +@@ -279,21 +279,21 @@ void __init paravirt_use_bytelocks(void)
42949 + #endif
42950 + }
42951 +
42952 +-struct pv_info pv_info = {
42953 ++struct pv_info pv_info __read_only = {
42954 + .name = "bare hardware",
42955 + .paravirt_enabled = 0,
42956 + .kernel_rpl = 0,
42957 + .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */
42958 + };
42959 +
42960 +-struct pv_init_ops pv_init_ops = {
42961 ++struct pv_init_ops pv_init_ops __read_only = {
42962 + .patch = native_patch,
42963 + .banner = default_banner,
42964 + .arch_setup = paravirt_nop,
42965 + .memory_setup = machine_specific_memory_setup,
42966 + };
42967 +
42968 +-struct pv_time_ops pv_time_ops = {
42969 ++struct pv_time_ops pv_time_ops __read_only = {
42970 + .time_init = hpet_time_init,
42971 + .get_wallclock = native_get_wallclock,
42972 + .set_wallclock = native_set_wallclock,
42973 +@@ -301,7 +301,7 @@ struct pv_time_ops pv_time_ops = {
42974 + .get_tsc_khz = native_calibrate_tsc,
42975 + };
42976 +
42977 +-struct pv_irq_ops pv_irq_ops = {
42978 ++struct pv_irq_ops pv_irq_ops __read_only = {
42979 + .init_IRQ = native_init_IRQ,
42980 + .save_fl = native_save_fl,
42981 + .restore_fl = native_restore_fl,
42982 +@@ -314,7 +314,7 @@ struct pv_irq_ops pv_irq_ops = {
42983 + #endif
42984 + };
42985 +
42986 +-struct pv_cpu_ops pv_cpu_ops = {
42987 ++struct pv_cpu_ops pv_cpu_ops __read_only = {
42988 + .cpuid = native_cpuid,
42989 + .get_debugreg = native_get_debugreg,
42990 + .set_debugreg = native_set_debugreg,
42991 +@@ -371,7 +371,7 @@ struct pv_cpu_ops pv_cpu_ops = {
42992 + },
42993 + };
42994 +
42995 +-struct pv_apic_ops pv_apic_ops = {
42996 ++struct pv_apic_ops pv_apic_ops __read_only = {
42997 + #ifdef CONFIG_X86_LOCAL_APIC
42998 + .apic_write = native_apic_write,
42999 + .apic_read = native_apic_read,
43000 +@@ -381,7 +381,7 @@ struct pv_apic_ops pv_apic_ops = {
43001 + #endif
43002 + };
43003 +
43004 +-struct pv_mmu_ops pv_mmu_ops = {
43005 ++struct pv_mmu_ops pv_mmu_ops __read_only = {
43006 + #ifndef CONFIG_X86_64
43007 + .pagetable_setup_start = native_pagetable_setup_start,
43008 + .pagetable_setup_done = native_pagetable_setup_done,
43009 +@@ -461,7 +461,7 @@ struct pv_mmu_ops pv_mmu_ops = {
43010 + .set_fixmap = native_set_fixmap,
43011 + };
43012 +
43013 +-struct pv_lock_ops pv_lock_ops = {
43014 ++struct pv_lock_ops pv_lock_ops __read_only = {
43015 + #ifdef CONFIG_SMP
43016 + .spin_is_locked = __ticket_spin_is_locked,
43017 + .spin_is_contended = __ticket_spin_is_contended,
43018 +diff -urNp linux-2.6.27.7/arch/x86/kernel/process_32.c linux-2.6.27.7/arch/x86/kernel/process_32.c
43019 +--- linux-2.6.27.7/arch/x86/kernel/process_32.c 2008-11-07 12:55:34.000000000 -0500
43020 ++++ linux-2.6.27.7/arch/x86/kernel/process_32.c 2008-11-18 03:38:44.000000000 -0500
43021 +@@ -62,8 +62,10 @@ asmlinkage void ret_from_fork(void) __as
43022 + DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
43023 + EXPORT_PER_CPU_SYMBOL(current_task);
43024 +
43025 ++#ifdef CONFIG_SMP
43026 + DEFINE_PER_CPU(int, cpu_number);
43027 + EXPORT_PER_CPU_SYMBOL(cpu_number);
43028 ++#endif
43029 +
43030 + /*
43031 + * Return saved PC of a blocked thread.
43032 +@@ -71,6 +73,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_number);
43033 + unsigned long thread_saved_pc(struct task_struct *tsk)
43034 + {
43035 + return ((unsigned long *)tsk->thread.sp)[3];
43036 ++//XXX return tsk->thread.eip;
43037 + }
43038 +
43039 + #ifdef CONFIG_HOTPLUG_CPU
43040 +@@ -162,7 +165,7 @@ void __show_registers(struct pt_regs *re
43041 + unsigned long sp;
43042 + unsigned short ss, gs;
43043 +
43044 +- if (user_mode_vm(regs)) {
43045 ++ if (user_mode(regs)) {
43046 + sp = regs->sp;
43047 + ss = regs->ss & 0xffff;
43048 + savesegment(gs, gs);
43049 +@@ -239,8 +242,8 @@ int kernel_thread(int (*fn)(void *), voi
43050 + regs.bx = (unsigned long) fn;
43051 + regs.dx = (unsigned long) arg;
43052 +
43053 +- regs.ds = __USER_DS;
43054 +- regs.es = __USER_DS;
43055 ++ regs.ds = __KERNEL_DS;
43056 ++ regs.es = __KERNEL_DS;
43057 + regs.fs = __KERNEL_PERCPU;
43058 + regs.orig_ax = -1;
43059 + regs.ip = (unsigned long) kernel_thread_helper;
43060 +@@ -262,7 +265,7 @@ void exit_thread(void)
43061 + struct task_struct *tsk = current;
43062 + struct thread_struct *t = &tsk->thread;
43063 + int cpu = get_cpu();
43064 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
43065 ++ struct tss_struct *tss = init_tss + cpu;
43066 +
43067 + kfree(t->io_bitmap_ptr);
43068 + t->io_bitmap_ptr = NULL;
43069 +@@ -283,6 +286,7 @@ void flush_thread(void)
43070 + {
43071 + struct task_struct *tsk = current;
43072 +
43073 ++ loadsegment(gs, 0);
43074 + tsk->thread.debugreg0 = 0;
43075 + tsk->thread.debugreg1 = 0;
43076 + tsk->thread.debugreg2 = 0;
43077 +@@ -322,7 +326,7 @@ int copy_thread(int nr, unsigned long cl
43078 + struct task_struct *tsk;
43079 + int err;
43080 +
43081 +- childregs = task_pt_regs(p);
43082 ++ childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
43083 + *childregs = *regs;
43084 + childregs->ax = 0;
43085 + childregs->sp = sp;
43086 +@@ -351,6 +355,7 @@ int copy_thread(int nr, unsigned long cl
43087 + * Set a new TLS for the child thread?
43088 + */
43089 + if (clone_flags & CLONE_SETTLS)
43090 ++//XXX needs set_fs()?
43091 + err = do_set_thread_area(p, -1,
43092 + (struct user_desc __user *)childregs->si, 0);
43093 +
43094 +@@ -550,7 +555,7 @@ struct task_struct * __switch_to(struct
43095 + struct thread_struct *prev = &prev_p->thread,
43096 + *next = &next_p->thread;
43097 + int cpu = smp_processor_id();
43098 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
43099 ++ struct tss_struct *tss = init_tss + cpu;
43100 +
43101 + /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
43102 +
43103 +@@ -578,6 +583,11 @@ struct task_struct * __switch_to(struct
43104 + */
43105 + savesegment(gs, prev->gs);
43106 +
43107 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
43108 ++ if (!segment_eq(task_thread_info(prev_p)->addr_limit, task_thread_info(next_p)->addr_limit))
43109 ++ __set_fs(task_thread_info(next_p)->addr_limit, cpu);
43110 ++#endif
43111 ++
43112 + /*
43113 + * Load the per-thread Thread-Local Storage descriptor.
43114 + */
43115 +@@ -716,15 +726,27 @@ unsigned long get_wchan(struct task_stru
43116 + return 0;
43117 + }
43118 +
43119 +-unsigned long arch_align_stack(unsigned long sp)
43120 ++#ifdef CONFIG_PAX_RANDKSTACK
43121 ++asmlinkage void pax_randomize_kstack(void)
43122 + {
43123 +- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
43124 +- sp -= get_random_int() % 8192;
43125 +- return sp & ~0xf;
43126 +-}
43127 ++ struct thread_struct *thread = &current->thread;
43128 ++ unsigned long time;
43129 +
43130 +-unsigned long arch_randomize_brk(struct mm_struct *mm)
43131 +-{
43132 +- unsigned long range_end = mm->brk + 0x02000000;
43133 +- return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
43134 ++ if (!randomize_va_space)
43135 ++ return;
43136 ++
43137 ++ rdtscl(time);
43138 ++
43139 ++ /* P4 seems to return a 0 LSB, ignore it */
43140 ++#ifdef CONFIG_MPENTIUM4
43141 ++ time &= 0x1EUL;
43142 ++ time <<= 2;
43143 ++#else
43144 ++ time &= 0xFUL;
43145 ++ time <<= 3;
43146 ++#endif
43147 ++
43148 ++ thread->sp0 ^= time;
43149 ++ load_sp0(init_tss + smp_processor_id(), thread);
43150 + }
43151 ++#endif
43152 +diff -urNp linux-2.6.27.7/arch/x86/kernel/process_64.c linux-2.6.27.7/arch/x86/kernel/process_64.c
43153 +--- linux-2.6.27.7/arch/x86/kernel/process_64.c 2008-11-07 12:55:34.000000000 -0500
43154 ++++ linux-2.6.27.7/arch/x86/kernel/process_64.c 2008-11-18 03:38:44.000000000 -0500
43155 +@@ -119,6 +119,8 @@ static inline void play_dead(void)
43156 + void cpu_idle(void)
43157 + {
43158 + current_thread_info()->status |= TS_POLLING;
43159 ++ current->stack_canary = pax_get_random_long();
43160 ++ write_pda(stack_canary, current->stack_canary);
43161 + /* endless idle loop with no priority at all */
43162 + while (1) {
43163 + tick_nohz_stop_sched_tick(1);
43164 +@@ -228,7 +230,7 @@ void exit_thread(void)
43165 + struct thread_struct *t = &me->thread;
43166 +
43167 + if (me->thread.io_bitmap_ptr) {
43168 +- struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
43169 ++ struct tss_struct *tss = init_tss + get_cpu();
43170 +
43171 + kfree(t->io_bitmap_ptr);
43172 + t->io_bitmap_ptr = NULL;
43173 +@@ -541,7 +543,7 @@ __switch_to(struct task_struct *prev_p,
43174 + struct thread_struct *prev = &prev_p->thread;
43175 + struct thread_struct *next = &next_p->thread;
43176 + int cpu = smp_processor_id();
43177 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
43178 ++ struct tss_struct *tss = init_tss + cpu;
43179 + unsigned fsindex, gsindex;
43180 +
43181 + /* we're going to use this soon, after a few expensive things */
43182 +@@ -630,7 +632,6 @@ __switch_to(struct task_struct *prev_p,
43183 + (unsigned long)task_stack_page(next_p) +
43184 + THREAD_SIZE - PDA_STACKOFFSET);
43185 + #ifdef CONFIG_CC_STACKPROTECTOR
43186 +- write_pda(stack_canary, next_p->stack_canary);
43187 + /*
43188 + * Build time only check to make sure the stack_canary is at
43189 + * offset 40 in the pda; this is a gcc ABI requirement
43190 +@@ -729,12 +730,11 @@ unsigned long get_wchan(struct task_stru
43191 + if (!p || p == current || p->state==TASK_RUNNING)
43192 + return 0;
43193 + stack = (unsigned long)task_stack_page(p);
43194 +- if (p->thread.sp < stack || p->thread.sp >= stack+THREAD_SIZE)
43195 ++ if (p->thread.sp < stack || p->thread.sp > stack+THREAD_SIZE-8-sizeof(u64))
43196 + return 0;
43197 + fp = *(u64 *)(p->thread.sp);
43198 + do {
43199 +- if (fp < (unsigned long)stack ||
43200 +- fp >= (unsigned long)stack+THREAD_SIZE)
43201 ++ if (fp < stack || fp > stack+THREAD_SIZE-8-sizeof(u64))
43202 + return 0;
43203 + ip = *(u64 *)(fp+8);
43204 + if (!in_sched_functions(ip))
43205 +@@ -844,16 +844,3 @@ long sys_arch_prctl(int code, unsigned l
43206 + {
43207 + return do_arch_prctl(current, code, addr);
43208 + }
43209 +-
43210 +-unsigned long arch_align_stack(unsigned long sp)
43211 +-{
43212 +- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
43213 +- sp -= get_random_int() % 8192;
43214 +- return sp & ~0xf;
43215 +-}
43216 +-
43217 +-unsigned long arch_randomize_brk(struct mm_struct *mm)
43218 +-{
43219 +- unsigned long range_end = mm->brk + 0x02000000;
43220 +- return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
43221 +-}
43222 +diff -urNp linux-2.6.27.7/arch/x86/kernel/ptrace.c linux-2.6.27.7/arch/x86/kernel/ptrace.c
43223 +--- linux-2.6.27.7/arch/x86/kernel/ptrace.c 2008-11-07 12:55:34.000000000 -0500
43224 ++++ linux-2.6.27.7/arch/x86/kernel/ptrace.c 2008-11-18 03:38:44.000000000 -0500
43225 +@@ -1369,7 +1369,7 @@ void send_sigtrap(struct task_struct *ts
43226 + info.si_code = TRAP_BRKPT;
43227 +
43228 + /* User-mode ip? */
43229 +- info.si_addr = user_mode_vm(regs) ? (void __user *) regs->ip : NULL;
43230 ++ info.si_addr = user_mode(regs) ? (void __user *) regs->ip : NULL;
43231 +
43232 + /* Send us the fake SIGTRAP */
43233 + force_sig_info(SIGTRAP, &info, tsk);
43234 +diff -urNp linux-2.6.27.7/arch/x86/kernel/reboot.c linux-2.6.27.7/arch/x86/kernel/reboot.c
43235 +--- linux-2.6.27.7/arch/x86/kernel/reboot.c 2008-11-07 12:55:34.000000000 -0500
43236 ++++ linux-2.6.27.7/arch/x86/kernel/reboot.c 2008-11-18 03:38:44.000000000 -0500
43237 +@@ -28,7 +28,7 @@ void (*pm_power_off)(void);
43238 + EXPORT_SYMBOL(pm_power_off);
43239 +
43240 + static const struct desc_ptr no_idt = {};
43241 +-static int reboot_mode;
43242 ++static unsigned short reboot_mode;
43243 + enum reboot_type reboot_type = BOOT_KBD;
43244 + int reboot_force;
43245 +
43246 +@@ -193,7 +193,7 @@ static struct dmi_system_id __initdata r
43247 + DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
43248 + },
43249 + },
43250 +- { }
43251 ++ { NULL, NULL, {{0, NULL}}, NULL}
43252 + };
43253 +
43254 + static int __init reboot_init(void)
43255 +@@ -209,12 +209,12 @@ core_initcall(reboot_init);
43256 + controller to pulse the CPU reset line, which is more thorough, but
43257 + doesn't work with at least one type of 486 motherboard. It is easy
43258 + to stop this code working; hence the copious comments. */
43259 +-static const unsigned long long
43260 +-real_mode_gdt_entries [3] =
43261 ++static struct desc_struct
43262 ++real_mode_gdt_entries [3] __read_only =
43263 + {
43264 +- 0x0000000000000000ULL, /* Null descriptor */
43265 +- 0x00009b000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
43266 +- 0x000093000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
43267 ++ {{{0x00000000, 0x00000000}}}, /* Null descriptor */
43268 ++ {{{0x0000ffff, 0x00009b00}}}, /* 16-bit real-mode 64k code at 0x00000000 */
43269 ++ {{{0x0100ffff, 0x00009300}}} /* 16-bit real-mode 64k data at 0x00000100 */
43270 + };
43271 +
43272 + static const struct desc_ptr
43273 +@@ -263,7 +263,7 @@ static const unsigned char jump_to_bios
43274 + * specified by the code and length parameters.
43275 + * We assume that length will aways be less that 100!
43276 + */
43277 +-void machine_real_restart(const unsigned char *code, int length)
43278 ++void machine_real_restart(const unsigned char *code, unsigned int length)
43279 + {
43280 + local_irq_disable();
43281 +
43282 +@@ -283,8 +283,8 @@ void machine_real_restart(const unsigned
43283 + /* Remap the kernel at virtual address zero, as well as offset zero
43284 + from the kernel segment. This assumes the kernel segment starts at
43285 + virtual address PAGE_OFFSET. */
43286 +- memcpy(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
43287 +- sizeof(swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
43288 ++ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
43289 ++ min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
43290 +
43291 + /*
43292 + * Use `swapper_pg_dir' as our page directory.
43293 +@@ -296,16 +296,15 @@ void machine_real_restart(const unsigned
43294 + boot)". This seems like a fairly standard thing that gets set by
43295 + REBOOT.COM programs, and the previous reset routine did this
43296 + too. */
43297 +- *((unsigned short *)0x472) = reboot_mode;
43298 ++ *(unsigned short *)(__va(0x472)) = reboot_mode;
43299 +
43300 + /* For the switch to real mode, copy some code to low memory. It has
43301 + to be in the first 64k because it is running in 16-bit mode, and it
43302 + has to have the same physical and virtual address, because it turns
43303 + off paging. Copy it near the end of the first page, out of the way
43304 + of BIOS variables. */
43305 +- memcpy((void *)(0x1000 - sizeof(real_mode_switch) - 100),
43306 +- real_mode_switch, sizeof (real_mode_switch));
43307 +- memcpy((void *)(0x1000 - 100), code, length);
43308 ++ memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch));
43309 ++ memcpy(__va(0x1000 - 100), code, length);
43310 +
43311 + /* Set up the IDT for real mode. */
43312 + load_idt(&real_mode_idt);
43313 +diff -urNp linux-2.6.27.7/arch/x86/kernel/setup.c linux-2.6.27.7/arch/x86/kernel/setup.c
43314 +--- linux-2.6.27.7/arch/x86/kernel/setup.c 2008-11-17 20:03:30.000000000 -0500
43315 ++++ linux-2.6.27.7/arch/x86/kernel/setup.c 2008-11-18 11:45:34.000000000 -0500
43316 +@@ -578,6 +578,7 @@ static struct x86_quirks default_x86_qui
43317 +
43318 + struct x86_quirks *x86_quirks __initdata = &default_x86_quirks;
43319 +
43320 ++#ifdef CONFIG_X86_RESERVE_LOW_64K
43321 + static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
43322 + {
43323 + printk(KERN_NOTICE
43324 +@@ -589,6 +590,7 @@ static int __init dmi_low_memory_corrupt
43325 +
43326 + return 0;
43327 + }
43328 ++#endif
43329 +
43330 + /* List of systems that have known low memory corruption BIOS problems */
43331 + static struct dmi_system_id __initdata bad_bios_dmi_table[] = {
43332 +@@ -682,8 +684,8 @@ void __init setup_arch(char **cmdline_p)
43333 +
43334 + if (!boot_params.hdr.root_flags)
43335 + root_mountflags &= ~MS_RDONLY;
43336 +- init_mm.start_code = (unsigned long) _text;
43337 +- init_mm.end_code = (unsigned long) _etext;
43338 ++ init_mm.start_code = ktla_ktva((unsigned long) _text);
43339 ++ init_mm.end_code = ktla_ktva((unsigned long) _etext);
43340 + init_mm.end_data = (unsigned long) _edata;
43341 + #ifdef CONFIG_X86_32
43342 + init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
43343 +@@ -691,9 +693,9 @@ void __init setup_arch(char **cmdline_p)
43344 + init_mm.brk = (unsigned long) &_end;
43345 + #endif
43346 +
43347 +- code_resource.start = virt_to_phys(_text);
43348 +- code_resource.end = virt_to_phys(_etext)-1;
43349 +- data_resource.start = virt_to_phys(_etext);
43350 ++ code_resource.start = virt_to_phys(ktla_ktva(_text));
43351 ++ code_resource.end = virt_to_phys(ktla_ktva(_etext))-1;
43352 ++ data_resource.start = virt_to_phys(_data);
43353 + data_resource.end = virt_to_phys(_edata)-1;
43354 + bss_resource.start = virt_to_phys(&__bss_start);
43355 + bss_resource.end = virt_to_phys(&__bss_stop)-1;
43356 +diff -urNp linux-2.6.27.7/arch/x86/kernel/setup_percpu.c linux-2.6.27.7/arch/x86/kernel/setup_percpu.c
43357 +--- linux-2.6.27.7/arch/x86/kernel/setup_percpu.c 2008-11-07 12:55:34.000000000 -0500
43358 ++++ linux-2.6.27.7/arch/x86/kernel/setup_percpu.c 2008-11-18 03:38:44.000000000 -0500
43359 +@@ -166,7 +166,11 @@ void __init setup_per_cpu_areas(void)
43360 + else
43361 + ptr = alloc_bootmem_pages_node(NODE_DATA(node), size);
43362 + #endif
43363 ++#ifdef CONFIG_X86_32
43364 ++ __per_cpu_offset[cpu] = ptr - __per_cpu_start;
43365 ++#else
43366 + per_cpu_offset(cpu) = ptr - __per_cpu_start;
43367 ++#endif
43368 + memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
43369 +
43370 + }
43371 +diff -urNp linux-2.6.27.7/arch/x86/kernel/signal_32.c linux-2.6.27.7/arch/x86/kernel/signal_32.c
43372 +--- linux-2.6.27.7/arch/x86/kernel/signal_32.c 2008-11-07 12:55:34.000000000 -0500
43373 ++++ linux-2.6.27.7/arch/x86/kernel/signal_32.c 2008-11-18 03:38:44.000000000 -0500
43374 +@@ -378,9 +378,9 @@ setup_frame(int sig, struct k_sigaction
43375 + }
43376 +
43377 + if (current->mm->context.vdso)
43378 +- restorer = VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
43379 ++ restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
43380 + else
43381 +- restorer = &frame->retcode;
43382 ++ restorer = (void __user *)&frame->retcode;
43383 + if (ka->sa.sa_flags & SA_RESTORER)
43384 + restorer = ka->sa.sa_restorer;
43385 +
43386 +@@ -460,7 +460,7 @@ static int setup_rt_frame(int sig, struc
43387 + goto give_sigsegv;
43388 +
43389 + /* Set up to return from userspace. */
43390 +- restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
43391 ++ restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
43392 + if (ka->sa.sa_flags & SA_RESTORER)
43393 + restorer = ka->sa.sa_restorer;
43394 + err |= __put_user(restorer, &frame->pretcode);
43395 +@@ -590,7 +590,7 @@ static void do_signal(struct pt_regs *re
43396 + * X86_32: vm86 regs switched out by assembly code before reaching
43397 + * here, so testing against kernel CS suffices.
43398 + */
43399 +- if (!user_mode(regs))
43400 ++ if (!user_mode_novm(regs))
43401 + return;
43402 +
43403 + if (current_thread_info()->status & TS_RESTORE_SIGMASK)
43404 +diff -urNp linux-2.6.27.7/arch/x86/kernel/signal_64.c linux-2.6.27.7/arch/x86/kernel/signal_64.c
43405 +--- linux-2.6.27.7/arch/x86/kernel/signal_64.c 2008-11-07 12:55:34.000000000 -0500
43406 ++++ linux-2.6.27.7/arch/x86/kernel/signal_64.c 2008-11-18 03:38:44.000000000 -0500
43407 +@@ -312,8 +312,8 @@ static int setup_rt_frame(int sig, struc
43408 + err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
43409 + err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
43410 + if (sizeof(*set) == 16) {
43411 +- __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
43412 +- __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
43413 ++ err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
43414 ++ err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
43415 + } else
43416 + err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
43417 +
43418 +diff -urNp linux-2.6.27.7/arch/x86/kernel/smpboot.c linux-2.6.27.7/arch/x86/kernel/smpboot.c
43419 +--- linux-2.6.27.7/arch/x86/kernel/smpboot.c 2008-11-07 12:55:34.000000000 -0500
43420 ++++ linux-2.6.27.7/arch/x86/kernel/smpboot.c 2008-11-18 03:38:44.000000000 -0500
43421 +@@ -816,6 +816,11 @@ static int __cpuinit do_boot_cpu(int api
43422 + .cpu = cpu,
43423 + .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
43424 + };
43425 ++
43426 ++#ifdef CONFIG_PAX_KERNEXEC
43427 ++ unsigned long cr0;
43428 ++#endif
43429 ++
43430 + INIT_WORK(&c_idle.work, do_fork_idle);
43431 +
43432 + #ifdef CONFIG_X86_64
43433 +@@ -866,7 +871,17 @@ do_rest:
43434 + cpu_pda(cpu)->pcurrent = c_idle.idle;
43435 + clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
43436 + #endif
43437 ++
43438 ++#ifdef CONFIG_PAX_KERNEXEC
43439 ++ pax_open_kernel(cr0);
43440 ++#endif
43441 ++
43442 + early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
43443 ++
43444 ++#ifdef CONFIG_PAX_KERNEXEC
43445 ++ pax_close_kernel(cr0);
43446 ++#endif
43447 ++
43448 + initial_code = (unsigned long)start_secondary;
43449 + stack_start.sp = (void *) c_idle.idle->thread.sp;
43450 +
43451 +diff -urNp linux-2.6.27.7/arch/x86/kernel/smpcommon.c linux-2.6.27.7/arch/x86/kernel/smpcommon.c
43452 +--- linux-2.6.27.7/arch/x86/kernel/smpcommon.c 2008-11-07 12:55:34.000000000 -0500
43453 ++++ linux-2.6.27.7/arch/x86/kernel/smpcommon.c 2008-11-18 03:38:44.000000000 -0500
43454 +@@ -3,9 +3,10 @@
43455 + */
43456 + #include <linux/module.h>
43457 + #include <asm/smp.h>
43458 ++#include <asm/sections.h>
43459 +
43460 + #ifdef CONFIG_X86_32
43461 +-DEFINE_PER_CPU(unsigned long, this_cpu_off);
43462 ++DEFINE_PER_CPU(unsigned long, this_cpu_off) = (unsigned long)__per_cpu_start;
43463 + EXPORT_PER_CPU_SYMBOL(this_cpu_off);
43464 +
43465 + /*
43466 +@@ -15,16 +16,19 @@ EXPORT_PER_CPU_SYMBOL(this_cpu_off);
43467 + */
43468 + __cpuinit void init_gdt(int cpu)
43469 + {
43470 +- struct desc_struct gdt;
43471 ++ struct desc_struct d, *gdt = get_cpu_gdt_table(cpu);
43472 ++ unsigned long base, limit;
43473 +
43474 +- pack_descriptor(&gdt, __per_cpu_offset[cpu], 0xFFFFF,
43475 +- 0x2 | DESCTYPE_S, 0x8);
43476 +- gdt.s = 1;
43477 ++ base = per_cpu_offset(cpu);
43478 ++ limit = PERCPU_ENOUGH_ROOM - 1;
43479 ++ if (limit < 64*1024)
43480 ++ pack_descriptor(&d, base, limit, 0x80 | DESCTYPE_S | 0x3, 0x4);
43481 ++ else
43482 ++ pack_descriptor(&d, base, limit >> PAGE_SHIFT, 0x80 | DESCTYPE_S | 0x3, 0xC);
43483 +
43484 +- write_gdt_entry(get_cpu_gdt_table(cpu),
43485 +- GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S);
43486 ++ write_gdt_entry(gdt, GDT_ENTRY_PERCPU, &d, DESCTYPE_S);
43487 +
43488 +- per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu];
43489 ++ per_cpu(this_cpu_off, cpu) = base;
43490 + per_cpu(cpu_number, cpu) = cpu;
43491 + }
43492 + #endif
43493 +diff -urNp linux-2.6.27.7/arch/x86/kernel/step.c linux-2.6.27.7/arch/x86/kernel/step.c
43494 +--- linux-2.6.27.7/arch/x86/kernel/step.c 2008-11-07 12:55:34.000000000 -0500
43495 ++++ linux-2.6.27.7/arch/x86/kernel/step.c 2008-11-18 03:38:44.000000000 -0500
43496 +@@ -23,22 +23,20 @@ unsigned long convert_ip_to_linear(struc
43497 + * and APM bios ones we just ignore here.
43498 + */
43499 + if ((seg & SEGMENT_TI_MASK) == SEGMENT_LDT) {
43500 +- u32 *desc;
43501 ++ struct desc_struct *desc;
43502 + unsigned long base;
43503 +
43504 +- seg &= ~7UL;
43505 ++ seg >>= 3;
43506 +
43507 + mutex_lock(&child->mm->context.lock);
43508 +- if (unlikely((seg >> 3) >= child->mm->context.size))
43509 +- addr = -1L; /* bogus selector, access would fault */
43510 ++ if (unlikely(seg >= child->mm->context.size))
43511 ++ addr = -EINVAL;
43512 + else {
43513 +- desc = child->mm->context.ldt + seg;
43514 +- base = ((desc[0] >> 16) |
43515 +- ((desc[1] & 0xff) << 16) |
43516 +- (desc[1] & 0xff000000));
43517 ++ desc = &child->mm->context.ldt[seg];
43518 ++ base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000);
43519 +
43520 + /* 16-bit code segment? */
43521 +- if (!((desc[1] >> 22) & 1))
43522 ++ if (!((desc->b >> 22) & 1))
43523 + addr &= 0xffff;
43524 + addr += base;
43525 + }
43526 +@@ -54,6 +52,9 @@ static int is_setting_trap_flag(struct t
43527 + unsigned char opcode[15];
43528 + unsigned long addr = convert_ip_to_linear(child, regs);
43529 +
43530 ++ if (addr == -EINVAL)
43531 ++ return 0;
43532 ++
43533 + copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
43534 + for (i = 0; i < copied; i++) {
43535 + switch (opcode[i]) {
43536 +@@ -75,7 +76,7 @@ static int is_setting_trap_flag(struct t
43537 +
43538 + #ifdef CONFIG_X86_64
43539 + case 0x40 ... 0x4f:
43540 +- if (regs->cs != __USER_CS)
43541 ++ if ((regs->cs & 0xffff) != __USER_CS)
43542 + /* 32-bit mode: register increment */
43543 + return 0;
43544 + /* 64-bit mode: REX prefix */
43545 +diff -urNp linux-2.6.27.7/arch/x86/kernel/syscall_table_32.S linux-2.6.27.7/arch/x86/kernel/syscall_table_32.S
43546 +--- linux-2.6.27.7/arch/x86/kernel/syscall_table_32.S 2008-11-07 12:55:34.000000000 -0500
43547 ++++ linux-2.6.27.7/arch/x86/kernel/syscall_table_32.S 2008-11-18 03:38:44.000000000 -0500
43548 +@@ -1,3 +1,4 @@
43549 ++.section .rodata,"a",@progbits
43550 + ENTRY(sys_call_table)
43551 + .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
43552 + .long sys_exit
43553 +diff -urNp linux-2.6.27.7/arch/x86/kernel/sys_i386_32.c linux-2.6.27.7/arch/x86/kernel/sys_i386_32.c
43554 +--- linux-2.6.27.7/arch/x86/kernel/sys_i386_32.c 2008-11-07 12:55:34.000000000 -0500
43555 ++++ linux-2.6.27.7/arch/x86/kernel/sys_i386_32.c 2008-11-18 03:38:44.000000000 -0500
43556 +@@ -22,6 +22,21 @@
43557 + #include <linux/uaccess.h>
43558 + #include <linux/unistd.h>
43559 +
43560 ++int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
43561 ++{
43562 ++ unsigned long pax_task_size = TASK_SIZE;
43563 ++
43564 ++#ifdef CONFIG_PAX_SEGMEXEC
43565 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
43566 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
43567 ++#endif
43568 ++
43569 ++ if (len > pax_task_size || addr > pax_task_size - len)
43570 ++ return -EINVAL;
43571 ++
43572 ++ return 0;
43573 ++}
43574 ++
43575 + asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
43576 + unsigned long prot, unsigned long flags,
43577 + unsigned long fd, unsigned long pgoff)
43578 +@@ -81,6 +96,205 @@ out:
43579 + return err;
43580 + }
43581 +
43582 ++unsigned long
43583 ++arch_get_unmapped_area(struct file *filp, unsigned long addr,
43584 ++ unsigned long len, unsigned long pgoff, unsigned long flags)
43585 ++{
43586 ++ struct mm_struct *mm = current->mm;
43587 ++ struct vm_area_struct *vma;
43588 ++ unsigned long start_addr, pax_task_size = TASK_SIZE;
43589 ++
43590 ++#ifdef CONFIG_PAX_SEGMEXEC
43591 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
43592 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
43593 ++#endif
43594 ++
43595 ++ if (len > pax_task_size)
43596 ++ return -ENOMEM;
43597 ++
43598 ++ if (flags & MAP_FIXED)
43599 ++ return addr;
43600 ++
43601 ++#ifdef CONFIG_PAX_RANDMMAP
43602 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
43603 ++#endif
43604 ++
43605 ++ if (addr) {
43606 ++ addr = PAGE_ALIGN(addr);
43607 ++ vma = find_vma(mm, addr);
43608 ++ if (pax_task_size - len >= addr &&
43609 ++ (!vma || addr + len <= vma->vm_start))
43610 ++ return addr;
43611 ++ }
43612 ++ if (len > mm->cached_hole_size) {
43613 ++ start_addr = addr = mm->free_area_cache;
43614 ++ } else {
43615 ++ start_addr = addr = mm->mmap_base;
43616 ++ mm->cached_hole_size = 0;
43617 ++ }
43618 ++
43619 ++#ifdef CONFIG_PAX_PAGEEXEC
43620 ++ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
43621 ++ start_addr = 0x00110000UL;
43622 ++
43623 ++#ifdef CONFIG_PAX_RANDMMAP
43624 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
43625 ++ start_addr += mm->delta_mmap & 0x03FFF000UL;
43626 ++#endif
43627 ++
43628 ++ if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
43629 ++ start_addr = addr = mm->mmap_base;
43630 ++ else
43631 ++ addr = start_addr;
43632 ++ }
43633 ++#endif
43634 ++
43635 ++full_search:
43636 ++ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
43637 ++ /* At this point: (!vma || addr < vma->vm_end). */
43638 ++ if (pax_task_size - len < addr) {
43639 ++ /*
43640 ++ * Start a new search - just in case we missed
43641 ++ * some holes.
43642 ++ */
43643 ++ if (start_addr != mm->mmap_base) {
43644 ++ start_addr = addr = mm->mmap_base;
43645 ++ mm->cached_hole_size = 0;
43646 ++ goto full_search;
43647 ++ }
43648 ++ return -ENOMEM;
43649 ++ }
43650 ++ if (!vma || addr + len <= vma->vm_start) {
43651 ++ /*
43652 ++ * Remember the place where we stopped the search:
43653 ++ */
43654 ++ mm->free_area_cache = addr + len;
43655 ++ return addr;
43656 ++ }
43657 ++ if (addr + mm->cached_hole_size < vma->vm_start)
43658 ++ mm->cached_hole_size = vma->vm_start - addr;
43659 ++ addr = vma->vm_end;
43660 ++ if (mm->start_brk <= addr && addr < mm->mmap_base) {
43661 ++ start_addr = addr = mm->mmap_base;
43662 ++ mm->cached_hole_size = 0;
43663 ++ goto full_search;
43664 ++ }
43665 ++ }
43666 ++}
43667 ++
43668 ++unsigned long
43669 ++arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
43670 ++ const unsigned long len, const unsigned long pgoff,
43671 ++ const unsigned long flags)
43672 ++{
43673 ++ struct vm_area_struct *vma;
43674 ++ struct mm_struct *mm = current->mm;
43675 ++ unsigned long base = mm->mmap_base, addr = addr0, pax_task_size = TASK_SIZE;
43676 ++
43677 ++#ifdef CONFIG_PAX_SEGMEXEC
43678 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
43679 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
43680 ++#endif
43681 ++
43682 ++ /* requested length too big for entire address space */
43683 ++ if (len > pax_task_size)
43684 ++ return -ENOMEM;
43685 ++
43686 ++ if (flags & MAP_FIXED)
43687 ++ return addr;
43688 ++
43689 ++#ifdef CONFIG_PAX_PAGEEXEC
43690 ++ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
43691 ++ goto bottomup;
43692 ++#endif
43693 ++
43694 ++#ifdef CONFIG_PAX_RANDMMAP
43695 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
43696 ++#endif
43697 ++
43698 ++ /* requesting a specific address */
43699 ++ if (addr) {
43700 ++ addr = PAGE_ALIGN(addr);
43701 ++ vma = find_vma(mm, addr);
43702 ++ if (pax_task_size - len >= addr &&
43703 ++ (!vma || addr + len <= vma->vm_start))
43704 ++ return addr;
43705 ++ }
43706 ++
43707 ++ /* check if free_area_cache is useful for us */
43708 ++ if (len <= mm->cached_hole_size) {
43709 ++ mm->cached_hole_size = 0;
43710 ++ mm->free_area_cache = mm->mmap_base;
43711 ++ }
43712 ++
43713 ++ /* either no address requested or can't fit in requested address hole */
43714 ++ addr = mm->free_area_cache;
43715 ++
43716 ++ /* make sure it can fit in the remaining address space */
43717 ++ if (addr > len) {
43718 ++ vma = find_vma(mm, addr-len);
43719 ++ if (!vma || addr <= vma->vm_start)
43720 ++ /* remember the address as a hint for next time */
43721 ++ return (mm->free_area_cache = addr-len);
43722 ++ }
43723 ++
43724 ++ if (mm->mmap_base < len)
43725 ++ goto bottomup;
43726 ++
43727 ++ addr = mm->mmap_base-len;
43728 ++
43729 ++ do {
43730 ++ /*
43731 ++ * Lookup failure means no vma is above this address,
43732 ++ * else if new region fits below vma->vm_start,
43733 ++ * return with success:
43734 ++ */
43735 ++ vma = find_vma(mm, addr);
43736 ++ if (!vma || addr+len <= vma->vm_start)
43737 ++ /* remember the address as a hint for next time */
43738 ++ return (mm->free_area_cache = addr);
43739 ++
43740 ++ /* remember the largest hole we saw so far */
43741 ++ if (addr + mm->cached_hole_size < vma->vm_start)
43742 ++ mm->cached_hole_size = vma->vm_start - addr;
43743 ++
43744 ++ /* try just below the current vma->vm_start */
43745 ++ addr = vma->vm_start-len;
43746 ++ } while (len < vma->vm_start);
43747 ++
43748 ++bottomup:
43749 ++ /*
43750 ++ * A failed mmap() very likely causes application failure,
43751 ++ * so fall back to the bottom-up function here. This scenario
43752 ++ * can happen with large stack limits and large mmap()
43753 ++ * allocations.
43754 ++ */
43755 ++
43756 ++#ifdef CONFIG_PAX_SEGMEXEC
43757 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
43758 ++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
43759 ++ else
43760 ++#endif
43761 ++
43762 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
43763 ++
43764 ++#ifdef CONFIG_PAX_RANDMMAP
43765 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
43766 ++ mm->mmap_base += mm->delta_mmap;
43767 ++#endif
43768 ++
43769 ++ mm->free_area_cache = mm->mmap_base;
43770 ++ mm->cached_hole_size = ~0UL;
43771 ++ addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
43772 ++ /*
43773 ++ * Restore the topdown base:
43774 ++ */
43775 ++ mm->mmap_base = base;
43776 ++ mm->free_area_cache = base;
43777 ++ mm->cached_hole_size = ~0UL;
43778 ++
43779 ++ return addr;
43780 ++}
43781 +
43782 + struct sel_arg_struct {
43783 + unsigned long n;
43784 +diff -urNp linux-2.6.27.7/arch/x86/kernel/sys_x86_64.c linux-2.6.27.7/arch/x86/kernel/sys_x86_64.c
43785 +--- linux-2.6.27.7/arch/x86/kernel/sys_x86_64.c 2008-11-07 12:55:34.000000000 -0500
43786 ++++ linux-2.6.27.7/arch/x86/kernel/sys_x86_64.c 2008-11-18 03:38:44.000000000 -0500
43787 +@@ -45,8 +45,8 @@ out:
43788 + return error;
43789 + }
43790 +
43791 +-static void find_start_end(unsigned long flags, unsigned long *begin,
43792 +- unsigned long *end)
43793 ++static void find_start_end(struct mm_struct *mm, unsigned long flags,
43794 ++ unsigned long *begin, unsigned long *end)
43795 + {
43796 + if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
43797 + unsigned long new_begin;
43798 +@@ -65,7 +65,7 @@ static void find_start_end(unsigned long
43799 + *begin = new_begin;
43800 + }
43801 + } else {
43802 +- *begin = TASK_UNMAPPED_BASE;
43803 ++ *begin = mm->mmap_base;
43804 + *end = TASK_SIZE;
43805 + }
43806 + }
43807 +@@ -82,11 +82,15 @@ arch_get_unmapped_area(struct file *filp
43808 + if (flags & MAP_FIXED)
43809 + return addr;
43810 +
43811 +- find_start_end(flags, &begin, &end);
43812 ++ find_start_end(mm, flags, &begin, &end);
43813 +
43814 + if (len > end)
43815 + return -ENOMEM;
43816 +
43817 ++#ifdef CONFIG_PAX_RANDMMAP
43818 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
43819 ++#endif
43820 ++
43821 + if (addr) {
43822 + addr = PAGE_ALIGN(addr);
43823 + vma = find_vma(mm, addr);
43824 +@@ -141,7 +145,7 @@ arch_get_unmapped_area_topdown(struct fi
43825 + {
43826 + struct vm_area_struct *vma;
43827 + struct mm_struct *mm = current->mm;
43828 +- unsigned long addr = addr0;
43829 ++ unsigned long base = mm->mmap_base, addr = addr0;
43830 +
43831 + /* requested length too big for entire address space */
43832 + if (len > TASK_SIZE)
43833 +@@ -154,6 +158,10 @@ arch_get_unmapped_area_topdown(struct fi
43834 + if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT))
43835 + goto bottomup;
43836 +
43837 ++#ifdef CONFIG_PAX_RANDMMAP
43838 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
43839 ++#endif
43840 ++
43841 + /* requesting a specific address */
43842 + if (addr) {
43843 + addr = PAGE_ALIGN(addr);
43844 +@@ -211,13 +219,21 @@ bottomup:
43845 + * can happen with large stack limits and large mmap()
43846 + * allocations.
43847 + */
43848 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
43849 ++
43850 ++#ifdef CONFIG_PAX_RANDMMAP
43851 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
43852 ++ mm->mmap_base += mm->delta_mmap;
43853 ++#endif
43854 ++
43855 ++ mm->free_area_cache = mm->mmap_base;
43856 + mm->cached_hole_size = ~0UL;
43857 +- mm->free_area_cache = TASK_UNMAPPED_BASE;
43858 + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
43859 + /*
43860 + * Restore the topdown base:
43861 + */
43862 +- mm->free_area_cache = mm->mmap_base;
43863 ++ mm->mmap_base = base;
43864 ++ mm->free_area_cache = base;
43865 + mm->cached_hole_size = ~0UL;
43866 +
43867 + return addr;
43868 +diff -urNp linux-2.6.27.7/arch/x86/kernel/time_32.c linux-2.6.27.7/arch/x86/kernel/time_32.c
43869 +--- linux-2.6.27.7/arch/x86/kernel/time_32.c 2008-11-07 12:55:34.000000000 -0500
43870 ++++ linux-2.6.27.7/arch/x86/kernel/time_32.c 2008-11-18 03:38:44.000000000 -0500
43871 +@@ -49,20 +49,30 @@ unsigned long profile_pc(struct pt_regs
43872 + if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs) &&
43873 + in_lock_functions(pc)) {
43874 + #ifdef CONFIG_FRAME_POINTER
43875 +- return *(unsigned long *)(regs->bp + 4);
43876 ++ return ktla_ktva(*(unsigned long *)(regs->bp + 4));
43877 + #else
43878 + unsigned long *sp = (unsigned long *)&regs->sp;
43879 +
43880 + /* Return address is either directly at stack pointer
43881 + or above a saved flags. Eflags has bits 22-31 zero,
43882 + kernel addresses don't. */
43883 ++
43884 ++#ifdef CONFIG_PAX_KERNEXEC
43885 ++ return ktla_ktva(sp[0]);
43886 ++#else
43887 + if (sp[0] >> 22)
43888 + return sp[0];
43889 + if (sp[1] >> 22)
43890 + return sp[1];
43891 + #endif
43892 ++
43893 ++#endif
43894 + }
43895 + #endif
43896 ++
43897 ++ if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs))
43898 ++ pc = ktla_ktva(pc);
43899 ++
43900 + return pc;
43901 + }
43902 + EXPORT_SYMBOL(profile_pc);
43903 +diff -urNp linux-2.6.27.7/arch/x86/kernel/tlb_32.c linux-2.6.27.7/arch/x86/kernel/tlb_32.c
43904 +--- linux-2.6.27.7/arch/x86/kernel/tlb_32.c 2008-11-07 12:55:34.000000000 -0500
43905 ++++ linux-2.6.27.7/arch/x86/kernel/tlb_32.c 2008-11-18 03:38:44.000000000 -0500
43906 +@@ -5,7 +5,7 @@
43907 + #include <asm/tlbflush.h>
43908 +
43909 + DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate)
43910 +- ____cacheline_aligned = { &init_mm, 0, };
43911 ++ ____cacheline_aligned = { &init_mm, 0, {0} };
43912 +
43913 + /* must come after the send_IPI functions above for inlining */
43914 + #include <mach_ipi.h>
43915 +diff -urNp linux-2.6.27.7/arch/x86/kernel/tls.c linux-2.6.27.7/arch/x86/kernel/tls.c
43916 +--- linux-2.6.27.7/arch/x86/kernel/tls.c 2008-11-07 12:55:34.000000000 -0500
43917 ++++ linux-2.6.27.7/arch/x86/kernel/tls.c 2008-11-18 03:38:44.000000000 -0500
43918 +@@ -84,6 +84,11 @@ int do_set_thread_area(struct task_struc
43919 + if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
43920 + return -EINVAL;
43921 +
43922 ++#ifdef CONFIG_PAX_SEGMEXEC
43923 ++ if ((p->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
43924 ++ return -EINVAL;
43925 ++#endif
43926 ++
43927 + set_tls_desc(p, idx, &info, 1);
43928 +
43929 + return 0;
43930 +diff -urNp linux-2.6.27.7/arch/x86/kernel/traps_32.c linux-2.6.27.7/arch/x86/kernel/traps_32.c
43931 +--- linux-2.6.27.7/arch/x86/kernel/traps_32.c 2008-11-07 12:55:34.000000000 -0500
43932 ++++ linux-2.6.27.7/arch/x86/kernel/traps_32.c 2008-11-18 03:38:44.000000000 -0500
43933 +@@ -70,14 +70,6 @@ asmlinkage int system_call(void);
43934 + /* Do we ignore FPU interrupts ? */
43935 + char ignore_fpu_irq;
43936 +
43937 +-/*
43938 +- * The IDT has to be page-aligned to simplify the Pentium
43939 +- * F0 0F bug workaround.. We have a special link segment
43940 +- * for this.
43941 +- */
43942 +-gate_desc idt_table[256]
43943 +- __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, };
43944 +-
43945 + int panic_on_unrecovered_nmi;
43946 + int kstack_depth_to_print = 24;
43947 + static unsigned int code_bytes = 64;
43948 +@@ -320,21 +312,22 @@ void show_registers(struct pt_regs *regs
43949 + * When in-kernel, we also print out the stack and code at the
43950 + * time of the fault..
43951 + */
43952 +- if (!user_mode_vm(regs)) {
43953 ++ if (!user_mode(regs)) {
43954 + unsigned int code_prologue = code_bytes * 43 / 64;
43955 + unsigned int code_len = code_bytes;
43956 + unsigned char c;
43957 + u8 *ip;
43958 ++ unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->cs) >> 3]);
43959 +
43960 + printk("\n" KERN_EMERG "Stack: ");
43961 + show_stack_log_lvl(NULL, regs, &regs->sp, 0, KERN_EMERG);
43962 +
43963 + printk(KERN_EMERG "Code: ");
43964 +
43965 +- ip = (u8 *)regs->ip - code_prologue;
43966 ++ ip = (u8 *)regs->ip - code_prologue + cs_base;
43967 + if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
43968 + /* try starting at EIP */
43969 +- ip = (u8 *)regs->ip;
43970 ++ ip = (u8 *)regs->ip + cs_base;
43971 + code_len = code_len - code_prologue + 1;
43972 + }
43973 + for (i = 0; i < code_len; i++, ip++) {
43974 +@@ -343,7 +336,7 @@ void show_registers(struct pt_regs *regs
43975 + printk(" Bad EIP value.");
43976 + break;
43977 + }
43978 +- if (ip == (u8 *)regs->ip)
43979 ++ if (ip == (u8 *)regs->ip + cs_base)
43980 + printk("<%02x> ", c);
43981 + else
43982 + printk("%02x ", c);
43983 +@@ -356,6 +349,7 @@ int is_valid_bugaddr(unsigned long ip)
43984 + {
43985 + unsigned short ud2;
43986 +
43987 ++ ip = ktla_ktva(ip);
43988 + if (ip < PAGE_OFFSET)
43989 + return 0;
43990 + if (probe_kernel_address((unsigned short *)ip, ud2))
43991 +@@ -469,7 +463,7 @@ void die(const char *str, struct pt_regs
43992 + static inline void
43993 + die_if_kernel(const char *str, struct pt_regs *regs, long err)
43994 + {
43995 +- if (!user_mode_vm(regs))
43996 ++ if (!user_mode(regs))
43997 + die(str, regs, err);
43998 + }
43999 +
44000 +@@ -479,7 +473,7 @@ do_trap(int trapnr, int signr, char *str
44001 + {
44002 + struct task_struct *tsk = current;
44003 +
44004 +- if (regs->flags & X86_VM_MASK) {
44005 ++ if (v8086_mode(regs)) {
44006 + if (vm86)
44007 + goto vm86_trap;
44008 + goto trap_signal;
44009 +@@ -513,6 +507,12 @@ kernel_trap:
44010 + tsk->thread.trap_no = trapnr;
44011 + die(str, regs, error_code);
44012 + }
44013 ++
44014 ++#ifdef CONFIG_PAX_REFCOUNT
44015 ++ if (trapnr == 4)
44016 ++ pax_report_refcount_overflow(regs);
44017 ++#endif
44018 ++
44019 + return;
44020 +
44021 + vm86_trap:
44022 +@@ -595,7 +595,7 @@ do_general_protection(struct pt_regs *re
44023 + int cpu;
44024 +
44025 + cpu = get_cpu();
44026 +- tss = &per_cpu(init_tss, cpu);
44027 ++ tss = init_tss + cpu;
44028 + thread = &current->thread;
44029 +
44030 + /*
44031 +@@ -627,13 +627,29 @@ do_general_protection(struct pt_regs *re
44032 + }
44033 + put_cpu();
44034 +
44035 +- if (regs->flags & X86_VM_MASK)
44036 ++ if (v8086_mode(regs))
44037 + goto gp_in_vm86;
44038 +
44039 + tsk = current;
44040 +- if (!user_mode(regs))
44041 ++ if (!user_mode_novm(regs))
44042 + goto gp_in_kernel;
44043 +
44044 ++#ifdef CONFIG_PAX_PAGEEXEC
44045 ++ if (!nx_enabled && tsk->mm && (tsk->mm->pax_flags & MF_PAX_PAGEEXEC)) {
44046 ++ struct mm_struct *mm = tsk->mm;
44047 ++ unsigned long limit;
44048 ++
44049 ++ down_write(&mm->mmap_sem);
44050 ++ limit = mm->context.user_cs_limit;
44051 ++ if (limit < TASK_SIZE) {
44052 ++ track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC);
44053 ++ up_write(&mm->mmap_sem);
44054 ++ return;
44055 ++ }
44056 ++ up_write(&mm->mmap_sem);
44057 ++ }
44058 ++#endif
44059 ++
44060 + tsk->thread.error_code = error_code;
44061 + tsk->thread.trap_no = 13;
44062 +
44063 +@@ -664,6 +680,13 @@ gp_in_kernel:
44064 + if (notify_die(DIE_GPF, "general protection fault", regs,
44065 + error_code, 13, SIGSEGV) == NOTIFY_STOP)
44066 + return;
44067 ++
44068 ++#ifdef CONFIG_PAX_KERNEXEC
44069 ++ if ((regs->cs & 0xFFFF) == __KERNEL_CS)
44070 ++ die("PAX: suspicious general protection fault", regs, error_code);
44071 ++ else
44072 ++#endif
44073 ++
44074 + die("general protection fault", regs, error_code);
44075 + }
44076 +
44077 +@@ -766,7 +789,7 @@ void notrace __kprobes die_nmi(char *str
44078 + * If we are in kernel we are probably nested up pretty bad
44079 + * and might aswell get out now while we still can:
44080 + */
44081 +- if (!user_mode_vm(regs)) {
44082 ++ if (!user_mode(regs)) {
44083 + current->thread.trap_no = 2;
44084 + crash_kexec(regs);
44085 + }
44086 +@@ -915,7 +938,7 @@ void __kprobes do_debug(struct pt_regs *
44087 + goto clear_dr7;
44088 + }
44089 +
44090 +- if (regs->flags & X86_VM_MASK)
44091 ++ if (v8086_mode(regs))
44092 + goto debug_vm86;
44093 +
44094 + /* Save debug status register where ptrace can see it */
44095 +@@ -931,7 +954,7 @@ void __kprobes do_debug(struct pt_regs *
44096 + * check for kernel mode by just checking the CPL
44097 + * of CS.
44098 + */
44099 +- if (!user_mode(regs))
44100 ++ if (!user_mode_novm(regs))
44101 + goto clear_TF_reenable;
44102 + }
44103 +
44104 +@@ -1086,7 +1109,7 @@ void do_simd_coprocessor_error(struct pt
44105 + * Handle strange cache flush from user space exception
44106 + * in all other cases. This is undocumented behaviour.
44107 + */
44108 +- if (regs->flags & X86_VM_MASK) {
44109 ++ if (v8086_mode(regs)) {
44110 + handle_vm86_fault((struct kernel_vm86_regs *)regs, error_code);
44111 + return;
44112 + }
44113 +@@ -1106,19 +1129,14 @@ void do_spurious_interrupt_bug(struct pt
44114 +
44115 + unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp)
44116 + {
44117 +- struct desc_struct *gdt = get_cpu_gdt_table(smp_processor_id());
44118 + unsigned long base = (kesp - uesp) & -THREAD_SIZE;
44119 + unsigned long new_kesp = kesp - base;
44120 + unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
44121 +- __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
44122 ++ struct desc_struct ss;
44123 +
44124 + /* Set up base for espfix segment */
44125 +- desc &= 0x00f0ff0000000000ULL;
44126 +- desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
44127 +- ((((__u64)base) << 32) & 0xff00000000000000ULL) |
44128 +- ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
44129 +- (lim_pages & 0xffff);
44130 +- *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
44131 ++ pack_descriptor(&ss, base, lim_pages, 0x93, 0xC);
44132 ++ write_gdt_entry(get_cpu_gdt_table(smp_processor_id()), GDT_ENTRY_ESPFIX_SS, &ss, DESCTYPE_S);
44133 +
44134 + return new_kesp;
44135 + }
44136 +diff -urNp linux-2.6.27.7/arch/x86/kernel/traps_64.c linux-2.6.27.7/arch/x86/kernel/traps_64.c
44137 +--- linux-2.6.27.7/arch/x86/kernel/traps_64.c 2008-11-07 12:55:34.000000000 -0500
44138 ++++ linux-2.6.27.7/arch/x86/kernel/traps_64.c 2008-11-18 03:38:44.000000000 -0500
44139 +@@ -634,6 +634,12 @@ kernel_trap:
44140 + tsk->thread.trap_no = trapnr;
44141 + die(str, regs, error_code);
44142 + }
44143 ++
44144 ++#ifdef CONFIG_PAX_REFCOUNT
44145 ++ if (trapnr == 4)
44146 ++ pax_report_refcount_overflow(regs);
44147 ++#endif
44148 ++
44149 + return;
44150 + }
44151 +
44152 +diff -urNp linux-2.6.27.7/arch/x86/kernel/tsc.c linux-2.6.27.7/arch/x86/kernel/tsc.c
44153 +--- linux-2.6.27.7/arch/x86/kernel/tsc.c 2008-11-17 20:03:30.000000000 -0500
44154 ++++ linux-2.6.27.7/arch/x86/kernel/tsc.c 2008-11-18 03:38:44.000000000 -0500
44155 +@@ -554,7 +554,7 @@ static struct dmi_system_id __initdata b
44156 + DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
44157 + },
44158 + },
44159 +- {}
44160 ++ { NULL, NULL, {{0, NULL}}, NULL}
44161 + };
44162 +
44163 + /*
44164 +diff -urNp linux-2.6.27.7/arch/x86/kernel/vm86_32.c linux-2.6.27.7/arch/x86/kernel/vm86_32.c
44165 +--- linux-2.6.27.7/arch/x86/kernel/vm86_32.c 2008-11-07 12:55:34.000000000 -0500
44166 ++++ linux-2.6.27.7/arch/x86/kernel/vm86_32.c 2008-11-18 03:38:44.000000000 -0500
44167 +@@ -147,7 +147,7 @@ struct pt_regs *save_v86_state(struct ke
44168 + do_exit(SIGSEGV);
44169 + }
44170 +
44171 +- tss = &per_cpu(init_tss, get_cpu());
44172 ++ tss = init_tss + get_cpu();
44173 + current->thread.sp0 = current->thread.saved_sp0;
44174 + current->thread.sysenter_cs = __KERNEL_CS;
44175 + load_sp0(tss, &current->thread);
44176 +@@ -324,7 +324,7 @@ static void do_sys_vm86(struct kernel_vm
44177 + tsk->thread.saved_fs = info->regs32->fs;
44178 + savesegment(gs, tsk->thread.saved_gs);
44179 +
44180 +- tss = &per_cpu(init_tss, get_cpu());
44181 ++ tss = init_tss + get_cpu();
44182 + tsk->thread.sp0 = (unsigned long) &info->VM86_TSS_ESP0;
44183 + if (cpu_has_sep)
44184 + tsk->thread.sysenter_cs = 0;
44185 +diff -urNp linux-2.6.27.7/arch/x86/kernel/vmi_32.c linux-2.6.27.7/arch/x86/kernel/vmi_32.c
44186 +--- linux-2.6.27.7/arch/x86/kernel/vmi_32.c 2008-11-07 12:55:34.000000000 -0500
44187 ++++ linux-2.6.27.7/arch/x86/kernel/vmi_32.c 2008-11-18 03:38:44.000000000 -0500
44188 +@@ -102,18 +102,43 @@ static unsigned patch_internal(int call,
44189 + {
44190 + u64 reloc;
44191 + struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
44192 ++
44193 ++#ifdef CONFIG_PAX_KERNEXEC
44194 ++ unsigned long cr0;
44195 ++#endif
44196 ++
44197 + reloc = call_vrom_long_func(vmi_rom, get_reloc, call);
44198 + switch(rel->type) {
44199 + case VMI_RELOCATION_CALL_REL:
44200 + BUG_ON(len < 5);
44201 ++
44202 ++#ifdef CONFIG_PAX_KERNEXEC
44203 ++ pax_open_kernel(cr0);
44204 ++#endif
44205 ++
44206 + *(char *)insnbuf = MNEM_CALL;
44207 + patch_offset(insnbuf, ip, (unsigned long)rel->eip);
44208 ++
44209 ++#ifdef CONFIG_PAX_KERNEXEC
44210 ++ pax_close_kernel(cr0);
44211 ++#endif
44212 ++
44213 + return 5;
44214 +
44215 + case VMI_RELOCATION_JUMP_REL:
44216 + BUG_ON(len < 5);
44217 ++
44218 ++#ifdef CONFIG_PAX_KERNEXEC
44219 ++ pax_open_kernel(cr0);
44220 ++#endif
44221 ++
44222 + *(char *)insnbuf = MNEM_JMP;
44223 + patch_offset(insnbuf, ip, (unsigned long)rel->eip);
44224 ++
44225 ++#ifdef CONFIG_PAX_KERNEXEC
44226 ++ pax_close_kernel(cr0);
44227 ++#endif
44228 ++
44229 + return 5;
44230 +
44231 + case VMI_RELOCATION_NOP:
44232 +@@ -516,14 +541,14 @@ static void vmi_set_pud(pud_t *pudp, pud
44233 +
44234 + static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
44235 + {
44236 +- const pte_t pte = { .pte = 0 };
44237 ++ const pte_t pte = __pte(0ULL);
44238 + vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE);
44239 + vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
44240 + }
44241 +
44242 + static void vmi_pmd_clear(pmd_t *pmd)
44243 + {
44244 +- const pte_t pte = { .pte = 0 };
44245 ++ const pte_t pte = __pte(0ULL);
44246 + vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD);
44247 + vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD);
44248 + }
44249 +@@ -552,8 +577,8 @@ vmi_startup_ipi_hook(int phys_apicid, un
44250 + ap.ss = __KERNEL_DS;
44251 + ap.esp = (unsigned long) start_esp;
44252 +
44253 +- ap.ds = __USER_DS;
44254 +- ap.es = __USER_DS;
44255 ++ ap.ds = __KERNEL_DS;
44256 ++ ap.es = __KERNEL_DS;
44257 + ap.fs = __KERNEL_PERCPU;
44258 + ap.gs = 0;
44259 +
44260 +@@ -748,12 +773,20 @@ static inline int __init activate_vmi(vo
44261 + u64 reloc;
44262 + const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc;
44263 +
44264 ++#ifdef CONFIG_PAX_KERNEXEC
44265 ++ unsigned long cr0;
44266 ++#endif
44267 ++
44268 + if (call_vrom_func(vmi_rom, vmi_init) != 0) {
44269 + printk(KERN_ERR "VMI ROM failed to initialize!");
44270 + return 0;
44271 + }
44272 + savesegment(cs, kernel_cs);
44273 +
44274 ++#ifdef CONFIG_PAX_KERNEXEC
44275 ++ pax_open_kernel(cr0);
44276 ++#endif
44277 ++
44278 + pv_info.paravirt_enabled = 1;
44279 + pv_info.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
44280 + pv_info.name = "vmi";
44281 +@@ -943,6 +976,10 @@ static inline int __init activate_vmi(vo
44282 +
44283 + para_fill(pv_irq_ops.safe_halt, Halt);
44284 +
44285 ++#ifdef CONFIG_PAX_KERNEXEC
44286 ++ pax_close_kernel(cr0);
44287 ++#endif
44288 ++
44289 + /*
44290 + * Alternative instruction rewriting doesn't happen soon enough
44291 + * to convert VMI_IRET to a call instead of a jump; so we have
44292 +diff -urNp linux-2.6.27.7/arch/x86/kernel/vmlinux_32.lds.S linux-2.6.27.7/arch/x86/kernel/vmlinux_32.lds.S
44293 +--- linux-2.6.27.7/arch/x86/kernel/vmlinux_32.lds.S 2008-11-07 12:55:34.000000000 -0500
44294 ++++ linux-2.6.27.7/arch/x86/kernel/vmlinux_32.lds.S 2008-11-18 03:38:44.000000000 -0500
44295 +@@ -15,6 +15,20 @@
44296 + #include <asm/page.h>
44297 + #include <asm/cache.h>
44298 + #include <asm/boot.h>
44299 ++#include <asm/segment.h>
44300 ++
44301 ++#ifdef CONFIG_X86_PAE
44302 ++#define PMD_SHIFT 21
44303 ++#else
44304 ++#define PMD_SHIFT 22
44305 ++#endif
44306 ++#define PMD_SIZE (1 << PMD_SHIFT)
44307 ++
44308 ++#ifdef CONFIG_PAX_KERNEXEC
44309 ++#define __KERNEL_TEXT_OFFSET (__PAGE_OFFSET + (((____LOAD_PHYSICAL_ADDR + 2*(PMD_SIZE - 1)) - 1) & ~(PMD_SIZE - 1)))
44310 ++#else
44311 ++#define __KERNEL_TEXT_OFFSET 0
44312 ++#endif
44313 +
44314 + OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
44315 + OUTPUT_ARCH(i386)
44316 +@@ -22,81 +36,23 @@ ENTRY(phys_startup_32)
44317 + jiffies = jiffies_64;
44318 +
44319 + PHDRS {
44320 +- text PT_LOAD FLAGS(5); /* R_E */
44321 +- data PT_LOAD FLAGS(7); /* RWE */
44322 +- note PT_NOTE FLAGS(0); /* ___ */
44323 ++ initdata PT_LOAD FLAGS(6); /* RW_ */
44324 ++ percpu PT_LOAD FLAGS(6); /* RW_ */
44325 ++ inittext PT_LOAD FLAGS(5); /* R_E */
44326 ++ text PT_LOAD FLAGS(5); /* R_E */
44327 ++ rodata PT_LOAD FLAGS(4); /* R__ */
44328 ++ data PT_LOAD FLAGS(6); /* RW_ */
44329 ++ note PT_NOTE FLAGS(0); /* ___ */
44330 + }
44331 + SECTIONS
44332 + {
44333 +- . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
44334 +- phys_startup_32 = startup_32 - LOAD_OFFSET;
44335 +-
44336 +- .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
44337 +- _text = .; /* Text and read-only data */
44338 +- *(.text.head)
44339 +- } :text = 0x9090
44340 +-
44341 +- /* read-only */
44342 +- .text : AT(ADDR(.text) - LOAD_OFFSET) {
44343 +- . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
44344 +- *(.text.page_aligned)
44345 +- TEXT_TEXT
44346 +- SCHED_TEXT
44347 +- LOCK_TEXT
44348 +- KPROBES_TEXT
44349 +- *(.fixup)
44350 +- *(.gnu.warning)
44351 +- _etext = .; /* End of text section */
44352 +- } :text = 0x9090
44353 +-
44354 +- NOTES :text :note
44355 ++ . = LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR;
44356 +
44357 +- . = ALIGN(16); /* Exception table */
44358 +- __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
44359 +- __start___ex_table = .;
44360 +- *(__ex_table)
44361 +- __stop___ex_table = .;
44362 +- } :text = 0x9090
44363 +-
44364 +- RODATA
44365 +-
44366 +- /* writeable */
44367 +- . = ALIGN(PAGE_SIZE);
44368 +- .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
44369 +- DATA_DATA
44370 +- CONSTRUCTORS
44371 +- } :data
44372 +-
44373 +- . = ALIGN(PAGE_SIZE);
44374 +- .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
44375 +- __nosave_begin = .;
44376 +- *(.data.nosave)
44377 +- . = ALIGN(PAGE_SIZE);
44378 +- __nosave_end = .;
44379 +- }
44380 +-
44381 +- . = ALIGN(PAGE_SIZE);
44382 +- .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
44383 +- *(.data.page_aligned)
44384 +- *(.data.idt)
44385 +- }
44386 +-
44387 +- . = ALIGN(32);
44388 +- .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
44389 +- *(.data.cacheline_aligned)
44390 +- }
44391 +-
44392 +- /* rarely changed data like cpu maps */
44393 +- . = ALIGN(32);
44394 +- .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
44395 +- *(.data.read_mostly)
44396 +- _edata = .; /* End of data section */
44397 +- }
44398 +-
44399 +- . = ALIGN(THREAD_SIZE); /* init_task */
44400 +- .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
44401 +- *(.data.init_task)
44402 +- }
44403 ++ .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
44404 ++ __LOAD_PHYSICAL_ADDR = . - LOAD_OFFSET;
44405 ++ phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
44406 ++ *(.text.startup)
44407 ++ } :initdata
44408 +
44409 + /* might get freed after init */
44410 + . = ALIGN(PAGE_SIZE);
44411 +@@ -114,14 +70,8 @@ SECTIONS
44412 + . = ALIGN(PAGE_SIZE);
44413 +
44414 + /* will be freed after init */
44415 +- . = ALIGN(PAGE_SIZE); /* Init code and data */
44416 +- .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
44417 +- __init_begin = .;
44418 +- _sinittext = .;
44419 +- INIT_TEXT
44420 +- _einittext = .;
44421 +- }
44422 + .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
44423 ++ __init_begin = .;
44424 + INIT_DATA
44425 + }
44426 + . = ALIGN(16);
44427 +@@ -161,11 +111,6 @@ SECTIONS
44428 + *(.parainstructions)
44429 + __parainstructions_end = .;
44430 + }
44431 +- /* .exit.text is discard at runtime, not link time, to deal with references
44432 +- from .altinstructions and .eh_frame */
44433 +- .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
44434 +- EXIT_TEXT
44435 +- }
44436 + .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
44437 + EXIT_DATA
44438 + }
44439 +@@ -178,17 +123,136 @@ SECTIONS
44440 + }
44441 + #endif
44442 + . = ALIGN(PAGE_SIZE);
44443 +- .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
44444 +- __per_cpu_start = .;
44445 ++ per_cpu_start = .;
44446 ++ .data.percpu (0) : AT(ADDR(.data.percpu) - LOAD_OFFSET + per_cpu_start) {
44447 ++ __per_cpu_start = . + per_cpu_start;
44448 ++ LONG(0)
44449 + *(.data.percpu)
44450 + *(.data.percpu.shared_aligned)
44451 +- __per_cpu_end = .;
44452 +- }
44453 ++ __per_cpu_end = . + per_cpu_start;
44454 ++ } :percpu
44455 ++ . += per_cpu_start;
44456 + . = ALIGN(PAGE_SIZE);
44457 + /* freed after init ends here */
44458 +
44459 ++ . = ALIGN(PAGE_SIZE); /* Init code and data */
44460 ++ .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
44461 ++ _sinittext = .;
44462 ++ INIT_TEXT
44463 ++ _einittext = .;
44464 ++ } :inittext
44465 ++
44466 ++ /* .exit.text is discard at runtime, not link time, to deal with references
44467 ++ from .altinstructions and .eh_frame */
44468 ++ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
44469 ++ EXIT_TEXT
44470 ++ }
44471 ++
44472 ++ .filler : AT(ADDR(.filler) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
44473 ++ BYTE(0)
44474 ++ . = ALIGN(2*PMD_SIZE) - 1;
44475 ++ }
44476 ++
44477 ++ /* freed after init ends here */
44478 ++
44479 ++ .text.head : AT(ADDR(.text.head) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
44480 ++ __init_end = . + __KERNEL_TEXT_OFFSET;
44481 ++ KERNEL_TEXT_OFFSET = . + __KERNEL_TEXT_OFFSET;
44482 ++ _text = .; /* Text and read-only data */
44483 ++ *(.text.head)
44484 ++ } :text = 0x9090
44485 ++
44486 ++ /* read-only */
44487 ++ .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
44488 ++ . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
44489 ++ *(.text.page_aligned)
44490 ++ TEXT_TEXT
44491 ++ SCHED_TEXT
44492 ++ LOCK_TEXT
44493 ++ KPROBES_TEXT
44494 ++ *(.fixup)
44495 ++ *(.gnu.warning)
44496 ++ _etext = .; /* End of text section */
44497 ++ } :text = 0x9090
44498 ++
44499 ++ . += __KERNEL_TEXT_OFFSET;
44500 ++
44501 ++ . = ALIGN(4096); /* Exception table */
44502 ++ __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
44503 ++ __start___ex_table = .;
44504 ++ *(__ex_table)
44505 ++ __stop___ex_table = .;
44506 ++ } :rodata
44507 ++
44508 ++ NOTES :rodata :note
44509 ++
44510 ++ RO_DATA(PAGE_SIZE)
44511 ++
44512 ++ . = ALIGN(PAGE_SIZE);
44513 ++ .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
44514 ++ *(.idt)
44515 ++ . = ALIGN(PAGE_SIZE);
44516 ++ *(.empty_zero_page)
44517 ++ *(.swapper_pg_pmd)
44518 ++ *(.swapper_pg_dir)
44519 ++ }
44520 ++
44521 ++#ifdef CONFIG_PAX_KERNEXEC
44522 ++
44523 ++#ifdef CONFIG_MODULES
44524 ++ . = ALIGN(PAGE_SIZE);
44525 ++ .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
44526 ++ MODULES_VADDR = .;
44527 ++ BYTE(0)
44528 ++ . += (6 * 1024 * 1024);
44529 ++ . = ALIGN( PMD_SIZE) - 1;
44530 ++ MODULES_END = .;
44531 ++ }
44532 ++#else
44533 ++ . = ALIGN(PMD_SIZE) - 1;
44534 ++#endif
44535 ++
44536 ++#endif
44537 ++
44538 ++ /* writeable */
44539 ++ . = ALIGN(PAGE_SIZE);
44540 ++ .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
44541 ++ _data = .;
44542 ++ DATA_DATA
44543 ++ CONSTRUCTORS
44544 ++ } :data
44545 ++
44546 ++ . = ALIGN(PAGE_SIZE);
44547 ++ .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
44548 ++ __nosave_begin = .;
44549 ++ *(.data.nosave)
44550 ++ . = ALIGN(PAGE_SIZE);
44551 ++ __nosave_end = .;
44552 ++ }
44553 ++
44554 ++ . = ALIGN(PAGE_SIZE);
44555 ++ .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
44556 ++ *(.data.page_aligned)
44557 ++ }
44558 ++
44559 ++ . = ALIGN(32);
44560 ++ .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
44561 ++ *(.data.cacheline_aligned)
44562 ++ }
44563 ++
44564 ++ /* rarely changed data like cpu maps */
44565 ++ . = ALIGN(32);
44566 ++ .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
44567 ++ *(.data.read_mostly)
44568 ++ _edata = .; /* End of data section */
44569 ++ }
44570 ++
44571 ++ . = ALIGN(THREAD_SIZE); /* init_task */
44572 ++ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
44573 ++ *(.data.init_task)
44574 ++ }
44575 ++
44576 + .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
44577 +- __init_end = .;
44578 + __bss_start = .; /* BSS */
44579 + *(.bss.page_aligned)
44580 + *(.bss)
44581 +diff -urNp linux-2.6.27.7/arch/x86/kernel/vmlinux_64.lds.S linux-2.6.27.7/arch/x86/kernel/vmlinux_64.lds.S
44582 +--- linux-2.6.27.7/arch/x86/kernel/vmlinux_64.lds.S 2008-11-07 12:55:34.000000000 -0500
44583 ++++ linux-2.6.27.7/arch/x86/kernel/vmlinux_64.lds.S 2008-11-18 03:38:44.000000000 -0500
44584 +@@ -16,7 +16,7 @@ jiffies_64 = jiffies;
44585 + _proxy_pda = 1;
44586 + PHDRS {
44587 + text PT_LOAD FLAGS(5); /* R_E */
44588 +- data PT_LOAD FLAGS(7); /* RWE */
44589 ++ data PT_LOAD FLAGS(6); /* RW_ */
44590 + user PT_LOAD FLAGS(7); /* RWE */
44591 + data.init PT_LOAD FLAGS(7); /* RWE */
44592 + note PT_NOTE FLAGS(0); /* ___ */
44593 +@@ -49,17 +49,20 @@ SECTIONS
44594 + __stop___ex_table = .;
44595 + } :text = 0x9090
44596 +
44597 +- RODATA
44598 ++ RO_DATA(PAGE_SIZE)
44599 +
44600 ++#ifdef CONFIG_PAX_KERNEXEC
44601 ++ . = ALIGN(2*1024*1024); /* Align data segment to PMD size boundary */
44602 ++#else
44603 + . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */
44604 ++#endif
44605 + /* Data */
44606 ++ _data = .;
44607 + .data : AT(ADDR(.data) - LOAD_OFFSET) {
44608 + DATA_DATA
44609 + CONSTRUCTORS
44610 + } :data
44611 +
44612 +- _edata = .; /* End of data section */
44613 +-
44614 + . = ALIGN(PAGE_SIZE);
44615 + . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
44616 + .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
44617 +@@ -70,9 +73,27 @@ SECTIONS
44618 + *(.data.read_mostly)
44619 + }
44620 +
44621 ++ . = ALIGN(THREAD_SIZE); /* init_task */
44622 ++ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
44623 ++ *(.data.init_task)
44624 ++ }
44625 ++
44626 ++ . = ALIGN(PAGE_SIZE);
44627 ++ .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
44628 ++ *(.data.page_aligned)
44629 ++ }
44630 ++
44631 ++ . = ALIGN(PAGE_SIZE);
44632 ++ __nosave_begin = .;
44633 ++ .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
44634 ++ . = ALIGN(PAGE_SIZE);
44635 ++ __nosave_end = .;
44636 ++
44637 ++ _edata = .; /* End of data section */
44638 ++
44639 + #define VSYSCALL_ADDR (-10*1024*1024)
44640 +-#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
44641 +-#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
44642 ++#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
44643 ++#define VSYSCALL_VIRT_ADDR ((ADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
44644 +
44645 + #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
44646 + #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
44647 +@@ -120,23 +141,13 @@ SECTIONS
44648 + #undef VVIRT_OFFSET
44649 + #undef VVIRT
44650 +
44651 +- . = ALIGN(THREAD_SIZE); /* init_task */
44652 +- .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
44653 +- *(.data.init_task)
44654 +- }:data.init
44655 +-
44656 +- . = ALIGN(PAGE_SIZE);
44657 +- .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
44658 +- *(.data.page_aligned)
44659 +- }
44660 +-
44661 + /* might get freed after init */
44662 + . = ALIGN(PAGE_SIZE);
44663 + __smp_alt_begin = .;
44664 + __smp_locks = .;
44665 + .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
44666 + *(.smp_locks)
44667 +- }
44668 ++ } :data.init
44669 + __smp_locks_end = .;
44670 + . = ALIGN(PAGE_SIZE);
44671 + __smp_alt_end = .;
44672 +@@ -213,16 +224,11 @@ SECTIONS
44673 + . = ALIGN(PAGE_SIZE);
44674 + __init_end = .;
44675 +
44676 +- . = ALIGN(PAGE_SIZE);
44677 +- __nosave_begin = .;
44678 +- .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
44679 +- . = ALIGN(PAGE_SIZE);
44680 +- __nosave_end = .;
44681 +-
44682 + __bss_start = .; /* BSS */
44683 + .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
44684 + *(.bss.page_aligned)
44685 + *(.bss)
44686 ++ . = ALIGN(2*1024*1024);
44687 + }
44688 + __bss_stop = .;
44689 +
44690 +diff -urNp linux-2.6.27.7/arch/x86/kernel/vsyscall_64.c linux-2.6.27.7/arch/x86/kernel/vsyscall_64.c
44691 +--- linux-2.6.27.7/arch/x86/kernel/vsyscall_64.c 2008-11-07 12:55:34.000000000 -0500
44692 ++++ linux-2.6.27.7/arch/x86/kernel/vsyscall_64.c 2008-11-18 03:38:44.000000000 -0500
44693 +@@ -236,13 +236,13 @@ static ctl_table kernel_table2[] = {
44694 + .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int),
44695 + .mode = 0644,
44696 + .proc_handler = vsyscall_sysctl_change },
44697 +- {}
44698 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
44699 + };
44700 +
44701 + static ctl_table kernel_root_table2[] = {
44702 + { .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555,
44703 + .child = kernel_table2 },
44704 +- {}
44705 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
44706 + };
44707 + #endif
44708 +
44709 +diff -urNp linux-2.6.27.7/arch/x86/kvm/svm.c linux-2.6.27.7/arch/x86/kvm/svm.c
44710 +--- linux-2.6.27.7/arch/x86/kvm/svm.c 2008-11-07 12:55:34.000000000 -0500
44711 ++++ linux-2.6.27.7/arch/x86/kvm/svm.c 2008-11-18 03:38:44.000000000 -0500
44712 +@@ -1515,7 +1515,19 @@ static void reload_tss(struct kvm_vcpu *
44713 + int cpu = raw_smp_processor_id();
44714 +
44715 + struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu);
44716 ++
44717 ++#ifdef CONFIG_PAX_KERNEXEC
44718 ++ unsigned long cr0;
44719 ++
44720 ++ pax_open_kernel(cr0);
44721 ++#endif
44722 ++
44723 + svm_data->tss_desc->type = 9; /* available 32/64-bit TSS */
44724 ++
44725 ++#ifdef CONFIG_PAX_KERNEXEC
44726 ++ pax_close_kernel(cr0);
44727 ++#endif
44728 ++
44729 + load_TR_desc();
44730 + }
44731 +
44732 +diff -urNp linux-2.6.27.7/arch/x86/kvm/vmx.c linux-2.6.27.7/arch/x86/kvm/vmx.c
44733 +--- linux-2.6.27.7/arch/x86/kvm/vmx.c 2008-11-07 12:55:34.000000000 -0500
44734 ++++ linux-2.6.27.7/arch/x86/kvm/vmx.c 2008-11-18 03:38:44.000000000 -0500
44735 +@@ -115,7 +115,7 @@ static struct vmcs_config {
44736 + u32 vmentry_ctrl;
44737 + } vmcs_config;
44738 +
44739 +-struct vmx_capability {
44740 ++static struct vmx_capability {
44741 + u32 ept;
44742 + u32 vpid;
44743 + } vmx_capability;
44744 +@@ -484,9 +484,23 @@ static void reload_tss(void)
44745 + struct descriptor_table gdt;
44746 + struct desc_struct *descs;
44747 +
44748 ++#ifdef CONFIG_PAX_KERNEXEC
44749 ++ unsigned long cr0;
44750 ++#endif
44751 ++
44752 + kvm_get_gdt(&gdt);
44753 + descs = (void *)gdt.base;
44754 ++
44755 ++#ifdef CONFIG_PAX_KERNEXEC
44756 ++ pax_open_kernel(cr0);
44757 ++#endif
44758 ++
44759 + descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
44760 ++
44761 ++#ifdef CONFIG_PAX_KERNEXEC
44762 ++ pax_close_kernel(cr0);
44763 ++#endif
44764 ++
44765 + load_TR_desc();
44766 + }
44767 +
44768 +@@ -3069,7 +3083,7 @@ static void vmx_vcpu_run(struct kvm_vcpu
44769 + (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
44770 + (GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS)) == 0;
44771 +
44772 +- asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
44773 ++ asm("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS));
44774 + vmx->launched = 1;
44775 +
44776 + intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
44777 +diff -urNp linux-2.6.27.7/arch/x86/kvm/x86.c linux-2.6.27.7/arch/x86/kvm/x86.c
44778 +--- linux-2.6.27.7/arch/x86/kvm/x86.c 2008-11-07 12:55:34.000000000 -0500
44779 ++++ linux-2.6.27.7/arch/x86/kvm/x86.c 2008-11-18 03:38:44.000000000 -0500
44780 +@@ -63,35 +63,35 @@ static int kvm_dev_ioctl_get_supported_c
44781 + struct kvm_x86_ops *kvm_x86_ops;
44782 +
44783 + struct kvm_stats_debugfs_item debugfs_entries[] = {
44784 +- { "pf_fixed", VCPU_STAT(pf_fixed) },
44785 +- { "pf_guest", VCPU_STAT(pf_guest) },
44786 +- { "tlb_flush", VCPU_STAT(tlb_flush) },
44787 +- { "invlpg", VCPU_STAT(invlpg) },
44788 +- { "exits", VCPU_STAT(exits) },
44789 +- { "io_exits", VCPU_STAT(io_exits) },
44790 +- { "mmio_exits", VCPU_STAT(mmio_exits) },
44791 +- { "signal_exits", VCPU_STAT(signal_exits) },
44792 +- { "irq_window", VCPU_STAT(irq_window_exits) },
44793 +- { "nmi_window", VCPU_STAT(nmi_window_exits) },
44794 +- { "halt_exits", VCPU_STAT(halt_exits) },
44795 +- { "halt_wakeup", VCPU_STAT(halt_wakeup) },
44796 +- { "hypercalls", VCPU_STAT(hypercalls) },
44797 +- { "request_irq", VCPU_STAT(request_irq_exits) },
44798 +- { "irq_exits", VCPU_STAT(irq_exits) },
44799 +- { "host_state_reload", VCPU_STAT(host_state_reload) },
44800 +- { "efer_reload", VCPU_STAT(efer_reload) },
44801 +- { "fpu_reload", VCPU_STAT(fpu_reload) },
44802 +- { "insn_emulation", VCPU_STAT(insn_emulation) },
44803 +- { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail) },
44804 +- { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped) },
44805 +- { "mmu_pte_write", VM_STAT(mmu_pte_write) },
44806 +- { "mmu_pte_updated", VM_STAT(mmu_pte_updated) },
44807 +- { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped) },
44808 +- { "mmu_flooded", VM_STAT(mmu_flooded) },
44809 +- { "mmu_recycled", VM_STAT(mmu_recycled) },
44810 +- { "mmu_cache_miss", VM_STAT(mmu_cache_miss) },
44811 +- { "remote_tlb_flush", VM_STAT(remote_tlb_flush) },
44812 +- { "largepages", VM_STAT(lpages) },
44813 ++ { "pf_fixed", VCPU_STAT(pf_fixed), NULL },
44814 ++ { "pf_guest", VCPU_STAT(pf_guest), NULL },
44815 ++ { "tlb_flush", VCPU_STAT(tlb_flush), NULL },
44816 ++ { "invlpg", VCPU_STAT(invlpg), NULL },
44817 ++ { "exits", VCPU_STAT(exits), NULL },
44818 ++ { "io_exits", VCPU_STAT(io_exits), NULL },
44819 ++ { "mmio_exits", VCPU_STAT(mmio_exits), NULL },
44820 ++ { "signal_exits", VCPU_STAT(signal_exits), NULL },
44821 ++ { "irq_window", VCPU_STAT(irq_window_exits), NULL },
44822 ++ { "nmi_window", VCPU_STAT(nmi_window_exits), NULL },
44823 ++ { "halt_exits", VCPU_STAT(halt_exits), NULL },
44824 ++ { "halt_wakeup", VCPU_STAT(halt_wakeup), NULL },
44825 ++ { "hypercalls", VCPU_STAT(hypercalls), NULL },
44826 ++ { "request_irq", VCPU_STAT(request_irq_exits), NULL },
44827 ++ { "irq_exits", VCPU_STAT(irq_exits), NULL },
44828 ++ { "host_state_reload", VCPU_STAT(host_state_reload), NULL },
44829 ++ { "efer_reload", VCPU_STAT(efer_reload), NULL },
44830 ++ { "fpu_reload", VCPU_STAT(fpu_reload), NULL },
44831 ++ { "insn_emulation", VCPU_STAT(insn_emulation), NULL },
44832 ++ { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail), NULL },
44833 ++ { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped), NULL },
44834 ++ { "mmu_pte_write", VM_STAT(mmu_pte_write), NULL },
44835 ++ { "mmu_pte_updated", VM_STAT(mmu_pte_updated), NULL },
44836 ++ { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped), NULL },
44837 ++ { "mmu_flooded", VM_STAT(mmu_flooded), NULL },
44838 ++ { "mmu_recycled", VM_STAT(mmu_recycled), NULL },
44839 ++ { "mmu_cache_miss", VM_STAT(mmu_cache_miss), NULL },
44840 ++ { "remote_tlb_flush", VM_STAT(remote_tlb_flush), NULL },
44841 ++ { "largepages", VM_STAT(lpages), NULL },
44842 + { NULL }
44843 + };
44844 +
44845 +@@ -1274,7 +1274,7 @@ static int kvm_vcpu_ioctl_set_lapic(stru
44846 + static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
44847 + struct kvm_interrupt *irq)
44848 + {
44849 +- if (irq->irq < 0 || irq->irq >= 256)
44850 ++ if (irq->irq >= 256)
44851 + return -EINVAL;
44852 + if (irqchip_in_kernel(vcpu->kvm))
44853 + return -ENXIO;
44854 +diff -urNp linux-2.6.27.7/arch/x86/lib/checksum_32.S linux-2.6.27.7/arch/x86/lib/checksum_32.S
44855 +--- linux-2.6.27.7/arch/x86/lib/checksum_32.S 2008-11-07 12:55:34.000000000 -0500
44856 ++++ linux-2.6.27.7/arch/x86/lib/checksum_32.S 2008-11-18 03:38:44.000000000 -0500
44857 +@@ -28,7 +28,8 @@
44858 + #include <linux/linkage.h>
44859 + #include <asm/dwarf2.h>
44860 + #include <asm/errno.h>
44861 +-
44862 ++#include <asm/segment.h>
44863 ++
44864 + /*
44865 + * computes a partial checksum, e.g. for TCP/UDP fragments
44866 + */
44867 +@@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic (
44868 +
44869 + #define ARGBASE 16
44870 + #define FP 12
44871 +-
44872 +-ENTRY(csum_partial_copy_generic)
44873 ++
44874 ++ENTRY(csum_partial_copy_generic_to_user)
44875 + CFI_STARTPROC
44876 ++ pushl $(__USER_DS)
44877 ++ CFI_ADJUST_CFA_OFFSET 4
44878 ++ popl %es
44879 ++ CFI_ADJUST_CFA_OFFSET -4
44880 ++ jmp csum_partial_copy_generic
44881 ++
44882 ++ENTRY(csum_partial_copy_generic_from_user)
44883 ++ pushl $(__USER_DS)
44884 ++ CFI_ADJUST_CFA_OFFSET 4
44885 ++ popl %ds
44886 ++ CFI_ADJUST_CFA_OFFSET -4
44887 ++
44888 ++ENTRY(csum_partial_copy_generic)
44889 + subl $4,%esp
44890 + CFI_ADJUST_CFA_OFFSET 4
44891 + pushl %edi
44892 +@@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic)
44893 + jmp 4f
44894 + SRC(1: movw (%esi), %bx )
44895 + addl $2, %esi
44896 +-DST( movw %bx, (%edi) )
44897 ++DST( movw %bx, %es:(%edi) )
44898 + addl $2, %edi
44899 + addw %bx, %ax
44900 + adcl $0, %eax
44901 +@@ -343,30 +357,30 @@ DST( movw %bx, (%edi) )
44902 + SRC(1: movl (%esi), %ebx )
44903 + SRC( movl 4(%esi), %edx )
44904 + adcl %ebx, %eax
44905 +-DST( movl %ebx, (%edi) )
44906 ++DST( movl %ebx, %es:(%edi) )
44907 + adcl %edx, %eax
44908 +-DST( movl %edx, 4(%edi) )
44909 ++DST( movl %edx, %es:4(%edi) )
44910 +
44911 + SRC( movl 8(%esi), %ebx )
44912 + SRC( movl 12(%esi), %edx )
44913 + adcl %ebx, %eax
44914 +-DST( movl %ebx, 8(%edi) )
44915 ++DST( movl %ebx, %es:8(%edi) )
44916 + adcl %edx, %eax
44917 +-DST( movl %edx, 12(%edi) )
44918 ++DST( movl %edx, %es:12(%edi) )
44919 +
44920 + SRC( movl 16(%esi), %ebx )
44921 + SRC( movl 20(%esi), %edx )
44922 + adcl %ebx, %eax
44923 +-DST( movl %ebx, 16(%edi) )
44924 ++DST( movl %ebx, %es:16(%edi) )
44925 + adcl %edx, %eax
44926 +-DST( movl %edx, 20(%edi) )
44927 ++DST( movl %edx, %es:20(%edi) )
44928 +
44929 + SRC( movl 24(%esi), %ebx )
44930 + SRC( movl 28(%esi), %edx )
44931 + adcl %ebx, %eax
44932 +-DST( movl %ebx, 24(%edi) )
44933 ++DST( movl %ebx, %es:24(%edi) )
44934 + adcl %edx, %eax
44935 +-DST( movl %edx, 28(%edi) )
44936 ++DST( movl %edx, %es:28(%edi) )
44937 +
44938 + lea 32(%esi), %esi
44939 + lea 32(%edi), %edi
44940 +@@ -380,7 +394,7 @@ DST( movl %edx, 28(%edi) )
44941 + shrl $2, %edx # This clears CF
44942 + SRC(3: movl (%esi), %ebx )
44943 + adcl %ebx, %eax
44944 +-DST( movl %ebx, (%edi) )
44945 ++DST( movl %ebx, %es:(%edi) )
44946 + lea 4(%esi), %esi
44947 + lea 4(%edi), %edi
44948 + dec %edx
44949 +@@ -392,12 +406,12 @@ DST( movl %ebx, (%edi) )
44950 + jb 5f
44951 + SRC( movw (%esi), %cx )
44952 + leal 2(%esi), %esi
44953 +-DST( movw %cx, (%edi) )
44954 ++DST( movw %cx, %es:(%edi) )
44955 + leal 2(%edi), %edi
44956 + je 6f
44957 + shll $16,%ecx
44958 + SRC(5: movb (%esi), %cl )
44959 +-DST( movb %cl, (%edi) )
44960 ++DST( movb %cl, %es:(%edi) )
44961 + 6: addl %ecx, %eax
44962 + adcl $0, %eax
44963 + 7:
44964 +@@ -408,7 +422,7 @@ DST( movb %cl, (%edi) )
44965 +
44966 + 6001:
44967 + movl ARGBASE+20(%esp), %ebx # src_err_ptr
44968 +- movl $-EFAULT, (%ebx)
44969 ++ movl $-EFAULT, %ss:(%ebx)
44970 +
44971 + # zero the complete destination - computing the rest
44972 + # is too much work
44973 +@@ -421,11 +435,19 @@ DST( movb %cl, (%edi) )
44974 +
44975 + 6002:
44976 + movl ARGBASE+24(%esp), %ebx # dst_err_ptr
44977 +- movl $-EFAULT,(%ebx)
44978 ++ movl $-EFAULT,%ss:(%ebx)
44979 + jmp 5000b
44980 +
44981 + .previous
44982 +
44983 ++ pushl %ss
44984 ++ CFI_ADJUST_CFA_OFFSET 4
44985 ++ popl %ds
44986 ++ CFI_ADJUST_CFA_OFFSET -4
44987 ++ pushl %ss
44988 ++ CFI_ADJUST_CFA_OFFSET 4
44989 ++ popl %es
44990 ++ CFI_ADJUST_CFA_OFFSET -4
44991 + popl %ebx
44992 + CFI_ADJUST_CFA_OFFSET -4
44993 + CFI_RESTORE ebx
44994 +@@ -439,26 +461,41 @@ DST( movb %cl, (%edi) )
44995 + CFI_ADJUST_CFA_OFFSET -4
44996 + ret
44997 + CFI_ENDPROC
44998 +-ENDPROC(csum_partial_copy_generic)
44999 ++ENDPROC(csum_partial_copy_generic_to_user)
45000 +
45001 + #else
45002 +
45003 + /* Version for PentiumII/PPro */
45004 +
45005 + #define ROUND1(x) \
45006 ++ nop; nop; nop; \
45007 + SRC(movl x(%esi), %ebx ) ; \
45008 + addl %ebx, %eax ; \
45009 +- DST(movl %ebx, x(%edi) ) ;
45010 ++ DST(movl %ebx, %es:x(%edi)) ;
45011 +
45012 + #define ROUND(x) \
45013 ++ nop; nop; nop; \
45014 + SRC(movl x(%esi), %ebx ) ; \
45015 + adcl %ebx, %eax ; \
45016 +- DST(movl %ebx, x(%edi) ) ;
45017 ++ DST(movl %ebx, %es:x(%edi)) ;
45018 +
45019 + #define ARGBASE 12
45020 +-
45021 +-ENTRY(csum_partial_copy_generic)
45022 ++
45023 ++ENTRY(csum_partial_copy_generic_to_user)
45024 + CFI_STARTPROC
45025 ++ pushl $(__USER_DS)
45026 ++ CFI_ADJUST_CFA_OFFSET 4
45027 ++ popl %es
45028 ++ CFI_ADJUST_CFA_OFFSET -4
45029 ++ jmp csum_partial_copy_generic
45030 ++
45031 ++ENTRY(csum_partial_copy_generic_from_user)
45032 ++ pushl $(__USER_DS)
45033 ++ CFI_ADJUST_CFA_OFFSET 4
45034 ++ popl %ds
45035 ++ CFI_ADJUST_CFA_OFFSET -4
45036 ++
45037 ++ENTRY(csum_partial_copy_generic)
45038 + pushl %ebx
45039 + CFI_ADJUST_CFA_OFFSET 4
45040 + CFI_REL_OFFSET ebx, 0
45041 +@@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic)
45042 + subl %ebx, %edi
45043 + lea -1(%esi),%edx
45044 + andl $-32,%edx
45045 +- lea 3f(%ebx,%ebx), %ebx
45046 ++ lea 3f(%ebx,%ebx,2), %ebx
45047 + testl %esi, %esi
45048 + jmp *%ebx
45049 + 1: addl $64,%esi
45050 +@@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic)
45051 + jb 5f
45052 + SRC( movw (%esi), %dx )
45053 + leal 2(%esi), %esi
45054 +-DST( movw %dx, (%edi) )
45055 ++DST( movw %dx, %es:(%edi) )
45056 + leal 2(%edi), %edi
45057 + je 6f
45058 + shll $16,%edx
45059 + 5:
45060 + SRC( movb (%esi), %dl )
45061 +-DST( movb %dl, (%edi) )
45062 ++DST( movb %dl, %es:(%edi) )
45063 + 6: addl %edx, %eax
45064 + adcl $0, %eax
45065 + 7:
45066 + .section .fixup, "ax"
45067 + 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
45068 +- movl $-EFAULT, (%ebx)
45069 ++ movl $-EFAULT, %ss:(%ebx)
45070 + # zero the complete destination (computing the rest is too much work)
45071 + movl ARGBASE+8(%esp),%edi # dst
45072 + movl ARGBASE+12(%esp),%ecx # len
45073 +@@ -523,10 +560,18 @@ DST( movb %dl, (%edi) )
45074 + rep; stosb
45075 + jmp 7b
45076 + 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
45077 +- movl $-EFAULT, (%ebx)
45078 ++ movl $-EFAULT, %ss:(%ebx)
45079 + jmp 7b
45080 + .previous
45081 +
45082 ++ pushl %ss
45083 ++ CFI_ADJUST_CFA_OFFSET 4
45084 ++ popl %ds
45085 ++ CFI_ADJUST_CFA_OFFSET -4
45086 ++ pushl %ss
45087 ++ CFI_ADJUST_CFA_OFFSET 4
45088 ++ popl %es
45089 ++ CFI_ADJUST_CFA_OFFSET -4
45090 + popl %esi
45091 + CFI_ADJUST_CFA_OFFSET -4
45092 + CFI_RESTORE esi
45093 +@@ -538,7 +583,7 @@ DST( movb %dl, (%edi) )
45094 + CFI_RESTORE ebx
45095 + ret
45096 + CFI_ENDPROC
45097 +-ENDPROC(csum_partial_copy_generic)
45098 ++ENDPROC(csum_partial_copy_generic_to_user)
45099 +
45100 + #undef ROUND
45101 + #undef ROUND1
45102 +diff -urNp linux-2.6.27.7/arch/x86/lib/clear_page_64.S linux-2.6.27.7/arch/x86/lib/clear_page_64.S
45103 +--- linux-2.6.27.7/arch/x86/lib/clear_page_64.S 2008-11-07 12:55:34.000000000 -0500
45104 ++++ linux-2.6.27.7/arch/x86/lib/clear_page_64.S 2008-11-18 03:38:44.000000000 -0500
45105 +@@ -44,7 +44,7 @@ ENDPROC(clear_page)
45106 +
45107 + #include <asm/cpufeature.h>
45108 +
45109 +- .section .altinstr_replacement,"ax"
45110 ++ .section .altinstr_replacement,"a"
45111 + 1: .byte 0xeb /* jmp <disp8> */
45112 + .byte (clear_page_c - clear_page) - (2f - 1b) /* offset */
45113 + 2:
45114 +diff -urNp linux-2.6.27.7/arch/x86/lib/copy_page_64.S linux-2.6.27.7/arch/x86/lib/copy_page_64.S
45115 +--- linux-2.6.27.7/arch/x86/lib/copy_page_64.S 2008-11-07 12:55:34.000000000 -0500
45116 ++++ linux-2.6.27.7/arch/x86/lib/copy_page_64.S 2008-11-18 03:38:44.000000000 -0500
45117 +@@ -104,7 +104,7 @@ ENDPROC(copy_page)
45118 +
45119 + #include <asm/cpufeature.h>
45120 +
45121 +- .section .altinstr_replacement,"ax"
45122 ++ .section .altinstr_replacement,"a"
45123 + 1: .byte 0xeb /* jmp <disp8> */
45124 + .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */
45125 + 2:
45126 +diff -urNp linux-2.6.27.7/arch/x86/lib/copy_user_64.S linux-2.6.27.7/arch/x86/lib/copy_user_64.S
45127 +--- linux-2.6.27.7/arch/x86/lib/copy_user_64.S 2008-11-07 12:55:34.000000000 -0500
45128 ++++ linux-2.6.27.7/arch/x86/lib/copy_user_64.S 2008-11-18 03:38:44.000000000 -0500
45129 +@@ -21,7 +21,7 @@
45130 + .byte 0xe9 /* 32bit jump */
45131 + .long \orig-1f /* by default jump to orig */
45132 + 1:
45133 +- .section .altinstr_replacement,"ax"
45134 ++ .section .altinstr_replacement,"a"
45135 + 2: .byte 0xe9 /* near jump with 32bit immediate */
45136 + .long \alt-1b /* offset */ /* or alternatively to alt */
45137 + .previous
45138 +@@ -106,6 +106,8 @@ ENDPROC(__copy_from_user_inatomic)
45139 + ENTRY(bad_from_user)
45140 + bad_from_user:
45141 + CFI_STARTPROC
45142 ++ testl %edx,%edx
45143 ++ js bad_to_user
45144 + movl %edx,%ecx
45145 + xorl %eax,%eax
45146 + rep
45147 +diff -urNp linux-2.6.27.7/arch/x86/lib/getuser.S linux-2.6.27.7/arch/x86/lib/getuser.S
45148 +--- linux-2.6.27.7/arch/x86/lib/getuser.S 2008-11-07 12:55:34.000000000 -0500
45149 ++++ linux-2.6.27.7/arch/x86/lib/getuser.S 2008-11-18 03:38:44.000000000 -0500
45150 +@@ -33,6 +33,7 @@
45151 + #include <asm/asm-offsets.h>
45152 + #include <asm/thread_info.h>
45153 + #include <asm/asm.h>
45154 ++#include <asm/segment.h>
45155 +
45156 + .text
45157 + ENTRY(__get_user_1)
45158 +@@ -40,7 +41,19 @@ ENTRY(__get_user_1)
45159 + GET_THREAD_INFO(%_ASM_DX)
45160 + cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
45161 + jae bad_get_user
45162 ++
45163 ++#ifdef CONFIG_X86_32
45164 ++ pushl $(__USER_DS)
45165 ++ popl %ds
45166 ++#endif
45167 ++
45168 + 1: movzb (%_ASM_AX),%edx
45169 ++
45170 ++#ifdef CONFIG_X86_32
45171 ++ pushl %ss
45172 ++ pop %ds
45173 ++#endif
45174 ++
45175 + xor %eax,%eax
45176 + ret
45177 + CFI_ENDPROC
45178 +@@ -53,7 +66,19 @@ ENTRY(__get_user_2)
45179 + GET_THREAD_INFO(%_ASM_DX)
45180 + cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
45181 + jae bad_get_user
45182 ++
45183 ++#ifdef CONFIG_X86_32
45184 ++ pushl $(__USER_DS)
45185 ++ popl %ds
45186 ++#endif
45187 ++
45188 + 2: movzwl -1(%_ASM_AX),%edx
45189 ++
45190 ++#ifdef CONFIG_X86_32
45191 ++ pushl %ss
45192 ++ pop %ds
45193 ++#endif
45194 ++
45195 + xor %eax,%eax
45196 + ret
45197 + CFI_ENDPROC
45198 +@@ -66,7 +91,19 @@ ENTRY(__get_user_4)
45199 + GET_THREAD_INFO(%_ASM_DX)
45200 + cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
45201 + jae bad_get_user
45202 ++
45203 ++#ifdef CONFIG_X86_32
45204 ++ pushl $(__USER_DS)
45205 ++ popl %ds
45206 ++#endif
45207 ++
45208 + 3: mov -3(%_ASM_AX),%edx
45209 ++
45210 ++#ifdef CONFIG_X86_32
45211 ++ pushl %ss
45212 ++ pop %ds
45213 ++#endif
45214 ++
45215 + xor %eax,%eax
45216 + ret
45217 + CFI_ENDPROC
45218 +@@ -89,6 +126,12 @@ ENDPROC(__get_user_8)
45219 +
45220 + bad_get_user:
45221 + CFI_STARTPROC
45222 ++
45223 ++#ifdef CONFIG_X86_32
45224 ++ pushl %ss
45225 ++ pop %ds
45226 ++#endif
45227 ++
45228 + xor %edx,%edx
45229 + mov $(-EFAULT),%_ASM_AX
45230 + ret
45231 +diff -urNp linux-2.6.27.7/arch/x86/lib/memcpy_64.S linux-2.6.27.7/arch/x86/lib/memcpy_64.S
45232 +--- linux-2.6.27.7/arch/x86/lib/memcpy_64.S 2008-11-07 12:55:34.000000000 -0500
45233 ++++ linux-2.6.27.7/arch/x86/lib/memcpy_64.S 2008-11-18 03:38:44.000000000 -0500
45234 +@@ -114,7 +114,7 @@ ENDPROC(__memcpy)
45235 + /* Some CPUs run faster using the string copy instructions.
45236 + It is also a lot simpler. Use this when possible */
45237 +
45238 +- .section .altinstr_replacement,"ax"
45239 ++ .section .altinstr_replacement,"a"
45240 + 1: .byte 0xeb /* jmp <disp8> */
45241 + .byte (memcpy_c - memcpy) - (2f - 1b) /* offset */
45242 + 2:
45243 +diff -urNp linux-2.6.27.7/arch/x86/lib/memset_64.S linux-2.6.27.7/arch/x86/lib/memset_64.S
45244 +--- linux-2.6.27.7/arch/x86/lib/memset_64.S 2008-11-07 12:55:34.000000000 -0500
45245 ++++ linux-2.6.27.7/arch/x86/lib/memset_64.S 2008-11-18 03:38:44.000000000 -0500
45246 +@@ -118,7 +118,7 @@ ENDPROC(__memset)
45247 +
45248 + #include <asm/cpufeature.h>
45249 +
45250 +- .section .altinstr_replacement,"ax"
45251 ++ .section .altinstr_replacement,"a"
45252 + 1: .byte 0xeb /* jmp <disp8> */
45253 + .byte (memset_c - memset) - (2f - 1b) /* offset */
45254 + 2:
45255 +diff -urNp linux-2.6.27.7/arch/x86/lib/mmx_32.c linux-2.6.27.7/arch/x86/lib/mmx_32.c
45256 +--- linux-2.6.27.7/arch/x86/lib/mmx_32.c 2008-11-07 12:55:34.000000000 -0500
45257 ++++ linux-2.6.27.7/arch/x86/lib/mmx_32.c 2008-11-18 03:38:44.000000000 -0500
45258 +@@ -29,6 +29,7 @@ void *_mmx_memcpy(void *to, const void *
45259 + {
45260 + void *p;
45261 + int i;
45262 ++ unsigned long cr0;
45263 +
45264 + if (unlikely(in_interrupt()))
45265 + return __memcpy(to, from, len);
45266 +@@ -39,44 +40,72 @@ void *_mmx_memcpy(void *to, const void *
45267 + kernel_fpu_begin();
45268 +
45269 + __asm__ __volatile__ (
45270 +- "1: prefetch (%0)\n" /* This set is 28 bytes */
45271 +- " prefetch 64(%0)\n"
45272 +- " prefetch 128(%0)\n"
45273 +- " prefetch 192(%0)\n"
45274 +- " prefetch 256(%0)\n"
45275 ++ "1: prefetch (%1)\n" /* This set is 28 bytes */
45276 ++ " prefetch 64(%1)\n"
45277 ++ " prefetch 128(%1)\n"
45278 ++ " prefetch 192(%1)\n"
45279 ++ " prefetch 256(%1)\n"
45280 + "2: \n"
45281 + ".section .fixup, \"ax\"\n"
45282 +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
45283 ++ "3: \n"
45284 ++
45285 ++#ifdef CONFIG_PAX_KERNEXEC
45286 ++ " movl %%cr0, %0\n"
45287 ++ " movl %0, %%eax\n"
45288 ++ " andl $0xFFFEFFFF, %%eax\n"
45289 ++ " movl %%eax, %%cr0\n"
45290 ++#endif
45291 ++
45292 ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
45293 ++
45294 ++#ifdef CONFIG_PAX_KERNEXEC
45295 ++ " movl %0, %%cr0\n"
45296 ++#endif
45297 ++
45298 + " jmp 2b\n"
45299 + ".previous\n"
45300 + _ASM_EXTABLE(1b, 3b)
45301 +- : : "r" (from));
45302 ++ : "=&r" (cr0) : "r" (from) : "ax");
45303 +
45304 + for ( ; i > 5; i--) {
45305 + __asm__ __volatile__ (
45306 +- "1: prefetch 320(%0)\n"
45307 +- "2: movq (%0), %%mm0\n"
45308 +- " movq 8(%0), %%mm1\n"
45309 +- " movq 16(%0), %%mm2\n"
45310 +- " movq 24(%0), %%mm3\n"
45311 +- " movq %%mm0, (%1)\n"
45312 +- " movq %%mm1, 8(%1)\n"
45313 +- " movq %%mm2, 16(%1)\n"
45314 +- " movq %%mm3, 24(%1)\n"
45315 +- " movq 32(%0), %%mm0\n"
45316 +- " movq 40(%0), %%mm1\n"
45317 +- " movq 48(%0), %%mm2\n"
45318 +- " movq 56(%0), %%mm3\n"
45319 +- " movq %%mm0, 32(%1)\n"
45320 +- " movq %%mm1, 40(%1)\n"
45321 +- " movq %%mm2, 48(%1)\n"
45322 +- " movq %%mm3, 56(%1)\n"
45323 ++ "1: prefetch 320(%1)\n"
45324 ++ "2: movq (%1), %%mm0\n"
45325 ++ " movq 8(%1), %%mm1\n"
45326 ++ " movq 16(%1), %%mm2\n"
45327 ++ " movq 24(%1), %%mm3\n"
45328 ++ " movq %%mm0, (%2)\n"
45329 ++ " movq %%mm1, 8(%2)\n"
45330 ++ " movq %%mm2, 16(%2)\n"
45331 ++ " movq %%mm3, 24(%2)\n"
45332 ++ " movq 32(%1), %%mm0\n"
45333 ++ " movq 40(%1), %%mm1\n"
45334 ++ " movq 48(%1), %%mm2\n"
45335 ++ " movq 56(%1), %%mm3\n"
45336 ++ " movq %%mm0, 32(%2)\n"
45337 ++ " movq %%mm1, 40(%2)\n"
45338 ++ " movq %%mm2, 48(%2)\n"
45339 ++ " movq %%mm3, 56(%2)\n"
45340 + ".section .fixup, \"ax\"\n"
45341 +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
45342 ++ "3:\n"
45343 ++
45344 ++#ifdef CONFIG_PAX_KERNEXEC
45345 ++ " movl %%cr0, %0\n"
45346 ++ " movl %0, %%eax\n"
45347 ++ " andl $0xFFFEFFFF, %%eax\n"
45348 ++ " movl %%eax, %%cr0\n"
45349 ++#endif
45350 ++
45351 ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
45352 ++
45353 ++#ifdef CONFIG_PAX_KERNEXEC
45354 ++ " movl %0, %%cr0\n"
45355 ++#endif
45356 ++
45357 + " jmp 2b\n"
45358 + ".previous\n"
45359 + _ASM_EXTABLE(1b, 3b)
45360 +- : : "r" (from), "r" (to) : "memory");
45361 ++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
45362 +
45363 + from += 64;
45364 + to += 64;
45365 +@@ -158,6 +187,7 @@ static void fast_clear_page(void *page)
45366 + static void fast_copy_page(void *to, void *from)
45367 + {
45368 + int i;
45369 ++ unsigned long cr0;
45370 +
45371 + kernel_fpu_begin();
45372 +
45373 +@@ -166,42 +196,70 @@ static void fast_copy_page(void *to, voi
45374 + * but that is for later. -AV
45375 + */
45376 + __asm__ __volatile__(
45377 +- "1: prefetch (%0)\n"
45378 +- " prefetch 64(%0)\n"
45379 +- " prefetch 128(%0)\n"
45380 +- " prefetch 192(%0)\n"
45381 +- " prefetch 256(%0)\n"
45382 ++ "1: prefetch (%1)\n"
45383 ++ " prefetch 64(%1)\n"
45384 ++ " prefetch 128(%1)\n"
45385 ++ " prefetch 192(%1)\n"
45386 ++ " prefetch 256(%1)\n"
45387 + "2: \n"
45388 + ".section .fixup, \"ax\"\n"
45389 +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
45390 ++ "3: \n"
45391 ++
45392 ++#ifdef CONFIG_PAX_KERNEXEC
45393 ++ " movl %%cr0, %0\n"
45394 ++ " movl %0, %%eax\n"
45395 ++ " andl $0xFFFEFFFF, %%eax\n"
45396 ++ " movl %%eax, %%cr0\n"
45397 ++#endif
45398 ++
45399 ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
45400 ++
45401 ++#ifdef CONFIG_PAX_KERNEXEC
45402 ++ " movl %0, %%cr0\n"
45403 ++#endif
45404 ++
45405 + " jmp 2b\n"
45406 + ".previous\n"
45407 +- _ASM_EXTABLE(1b, 3b) : : "r" (from));
45408 ++ _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
45409 +
45410 + for (i = 0; i < (4096-320)/64; i++) {
45411 + __asm__ __volatile__ (
45412 +- "1: prefetch 320(%0)\n"
45413 +- "2: movq (%0), %%mm0\n"
45414 +- " movntq %%mm0, (%1)\n"
45415 +- " movq 8(%0), %%mm1\n"
45416 +- " movntq %%mm1, 8(%1)\n"
45417 +- " movq 16(%0), %%mm2\n"
45418 +- " movntq %%mm2, 16(%1)\n"
45419 +- " movq 24(%0), %%mm3\n"
45420 +- " movntq %%mm3, 24(%1)\n"
45421 +- " movq 32(%0), %%mm4\n"
45422 +- " movntq %%mm4, 32(%1)\n"
45423 +- " movq 40(%0), %%mm5\n"
45424 +- " movntq %%mm5, 40(%1)\n"
45425 +- " movq 48(%0), %%mm6\n"
45426 +- " movntq %%mm6, 48(%1)\n"
45427 +- " movq 56(%0), %%mm7\n"
45428 +- " movntq %%mm7, 56(%1)\n"
45429 ++ "1: prefetch 320(%1)\n"
45430 ++ "2: movq (%1), %%mm0\n"
45431 ++ " movntq %%mm0, (%2)\n"
45432 ++ " movq 8(%1), %%mm1\n"
45433 ++ " movntq %%mm1, 8(%2)\n"
45434 ++ " movq 16(%1), %%mm2\n"
45435 ++ " movntq %%mm2, 16(%2)\n"
45436 ++ " movq 24(%1), %%mm3\n"
45437 ++ " movntq %%mm3, 24(%2)\n"
45438 ++ " movq 32(%1), %%mm4\n"
45439 ++ " movntq %%mm4, 32(%2)\n"
45440 ++ " movq 40(%1), %%mm5\n"
45441 ++ " movntq %%mm5, 40(%2)\n"
45442 ++ " movq 48(%1), %%mm6\n"
45443 ++ " movntq %%mm6, 48(%2)\n"
45444 ++ " movq 56(%1), %%mm7\n"
45445 ++ " movntq %%mm7, 56(%2)\n"
45446 + ".section .fixup, \"ax\"\n"
45447 +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
45448 ++ "3:\n"
45449 ++
45450 ++#ifdef CONFIG_PAX_KERNEXEC
45451 ++ " movl %%cr0, %0\n"
45452 ++ " movl %0, %%eax\n"
45453 ++ " andl $0xFFFEFFFF, %%eax\n"
45454 ++ " movl %%eax, %%cr0\n"
45455 ++#endif
45456 ++
45457 ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
45458 ++
45459 ++#ifdef CONFIG_PAX_KERNEXEC
45460 ++ " movl %0, %%cr0\n"
45461 ++#endif
45462 ++
45463 + " jmp 2b\n"
45464 + ".previous\n"
45465 +- _ASM_EXTABLE(1b, 3b) : : "r" (from), "r" (to) : "memory");
45466 ++ _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
45467 +
45468 + from += 64;
45469 + to += 64;
45470 +@@ -280,47 +338,76 @@ static void fast_clear_page(void *page)
45471 + static void fast_copy_page(void *to, void *from)
45472 + {
45473 + int i;
45474 ++ unsigned long cr0;
45475 +
45476 + kernel_fpu_begin();
45477 +
45478 + __asm__ __volatile__ (
45479 +- "1: prefetch (%0)\n"
45480 +- " prefetch 64(%0)\n"
45481 +- " prefetch 128(%0)\n"
45482 +- " prefetch 192(%0)\n"
45483 +- " prefetch 256(%0)\n"
45484 ++ "1: prefetch (%1)\n"
45485 ++ " prefetch 64(%1)\n"
45486 ++ " prefetch 128(%1)\n"
45487 ++ " prefetch 192(%1)\n"
45488 ++ " prefetch 256(%1)\n"
45489 + "2: \n"
45490 + ".section .fixup, \"ax\"\n"
45491 +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
45492 ++ "3: \n"
45493 ++
45494 ++#ifdef CONFIG_PAX_KERNEXEC
45495 ++ " movl %%cr0, %0\n"
45496 ++ " movl %0, %%eax\n"
45497 ++ " andl $0xFFFEFFFF, %%eax\n"
45498 ++ " movl %%eax, %%cr0\n"
45499 ++#endif
45500 ++
45501 ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
45502 ++
45503 ++#ifdef CONFIG_PAX_KERNEXEC
45504 ++ " movl %0, %%cr0\n"
45505 ++#endif
45506 ++
45507 + " jmp 2b\n"
45508 + ".previous\n"
45509 +- _ASM_EXTABLE(1b, 3b) : : "r" (from));
45510 ++ _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
45511 +
45512 + for (i = 0; i < 4096/64; i++) {
45513 + __asm__ __volatile__ (
45514 +- "1: prefetch 320(%0)\n"
45515 +- "2: movq (%0), %%mm0\n"
45516 +- " movq 8(%0), %%mm1\n"
45517 +- " movq 16(%0), %%mm2\n"
45518 +- " movq 24(%0), %%mm3\n"
45519 +- " movq %%mm0, (%1)\n"
45520 +- " movq %%mm1, 8(%1)\n"
45521 +- " movq %%mm2, 16(%1)\n"
45522 +- " movq %%mm3, 24(%1)\n"
45523 +- " movq 32(%0), %%mm0\n"
45524 +- " movq 40(%0), %%mm1\n"
45525 +- " movq 48(%0), %%mm2\n"
45526 +- " movq 56(%0), %%mm3\n"
45527 +- " movq %%mm0, 32(%1)\n"
45528 +- " movq %%mm1, 40(%1)\n"
45529 +- " movq %%mm2, 48(%1)\n"
45530 +- " movq %%mm3, 56(%1)\n"
45531 ++ "1: prefetch 320(%1)\n"
45532 ++ "2: movq (%1), %%mm0\n"
45533 ++ " movq 8(%1), %%mm1\n"
45534 ++ " movq 16(%1), %%mm2\n"
45535 ++ " movq 24(%1), %%mm3\n"
45536 ++ " movq %%mm0, (%2)\n"
45537 ++ " movq %%mm1, 8(%2)\n"
45538 ++ " movq %%mm2, 16(%2)\n"
45539 ++ " movq %%mm3, 24(%2)\n"
45540 ++ " movq 32(%1), %%mm0\n"
45541 ++ " movq 40(%1), %%mm1\n"
45542 ++ " movq 48(%1), %%mm2\n"
45543 ++ " movq 56(%1), %%mm3\n"
45544 ++ " movq %%mm0, 32(%2)\n"
45545 ++ " movq %%mm1, 40(%2)\n"
45546 ++ " movq %%mm2, 48(%2)\n"
45547 ++ " movq %%mm3, 56(%2)\n"
45548 + ".section .fixup, \"ax\"\n"
45549 +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
45550 ++ "3:\n"
45551 ++
45552 ++#ifdef CONFIG_PAX_KERNEXEC
45553 ++ " movl %%cr0, %0\n"
45554 ++ " movl %0, %%eax\n"
45555 ++ " andl $0xFFFEFFFF, %%eax\n"
45556 ++ " movl %%eax, %%cr0\n"
45557 ++#endif
45558 ++
45559 ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
45560 ++
45561 ++#ifdef CONFIG_PAX_KERNEXEC
45562 ++ " movl %0, %%cr0\n"
45563 ++#endif
45564 ++
45565 + " jmp 2b\n"
45566 + ".previous\n"
45567 + _ASM_EXTABLE(1b, 3b)
45568 +- : : "r" (from), "r" (to) : "memory");
45569 ++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
45570 +
45571 + from += 64;
45572 + to += 64;
45573 +diff -urNp linux-2.6.27.7/arch/x86/lib/putuser.S linux-2.6.27.7/arch/x86/lib/putuser.S
45574 +--- linux-2.6.27.7/arch/x86/lib/putuser.S 2008-11-07 12:55:34.000000000 -0500
45575 ++++ linux-2.6.27.7/arch/x86/lib/putuser.S 2008-11-18 03:38:44.000000000 -0500
45576 +@@ -15,6 +15,7 @@
45577 + #include <asm/thread_info.h>
45578 + #include <asm/errno.h>
45579 + #include <asm/asm.h>
45580 ++#include <asm/segment.h>
45581 +
45582 +
45583 + /*
45584 +@@ -39,7 +40,19 @@ ENTRY(__put_user_1)
45585 + ENTER
45586 + cmp TI_addr_limit(%_ASM_BX),%_ASM_CX
45587 + jae bad_put_user
45588 ++
45589 ++#ifdef CONFIG_X86_32
45590 ++ pushl $(__USER_DS)
45591 ++ popl %ds
45592 ++#endif
45593 ++
45594 + 1: movb %al,(%_ASM_CX)
45595 ++
45596 ++#ifdef CONFIG_X86_32
45597 ++ pushl %ss
45598 ++ popl %ds
45599 ++#endif
45600 ++
45601 + xor %eax,%eax
45602 + EXIT
45603 + ENDPROC(__put_user_1)
45604 +@@ -50,7 +63,19 @@ ENTRY(__put_user_2)
45605 + sub $1,%_ASM_BX
45606 + cmp %_ASM_BX,%_ASM_CX
45607 + jae bad_put_user
45608 ++
45609 ++#ifdef CONFIG_X86_32
45610 ++ pushl $(__USER_DS)
45611 ++ popl %ds
45612 ++#endif
45613 ++
45614 + 2: movw %ax,(%_ASM_CX)
45615 ++
45616 ++#ifdef CONFIG_X86_32
45617 ++ pushl %ss
45618 ++ popl %ds
45619 ++#endif
45620 ++
45621 + xor %eax,%eax
45622 + EXIT
45623 + ENDPROC(__put_user_2)
45624 +@@ -61,7 +86,19 @@ ENTRY(__put_user_4)
45625 + sub $3,%_ASM_BX
45626 + cmp %_ASM_BX,%_ASM_CX
45627 + jae bad_put_user
45628 ++
45629 ++#ifdef CONFIG_X86_32
45630 ++ pushl $(__USER_DS)
45631 ++ popl %ds
45632 ++#endif
45633 ++
45634 + 3: movl %eax,(%_ASM_CX)
45635 ++
45636 ++#ifdef CONFIG_X86_32
45637 ++ pushl %ss
45638 ++ popl %ds
45639 ++#endif
45640 ++
45641 + xor %eax,%eax
45642 + EXIT
45643 + ENDPROC(__put_user_4)
45644 +@@ -72,16 +109,34 @@ ENTRY(__put_user_8)
45645 + sub $7,%_ASM_BX
45646 + cmp %_ASM_BX,%_ASM_CX
45647 + jae bad_put_user
45648 ++
45649 ++#ifdef CONFIG_X86_32
45650 ++ pushl $(__USER_DS)
45651 ++ popl %ds
45652 ++#endif
45653 ++
45654 + 4: mov %_ASM_AX,(%_ASM_CX)
45655 + #ifdef CONFIG_X86_32
45656 + 5: movl %edx,4(%_ASM_CX)
45657 + #endif
45658 ++
45659 ++#ifdef CONFIG_X86_32
45660 ++ pushl %ss
45661 ++ popl %ds
45662 ++#endif
45663 ++
45664 + xor %eax,%eax
45665 + EXIT
45666 + ENDPROC(__put_user_8)
45667 +
45668 + bad_put_user:
45669 + CFI_STARTPROC
45670 ++
45671 ++#ifdef CONFIG_X86_32
45672 ++ pushl %ss
45673 ++ popl %ds
45674 ++#endif
45675 ++
45676 + movl $-EFAULT,%eax
45677 + EXIT
45678 + END(bad_put_user)
45679 +diff -urNp linux-2.6.27.7/arch/x86/lib/usercopy_32.c linux-2.6.27.7/arch/x86/lib/usercopy_32.c
45680 +--- linux-2.6.27.7/arch/x86/lib/usercopy_32.c 2008-11-07 12:55:34.000000000 -0500
45681 ++++ linux-2.6.27.7/arch/x86/lib/usercopy_32.c 2008-11-18 03:38:44.000000000 -0500
45682 +@@ -29,31 +29,38 @@ static inline int __movsl_is_ok(unsigned
45683 + * Copy a null terminated string from userspace.
45684 + */
45685 +
45686 +-#define __do_strncpy_from_user(dst, src, count, res) \
45687 +-do { \
45688 +- int __d0, __d1, __d2; \
45689 +- might_sleep(); \
45690 +- __asm__ __volatile__( \
45691 +- " testl %1,%1\n" \
45692 +- " jz 2f\n" \
45693 +- "0: lodsb\n" \
45694 +- " stosb\n" \
45695 +- " testb %%al,%%al\n" \
45696 +- " jz 1f\n" \
45697 +- " decl %1\n" \
45698 +- " jnz 0b\n" \
45699 +- "1: subl %1,%0\n" \
45700 +- "2:\n" \
45701 +- ".section .fixup,\"ax\"\n" \
45702 +- "3: movl %5,%0\n" \
45703 +- " jmp 2b\n" \
45704 +- ".previous\n" \
45705 +- _ASM_EXTABLE(0b,3b) \
45706 +- : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \
45707 +- "=&D" (__d2) \
45708 +- : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
45709 +- : "memory"); \
45710 +-} while (0)
45711 ++static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
45712 ++{
45713 ++ int __d0, __d1, __d2;
45714 ++ long res = -EFAULT;
45715 ++
45716 ++ might_sleep();
45717 ++ __asm__ __volatile__(
45718 ++ " movw %w10,%%ds\n"
45719 ++ " testl %1,%1\n"
45720 ++ " jz 2f\n"
45721 ++ "0: lodsb\n"
45722 ++ " stosb\n"
45723 ++ " testb %%al,%%al\n"
45724 ++ " jz 1f\n"
45725 ++ " decl %1\n"
45726 ++ " jnz 0b\n"
45727 ++ "1: subl %1,%0\n"
45728 ++ "2:\n"
45729 ++ " pushl %%ss\n"
45730 ++ " popl %%ds\n"
45731 ++ ".section .fixup,\"ax\"\n"
45732 ++ "3: movl %5,%0\n"
45733 ++ " jmp 2b\n"
45734 ++ ".previous\n"
45735 ++ _ASM_EXTABLE(0b,3b)
45736 ++ : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),
45737 ++ "=&D" (__d2)
45738 ++ : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
45739 ++ "r"(__USER_DS)
45740 ++ : "memory");
45741 ++ return res;
45742 ++}
45743 +
45744 + /**
45745 + * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
45746 +@@ -78,9 +85,7 @@ do { \
45747 + long
45748 + __strncpy_from_user(char *dst, const char __user *src, long count)
45749 + {
45750 +- long res;
45751 +- __do_strncpy_from_user(dst, src, count, res);
45752 +- return res;
45753 ++ return __do_strncpy_from_user(dst, src, count);
45754 + }
45755 + EXPORT_SYMBOL(__strncpy_from_user);
45756 +
45757 +@@ -107,7 +112,7 @@ strncpy_from_user(char *dst, const char
45758 + {
45759 + long res = -EFAULT;
45760 + if (access_ok(VERIFY_READ, src, 1))
45761 +- __do_strncpy_from_user(dst, src, count, res);
45762 ++ res = __do_strncpy_from_user(dst, src, count);
45763 + return res;
45764 + }
45765 + EXPORT_SYMBOL(strncpy_from_user);
45766 +@@ -116,24 +121,30 @@ EXPORT_SYMBOL(strncpy_from_user);
45767 + * Zero Userspace
45768 + */
45769 +
45770 +-#define __do_clear_user(addr,size) \
45771 +-do { \
45772 +- int __d0; \
45773 +- might_sleep(); \
45774 +- __asm__ __volatile__( \
45775 +- "0: rep; stosl\n" \
45776 +- " movl %2,%0\n" \
45777 +- "1: rep; stosb\n" \
45778 +- "2:\n" \
45779 +- ".section .fixup,\"ax\"\n" \
45780 +- "3: lea 0(%2,%0,4),%0\n" \
45781 +- " jmp 2b\n" \
45782 +- ".previous\n" \
45783 +- _ASM_EXTABLE(0b,3b) \
45784 +- _ASM_EXTABLE(1b,2b) \
45785 +- : "=&c"(size), "=&D" (__d0) \
45786 +- : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
45787 +-} while (0)
45788 ++static unsigned long __do_clear_user(void __user *addr, unsigned long size)
45789 ++{
45790 ++ int __d0;
45791 ++
45792 ++ might_sleep();
45793 ++ __asm__ __volatile__(
45794 ++ " movw %w6,%%es\n"
45795 ++ "0: rep; stosl\n"
45796 ++ " movl %2,%0\n"
45797 ++ "1: rep; stosb\n"
45798 ++ "2:\n"
45799 ++ " pushl %%ss\n"
45800 ++ " popl %%es\n"
45801 ++ ".section .fixup,\"ax\"\n"
45802 ++ "3: lea 0(%2,%0,4),%0\n"
45803 ++ " jmp 2b\n"
45804 ++ ".previous\n"
45805 ++ _ASM_EXTABLE(0b,3b)
45806 ++ _ASM_EXTABLE(1b,2b)
45807 ++ : "=&c"(size), "=&D" (__d0)
45808 ++ : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
45809 ++ "r"(__USER_DS));
45810 ++ return size;
45811 ++}
45812 +
45813 + /**
45814 + * clear_user: - Zero a block of memory in user space.
45815 +@@ -150,7 +161,7 @@ clear_user(void __user *to, unsigned lon
45816 + {
45817 + might_sleep();
45818 + if (access_ok(VERIFY_WRITE, to, n))
45819 +- __do_clear_user(to, n);
45820 ++ n = __do_clear_user(to, n);
45821 + return n;
45822 + }
45823 + EXPORT_SYMBOL(clear_user);
45824 +@@ -169,8 +180,7 @@ EXPORT_SYMBOL(clear_user);
45825 + unsigned long
45826 + __clear_user(void __user *to, unsigned long n)
45827 + {
45828 +- __do_clear_user(to, n);
45829 +- return n;
45830 ++ return __do_clear_user(to, n);
45831 + }
45832 + EXPORT_SYMBOL(__clear_user);
45833 +
45834 +@@ -193,14 +203,17 @@ long strnlen_user(const char __user *s,
45835 + might_sleep();
45836 +
45837 + __asm__ __volatile__(
45838 ++ " movw %w8,%%es\n"
45839 + " testl %0, %0\n"
45840 + " jz 3f\n"
45841 +- " andl %0,%%ecx\n"
45842 ++ " movl %0,%%ecx\n"
45843 + "0: repne; scasb\n"
45844 + " setne %%al\n"
45845 + " subl %%ecx,%0\n"
45846 + " addl %0,%%eax\n"
45847 + "1:\n"
45848 ++ " pushl %%ss\n"
45849 ++ " popl %%es\n"
45850 + ".section .fixup,\"ax\"\n"
45851 + "2: xorl %%eax,%%eax\n"
45852 + " jmp 1b\n"
45853 +@@ -212,7 +225,7 @@ long strnlen_user(const char __user *s,
45854 + " .long 0b,2b\n"
45855 + ".previous"
45856 + :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
45857 +- :"0" (n), "1" (s), "2" (0), "3" (mask)
45858 ++ :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
45859 + :"cc");
45860 + return res & mask;
45861 + }
45862 +@@ -220,10 +233,11 @@ EXPORT_SYMBOL(strnlen_user);
45863 +
45864 + #ifdef CONFIG_X86_INTEL_USERCOPY
45865 + static unsigned long
45866 +-__copy_user_intel(void __user *to, const void *from, unsigned long size)
45867 ++__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
45868 + {
45869 + int d0, d1;
45870 + __asm__ __volatile__(
45871 ++ " movw %w6, %%es\n"
45872 + " .align 2,0x90\n"
45873 + "1: movl 32(%4), %%eax\n"
45874 + " cmpl $67, %0\n"
45875 +@@ -232,36 +246,36 @@ __copy_user_intel(void __user *to, const
45876 + " .align 2,0x90\n"
45877 + "3: movl 0(%4), %%eax\n"
45878 + "4: movl 4(%4), %%edx\n"
45879 +- "5: movl %%eax, 0(%3)\n"
45880 +- "6: movl %%edx, 4(%3)\n"
45881 ++ "5: movl %%eax, %%es:0(%3)\n"
45882 ++ "6: movl %%edx, %%es:4(%3)\n"
45883 + "7: movl 8(%4), %%eax\n"
45884 + "8: movl 12(%4),%%edx\n"
45885 +- "9: movl %%eax, 8(%3)\n"
45886 +- "10: movl %%edx, 12(%3)\n"
45887 ++ "9: movl %%eax, %%es:8(%3)\n"
45888 ++ "10: movl %%edx, %%es:12(%3)\n"
45889 + "11: movl 16(%4), %%eax\n"
45890 + "12: movl 20(%4), %%edx\n"
45891 +- "13: movl %%eax, 16(%3)\n"
45892 +- "14: movl %%edx, 20(%3)\n"
45893 ++ "13: movl %%eax, %%es:16(%3)\n"
45894 ++ "14: movl %%edx, %%es:20(%3)\n"
45895 + "15: movl 24(%4), %%eax\n"
45896 + "16: movl 28(%4), %%edx\n"
45897 +- "17: movl %%eax, 24(%3)\n"
45898 +- "18: movl %%edx, 28(%3)\n"
45899 ++ "17: movl %%eax, %%es:24(%3)\n"
45900 ++ "18: movl %%edx, %%es:28(%3)\n"
45901 + "19: movl 32(%4), %%eax\n"
45902 + "20: movl 36(%4), %%edx\n"
45903 +- "21: movl %%eax, 32(%3)\n"
45904 +- "22: movl %%edx, 36(%3)\n"
45905 ++ "21: movl %%eax, %%es:32(%3)\n"
45906 ++ "22: movl %%edx, %%es:36(%3)\n"
45907 + "23: movl 40(%4), %%eax\n"
45908 + "24: movl 44(%4), %%edx\n"
45909 +- "25: movl %%eax, 40(%3)\n"
45910 +- "26: movl %%edx, 44(%3)\n"
45911 ++ "25: movl %%eax, %%es:40(%3)\n"
45912 ++ "26: movl %%edx, %%es:44(%3)\n"
45913 + "27: movl 48(%4), %%eax\n"
45914 + "28: movl 52(%4), %%edx\n"
45915 +- "29: movl %%eax, 48(%3)\n"
45916 +- "30: movl %%edx, 52(%3)\n"
45917 ++ "29: movl %%eax, %%es:48(%3)\n"
45918 ++ "30: movl %%edx, %%es:52(%3)\n"
45919 + "31: movl 56(%4), %%eax\n"
45920 + "32: movl 60(%4), %%edx\n"
45921 +- "33: movl %%eax, 56(%3)\n"
45922 +- "34: movl %%edx, 60(%3)\n"
45923 ++ "33: movl %%eax, %%es:56(%3)\n"
45924 ++ "34: movl %%edx, %%es:60(%3)\n"
45925 + " addl $-64, %0\n"
45926 + " addl $64, %4\n"
45927 + " addl $64, %3\n"
45928 +@@ -275,6 +289,8 @@ __copy_user_intel(void __user *to, const
45929 + "36: movl %%eax, %0\n"
45930 + "37: rep; movsb\n"
45931 + "100:\n"
45932 ++ " pushl %%ss\n"
45933 ++ " popl %%es\n"
45934 + ".section .fixup,\"ax\"\n"
45935 + "101: lea 0(%%eax,%0,4),%0\n"
45936 + " jmp 100b\n"
45937 +@@ -321,7 +337,117 @@ __copy_user_intel(void __user *to, const
45938 + " .long 99b,101b\n"
45939 + ".previous"
45940 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
45941 +- : "1"(to), "2"(from), "0"(size)
45942 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
45943 ++ : "eax", "edx", "memory");
45944 ++ return size;
45945 ++}
45946 ++
45947 ++static unsigned long
45948 ++__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
45949 ++{
45950 ++ int d0, d1;
45951 ++ __asm__ __volatile__(
45952 ++ " movw %w6, %%ds\n"
45953 ++ " .align 2,0x90\n"
45954 ++ "1: movl 32(%4), %%eax\n"
45955 ++ " cmpl $67, %0\n"
45956 ++ " jbe 3f\n"
45957 ++ "2: movl 64(%4), %%eax\n"
45958 ++ " .align 2,0x90\n"
45959 ++ "3: movl 0(%4), %%eax\n"
45960 ++ "4: movl 4(%4), %%edx\n"
45961 ++ "5: movl %%eax, %%es:0(%3)\n"
45962 ++ "6: movl %%edx, %%es:4(%3)\n"
45963 ++ "7: movl 8(%4), %%eax\n"
45964 ++ "8: movl 12(%4),%%edx\n"
45965 ++ "9: movl %%eax, %%es:8(%3)\n"
45966 ++ "10: movl %%edx, %%es:12(%3)\n"
45967 ++ "11: movl 16(%4), %%eax\n"
45968 ++ "12: movl 20(%4), %%edx\n"
45969 ++ "13: movl %%eax, %%es:16(%3)\n"
45970 ++ "14: movl %%edx, %%es:20(%3)\n"
45971 ++ "15: movl 24(%4), %%eax\n"
45972 ++ "16: movl 28(%4), %%edx\n"
45973 ++ "17: movl %%eax, %%es:24(%3)\n"
45974 ++ "18: movl %%edx, %%es:28(%3)\n"
45975 ++ "19: movl 32(%4), %%eax\n"
45976 ++ "20: movl 36(%4), %%edx\n"
45977 ++ "21: movl %%eax, %%es:32(%3)\n"
45978 ++ "22: movl %%edx, %%es:36(%3)\n"
45979 ++ "23: movl 40(%4), %%eax\n"
45980 ++ "24: movl 44(%4), %%edx\n"
45981 ++ "25: movl %%eax, %%es:40(%3)\n"
45982 ++ "26: movl %%edx, %%es:44(%3)\n"
45983 ++ "27: movl 48(%4), %%eax\n"
45984 ++ "28: movl 52(%4), %%edx\n"
45985 ++ "29: movl %%eax, %%es:48(%3)\n"
45986 ++ "30: movl %%edx, %%es:52(%3)\n"
45987 ++ "31: movl 56(%4), %%eax\n"
45988 ++ "32: movl 60(%4), %%edx\n"
45989 ++ "33: movl %%eax, %%es:56(%3)\n"
45990 ++ "34: movl %%edx, %%es:60(%3)\n"
45991 ++ " addl $-64, %0\n"
45992 ++ " addl $64, %4\n"
45993 ++ " addl $64, %3\n"
45994 ++ " cmpl $63, %0\n"
45995 ++ " ja 1b\n"
45996 ++ "35: movl %0, %%eax\n"
45997 ++ " shrl $2, %0\n"
45998 ++ " andl $3, %%eax\n"
45999 ++ " cld\n"
46000 ++ "99: rep; movsl\n"
46001 ++ "36: movl %%eax, %0\n"
46002 ++ "37: rep; movsb\n"
46003 ++ "100:\n"
46004 ++ " pushl %%ss\n"
46005 ++ " popl %%ds\n"
46006 ++ ".section .fixup,\"ax\"\n"
46007 ++ "101: lea 0(%%eax,%0,4),%0\n"
46008 ++ " jmp 100b\n"
46009 ++ ".previous\n"
46010 ++ ".section __ex_table,\"a\"\n"
46011 ++ " .align 4\n"
46012 ++ " .long 1b,100b\n"
46013 ++ " .long 2b,100b\n"
46014 ++ " .long 3b,100b\n"
46015 ++ " .long 4b,100b\n"
46016 ++ " .long 5b,100b\n"
46017 ++ " .long 6b,100b\n"
46018 ++ " .long 7b,100b\n"
46019 ++ " .long 8b,100b\n"
46020 ++ " .long 9b,100b\n"
46021 ++ " .long 10b,100b\n"
46022 ++ " .long 11b,100b\n"
46023 ++ " .long 12b,100b\n"
46024 ++ " .long 13b,100b\n"
46025 ++ " .long 14b,100b\n"
46026 ++ " .long 15b,100b\n"
46027 ++ " .long 16b,100b\n"
46028 ++ " .long 17b,100b\n"
46029 ++ " .long 18b,100b\n"
46030 ++ " .long 19b,100b\n"
46031 ++ " .long 20b,100b\n"
46032 ++ " .long 21b,100b\n"
46033 ++ " .long 22b,100b\n"
46034 ++ " .long 23b,100b\n"
46035 ++ " .long 24b,100b\n"
46036 ++ " .long 25b,100b\n"
46037 ++ " .long 26b,100b\n"
46038 ++ " .long 27b,100b\n"
46039 ++ " .long 28b,100b\n"
46040 ++ " .long 29b,100b\n"
46041 ++ " .long 30b,100b\n"
46042 ++ " .long 31b,100b\n"
46043 ++ " .long 32b,100b\n"
46044 ++ " .long 33b,100b\n"
46045 ++ " .long 34b,100b\n"
46046 ++ " .long 35b,100b\n"
46047 ++ " .long 36b,100b\n"
46048 ++ " .long 37b,100b\n"
46049 ++ " .long 99b,101b\n"
46050 ++ ".previous"
46051 ++ : "=&c"(size), "=&D" (d0), "=&S" (d1)
46052 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
46053 + : "eax", "edx", "memory");
46054 + return size;
46055 + }
46056 +@@ -331,6 +457,7 @@ __copy_user_zeroing_intel(void *to, cons
46057 + {
46058 + int d0, d1;
46059 + __asm__ __volatile__(
46060 ++ " movw %w6, %%ds\n"
46061 + " .align 2,0x90\n"
46062 + "0: movl 32(%4), %%eax\n"
46063 + " cmpl $67, %0\n"
46064 +@@ -339,36 +466,36 @@ __copy_user_zeroing_intel(void *to, cons
46065 + " .align 2,0x90\n"
46066 + "2: movl 0(%4), %%eax\n"
46067 + "21: movl 4(%4), %%edx\n"
46068 +- " movl %%eax, 0(%3)\n"
46069 +- " movl %%edx, 4(%3)\n"
46070 ++ " movl %%eax, %%es:0(%3)\n"
46071 ++ " movl %%edx, %%es:4(%3)\n"
46072 + "3: movl 8(%4), %%eax\n"
46073 + "31: movl 12(%4),%%edx\n"
46074 +- " movl %%eax, 8(%3)\n"
46075 +- " movl %%edx, 12(%3)\n"
46076 ++ " movl %%eax, %%es:8(%3)\n"
46077 ++ " movl %%edx, %%es:12(%3)\n"
46078 + "4: movl 16(%4), %%eax\n"
46079 + "41: movl 20(%4), %%edx\n"
46080 +- " movl %%eax, 16(%3)\n"
46081 +- " movl %%edx, 20(%3)\n"
46082 ++ " movl %%eax, %%es:16(%3)\n"
46083 ++ " movl %%edx, %%es:20(%3)\n"
46084 + "10: movl 24(%4), %%eax\n"
46085 + "51: movl 28(%4), %%edx\n"
46086 +- " movl %%eax, 24(%3)\n"
46087 +- " movl %%edx, 28(%3)\n"
46088 ++ " movl %%eax, %%es:24(%3)\n"
46089 ++ " movl %%edx, %%es:28(%3)\n"
46090 + "11: movl 32(%4), %%eax\n"
46091 + "61: movl 36(%4), %%edx\n"
46092 +- " movl %%eax, 32(%3)\n"
46093 +- " movl %%edx, 36(%3)\n"
46094 ++ " movl %%eax, %%es:32(%3)\n"
46095 ++ " movl %%edx, %%es:36(%3)\n"
46096 + "12: movl 40(%4), %%eax\n"
46097 + "71: movl 44(%4), %%edx\n"
46098 +- " movl %%eax, 40(%3)\n"
46099 +- " movl %%edx, 44(%3)\n"
46100 ++ " movl %%eax, %%es:40(%3)\n"
46101 ++ " movl %%edx, %%es:44(%3)\n"
46102 + "13: movl 48(%4), %%eax\n"
46103 + "81: movl 52(%4), %%edx\n"
46104 +- " movl %%eax, 48(%3)\n"
46105 +- " movl %%edx, 52(%3)\n"
46106 ++ " movl %%eax, %%es:48(%3)\n"
46107 ++ " movl %%edx, %%es:52(%3)\n"
46108 + "14: movl 56(%4), %%eax\n"
46109 + "91: movl 60(%4), %%edx\n"
46110 +- " movl %%eax, 56(%3)\n"
46111 +- " movl %%edx, 60(%3)\n"
46112 ++ " movl %%eax, %%es:56(%3)\n"
46113 ++ " movl %%edx, %%es:60(%3)\n"
46114 + " addl $-64, %0\n"
46115 + " addl $64, %4\n"
46116 + " addl $64, %3\n"
46117 +@@ -382,6 +509,8 @@ __copy_user_zeroing_intel(void *to, cons
46118 + " movl %%eax,%0\n"
46119 + "7: rep; movsb\n"
46120 + "8:\n"
46121 ++ " pushl %%ss\n"
46122 ++ " popl %%ds\n"
46123 + ".section .fixup,\"ax\"\n"
46124 + "9: lea 0(%%eax,%0,4),%0\n"
46125 + "16: pushl %0\n"
46126 +@@ -416,7 +545,7 @@ __copy_user_zeroing_intel(void *to, cons
46127 + " .long 7b,16b\n"
46128 + ".previous"
46129 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
46130 +- : "1"(to), "2"(from), "0"(size)
46131 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
46132 + : "eax", "edx", "memory");
46133 + return size;
46134 + }
46135 +@@ -432,6 +561,7 @@ static unsigned long __copy_user_zeroing
46136 + int d0, d1;
46137 +
46138 + __asm__ __volatile__(
46139 ++ " movw %w6, %%ds\n"
46140 + " .align 2,0x90\n"
46141 + "0: movl 32(%4), %%eax\n"
46142 + " cmpl $67, %0\n"
46143 +@@ -440,36 +570,36 @@ static unsigned long __copy_user_zeroing
46144 + " .align 2,0x90\n"
46145 + "2: movl 0(%4), %%eax\n"
46146 + "21: movl 4(%4), %%edx\n"
46147 +- " movnti %%eax, 0(%3)\n"
46148 +- " movnti %%edx, 4(%3)\n"
46149 ++ " movnti %%eax, %%es:0(%3)\n"
46150 ++ " movnti %%edx, %%es:4(%3)\n"
46151 + "3: movl 8(%4), %%eax\n"
46152 + "31: movl 12(%4),%%edx\n"
46153 +- " movnti %%eax, 8(%3)\n"
46154 +- " movnti %%edx, 12(%3)\n"
46155 ++ " movnti %%eax, %%es:8(%3)\n"
46156 ++ " movnti %%edx, %%es:12(%3)\n"
46157 + "4: movl 16(%4), %%eax\n"
46158 + "41: movl 20(%4), %%edx\n"
46159 +- " movnti %%eax, 16(%3)\n"
46160 +- " movnti %%edx, 20(%3)\n"
46161 ++ " movnti %%eax, %%es:16(%3)\n"
46162 ++ " movnti %%edx, %%es:20(%3)\n"
46163 + "10: movl 24(%4), %%eax\n"
46164 + "51: movl 28(%4), %%edx\n"
46165 +- " movnti %%eax, 24(%3)\n"
46166 +- " movnti %%edx, 28(%3)\n"
46167 ++ " movnti %%eax, %%es:24(%3)\n"
46168 ++ " movnti %%edx, %%es:28(%3)\n"
46169 + "11: movl 32(%4), %%eax\n"
46170 + "61: movl 36(%4), %%edx\n"
46171 +- " movnti %%eax, 32(%3)\n"
46172 +- " movnti %%edx, 36(%3)\n"
46173 ++ " movnti %%eax, %%es:32(%3)\n"
46174 ++ " movnti %%edx, %%es:36(%3)\n"
46175 + "12: movl 40(%4), %%eax\n"
46176 + "71: movl 44(%4), %%edx\n"
46177 +- " movnti %%eax, 40(%3)\n"
46178 +- " movnti %%edx, 44(%3)\n"
46179 ++ " movnti %%eax, %%es:40(%3)\n"
46180 ++ " movnti %%edx, %%es:44(%3)\n"
46181 + "13: movl 48(%4), %%eax\n"
46182 + "81: movl 52(%4), %%edx\n"
46183 +- " movnti %%eax, 48(%3)\n"
46184 +- " movnti %%edx, 52(%3)\n"
46185 ++ " movnti %%eax, %%es:48(%3)\n"
46186 ++ " movnti %%edx, %%es:52(%3)\n"
46187 + "14: movl 56(%4), %%eax\n"
46188 + "91: movl 60(%4), %%edx\n"
46189 +- " movnti %%eax, 56(%3)\n"
46190 +- " movnti %%edx, 60(%3)\n"
46191 ++ " movnti %%eax, %%es:56(%3)\n"
46192 ++ " movnti %%edx, %%es:60(%3)\n"
46193 + " addl $-64, %0\n"
46194 + " addl $64, %4\n"
46195 + " addl $64, %3\n"
46196 +@@ -484,6 +614,8 @@ static unsigned long __copy_user_zeroing
46197 + " movl %%eax,%0\n"
46198 + "7: rep; movsb\n"
46199 + "8:\n"
46200 ++ " pushl %%ss\n"
46201 ++ " popl %%ds\n"
46202 + ".section .fixup,\"ax\"\n"
46203 + "9: lea 0(%%eax,%0,4),%0\n"
46204 + "16: pushl %0\n"
46205 +@@ -518,7 +650,7 @@ static unsigned long __copy_user_zeroing
46206 + " .long 7b,16b\n"
46207 + ".previous"
46208 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
46209 +- : "1"(to), "2"(from), "0"(size)
46210 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
46211 + : "eax", "edx", "memory");
46212 + return size;
46213 + }
46214 +@@ -529,6 +661,7 @@ static unsigned long __copy_user_intel_n
46215 + int d0, d1;
46216 +
46217 + __asm__ __volatile__(
46218 ++ " movw %w6, %%ds\n"
46219 + " .align 2,0x90\n"
46220 + "0: movl 32(%4), %%eax\n"
46221 + " cmpl $67, %0\n"
46222 +@@ -537,36 +670,36 @@ static unsigned long __copy_user_intel_n
46223 + " .align 2,0x90\n"
46224 + "2: movl 0(%4), %%eax\n"
46225 + "21: movl 4(%4), %%edx\n"
46226 +- " movnti %%eax, 0(%3)\n"
46227 +- " movnti %%edx, 4(%3)\n"
46228 ++ " movnti %%eax, %%es:0(%3)\n"
46229 ++ " movnti %%edx, %%es:4(%3)\n"
46230 + "3: movl 8(%4), %%eax\n"
46231 + "31: movl 12(%4),%%edx\n"
46232 +- " movnti %%eax, 8(%3)\n"
46233 +- " movnti %%edx, 12(%3)\n"
46234 ++ " movnti %%eax, %%es:8(%3)\n"
46235 ++ " movnti %%edx, %%es:12(%3)\n"
46236 + "4: movl 16(%4), %%eax\n"
46237 + "41: movl 20(%4), %%edx\n"
46238 +- " movnti %%eax, 16(%3)\n"
46239 +- " movnti %%edx, 20(%3)\n"
46240 ++ " movnti %%eax, %%es:16(%3)\n"
46241 ++ " movnti %%edx, %%es:20(%3)\n"
46242 + "10: movl 24(%4), %%eax\n"
46243 + "51: movl 28(%4), %%edx\n"
46244 +- " movnti %%eax, 24(%3)\n"
46245 +- " movnti %%edx, 28(%3)\n"
46246 ++ " movnti %%eax, %%es:24(%3)\n"
46247 ++ " movnti %%edx, %%es:28(%3)\n"
46248 + "11: movl 32(%4), %%eax\n"
46249 + "61: movl 36(%4), %%edx\n"
46250 +- " movnti %%eax, 32(%3)\n"
46251 +- " movnti %%edx, 36(%3)\n"
46252 ++ " movnti %%eax, %%es:32(%3)\n"
46253 ++ " movnti %%edx, %%es:36(%3)\n"
46254 + "12: movl 40(%4), %%eax\n"
46255 + "71: movl 44(%4), %%edx\n"
46256 +- " movnti %%eax, 40(%3)\n"
46257 +- " movnti %%edx, 44(%3)\n"
46258 ++ " movnti %%eax, %%es:40(%3)\n"
46259 ++ " movnti %%edx, %%es:44(%3)\n"
46260 + "13: movl 48(%4), %%eax\n"
46261 + "81: movl 52(%4), %%edx\n"
46262 +- " movnti %%eax, 48(%3)\n"
46263 +- " movnti %%edx, 52(%3)\n"
46264 ++ " movnti %%eax, %%es:48(%3)\n"
46265 ++ " movnti %%edx, %%es:52(%3)\n"
46266 + "14: movl 56(%4), %%eax\n"
46267 + "91: movl 60(%4), %%edx\n"
46268 +- " movnti %%eax, 56(%3)\n"
46269 +- " movnti %%edx, 60(%3)\n"
46270 ++ " movnti %%eax, %%es:56(%3)\n"
46271 ++ " movnti %%edx, %%es:60(%3)\n"
46272 + " addl $-64, %0\n"
46273 + " addl $64, %4\n"
46274 + " addl $64, %3\n"
46275 +@@ -581,6 +714,8 @@ static unsigned long __copy_user_intel_n
46276 + " movl %%eax,%0\n"
46277 + "7: rep; movsb\n"
46278 + "8:\n"
46279 ++ " pushl %%ss\n"
46280 ++ " popl %%ds\n"
46281 + ".section .fixup,\"ax\"\n"
46282 + "9: lea 0(%%eax,%0,4),%0\n"
46283 + "16: jmp 8b\n"
46284 +@@ -609,7 +744,7 @@ static unsigned long __copy_user_intel_n
46285 + " .long 7b,16b\n"
46286 + ".previous"
46287 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
46288 +- : "1"(to), "2"(from), "0"(size)
46289 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
46290 + : "eax", "edx", "memory");
46291 + return size;
46292 + }
46293 +@@ -622,90 +757,146 @@ static unsigned long __copy_user_intel_n
46294 + */
46295 + unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
46296 + unsigned long size);
46297 +-unsigned long __copy_user_intel(void __user *to, const void *from,
46298 ++unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
46299 ++ unsigned long size);
46300 ++unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
46301 + unsigned long size);
46302 + unsigned long __copy_user_zeroing_intel_nocache(void *to,
46303 + const void __user *from, unsigned long size);
46304 + #endif /* CONFIG_X86_INTEL_USERCOPY */
46305 +
46306 + /* Generic arbitrary sized copy. */
46307 +-#define __copy_user(to, from, size) \
46308 +-do { \
46309 +- int __d0, __d1, __d2; \
46310 +- __asm__ __volatile__( \
46311 +- " cmp $7,%0\n" \
46312 +- " jbe 1f\n" \
46313 +- " movl %1,%0\n" \
46314 +- " negl %0\n" \
46315 +- " andl $7,%0\n" \
46316 +- " subl %0,%3\n" \
46317 +- "4: rep; movsb\n" \
46318 +- " movl %3,%0\n" \
46319 +- " shrl $2,%0\n" \
46320 +- " andl $3,%3\n" \
46321 +- " .align 2,0x90\n" \
46322 +- "0: rep; movsl\n" \
46323 +- " movl %3,%0\n" \
46324 +- "1: rep; movsb\n" \
46325 +- "2:\n" \
46326 +- ".section .fixup,\"ax\"\n" \
46327 +- "5: addl %3,%0\n" \
46328 +- " jmp 2b\n" \
46329 +- "3: lea 0(%3,%0,4),%0\n" \
46330 +- " jmp 2b\n" \
46331 +- ".previous\n" \
46332 +- ".section __ex_table,\"a\"\n" \
46333 +- " .align 4\n" \
46334 +- " .long 4b,5b\n" \
46335 +- " .long 0b,3b\n" \
46336 +- " .long 1b,2b\n" \
46337 +- ".previous" \
46338 +- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
46339 +- : "3"(size), "0"(size), "1"(to), "2"(from) \
46340 +- : "memory"); \
46341 +-} while (0)
46342 +-
46343 +-#define __copy_user_zeroing(to, from, size) \
46344 +-do { \
46345 +- int __d0, __d1, __d2; \
46346 +- __asm__ __volatile__( \
46347 +- " cmp $7,%0\n" \
46348 +- " jbe 1f\n" \
46349 +- " movl %1,%0\n" \
46350 +- " negl %0\n" \
46351 +- " andl $7,%0\n" \
46352 +- " subl %0,%3\n" \
46353 +- "4: rep; movsb\n" \
46354 +- " movl %3,%0\n" \
46355 +- " shrl $2,%0\n" \
46356 +- " andl $3,%3\n" \
46357 +- " .align 2,0x90\n" \
46358 +- "0: rep; movsl\n" \
46359 +- " movl %3,%0\n" \
46360 +- "1: rep; movsb\n" \
46361 +- "2:\n" \
46362 +- ".section .fixup,\"ax\"\n" \
46363 +- "5: addl %3,%0\n" \
46364 +- " jmp 6f\n" \
46365 +- "3: lea 0(%3,%0,4),%0\n" \
46366 +- "6: pushl %0\n" \
46367 +- " pushl %%eax\n" \
46368 +- " xorl %%eax,%%eax\n" \
46369 +- " rep; stosb\n" \
46370 +- " popl %%eax\n" \
46371 +- " popl %0\n" \
46372 +- " jmp 2b\n" \
46373 +- ".previous\n" \
46374 +- ".section __ex_table,\"a\"\n" \
46375 +- " .align 4\n" \
46376 +- " .long 4b,5b\n" \
46377 +- " .long 0b,3b\n" \
46378 +- " .long 1b,6b\n" \
46379 +- ".previous" \
46380 +- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
46381 +- : "3"(size), "0"(size), "1"(to), "2"(from) \
46382 +- : "memory"); \
46383 +-} while (0)
46384 ++static unsigned long
46385 ++__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
46386 ++{
46387 ++ int __d0, __d1, __d2;
46388 ++
46389 ++ __asm__ __volatile__(
46390 ++ " movw %w8,%%es\n"
46391 ++ " cmp $7,%0\n"
46392 ++ " jbe 1f\n"
46393 ++ " movl %1,%0\n"
46394 ++ " negl %0\n"
46395 ++ " andl $7,%0\n"
46396 ++ " subl %0,%3\n"
46397 ++ "4: rep; movsb\n"
46398 ++ " movl %3,%0\n"
46399 ++ " shrl $2,%0\n"
46400 ++ " andl $3,%3\n"
46401 ++ " .align 2,0x90\n"
46402 ++ "0: rep; movsl\n"
46403 ++ " movl %3,%0\n"
46404 ++ "1: rep; movsb\n"
46405 ++ "2:\n"
46406 ++ " pushl %%ss\n"
46407 ++ " popl %%es\n"
46408 ++ ".section .fixup,\"ax\"\n"
46409 ++ "5: addl %3,%0\n"
46410 ++ " jmp 2b\n"
46411 ++ "3: lea 0(%3,%0,4),%0\n"
46412 ++ " jmp 2b\n"
46413 ++ ".previous\n"
46414 ++ ".section __ex_table,\"a\"\n"
46415 ++ " .align 4\n"
46416 ++ " .long 4b,5b\n"
46417 ++ " .long 0b,3b\n"
46418 ++ " .long 1b,2b\n"
46419 ++ ".previous"
46420 ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
46421 ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
46422 ++ : "memory");
46423 ++ return size;
46424 ++}
46425 ++
46426 ++static unsigned long
46427 ++__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
46428 ++{
46429 ++ int __d0, __d1, __d2;
46430 ++
46431 ++ __asm__ __volatile__(
46432 ++ " movw %w8,%%ds\n"
46433 ++ " cmp $7,%0\n"
46434 ++ " jbe 1f\n"
46435 ++ " movl %1,%0\n"
46436 ++ " negl %0\n"
46437 ++ " andl $7,%0\n"
46438 ++ " subl %0,%3\n"
46439 ++ "4: rep; movsb\n"
46440 ++ " movl %3,%0\n"
46441 ++ " shrl $2,%0\n"
46442 ++ " andl $3,%3\n"
46443 ++ " .align 2,0x90\n"
46444 ++ "0: rep; movsl\n"
46445 ++ " movl %3,%0\n"
46446 ++ "1: rep; movsb\n"
46447 ++ "2:\n"
46448 ++ " pushl %%ss\n"
46449 ++ " popl %%ds\n"
46450 ++ ".section .fixup,\"ax\"\n"
46451 ++ "5: addl %3,%0\n"
46452 ++ " jmp 2b\n"
46453 ++ "3: lea 0(%3,%0,4),%0\n"
46454 ++ " jmp 2b\n"
46455 ++ ".previous\n"
46456 ++ ".section __ex_table,\"a\"\n"
46457 ++ " .align 4\n"
46458 ++ " .long 4b,5b\n"
46459 ++ " .long 0b,3b\n"
46460 ++ " .long 1b,2b\n"
46461 ++ ".previous"
46462 ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
46463 ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
46464 ++ : "memory");
46465 ++ return size;
46466 ++}
46467 ++
46468 ++static unsigned long
46469 ++__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
46470 ++{
46471 ++ int __d0, __d1, __d2;
46472 ++
46473 ++ __asm__ __volatile__(
46474 ++ " movw %w8,%%ds\n"
46475 ++ " cmp $7,%0\n"
46476 ++ " jbe 1f\n"
46477 ++ " movl %1,%0\n"
46478 ++ " negl %0\n"
46479 ++ " andl $7,%0\n"
46480 ++ " subl %0,%3\n"
46481 ++ "4: rep; movsb\n"
46482 ++ " movl %3,%0\n"
46483 ++ " shrl $2,%0\n"
46484 ++ " andl $3,%3\n"
46485 ++ " .align 2,0x90\n"
46486 ++ "0: rep; movsl\n"
46487 ++ " movl %3,%0\n"
46488 ++ "1: rep; movsb\n"
46489 ++ "2:\n"
46490 ++ " pushl %%ss\n"
46491 ++ " popl %%ds\n"
46492 ++ ".section .fixup,\"ax\"\n"
46493 ++ "5: addl %3,%0\n"
46494 ++ " jmp 6f\n"
46495 ++ "3: lea 0(%3,%0,4),%0\n"
46496 ++ "6: pushl %0\n"
46497 ++ " pushl %%eax\n"
46498 ++ " xorl %%eax,%%eax\n"
46499 ++ " rep; stosb\n"
46500 ++ " popl %%eax\n"
46501 ++ " popl %0\n"
46502 ++ " jmp 2b\n"
46503 ++ ".previous\n"
46504 ++ ".section __ex_table,\"a\"\n"
46505 ++ " .align 4\n"
46506 ++ " .long 4b,5b\n"
46507 ++ " .long 0b,3b\n"
46508 ++ " .long 1b,6b\n"
46509 ++ ".previous"
46510 ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
46511 ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
46512 ++ : "memory");
46513 ++ return size;
46514 ++}
46515 +
46516 + unsigned long __copy_to_user_ll(void __user *to, const void *from,
46517 + unsigned long n)
46518 +@@ -768,9 +959,9 @@ survive:
46519 + }
46520 + #endif
46521 + if (movsl_is_ok(to, from, n))
46522 +- __copy_user(to, from, n);
46523 ++ n = __generic_copy_to_user(to, from, n);
46524 + else
46525 +- n = __copy_user_intel(to, from, n);
46526 ++ n = __generic_copy_to_user_intel(to, from, n);
46527 + return n;
46528 + }
46529 + EXPORT_SYMBOL(__copy_to_user_ll);
46530 +@@ -779,7 +970,7 @@ unsigned long __copy_from_user_ll(void *
46531 + unsigned long n)
46532 + {
46533 + if (movsl_is_ok(to, from, n))
46534 +- __copy_user_zeroing(to, from, n);
46535 ++ n = __copy_user_zeroing(to, from, n);
46536 + else
46537 + n = __copy_user_zeroing_intel(to, from, n);
46538 + return n;
46539 +@@ -790,10 +981,9 @@ unsigned long __copy_from_user_ll_nozero
46540 + unsigned long n)
46541 + {
46542 + if (movsl_is_ok(to, from, n))
46543 +- __copy_user(to, from, n);
46544 ++ n = __generic_copy_from_user(to, from, n);
46545 + else
46546 +- n = __copy_user_intel((void __user *)to,
46547 +- (const void *)from, n);
46548 ++ n = __generic_copy_from_user_intel(to, from, n);
46549 + return n;
46550 + }
46551 + EXPORT_SYMBOL(__copy_from_user_ll_nozero);
46552 +@@ -802,12 +992,12 @@ unsigned long __copy_from_user_ll_nocach
46553 + unsigned long n)
46554 + {
46555 + #ifdef CONFIG_X86_INTEL_USERCOPY
46556 +- if (n > 64 && cpu_has_xmm2)
46557 ++ if ( n > 64 && cpu_has_xmm2)
46558 + n = __copy_user_zeroing_intel_nocache(to, from, n);
46559 + else
46560 +- __copy_user_zeroing(to, from, n);
46561 ++ n = __copy_user_zeroing(to, from, n);
46562 + #else
46563 +- __copy_user_zeroing(to, from, n);
46564 ++ n = __copy_user_zeroing(to, from, n);
46565 + #endif
46566 + return n;
46567 + }
46568 +@@ -817,12 +1007,12 @@ unsigned long __copy_from_user_ll_nocach
46569 + unsigned long n)
46570 + {
46571 + #ifdef CONFIG_X86_INTEL_USERCOPY
46572 +- if (n > 64 && cpu_has_xmm2)
46573 ++ if ( n > 64 && cpu_has_xmm2)
46574 + n = __copy_user_intel_nocache(to, from, n);
46575 + else
46576 +- __copy_user(to, from, n);
46577 ++ n = __generic_copy_from_user(to, from, n);
46578 + #else
46579 +- __copy_user(to, from, n);
46580 ++ n = __generic_copy_from_user(to, from, n);
46581 + #endif
46582 + return n;
46583 + }
46584 +@@ -871,8 +1061,35 @@ copy_from_user(void *to, const void __us
46585 + {
46586 + if (access_ok(VERIFY_READ, from, n))
46587 + n = __copy_from_user(to, from, n);
46588 +- else
46589 ++ else if ((long)n > 0)
46590 + memset(to, 0, n);
46591 + return n;
46592 + }
46593 + EXPORT_SYMBOL(copy_from_user);
46594 ++
46595 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
46596 ++void __set_fs(mm_segment_t x, int cpu)
46597 ++{
46598 ++ unsigned long limit = x.seg;
46599 ++ struct desc_struct d;
46600 ++
46601 ++ current_thread_info()->addr_limit = x;
46602 ++ if (likely(limit))
46603 ++ limit = (limit - 1UL) >> PAGE_SHIFT;
46604 ++ pack_descriptor(&d, 0UL, limit, 0xF3, 0xC);
46605 ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, &d, DESCTYPE_S);
46606 ++}
46607 ++
46608 ++void set_fs(mm_segment_t x)
46609 ++{
46610 ++ __set_fs(x, get_cpu());
46611 ++ put_cpu_no_resched();
46612 ++}
46613 ++#else
46614 ++void set_fs(mm_segment_t x)
46615 ++{
46616 ++ current_thread_info()->addr_limit = x;
46617 ++}
46618 ++#endif
46619 ++
46620 ++EXPORT_SYMBOL(set_fs);
46621 +diff -urNp linux-2.6.27.7/arch/x86/mach-voyager/voyager_basic.c linux-2.6.27.7/arch/x86/mach-voyager/voyager_basic.c
46622 +--- linux-2.6.27.7/arch/x86/mach-voyager/voyager_basic.c 2008-11-07 12:55:34.000000000 -0500
46623 ++++ linux-2.6.27.7/arch/x86/mach-voyager/voyager_basic.c 2008-11-18 03:38:44.000000000 -0500
46624 +@@ -123,7 +123,7 @@ int __init voyager_memory_detect(int reg
46625 + __u8 cmos[4];
46626 + ClickMap_t *map;
46627 + unsigned long map_addr;
46628 +- unsigned long old;
46629 ++ pte_t old;
46630 +
46631 + if (region >= CLICK_ENTRIES) {
46632 + printk("Voyager: Illegal ClickMap region %d\n", region);
46633 +@@ -138,7 +138,7 @@ int __init voyager_memory_detect(int reg
46634 +
46635 + /* steal page 0 for this */
46636 + old = pg0[0];
46637 +- pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
46638 ++ pg0[0] = __pte((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
46639 + local_flush_tlb();
46640 + /* now clear everything out but page 0 */
46641 + map = (ClickMap_t *) (map_addr & (~PAGE_MASK));
46642 +diff -urNp linux-2.6.27.7/arch/x86/mach-voyager/voyager_smp.c linux-2.6.27.7/arch/x86/mach-voyager/voyager_smp.c
46643 +--- linux-2.6.27.7/arch/x86/mach-voyager/voyager_smp.c 2008-11-07 12:55:34.000000000 -0500
46644 ++++ linux-2.6.27.7/arch/x86/mach-voyager/voyager_smp.c 2008-11-18 03:38:44.000000000 -0500
46645 +@@ -510,6 +510,10 @@ static void __init do_boot_cpu(__u8 cpu)
46646 + __u32 *hijack_vector;
46647 + __u32 start_phys_address = setup_trampoline();
46648 +
46649 ++#ifdef CONFIG_PAX_KERNEXEC
46650 ++ unsigned long cr0;
46651 ++#endif
46652 ++
46653 + /* There's a clever trick to this: The linux trampoline is
46654 + * compiled to begin at absolute location zero, so make the
46655 + * address zero but have the data segment selector compensate
46656 +@@ -529,7 +533,17 @@ static void __init do_boot_cpu(__u8 cpu)
46657 +
46658 + init_gdt(cpu);
46659 + per_cpu(current_task, cpu) = idle;
46660 +- early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
46661 ++
46662 ++#ifdef CONFIG_PAX_KERNEXEC
46663 ++ pax_open_kernel(cr0);
46664 ++#endif
46665 ++
46666 ++ early_gdt_descr.address = get_cpu_gdt_table(cpu);
46667 ++
46668 ++#ifdef CONFIG_PAX_KERNEXEC
46669 ++ pax_close_kernel(cr0);
46670 ++#endif
46671 ++
46672 + irq_ctx_init(cpu);
46673 +
46674 + /* Note: Don't modify initial ss override */
46675 +@@ -1141,7 +1155,7 @@ void smp_local_timer_interrupt(void)
46676 + per_cpu(prof_counter, cpu);
46677 + }
46678 +
46679 +- update_process_times(user_mode_vm(get_irq_regs()));
46680 ++ update_process_times(user_mode(get_irq_regs()));
46681 + }
46682 +
46683 + if (((1 << cpu) & voyager_extended_vic_processors) == 0)
46684 +diff -urNp linux-2.6.27.7/arch/x86/Makefile linux-2.6.27.7/arch/x86/Makefile
46685 +--- linux-2.6.27.7/arch/x86/Makefile 2008-11-07 12:55:34.000000000 -0500
46686 ++++ linux-2.6.27.7/arch/x86/Makefile 2008-11-18 03:38:44.000000000 -0500
46687 +@@ -232,3 +232,12 @@ endef
46688 + CLEAN_FILES += arch/x86/boot/fdimage \
46689 + arch/x86/boot/image.iso \
46690 + arch/x86/boot/mtools.conf
46691 ++
46692 ++define OLD_LD
46693 ++
46694 ++*** ${VERSION}.${PATCHLEVEL} PaX kernels no longer build correctly with old versions of binutils.
46695 ++*** Please upgrade your binutils to 2.18 or newer
46696 ++endef
46697 ++
46698 ++archprepare:
46699 ++ $(if $(LDFLAGS_BUILD_ID),,$(error $(OLD_LD)))
46700 +diff -urNp linux-2.6.27.7/arch/x86/mm/discontig_32.c linux-2.6.27.7/arch/x86/mm/discontig_32.c
46701 +--- linux-2.6.27.7/arch/x86/mm/discontig_32.c 2008-11-07 12:55:34.000000000 -0500
46702 ++++ linux-2.6.27.7/arch/x86/mm/discontig_32.c 2008-11-18 03:38:44.000000000 -0500
46703 +@@ -98,7 +98,6 @@ unsigned long node_memmap_size_bytes(int
46704 + }
46705 + #endif
46706 +
46707 +-extern unsigned long find_max_low_pfn(void);
46708 + extern unsigned long highend_pfn, highstart_pfn;
46709 +
46710 + #define LARGE_PAGE_BYTES (PTRS_PER_PTE * PAGE_SIZE)
46711 +diff -urNp linux-2.6.27.7/arch/x86/mm/extable.c linux-2.6.27.7/arch/x86/mm/extable.c
46712 +--- linux-2.6.27.7/arch/x86/mm/extable.c 2008-11-07 12:55:34.000000000 -0500
46713 ++++ linux-2.6.27.7/arch/x86/mm/extable.c 2008-11-18 03:38:44.000000000 -0500
46714 +@@ -1,14 +1,62 @@
46715 + #include <linux/module.h>
46716 + #include <linux/spinlock.h>
46717 ++#include <linux/sort.h>
46718 + #include <asm/uaccess.h>
46719 +
46720 ++/*
46721 ++ * The exception table needs to be sorted so that the binary
46722 ++ * search that we use to find entries in it works properly.
46723 ++ * This is used both for the kernel exception table and for
46724 ++ * the exception tables of modules that get loaded.
46725 ++ */
46726 ++static int cmp_ex(const void *a, const void *b)
46727 ++{
46728 ++ const struct exception_table_entry *x = a, *y = b;
46729 ++
46730 ++ /* avoid overflow */
46731 ++ if (x->insn > y->insn)
46732 ++ return 1;
46733 ++ if (x->insn < y->insn)
46734 ++ return -1;
46735 ++ return 0;
46736 ++}
46737 ++
46738 ++static void swap_ex(void *a, void *b, int size)
46739 ++{
46740 ++ struct exception_table_entry t, *x = a, *y = b;
46741 ++
46742 ++#ifdef CONFIG_PAX_KERNEXEC
46743 ++ unsigned long cr0;
46744 ++#endif
46745 ++
46746 ++ t = *x;
46747 ++
46748 ++#ifdef CONFIG_PAX_KERNEXEC
46749 ++ pax_open_kernel(cr0);
46750 ++#endif
46751 ++
46752 ++ *x = *y;
46753 ++ *y = t;
46754 ++
46755 ++#ifdef CONFIG_PAX_KERNEXEC
46756 ++ pax_close_kernel(cr0);
46757 ++#endif
46758 ++
46759 ++}
46760 ++
46761 ++void sort_extable(struct exception_table_entry *start,
46762 ++ struct exception_table_entry *finish)
46763 ++{
46764 ++ sort(start, finish - start, sizeof(struct exception_table_entry),
46765 ++ cmp_ex, swap_ex);
46766 ++}
46767 +
46768 + int fixup_exception(struct pt_regs *regs)
46769 + {
46770 + const struct exception_table_entry *fixup;
46771 +
46772 + #ifdef CONFIG_PNPBIOS
46773 +- if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) {
46774 ++ if (unlikely(!v8086_mode(regs) && SEGMENT_IS_PNP_CODE(regs->cs))) {
46775 + extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
46776 + extern u32 pnp_bios_is_utter_crap;
46777 + pnp_bios_is_utter_crap = 1;
46778 +diff -urNp linux-2.6.27.7/arch/x86/mm/fault.c linux-2.6.27.7/arch/x86/mm/fault.c
46779 +--- linux-2.6.27.7/arch/x86/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
46780 ++++ linux-2.6.27.7/arch/x86/mm/fault.c 2008-11-18 03:38:44.000000000 -0500
46781 +@@ -26,6 +26,8 @@
46782 + #include <linux/kprobes.h>
46783 + #include <linux/uaccess.h>
46784 + #include <linux/kdebug.h>
46785 ++#include <linux/unistd.h>
46786 ++#include <linux/compiler.h>
46787 +
46788 + #include <asm/system.h>
46789 + #include <asm/desc.h>
46790 +@@ -35,6 +37,7 @@
46791 + #include <asm/tlbflush.h>
46792 + #include <asm/proto.h>
46793 + #include <asm-generic/sections.h>
46794 ++#include <asm/tlbflush.h>
46795 +
46796 + /*
46797 + * Page fault error code bits
46798 +@@ -66,7 +69,7 @@ static inline int notify_page_fault(stru
46799 + int ret = 0;
46800 +
46801 + /* kprobe_running() needs smp_processor_id() */
46802 +- if (!user_mode_vm(regs)) {
46803 ++ if (!user_mode(regs)) {
46804 + preempt_disable();
46805 + if (kprobe_running() && kprobe_fault_handler(regs, 14))
46806 + ret = 1;
46807 +@@ -264,6 +267,30 @@ bad:
46808 + #endif
46809 + }
46810 +
46811 ++#ifdef CONFIG_PAX_EMUTRAMP
46812 ++static int pax_handle_fetch_fault(struct pt_regs *regs);
46813 ++#endif
46814 ++
46815 ++#ifdef CONFIG_PAX_PAGEEXEC
46816 ++static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
46817 ++{
46818 ++ pgd_t *pgd;
46819 ++ pud_t *pud;
46820 ++ pmd_t *pmd;
46821 ++
46822 ++ pgd = pgd_offset(mm, address);
46823 ++ if (!pgd_present(*pgd))
46824 ++ return NULL;
46825 ++ pud = pud_offset(pgd, address);
46826 ++ if (!pud_present(*pud))
46827 ++ return NULL;
46828 ++ pmd = pmd_offset(pud, address);
46829 ++ if (!pmd_present(*pmd))
46830 ++ return NULL;
46831 ++ return pmd;
46832 ++}
46833 ++#endif
46834 ++
46835 + #ifdef CONFIG_X86_32
46836 + static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
46837 + {
46838 +@@ -350,7 +377,7 @@ static int is_errata93(struct pt_regs *r
46839 + static int is_errata100(struct pt_regs *regs, unsigned long address)
46840 + {
46841 + #ifdef CONFIG_X86_64
46842 +- if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) &&
46843 ++ if ((regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT)) &&
46844 + (address >> 32))
46845 + return 1;
46846 + #endif
46847 +@@ -387,14 +414,31 @@ static void show_fault_oops(struct pt_re
46848 + #endif
46849 +
46850 + #ifdef CONFIG_X86_PAE
46851 +- if (error_code & PF_INSTR) {
46852 ++ if (nx_enabled && (error_code & PF_INSTR)) {
46853 + unsigned int level;
46854 + pte_t *pte = lookup_address(address, &level);
46855 +
46856 + if (pte && pte_present(*pte) && !pte_exec(*pte))
46857 + printk(KERN_CRIT "kernel tried to execute "
46858 + "NX-protected page - exploit attempt? "
46859 +- "(uid: %d)\n", current->uid);
46860 ++ "(uid: %d, task: %s, pid: %d)\n",
46861 ++ current->uid, current->comm, task_pid_nr(current));
46862 ++ }
46863 ++#endif
46864 ++
46865 ++#ifdef CONFIG_PAX_KERNEXEC
46866 ++#ifdef CONFIG_MODULES
46867 ++ if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
46868 ++#else
46869 ++ if (init_mm.start_code <= address && address < init_mm.end_code)
46870 ++#endif
46871 ++ {
46872 ++ if (current->signal->curr_ip)
46873 ++ printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
46874 ++ NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current->uid, current->euid);
46875 ++ else
46876 ++ printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
46877 ++ current->comm, task_pid_nr(current), current->uid, current->euid);
46878 + }
46879 + #endif
46880 +
46881 +@@ -586,13 +630,22 @@ void __kprobes do_page_fault(struct pt_r
46882 + struct task_struct *tsk;
46883 + struct mm_struct *mm;
46884 + struct vm_area_struct *vma;
46885 +- unsigned long address;
46886 + int write, si_code;
46887 + int fault;
46888 + #ifdef CONFIG_X86_64
46889 + unsigned long flags;
46890 + #endif
46891 +
46892 ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
46893 ++ pte_t *pte;
46894 ++ pmd_t *pmd;
46895 ++ spinlock_t *ptl;
46896 ++ unsigned char pte_mask;
46897 ++#endif
46898 ++
46899 ++ /* get the address */
46900 ++ const unsigned long address = read_cr2();
46901 ++
46902 + /*
46903 + * We can fault from pretty much anywhere, with unknown IRQ state.
46904 + */
46905 +@@ -602,9 +655,6 @@ void __kprobes do_page_fault(struct pt_r
46906 + mm = tsk->mm;
46907 + prefetchw(&mm->mmap_sem);
46908 +
46909 +- /* get the address */
46910 +- address = read_cr2();
46911 +-
46912 + si_code = SEGV_MAPERR;
46913 +
46914 + if (notify_page_fault(regs))
46915 +@@ -657,7 +707,7 @@ void __kprobes do_page_fault(struct pt_r
46916 + * atomic region then we must not take the fault.
46917 + */
46918 + if (in_atomic() || !mm)
46919 +- goto bad_area_nosemaphore;
46920 ++ goto bad_area_nopax;
46921 + #else /* CONFIG_X86_64 */
46922 + if (likely(regs->flags & X86_EFLAGS_IF))
46923 + local_irq_enable();
46924 +@@ -670,13 +720,13 @@ void __kprobes do_page_fault(struct pt_r
46925 + * atomic region then we must not take the fault.
46926 + */
46927 + if (unlikely(in_atomic() || !mm))
46928 +- goto bad_area_nosemaphore;
46929 ++ goto bad_area_nopax;
46930 +
46931 + /*
46932 + * User-mode registers count as a user access even for any
46933 + * potential system fault or CPU buglet.
46934 + */
46935 +- if (user_mode_vm(regs))
46936 ++ if (user_mode(regs))
46937 + error_code |= PF_USER;
46938 + again:
46939 + #endif
46940 +@@ -698,10 +748,104 @@ again:
46941 + if (!down_read_trylock(&mm->mmap_sem)) {
46942 + if ((error_code & PF_USER) == 0 &&
46943 + !search_exception_tables(regs->ip))
46944 +- goto bad_area_nosemaphore;
46945 ++ goto bad_area_nopax;
46946 + down_read(&mm->mmap_sem);
46947 + }
46948 +
46949 ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
46950 ++ if (nx_enabled || (error_code & (PF_PROT|PF_USER)) != (PF_PROT|PF_USER) || v8086_mode(regs) ||
46951 ++ !(mm->pax_flags & MF_PAX_PAGEEXEC))
46952 ++ goto not_pax_fault;
46953 ++
46954 ++ /* PaX: it's our fault, let's handle it if we can */
46955 ++
46956 ++ /* PaX: take a look at read faults before acquiring any locks */
46957 ++ if (unlikely(!(error_code & PF_WRITE) && (regs->ip == address))) {
46958 ++ /* instruction fetch attempt from a protected page in user mode */
46959 ++ up_read(&mm->mmap_sem);
46960 ++
46961 ++#ifdef CONFIG_PAX_EMUTRAMP
46962 ++ switch (pax_handle_fetch_fault(regs)) {
46963 ++ case 2:
46964 ++ return;
46965 ++ }
46966 ++#endif
46967 ++
46968 ++ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
46969 ++ do_group_exit(SIGKILL);
46970 ++ }
46971 ++
46972 ++ pmd = pax_get_pmd(mm, address);
46973 ++ if (unlikely(!pmd))
46974 ++ goto not_pax_fault;
46975 ++
46976 ++ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
46977 ++ if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
46978 ++ pte_unmap_unlock(pte, ptl);
46979 ++ goto not_pax_fault;
46980 ++ }
46981 ++
46982 ++ if (unlikely((error_code & PF_WRITE) && !pte_write(*pte))) {
46983 ++ /* write attempt to a protected page in user mode */
46984 ++ pte_unmap_unlock(pte, ptl);
46985 ++ goto not_pax_fault;
46986 ++ }
46987 ++
46988 ++#ifdef CONFIG_SMP
46989 ++ if (likely(address > get_limit(regs->cs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
46990 ++#else
46991 ++ if (likely(address > get_limit(regs->cs)))
46992 ++#endif
46993 ++ {
46994 ++ set_pte(pte, pte_mkread(*pte));
46995 ++ __flush_tlb_one(address);
46996 ++ pte_unmap_unlock(pte, ptl);
46997 ++ up_read(&mm->mmap_sem);
46998 ++ return;
46999 ++ }
47000 ++
47001 ++ pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & PF_WRITE) << (_PAGE_BIT_DIRTY-1));
47002 ++
47003 ++ /*
47004 ++ * PaX: fill DTLB with user rights and retry
47005 ++ */
47006 ++ __asm__ __volatile__ (
47007 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
47008 ++ "movw %w4,%%es\n"
47009 ++#endif
47010 ++ "orb %2,(%1)\n"
47011 ++#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
47012 ++/*
47013 ++ * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
47014 ++ * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
47015 ++ * page fault when examined during a TLB load attempt. this is true not only
47016 ++ * for PTEs holding a non-present entry but also present entries that will
47017 ++ * raise a page fault (such as those set up by PaX, or the copy-on-write
47018 ++ * mechanism). in effect it means that we do *not* need to flush the TLBs
47019 ++ * for our target pages since their PTEs are simply not in the TLBs at all.
47020 ++
47021 ++ * the best thing in omitting it is that we gain around 15-20% speed in the
47022 ++ * fast path of the page fault handler and can get rid of tracing since we
47023 ++ * can no longer flush unintended entries.
47024 ++ */
47025 ++ "invlpg (%0)\n"
47026 ++#endif
47027 ++ "testb $0,%%es:(%0)\n"
47028 ++ "xorb %3,(%1)\n"
47029 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
47030 ++ "pushl %%ss\n"
47031 ++ "popl %%es\n"
47032 ++#endif
47033 ++ :
47034 ++ : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
47035 ++ : "memory", "cc");
47036 ++ pte_unmap_unlock(pte, ptl);
47037 ++ up_read(&mm->mmap_sem);
47038 ++ return;
47039 ++
47040 ++not_pax_fault:
47041 ++#endif
47042 ++
47043 + vma = find_vma(mm, address);
47044 + if (!vma)
47045 + goto bad_area;
47046 +@@ -719,6 +863,12 @@ again:
47047 + if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp)
47048 + goto bad_area;
47049 + }
47050 ++
47051 ++#ifdef CONFIG_PAX_SEGMEXEC
47052 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)
47053 ++ goto bad_area;
47054 ++#endif
47055 ++
47056 + if (expand_stack(vma, address))
47057 + goto bad_area;
47058 + /*
47059 +@@ -728,6 +878,8 @@ again:
47060 + good_area:
47061 + si_code = SEGV_ACCERR;
47062 + write = 0;
47063 ++ if (nx_enabled && (error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
47064 ++ goto bad_area;
47065 + switch (error_code & (PF_PROT|PF_WRITE)) {
47066 + default: /* 3: write, present */
47067 + /* fall through */
47068 +@@ -785,6 +937,54 @@ bad_area:
47069 + up_read(&mm->mmap_sem);
47070 +
47071 + bad_area_nosemaphore:
47072 ++
47073 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
47074 ++ if (mm && (error_code & PF_USER)) {
47075 ++ unsigned long ip = regs->ip;
47076 ++
47077 ++ if (v8086_mode(regs))
47078 ++ ip = ((regs->cs & 0xffff) << 4) + (regs->ip & 0xffff);
47079 ++
47080 ++ /*
47081 ++ * It's possible to have interrupts off here.
47082 ++ */
47083 ++ local_irq_enable();
47084 ++
47085 ++#ifdef CONFIG_PAX_PAGEEXEC
47086 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) &&
47087 ++ ((nx_enabled && (error_code & PF_INSTR)) || (!(error_code & (PF_PROT | PF_WRITE)) && regs->ip == address))) {
47088 ++
47089 ++#ifdef CONFIG_PAX_EMUTRAMP
47090 ++ switch (pax_handle_fetch_fault(regs)) {
47091 ++ case 2:
47092 ++ return;
47093 ++ }
47094 ++#endif
47095 ++
47096 ++ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
47097 ++ do_group_exit(SIGKILL);
47098 ++ }
47099 ++#endif
47100 ++
47101 ++#ifdef CONFIG_PAX_SEGMEXEC
47102 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & (PF_PROT | PF_WRITE)) && (regs->ip + SEGMEXEC_TASK_SIZE == address)) {
47103 ++
47104 ++#ifdef CONFIG_PAX_EMUTRAMP
47105 ++ switch (pax_handle_fetch_fault(regs)) {
47106 ++ case 2:
47107 ++ return;
47108 ++ }
47109 ++#endif
47110 ++
47111 ++ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
47112 ++ do_group_exit(SIGKILL);
47113 ++ }
47114 ++#endif
47115 ++
47116 ++ }
47117 ++#endif
47118 ++
47119 ++bad_area_nopax:
47120 + /* User mode accesses just cause a SIGSEGV */
47121 + if (error_code & PF_USER) {
47122 + /*
47123 +@@ -863,7 +1063,7 @@ no_context:
47124 + #ifdef CONFIG_X86_32
47125 + die("Oops", regs, error_code);
47126 + bust_spinlocks(0);
47127 +- do_exit(SIGKILL);
47128 ++ do_group_exit(SIGKILL);
47129 + #else
47130 + if (__die("Oops", regs, error_code))
47131 + regs = NULL;
47132 +@@ -877,17 +1077,17 @@ no_context:
47133 + * us unable to handle the page fault gracefully.
47134 + */
47135 + out_of_memory:
47136 +- up_read(&mm->mmap_sem);
47137 + if (is_global_init(tsk)) {
47138 + yield();
47139 + #ifdef CONFIG_X86_32
47140 +- down_read(&mm->mmap_sem);
47141 + goto survive;
47142 + #else
47143 ++ up_read(&mm->mmap_sem);
47144 + goto again;
47145 + #endif
47146 + }
47147 +
47148 ++ up_read(&mm->mmap_sem);
47149 + printk("VM: killing process %s\n", tsk->comm);
47150 + if (error_code & PF_USER)
47151 + do_group_exit(SIGKILL);
47152 +@@ -959,3 +1159,174 @@ void vmalloc_sync_all(void)
47153 + }
47154 + #endif
47155 + }
47156 ++
47157 ++#ifdef CONFIG_PAX_EMUTRAMP
47158 ++static int pax_handle_fetch_fault_32(struct pt_regs *regs)
47159 ++{
47160 ++ int err;
47161 ++
47162 ++ do { /* PaX: gcc trampoline emulation #1 */
47163 ++ unsigned char mov1, mov2;
47164 ++ unsigned short jmp;
47165 ++ unsigned int addr1, addr2;
47166 ++
47167 ++#ifdef CONFIG_X86_64
47168 ++ if ((regs->ip + 11) >> 32)
47169 ++ break;
47170 ++#endif
47171 ++
47172 ++ err = get_user(mov1, (unsigned char __user *)regs->ip);
47173 ++ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
47174 ++ err |= get_user(mov2, (unsigned char __user *)(regs->ip + 5));
47175 ++ err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
47176 ++ err |= get_user(jmp, (unsigned short __user *)(regs->ip + 10));
47177 ++
47178 ++ if (err)
47179 ++ break;
47180 ++
47181 ++ if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
47182 ++ regs->cx = addr1;
47183 ++ regs->ax = addr2;
47184 ++ regs->ip = addr2;
47185 ++ return 2;
47186 ++ }
47187 ++ } while (0);
47188 ++
47189 ++ do { /* PaX: gcc trampoline emulation #2 */
47190 ++ unsigned char mov, jmp;
47191 ++ unsigned int addr1, addr2;
47192 ++
47193 ++#ifdef CONFIG_X86_64
47194 ++ if ((regs->ip + 9) >> 32)
47195 ++ break;
47196 ++#endif
47197 ++
47198 ++ err = get_user(mov, (unsigned char __user *)regs->ip);
47199 ++ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
47200 ++ err |= get_user(jmp, (unsigned char __user *)(regs->ip + 5));
47201 ++ err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
47202 ++
47203 ++ if (err)
47204 ++ break;
47205 ++
47206 ++ if (mov == 0xB9 && jmp == 0xE9) {
47207 ++ regs->cx = addr1;
47208 ++ regs->ip = (unsigned int)(regs->ip + addr2 + 10);
47209 ++ return 2;
47210 ++ }
47211 ++ } while (0);
47212 ++
47213 ++ return 1; /* PaX in action */
47214 ++}
47215 ++
47216 ++#ifdef CONFIG_X86_64
47217 ++static int pax_handle_fetch_fault_64(struct pt_regs *regs)
47218 ++{
47219 ++ int err;
47220 ++
47221 ++ do { /* PaX: gcc trampoline emulation #1 */
47222 ++ unsigned short mov1, mov2, jmp1;
47223 ++ unsigned char jmp2;
47224 ++ unsigned int addr1;
47225 ++ unsigned long addr2;
47226 ++
47227 ++ err = get_user(mov1, (unsigned short __user *)regs->ip);
47228 ++ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 2));
47229 ++ err |= get_user(mov2, (unsigned short __user *)(regs->ip + 6));
47230 ++ err |= get_user(addr2, (unsigned long __user *)(regs->ip + 8));
47231 ++ err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 16));
47232 ++ err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 18));
47233 ++
47234 ++ if (err)
47235 ++ break;
47236 ++
47237 ++ if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
47238 ++ regs->r11 = addr1;
47239 ++ regs->r10 = addr2;
47240 ++ regs->ip = addr1;
47241 ++ return 2;
47242 ++ }
47243 ++ } while (0);
47244 ++
47245 ++ do { /* PaX: gcc trampoline emulation #2 */
47246 ++ unsigned short mov1, mov2, jmp1;
47247 ++ unsigned char jmp2;
47248 ++ unsigned long addr1, addr2;
47249 ++
47250 ++ err = get_user(mov1, (unsigned short __user *)regs->ip);
47251 ++ err |= get_user(addr1, (unsigned long __user *)(regs->ip + 2));
47252 ++ err |= get_user(mov2, (unsigned short __user *)(regs->ip + 10));
47253 ++ err |= get_user(addr2, (unsigned long __user *)(regs->ip + 12));
47254 ++ err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 20));
47255 ++ err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 22));
47256 ++
47257 ++ if (err)
47258 ++ break;
47259 ++
47260 ++ if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
47261 ++ regs->r11 = addr1;
47262 ++ regs->r10 = addr2;
47263 ++ regs->ip = addr1;
47264 ++ return 2;
47265 ++ }
47266 ++ } while (0);
47267 ++
47268 ++ return 1; /* PaX in action */
47269 ++}
47270 ++#endif
47271 ++
47272 ++/*
47273 ++ * PaX: decide what to do with offenders (regs->ip = fault address)
47274 ++ *
47275 ++ * returns 1 when task should be killed
47276 ++ * 2 when gcc trampoline was detected
47277 ++ */
47278 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
47279 ++{
47280 ++ if (v8086_mode(regs))
47281 ++ return 1;
47282 ++
47283 ++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
47284 ++ return 1;
47285 ++
47286 ++#ifdef CONFIG_X86_32
47287 ++ return pax_handle_fetch_fault_32(regs);
47288 ++#else
47289 ++ if (regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT))
47290 ++ return pax_handle_fetch_fault_32(regs);
47291 ++ else
47292 ++ return pax_handle_fetch_fault_64(regs);
47293 ++#endif
47294 ++}
47295 ++#endif
47296 ++
47297 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
47298 ++void pax_report_insns(void *pc, void *sp)
47299 ++{
47300 ++ long i;
47301 ++
47302 ++ printk(KERN_ERR "PAX: bytes at PC: ");
47303 ++ for (i = 0; i < 20; i++) {
47304 ++ unsigned char c;
47305 ++ if (get_user(c, (unsigned char __user *)pc+i))
47306 ++ printk(KERN_CONT "?? ");
47307 ++ else
47308 ++ printk(KERN_CONT "%02x ", c);
47309 ++ }
47310 ++ printk("\n");
47311 ++
47312 ++ printk(KERN_ERR "PAX: bytes at SP-%lu: ", (unsigned long)sizeof(long));
47313 ++ for (i = -1; i < 80 / sizeof(long); i++) {
47314 ++ unsigned long c;
47315 ++ if (get_user(c, (unsigned long __user *)sp+i))
47316 ++#ifdef CONFIG_X86_32
47317 ++ printk(KERN_CONT "???????? ");
47318 ++#else
47319 ++ printk(KERN_CONT "???????????????? ");
47320 ++#endif
47321 ++ else
47322 ++ printk(KERN_CONT "%0*lx ", 2 * (int)sizeof(long), c);
47323 ++ }
47324 ++ printk("\n");
47325 ++}
47326 ++#endif
47327 +diff -urNp linux-2.6.27.7/arch/x86/mm/highmem_32.c linux-2.6.27.7/arch/x86/mm/highmem_32.c
47328 +--- linux-2.6.27.7/arch/x86/mm/highmem_32.c 2008-11-07 12:55:34.000000000 -0500
47329 ++++ linux-2.6.27.7/arch/x86/mm/highmem_32.c 2008-11-18 03:38:44.000000000 -0500
47330 +@@ -74,6 +74,10 @@ void *kmap_atomic_prot(struct page *page
47331 + enum fixed_addresses idx;
47332 + unsigned long vaddr;
47333 +
47334 ++#ifdef CONFIG_PAX_KERNEXEC
47335 ++ unsigned long cr0;
47336 ++#endif
47337 ++
47338 + /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
47339 + pagefault_disable();
47340 +
47341 +@@ -85,7 +89,17 @@ void *kmap_atomic_prot(struct page *page
47342 + idx = type + KM_TYPE_NR*smp_processor_id();
47343 + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
47344 + BUG_ON(!pte_none(*(kmap_pte-idx)));
47345 ++
47346 ++#ifdef CONFIG_PAX_KERNEXEC
47347 ++ pax_open_kernel(cr0);
47348 ++#endif
47349 ++
47350 + set_pte(kmap_pte-idx, mk_pte(page, prot));
47351 ++
47352 ++#ifdef CONFIG_PAX_KERNEXEC
47353 ++ pax_close_kernel(cr0);
47354 ++#endif
47355 ++
47356 + arch_flush_lazy_mmu_mode();
47357 +
47358 + return (void *)vaddr;
47359 +@@ -101,15 +115,29 @@ void kunmap_atomic(void *kvaddr, enum km
47360 + unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
47361 + enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
47362 +
47363 ++#ifdef CONFIG_PAX_KERNEXEC
47364 ++ unsigned long cr0;
47365 ++#endif
47366 ++
47367 + /*
47368 + * Force other mappings to Oops if they'll try to access this pte
47369 + * without first remap it. Keeping stale mappings around is a bad idea
47370 + * also, in case the page changes cacheability attributes or becomes
47371 + * a protected page in a hypervisor.
47372 + */
47373 +- if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx))
47374 ++ if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) {
47375 ++
47376 ++#ifdef CONFIG_PAX_KERNEXEC
47377 ++ pax_open_kernel(cr0);
47378 ++#endif
47379 ++
47380 + kpte_clear_flush(kmap_pte-idx, vaddr);
47381 +- else {
47382 ++
47383 ++#ifdef CONFIG_PAX_KERNEXEC
47384 ++ pax_close_kernel(cr0);
47385 ++#endif
47386 ++
47387 ++ } else {
47388 + #ifdef CONFIG_DEBUG_HIGHMEM
47389 + BUG_ON(vaddr < PAGE_OFFSET);
47390 + BUG_ON(vaddr >= (unsigned long)high_memory);
47391 +@@ -128,11 +156,25 @@ void *kmap_atomic_pfn(unsigned long pfn,
47392 + enum fixed_addresses idx;
47393 + unsigned long vaddr;
47394 +
47395 ++#ifdef CONFIG_PAX_KERNEXEC
47396 ++ unsigned long cr0;
47397 ++#endif
47398 ++
47399 + pagefault_disable();
47400 +
47401 + idx = type + KM_TYPE_NR*smp_processor_id();
47402 + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
47403 ++
47404 ++#ifdef CONFIG_PAX_KERNEXEC
47405 ++ pax_open_kernel(cr0);
47406 ++#endif
47407 ++
47408 + set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
47409 ++
47410 ++#ifdef CONFIG_PAX_KERNEXEC
47411 ++ pax_close_kernel(cr0);
47412 ++#endif
47413 ++
47414 + arch_flush_lazy_mmu_mode();
47415 +
47416 + return (void*) vaddr;
47417 +diff -urNp linux-2.6.27.7/arch/x86/mm/hugetlbpage.c linux-2.6.27.7/arch/x86/mm/hugetlbpage.c
47418 +--- linux-2.6.27.7/arch/x86/mm/hugetlbpage.c 2008-11-07 12:55:34.000000000 -0500
47419 ++++ linux-2.6.27.7/arch/x86/mm/hugetlbpage.c 2008-11-18 03:38:44.000000000 -0500
47420 +@@ -263,13 +263,18 @@ static unsigned long hugetlb_get_unmappe
47421 + struct hstate *h = hstate_file(file);
47422 + struct mm_struct *mm = current->mm;
47423 + struct vm_area_struct *vma;
47424 +- unsigned long start_addr;
47425 ++ unsigned long start_addr, pax_task_size = TASK_SIZE;
47426 ++
47427 ++#ifdef CONFIG_PAX_SEGMEXEC
47428 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
47429 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
47430 ++#endif
47431 +
47432 + if (len > mm->cached_hole_size) {
47433 +- start_addr = mm->free_area_cache;
47434 ++ start_addr = mm->free_area_cache;
47435 + } else {
47436 +- start_addr = TASK_UNMAPPED_BASE;
47437 +- mm->cached_hole_size = 0;
47438 ++ start_addr = mm->mmap_base;
47439 ++ mm->cached_hole_size = 0;
47440 + }
47441 +
47442 + full_search:
47443 +@@ -277,13 +282,13 @@ full_search:
47444 +
47445 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
47446 + /* At this point: (!vma || addr < vma->vm_end). */
47447 +- if (TASK_SIZE - len < addr) {
47448 ++ if (pax_task_size - len < addr) {
47449 + /*
47450 + * Start a new search - just in case we missed
47451 + * some holes.
47452 + */
47453 +- if (start_addr != TASK_UNMAPPED_BASE) {
47454 +- start_addr = TASK_UNMAPPED_BASE;
47455 ++ if (start_addr != mm->mmap_base) {
47456 ++ start_addr = mm->mmap_base;
47457 + mm->cached_hole_size = 0;
47458 + goto full_search;
47459 + }
47460 +@@ -306,9 +311,8 @@ static unsigned long hugetlb_get_unmappe
47461 + struct hstate *h = hstate_file(file);
47462 + struct mm_struct *mm = current->mm;
47463 + struct vm_area_struct *vma, *prev_vma;
47464 +- unsigned long base = mm->mmap_base, addr = addr0;
47465 ++ unsigned long base = mm->mmap_base, addr;
47466 + unsigned long largest_hole = mm->cached_hole_size;
47467 +- int first_time = 1;
47468 +
47469 + /* don't allow allocations above current base */
47470 + if (mm->free_area_cache > base)
47471 +@@ -318,7 +322,7 @@ static unsigned long hugetlb_get_unmappe
47472 + largest_hole = 0;
47473 + mm->free_area_cache = base;
47474 + }
47475 +-try_again:
47476 ++
47477 + /* make sure it can fit in the remaining address space */
47478 + if (mm->free_area_cache < len)
47479 + goto fail;
47480 +@@ -360,22 +364,26 @@ try_again:
47481 +
47482 + fail:
47483 + /*
47484 +- * if hint left us with no space for the requested
47485 +- * mapping then try again:
47486 +- */
47487 +- if (first_time) {
47488 +- mm->free_area_cache = base;
47489 +- largest_hole = 0;
47490 +- first_time = 0;
47491 +- goto try_again;
47492 +- }
47493 +- /*
47494 + * A failed mmap() very likely causes application failure,
47495 + * so fall back to the bottom-up function here. This scenario
47496 + * can happen with large stack limits and large mmap()
47497 + * allocations.
47498 + */
47499 +- mm->free_area_cache = TASK_UNMAPPED_BASE;
47500 ++
47501 ++#ifdef CONFIG_PAX_SEGMEXEC
47502 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
47503 ++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
47504 ++ else
47505 ++#endif
47506 ++
47507 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
47508 ++
47509 ++#ifdef CONFIG_PAX_RANDMMAP
47510 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
47511 ++ mm->mmap_base += mm->delta_mmap;
47512 ++#endif
47513 ++
47514 ++ mm->free_area_cache = mm->mmap_base;
47515 + mm->cached_hole_size = ~0UL;
47516 + addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
47517 + len, pgoff, flags);
47518 +@@ -383,6 +391,7 @@ fail:
47519 + /*
47520 + * Restore the topdown base:
47521 + */
47522 ++ mm->mmap_base = base;
47523 + mm->free_area_cache = base;
47524 + mm->cached_hole_size = ~0UL;
47525 +
47526 +@@ -396,10 +405,17 @@ hugetlb_get_unmapped_area(struct file *f
47527 + struct hstate *h = hstate_file(file);
47528 + struct mm_struct *mm = current->mm;
47529 + struct vm_area_struct *vma;
47530 ++ unsigned long pax_task_size = TASK_SIZE;
47531 +
47532 + if (len & ~huge_page_mask(h))
47533 + return -EINVAL;
47534 +- if (len > TASK_SIZE)
47535 ++
47536 ++#ifdef CONFIG_PAX_SEGMEXEC
47537 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
47538 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
47539 ++#endif
47540 ++
47541 ++ if (len > pax_task_size)
47542 + return -ENOMEM;
47543 +
47544 + if (flags & MAP_FIXED) {
47545 +@@ -411,7 +427,7 @@ hugetlb_get_unmapped_area(struct file *f
47546 + if (addr) {
47547 + addr = ALIGN(addr, huge_page_size(h));
47548 + vma = find_vma(mm, addr);
47549 +- if (TASK_SIZE - len >= addr &&
47550 ++ if (pax_task_size - len >= addr &&
47551 + (!vma || addr + len <= vma->vm_start))
47552 + return addr;
47553 + }
47554 +diff -urNp linux-2.6.27.7/arch/x86/mm/init_32.c linux-2.6.27.7/arch/x86/mm/init_32.c
47555 +--- linux-2.6.27.7/arch/x86/mm/init_32.c 2008-11-07 12:55:34.000000000 -0500
47556 ++++ linux-2.6.27.7/arch/x86/mm/init_32.c 2008-11-18 03:38:44.000000000 -0500
47557 +@@ -47,6 +47,7 @@
47558 + #include <asm/paravirt.h>
47559 + #include <asm/setup.h>
47560 + #include <asm/cacheflush.h>
47561 ++#include <asm/desc.h>
47562 +
47563 + unsigned int __VMALLOC_RESERVE = 128 << 20;
47564 +
47565 +@@ -80,35 +81,6 @@ static __init void *alloc_low_page(unsig
47566 + }
47567 +
47568 + /*
47569 +- * Creates a middle page table and puts a pointer to it in the
47570 +- * given global directory entry. This only returns the gd entry
47571 +- * in non-PAE compilation mode, since the middle layer is folded.
47572 +- */
47573 +-static pmd_t * __init one_md_table_init(pgd_t *pgd)
47574 +-{
47575 +- pud_t *pud;
47576 +- pmd_t *pmd_table;
47577 +-
47578 +-#ifdef CONFIG_X86_PAE
47579 +- unsigned long phys;
47580 +- if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
47581 +- if (after_init_bootmem)
47582 +- pmd_table = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
47583 +- else
47584 +- pmd_table = (pmd_t *)alloc_low_page(&phys);
47585 +- paravirt_alloc_pmd(&init_mm, __pa(pmd_table) >> PAGE_SHIFT);
47586 +- set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
47587 +- pud = pud_offset(pgd, 0);
47588 +- BUG_ON(pmd_table != pmd_offset(pud, 0));
47589 +- }
47590 +-#endif
47591 +- pud = pud_offset(pgd, 0);
47592 +- pmd_table = pmd_offset(pud, 0);
47593 +-
47594 +- return pmd_table;
47595 +-}
47596 +-
47597 +-/*
47598 + * Create a page table and place a pointer to it in a middle page
47599 + * directory entry:
47600 + */
47601 +@@ -130,7 +102,11 @@ static pte_t * __init one_page_table_ini
47602 + }
47603 +
47604 + paravirt_alloc_pte(&init_mm, __pa(page_table) >> PAGE_SHIFT);
47605 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
47606 ++ set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
47607 ++#else
47608 + set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
47609 ++#endif
47610 + BUG_ON(page_table != pte_offset_kernel(pmd, 0));
47611 + }
47612 +
47613 +@@ -152,6 +128,7 @@ page_table_range_init(unsigned long star
47614 + int pgd_idx, pmd_idx;
47615 + unsigned long vaddr;
47616 + pgd_t *pgd;
47617 ++ pud_t *pud;
47618 + pmd_t *pmd;
47619 +
47620 + vaddr = start;
47621 +@@ -160,8 +137,13 @@ page_table_range_init(unsigned long star
47622 + pgd = pgd_base + pgd_idx;
47623 +
47624 + for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
47625 +- pmd = one_md_table_init(pgd);
47626 +- pmd = pmd + pmd_index(vaddr);
47627 ++ pud = pud_offset(pgd, vaddr);
47628 ++ pmd = pmd_offset(pud, vaddr);
47629 ++
47630 ++#ifdef CONFIG_X86_PAE
47631 ++ paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
47632 ++#endif
47633 ++
47634 + for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end);
47635 + pmd++, pmd_idx++) {
47636 + one_page_table_init(pmd);
47637 +@@ -172,11 +154,23 @@ page_table_range_init(unsigned long star
47638 + }
47639 + }
47640 +
47641 +-static inline int is_kernel_text(unsigned long addr)
47642 ++static inline int is_kernel_text(unsigned long start, unsigned long end)
47643 + {
47644 +- if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
47645 +- return 1;
47646 +- return 0;
47647 ++ unsigned long etext;
47648 ++
47649 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
47650 ++ etext = ktva_ktla((unsigned long)&MODULES_END);
47651 ++#else
47652 ++ etext = (unsigned long)&_etext;
47653 ++#endif
47654 ++
47655 ++ if ((start > ktla_ktva(etext) ||
47656 ++ end <= ktla_ktva((unsigned long)_stext)) &&
47657 ++ (start > ktla_ktva((unsigned long)_einittext) ||
47658 ++ end <= ktla_ktva((unsigned long)_sinittext)) &&
47659 ++ (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000)))
47660 ++ return 0;
47661 ++ return 1;
47662 + }
47663 +
47664 + /*
47665 +@@ -189,9 +183,10 @@ static void __init kernel_physical_mappi
47666 + unsigned long end_pfn,
47667 + int use_pse)
47668 + {
47669 +- int pgd_idx, pmd_idx, pte_ofs;
47670 ++ unsigned int pgd_idx, pmd_idx, pte_ofs;
47671 + unsigned long pfn;
47672 + pgd_t *pgd;
47673 ++ pud_t *pud;
47674 + pmd_t *pmd;
47675 + pte_t *pte;
47676 + unsigned pages_2m = 0, pages_4k = 0;
47677 +@@ -202,8 +197,13 @@ static void __init kernel_physical_mappi
47678 + pfn = start_pfn;
47679 + pgd_idx = pgd_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET);
47680 + pgd = pgd_base + pgd_idx;
47681 +- for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
47682 +- pmd = one_md_table_init(pgd);
47683 ++ for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
47684 ++ pud = pud_offset(pgd, 0);
47685 ++ pmd = pmd_offset(pud, 0);
47686 ++
47687 ++#ifdef CONFIG_X86_PAE
47688 ++ paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
47689 ++#endif
47690 +
47691 + if (pfn >= end_pfn)
47692 + continue;
47693 +@@ -215,21 +215,16 @@ static void __init kernel_physical_mappi
47694 + #endif
47695 + for (; pmd_idx < PTRS_PER_PMD && pfn < end_pfn;
47696 + pmd++, pmd_idx++) {
47697 +- unsigned int addr = pfn * PAGE_SIZE + PAGE_OFFSET;
47698 ++ unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
47699 +
47700 + /*
47701 + * Map with big pages if possible, otherwise
47702 + * create normal page tables:
47703 + */
47704 + if (use_pse) {
47705 +- unsigned int addr2;
47706 + pgprot_t prot = PAGE_KERNEL_LARGE;
47707 +
47708 +- addr2 = (pfn + PTRS_PER_PTE-1) * PAGE_SIZE +
47709 +- PAGE_OFFSET + PAGE_SIZE-1;
47710 +-
47711 +- if (is_kernel_text(addr) ||
47712 +- is_kernel_text(addr2))
47713 ++ if (is_kernel_text(address, address + PMD_SIZE))
47714 + prot = PAGE_KERNEL_LARGE_EXEC;
47715 +
47716 + pages_2m++;
47717 +@@ -243,10 +238,10 @@ static void __init kernel_physical_mappi
47718 + pte_ofs = pte_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET);
47719 + pte += pte_ofs;
47720 + for (; pte_ofs < PTRS_PER_PTE && pfn < end_pfn;
47721 +- pte++, pfn++, pte_ofs++, addr += PAGE_SIZE) {
47722 ++ pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
47723 + pgprot_t prot = PAGE_KERNEL;
47724 +
47725 +- if (is_kernel_text(addr))
47726 ++ if (is_kernel_text(address, address + PAGE_SIZE))
47727 + prot = PAGE_KERNEL_EXEC;
47728 +
47729 + pages_4k++;
47730 +@@ -270,7 +265,9 @@ static void __init kernel_physical_mappi
47731 + */
47732 + int devmem_is_allowed(unsigned long pagenr)
47733 + {
47734 +- if (pagenr <= 256)
47735 ++ if (!pagenr)
47736 ++ return 1;
47737 ++ if ((ISA_START_ADDRESS >> PAGE_SHIFT) <= pagenr && pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
47738 + return 1;
47739 + if (!page_is_ram(pagenr))
47740 + return 1;
47741 +@@ -404,7 +401,7 @@ void __init native_pagetable_setup_start
47742 +
47743 + pud = pud_offset(pgd, va);
47744 + pmd = pmd_offset(pud, va);
47745 +- if (!pmd_present(*pmd))
47746 ++ if (!pmd_present(*pmd) || pmd_huge(*pmd))
47747 + break;
47748 +
47749 + pte = pte_offset_kernel(pmd, va);
47750 +@@ -456,9 +453,7 @@ static void __init early_ioremap_page_ta
47751 +
47752 + static void __init pagetable_init(void)
47753 + {
47754 +- pgd_t *pgd_base = swapper_pg_dir;
47755 +-
47756 +- permanent_kmaps_init(pgd_base);
47757 ++ permanent_kmaps_init(swapper_pg_dir);
47758 + }
47759 +
47760 + #ifdef CONFIG_ACPI_SLEEP
47761 +@@ -466,12 +461,12 @@ static void __init pagetable_init(void)
47762 + * ACPI suspend needs this for resume, because things like the intel-agp
47763 + * driver might have split up a kernel 4MB mapping.
47764 + */
47765 +-char swsusp_pg_dir[PAGE_SIZE]
47766 ++pgd_t swsusp_pg_dir[PTRS_PER_PGD]
47767 + __attribute__ ((aligned(PAGE_SIZE)));
47768 +
47769 + static inline void save_pg_dir(void)
47770 + {
47771 +- memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
47772 ++ clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD);
47773 + }
47774 + #else /* !CONFIG_ACPI_SLEEP */
47775 + static inline void save_pg_dir(void)
47776 +@@ -501,13 +496,11 @@ void zap_low_mappings(void)
47777 +
47778 + int nx_enabled;
47779 +
47780 +-pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL);
47781 ++pteval_t __supported_pte_mask __read_only = ~(_PAGE_NX | _PAGE_GLOBAL);
47782 + EXPORT_SYMBOL_GPL(__supported_pte_mask);
47783 +
47784 + #ifdef CONFIG_X86_PAE
47785 +
47786 +-static int disable_nx __initdata;
47787 +-
47788 + /*
47789 + * noexec = on|off
47790 + *
47791 +@@ -516,40 +509,33 @@ static int disable_nx __initdata;
47792 + * on Enable
47793 + * off Disable
47794 + */
47795 ++#if !defined(CONFIG_PAX_PAGEEXEC)
47796 + static int __init noexec_setup(char *str)
47797 + {
47798 + if (!str || !strcmp(str, "on")) {
47799 +- if (cpu_has_nx) {
47800 +- __supported_pte_mask |= _PAGE_NX;
47801 +- disable_nx = 0;
47802 +- }
47803 ++ if (cpu_has_nx)
47804 ++ nx_enabled = 1;
47805 + } else {
47806 +- if (!strcmp(str, "off")) {
47807 +- disable_nx = 1;
47808 +- __supported_pte_mask &= ~_PAGE_NX;
47809 +- } else {
47810 ++ if (!strcmp(str, "off"))
47811 ++ nx_enabled = 0;
47812 ++ else
47813 + return -EINVAL;
47814 +- }
47815 + }
47816 +
47817 + return 0;
47818 + }
47819 + early_param("noexec", noexec_setup);
47820 ++#endif
47821 +
47822 + static void __init set_nx(void)
47823 + {
47824 +- unsigned int v[4], l, h;
47825 +-
47826 +- if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
47827 +- cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
47828 ++ if (!nx_enabled && cpu_has_nx) {
47829 ++ unsigned l, h;
47830 +
47831 +- if ((v[3] & (1 << 20)) && !disable_nx) {
47832 +- rdmsr(MSR_EFER, l, h);
47833 +- l |= EFER_NX;
47834 +- wrmsr(MSR_EFER, l, h);
47835 +- nx_enabled = 1;
47836 +- __supported_pte_mask |= _PAGE_NX;
47837 +- }
47838 ++ __supported_pte_mask &= ~_PAGE_NX;
47839 ++ rdmsr(MSR_EFER, l, h);
47840 ++ l &= ~EFER_NX;
47841 ++ wrmsr(MSR_EFER, l, h);
47842 + }
47843 + }
47844 + #endif
47845 +@@ -920,7 +906,7 @@ void __init mem_init(void)
47846 + set_highmem_pages_init();
47847 +
47848 + codesize = (unsigned long) &_etext - (unsigned long) &_text;
47849 +- datasize = (unsigned long) &_edata - (unsigned long) &_etext;
47850 ++ datasize = (unsigned long) &_edata - (unsigned long) &_data;
47851 + initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
47852 +
47853 + kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
47854 +@@ -966,10 +952,10 @@ void __init mem_init(void)
47855 + ((unsigned long)&__init_end -
47856 + (unsigned long)&__init_begin) >> 10,
47857 +
47858 +- (unsigned long)&_etext, (unsigned long)&_edata,
47859 +- ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
47860 ++ (unsigned long)&_data, (unsigned long)&_edata,
47861 ++ ((unsigned long)&_edata - (unsigned long)&_data) >> 10,
47862 +
47863 +- (unsigned long)&_text, (unsigned long)&_etext,
47864 ++ ktla_ktva((unsigned long)&_text), ktla_ktva((unsigned long)&_etext),
47865 + ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
47866 +
47867 + #ifdef CONFIG_HIGHMEM
47868 +@@ -1099,6 +1085,46 @@ void free_init_pages(char *what, unsigne
47869 +
47870 + void free_initmem(void)
47871 + {
47872 ++
47873 ++#ifdef CONFIG_PAX_KERNEXEC
47874 ++ /* PaX: limit KERNEL_CS to actual size */
47875 ++ unsigned long addr, limit;
47876 ++ struct desc_struct d;
47877 ++ int cpu;
47878 ++ pgd_t *pgd;
47879 ++ pud_t *pud;
47880 ++ pmd_t *pmd;
47881 ++
47882 ++#ifdef CONFIG_MODULES
47883 ++ limit = ktva_ktla((unsigned long)&MODULES_END);
47884 ++#else
47885 ++ limit = (unsigned long)&_etext;
47886 ++#endif
47887 ++ limit = (limit - 1UL) >> PAGE_SHIFT;
47888 ++
47889 ++ for (cpu = 0; cpu < NR_CPUS; cpu++) {
47890 ++ pack_descriptor(&d, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC);
47891 ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, &d, DESCTYPE_S);
47892 ++ }
47893 ++
47894 ++ /* PaX: make KERNEL_CS read-only */
47895 ++ for (addr = ktla_ktva((unsigned long)&_text); addr < (unsigned long)&_data; addr += PMD_SIZE) {
47896 ++ pgd = pgd_offset_k(addr);
47897 ++ pud = pud_offset(pgd, addr);
47898 ++ pmd = pmd_offset(pud, addr);
47899 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
47900 ++ }
47901 ++#ifdef CONFIG_X86_PAE
47902 ++ for (addr = (unsigned long)&__init_begin; addr < (unsigned long)&__init_end; addr += PMD_SIZE) {
47903 ++ pgd = pgd_offset_k(addr);
47904 ++ pud = pud_offset(pgd, addr);
47905 ++ pmd = pmd_offset(pud, addr);
47906 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
47907 ++ }
47908 ++#endif
47909 ++ flush_tlb_all();
47910 ++#endif
47911 ++
47912 + free_init_pages("unused kernel memory",
47913 + (unsigned long)(&__init_begin),
47914 + (unsigned long)(&__init_end));
47915 +diff -urNp linux-2.6.27.7/arch/x86/mm/init_64.c linux-2.6.27.7/arch/x86/mm/init_64.c
47916 +--- linux-2.6.27.7/arch/x86/mm/init_64.c 2008-11-07 12:55:34.000000000 -0500
47917 ++++ linux-2.6.27.7/arch/x86/mm/init_64.c 2008-11-18 03:38:44.000000000 -0500
47918 +@@ -118,6 +118,10 @@ set_pte_vaddr_pud(pud_t *pud_page, unsig
47919 + pmd_t *pmd;
47920 + pte_t *pte;
47921 +
47922 ++#ifdef CONFIG_PAX_KERNEXEC
47923 ++ unsigned long cr0;
47924 ++#endif
47925 ++
47926 + pud = pud_page + pud_index(vaddr);
47927 + if (pud_none(*pud)) {
47928 + pmd = (pmd_t *) spp_getpage();
47929 +@@ -142,8 +146,17 @@ set_pte_vaddr_pud(pud_t *pud_page, unsig
47930 + if (!pte_none(*pte) && pte_val(new_pte) &&
47931 + pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask))
47932 + pte_ERROR(*pte);
47933 ++
47934 ++#ifdef CONFIG_PAX_KERNEXEC
47935 ++ pax_open_kernel(cr0);
47936 ++#endif
47937 ++
47938 + set_pte(pte, new_pte);
47939 +
47940 ++#ifdef CONFIG_PAX_KERNEXEC
47941 ++ pax_close_kernel(cr0);
47942 ++#endif
47943 ++
47944 + /*
47945 + * It's enough to flush this one mapping.
47946 + * (PGE mappings get flushed as well)
47947 +@@ -184,14 +197,12 @@ static void __init __init_extra_mapping(
47948 + pgd = pgd_offset_k((unsigned long)__va(phys));
47949 + if (pgd_none(*pgd)) {
47950 + pud = (pud_t *) spp_getpage();
47951 +- set_pgd(pgd, __pgd(__pa(pud) | _KERNPG_TABLE |
47952 +- _PAGE_USER));
47953 ++ set_pgd(pgd, __pgd(__pa(pud) | _PAGE_TABLE));
47954 + }
47955 + pud = pud_offset(pgd, (unsigned long)__va(phys));
47956 + if (pud_none(*pud)) {
47957 + pmd = (pmd_t *) spp_getpage();
47958 +- set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE |
47959 +- _PAGE_USER));
47960 ++ set_pud(pud, __pud(__pa(pmd) | _PAGE_TABLE));
47961 + }
47962 + pmd = pmd_offset(pud, phys);
47963 + BUG_ON(!pmd_none(*pmd));
47964 +@@ -754,7 +765,9 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to
47965 + */
47966 + int devmem_is_allowed(unsigned long pagenr)
47967 + {
47968 +- if (pagenr <= 256)
47969 ++ if (!pagenr)
47970 ++ return 1;
47971 ++ if ((ISA_START_ADDRESS >> PAGE_SHIFT) <= pagenr && pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
47972 + return 1;
47973 + if (!page_is_ram(pagenr))
47974 + return 1;
47975 +@@ -842,6 +855,39 @@ void free_init_pages(char *what, unsigne
47976 +
47977 + void free_initmem(void)
47978 + {
47979 ++
47980 ++#ifdef CONFIG_PAX_KERNEXEC
47981 ++ unsigned long addr, end;
47982 ++ pgd_t *pgd;
47983 ++ pud_t *pud;
47984 ++ pmd_t *pmd;
47985 ++
47986 ++ /* PaX: make kernel code/rodata read-only, rest non-executable */
47987 ++ for (addr = __START_KERNEL_map; addr < __START_KERNEL_map + KERNEL_IMAGE_SIZE; addr += PMD_SIZE) {
47988 ++ pgd = pgd_offset_k(addr);
47989 ++ pud = pud_offset(pgd, addr);
47990 ++ pmd = pmd_offset(pud, addr);
47991 ++ if ((unsigned long)_text <= addr && addr < (unsigned long)_data)
47992 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
47993 ++ else
47994 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
47995 ++ }
47996 ++
47997 ++ addr = (unsigned long)__va(__pa(__START_KERNEL_map));
47998 ++ end = addr + KERNEL_IMAGE_SIZE;
47999 ++ for (; addr < end; addr += PMD_SIZE) {
48000 ++ pgd = pgd_offset_k(addr);
48001 ++ pud = pud_offset(pgd, addr);
48002 ++ pmd = pmd_offset(pud, addr);
48003 ++ if ((unsigned long)__va(__pa(_text)) <= addr && addr < (unsigned long)__va(__pa(_data)))
48004 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
48005 ++ else
48006 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
48007 ++ }
48008 ++
48009 ++ flush_tlb_all();
48010 ++#endif
48011 ++
48012 + free_init_pages("unused kernel memory",
48013 + (unsigned long)(&__init_begin),
48014 + (unsigned long)(&__init_end));
48015 +@@ -1014,7 +1060,7 @@ int in_gate_area_no_task(unsigned long a
48016 +
48017 + const char *arch_vma_name(struct vm_area_struct *vma)
48018 + {
48019 +- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
48020 ++ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
48021 + return "[vdso]";
48022 + if (vma == &gate_vma)
48023 + return "[vsyscall]";
48024 +diff -urNp linux-2.6.27.7/arch/x86/mm/ioremap.c linux-2.6.27.7/arch/x86/mm/ioremap.c
48025 +--- linux-2.6.27.7/arch/x86/mm/ioremap.c 2008-11-07 12:55:34.000000000 -0500
48026 ++++ linux-2.6.27.7/arch/x86/mm/ioremap.c 2008-11-18 03:38:44.000000000 -0500
48027 +@@ -63,8 +63,8 @@ int page_is_ram(unsigned long pagenr)
48028 + * Second special case: Some BIOSen report the PC BIOS
48029 + * area (640->1Mb) as ram even though it is not.
48030 + */
48031 +- if (pagenr >= (BIOS_BEGIN >> PAGE_SHIFT) &&
48032 +- pagenr < (BIOS_END >> PAGE_SHIFT))
48033 ++ if (pagenr >= (ISA_START_ADDRESS >> PAGE_SHIFT) &&
48034 ++ pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
48035 + return 0;
48036 +
48037 + for (i = 0; i < e820.nr_map; i++) {
48038 +@@ -217,6 +217,8 @@ static void __iomem *__ioremap_caller(re
48039 + break;
48040 + }
48041 +
48042 ++ prot = canon_pgprot(prot);
48043 ++
48044 + /*
48045 + * Ok, go for it..
48046 + */
48047 +diff -urNp linux-2.6.27.7/arch/x86/mm/mmap.c linux-2.6.27.7/arch/x86/mm/mmap.c
48048 +--- linux-2.6.27.7/arch/x86/mm/mmap.c 2008-11-07 12:55:34.000000000 -0500
48049 ++++ linux-2.6.27.7/arch/x86/mm/mmap.c 2008-11-18 03:38:44.000000000 -0500
48050 +@@ -36,7 +36,7 @@
48051 + * Leave an at least ~128 MB hole.
48052 + */
48053 + #define MIN_GAP (128*1024*1024)
48054 +-#define MAX_GAP (TASK_SIZE/6*5)
48055 ++#define MAX_GAP (pax_task_size/6*5)
48056 +
48057 + /*
48058 + * True on X86_32 or when emulating IA32 on X86_64
48059 +@@ -81,27 +81,40 @@ static unsigned long mmap_rnd(void)
48060 + return rnd << PAGE_SHIFT;
48061 + }
48062 +
48063 +-static unsigned long mmap_base(void)
48064 ++static unsigned long mmap_base(struct mm_struct *mm)
48065 + {
48066 + unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
48067 ++ unsigned long pax_task_size = TASK_SIZE;
48068 ++
48069 ++#ifdef CONFIG_PAX_SEGMEXEC
48070 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
48071 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
48072 ++#endif
48073 +
48074 + if (gap < MIN_GAP)
48075 + gap = MIN_GAP;
48076 + else if (gap > MAX_GAP)
48077 + gap = MAX_GAP;
48078 +
48079 +- return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
48080 ++ return PAGE_ALIGN(pax_task_size - gap - mmap_rnd());
48081 + }
48082 +
48083 + /*
48084 + * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64
48085 + * does, but not when emulating X86_32
48086 + */
48087 +-static unsigned long mmap_legacy_base(void)
48088 ++static unsigned long mmap_legacy_base(struct mm_struct *mm)
48089 + {
48090 +- if (mmap_is_ia32())
48091 ++ if (mmap_is_ia32()) {
48092 ++
48093 ++#ifdef CONFIG_PAX_SEGMEXEC
48094 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
48095 ++ return SEGMEXEC_TASK_UNMAPPED_BASE;
48096 ++ else
48097 ++#endif
48098 ++
48099 + return TASK_UNMAPPED_BASE;
48100 +- else
48101 ++ } else
48102 + return TASK_UNMAPPED_BASE + mmap_rnd();
48103 + }
48104 +
48105 +@@ -112,11 +125,23 @@ static unsigned long mmap_legacy_base(vo
48106 + void arch_pick_mmap_layout(struct mm_struct *mm)
48107 + {
48108 + if (mmap_is_legacy()) {
48109 +- mm->mmap_base = mmap_legacy_base();
48110 ++ mm->mmap_base = mmap_legacy_base(mm);
48111 ++
48112 ++#ifdef CONFIG_PAX_RANDMMAP
48113 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
48114 ++ mm->mmap_base += mm->delta_mmap;
48115 ++#endif
48116 ++
48117 + mm->get_unmapped_area = arch_get_unmapped_area;
48118 + mm->unmap_area = arch_unmap_area;
48119 + } else {
48120 +- mm->mmap_base = mmap_base();
48121 ++ mm->mmap_base = mmap_base(mm);
48122 ++
48123 ++#ifdef CONFIG_PAX_RANDMMAP
48124 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
48125 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
48126 ++#endif
48127 ++
48128 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
48129 + mm->unmap_area = arch_unmap_area_topdown;
48130 + }
48131 +diff -urNp linux-2.6.27.7/arch/x86/mm/pageattr.c linux-2.6.27.7/arch/x86/mm/pageattr.c
48132 +--- linux-2.6.27.7/arch/x86/mm/pageattr.c 2008-11-07 12:55:34.000000000 -0500
48133 ++++ linux-2.6.27.7/arch/x86/mm/pageattr.c 2008-11-18 03:38:44.000000000 -0500
48134 +@@ -20,6 +20,7 @@
48135 + #include <asm/pgalloc.h>
48136 + #include <asm/proto.h>
48137 + #include <asm/pat.h>
48138 ++#include <asm/desc.h>
48139 +
48140 + /*
48141 + * The current flushing context - we pass it instead of 5 arguments:
48142 +@@ -213,7 +214,7 @@ static inline pgprot_t static_protection
48143 + * Does not cover __inittext since that is gone later on. On
48144 + * 64bit we do not enforce !NX on the low mapping
48145 + */
48146 +- if (within(address, (unsigned long)_text, (unsigned long)_etext))
48147 ++ if (within(address, ktla_ktva((unsigned long)_text), ktla_ktva((unsigned long)_etext)))
48148 + pgprot_val(forbidden) |= _PAGE_NX;
48149 +
48150 + /*
48151 +@@ -275,8 +276,20 @@ EXPORT_SYMBOL_GPL(lookup_address);
48152 + */
48153 + static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
48154 + {
48155 ++
48156 ++#ifdef CONFIG_PAX_KERNEXEC
48157 ++ unsigned long cr0;
48158 ++
48159 ++ pax_open_kernel(cr0);
48160 ++#endif
48161 ++
48162 + /* change init_mm */
48163 + set_pte_atomic(kpte, pte);
48164 ++
48165 ++#ifdef CONFIG_PAX_KERNEXEC
48166 ++ pax_close_kernel(cr0);
48167 ++#endif
48168 ++
48169 + #ifdef CONFIG_X86_32
48170 + if (!SHARED_KERNEL_PMD) {
48171 + struct page *page;
48172 +diff -urNp linux-2.6.27.7/arch/x86/mm/pat.c linux-2.6.27.7/arch/x86/mm/pat.c
48173 +--- linux-2.6.27.7/arch/x86/mm/pat.c 2008-11-07 12:55:34.000000000 -0500
48174 ++++ linux-2.6.27.7/arch/x86/mm/pat.c 2008-11-18 03:38:44.000000000 -0500
48175 +@@ -396,7 +396,7 @@ pgprot_t phys_mem_access_prot(struct fil
48176 + return vma_prot;
48177 + }
48178 +
48179 +-#ifdef CONFIG_STRICT_DEVMEM
48180 ++#ifndef CONFIG_STRICT_DEVMEM
48181 + /* This check is done in drivers/char/mem.c in case of STRICT_DEVMEM*/
48182 + static inline int range_is_allowed(unsigned long pfn, unsigned long size)
48183 + {
48184 +diff -urNp linux-2.6.27.7/arch/x86/mm/pgtable_32.c linux-2.6.27.7/arch/x86/mm/pgtable_32.c
48185 +--- linux-2.6.27.7/arch/x86/mm/pgtable_32.c 2008-11-07 12:55:34.000000000 -0500
48186 ++++ linux-2.6.27.7/arch/x86/mm/pgtable_32.c 2008-11-18 03:38:44.000000000 -0500
48187 +@@ -31,6 +31,10 @@ void set_pte_vaddr(unsigned long vaddr,
48188 + pmd_t *pmd;
48189 + pte_t *pte;
48190 +
48191 ++#ifdef CONFIG_PAX_KERNEXEC
48192 ++ unsigned long cr0;
48193 ++#endif
48194 ++
48195 + pgd = swapper_pg_dir + pgd_index(vaddr);
48196 + if (pgd_none(*pgd)) {
48197 + BUG();
48198 +@@ -47,11 +51,20 @@ void set_pte_vaddr(unsigned long vaddr,
48199 + return;
48200 + }
48201 + pte = pte_offset_kernel(pmd, vaddr);
48202 ++
48203 ++#ifdef CONFIG_PAX_KERNEXEC
48204 ++ pax_open_kernel(cr0);
48205 ++#endif
48206 ++
48207 + if (pte_val(pteval))
48208 + set_pte_present(&init_mm, vaddr, pte, pteval);
48209 + else
48210 + pte_clear(&init_mm, vaddr, pte);
48211 +
48212 ++#ifdef CONFIG_PAX_KERNEXEC
48213 ++ pax_close_kernel(cr0);
48214 ++#endif
48215 ++
48216 + /*
48217 + * It's enough to flush this one mapping.
48218 + * (PGE mappings get flushed as well)
48219 +diff -urNp linux-2.6.27.7/arch/x86/oprofile/backtrace.c linux-2.6.27.7/arch/x86/oprofile/backtrace.c
48220 +--- linux-2.6.27.7/arch/x86/oprofile/backtrace.c 2008-11-07 12:55:34.000000000 -0500
48221 ++++ linux-2.6.27.7/arch/x86/oprofile/backtrace.c 2008-11-18 03:38:44.000000000 -0500
48222 +@@ -37,7 +37,7 @@ static void backtrace_address(void *data
48223 + unsigned int *depth = data;
48224 +
48225 + if ((*depth)--)
48226 +- oprofile_add_trace(addr);
48227 ++ oprofile_add_trace(ktla_ktva(addr));
48228 + }
48229 +
48230 + static struct stacktrace_ops backtrace_ops = {
48231 +@@ -79,7 +79,7 @@ x86_backtrace(struct pt_regs * const reg
48232 + struct frame_head *head = (struct frame_head *)frame_pointer(regs);
48233 + unsigned long stack = kernel_trap_sp(regs);
48234 +
48235 +- if (!user_mode_vm(regs)) {
48236 ++ if (!user_mode(regs)) {
48237 + if (depth)
48238 + dump_trace(NULL, regs, (unsigned long *)stack, 0,
48239 + &backtrace_ops, &depth);
48240 +diff -urNp linux-2.6.27.7/arch/x86/oprofile/op_model_p4.c linux-2.6.27.7/arch/x86/oprofile/op_model_p4.c
48241 +--- linux-2.6.27.7/arch/x86/oprofile/op_model_p4.c 2008-11-07 12:55:34.000000000 -0500
48242 ++++ linux-2.6.27.7/arch/x86/oprofile/op_model_p4.c 2008-11-18 03:38:44.000000000 -0500
48243 +@@ -47,7 +47,7 @@ static inline void setup_num_counters(vo
48244 + #endif
48245 + }
48246 +
48247 +-static int inline addr_increment(void)
48248 ++static inline int addr_increment(void)
48249 + {
48250 + #ifdef CONFIG_SMP
48251 + return smp_num_siblings == 2 ? 2 : 1;
48252 +diff -urNp linux-2.6.27.7/arch/x86/pci/common.c linux-2.6.27.7/arch/x86/pci/common.c
48253 +--- linux-2.6.27.7/arch/x86/pci/common.c 2008-11-07 12:55:34.000000000 -0500
48254 ++++ linux-2.6.27.7/arch/x86/pci/common.c 2008-11-18 03:38:44.000000000 -0500
48255 +@@ -362,7 +362,7 @@ static struct dmi_system_id __devinitdat
48256 + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"),
48257 + },
48258 + },
48259 +- {}
48260 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
48261 + };
48262 +
48263 + void __init dmi_check_pciprobe(void)
48264 +diff -urNp linux-2.6.27.7/arch/x86/pci/fixup.c linux-2.6.27.7/arch/x86/pci/fixup.c
48265 +--- linux-2.6.27.7/arch/x86/pci/fixup.c 2008-11-07 12:55:34.000000000 -0500
48266 ++++ linux-2.6.27.7/arch/x86/pci/fixup.c 2008-11-18 03:38:44.000000000 -0500
48267 +@@ -365,7 +365,7 @@ static struct dmi_system_id __devinitdat
48268 + DMI_MATCH(DMI_PRODUCT_NAME, "MS-6702E"),
48269 + },
48270 + },
48271 +- {}
48272 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
48273 + };
48274 +
48275 + /*
48276 +@@ -436,7 +436,7 @@ static struct dmi_system_id __devinitdat
48277 + DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
48278 + },
48279 + },
48280 +- { }
48281 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
48282 + };
48283 +
48284 + static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
48285 +diff -urNp linux-2.6.27.7/arch/x86/pci/irq.c linux-2.6.27.7/arch/x86/pci/irq.c
48286 +--- linux-2.6.27.7/arch/x86/pci/irq.c 2008-11-07 12:55:34.000000000 -0500
48287 ++++ linux-2.6.27.7/arch/x86/pci/irq.c 2008-11-18 03:38:44.000000000 -0500
48288 +@@ -544,7 +544,7 @@ static __init int intel_router_probe(str
48289 + static struct pci_device_id __initdata pirq_440gx[] = {
48290 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
48291 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
48292 +- { },
48293 ++ { PCI_DEVICE(0, 0) }
48294 + };
48295 +
48296 + /* 440GX has a proprietary PIRQ router -- don't use it */
48297 +@@ -1131,7 +1131,7 @@ static struct dmi_system_id __initdata p
48298 + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
48299 + },
48300 + },
48301 +- { }
48302 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
48303 + };
48304 +
48305 + int __init pcibios_irq_init(void)
48306 +diff -urNp linux-2.6.27.7/arch/x86/pci/pcbios.c linux-2.6.27.7/arch/x86/pci/pcbios.c
48307 +--- linux-2.6.27.7/arch/x86/pci/pcbios.c 2008-11-07 12:55:34.000000000 -0500
48308 ++++ linux-2.6.27.7/arch/x86/pci/pcbios.c 2008-11-18 03:38:44.000000000 -0500
48309 +@@ -57,50 +57,120 @@ union bios32 {
48310 + static struct {
48311 + unsigned long address;
48312 + unsigned short segment;
48313 +-} bios32_indirect = { 0, __KERNEL_CS };
48314 ++} bios32_indirect __read_only = { 0, __PCIBIOS_CS };
48315 +
48316 + /*
48317 + * Returns the entry point for the given service, NULL on error
48318 + */
48319 +
48320 +-static unsigned long bios32_service(unsigned long service)
48321 ++static unsigned long __devinit bios32_service(unsigned long service)
48322 + {
48323 + unsigned char return_code; /* %al */
48324 + unsigned long address; /* %ebx */
48325 + unsigned long length; /* %ecx */
48326 + unsigned long entry; /* %edx */
48327 + unsigned long flags;
48328 ++ struct desc_struct d, *gdt;
48329 ++
48330 ++#ifdef CONFIG_PAX_KERNEXEC
48331 ++ unsigned long cr0;
48332 ++#endif
48333 +
48334 + local_irq_save(flags);
48335 +- __asm__("lcall *(%%edi); cld"
48336 ++
48337 ++ gdt = get_cpu_gdt_table(smp_processor_id());
48338 ++
48339 ++#ifdef CONFIG_PAX_KERNEXEC
48340 ++ pax_open_kernel(cr0);
48341 ++#endif
48342 ++
48343 ++ pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x9B, 0xC);
48344 ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
48345 ++ pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x93, 0xC);
48346 ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
48347 ++
48348 ++#ifdef CONFIG_PAX_KERNEXEC
48349 ++ pax_close_kernel(cr0);
48350 ++#endif
48351 ++
48352 ++ __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld"
48353 + : "=a" (return_code),
48354 + "=b" (address),
48355 + "=c" (length),
48356 + "=d" (entry)
48357 + : "0" (service),
48358 + "1" (0),
48359 +- "D" (&bios32_indirect));
48360 ++ "D" (&bios32_indirect),
48361 ++ "r"(__PCIBIOS_DS)
48362 ++ : "memory");
48363 ++
48364 ++#ifdef CONFIG_PAX_KERNEXEC
48365 ++ pax_open_kernel(cr0);
48366 ++#endif
48367 ++
48368 ++ gdt[GDT_ENTRY_PCIBIOS_CS].a = 0;
48369 ++ gdt[GDT_ENTRY_PCIBIOS_CS].b = 0;
48370 ++ gdt[GDT_ENTRY_PCIBIOS_DS].a = 0;
48371 ++ gdt[GDT_ENTRY_PCIBIOS_DS].b = 0;
48372 ++
48373 ++#ifdef CONFIG_PAX_KERNEXEC
48374 ++ pax_close_kernel(cr0);
48375 ++#endif
48376 ++
48377 + local_irq_restore(flags);
48378 +
48379 + switch (return_code) {
48380 +- case 0:
48381 +- return address + entry;
48382 +- case 0x80: /* Not present */
48383 +- printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
48384 +- return 0;
48385 +- default: /* Shouldn't happen */
48386 +- printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
48387 +- service, return_code);
48388 ++ case 0: {
48389 ++ int cpu;
48390 ++ unsigned char flags;
48391 ++
48392 ++ printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry);
48393 ++ if (address >= 0xFFFF0 || length > 0x100000 - address || length <= entry) {
48394 ++ printk(KERN_WARNING "bios32_service: not valid\n");
48395 + return 0;
48396 ++ }
48397 ++ address = address + PAGE_OFFSET;
48398 ++ length += 16UL; /* some BIOSs underreport this... */
48399 ++ flags = 4;
48400 ++ if (length >= 64*1024*1024) {
48401 ++ length >>= PAGE_SHIFT;
48402 ++ flags |= 8;
48403 ++ }
48404 ++
48405 ++#ifdef CONFIG_PAX_KERNEXEC
48406 ++ pax_open_kernel(cr0);
48407 ++#endif
48408 ++
48409 ++ for (cpu = 0; cpu < NR_CPUS; cpu++) {
48410 ++ gdt = get_cpu_gdt_table(cpu);
48411 ++ pack_descriptor(&d, address, length, 0x9b, flags);
48412 ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
48413 ++ pack_descriptor(&d, address, length, 0x93, flags);
48414 ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
48415 ++ }
48416 ++
48417 ++#ifdef CONFIG_PAX_KERNEXEC
48418 ++ pax_close_kernel(cr0);
48419 ++#endif
48420 ++
48421 ++ return entry;
48422 ++ }
48423 ++ case 0x80: /* Not present */
48424 ++ printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
48425 ++ return 0;
48426 ++ default: /* Shouldn't happen */
48427 ++ printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
48428 ++ service, return_code);
48429 ++ return 0;
48430 + }
48431 + }
48432 +
48433 + static struct {
48434 + unsigned long address;
48435 + unsigned short segment;
48436 +-} pci_indirect = { 0, __KERNEL_CS };
48437 ++} pci_indirect __read_only = { 0, __PCIBIOS_CS };
48438 +
48439 +-static int pci_bios_present;
48440 ++static int pci_bios_present __read_only;
48441 +
48442 + static int __devinit check_pcibios(void)
48443 + {
48444 +@@ -109,11 +179,13 @@ static int __devinit check_pcibios(void)
48445 + unsigned long flags, pcibios_entry;
48446 +
48447 + if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
48448 +- pci_indirect.address = pcibios_entry + PAGE_OFFSET;
48449 ++ pci_indirect.address = pcibios_entry;
48450 +
48451 + local_irq_save(flags);
48452 +- __asm__(
48453 +- "lcall *(%%edi); cld\n\t"
48454 ++ __asm__("movw %w6, %%ds\n\t"
48455 ++ "lcall *%%ss:(%%edi); cld\n\t"
48456 ++ "push %%ss\n\t"
48457 ++ "pop %%ds\n\t"
48458 + "jc 1f\n\t"
48459 + "xor %%ah, %%ah\n"
48460 + "1:"
48461 +@@ -122,7 +194,8 @@ static int __devinit check_pcibios(void)
48462 + "=b" (ebx),
48463 + "=c" (ecx)
48464 + : "1" (PCIBIOS_PCI_BIOS_PRESENT),
48465 +- "D" (&pci_indirect)
48466 ++ "D" (&pci_indirect),
48467 ++ "r" (__PCIBIOS_DS)
48468 + : "memory");
48469 + local_irq_restore(flags);
48470 +
48471 +@@ -166,7 +239,10 @@ static int pci_bios_read(unsigned int se
48472 +
48473 + switch (len) {
48474 + case 1:
48475 +- __asm__("lcall *(%%esi); cld\n\t"
48476 ++ __asm__("movw %w6, %%ds\n\t"
48477 ++ "lcall *%%ss:(%%esi); cld\n\t"
48478 ++ "push %%ss\n\t"
48479 ++ "pop %%ds\n\t"
48480 + "jc 1f\n\t"
48481 + "xor %%ah, %%ah\n"
48482 + "1:"
48483 +@@ -175,7 +251,8 @@ static int pci_bios_read(unsigned int se
48484 + : "1" (PCIBIOS_READ_CONFIG_BYTE),
48485 + "b" (bx),
48486 + "D" ((long)reg),
48487 +- "S" (&pci_indirect));
48488 ++ "S" (&pci_indirect),
48489 ++ "r" (__PCIBIOS_DS));
48490 + /*
48491 + * Zero-extend the result beyond 8 bits, do not trust the
48492 + * BIOS having done it:
48493 +@@ -183,7 +260,10 @@ static int pci_bios_read(unsigned int se
48494 + *value &= 0xff;
48495 + break;
48496 + case 2:
48497 +- __asm__("lcall *(%%esi); cld\n\t"
48498 ++ __asm__("movw %w6, %%ds\n\t"
48499 ++ "lcall *%%ss:(%%esi); cld\n\t"
48500 ++ "push %%ss\n\t"
48501 ++ "pop %%ds\n\t"
48502 + "jc 1f\n\t"
48503 + "xor %%ah, %%ah\n"
48504 + "1:"
48505 +@@ -192,7 +272,8 @@ static int pci_bios_read(unsigned int se
48506 + : "1" (PCIBIOS_READ_CONFIG_WORD),
48507 + "b" (bx),
48508 + "D" ((long)reg),
48509 +- "S" (&pci_indirect));
48510 ++ "S" (&pci_indirect),
48511 ++ "r" (__PCIBIOS_DS));
48512 + /*
48513 + * Zero-extend the result beyond 16 bits, do not trust the
48514 + * BIOS having done it:
48515 +@@ -200,7 +281,10 @@ static int pci_bios_read(unsigned int se
48516 + *value &= 0xffff;
48517 + break;
48518 + case 4:
48519 +- __asm__("lcall *(%%esi); cld\n\t"
48520 ++ __asm__("movw %w6, %%ds\n\t"
48521 ++ "lcall *%%ss:(%%esi); cld\n\t"
48522 ++ "push %%ss\n\t"
48523 ++ "pop %%ds\n\t"
48524 + "jc 1f\n\t"
48525 + "xor %%ah, %%ah\n"
48526 + "1:"
48527 +@@ -209,7 +293,8 @@ static int pci_bios_read(unsigned int se
48528 + : "1" (PCIBIOS_READ_CONFIG_DWORD),
48529 + "b" (bx),
48530 + "D" ((long)reg),
48531 +- "S" (&pci_indirect));
48532 ++ "S" (&pci_indirect),
48533 ++ "r" (__PCIBIOS_DS));
48534 + break;
48535 + }
48536 +
48537 +@@ -232,7 +317,10 @@ static int pci_bios_write(unsigned int s
48538 +
48539 + switch (len) {
48540 + case 1:
48541 +- __asm__("lcall *(%%esi); cld\n\t"
48542 ++ __asm__("movw %w6, %%ds\n\t"
48543 ++ "lcall *%%ss:(%%esi); cld\n\t"
48544 ++ "push %%ss\n\t"
48545 ++ "pop %%ds\n\t"
48546 + "jc 1f\n\t"
48547 + "xor %%ah, %%ah\n"
48548 + "1:"
48549 +@@ -241,10 +329,14 @@ static int pci_bios_write(unsigned int s
48550 + "c" (value),
48551 + "b" (bx),
48552 + "D" ((long)reg),
48553 +- "S" (&pci_indirect));
48554 ++ "S" (&pci_indirect),
48555 ++ "r" (__PCIBIOS_DS));
48556 + break;
48557 + case 2:
48558 +- __asm__("lcall *(%%esi); cld\n\t"
48559 ++ __asm__("movw %w6, %%ds\n\t"
48560 ++ "lcall *%%ss:(%%esi); cld\n\t"
48561 ++ "push %%ss\n\t"
48562 ++ "pop %%ds\n\t"
48563 + "jc 1f\n\t"
48564 + "xor %%ah, %%ah\n"
48565 + "1:"
48566 +@@ -253,10 +345,14 @@ static int pci_bios_write(unsigned int s
48567 + "c" (value),
48568 + "b" (bx),
48569 + "D" ((long)reg),
48570 +- "S" (&pci_indirect));
48571 ++ "S" (&pci_indirect),
48572 ++ "r" (__PCIBIOS_DS));
48573 + break;
48574 + case 4:
48575 +- __asm__("lcall *(%%esi); cld\n\t"
48576 ++ __asm__("movw %w6, %%ds\n\t"
48577 ++ "lcall *%%ss:(%%esi); cld\n\t"
48578 ++ "push %%ss\n\t"
48579 ++ "pop %%ds\n\t"
48580 + "jc 1f\n\t"
48581 + "xor %%ah, %%ah\n"
48582 + "1:"
48583 +@@ -265,7 +361,8 @@ static int pci_bios_write(unsigned int s
48584 + "c" (value),
48585 + "b" (bx),
48586 + "D" ((long)reg),
48587 +- "S" (&pci_indirect));
48588 ++ "S" (&pci_indirect),
48589 ++ "r" (__PCIBIOS_DS));
48590 + break;
48591 + }
48592 +
48593 +@@ -369,10 +466,13 @@ struct irq_routing_table * pcibios_get_i
48594 +
48595 + DBG("PCI: Fetching IRQ routing table... ");
48596 + __asm__("push %%es\n\t"
48597 ++ "movw %w8, %%ds\n\t"
48598 + "push %%ds\n\t"
48599 + "pop %%es\n\t"
48600 +- "lcall *(%%esi); cld\n\t"
48601 ++ "lcall *%%ss:(%%esi); cld\n\t"
48602 + "pop %%es\n\t"
48603 ++ "push %%ss\n\t"
48604 ++ "pop %%ds\n"
48605 + "jc 1f\n\t"
48606 + "xor %%ah, %%ah\n"
48607 + "1:"
48608 +@@ -383,7 +483,8 @@ struct irq_routing_table * pcibios_get_i
48609 + "1" (0),
48610 + "D" ((long) &opt),
48611 + "S" (&pci_indirect),
48612 +- "m" (opt)
48613 ++ "m" (opt),
48614 ++ "r" (__PCIBIOS_DS)
48615 + : "memory");
48616 + DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map);
48617 + if (ret & 0xff00)
48618 +@@ -407,7 +508,10 @@ int pcibios_set_irq_routing(struct pci_d
48619 + {
48620 + int ret;
48621 +
48622 +- __asm__("lcall *(%%esi); cld\n\t"
48623 ++ __asm__("movw %w5, %%ds\n\t"
48624 ++ "lcall *%%ss:(%%esi); cld\n\t"
48625 ++ "push %%ss\n\t"
48626 ++ "pop %%ds\n"
48627 + "jc 1f\n\t"
48628 + "xor %%ah, %%ah\n"
48629 + "1:"
48630 +@@ -415,7 +519,8 @@ int pcibios_set_irq_routing(struct pci_d
48631 + : "0" (PCIBIOS_SET_PCI_HW_INT),
48632 + "b" ((dev->bus->number << 8) | dev->devfn),
48633 + "c" ((irq << 8) | (pin + 10)),
48634 +- "S" (&pci_indirect));
48635 ++ "S" (&pci_indirect),
48636 ++ "r" (__PCIBIOS_DS));
48637 + return !(ret & 0xff00);
48638 + }
48639 + EXPORT_SYMBOL(pcibios_set_irq_routing);
48640 +diff -urNp linux-2.6.27.7/arch/x86/power/cpu_32.c linux-2.6.27.7/arch/x86/power/cpu_32.c
48641 +--- linux-2.6.27.7/arch/x86/power/cpu_32.c 2008-11-07 12:55:34.000000000 -0500
48642 ++++ linux-2.6.27.7/arch/x86/power/cpu_32.c 2008-11-18 03:38:44.000000000 -0500
48643 +@@ -66,7 +66,7 @@ static void do_fpu_end(void)
48644 + static void fix_processor_context(void)
48645 + {
48646 + int cpu = smp_processor_id();
48647 +- struct tss_struct *t = &per_cpu(init_tss, cpu);
48648 ++ struct tss_struct *t = init_tss + cpu;
48649 +
48650 + set_tss_desc(cpu, t); /*
48651 + * This just modifies memory; should not be
48652 +diff -urNp linux-2.6.27.7/arch/x86/power/cpu_64.c linux-2.6.27.7/arch/x86/power/cpu_64.c
48653 +--- linux-2.6.27.7/arch/x86/power/cpu_64.c 2008-11-07 12:55:34.000000000 -0500
48654 ++++ linux-2.6.27.7/arch/x86/power/cpu_64.c 2008-11-18 03:38:44.000000000 -0500
48655 +@@ -136,7 +136,11 @@ void restore_processor_state(void)
48656 + static void fix_processor_context(void)
48657 + {
48658 + int cpu = smp_processor_id();
48659 +- struct tss_struct *t = &per_cpu(init_tss, cpu);
48660 ++ struct tss_struct *t = init_tss + cpu;
48661 ++
48662 ++#ifdef CONFIG_PAX_KERNEXEC
48663 ++ unsigned long cr0;
48664 ++#endif
48665 +
48666 + /*
48667 + * This just modifies memory; should not be necessary. But... This
48668 +@@ -145,8 +149,16 @@ static void fix_processor_context(void)
48669 + */
48670 + set_tss_desc(cpu, t);
48671 +
48672 ++#ifdef CONFIG_PAX_KERNEXEC
48673 ++ pax_open_kernel(cr0);
48674 ++#endif
48675 ++
48676 + get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9;
48677 +
48678 ++#ifdef CONFIG_PAX_KERNEXEC
48679 ++ pax_close_kernel(cr0);
48680 ++#endif
48681 ++
48682 + syscall_init(); /* This sets MSR_*STAR and related */
48683 + load_TR_desc(); /* This does ltr */
48684 + load_LDT(&current->active_mm->context); /* This does lldt */
48685 +diff -urNp linux-2.6.27.7/arch/x86/vdso/vdso32-setup.c linux-2.6.27.7/arch/x86/vdso/vdso32-setup.c
48686 +--- linux-2.6.27.7/arch/x86/vdso/vdso32-setup.c 2008-11-07 12:55:34.000000000 -0500
48687 ++++ linux-2.6.27.7/arch/x86/vdso/vdso32-setup.c 2008-11-18 03:38:44.000000000 -0500
48688 +@@ -226,7 +226,7 @@ static inline void map_compat_vdso(int m
48689 + void enable_sep_cpu(void)
48690 + {
48691 + int cpu = get_cpu();
48692 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
48693 ++ struct tss_struct *tss = init_tss + cpu;
48694 +
48695 + if (!boot_cpu_has(X86_FEATURE_SEP)) {
48696 + put_cpu();
48697 +@@ -249,7 +249,7 @@ static int __init gate_vma_init(void)
48698 + gate_vma.vm_start = FIXADDR_USER_START;
48699 + gate_vma.vm_end = FIXADDR_USER_END;
48700 + gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
48701 +- gate_vma.vm_page_prot = __P101;
48702 ++ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
48703 + /*
48704 + * Make sure the vDSO gets into every core dump.
48705 + * Dumping its contents makes post-mortem fully interpretable later
48706 +@@ -331,7 +331,7 @@ int arch_setup_additional_pages(struct l
48707 + if (compat)
48708 + addr = VDSO_HIGH_BASE;
48709 + else {
48710 +- addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
48711 ++ addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
48712 + if (IS_ERR_VALUE(addr)) {
48713 + ret = addr;
48714 + goto up_fail;
48715 +@@ -358,7 +358,7 @@ int arch_setup_additional_pages(struct l
48716 + goto up_fail;
48717 + }
48718 +
48719 +- current->mm->context.vdso = (void *)addr;
48720 ++ current->mm->context.vdso = addr;
48721 + current_thread_info()->sysenter_return =
48722 + VDSO32_SYMBOL(addr, SYSENTER_RETURN);
48723 +
48724 +@@ -384,7 +384,7 @@ static ctl_table abi_table2[] = {
48725 + .mode = 0644,
48726 + .proc_handler = proc_dointvec
48727 + },
48728 +- {}
48729 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
48730 + };
48731 +
48732 + static ctl_table abi_root_table2[] = {
48733 +@@ -394,7 +394,7 @@ static ctl_table abi_root_table2[] = {
48734 + .mode = 0555,
48735 + .child = abi_table2
48736 + },
48737 +- {}
48738 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
48739 + };
48740 +
48741 + static __init int ia32_binfmt_init(void)
48742 +@@ -409,8 +409,14 @@ __initcall(ia32_binfmt_init);
48743 +
48744 + const char *arch_vma_name(struct vm_area_struct *vma)
48745 + {
48746 +- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
48747 ++ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
48748 + return "[vdso]";
48749 ++
48750 ++#ifdef CONFIG_PAX_SEGMEXEC
48751 ++ if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso)
48752 ++ return "[vdso]";
48753 ++#endif
48754 ++
48755 + return NULL;
48756 + }
48757 +
48758 +@@ -419,7 +425,7 @@ struct vm_area_struct *get_gate_vma(stru
48759 + struct mm_struct *mm = tsk->mm;
48760 +
48761 + /* Check to see if this task was created in compat vdso mode */
48762 +- if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
48763 ++ if (mm && mm->context.vdso == VDSO_HIGH_BASE)
48764 + return &gate_vma;
48765 + return NULL;
48766 + }
48767 +diff -urNp linux-2.6.27.7/arch/x86/vdso/vma.c linux-2.6.27.7/arch/x86/vdso/vma.c
48768 +--- linux-2.6.27.7/arch/x86/vdso/vma.c 2008-11-07 12:55:34.000000000 -0500
48769 ++++ linux-2.6.27.7/arch/x86/vdso/vma.c 2008-11-18 03:38:44.000000000 -0500
48770 +@@ -123,7 +123,7 @@ int arch_setup_additional_pages(struct l
48771 + if (ret)
48772 + goto up_fail;
48773 +
48774 +- current->mm->context.vdso = (void *)addr;
48775 ++ current->mm->context.vdso = addr;
48776 + up_fail:
48777 + up_write(&mm->mmap_sem);
48778 + return ret;
48779 +diff -urNp linux-2.6.27.7/arch/x86/xen/enlighten.c linux-2.6.27.7/arch/x86/xen/enlighten.c
48780 +--- linux-2.6.27.7/arch/x86/xen/enlighten.c 2008-11-07 12:55:34.000000000 -0500
48781 ++++ linux-2.6.27.7/arch/x86/xen/enlighten.c 2008-11-18 03:38:44.000000000 -0500
48782 +@@ -343,7 +343,7 @@ static void xen_set_ldt(const void *addr
48783 + static void xen_load_gdt(const struct desc_ptr *dtr)
48784 + {
48785 + unsigned long *frames;
48786 +- unsigned long va = dtr->address;
48787 ++ unsigned long va = (unsigned long)dtr->address;
48788 + unsigned int size = dtr->size + 1;
48789 + unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
48790 + int f;
48791 +@@ -358,7 +358,7 @@ static void xen_load_gdt(const struct de
48792 + mcs = xen_mc_entry(sizeof(*frames) * pages);
48793 + frames = mcs.args;
48794 +
48795 +- for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
48796 ++ for (f = 0; va < (unsigned long)dtr->address + size; va += PAGE_SIZE, f++) {
48797 + frames[f] = virt_to_mfn(va);
48798 + make_lowmem_page_readonly((void *)va);
48799 + }
48800 +@@ -467,7 +467,7 @@ static void xen_write_idt_entry(gate_des
48801 +
48802 + preempt_disable();
48803 +
48804 +- start = __get_cpu_var(idt_desc).address;
48805 ++ start = (unsigned long)__get_cpu_var(idt_desc).address;
48806 + end = start + __get_cpu_var(idt_desc).size + 1;
48807 +
48808 + xen_mc_flush();
48809 +@@ -1574,6 +1574,8 @@ static __init pgd_t *xen_setup_kernel_pa
48810 + convert_pfn_mfn(init_level4_pgt);
48811 + convert_pfn_mfn(level3_ident_pgt);
48812 + convert_pfn_mfn(level3_kernel_pgt);
48813 ++ convert_pfn_mfn(level3_vmalloc_pgt);
48814 ++ convert_pfn_mfn(level3_vmemmap_pgt);
48815 +
48816 + l3 = m2v(pgd[pgd_index(__START_KERNEL_map)].pgd);
48817 + l2 = m2v(l3[pud_index(__START_KERNEL_map)].pud);
48818 +@@ -1592,9 +1594,12 @@ static __init pgd_t *xen_setup_kernel_pa
48819 + set_page_prot(init_level4_pgt, PAGE_KERNEL_RO);
48820 + set_page_prot(level3_ident_pgt, PAGE_KERNEL_RO);
48821 + set_page_prot(level3_kernel_pgt, PAGE_KERNEL_RO);
48822 ++ set_page_prot(level3_vmalloc_pgt, PAGE_KERNEL_RO);
48823 ++ set_page_prot(level3_vmemmap_pgt, PAGE_KERNEL_RO);
48824 + set_page_prot(level3_user_vsyscall, PAGE_KERNEL_RO);
48825 + set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO);
48826 + set_page_prot(level2_fixmap_pgt, PAGE_KERNEL_RO);
48827 ++ set_page_prot(level1_fixmap_pgt, PAGE_KERNEL_RO);
48828 +
48829 + /* Pin down new L4 */
48830 + pin_pagetable_pfn(MMUEXT_PIN_L4_TABLE,
48831 +diff -urNp linux-2.6.27.7/arch/x86/xen/smp.c linux-2.6.27.7/arch/x86/xen/smp.c
48832 +--- linux-2.6.27.7/arch/x86/xen/smp.c 2008-11-07 12:55:34.000000000 -0500
48833 ++++ linux-2.6.27.7/arch/x86/xen/smp.c 2008-11-18 03:38:44.000000000 -0500
48834 +@@ -170,11 +170,6 @@ static void __init xen_smp_prepare_boot_
48835 + {
48836 + BUG_ON(smp_processor_id() != 0);
48837 + native_smp_prepare_boot_cpu();
48838 +-
48839 +- /* We've switched to the "real" per-cpu gdt, so make sure the
48840 +- old memory can be recycled */
48841 +- make_lowmem_page_readwrite(&per_cpu_var(gdt_page));
48842 +-
48843 + xen_setup_vcpu_info_placement();
48844 + }
48845 +
48846 +@@ -232,8 +227,8 @@ cpu_initialize_context(unsigned int cpu,
48847 + gdt = get_cpu_gdt_table(cpu);
48848 +
48849 + ctxt->flags = VGCF_IN_KERNEL;
48850 +- ctxt->user_regs.ds = __USER_DS;
48851 +- ctxt->user_regs.es = __USER_DS;
48852 ++ ctxt->user_regs.ds = __KERNEL_DS;
48853 ++ ctxt->user_regs.es = __KERNEL_DS;
48854 + ctxt->user_regs.ss = __KERNEL_DS;
48855 + #ifdef CONFIG_X86_32
48856 + ctxt->user_regs.fs = __KERNEL_PERCPU;
48857 +diff -urNp linux-2.6.27.7/crypto/async_tx/async_tx.c linux-2.6.27.7/crypto/async_tx/async_tx.c
48858 +--- linux-2.6.27.7/crypto/async_tx/async_tx.c 2008-11-07 12:55:34.000000000 -0500
48859 ++++ linux-2.6.27.7/crypto/async_tx/async_tx.c 2008-11-18 03:38:44.000000000 -0500
48860 +@@ -358,8 +358,8 @@ async_tx_init(void)
48861 + err:
48862 + printk(KERN_ERR "async_tx: initialization failure\n");
48863 +
48864 +- while (--cap >= 0)
48865 +- free_percpu(channel_table[cap]);
48866 ++ while (cap)
48867 ++ free_percpu(channel_table[--cap]);
48868 +
48869 + return 1;
48870 + }
48871 +diff -urNp linux-2.6.27.7/crypto/lrw.c linux-2.6.27.7/crypto/lrw.c
48872 +--- linux-2.6.27.7/crypto/lrw.c 2008-11-07 12:55:34.000000000 -0500
48873 ++++ linux-2.6.27.7/crypto/lrw.c 2008-11-18 03:38:44.000000000 -0500
48874 +@@ -54,7 +54,7 @@ static int setkey(struct crypto_tfm *par
48875 + struct priv *ctx = crypto_tfm_ctx(parent);
48876 + struct crypto_cipher *child = ctx->child;
48877 + int err, i;
48878 +- be128 tmp = { 0 };
48879 ++ be128 tmp = { 0, 0 };
48880 + int bsize = crypto_cipher_blocksize(child);
48881 +
48882 + crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
48883 +diff -urNp linux-2.6.27.7/Documentation/dontdiff linux-2.6.27.7/Documentation/dontdiff
48884 +--- linux-2.6.27.7/Documentation/dontdiff 2008-11-07 12:55:34.000000000 -0500
48885 ++++ linux-2.6.27.7/Documentation/dontdiff 2008-11-18 03:39:50.000000000 -0500
48886 +@@ -3,6 +3,7 @@
48887 + *.bin
48888 + *.cpio
48889 + *.css
48890 ++*.dbg
48891 + *.dvi
48892 + *.eps
48893 + *.fw.gen.S
48894 +@@ -53,9 +54,14 @@ COPYING
48895 + CREDITS
48896 + CVS
48897 + ChangeSet
48898 ++GPATH
48899 ++GRTAGS
48900 ++GSYMS
48901 ++GTAGS
48902 + Image
48903 + Kerntypes
48904 + MODS.txt
48905 ++Module.markers
48906 + Module.symvers
48907 + PENDING
48908 + SCCS
48909 +@@ -66,7 +72,6 @@ aic7*reg_print.c*
48910 + aic7*seq.h*
48911 + aicasm
48912 + aicdb.h*
48913 +-asm
48914 + asm-offsets.h
48915 + asm_offsets.h
48916 + autoconf.h*
48917 +@@ -74,6 +79,7 @@ bbootsect
48918 + bin2c
48919 + binkernel.spec
48920 + bootsect
48921 ++bounds.h
48922 + bsetup
48923 + btfixupprep
48924 + build
48925 +@@ -90,6 +96,7 @@ config_data.gz*
48926 + conmakehash
48927 + consolemap_deftbl.c*
48928 + crc32table.h*
48929 ++cpustr.h
48930 + cscope.*
48931 + defkeymap.c*
48932 + devlist.h*
48933 +@@ -138,6 +145,7 @@ miboot*
48934 + mk_elfconfig
48935 + mkboot
48936 + mkbugboot
48937 ++mkcpustr
48938 + mkdep
48939 + mkprep
48940 + mktables
48941 +@@ -179,16 +187,21 @@ times.h*
48942 + tkparse
48943 + trix_boot.h
48944 + utsrelease.h*
48945 +-vdso.lds
48946 ++vdso*.lds
48947 + version.h*
48948 + vmlinux
48949 + vmlinux-*
48950 + vmlinux.aout
48951 +-vmlinux*.lds*
48952 ++vmlinux.bin.all
48953 ++vmlinux*.lds
48954 ++vmlinux.relocs
48955 + vmlinux*.scr
48956 +-vsyscall.lds
48957 ++vsyscall*.lds
48958 ++wakeup.elf
48959 ++wakeup.lds
48960 + wanxlfw.inc
48961 + uImage
48962 + unifdef
48963 ++utsrelease.h
48964 + zImage*
48965 + zconf.hash.c
48966 +diff -urNp linux-2.6.27.7/drivers/acpi/blacklist.c linux-2.6.27.7/drivers/acpi/blacklist.c
48967 +--- linux-2.6.27.7/drivers/acpi/blacklist.c 2008-11-07 12:55:34.000000000 -0500
48968 ++++ linux-2.6.27.7/drivers/acpi/blacklist.c 2008-11-18 03:38:44.000000000 -0500
48969 +@@ -71,7 +71,7 @@ static struct acpi_blacklist_item acpi_b
48970 + {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
48971 + "Incorrect _ADR", 1},
48972 +
48973 +- {""}
48974 ++ {"", "", 0, 0, 0, all_versions, 0}
48975 + };
48976 +
48977 + #if CONFIG_ACPI_BLACKLIST_YEAR
48978 +diff -urNp linux-2.6.27.7/drivers/acpi/osl.c linux-2.6.27.7/drivers/acpi/osl.c
48979 +--- linux-2.6.27.7/drivers/acpi/osl.c 2008-11-07 12:55:34.000000000 -0500
48980 ++++ linux-2.6.27.7/drivers/acpi/osl.c 2008-11-18 03:38:44.000000000 -0500
48981 +@@ -494,6 +494,8 @@ acpi_os_read_memory(acpi_physical_addres
48982 + void __iomem *virt_addr;
48983 +
48984 + virt_addr = ioremap(phys_addr, width);
48985 ++ if (!virt_addr)
48986 ++ return AE_NO_MEMORY;
48987 + if (!value)
48988 + value = &dummy;
48989 +
48990 +@@ -522,6 +524,8 @@ acpi_os_write_memory(acpi_physical_addre
48991 + void __iomem *virt_addr;
48992 +
48993 + virt_addr = ioremap(phys_addr, width);
48994 ++ if (!virt_addr)
48995 ++ return AE_NO_MEMORY;
48996 +
48997 + switch (width) {
48998 + case 8:
48999 +diff -urNp linux-2.6.27.7/drivers/acpi/processor_core.c linux-2.6.27.7/drivers/acpi/processor_core.c
49000 +--- linux-2.6.27.7/drivers/acpi/processor_core.c 2008-11-07 12:55:34.000000000 -0500
49001 ++++ linux-2.6.27.7/drivers/acpi/processor_core.c 2008-11-18 03:38:44.000000000 -0500
49002 +@@ -667,7 +667,7 @@ static int __cpuinit acpi_processor_star
49003 + return 0;
49004 + }
49005 +
49006 +- BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
49007 ++ BUG_ON(pr->id >= nr_cpu_ids);
49008 +
49009 + /*
49010 + * Buggy BIOS check
49011 +diff -urNp linux-2.6.27.7/drivers/acpi/processor_idle.c linux-2.6.27.7/drivers/acpi/processor_idle.c
49012 +--- linux-2.6.27.7/drivers/acpi/processor_idle.c 2008-11-07 12:55:34.000000000 -0500
49013 ++++ linux-2.6.27.7/drivers/acpi/processor_idle.c 2008-11-18 03:38:44.000000000 -0500
49014 +@@ -182,7 +182,7 @@ static struct dmi_system_id __cpuinitdat
49015 + DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
49016 + DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
49017 + (void *)2},
49018 +- {},
49019 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
49020 + };
49021 +
49022 + static inline u32 ticks_elapsed(u32 t1, u32 t2)
49023 +diff -urNp linux-2.6.27.7/drivers/acpi/tables/tbfadt.c linux-2.6.27.7/drivers/acpi/tables/tbfadt.c
49024 +--- linux-2.6.27.7/drivers/acpi/tables/tbfadt.c 2008-11-07 12:55:34.000000000 -0500
49025 ++++ linux-2.6.27.7/drivers/acpi/tables/tbfadt.c 2008-11-18 03:38:44.000000000 -0500
49026 +@@ -48,7 +48,7 @@
49027 + ACPI_MODULE_NAME("tbfadt")
49028 +
49029 + /* Local prototypes */
49030 +-static void inline
49031 ++static inline void
49032 + acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
49033 + u8 bit_width, u64 address);
49034 +
49035 +@@ -122,7 +122,7 @@ static struct acpi_fadt_info fadt_info_t
49036 + *
49037 + ******************************************************************************/
49038 +
49039 +-static void inline
49040 ++static inline void
49041 + acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
49042 + u8 bit_width, u64 address)
49043 + {
49044 +diff -urNp linux-2.6.27.7/drivers/ata/ahci.c linux-2.6.27.7/drivers/ata/ahci.c
49045 +--- linux-2.6.27.7/drivers/ata/ahci.c 2008-11-07 12:55:34.000000000 -0500
49046 ++++ linux-2.6.27.7/drivers/ata/ahci.c 2008-11-18 03:38:44.000000000 -0500
49047 +@@ -591,7 +591,7 @@ static const struct pci_device_id ahci_p
49048 + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
49049 + PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
49050 +
49051 +- { } /* terminate list */
49052 ++ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
49053 + };
49054 +
49055 +
49056 +diff -urNp linux-2.6.27.7/drivers/ata/ata_piix.c linux-2.6.27.7/drivers/ata/ata_piix.c
49057 +--- linux-2.6.27.7/drivers/ata/ata_piix.c 2008-11-07 12:55:34.000000000 -0500
49058 ++++ linux-2.6.27.7/drivers/ata/ata_piix.c 2008-11-18 03:38:44.000000000 -0500
49059 +@@ -284,7 +284,7 @@ static const struct pci_device_id piix_p
49060 + /* SATA Controller IDE (PCH) */
49061 + { 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
49062 +
49063 +- { } /* terminate list */
49064 ++ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
49065 + };
49066 +
49067 + static struct pci_driver piix_pci_driver = {
49068 +@@ -587,7 +587,7 @@ static const struct ich_laptop ich_lapto
49069 + { 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */
49070 + { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */
49071 + /* end marker */
49072 +- { 0, }
49073 ++ { 0, 0, 0 }
49074 + };
49075 +
49076 + /**
49077 +@@ -1143,7 +1143,7 @@ static int piix_broken_suspend(void)
49078 + },
49079 + },
49080 +
49081 +- { } /* terminate list */
49082 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } /* terminate list */
49083 + };
49084 + static const char *oemstrs[] = {
49085 + "Tecra M3,",
49086 +diff -urNp linux-2.6.27.7/drivers/ata/libata-core.c linux-2.6.27.7/drivers/ata/libata-core.c
49087 +--- linux-2.6.27.7/drivers/ata/libata-core.c 2008-11-07 12:55:34.000000000 -0500
49088 ++++ linux-2.6.27.7/drivers/ata/libata-core.c 2008-11-18 03:38:44.000000000 -0500
49089 +@@ -746,7 +746,7 @@ static const struct ata_xfer_ent {
49090 + { ATA_SHIFT_PIO, ATA_NR_PIO_MODES, XFER_PIO_0 },
49091 + { ATA_SHIFT_MWDMA, ATA_NR_MWDMA_MODES, XFER_MW_DMA_0 },
49092 + { ATA_SHIFT_UDMA, ATA_NR_UDMA_MODES, XFER_UDMA_0 },
49093 +- { -1, },
49094 ++ { -1, 0, 0 }
49095 + };
49096 +
49097 + /**
49098 +@@ -2910,7 +2910,7 @@ static const struct ata_timing ata_timin
49099 + { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 20 },
49100 + { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 15 },
49101 +
49102 +- { 0xFF }
49103 ++ { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
49104 + };
49105 +
49106 + #define ENOUGH(v, unit) (((v)-1)/(unit)+1)
49107 +@@ -3999,7 +3999,7 @@ static const struct ata_blacklist_entry
49108 + { "TSSTcorp CDDVDW SH-S202N", "SB01", ATA_HORKAGE_IVB, },
49109 +
49110 + /* End Marker */
49111 +- { }
49112 ++ { NULL, NULL, 0 }
49113 + };
49114 +
49115 + static int strn_pattern_cmp(const char *patt, const char *name, int wildchar)
49116 +diff -urNp linux-2.6.27.7/drivers/char/agp/frontend.c linux-2.6.27.7/drivers/char/agp/frontend.c
49117 +--- linux-2.6.27.7/drivers/char/agp/frontend.c 2008-11-07 12:55:34.000000000 -0500
49118 ++++ linux-2.6.27.7/drivers/char/agp/frontend.c 2008-11-18 03:38:44.000000000 -0500
49119 +@@ -824,7 +824,7 @@ static int agpioc_reserve_wrap(struct ag
49120 + if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
49121 + return -EFAULT;
49122 +
49123 +- if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
49124 ++ if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
49125 + return -EFAULT;
49126 +
49127 + client = agp_find_client_by_pid(reserve.pid);
49128 +diff -urNp linux-2.6.27.7/drivers/char/agp/intel-agp.c linux-2.6.27.7/drivers/char/agp/intel-agp.c
49129 +--- linux-2.6.27.7/drivers/char/agp/intel-agp.c 2008-11-07 12:55:34.000000000 -0500
49130 ++++ linux-2.6.27.7/drivers/char/agp/intel-agp.c 2008-11-18 03:38:44.000000000 -0500
49131 +@@ -2332,7 +2332,7 @@ static struct pci_device_id agp_intel_pc
49132 + ID(PCI_DEVICE_ID_INTEL_IGD_E_HB),
49133 + ID(PCI_DEVICE_ID_INTEL_Q45_HB),
49134 + ID(PCI_DEVICE_ID_INTEL_G45_HB),
49135 +- { }
49136 ++ { 0, 0, 0, 0, 0, 0, 0 }
49137 + };
49138 +
49139 + MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
49140 +diff -urNp linux-2.6.27.7/drivers/char/hpet.c linux-2.6.27.7/drivers/char/hpet.c
49141 +--- linux-2.6.27.7/drivers/char/hpet.c 2008-11-07 12:55:34.000000000 -0500
49142 ++++ linux-2.6.27.7/drivers/char/hpet.c 2008-11-18 03:38:44.000000000 -0500
49143 +@@ -959,7 +959,7 @@ static struct acpi_driver hpet_acpi_driv
49144 + },
49145 + };
49146 +
49147 +-static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
49148 ++static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL };
49149 +
49150 + static int __init hpet_init(void)
49151 + {
49152 +diff -urNp linux-2.6.27.7/drivers/char/keyboard.c linux-2.6.27.7/drivers/char/keyboard.c
49153 +--- linux-2.6.27.7/drivers/char/keyboard.c 2008-11-07 12:55:34.000000000 -0500
49154 ++++ linux-2.6.27.7/drivers/char/keyboard.c 2008-11-18 03:38:44.000000000 -0500
49155 +@@ -635,6 +635,16 @@ static void k_spec(struct vc_data *vc, u
49156 + kbd->kbdmode == VC_MEDIUMRAW) &&
49157 + value != KVAL(K_SAK))
49158 + return; /* SAK is allowed even in raw mode */
49159 ++
49160 ++#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
49161 ++ {
49162 ++ void *func = fn_handler[value];
49163 ++ if (func == fn_show_state || func == fn_show_ptregs ||
49164 ++ func == fn_show_mem)
49165 ++ return;
49166 ++ }
49167 ++#endif
49168 ++
49169 + fn_handler[value](vc);
49170 + }
49171 +
49172 +@@ -1388,7 +1398,7 @@ static const struct input_device_id kbd_
49173 + .evbit = { BIT_MASK(EV_SND) },
49174 + },
49175 +
49176 +- { }, /* Terminating entry */
49177 ++ { 0 }, /* Terminating entry */
49178 + };
49179 +
49180 + MODULE_DEVICE_TABLE(input, kbd_ids);
49181 +diff -urNp linux-2.6.27.7/drivers/char/mem.c linux-2.6.27.7/drivers/char/mem.c
49182 +--- linux-2.6.27.7/drivers/char/mem.c 2008-11-07 12:55:34.000000000 -0500
49183 ++++ linux-2.6.27.7/drivers/char/mem.c 2008-11-18 03:38:44.000000000 -0500
49184 +@@ -27,6 +27,7 @@
49185 + #include <linux/splice.h>
49186 + #include <linux/pfn.h>
49187 + #include <linux/smp_lock.h>
49188 ++#include <linux/grsecurity.h>
49189 +
49190 + #include <asm/uaccess.h>
49191 + #include <asm/io.h>
49192 +@@ -35,6 +36,10 @@
49193 + # include <linux/efi.h>
49194 + #endif
49195 +
49196 ++#ifdef CONFIG_GRKERNSEC
49197 ++extern struct file_operations grsec_fops;
49198 ++#endif
49199 ++
49200 + /*
49201 + * Architectures vary in how they handle caching for addresses
49202 + * outside of main memory.
49203 +@@ -192,6 +197,11 @@ static ssize_t write_mem(struct file * f
49204 + if (!valid_phys_addr_range(p, count))
49205 + return -EFAULT;
49206 +
49207 ++#ifdef CONFIG_GRKERNSEC_KMEM
49208 ++ gr_handle_mem_write();
49209 ++ return -EPERM;
49210 ++#endif
49211 ++
49212 + written = 0;
49213 +
49214 + #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
49215 +@@ -350,6 +360,11 @@ static int mmap_mem(struct file * file,
49216 + &vma->vm_page_prot))
49217 + return -EINVAL;
49218 +
49219 ++#ifdef CONFIG_GRKERNSEC_KMEM
49220 ++ if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
49221 ++ return -EPERM;
49222 ++#endif
49223 ++
49224 + vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
49225 + size,
49226 + vma->vm_page_prot);
49227 +@@ -588,6 +603,11 @@ static ssize_t write_kmem(struct file *
49228 + ssize_t written;
49229 + char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
49230 +
49231 ++#ifdef CONFIG_GRKERNSEC_KMEM
49232 ++ gr_handle_kmem_write();
49233 ++ return -EPERM;
49234 ++#endif
49235 ++
49236 + if (p < (unsigned long) high_memory) {
49237 +
49238 + wrote = count;
49239 +@@ -791,6 +811,16 @@ static loff_t memory_lseek(struct file *
49240 +
49241 + static int open_port(struct inode * inode, struct file * filp)
49242 + {
49243 ++#ifdef CONFIG_GRKERNSEC_KMEM
49244 ++ gr_handle_open_port();
49245 ++ return -EPERM;
49246 ++#endif
49247 ++
49248 ++ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
49249 ++}
49250 ++
49251 ++static int open_mem(struct inode * inode, struct file * filp)
49252 ++{
49253 + return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
49254 + }
49255 +
49256 +@@ -798,7 +828,6 @@ static int open_port(struct inode * inod
49257 + #define full_lseek null_lseek
49258 + #define write_zero write_null
49259 + #define read_full read_zero
49260 +-#define open_mem open_port
49261 + #define open_kmem open_mem
49262 + #define open_oldmem open_mem
49263 +
49264 +@@ -938,6 +967,11 @@ static int memory_open(struct inode * in
49265 + filp->f_op = &oldmem_fops;
49266 + break;
49267 + #endif
49268 ++#ifdef CONFIG_GRKERNSEC
49269 ++ case 13:
49270 ++ filp->f_op = &grsec_fops;
49271 ++ break;
49272 ++#endif
49273 + default:
49274 + unlock_kernel();
49275 + return -ENXIO;
49276 +@@ -974,6 +1008,9 @@ static const struct {
49277 + #ifdef CONFIG_CRASH_DUMP
49278 + {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
49279 + #endif
49280 ++#ifdef CONFIG_GRKERNSEC
49281 ++ {13,"grsec", S_IRUSR | S_IWUGO, &grsec_fops},
49282 ++#endif
49283 + };
49284 +
49285 + static struct class *mem_class;
49286 +diff -urNp linux-2.6.27.7/drivers/char/nvram.c linux-2.6.27.7/drivers/char/nvram.c
49287 +--- linux-2.6.27.7/drivers/char/nvram.c 2008-11-07 12:55:34.000000000 -0500
49288 ++++ linux-2.6.27.7/drivers/char/nvram.c 2008-11-18 03:38:44.000000000 -0500
49289 +@@ -433,7 +433,10 @@ static const struct file_operations nvra
49290 + static struct miscdevice nvram_dev = {
49291 + NVRAM_MINOR,
49292 + "nvram",
49293 +- &nvram_fops
49294 ++ &nvram_fops,
49295 ++ {NULL, NULL},
49296 ++ NULL,
49297 ++ NULL
49298 + };
49299 +
49300 + static int __init
49301 +diff -urNp linux-2.6.27.7/drivers/char/random.c linux-2.6.27.7/drivers/char/random.c
49302 +--- linux-2.6.27.7/drivers/char/random.c 2008-11-07 12:55:34.000000000 -0500
49303 ++++ linux-2.6.27.7/drivers/char/random.c 2008-11-18 03:38:44.000000000 -0500
49304 +@@ -249,8 +249,13 @@
49305 + /*
49306 + * Configuration information
49307 + */
49308 ++#ifdef CONFIG_GRKERNSEC_RANDNET
49309 ++#define INPUT_POOL_WORDS 512
49310 ++#define OUTPUT_POOL_WORDS 128
49311 ++#else
49312 + #define INPUT_POOL_WORDS 128
49313 + #define OUTPUT_POOL_WORDS 32
49314 ++#endif
49315 + #define SEC_XFER_SIZE 512
49316 +
49317 + /*
49318 +@@ -287,10 +292,17 @@ static struct poolinfo {
49319 + int poolwords;
49320 + int tap1, tap2, tap3, tap4, tap5;
49321 + } poolinfo_table[] = {
49322 ++#ifdef CONFIG_GRKERNSEC_RANDNET
49323 ++ /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
49324 ++ { 512, 411, 308, 208, 104, 1 },
49325 ++ /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
49326 ++ { 128, 103, 76, 51, 25, 1 },
49327 ++#else
49328 + /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
49329 + { 128, 103, 76, 51, 25, 1 },
49330 + /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
49331 + { 32, 26, 20, 14, 7, 1 },
49332 ++#endif
49333 + #if 0
49334 + /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
49335 + { 2048, 1638, 1231, 819, 411, 1 },
49336 +@@ -1166,7 +1178,7 @@ EXPORT_SYMBOL(generate_random_uuid);
49337 + #include <linux/sysctl.h>
49338 +
49339 + static int min_read_thresh = 8, min_write_thresh;
49340 +-static int max_read_thresh = INPUT_POOL_WORDS * 32;
49341 ++static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
49342 + static int max_write_thresh = INPUT_POOL_WORDS * 32;
49343 + static char sysctl_bootid[16];
49344 +
49345 +diff -urNp linux-2.6.27.7/drivers/char/tpm/tpm.c linux-2.6.27.7/drivers/char/tpm/tpm.c
49346 +--- linux-2.6.27.7/drivers/char/tpm/tpm.c 2008-11-07 12:55:34.000000000 -0500
49347 ++++ linux-2.6.27.7/drivers/char/tpm/tpm.c 2008-11-18 03:38:44.000000000 -0500
49348 +@@ -1037,7 +1037,7 @@ ssize_t tpm_write(struct file *file, con
49349 +
49350 + mutex_lock(&chip->buffer_mutex);
49351 +
49352 +- if (in_size > TPM_BUFSIZE)
49353 ++ if (in_size > (unsigned int)TPM_BUFSIZE)
49354 + in_size = TPM_BUFSIZE;
49355 +
49356 + if (copy_from_user
49357 +diff -urNp linux-2.6.27.7/drivers/char/vt_ioctl.c linux-2.6.27.7/drivers/char/vt_ioctl.c
49358 +--- linux-2.6.27.7/drivers/char/vt_ioctl.c 2008-11-07 12:55:34.000000000 -0500
49359 ++++ linux-2.6.27.7/drivers/char/vt_ioctl.c 2008-11-18 03:38:44.000000000 -0500
49360 +@@ -96,6 +96,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
49361 + case KDSKBENT:
49362 + if (!perm)
49363 + return -EPERM;
49364 ++
49365 ++#ifdef CONFIG_GRKERNSEC
49366 ++ if (!capable(CAP_SYS_TTY_CONFIG))
49367 ++ return -EPERM;
49368 ++#endif
49369 ++
49370 + if (!i && v == K_NOSUCHMAP) {
49371 + /* deallocate map */
49372 + key_map = key_maps[s];
49373 +@@ -236,6 +242,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry
49374 + goto reterr;
49375 + }
49376 +
49377 ++#ifdef CONFIG_GRKERNSEC
49378 ++ if (!capable(CAP_SYS_TTY_CONFIG)) {
49379 ++ ret = -EPERM;
49380 ++ goto reterr;
49381 ++ }
49382 ++#endif
49383 ++
49384 + q = func_table[i];
49385 + first_free = funcbufptr + (funcbufsize - funcbufleft);
49386 + for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
49387 +diff -urNp linux-2.6.27.7/drivers/edac/edac_core.h linux-2.6.27.7/drivers/edac/edac_core.h
49388 +--- linux-2.6.27.7/drivers/edac/edac_core.h 2008-11-07 12:55:34.000000000 -0500
49389 ++++ linux-2.6.27.7/drivers/edac/edac_core.h 2008-11-18 03:38:44.000000000 -0500
49390 +@@ -85,11 +85,11 @@ extern int edac_debug_level;
49391 +
49392 + #else /* !CONFIG_EDAC_DEBUG */
49393 +
49394 +-#define debugf0( ... )
49395 +-#define debugf1( ... )
49396 +-#define debugf2( ... )
49397 +-#define debugf3( ... )
49398 +-#define debugf4( ... )
49399 ++#define debugf0( ... ) do {} while (0)
49400 ++#define debugf1( ... ) do {} while (0)
49401 ++#define debugf2( ... ) do {} while (0)
49402 ++#define debugf3( ... ) do {} while (0)
49403 ++#define debugf4( ... ) do {} while (0)
49404 +
49405 + #endif /* !CONFIG_EDAC_DEBUG */
49406 +
49407 +diff -urNp linux-2.6.27.7/drivers/firmware/dmi_scan.c linux-2.6.27.7/drivers/firmware/dmi_scan.c
49408 +--- linux-2.6.27.7/drivers/firmware/dmi_scan.c 2008-11-07 12:55:34.000000000 -0500
49409 ++++ linux-2.6.27.7/drivers/firmware/dmi_scan.c 2008-11-18 03:38:44.000000000 -0500
49410 +@@ -384,11 +384,6 @@ void __init dmi_scan_machine(void)
49411 + }
49412 + }
49413 + else {
49414 +- /*
49415 +- * no iounmap() for that ioremap(); it would be a no-op, but
49416 +- * it's so early in setup that sucker gets confused into doing
49417 +- * what it shouldn't if we actually call it.
49418 +- */
49419 + p = dmi_ioremap(0xF0000, 0x10000);
49420 + if (p == NULL)
49421 + goto out;
49422 +diff -urNp linux-2.6.27.7/drivers/hwmon/fscpos.c linux-2.6.27.7/drivers/hwmon/fscpos.c
49423 +--- linux-2.6.27.7/drivers/hwmon/fscpos.c 2008-11-07 12:55:34.000000000 -0500
49424 ++++ linux-2.6.27.7/drivers/hwmon/fscpos.c 2008-11-18 03:38:44.000000000 -0500
49425 +@@ -240,7 +240,6 @@ static ssize_t set_pwm(struct i2c_client
49426 + unsigned long v = simple_strtoul(buf, NULL, 10);
49427 +
49428 + /* Range: 0..255 */
49429 +- if (v < 0) v = 0;
49430 + if (v > 255) v = 255;
49431 +
49432 + mutex_lock(&data->update_lock);
49433 +diff -urNp linux-2.6.27.7/drivers/hwmon/k8temp.c linux-2.6.27.7/drivers/hwmon/k8temp.c
49434 +--- linux-2.6.27.7/drivers/hwmon/k8temp.c 2008-11-07 12:55:34.000000000 -0500
49435 ++++ linux-2.6.27.7/drivers/hwmon/k8temp.c 2008-11-18 03:38:44.000000000 -0500
49436 +@@ -130,7 +130,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
49437 +
49438 + static struct pci_device_id k8temp_ids[] = {
49439 + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
49440 +- { 0 },
49441 ++ { 0, 0, 0, 0, 0, 0, 0 },
49442 + };
49443 +
49444 + MODULE_DEVICE_TABLE(pci, k8temp_ids);
49445 +diff -urNp linux-2.6.27.7/drivers/hwmon/sis5595.c linux-2.6.27.7/drivers/hwmon/sis5595.c
49446 +--- linux-2.6.27.7/drivers/hwmon/sis5595.c 2008-11-07 12:55:34.000000000 -0500
49447 ++++ linux-2.6.27.7/drivers/hwmon/sis5595.c 2008-11-18 03:38:44.000000000 -0500
49448 +@@ -698,7 +698,7 @@ static struct sis5595_data *sis5595_upda
49449 +
49450 + static struct pci_device_id sis5595_pci_ids[] = {
49451 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
49452 +- { 0, }
49453 ++ { 0, 0, 0, 0, 0, 0, 0 }
49454 + };
49455 +
49456 + MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
49457 +diff -urNp linux-2.6.27.7/drivers/hwmon/via686a.c linux-2.6.27.7/drivers/hwmon/via686a.c
49458 +--- linux-2.6.27.7/drivers/hwmon/via686a.c 2008-11-07 12:55:34.000000000 -0500
49459 ++++ linux-2.6.27.7/drivers/hwmon/via686a.c 2008-11-18 03:38:44.000000000 -0500
49460 +@@ -768,7 +768,7 @@ static struct via686a_data *via686a_upda
49461 +
49462 + static struct pci_device_id via686a_pci_ids[] = {
49463 + { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
49464 +- { 0, }
49465 ++ { 0, 0, 0, 0, 0, 0, 0 }
49466 + };
49467 +
49468 + MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
49469 +diff -urNp linux-2.6.27.7/drivers/hwmon/vt8231.c linux-2.6.27.7/drivers/hwmon/vt8231.c
49470 +--- linux-2.6.27.7/drivers/hwmon/vt8231.c 2008-11-07 12:55:34.000000000 -0500
49471 ++++ linux-2.6.27.7/drivers/hwmon/vt8231.c 2008-11-18 03:38:44.000000000 -0500
49472 +@@ -698,7 +698,7 @@ static struct platform_driver vt8231_dri
49473 +
49474 + static struct pci_device_id vt8231_pci_ids[] = {
49475 + { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
49476 +- { 0, }
49477 ++ { 0, 0, 0, 0, 0, 0, 0 }
49478 + };
49479 +
49480 + MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
49481 +diff -urNp linux-2.6.27.7/drivers/hwmon/w83791d.c linux-2.6.27.7/drivers/hwmon/w83791d.c
49482 +--- linux-2.6.27.7/drivers/hwmon/w83791d.c 2008-11-07 12:55:34.000000000 -0500
49483 ++++ linux-2.6.27.7/drivers/hwmon/w83791d.c 2008-11-18 03:38:44.000000000 -0500
49484 +@@ -289,8 +289,8 @@ static int w83791d_detect(struct i2c_cli
49485 + struct i2c_board_info *info);
49486 + static int w83791d_remove(struct i2c_client *client);
49487 +
49488 +-static int w83791d_read(struct i2c_client *client, u8 register);
49489 +-static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
49490 ++static int w83791d_read(struct i2c_client *client, u8 reg);
49491 ++static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
49492 + static struct w83791d_data *w83791d_update_device(struct device *dev);
49493 +
49494 + #ifdef DEBUG
49495 +diff -urNp linux-2.6.27.7/drivers/i2c/busses/i2c-i801.c linux-2.6.27.7/drivers/i2c/busses/i2c-i801.c
49496 +--- linux-2.6.27.7/drivers/i2c/busses/i2c-i801.c 2008-11-07 12:55:34.000000000 -0500
49497 ++++ linux-2.6.27.7/drivers/i2c/busses/i2c-i801.c 2008-11-18 03:38:44.000000000 -0500
49498 +@@ -576,7 +576,7 @@ static struct pci_device_id i801_ids[] =
49499 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TOLAPAI_1) },
49500 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) },
49501 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) },
49502 +- { 0, }
49503 ++ { 0, 0, 0, 0, 0, 0, 0 }
49504 + };
49505 +
49506 + MODULE_DEVICE_TABLE (pci, i801_ids);
49507 +diff -urNp linux-2.6.27.7/drivers/i2c/busses/i2c-piix4.c linux-2.6.27.7/drivers/i2c/busses/i2c-piix4.c
49508 +--- linux-2.6.27.7/drivers/i2c/busses/i2c-piix4.c 2008-11-07 12:55:34.000000000 -0500
49509 ++++ linux-2.6.27.7/drivers/i2c/busses/i2c-piix4.c 2008-11-18 03:38:44.000000000 -0500
49510 +@@ -123,7 +123,7 @@ static struct dmi_system_id __devinitdat
49511 + .ident = "IBM",
49512 + .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
49513 + },
49514 +- { },
49515 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL },
49516 + };
49517 +
49518 + static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
49519 +@@ -424,7 +424,7 @@ static struct pci_device_id piix4_ids[]
49520 + PCI_DEVICE_ID_SERVERWORKS_CSB6) },
49521 + { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
49522 + PCI_DEVICE_ID_SERVERWORKS_HT1000SB) },
49523 +- { 0, }
49524 ++ { 0, 0, 0, 0, 0, 0, 0 }
49525 + };
49526 +
49527 + MODULE_DEVICE_TABLE (pci, piix4_ids);
49528 +diff -urNp linux-2.6.27.7/drivers/i2c/busses/i2c-sis630.c linux-2.6.27.7/drivers/i2c/busses/i2c-sis630.c
49529 +--- linux-2.6.27.7/drivers/i2c/busses/i2c-sis630.c 2008-11-07 12:55:34.000000000 -0500
49530 ++++ linux-2.6.27.7/drivers/i2c/busses/i2c-sis630.c 2008-11-18 03:38:44.000000000 -0500
49531 +@@ -472,7 +472,7 @@ static struct i2c_adapter sis630_adapter
49532 + static struct pci_device_id sis630_ids[] __devinitdata = {
49533 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
49534 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
49535 +- { 0, }
49536 ++ { 0, 0, 0, 0, 0, 0, 0 }
49537 + };
49538 +
49539 + MODULE_DEVICE_TABLE (pci, sis630_ids);
49540 +diff -urNp linux-2.6.27.7/drivers/i2c/busses/i2c-sis96x.c linux-2.6.27.7/drivers/i2c/busses/i2c-sis96x.c
49541 +--- linux-2.6.27.7/drivers/i2c/busses/i2c-sis96x.c 2008-11-07 12:55:34.000000000 -0500
49542 ++++ linux-2.6.27.7/drivers/i2c/busses/i2c-sis96x.c 2008-11-18 03:38:44.000000000 -0500
49543 +@@ -248,7 +248,7 @@ static struct i2c_adapter sis96x_adapter
49544 +
49545 + static struct pci_device_id sis96x_ids[] = {
49546 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
49547 +- { 0, }
49548 ++ { 0, 0, 0, 0, 0, 0, 0 }
49549 + };
49550 +
49551 + MODULE_DEVICE_TABLE (pci, sis96x_ids);
49552 +diff -urNp linux-2.6.27.7/drivers/ieee1394/dv1394.c linux-2.6.27.7/drivers/ieee1394/dv1394.c
49553 +--- linux-2.6.27.7/drivers/ieee1394/dv1394.c 2008-11-07 12:55:34.000000000 -0500
49554 ++++ linux-2.6.27.7/drivers/ieee1394/dv1394.c 2008-11-18 03:38:44.000000000 -0500
49555 +@@ -739,7 +739,7 @@ static void frame_prepare(struct video_c
49556 + based upon DIF section and sequence
49557 + */
49558 +
49559 +-static void inline
49560 ++static inline void
49561 + frame_put_packet (struct frame *f, struct packet *p)
49562 + {
49563 + int section_type = p->data[0] >> 5; /* section type is in bits 5 - 7 */
49564 +@@ -918,7 +918,7 @@ static int do_dv1394_init(struct video_c
49565 + /* default SYT offset is 3 cycles */
49566 + init->syt_offset = 3;
49567 +
49568 +- if ( (init->channel > 63) || (init->channel < 0) )
49569 ++ if (init->channel > 63)
49570 + init->channel = 63;
49571 +
49572 + chan_mask = (u64)1 << init->channel;
49573 +@@ -2174,7 +2174,7 @@ static struct ieee1394_device_id dv1394_
49574 + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
49575 + .version = AVC_SW_VERSION_ENTRY & 0xffffff
49576 + },
49577 +- { }
49578 ++ { 0, 0, 0, 0, 0, 0 }
49579 + };
49580 +
49581 + MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
49582 +diff -urNp linux-2.6.27.7/drivers/ieee1394/eth1394.c linux-2.6.27.7/drivers/ieee1394/eth1394.c
49583 +--- linux-2.6.27.7/drivers/ieee1394/eth1394.c 2008-11-07 12:55:34.000000000 -0500
49584 ++++ linux-2.6.27.7/drivers/ieee1394/eth1394.c 2008-11-18 03:38:44.000000000 -0500
49585 +@@ -451,7 +451,7 @@ static struct ieee1394_device_id eth1394
49586 + .specifier_id = ETHER1394_GASP_SPECIFIER_ID,
49587 + .version = ETHER1394_GASP_VERSION,
49588 + },
49589 +- {}
49590 ++ { 0, 0, 0, 0, 0, 0 }
49591 + };
49592 +
49593 + MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
49594 +diff -urNp linux-2.6.27.7/drivers/ieee1394/hosts.c linux-2.6.27.7/drivers/ieee1394/hosts.c
49595 +--- linux-2.6.27.7/drivers/ieee1394/hosts.c 2008-11-07 12:55:34.000000000 -0500
49596 ++++ linux-2.6.27.7/drivers/ieee1394/hosts.c 2008-11-18 03:38:44.000000000 -0500
49597 +@@ -78,6 +78,7 @@ static int dummy_isoctl(struct hpsb_iso
49598 + }
49599 +
49600 + static struct hpsb_host_driver dummy_driver = {
49601 ++ .name = "dummy",
49602 + .transmit_packet = dummy_transmit_packet,
49603 + .devctl = dummy_devctl,
49604 + .isoctl = dummy_isoctl
49605 +diff -urNp linux-2.6.27.7/drivers/ieee1394/ohci1394.c linux-2.6.27.7/drivers/ieee1394/ohci1394.c
49606 +--- linux-2.6.27.7/drivers/ieee1394/ohci1394.c 2008-11-07 12:55:34.000000000 -0500
49607 ++++ linux-2.6.27.7/drivers/ieee1394/ohci1394.c 2008-11-18 03:38:44.000000000 -0500
49608 +@@ -147,9 +147,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
49609 + printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
49610 +
49611 + /* Module Parameters */
49612 +-static int phys_dma = 1;
49613 ++static int phys_dma;
49614 + module_param(phys_dma, int, 0444);
49615 +-MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 1).");
49616 ++MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 0).");
49617 +
49618 + static void dma_trm_tasklet(unsigned long data);
49619 + static void dma_trm_reset(struct dma_trm_ctx *d);
49620 +@@ -3437,7 +3437,7 @@ static struct pci_device_id ohci1394_pci
49621 + .subvendor = PCI_ANY_ID,
49622 + .subdevice = PCI_ANY_ID,
49623 + },
49624 +- { 0, },
49625 ++ { 0, 0, 0, 0, 0, 0, 0 },
49626 + };
49627 +
49628 + MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
49629 +diff -urNp linux-2.6.27.7/drivers/ieee1394/raw1394.c linux-2.6.27.7/drivers/ieee1394/raw1394.c
49630 +--- linux-2.6.27.7/drivers/ieee1394/raw1394.c 2008-11-07 12:55:34.000000000 -0500
49631 ++++ linux-2.6.27.7/drivers/ieee1394/raw1394.c 2008-11-18 03:38:44.000000000 -0500
49632 +@@ -2968,7 +2968,7 @@ static struct ieee1394_device_id raw1394
49633 + .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
49634 + .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
49635 + .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff},
49636 +- {}
49637 ++ { 0, 0, 0, 0, 0, 0 }
49638 + };
49639 +
49640 + MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
49641 +diff -urNp linux-2.6.27.7/drivers/ieee1394/sbp2.c linux-2.6.27.7/drivers/ieee1394/sbp2.c
49642 +--- linux-2.6.27.7/drivers/ieee1394/sbp2.c 2008-11-07 12:55:34.000000000 -0500
49643 ++++ linux-2.6.27.7/drivers/ieee1394/sbp2.c 2008-11-18 03:38:44.000000000 -0500
49644 +@@ -290,7 +290,7 @@ static struct ieee1394_device_id sbp2_id
49645 + .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
49646 + .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
49647 + .version = SBP2_SW_VERSION_ENTRY & 0xffffff},
49648 +- {}
49649 ++ { 0, 0, 0, 0, 0, 0 }
49650 + };
49651 + MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
49652 +
49653 +@@ -2130,7 +2130,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot
49654 + MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
49655 + MODULE_LICENSE("GPL");
49656 +
49657 +-static int sbp2_module_init(void)
49658 ++static int __init sbp2_module_init(void)
49659 + {
49660 + int ret;
49661 +
49662 +diff -urNp linux-2.6.27.7/drivers/ieee1394/video1394.c linux-2.6.27.7/drivers/ieee1394/video1394.c
49663 +--- linux-2.6.27.7/drivers/ieee1394/video1394.c 2008-11-07 12:55:34.000000000 -0500
49664 ++++ linux-2.6.27.7/drivers/ieee1394/video1394.c 2008-11-18 03:38:44.000000000 -0500
49665 +@@ -893,7 +893,7 @@ static long video1394_ioctl(struct file
49666 + if (unlikely(d == NULL))
49667 + return -EFAULT;
49668 +
49669 +- if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) {
49670 ++ if (unlikely(v.buffer>=d->num_desc - 1)) {
49671 + PRINT(KERN_ERR, ohci->host->id,
49672 + "Buffer %d out of range",v.buffer);
49673 + return -EINVAL;
49674 +@@ -959,7 +959,7 @@ static long video1394_ioctl(struct file
49675 + if (unlikely(d == NULL))
49676 + return -EFAULT;
49677 +
49678 +- if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) {
49679 ++ if (unlikely(v.buffer>d->num_desc - 1)) {
49680 + PRINT(KERN_ERR, ohci->host->id,
49681 + "Buffer %d out of range",v.buffer);
49682 + return -EINVAL;
49683 +@@ -1030,7 +1030,7 @@ static long video1394_ioctl(struct file
49684 + d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
49685 + if (d == NULL) return -EFAULT;
49686 +
49687 +- if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
49688 ++ if (v.buffer>=d->num_desc - 1) {
49689 + PRINT(KERN_ERR, ohci->host->id,
49690 + "Buffer %d out of range",v.buffer);
49691 + return -EINVAL;
49692 +@@ -1137,7 +1137,7 @@ static long video1394_ioctl(struct file
49693 + d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
49694 + if (d == NULL) return -EFAULT;
49695 +
49696 +- if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
49697 ++ if (v.buffer>=d->num_desc-1) {
49698 + PRINT(KERN_ERR, ohci->host->id,
49699 + "Buffer %d out of range",v.buffer);
49700 + return -EINVAL;
49701 +@@ -1310,7 +1310,7 @@ static struct ieee1394_device_id video13
49702 + .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
49703 + .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff
49704 + },
49705 +- { }
49706 ++ { 0, 0, 0, 0, 0, 0 }
49707 + };
49708 +
49709 + MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
49710 +diff -urNp linux-2.6.27.7/drivers/input/keyboard/atkbd.c linux-2.6.27.7/drivers/input/keyboard/atkbd.c
49711 +--- linux-2.6.27.7/drivers/input/keyboard/atkbd.c 2008-11-07 12:55:34.000000000 -0500
49712 ++++ linux-2.6.27.7/drivers/input/keyboard/atkbd.c 2008-11-18 03:38:44.000000000 -0500
49713 +@@ -1132,7 +1132,7 @@ static struct serio_device_id atkbd_seri
49714 + .id = SERIO_ANY,
49715 + .extra = SERIO_ANY,
49716 + },
49717 +- { 0 }
49718 ++ { 0, 0, 0, 0 }
49719 + };
49720 +
49721 + MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
49722 +diff -urNp linux-2.6.27.7/drivers/input/mouse/lifebook.c linux-2.6.27.7/drivers/input/mouse/lifebook.c
49723 +--- linux-2.6.27.7/drivers/input/mouse/lifebook.c 2008-11-07 12:55:34.000000000 -0500
49724 ++++ linux-2.6.27.7/drivers/input/mouse/lifebook.c 2008-11-18 03:38:44.000000000 -0500
49725 +@@ -110,7 +110,7 @@ static const struct dmi_system_id lifebo
49726 + DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
49727 + },
49728 + },
49729 +- { }
49730 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
49731 + };
49732 +
49733 + static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
49734 +diff -urNp linux-2.6.27.7/drivers/input/mouse/psmouse-base.c linux-2.6.27.7/drivers/input/mouse/psmouse-base.c
49735 +--- linux-2.6.27.7/drivers/input/mouse/psmouse-base.c 2008-11-07 12:55:34.000000000 -0500
49736 ++++ linux-2.6.27.7/drivers/input/mouse/psmouse-base.c 2008-11-18 03:38:44.000000000 -0500
49737 +@@ -1328,7 +1328,7 @@ static struct serio_device_id psmouse_se
49738 + .id = SERIO_ANY,
49739 + .extra = SERIO_ANY,
49740 + },
49741 +- { 0 }
49742 ++ { 0, 0, 0, 0 }
49743 + };
49744 +
49745 + MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
49746 +diff -urNp linux-2.6.27.7/drivers/input/mouse/synaptics.c linux-2.6.27.7/drivers/input/mouse/synaptics.c
49747 +--- linux-2.6.27.7/drivers/input/mouse/synaptics.c 2008-11-07 12:55:34.000000000 -0500
49748 ++++ linux-2.6.27.7/drivers/input/mouse/synaptics.c 2008-11-18 03:38:45.000000000 -0500
49749 +@@ -417,7 +417,7 @@ static void synaptics_process_packet(str
49750 + break;
49751 + case 2:
49752 + if (SYN_MODEL_PEN(priv->model_id))
49753 +- ; /* Nothing, treat a pen as a single finger */
49754 ++ break; /* Nothing, treat a pen as a single finger */
49755 + break;
49756 + case 4 ... 15:
49757 + if (SYN_CAP_PALMDETECT(priv->capabilities))
49758 +@@ -624,7 +624,7 @@ static const struct dmi_system_id toshib
49759 + DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
49760 + },
49761 + },
49762 +- { }
49763 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
49764 + };
49765 + #endif
49766 +
49767 +diff -urNp linux-2.6.27.7/drivers/input/mousedev.c linux-2.6.27.7/drivers/input/mousedev.c
49768 +--- linux-2.6.27.7/drivers/input/mousedev.c 2008-11-07 12:55:34.000000000 -0500
49769 ++++ linux-2.6.27.7/drivers/input/mousedev.c 2008-11-18 03:38:45.000000000 -0500
49770 +@@ -1064,7 +1064,7 @@ static struct input_handler mousedev_han
49771 +
49772 + #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
49773 + static struct miscdevice psaux_mouse = {
49774 +- PSMOUSE_MINOR, "psaux", &mousedev_fops
49775 ++ PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL
49776 + };
49777 + static int psaux_registered;
49778 + #endif
49779 +diff -urNp linux-2.6.27.7/drivers/input/serio/i8042-x86ia64io.h linux-2.6.27.7/drivers/input/serio/i8042-x86ia64io.h
49780 +--- linux-2.6.27.7/drivers/input/serio/i8042-x86ia64io.h 2008-11-07 12:55:34.000000000 -0500
49781 ++++ linux-2.6.27.7/drivers/input/serio/i8042-x86ia64io.h 2008-11-18 03:38:45.000000000 -0500
49782 +@@ -135,7 +135,7 @@ static struct dmi_system_id __initdata i
49783 + DMI_MATCH(DMI_PRODUCT_VERSION, "5a"),
49784 + },
49785 + },
49786 +- { }
49787 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
49788 + };
49789 +
49790 + /*
49791 +@@ -322,7 +322,7 @@ static struct dmi_system_id __initdata i
49792 + DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"),
49793 + },
49794 + },
49795 +- { }
49796 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
49797 + };
49798 +
49799 + #ifdef CONFIG_PNP
49800 +@@ -334,7 +334,7 @@ static struct dmi_system_id __initdata i
49801 + DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
49802 + },
49803 + },
49804 +- { }
49805 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
49806 + };
49807 + #endif
49808 +
49809 +@@ -401,7 +401,7 @@ static struct dmi_system_id __initdata i
49810 + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"),
49811 + },
49812 + },
49813 +- { }
49814 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
49815 + };
49816 +
49817 + #endif /* CONFIG_X86 */
49818 +diff -urNp linux-2.6.27.7/drivers/input/serio/serio_raw.c linux-2.6.27.7/drivers/input/serio/serio_raw.c
49819 +--- linux-2.6.27.7/drivers/input/serio/serio_raw.c 2008-11-07 12:55:34.000000000 -0500
49820 ++++ linux-2.6.27.7/drivers/input/serio/serio_raw.c 2008-11-18 03:38:45.000000000 -0500
49821 +@@ -373,7 +373,7 @@ static struct serio_device_id serio_raw_
49822 + .id = SERIO_ANY,
49823 + .extra = SERIO_ANY,
49824 + },
49825 +- { 0 }
49826 ++ { 0, 0, 0, 0 }
49827 + };
49828 +
49829 + MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
49830 +diff -urNp linux-2.6.27.7/drivers/md/bitmap.c linux-2.6.27.7/drivers/md/bitmap.c
49831 +--- linux-2.6.27.7/drivers/md/bitmap.c 2008-11-07 12:55:34.000000000 -0500
49832 ++++ linux-2.6.27.7/drivers/md/bitmap.c 2008-11-18 03:38:45.000000000 -0500
49833 +@@ -57,7 +57,7 @@
49834 + # if DEBUG > 0
49835 + # define PRINTK(x...) printk(KERN_DEBUG x)
49836 + # else
49837 +-# define PRINTK(x...)
49838 ++# define PRINTK(x...) do {} while (0)
49839 + # endif
49840 + #endif
49841 +
49842 +diff -urNp linux-2.6.27.7/drivers/mtd/devices/doc2000.c linux-2.6.27.7/drivers/mtd/devices/doc2000.c
49843 +--- linux-2.6.27.7/drivers/mtd/devices/doc2000.c 2008-11-07 12:55:34.000000000 -0500
49844 ++++ linux-2.6.27.7/drivers/mtd/devices/doc2000.c 2008-11-18 03:38:45.000000000 -0500
49845 +@@ -777,7 +777,7 @@ static int doc_write(struct mtd_info *mt
49846 +
49847 + /* The ECC will not be calculated correctly if less than 512 is written */
49848 + /* DBB-
49849 +- if (len != 0x200 && eccbuf)
49850 ++ if (len != 0x200)
49851 + printk(KERN_WARNING
49852 + "ECC needs a full sector write (adr: %lx size %lx)\n",
49853 + (long) to, (long) len);
49854 +diff -urNp linux-2.6.27.7/drivers/mtd/devices/doc2001.c linux-2.6.27.7/drivers/mtd/devices/doc2001.c
49855 +--- linux-2.6.27.7/drivers/mtd/devices/doc2001.c 2008-11-07 12:55:34.000000000 -0500
49856 ++++ linux-2.6.27.7/drivers/mtd/devices/doc2001.c 2008-11-18 03:38:45.000000000 -0500
49857 +@@ -396,6 +396,8 @@ static int doc_read (struct mtd_info *mt
49858 + /* Don't allow read past end of device */
49859 + if (from >= this->totlen)
49860 + return -EINVAL;
49861 ++ if (!len)
49862 ++ return -EINVAL;
49863 +
49864 + /* Don't allow a single read to cross a 512-byte block boundary */
49865 + if (from + len > ((from | 0x1ff) + 1))
49866 +diff -urNp linux-2.6.27.7/drivers/mtd/devices/slram.c linux-2.6.27.7/drivers/mtd/devices/slram.c
49867 +--- linux-2.6.27.7/drivers/mtd/devices/slram.c 2008-11-07 12:55:34.000000000 -0500
49868 ++++ linux-2.6.27.7/drivers/mtd/devices/slram.c 2008-11-18 03:38:45.000000000 -0500
49869 +@@ -273,7 +273,7 @@ static int parse_cmdline(char *devname,
49870 + }
49871 + T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n",
49872 + devname, devstart, devlength);
49873 +- if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) {
49874 ++ if (devlength % SLRAM_BLK_SZ != 0) {
49875 + E("slram: Illegal start / length parameter.\n");
49876 + return(-EINVAL);
49877 + }
49878 +diff -urNp linux-2.6.27.7/drivers/mtd/ubi/build.c linux-2.6.27.7/drivers/mtd/ubi/build.c
49879 +--- linux-2.6.27.7/drivers/mtd/ubi/build.c 2008-11-07 12:55:34.000000000 -0500
49880 ++++ linux-2.6.27.7/drivers/mtd/ubi/build.c 2008-11-18 03:38:45.000000000 -0500
49881 +@@ -1104,7 +1104,7 @@ static int __init bytes_str_to_int(const
49882 + unsigned long result;
49883 +
49884 + result = simple_strtoul(str, &endp, 0);
49885 +- if (str == endp || result < 0) {
49886 ++ if (str == endp) {
49887 + printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n",
49888 + str);
49889 + return -EINVAL;
49890 +diff -urNp linux-2.6.27.7/drivers/net/eepro100.c linux-2.6.27.7/drivers/net/eepro100.c
49891 +--- linux-2.6.27.7/drivers/net/eepro100.c 2008-11-07 12:55:34.000000000 -0500
49892 ++++ linux-2.6.27.7/drivers/net/eepro100.c 2008-11-18 03:38:45.000000000 -0500
49893 +@@ -47,7 +47,7 @@ static int rxdmacount /* = 0 */;
49894 + # define rx_align(skb) skb_reserve((skb), 2)
49895 + # define RxFD_ALIGNMENT __attribute__ ((aligned (2), packed))
49896 + #else
49897 +-# define rx_align(skb)
49898 ++# define rx_align(skb) do {} while (0)
49899 + # define RxFD_ALIGNMENT
49900 + #endif
49901 +
49902 +@@ -2334,33 +2334,33 @@ static void __devexit eepro100_remove_on
49903 + }
49904 +
49905 + static struct pci_device_id eepro100_pci_tbl[] = {
49906 +- { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, },
49907 +- { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, },
49908 +- { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, },
49909 +- { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, },
49910 +- { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, },
49911 +- { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, },
49912 +- { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, },
49913 +- { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, },
49914 +- { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, },
49915 +- { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, },
49916 +- { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, },
49917 +- { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, },
49918 +- { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, },
49919 +- { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, },
49920 +- { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, },
49921 +- { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, },
49922 +- { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, },
49923 +- { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, },
49924 +- { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, },
49925 +- { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, },
49926 +- { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
49927 +- { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, },
49928 +- { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, },
49929 +- { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, },
49930 +- { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, },
49931 +- { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, },
49932 +- { 0,}
49933 ++ { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49934 ++ { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49935 ++ { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49936 ++ { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49937 ++ { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49938 ++ { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49939 ++ { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49940 ++ { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49941 ++ { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49942 ++ { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49943 ++ { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49944 ++ { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49945 ++ { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49946 ++ { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49947 ++ { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49948 ++ { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49949 ++ { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49950 ++ { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49951 ++ { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49952 ++ { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49953 ++ { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49954 ++ { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49955 ++ { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49956 ++ { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49957 ++ { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49958 ++ { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
49959 ++ { 0, 0, 0, 0, 0, 0, 0 }
49960 + };
49961 + MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
49962 +
49963 +diff -urNp linux-2.6.27.7/drivers/net/irda/vlsi_ir.c linux-2.6.27.7/drivers/net/irda/vlsi_ir.c
49964 +--- linux-2.6.27.7/drivers/net/irda/vlsi_ir.c 2008-11-07 12:55:34.000000000 -0500
49965 ++++ linux-2.6.27.7/drivers/net/irda/vlsi_ir.c 2008-11-18 03:38:45.000000000 -0500
49966 +@@ -906,13 +906,12 @@ static int vlsi_hard_start_xmit(struct s
49967 + /* no race - tx-ring already empty */
49968 + vlsi_set_baud(idev, iobase);
49969 + netif_wake_queue(ndev);
49970 +- }
49971 +- else
49972 +- ;
49973 ++ } else {
49974 + /* keep the speed change pending like it would
49975 + * for any len>0 packet. tx completion interrupt
49976 + * will apply it when the tx ring becomes empty.
49977 + */
49978 ++ }
49979 + spin_unlock_irqrestore(&idev->lock, flags);
49980 + dev_kfree_skb_any(skb);
49981 + return 0;
49982 +diff -urNp linux-2.6.27.7/drivers/net/pcnet32.c linux-2.6.27.7/drivers/net/pcnet32.c
49983 +--- linux-2.6.27.7/drivers/net/pcnet32.c 2008-11-07 12:55:34.000000000 -0500
49984 ++++ linux-2.6.27.7/drivers/net/pcnet32.c 2008-11-18 03:38:45.000000000 -0500
49985 +@@ -78,7 +78,7 @@ static int cards_found;
49986 + /*
49987 + * VLB I/O addresses
49988 + */
49989 +-static unsigned int pcnet32_portlist[] __initdata =
49990 ++static unsigned int pcnet32_portlist[] __devinitdata =
49991 + { 0x300, 0x320, 0x340, 0x360, 0 };
49992 +
49993 + static int pcnet32_debug = 0;
49994 +diff -urNp linux-2.6.27.7/drivers/net/tg3.h linux-2.6.27.7/drivers/net/tg3.h
49995 +--- linux-2.6.27.7/drivers/net/tg3.h 2008-11-07 12:55:34.000000000 -0500
49996 ++++ linux-2.6.27.7/drivers/net/tg3.h 2008-11-18 03:38:45.000000000 -0500
49997 +@@ -102,6 +102,7 @@
49998 + #define CHIPREV_ID_5750_A0 0x4000
49999 + #define CHIPREV_ID_5750_A1 0x4001
50000 + #define CHIPREV_ID_5750_A3 0x4003
50001 ++#define CHIPREV_ID_5750_C1 0x4201
50002 + #define CHIPREV_ID_5750_C2 0x4202
50003 + #define CHIPREV_ID_5752_A0_HW 0x5000
50004 + #define CHIPREV_ID_5752_A0 0x6000
50005 +diff -urNp linux-2.6.27.7/drivers/pci/hotplug/cpqphp_nvram.c linux-2.6.27.7/drivers/pci/hotplug/cpqphp_nvram.c
50006 +--- linux-2.6.27.7/drivers/pci/hotplug/cpqphp_nvram.c 2008-11-07 12:55:34.000000000 -0500
50007 ++++ linux-2.6.27.7/drivers/pci/hotplug/cpqphp_nvram.c 2008-11-18 03:38:45.000000000 -0500
50008 +@@ -425,9 +425,13 @@ static u32 store_HRT (void __iomem *rom_
50009 +
50010 + void compaq_nvram_init (void __iomem *rom_start)
50011 + {
50012 ++
50013 ++#ifndef CONFIG_PAX_KERNEXEC
50014 + if (rom_start) {
50015 + compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
50016 + }
50017 ++#endif
50018 ++
50019 + dbg("int15 entry = %p\n", compaq_int15_entry_point);
50020 +
50021 + /* initialize our int15 lock */
50022 +diff -urNp linux-2.6.27.7/drivers/pci/pcie/aer/aerdrv.c linux-2.6.27.7/drivers/pci/pcie/aer/aerdrv.c
50023 +--- linux-2.6.27.7/drivers/pci/pcie/aer/aerdrv.c 2008-11-07 12:55:34.000000000 -0500
50024 ++++ linux-2.6.27.7/drivers/pci/pcie/aer/aerdrv.c 2008-11-18 03:38:45.000000000 -0500
50025 +@@ -59,7 +59,7 @@ static struct pcie_port_service_id aer_i
50026 + .port_type = PCIE_RC_PORT,
50027 + .service_type = PCIE_PORT_SERVICE_AER,
50028 + },
50029 +- { /* end: all zeroes */ }
50030 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
50031 + };
50032 +
50033 + static struct pci_error_handlers aer_error_handlers = {
50034 +diff -urNp linux-2.6.27.7/drivers/pci/pcie/aer/aerdrv_core.c linux-2.6.27.7/drivers/pci/pcie/aer/aerdrv_core.c
50035 +--- linux-2.6.27.7/drivers/pci/pcie/aer/aerdrv_core.c 2008-11-07 12:55:34.000000000 -0500
50036 ++++ linux-2.6.27.7/drivers/pci/pcie/aer/aerdrv_core.c 2008-11-18 03:38:45.000000000 -0500
50037 +@@ -663,7 +663,7 @@ static void aer_isr_one_error(struct pci
50038 + struct aer_err_source *e_src)
50039 + {
50040 + struct device *s_device;
50041 +- struct aer_err_info e_info = {0, 0, 0,};
50042 ++ struct aer_err_info e_info = {0, 0, 0, {0, 0, 0, 0}};
50043 + int i;
50044 + u16 id;
50045 +
50046 +diff -urNp linux-2.6.27.7/drivers/pci/pcie/portdrv_pci.c linux-2.6.27.7/drivers/pci/pcie/portdrv_pci.c
50047 +--- linux-2.6.27.7/drivers/pci/pcie/portdrv_pci.c 2008-11-07 12:55:34.000000000 -0500
50048 ++++ linux-2.6.27.7/drivers/pci/pcie/portdrv_pci.c 2008-11-18 03:38:45.000000000 -0500
50049 +@@ -264,7 +264,7 @@ static void pcie_portdrv_err_resume(stru
50050 + static const struct pci_device_id port_pci_ids[] = { {
50051 + /* handle any PCI-Express port */
50052 + PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
50053 +- }, { /* end: all zeroes */ }
50054 ++ }, { 0, 0, 0, 0, 0, 0, 0 }
50055 + };
50056 + MODULE_DEVICE_TABLE(pci, port_pci_ids);
50057 +
50058 +diff -urNp linux-2.6.27.7/drivers/pci/proc.c linux-2.6.27.7/drivers/pci/proc.c
50059 +--- linux-2.6.27.7/drivers/pci/proc.c 2008-11-07 12:55:34.000000000 -0500
50060 ++++ linux-2.6.27.7/drivers/pci/proc.c 2008-11-18 03:38:45.000000000 -0500
50061 +@@ -470,7 +470,16 @@ static const struct file_operations proc
50062 + static int __init pci_proc_init(void)
50063 + {
50064 + struct pci_dev *dev = NULL;
50065 ++
50066 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
50067 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
50068 ++ proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR, NULL);
50069 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
50070 ++ proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
50071 ++#endif
50072 ++#else
50073 + proc_bus_pci_dir = proc_mkdir("bus/pci", NULL);
50074 ++#endif
50075 + proc_create("devices", 0, proc_bus_pci_dir,
50076 + &proc_bus_pci_dev_operations);
50077 + proc_initialized = 1;
50078 +diff -urNp linux-2.6.27.7/drivers/pcmcia/ti113x.h linux-2.6.27.7/drivers/pcmcia/ti113x.h
50079 +--- linux-2.6.27.7/drivers/pcmcia/ti113x.h 2008-11-07 12:55:34.000000000 -0500
50080 ++++ linux-2.6.27.7/drivers/pcmcia/ti113x.h 2008-11-18 03:38:45.000000000 -0500
50081 +@@ -897,7 +897,7 @@ static struct pci_device_id ene_tune_tbl
50082 + DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
50083 + ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
50084 +
50085 +- {}
50086 ++ { 0, 0, 0, 0, 0, 0, 0 }
50087 + };
50088 +
50089 + static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
50090 +diff -urNp linux-2.6.27.7/drivers/pcmcia/yenta_socket.c linux-2.6.27.7/drivers/pcmcia/yenta_socket.c
50091 +--- linux-2.6.27.7/drivers/pcmcia/yenta_socket.c 2008-11-07 12:55:34.000000000 -0500
50092 ++++ linux-2.6.27.7/drivers/pcmcia/yenta_socket.c 2008-11-18 03:38:45.000000000 -0500
50093 +@@ -1358,7 +1358,7 @@ static struct pci_device_id yenta_table
50094 +
50095 + /* match any cardbus bridge */
50096 + CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
50097 +- { /* all zeroes */ }
50098 ++ { 0, 0, 0, 0, 0, 0, 0 }
50099 + };
50100 + MODULE_DEVICE_TABLE(pci, yenta_table);
50101 +
50102 +diff -urNp linux-2.6.27.7/drivers/pnp/pnpbios/bioscalls.c linux-2.6.27.7/drivers/pnp/pnpbios/bioscalls.c
50103 +--- linux-2.6.27.7/drivers/pnp/pnpbios/bioscalls.c 2008-11-07 12:55:34.000000000 -0500
50104 ++++ linux-2.6.27.7/drivers/pnp/pnpbios/bioscalls.c 2008-11-18 03:38:45.000000000 -0500
50105 +@@ -60,7 +60,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
50106 + set_limit(gdt[(selname) >> 3], size); \
50107 + } while(0)
50108 +
50109 +-static struct desc_struct bad_bios_desc;
50110 ++static struct desc_struct bad_bios_desc __read_only;
50111 +
50112 + /*
50113 + * At some point we want to use this stack frame pointer to unwind
50114 +@@ -87,6 +87,10 @@ static inline u16 call_pnp_bios(u16 func
50115 + struct desc_struct save_desc_40;
50116 + int cpu;
50117 +
50118 ++#ifdef CONFIG_PAX_KERNEXEC
50119 ++ unsigned long cr0;
50120 ++#endif
50121 ++
50122 + /*
50123 + * PnP BIOSes are generally not terribly re-entrant.
50124 + * Also, don't rely on them to save everything correctly.
50125 +@@ -96,8 +100,17 @@ static inline u16 call_pnp_bios(u16 func
50126 +
50127 + cpu = get_cpu();
50128 + save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
50129 ++
50130 ++#ifdef CONFIG_PAX_KERNEXEC
50131 ++ pax_open_kernel(cr0);
50132 ++#endif
50133 ++
50134 + get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
50135 +
50136 ++#ifdef CONFIG_PAX_KERNEXEC
50137 ++ pax_close_kernel(cr0);
50138 ++#endif
50139 ++
50140 + /* On some boxes IRQ's during PnP BIOS calls are deadly. */
50141 + spin_lock_irqsave(&pnp_bios_lock, flags);
50142 +
50143 +@@ -134,7 +147,16 @@ static inline u16 call_pnp_bios(u16 func
50144 + :"memory");
50145 + spin_unlock_irqrestore(&pnp_bios_lock, flags);
50146 +
50147 ++#ifdef CONFIG_PAX_KERNEXEC
50148 ++ pax_open_kernel(cr0);
50149 ++#endif
50150 ++
50151 + get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
50152 ++
50153 ++#ifdef CONFIG_PAX_KERNEXEC
50154 ++ pax_close_kernel(cr0);
50155 ++#endif
50156 ++
50157 + put_cpu();
50158 +
50159 + /* If we get here and this is set then the PnP BIOS faulted on us. */
50160 +@@ -468,16 +490,24 @@ int pnp_bios_read_escd(char *data, u32 n
50161 + return status;
50162 + }
50163 +
50164 +-void pnpbios_calls_init(union pnp_bios_install_struct *header)
50165 ++void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
50166 + {
50167 + int i;
50168 +
50169 ++#ifdef CONFIG_PAX_KERNEXEC
50170 ++ unsigned long cr0;
50171 ++#endif
50172 ++
50173 + spin_lock_init(&pnp_bios_lock);
50174 + pnp_bios_callpoint.offset = header->fields.pm16offset;
50175 + pnp_bios_callpoint.segment = PNP_CS16;
50176 +
50177 ++#ifdef CONFIG_PAX_KERNEXEC
50178 ++ pax_open_kernel(cr0);
50179 ++#endif
50180 ++
50181 + bad_bios_desc.a = 0;
50182 +- bad_bios_desc.b = 0x00409200;
50183 ++ bad_bios_desc.b = 0x00409300;
50184 +
50185 + set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
50186 + _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
50187 +@@ -491,4 +521,9 @@ void pnpbios_calls_init(union pnp_bios_i
50188 + set_base(gdt[GDT_ENTRY_PNPBIOS_DS],
50189 + __va(header->fields.pm16dseg));
50190 + }
50191 ++
50192 ++#ifdef CONFIG_PAX_KERNEXEC
50193 ++ pax_close_kernel(cr0);
50194 ++#endif
50195 ++
50196 + }
50197 +diff -urNp linux-2.6.27.7/drivers/pnp/quirks.c linux-2.6.27.7/drivers/pnp/quirks.c
50198 +--- linux-2.6.27.7/drivers/pnp/quirks.c 2008-11-07 12:55:34.000000000 -0500
50199 ++++ linux-2.6.27.7/drivers/pnp/quirks.c 2008-11-18 03:38:45.000000000 -0500
50200 +@@ -327,7 +327,7 @@ static struct pnp_fixup pnp_fixups[] = {
50201 + /* PnP resources that might overlap PCI BARs */
50202 + {"PNP0c01", quirk_system_pci_resources},
50203 + {"PNP0c02", quirk_system_pci_resources},
50204 +- {""}
50205 ++ {"", NULL}
50206 + };
50207 +
50208 + void pnp_fixup_device(struct pnp_dev *dev)
50209 +diff -urNp linux-2.6.27.7/drivers/pnp/resource.c linux-2.6.27.7/drivers/pnp/resource.c
50210 +--- linux-2.6.27.7/drivers/pnp/resource.c 2008-11-07 12:55:34.000000000 -0500
50211 ++++ linux-2.6.27.7/drivers/pnp/resource.c 2008-11-18 03:38:45.000000000 -0500
50212 +@@ -355,7 +355,7 @@ int pnp_check_irq(struct pnp_dev *dev, s
50213 + return 1;
50214 +
50215 + /* check if the resource is valid */
50216 +- if (*irq < 0 || *irq > 15)
50217 ++ if (*irq > 15)
50218 + return 0;
50219 +
50220 + /* check if the resource is reserved */
50221 +@@ -419,7 +419,7 @@ int pnp_check_dma(struct pnp_dev *dev, s
50222 + return 1;
50223 +
50224 + /* check if the resource is valid */
50225 +- if (*dma < 0 || *dma == 4 || *dma > 7)
50226 ++ if (*dma == 4 || *dma > 7)
50227 + return 0;
50228 +
50229 + /* check if the resource is reserved */
50230 +diff -urNp linux-2.6.27.7/drivers/scsi/scsi_logging.h linux-2.6.27.7/drivers/scsi/scsi_logging.h
50231 +--- linux-2.6.27.7/drivers/scsi/scsi_logging.h 2008-11-07 12:55:34.000000000 -0500
50232 ++++ linux-2.6.27.7/drivers/scsi/scsi_logging.h 2008-11-18 03:38:45.000000000 -0500
50233 +@@ -51,7 +51,7 @@ do { \
50234 + } while (0); \
50235 + } while (0)
50236 + #else
50237 +-#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
50238 ++#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
50239 + #endif /* CONFIG_SCSI_LOGGING */
50240 +
50241 + /*
50242 +diff -urNp linux-2.6.27.7/drivers/serial/8250_pci.c linux-2.6.27.7/drivers/serial/8250_pci.c
50243 +--- linux-2.6.27.7/drivers/serial/8250_pci.c 2008-11-07 12:55:34.000000000 -0500
50244 ++++ linux-2.6.27.7/drivers/serial/8250_pci.c 2008-11-18 03:38:45.000000000 -0500
50245 +@@ -2859,7 +2859,7 @@ static struct pci_device_id serial_pci_t
50246 + PCI_ANY_ID, PCI_ANY_ID,
50247 + PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
50248 + 0xffff00, pbn_default },
50249 +- { 0, }
50250 ++ { 0, 0, 0, 0, 0, 0, 0 }
50251 + };
50252 +
50253 + static struct pci_driver serial_pci_driver = {
50254 +diff -urNp linux-2.6.27.7/drivers/usb/class/cdc-acm.c linux-2.6.27.7/drivers/usb/class/cdc-acm.c
50255 +--- linux-2.6.27.7/drivers/usb/class/cdc-acm.c 2008-11-18 11:38:40.000000000 -0500
50256 ++++ linux-2.6.27.7/drivers/usb/class/cdc-acm.c 2008-11-18 11:40:52.000000000 -0500
50257 +@@ -1381,7 +1381,7 @@ static struct usb_device_id acm_ids[] =
50258 + USB_CDC_ACM_PROTO_AT_CDMA) },
50259 +
50260 + /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */
50261 +- { }
50262 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
50263 + };
50264 +
50265 + MODULE_DEVICE_TABLE (usb, acm_ids);
50266 +diff -urNp linux-2.6.27.7/drivers/usb/class/usblp.c linux-2.6.27.7/drivers/usb/class/usblp.c
50267 +--- linux-2.6.27.7/drivers/usb/class/usblp.c 2008-11-07 12:55:34.000000000 -0500
50268 ++++ linux-2.6.27.7/drivers/usb/class/usblp.c 2008-11-18 03:38:45.000000000 -0500
50269 +@@ -227,7 +227,7 @@ static const struct quirk_printer_struct
50270 + { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
50271 + { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@×××.de> */
50272 + { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
50273 +- { 0, 0 }
50274 ++ { 0, 0, 0 }
50275 + };
50276 +
50277 + static int usblp_wwait(struct usblp *usblp, int nonblock);
50278 +@@ -1401,7 +1401,7 @@ static struct usb_device_id usblp_ids []
50279 + { USB_INTERFACE_INFO(7, 1, 2) },
50280 + { USB_INTERFACE_INFO(7, 1, 3) },
50281 + { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */
50282 +- { } /* Terminating entry */
50283 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
50284 + };
50285 +
50286 + MODULE_DEVICE_TABLE (usb, usblp_ids);
50287 +diff -urNp linux-2.6.27.7/drivers/usb/core/hub.c linux-2.6.27.7/drivers/usb/core/hub.c
50288 +--- linux-2.6.27.7/drivers/usb/core/hub.c 2008-11-07 12:55:34.000000000 -0500
50289 ++++ linux-2.6.27.7/drivers/usb/core/hub.c 2008-11-18 03:38:45.000000000 -0500
50290 +@@ -3111,7 +3111,7 @@ static struct usb_device_id hub_id_table
50291 + .bDeviceClass = USB_CLASS_HUB},
50292 + { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
50293 + .bInterfaceClass = USB_CLASS_HUB},
50294 +- { } /* Terminating entry */
50295 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
50296 + };
50297 +
50298 + MODULE_DEVICE_TABLE (usb, hub_id_table);
50299 +diff -urNp linux-2.6.27.7/drivers/usb/host/ehci-pci.c linux-2.6.27.7/drivers/usb/host/ehci-pci.c
50300 +--- linux-2.6.27.7/drivers/usb/host/ehci-pci.c 2008-11-07 12:55:34.000000000 -0500
50301 ++++ linux-2.6.27.7/drivers/usb/host/ehci-pci.c 2008-11-18 03:38:45.000000000 -0500
50302 +@@ -390,7 +390,7 @@ static const struct pci_device_id pci_id
50303 + PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
50304 + .driver_data = (unsigned long) &ehci_pci_hc_driver,
50305 + },
50306 +- { /* end: all zeroes */ }
50307 ++ { 0, 0, 0, 0, 0, 0, 0 }
50308 + };
50309 + MODULE_DEVICE_TABLE(pci, pci_ids);
50310 +
50311 +diff -urNp linux-2.6.27.7/drivers/usb/host/uhci-hcd.c linux-2.6.27.7/drivers/usb/host/uhci-hcd.c
50312 +--- linux-2.6.27.7/drivers/usb/host/uhci-hcd.c 2008-11-07 12:55:34.000000000 -0500
50313 ++++ linux-2.6.27.7/drivers/usb/host/uhci-hcd.c 2008-11-18 03:38:45.000000000 -0500
50314 +@@ -928,7 +928,7 @@ static const struct pci_device_id uhci_p
50315 + /* handle any USB UHCI controller */
50316 + PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),
50317 + .driver_data = (unsigned long) &uhci_driver,
50318 +- }, { /* end: all zeroes */ }
50319 ++ }, { 0, 0, 0, 0, 0, 0, 0 }
50320 + };
50321 +
50322 + MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
50323 +diff -urNp linux-2.6.27.7/drivers/usb/storage/debug.h linux-2.6.27.7/drivers/usb/storage/debug.h
50324 +--- linux-2.6.27.7/drivers/usb/storage/debug.h 2008-11-07 12:55:34.000000000 -0500
50325 ++++ linux-2.6.27.7/drivers/usb/storage/debug.h 2008-11-18 03:38:45.000000000 -0500
50326 +@@ -54,9 +54,9 @@ void usb_stor_show_sense( unsigned char
50327 + #define US_DEBUGPX(x...) printk( x )
50328 + #define US_DEBUG(x) x
50329 + #else
50330 +-#define US_DEBUGP(x...)
50331 +-#define US_DEBUGPX(x...)
50332 +-#define US_DEBUG(x)
50333 ++#define US_DEBUGP(x...) do {} while (0)
50334 ++#define US_DEBUGPX(x...) do {} while (0)
50335 ++#define US_DEBUG(x) do {} while (0)
50336 + #endif
50337 +
50338 + #endif
50339 +diff -urNp linux-2.6.27.7/drivers/usb/storage/usb.c linux-2.6.27.7/drivers/usb/storage/usb.c
50340 +--- linux-2.6.27.7/drivers/usb/storage/usb.c 2008-11-07 12:55:34.000000000 -0500
50341 ++++ linux-2.6.27.7/drivers/usb/storage/usb.c 2008-11-18 03:38:45.000000000 -0500
50342 +@@ -136,7 +136,7 @@ static struct usb_device_id storage_usb_
50343 + #undef UNUSUAL_DEV
50344 + #undef USUAL_DEV
50345 + /* Terminating entry */
50346 +- { }
50347 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
50348 + };
50349 +
50350 + MODULE_DEVICE_TABLE (usb, storage_usb_ids);
50351 +@@ -176,7 +176,7 @@ static struct us_unusual_dev us_unusual_
50352 + # undef USUAL_DEV
50353 +
50354 + /* Terminating entry */
50355 +- { NULL }
50356 ++ { NULL, NULL, 0, 0, NULL }
50357 + };
50358 +
50359 +
50360 +diff -urNp linux-2.6.27.7/drivers/video/fbcmap.c linux-2.6.27.7/drivers/video/fbcmap.c
50361 +--- linux-2.6.27.7/drivers/video/fbcmap.c 2008-11-07 12:55:34.000000000 -0500
50362 ++++ linux-2.6.27.7/drivers/video/fbcmap.c 2008-11-18 03:38:45.000000000 -0500
50363 +@@ -250,8 +250,7 @@ int fb_set_user_cmap(struct fb_cmap_user
50364 + int rc, size = cmap->len * sizeof(u16);
50365 + struct fb_cmap umap;
50366 +
50367 +- if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
50368 +- !info->fbops->fb_setcmap))
50369 ++ if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)
50370 + return -EINVAL;
50371 +
50372 + memset(&umap, 0, sizeof(struct fb_cmap));
50373 +diff -urNp linux-2.6.27.7/drivers/video/fbmem.c linux-2.6.27.7/drivers/video/fbmem.c
50374 +--- linux-2.6.27.7/drivers/video/fbmem.c 2008-11-07 12:55:34.000000000 -0500
50375 ++++ linux-2.6.27.7/drivers/video/fbmem.c 2008-11-18 03:38:45.000000000 -0500
50376 +@@ -395,7 +395,7 @@ static void fb_do_show_logo(struct fb_in
50377 + image->dx += image->width + 8;
50378 + }
50379 + } else if (rotate == FB_ROTATE_UD) {
50380 +- for (x = 0; x < num && image->dx >= 0; x++) {
50381 ++ for (x = 0; x < num && (__s32)image->dx >= 0; x++) {
50382 + info->fbops->fb_imageblit(info, image);
50383 + image->dx -= image->width + 8;
50384 + }
50385 +@@ -407,7 +407,7 @@ static void fb_do_show_logo(struct fb_in
50386 + image->dy += image->height + 8;
50387 + }
50388 + } else if (rotate == FB_ROTATE_CCW) {
50389 +- for (x = 0; x < num && image->dy >= 0; x++) {
50390 ++ for (x = 0; x < num && (__s32)image->dy >= 0; x++) {
50391 + info->fbops->fb_imageblit(info, image);
50392 + image->dy -= image->height + 8;
50393 + }
50394 +@@ -1083,7 +1083,7 @@ fb_ioctl(struct inode *inode, struct fil
50395 + return - EFAULT;
50396 + if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
50397 + return -EINVAL;
50398 +- if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
50399 ++ if (con2fb.framebuffer >= FB_MAX)
50400 + return -EINVAL;
50401 + #ifdef CONFIG_KMOD
50402 + if (!registered_fb[con2fb.framebuffer])
50403 +diff -urNp linux-2.6.27.7/drivers/video/fbmon.c linux-2.6.27.7/drivers/video/fbmon.c
50404 +--- linux-2.6.27.7/drivers/video/fbmon.c 2008-11-07 12:55:34.000000000 -0500
50405 ++++ linux-2.6.27.7/drivers/video/fbmon.c 2008-11-18 03:38:45.000000000 -0500
50406 +@@ -45,7 +45,7 @@
50407 + #ifdef DEBUG
50408 + #define DPRINTK(fmt, args...) printk(fmt,## args)
50409 + #else
50410 +-#define DPRINTK(fmt, args...)
50411 ++#define DPRINTK(fmt, args...) do {} while (0)
50412 + #endif
50413 +
50414 + #define FBMON_FIX_HEADER 1
50415 +diff -urNp linux-2.6.27.7/drivers/video/i810/i810_accel.c linux-2.6.27.7/drivers/video/i810/i810_accel.c
50416 +--- linux-2.6.27.7/drivers/video/i810/i810_accel.c 2008-11-07 12:55:34.000000000 -0500
50417 ++++ linux-2.6.27.7/drivers/video/i810/i810_accel.c 2008-11-18 03:38:45.000000000 -0500
50418 +@@ -73,6 +73,7 @@ static inline int wait_for_space(struct
50419 + }
50420 + }
50421 + printk("ringbuffer lockup!!!\n");
50422 ++ printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
50423 + i810_report_error(mmio);
50424 + par->dev_flags |= LOCKUP;
50425 + info->pixmap.scan_align = 1;
50426 +diff -urNp linux-2.6.27.7/drivers/video/i810/i810_main.c linux-2.6.27.7/drivers/video/i810/i810_main.c
50427 +--- linux-2.6.27.7/drivers/video/i810/i810_main.c 2008-11-07 12:55:34.000000000 -0500
50428 ++++ linux-2.6.27.7/drivers/video/i810/i810_main.c 2008-11-18 03:38:45.000000000 -0500
50429 +@@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t
50430 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
50431 + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,
50432 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
50433 +- { 0 },
50434 ++ { 0, 0, 0, 0, 0, 0, 0 },
50435 + };
50436 +
50437 + static struct pci_driver i810fb_driver = {
50438 +@@ -1509,7 +1509,7 @@ static int i810fb_cursor(struct fb_info
50439 + int size = ((cursor->image.width + 7) >> 3) *
50440 + cursor->image.height;
50441 + int i;
50442 +- u8 *data = kmalloc(64 * 8, GFP_ATOMIC);
50443 ++ u8 *data = kmalloc(64 * 8, GFP_KERNEL);
50444 +
50445 + if (data == NULL)
50446 + return -ENOMEM;
50447 +diff -urNp linux-2.6.27.7/drivers/video/modedb.c linux-2.6.27.7/drivers/video/modedb.c
50448 +--- linux-2.6.27.7/drivers/video/modedb.c 2008-11-07 12:55:34.000000000 -0500
50449 ++++ linux-2.6.27.7/drivers/video/modedb.c 2008-11-18 03:38:45.000000000 -0500
50450 +@@ -38,232 +38,232 @@ static const struct fb_videomode modedb[
50451 + {
50452 + /* 640x400 @ 70 Hz, 31.5 kHz hsync */
50453 + NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
50454 +- 0, FB_VMODE_NONINTERLACED
50455 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50456 + }, {
50457 + /* 640x480 @ 60 Hz, 31.5 kHz hsync */
50458 + NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
50459 +- 0, FB_VMODE_NONINTERLACED
50460 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50461 + }, {
50462 + /* 800x600 @ 56 Hz, 35.15 kHz hsync */
50463 + NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
50464 +- 0, FB_VMODE_NONINTERLACED
50465 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50466 + }, {
50467 + /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
50468 + NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
50469 +- 0, FB_VMODE_INTERLACED
50470 ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
50471 + }, {
50472 + /* 640x400 @ 85 Hz, 37.86 kHz hsync */
50473 + NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
50474 +- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
50475 ++ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50476 + }, {
50477 + /* 640x480 @ 72 Hz, 36.5 kHz hsync */
50478 + NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
50479 +- 0, FB_VMODE_NONINTERLACED
50480 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50481 + }, {
50482 + /* 640x480 @ 75 Hz, 37.50 kHz hsync */
50483 + NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
50484 +- 0, FB_VMODE_NONINTERLACED
50485 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50486 + }, {
50487 + /* 800x600 @ 60 Hz, 37.8 kHz hsync */
50488 + NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
50489 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
50490 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50491 + }, {
50492 + /* 640x480 @ 85 Hz, 43.27 kHz hsync */
50493 + NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
50494 +- 0, FB_VMODE_NONINTERLACED
50495 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50496 + }, {
50497 + /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
50498 + NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
50499 +- 0, FB_VMODE_INTERLACED
50500 ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
50501 + }, {
50502 + /* 800x600 @ 72 Hz, 48.0 kHz hsync */
50503 + NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
50504 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
50505 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50506 + }, {
50507 + /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
50508 + NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
50509 +- 0, FB_VMODE_NONINTERLACED
50510 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50511 + }, {
50512 + /* 640x480 @ 100 Hz, 53.01 kHz hsync */
50513 + NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
50514 +- 0, FB_VMODE_NONINTERLACED
50515 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50516 + }, {
50517 + /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
50518 + NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
50519 +- 0, FB_VMODE_NONINTERLACED
50520 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50521 + }, {
50522 + /* 800x600 @ 85 Hz, 55.84 kHz hsync */
50523 + NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
50524 +- 0, FB_VMODE_NONINTERLACED
50525 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50526 + }, {
50527 + /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
50528 + NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
50529 +- 0, FB_VMODE_NONINTERLACED
50530 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50531 + }, {
50532 + /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
50533 + NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
50534 +- 0, FB_VMODE_INTERLACED
50535 ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
50536 + }, {
50537 + /* 800x600 @ 100 Hz, 64.02 kHz hsync */
50538 + NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
50539 +- 0, FB_VMODE_NONINTERLACED
50540 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50541 + }, {
50542 + /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
50543 + NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
50544 +- 0, FB_VMODE_NONINTERLACED
50545 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50546 + }, {
50547 + /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
50548 + NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
50549 +- 0, FB_VMODE_NONINTERLACED
50550 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50551 + }, {
50552 + /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
50553 + NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
50554 +- 0, FB_VMODE_NONINTERLACED
50555 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50556 + }, {
50557 + /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
50558 + NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
50559 +- 0, FB_VMODE_NONINTERLACED
50560 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50561 + }, {
50562 + /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
50563 + NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13,
50564 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
50565 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50566 + }, {
50567 + /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
50568 + NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
50569 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
50570 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50571 + }, {
50572 + /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
50573 + NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
50574 +- 0, FB_VMODE_NONINTERLACED
50575 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50576 + }, {
50577 + /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
50578 + NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
50579 +- 0, FB_VMODE_NONINTERLACED
50580 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50581 + }, {
50582 + /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
50583 + NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
50584 +- 0, FB_VMODE_NONINTERLACED
50585 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50586 + }, {
50587 + /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
50588 + NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
50589 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
50590 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50591 + }, {
50592 + /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
50593 + NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
50594 +- 0, FB_VMODE_NONINTERLACED
50595 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50596 + }, {
50597 + /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
50598 + NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
50599 +- 0, FB_VMODE_NONINTERLACED
50600 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50601 + }, {
50602 + /* 1024x768 @ 100Hz, 80.21 kHz hsync */
50603 + NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
50604 +- 0, FB_VMODE_NONINTERLACED
50605 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50606 + }, {
50607 + /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
50608 + NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
50609 +- 0, FB_VMODE_NONINTERLACED
50610 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50611 + }, {
50612 + /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
50613 + NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
50614 +- 0, FB_VMODE_NONINTERLACED
50615 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50616 + }, {
50617 + /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
50618 + NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
50619 +- 0, FB_VMODE_NONINTERLACED
50620 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50621 + }, {
50622 + /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
50623 + NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
50624 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
50625 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50626 + }, {
50627 + /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
50628 + NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
50629 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
50630 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50631 + }, {
50632 + /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
50633 + NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
50634 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
50635 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50636 + }, {
50637 + /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
50638 + NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
50639 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
50640 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50641 + }, {
50642 + /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
50643 + NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
50644 +- 0, FB_VMODE_NONINTERLACED
50645 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50646 + }, {
50647 + /* 1800x1440 @ 64Hz, 96.15 kHz hsync */
50648 + NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
50649 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
50650 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50651 + }, {
50652 + /* 1800x1440 @ 70Hz, 104.52 kHz hsync */
50653 + NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
50654 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
50655 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50656 + }, {
50657 + /* 512x384 @ 78 Hz, 31.50 kHz hsync */
50658 + NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
50659 +- 0, FB_VMODE_NONINTERLACED
50660 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50661 + }, {
50662 + /* 512x384 @ 85 Hz, 34.38 kHz hsync */
50663 + NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
50664 +- 0, FB_VMODE_NONINTERLACED
50665 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50666 + }, {
50667 + /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
50668 + NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
50669 +- 0, FB_VMODE_DOUBLE
50670 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
50671 + }, {
50672 + /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
50673 + NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
50674 +- 0, FB_VMODE_DOUBLE
50675 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
50676 + }, {
50677 + /* 320x240 @ 72 Hz, 36.5 kHz hsync */
50678 + NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
50679 +- 0, FB_VMODE_DOUBLE
50680 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
50681 + }, {
50682 + /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
50683 + NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
50684 +- 0, FB_VMODE_DOUBLE
50685 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
50686 + }, {
50687 + /* 400x300 @ 60 Hz, 37.8 kHz hsync */
50688 + NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
50689 +- 0, FB_VMODE_DOUBLE
50690 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
50691 + }, {
50692 + /* 400x300 @ 72 Hz, 48.0 kHz hsync */
50693 + NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
50694 +- 0, FB_VMODE_DOUBLE
50695 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
50696 + }, {
50697 + /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
50698 + NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
50699 +- 0, FB_VMODE_DOUBLE
50700 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
50701 + }, {
50702 + /* 480x300 @ 60 Hz, 37.8 kHz hsync */
50703 + NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
50704 +- 0, FB_VMODE_DOUBLE
50705 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
50706 + }, {
50707 + /* 480x300 @ 63 Hz, 39.6 kHz hsync */
50708 + NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
50709 +- 0, FB_VMODE_DOUBLE
50710 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
50711 + }, {
50712 + /* 480x300 @ 72 Hz, 48.0 kHz hsync */
50713 + NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
50714 +- 0, FB_VMODE_DOUBLE
50715 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
50716 + }, {
50717 + /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
50718 + NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
50719 + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
50720 +- FB_VMODE_NONINTERLACED
50721 ++ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50722 + }, {
50723 + /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
50724 + NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6,
50725 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
50726 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50727 + }, {
50728 + /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
50729 + NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
50730 +- 0, FB_VMODE_NONINTERLACED
50731 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50732 + }, {
50733 + /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */
50734 + NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3,
50735 +- 0, FB_VMODE_NONINTERLACED
50736 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
50737 + },
50738 + };
50739 +
50740 +diff -urNp linux-2.6.27.7/drivers/video/uvesafb.c linux-2.6.27.7/drivers/video/uvesafb.c
50741 +--- linux-2.6.27.7/drivers/video/uvesafb.c 2008-11-07 12:55:34.000000000 -0500
50742 ++++ linux-2.6.27.7/drivers/video/uvesafb.c 2008-11-18 03:38:45.000000000 -0500
50743 +@@ -18,6 +18,7 @@
50744 + #include <linux/fb.h>
50745 + #include <linux/io.h>
50746 + #include <linux/mutex.h>
50747 ++#include <linux/moduleloader.h>
50748 + #include <video/edid.h>
50749 + #include <video/uvesafb.h>
50750 + #ifdef CONFIG_X86
50751 +@@ -117,7 +118,7 @@ static int uvesafb_helper_start(void)
50752 + NULL,
50753 + };
50754 +
50755 +- return call_usermodehelper(v86d_path, argv, envp, 1);
50756 ++ return call_usermodehelper(v86d_path, argv, envp, UMH_WAIT_PROC);
50757 + }
50758 +
50759 + /*
50760 +@@ -569,10 +570,34 @@ static int __devinit uvesafb_vbe_getpmi(
50761 + if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000) {
50762 + par->pmi_setpal = par->ypan = 0;
50763 + } else {
50764 ++
50765 ++#ifdef CONFIG_PAX_KERNEXEC
50766 ++#ifdef CONFIG_MODULES
50767 ++ unsigned long cr0;
50768 ++
50769 ++ par->pmi_code = module_alloc_exec((u16)task->t.regs.ecx);
50770 ++#endif
50771 ++ if (!par->pmi_code) {
50772 ++ par->pmi_setpal = par->ypan = 0;
50773 ++ return 0;
50774 ++ }
50775 ++#endif
50776 ++
50777 + par->pmi_base = (u16 *)phys_to_virt(((u32)task->t.regs.es << 4)
50778 + + task->t.regs.edi);
50779 ++
50780 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
50781 ++ pax_open_kernel(cr0);
50782 ++ memcpy(par->pmi_code, par->pmi_base, (u16)task->t.regs.ecx);
50783 ++ pax_close_kernel(cr0);
50784 ++
50785 ++ par->pmi_start = ktva_ktla(par->pmi_code + par->pmi_base[1]);
50786 ++ par->pmi_pal = ktva_ktla(par->pmi_code + par->pmi_base[2]);
50787 ++#else
50788 + par->pmi_start = (u8 *)par->pmi_base + par->pmi_base[1];
50789 + par->pmi_pal = (u8 *)par->pmi_base + par->pmi_base[2];
50790 ++#endif
50791 ++
50792 + printk(KERN_INFO "uvesafb: protected mode interface info at "
50793 + "%04x:%04x\n",
50794 + (u16)task->t.regs.es, (u16)task->t.regs.edi);
50795 +@@ -1827,6 +1852,11 @@ out:
50796 + if (par->vbe_modes)
50797 + kfree(par->vbe_modes);
50798 +
50799 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
50800 ++ if (par->pmi_code)
50801 ++ module_free_exec(NULL, par->pmi_code);
50802 ++#endif
50803 ++
50804 + framebuffer_release(info);
50805 + return err;
50806 + }
50807 +@@ -1853,6 +1883,12 @@ static int uvesafb_remove(struct platfor
50808 + kfree(par->vbe_state_orig);
50809 + if (par->vbe_state_saved)
50810 + kfree(par->vbe_state_saved);
50811 ++
50812 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
50813 ++ if (par->pmi_code)
50814 ++ module_free_exec(NULL, par->pmi_code);
50815 ++#endif
50816 ++
50817 + }
50818 +
50819 + framebuffer_release(info);
50820 +diff -urNp linux-2.6.27.7/drivers/video/vesafb.c linux-2.6.27.7/drivers/video/vesafb.c
50821 +--- linux-2.6.27.7/drivers/video/vesafb.c 2008-11-07 12:55:34.000000000 -0500
50822 ++++ linux-2.6.27.7/drivers/video/vesafb.c 2008-11-18 03:38:45.000000000 -0500
50823 +@@ -9,6 +9,7 @@
50824 + */
50825 +
50826 + #include <linux/module.h>
50827 ++#include <linux/moduleloader.h>
50828 + #include <linux/kernel.h>
50829 + #include <linux/errno.h>
50830 + #include <linux/string.h>
50831 +@@ -53,8 +54,8 @@ static int vram_remap __initdata; /*
50832 + static int vram_total __initdata; /* Set total amount of memory */
50833 + static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */
50834 + static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */
50835 +-static void (*pmi_start)(void) __read_mostly;
50836 +-static void (*pmi_pal) (void) __read_mostly;
50837 ++static void (*pmi_start)(void) __read_only;
50838 ++static void (*pmi_pal) (void) __read_only;
50839 + static int depth __read_mostly;
50840 + static int vga_compat __read_mostly;
50841 + /* --------------------------------------------------------------------- */
50842 +@@ -224,6 +225,7 @@ static int __init vesafb_probe(struct pl
50843 + unsigned int size_vmode;
50844 + unsigned int size_remap;
50845 + unsigned int size_total;
50846 ++ void *pmi_code = NULL;
50847 +
50848 + if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
50849 + return -ENODEV;
50850 +@@ -266,10 +268,6 @@ static int __init vesafb_probe(struct pl
50851 + size_remap = size_total;
50852 + vesafb_fix.smem_len = size_remap;
50853 +
50854 +-#ifndef __i386__
50855 +- screen_info.vesapm_seg = 0;
50856 +-#endif
50857 +-
50858 + if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
50859 + printk(KERN_WARNING
50860 + "vesafb: cannot reserve video memory at 0x%lx\n",
50861 +@@ -302,9 +300,21 @@ static int __init vesafb_probe(struct pl
50862 + printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
50863 + vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
50864 +
50865 ++#ifdef __i386__
50866 ++
50867 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
50868 ++ pmi_code = module_alloc_exec(screen_info.vesapm_size);
50869 ++ if (!pmi_code)
50870 ++#elif !defined(CONFIG_PAX_KERNEXEC)
50871 ++ if (0)
50872 ++#endif
50873 ++
50874 ++#endif
50875 ++ screen_info.vesapm_seg = 0;
50876 ++
50877 + if (screen_info.vesapm_seg) {
50878 +- printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
50879 +- screen_info.vesapm_seg,screen_info.vesapm_off);
50880 ++ printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n",
50881 ++ screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size);
50882 + }
50883 +
50884 + if (screen_info.vesapm_seg < 0xc000)
50885 +@@ -312,9 +322,29 @@ static int __init vesafb_probe(struct pl
50886 +
50887 + if (ypan || pmi_setpal) {
50888 + unsigned short *pmi_base;
50889 +- pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
50890 +- pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
50891 +- pmi_pal = (void*)((char*)pmi_base + pmi_base[2]);
50892 ++
50893 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
50894 ++ unsigned long cr0;
50895 ++#endif
50896 ++
50897 ++ pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
50898 ++
50899 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
50900 ++ pax_open_kernel(cr0);
50901 ++ memcpy(pmi_code, pmi_base, screen_info.vesapm_size);
50902 ++#else
50903 ++ pmi_code = pmi_base;
50904 ++#endif
50905 ++
50906 ++ pmi_start = (void*)((char*)pmi_code + pmi_base[1]);
50907 ++ pmi_pal = (void*)((char*)pmi_code + pmi_base[2]);
50908 ++
50909 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
50910 ++ pmi_start = ktva_ktla(pmi_start);
50911 ++ pmi_pal = ktva_ktla(pmi_pal);
50912 ++ pax_close_kernel(cr0);
50913 ++#endif
50914 ++
50915 + printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
50916 + if (pmi_base[3]) {
50917 + printk(KERN_INFO "vesafb: pmi: ports = ");
50918 +@@ -456,6 +486,11 @@ static int __init vesafb_probe(struct pl
50919 + info->node, info->fix.id);
50920 + return 0;
50921 + err:
50922 ++
50923 ++#if defined(__i386__) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
50924 ++ module_free_exec(NULL, pmi_code);
50925 ++#endif
50926 ++
50927 + if (info->screen_base)
50928 + iounmap(info->screen_base);
50929 + framebuffer_release(info);
50930 +diff -urNp linux-2.6.27.7/fs/9p/vfs_inode.c linux-2.6.27.7/fs/9p/vfs_inode.c
50931 +--- linux-2.6.27.7/fs/9p/vfs_inode.c 2008-11-07 12:55:34.000000000 -0500
50932 ++++ linux-2.6.27.7/fs/9p/vfs_inode.c 2008-11-18 03:38:45.000000000 -0500
50933 +@@ -1021,7 +1021,7 @@ static void *v9fs_vfs_follow_link(struct
50934 + static void
50935 + v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
50936 + {
50937 +- char *s = nd_get_link(nd);
50938 ++ const char *s = nd_get_link(nd);
50939 +
50940 + P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name, s);
50941 + if (!IS_ERR(s))
50942 +diff -urNp linux-2.6.27.7/fs/aio.c linux-2.6.27.7/fs/aio.c
50943 +--- linux-2.6.27.7/fs/aio.c 2008-11-07 12:55:34.000000000 -0500
50944 ++++ linux-2.6.27.7/fs/aio.c 2008-11-18 03:38:45.000000000 -0500
50945 +@@ -114,7 +114,7 @@ static int aio_setup_ring(struct kioctx
50946 + size += sizeof(struct io_event) * nr_events;
50947 + nr_pages = (size + PAGE_SIZE-1) >> PAGE_SHIFT;
50948 +
50949 +- if (nr_pages < 0)
50950 ++ if (nr_pages <= 0)
50951 + return -EINVAL;
50952 +
50953 + nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) / sizeof(struct io_event);
50954 +diff -urNp linux-2.6.27.7/fs/autofs4/symlink.c linux-2.6.27.7/fs/autofs4/symlink.c
50955 +--- linux-2.6.27.7/fs/autofs4/symlink.c 2008-11-07 12:55:34.000000000 -0500
50956 ++++ linux-2.6.27.7/fs/autofs4/symlink.c 2008-11-18 03:38:45.000000000 -0500
50957 +@@ -15,7 +15,7 @@
50958 + static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
50959 + {
50960 + struct autofs_info *ino = autofs4_dentry_ino(dentry);
50961 +- nd_set_link(nd, (char *)ino->u.symlink);
50962 ++ nd_set_link(nd, ino->u.symlink);
50963 + return NULL;
50964 + }
50965 +
50966 +diff -urNp linux-2.6.27.7/fs/befs/linuxvfs.c linux-2.6.27.7/fs/befs/linuxvfs.c
50967 +--- linux-2.6.27.7/fs/befs/linuxvfs.c 2008-11-07 12:55:34.000000000 -0500
50968 ++++ linux-2.6.27.7/fs/befs/linuxvfs.c 2008-11-18 03:38:45.000000000 -0500
50969 +@@ -490,7 +490,7 @@ static void befs_put_link(struct dentry
50970 + {
50971 + befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
50972 + if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
50973 +- char *link = nd_get_link(nd);
50974 ++ const char *link = nd_get_link(nd);
50975 + if (!IS_ERR(link))
50976 + kfree(link);
50977 + }
50978 +diff -urNp linux-2.6.27.7/fs/binfmt_aout.c linux-2.6.27.7/fs/binfmt_aout.c
50979 +--- linux-2.6.27.7/fs/binfmt_aout.c 2008-11-07 12:55:34.000000000 -0500
50980 ++++ linux-2.6.27.7/fs/binfmt_aout.c 2008-11-18 03:38:45.000000000 -0500
50981 +@@ -24,6 +24,7 @@
50982 + #include <linux/binfmts.h>
50983 + #include <linux/personality.h>
50984 + #include <linux/init.h>
50985 ++#include <linux/grsecurity.h>
50986 +
50987 + #include <asm/system.h>
50988 + #include <asm/uaccess.h>
50989 +@@ -124,18 +125,22 @@ static int aout_core_dump(long signr, st
50990 + /* If the size of the dump file exceeds the rlimit, then see what would happen
50991 + if we wrote the stack, but not the data area. */
50992 + #ifdef __sparc__
50993 ++ gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize + dump.u_ssize, 1);
50994 + if ((dump.u_dsize + dump.u_ssize) > limit)
50995 + dump.u_dsize = 0;
50996 + #else
50997 ++ gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE, 1);
50998 + if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > limit)
50999 + dump.u_dsize = 0;
51000 + #endif
51001 +
51002 + /* Make sure we have enough room to write the stack and data areas. */
51003 + #ifdef __sparc__
51004 ++ gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
51005 + if (dump.u_ssize > limit)
51006 + dump.u_ssize = 0;
51007 + #else
51008 ++ gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize + 1) * PAGE_SIZE, 1);
51009 + if ((dump.u_ssize + 1) * PAGE_SIZE > limit)
51010 + dump.u_ssize = 0;
51011 + #endif
51012 +@@ -291,6 +296,8 @@ static int load_aout_binary(struct linux
51013 + rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
51014 + if (rlim >= RLIM_INFINITY)
51015 + rlim = ~0;
51016 ++
51017 ++ gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
51018 + if (ex.a_data + ex.a_bss > rlim)
51019 + return -ENOMEM;
51020 +
51021 +@@ -322,6 +329,28 @@ static int load_aout_binary(struct linux
51022 +
51023 + compute_creds(bprm);
51024 + current->flags &= ~PF_FORKNOEXEC;
51025 ++
51026 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
51027 ++ current->mm->pax_flags = 0UL;
51028 ++#endif
51029 ++
51030 ++#ifdef CONFIG_PAX_PAGEEXEC
51031 ++ if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
51032 ++ current->mm->pax_flags |= MF_PAX_PAGEEXEC;
51033 ++
51034 ++#ifdef CONFIG_PAX_EMUTRAMP
51035 ++ if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
51036 ++ current->mm->pax_flags |= MF_PAX_EMUTRAMP;
51037 ++#endif
51038 ++
51039 ++#ifdef CONFIG_PAX_MPROTECT
51040 ++ if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
51041 ++ current->mm->pax_flags |= MF_PAX_MPROTECT;
51042 ++#endif
51043 ++
51044 ++ }
51045 ++#endif
51046 ++
51047 + #ifdef __sparc__
51048 + if (N_MAGIC(ex) == NMAGIC) {
51049 + loff_t pos = fd_offset;
51050 +@@ -413,7 +442,7 @@ static int load_aout_binary(struct linux
51051 +
51052 + down_write(&current->mm->mmap_sem);
51053 + error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
51054 +- PROT_READ | PROT_WRITE | PROT_EXEC,
51055 ++ PROT_READ | PROT_WRITE,
51056 + MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
51057 + fd_offset + ex.a_text);
51058 + up_write(&current->mm->mmap_sem);
51059 +diff -urNp linux-2.6.27.7/fs/binfmt_elf.c linux-2.6.27.7/fs/binfmt_elf.c
51060 +--- linux-2.6.27.7/fs/binfmt_elf.c 2008-11-07 12:55:34.000000000 -0500
51061 ++++ linux-2.6.27.7/fs/binfmt_elf.c 2008-11-18 03:38:45.000000000 -0500
51062 +@@ -38,10 +38,16 @@
51063 + #include <linux/random.h>
51064 + #include <linux/elf.h>
51065 + #include <linux/utsname.h>
51066 ++#include <linux/grsecurity.h>
51067 ++
51068 + #include <asm/uaccess.h>
51069 + #include <asm/param.h>
51070 + #include <asm/page.h>
51071 +
51072 ++#ifdef CONFIG_PAX_SEGMEXEC
51073 ++#include <asm/desc.h>
51074 ++#endif
51075 ++
51076 + static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
51077 + static int load_elf_library(struct file *);
51078 + static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *,
51079 +@@ -84,6 +90,8 @@ static struct linux_binfmt elf_format =
51080 +
51081 + static int set_brk(unsigned long start, unsigned long end)
51082 + {
51083 ++ unsigned long e = end;
51084 ++
51085 + start = ELF_PAGEALIGN(start);
51086 + end = ELF_PAGEALIGN(end);
51087 + if (end > start) {
51088 +@@ -94,7 +102,7 @@ static int set_brk(unsigned long start,
51089 + if (BAD_ADDR(addr))
51090 + return addr;
51091 + }
51092 +- current->mm->start_brk = current->mm->brk = end;
51093 ++ current->mm->start_brk = current->mm->brk = e;
51094 + return 0;
51095 + }
51096 +
51097 +@@ -380,10 +388,10 @@ static unsigned long load_elf_interp(str
51098 + {
51099 + struct elf_phdr *elf_phdata;
51100 + struct elf_phdr *eppnt;
51101 +- unsigned long load_addr = 0;
51102 ++ unsigned long load_addr = 0, pax_task_size = TASK_SIZE;
51103 + int load_addr_set = 0;
51104 + unsigned long last_bss = 0, elf_bss = 0;
51105 +- unsigned long error = ~0UL;
51106 ++ unsigned long error = -EINVAL;
51107 + unsigned long total_size;
51108 + int retval, i, size;
51109 +
51110 +@@ -429,6 +437,11 @@ static unsigned long load_elf_interp(str
51111 + goto out_close;
51112 + }
51113 +
51114 ++#ifdef CONFIG_PAX_SEGMEXEC
51115 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
51116 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
51117 ++#endif
51118 ++
51119 + eppnt = elf_phdata;
51120 + for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
51121 + if (eppnt->p_type == PT_LOAD) {
51122 +@@ -472,8 +485,8 @@ static unsigned long load_elf_interp(str
51123 + k = load_addr + eppnt->p_vaddr;
51124 + if (BAD_ADDR(k) ||
51125 + eppnt->p_filesz > eppnt->p_memsz ||
51126 +- eppnt->p_memsz > TASK_SIZE ||
51127 +- TASK_SIZE - eppnt->p_memsz < k) {
51128 ++ eppnt->p_memsz > pax_task_size ||
51129 ++ pax_task_size - eppnt->p_memsz < k) {
51130 + error = -ENOMEM;
51131 + goto out_close;
51132 + }
51133 +@@ -527,6 +540,177 @@ out:
51134 + return error;
51135 + }
51136 +
51137 ++#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
51138 ++static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
51139 ++{
51140 ++ unsigned long pax_flags = 0UL;
51141 ++
51142 ++#ifdef CONFIG_PAX_PAGEEXEC
51143 ++ if (elf_phdata->p_flags & PF_PAGEEXEC)
51144 ++ pax_flags |= MF_PAX_PAGEEXEC;
51145 ++#endif
51146 ++
51147 ++#ifdef CONFIG_PAX_SEGMEXEC
51148 ++ if (elf_phdata->p_flags & PF_SEGMEXEC)
51149 ++ pax_flags |= MF_PAX_SEGMEXEC;
51150 ++#endif
51151 ++
51152 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
51153 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
51154 ++ if (nx_enabled)
51155 ++ pax_flags &= ~MF_PAX_SEGMEXEC;
51156 ++ else
51157 ++ pax_flags &= ~MF_PAX_PAGEEXEC;
51158 ++ }
51159 ++#endif
51160 ++
51161 ++#ifdef CONFIG_PAX_EMUTRAMP
51162 ++ if (elf_phdata->p_flags & PF_EMUTRAMP)
51163 ++ pax_flags |= MF_PAX_EMUTRAMP;
51164 ++#endif
51165 ++
51166 ++#ifdef CONFIG_PAX_MPROTECT
51167 ++ if (elf_phdata->p_flags & PF_MPROTECT)
51168 ++ pax_flags |= MF_PAX_MPROTECT;
51169 ++#endif
51170 ++
51171 ++#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
51172 ++ if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
51173 ++ pax_flags |= MF_PAX_RANDMMAP;
51174 ++#endif
51175 ++
51176 ++ return pax_flags;
51177 ++}
51178 ++#endif
51179 ++
51180 ++#ifdef CONFIG_PAX_PT_PAX_FLAGS
51181 ++static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
51182 ++{
51183 ++ unsigned long pax_flags = 0UL;
51184 ++
51185 ++#ifdef CONFIG_PAX_PAGEEXEC
51186 ++ if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
51187 ++ pax_flags |= MF_PAX_PAGEEXEC;
51188 ++#endif
51189 ++
51190 ++#ifdef CONFIG_PAX_SEGMEXEC
51191 ++ if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
51192 ++ pax_flags |= MF_PAX_SEGMEXEC;
51193 ++#endif
51194 ++
51195 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
51196 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
51197 ++ if (nx_enabled)
51198 ++ pax_flags &= ~MF_PAX_SEGMEXEC;
51199 ++ else
51200 ++ pax_flags &= ~MF_PAX_PAGEEXEC;
51201 ++ }
51202 ++#endif
51203 ++
51204 ++#ifdef CONFIG_PAX_EMUTRAMP
51205 ++ if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
51206 ++ pax_flags |= MF_PAX_EMUTRAMP;
51207 ++#endif
51208 ++
51209 ++#ifdef CONFIG_PAX_MPROTECT
51210 ++ if (!(elf_phdata->p_flags & PF_NOMPROTECT))
51211 ++ pax_flags |= MF_PAX_MPROTECT;
51212 ++#endif
51213 ++
51214 ++#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
51215 ++ if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
51216 ++ pax_flags |= MF_PAX_RANDMMAP;
51217 ++#endif
51218 ++
51219 ++ return pax_flags;
51220 ++}
51221 ++#endif
51222 ++
51223 ++#ifdef CONFIG_PAX_EI_PAX
51224 ++static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
51225 ++{
51226 ++ unsigned long pax_flags = 0UL;
51227 ++
51228 ++#ifdef CONFIG_PAX_PAGEEXEC
51229 ++ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
51230 ++ pax_flags |= MF_PAX_PAGEEXEC;
51231 ++#endif
51232 ++
51233 ++#ifdef CONFIG_PAX_SEGMEXEC
51234 ++ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
51235 ++ pax_flags |= MF_PAX_SEGMEXEC;
51236 ++#endif
51237 ++
51238 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
51239 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
51240 ++ if (nx_enabled)
51241 ++ pax_flags &= ~MF_PAX_SEGMEXEC;
51242 ++ else
51243 ++ pax_flags &= ~MF_PAX_PAGEEXEC;
51244 ++ }
51245 ++#endif
51246 ++
51247 ++#ifdef CONFIG_PAX_EMUTRAMP
51248 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
51249 ++ pax_flags |= MF_PAX_EMUTRAMP;
51250 ++#endif
51251 ++
51252 ++#ifdef CONFIG_PAX_MPROTECT
51253 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
51254 ++ pax_flags |= MF_PAX_MPROTECT;
51255 ++#endif
51256 ++
51257 ++#ifdef CONFIG_PAX_ASLR
51258 ++ if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
51259 ++ pax_flags |= MF_PAX_RANDMMAP;
51260 ++#endif
51261 ++
51262 ++ return pax_flags;
51263 ++}
51264 ++#endif
51265 ++
51266 ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
51267 ++static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
51268 ++{
51269 ++ unsigned long pax_flags = 0UL;
51270 ++
51271 ++#ifdef CONFIG_PAX_PT_PAX_FLAGS
51272 ++ unsigned long i;
51273 ++#endif
51274 ++
51275 ++#ifdef CONFIG_PAX_EI_PAX
51276 ++ pax_flags = pax_parse_ei_pax(elf_ex);
51277 ++#endif
51278 ++
51279 ++#ifdef CONFIG_PAX_PT_PAX_FLAGS
51280 ++ for (i = 0UL; i < elf_ex->e_phnum; i++)
51281 ++ if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
51282 ++ if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
51283 ++ ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
51284 ++ ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
51285 ++ ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
51286 ++ ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
51287 ++ return -EINVAL;
51288 ++
51289 ++#ifdef CONFIG_PAX_SOFTMODE
51290 ++ if (pax_softmode)
51291 ++ pax_flags = pax_parse_softmode(&elf_phdata[i]);
51292 ++ else
51293 ++#endif
51294 ++
51295 ++ pax_flags = pax_parse_hardmode(&elf_phdata[i]);
51296 ++ break;
51297 ++ }
51298 ++#endif
51299 ++
51300 ++ if (0 > pax_check_flags(&pax_flags))
51301 ++ return -EINVAL;
51302 ++
51303 ++ current->mm->pax_flags = pax_flags;
51304 ++ return 0;
51305 ++}
51306 ++#endif
51307 ++
51308 + /*
51309 + * These are the functions used to load ELF style executables and shared
51310 + * libraries. There is no binary dependent code anywhere else.
51311 +@@ -543,6 +727,11 @@ static unsigned long randomize_stack_top
51312 + {
51313 + unsigned int random_variable = 0;
51314 +
51315 ++#ifdef CONFIG_PAX_RANDUSTACK
51316 ++ if (randomize_va_space)
51317 ++ return stack_top - current->mm->delta_stack;
51318 ++#endif
51319 ++
51320 + if ((current->flags & PF_RANDOMIZE) &&
51321 + !(current->personality & ADDR_NO_RANDOMIZE)) {
51322 + random_variable = get_random_int() & STACK_RND_MASK;
51323 +@@ -561,7 +750,7 @@ static int load_elf_binary(struct linux_
51324 + unsigned long load_addr = 0, load_bias = 0;
51325 + int load_addr_set = 0;
51326 + char * elf_interpreter = NULL;
51327 +- unsigned long error;
51328 ++ unsigned long error = 0;
51329 + struct elf_phdr *elf_ppnt, *elf_phdata;
51330 + unsigned long elf_bss, elf_brk;
51331 + int elf_exec_fileno;
51332 +@@ -572,11 +761,11 @@ static int load_elf_binary(struct linux_
51333 + unsigned long start_code, end_code, start_data, end_data;
51334 + unsigned long reloc_func_desc = 0;
51335 + int executable_stack = EXSTACK_DEFAULT;
51336 +- unsigned long def_flags = 0;
51337 + struct {
51338 + struct elfhdr elf_ex;
51339 + struct elfhdr interp_elf_ex;
51340 + } *loc;
51341 ++ unsigned long pax_task_size = TASK_SIZE;
51342 +
51343 + loc = kmalloc(sizeof(*loc), GFP_KERNEL);
51344 + if (!loc) {
51345 +@@ -744,11 +933,80 @@ static int load_elf_binary(struct linux_
51346 +
51347 + /* OK, This is the point of no return */
51348 + current->flags &= ~PF_FORKNOEXEC;
51349 +- current->mm->def_flags = def_flags;
51350 ++
51351 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
51352 ++ current->mm->pax_flags = 0UL;
51353 ++#endif
51354 ++
51355 ++#ifdef CONFIG_PAX_DLRESOLVE
51356 ++ current->mm->call_dl_resolve = 0UL;
51357 ++#endif
51358 ++
51359 ++#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
51360 ++ current->mm->call_syscall = 0UL;
51361 ++#endif
51362 ++
51363 ++#ifdef CONFIG_PAX_ASLR
51364 ++ current->mm->delta_mmap = 0UL;
51365 ++ current->mm->delta_stack = 0UL;
51366 ++#endif
51367 ++
51368 ++ current->mm->def_flags = 0;
51369 ++
51370 ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
51371 ++ if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
51372 ++ send_sig(SIGKILL, current, 0);
51373 ++ goto out_free_dentry;
51374 ++ }
51375 ++#endif
51376 ++
51377 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
51378 ++ pax_set_initial_flags(bprm);
51379 ++#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
51380 ++ if (pax_set_initial_flags_func)
51381 ++ (pax_set_initial_flags_func)(bprm);
51382 ++#endif
51383 ++
51384 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
51385 ++ if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !nx_enabled) {
51386 ++ current->mm->context.user_cs_limit = PAGE_SIZE;
51387 ++ current->mm->def_flags |= VM_PAGEEXEC;
51388 ++ }
51389 ++#endif
51390 ++
51391 ++#ifdef CONFIG_PAX_SEGMEXEC
51392 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
51393 ++ current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
51394 ++ current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE;
51395 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
51396 ++ }
51397 ++#endif
51398 ++
51399 ++#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
51400 ++ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
51401 ++ set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
51402 ++ put_cpu_no_resched();
51403 ++ }
51404 ++#endif
51405 ++
51406 ++#ifdef CONFIG_PAX_ASLR
51407 ++ if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
51408 ++ current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT;
51409 ++ current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT;
51410 ++ }
51411 ++#endif
51412 +
51413 + /* Do this immediately, since STACK_TOP as used in setup_arg_pages
51414 + may depend on the personality. */
51415 + SET_PERSONALITY(loc->elf_ex, 0);
51416 ++
51417 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
51418 ++ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
51419 ++ executable_stack = EXSTACK_DISABLE_X;
51420 ++ current->personality &= ~READ_IMPLIES_EXEC;
51421 ++ } else
51422 ++#endif
51423 ++
51424 + if (elf_read_implies_exec(loc->elf_ex, executable_stack))
51425 + current->personality |= READ_IMPLIES_EXEC;
51426 +
51427 +@@ -829,6 +1087,20 @@ static int load_elf_binary(struct linux_
51428 + #else
51429 + load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
51430 + #endif
51431 ++
51432 ++#ifdef CONFIG_PAX_RANDMMAP
51433 ++ /* PaX: randomize base address at the default exe base if requested */
51434 ++ if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) {
51435 ++#ifdef CONFIG_SPARC64
51436 ++ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1);
51437 ++#else
51438 ++ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT;
51439 ++#endif
51440 ++ load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias);
51441 ++ elf_flags |= MAP_FIXED;
51442 ++ }
51443 ++#endif
51444 ++
51445 + }
51446 +
51447 + error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
51448 +@@ -861,9 +1133,9 @@ static int load_elf_binary(struct linux_
51449 + * allowed task size. Note that p_filesz must always be
51450 + * <= p_memsz so it is only necessary to check p_memsz.
51451 + */
51452 +- if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
51453 +- elf_ppnt->p_memsz > TASK_SIZE ||
51454 +- TASK_SIZE - elf_ppnt->p_memsz < k) {
51455 ++ if (k >= pax_task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
51456 ++ elf_ppnt->p_memsz > pax_task_size ||
51457 ++ pax_task_size - elf_ppnt->p_memsz < k) {
51458 + /* set_brk can never work. Avoid overflows. */
51459 + send_sig(SIGKILL, current, 0);
51460 + retval = -EINVAL;
51461 +@@ -891,6 +1163,11 @@ static int load_elf_binary(struct linux_
51462 + start_data += load_bias;
51463 + end_data += load_bias;
51464 +
51465 ++#ifdef CONFIG_PAX_RANDMMAP
51466 ++ if (current->mm->pax_flags & MF_PAX_RANDMMAP)
51467 ++ elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4);
51468 ++#endif
51469 ++
51470 + /* Calling set_brk effectively mmaps the pages that we need
51471 + * for the bss and break sections. We must do this before
51472 + * mapping in the interpreter, to make sure it doesn't wind
51473 +@@ -902,9 +1179,11 @@ static int load_elf_binary(struct linux_
51474 + goto out_free_dentry;
51475 + }
51476 + if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
51477 +- send_sig(SIGSEGV, current, 0);
51478 +- retval = -EFAULT; /* Nobody gets to see this, but.. */
51479 +- goto out_free_dentry;
51480 ++ /*
51481 ++ * This bss-zeroing can fail if the ELF
51482 ++ * file specifies odd protections. So
51483 ++ * we don't check the return value
51484 ++ */
51485 + }
51486 +
51487 + if (elf_interpreter) {
51488 +@@ -1141,8 +1420,10 @@ static int dump_seek(struct file *file,
51489 + unsigned long n = off;
51490 + if (n > PAGE_SIZE)
51491 + n = PAGE_SIZE;
51492 +- if (!dump_write(file, buf, n))
51493 ++ if (!dump_write(file, buf, n)) {
51494 ++ free_page((unsigned long)buf);
51495 + return 0;
51496 ++ }
51497 + off -= n;
51498 + }
51499 + free_page((unsigned long)buf);
51500 +@@ -1154,7 +1435,7 @@ static int dump_seek(struct file *file,
51501 + * Decide what to dump of a segment, part, all or none.
51502 + */
51503 + static unsigned long vma_dump_size(struct vm_area_struct *vma,
51504 +- unsigned long mm_flags)
51505 ++ unsigned long mm_flags, long signr)
51506 + {
51507 + /* The vma can be set up to tell us the answer directly. */
51508 + if (vma->vm_flags & VM_ALWAYSDUMP)
51509 +@@ -1180,7 +1461,7 @@ static unsigned long vma_dump_size(struc
51510 + if (vma->vm_file == NULL)
51511 + return 0;
51512 +
51513 +- if (FILTER(MAPPED_PRIVATE))
51514 ++ if (signr == SIGKILL || FILTER(MAPPED_PRIVATE))
51515 + goto whole;
51516 +
51517 + /*
51518 +@@ -1266,8 +1547,11 @@ static int writenote(struct memelfnote *
51519 + #undef DUMP_WRITE
51520 +
51521 + #define DUMP_WRITE(addr, nr) \
51522 ++ do { \
51523 ++ gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
51524 + if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
51525 +- goto end_coredump;
51526 ++ goto end_coredump; \
51527 ++ } while (0);
51528 + #define DUMP_SEEK(off) \
51529 + if (!dump_seek(file, (off))) \
51530 + goto end_coredump;
51531 +@@ -1973,7 +2257,7 @@ static int elf_core_dump(long signr, str
51532 + phdr.p_offset = offset;
51533 + phdr.p_vaddr = vma->vm_start;
51534 + phdr.p_paddr = 0;
51535 +- phdr.p_filesz = vma_dump_size(vma, mm_flags);
51536 ++ phdr.p_filesz = vma_dump_size(vma, mm_flags, signr);
51537 + phdr.p_memsz = vma->vm_end - vma->vm_start;
51538 + offset += phdr.p_filesz;
51539 + phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
51540 +@@ -2005,7 +2289,7 @@ static int elf_core_dump(long signr, str
51541 + unsigned long addr;
51542 + unsigned long end;
51543 +
51544 +- end = vma->vm_start + vma_dump_size(vma, mm_flags);
51545 ++ end = vma->vm_start + vma_dump_size(vma, mm_flags, signr);
51546 +
51547 + for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
51548 + struct page *page;
51549 +@@ -2025,6 +2309,7 @@ static int elf_core_dump(long signr, str
51550 + flush_cache_page(tmp_vma, addr,
51551 + page_to_pfn(page));
51552 + kaddr = kmap(page);
51553 ++ gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
51554 + if ((size += PAGE_SIZE) > limit ||
51555 + !dump_write(file, kaddr,
51556 + PAGE_SIZE)) {
51557 +diff -urNp linux-2.6.27.7/fs/binfmt_flat.c linux-2.6.27.7/fs/binfmt_flat.c
51558 +--- linux-2.6.27.7/fs/binfmt_flat.c 2008-11-07 12:55:34.000000000 -0500
51559 ++++ linux-2.6.27.7/fs/binfmt_flat.c 2008-11-18 03:38:45.000000000 -0500
51560 +@@ -561,7 +561,9 @@ static int load_flat_file(struct linux_b
51561 + realdatastart = (unsigned long) -ENOMEM;
51562 + printk("Unable to allocate RAM for process data, errno %d\n",
51563 + (int)-realdatastart);
51564 ++ down_write(&current->mm->mmap_sem);
51565 + do_munmap(current->mm, textpos, text_len);
51566 ++ up_write(&current->mm->mmap_sem);
51567 + ret = realdatastart;
51568 + goto err;
51569 + }
51570 +@@ -583,8 +585,10 @@ static int load_flat_file(struct linux_b
51571 + }
51572 + if (result >= (unsigned long)-4096) {
51573 + printk("Unable to read data+bss, errno %d\n", (int)-result);
51574 ++ down_write(&current->mm->mmap_sem);
51575 + do_munmap(current->mm, textpos, text_len);
51576 + do_munmap(current->mm, realdatastart, data_len + extra);
51577 ++ up_write(&current->mm->mmap_sem);
51578 + ret = result;
51579 + goto err;
51580 + }
51581 +@@ -657,8 +661,10 @@ static int load_flat_file(struct linux_b
51582 + }
51583 + if (result >= (unsigned long)-4096) {
51584 + printk("Unable to read code+data+bss, errno %d\n",(int)-result);
51585 ++ down_write(&current->mm->mmap_sem);
51586 + do_munmap(current->mm, textpos, text_len + data_len + extra +
51587 + MAX_SHARED_LIBS * sizeof(unsigned long));
51588 ++ up_write(&current->mm->mmap_sem);
51589 + ret = result;
51590 + goto err;
51591 + }
51592 +diff -urNp linux-2.6.27.7/fs/binfmt_misc.c linux-2.6.27.7/fs/binfmt_misc.c
51593 +--- linux-2.6.27.7/fs/binfmt_misc.c 2008-11-07 12:55:34.000000000 -0500
51594 ++++ linux-2.6.27.7/fs/binfmt_misc.c 2008-11-18 03:38:45.000000000 -0500
51595 +@@ -696,7 +696,7 @@ static int bm_fill_super(struct super_bl
51596 + static struct tree_descr bm_files[] = {
51597 + [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
51598 + [3] = {"register", &bm_register_operations, S_IWUSR},
51599 +- /* last one */ {""}
51600 ++ /* last one */ {"", NULL, 0}
51601 + };
51602 + int err = simple_fill_super(sb, 0x42494e4d, bm_files);
51603 + if (!err)
51604 +diff -urNp linux-2.6.27.7/fs/bio.c linux-2.6.27.7/fs/bio.c
51605 +--- linux-2.6.27.7/fs/bio.c 2008-11-07 12:55:34.000000000 -0500
51606 ++++ linux-2.6.27.7/fs/bio.c 2008-11-18 03:38:45.000000000 -0500
51607 +@@ -507,7 +507,7 @@ static int __bio_copy_iov(struct bio *bi
51608 +
51609 + while (bv_len && iov_idx < iov_count) {
51610 + unsigned int bytes;
51611 +- char *iov_addr;
51612 ++ char __user *iov_addr;
51613 +
51614 + bytes = min_t(unsigned int,
51615 + iov[iov_idx].iov_len - iov_off, bv_len);
51616 +diff -urNp linux-2.6.27.7/fs/buffer.c linux-2.6.27.7/fs/buffer.c
51617 +--- linux-2.6.27.7/fs/buffer.c 2008-11-07 12:55:34.000000000 -0500
51618 ++++ linux-2.6.27.7/fs/buffer.c 2008-11-18 03:38:45.000000000 -0500
51619 +@@ -41,6 +41,7 @@
51620 + #include <linux/bitops.h>
51621 + #include <linux/mpage.h>
51622 + #include <linux/bit_spinlock.h>
51623 ++#include <linux/grsecurity.h>
51624 +
51625 + static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
51626 +
51627 +@@ -2249,6 +2250,7 @@ int generic_cont_expand_simple(struct in
51628 +
51629 + err = -EFBIG;
51630 + limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
51631 ++ gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
51632 + if (limit != RLIM_INFINITY && size > (loff_t)limit) {
51633 + send_sig(SIGXFSZ, current, 0);
51634 + goto out;
51635 +diff -urNp linux-2.6.27.7/fs/cifs/cifs_uniupr.h linux-2.6.27.7/fs/cifs/cifs_uniupr.h
51636 +--- linux-2.6.27.7/fs/cifs/cifs_uniupr.h 2008-11-07 12:55:34.000000000 -0500
51637 ++++ linux-2.6.27.7/fs/cifs/cifs_uniupr.h 2008-11-18 03:38:45.000000000 -0500
51638 +@@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa
51639 + {0x0490, 0x04cc, UniCaseRangeU0490},
51640 + {0x1e00, 0x1ffc, UniCaseRangeU1e00},
51641 + {0xff40, 0xff5a, UniCaseRangeUff40},
51642 +- {0}
51643 ++ {0, 0, NULL}
51644 + };
51645 + #endif
51646 +
51647 +diff -urNp linux-2.6.27.7/fs/cifs/link.c linux-2.6.27.7/fs/cifs/link.c
51648 +--- linux-2.6.27.7/fs/cifs/link.c 2008-11-07 12:55:34.000000000 -0500
51649 ++++ linux-2.6.27.7/fs/cifs/link.c 2008-11-18 03:38:45.000000000 -0500
51650 +@@ -318,7 +318,7 @@ cifs_readlink(struct dentry *direntry, c
51651 +
51652 + void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
51653 + {
51654 +- char *p = nd_get_link(nd);
51655 ++ const char *p = nd_get_link(nd);
51656 + if (!IS_ERR(p))
51657 + kfree(p);
51658 + }
51659 +diff -urNp linux-2.6.27.7/fs/compat.c linux-2.6.27.7/fs/compat.c
51660 +--- linux-2.6.27.7/fs/compat.c 2008-11-07 12:55:34.000000000 -0500
51661 ++++ linux-2.6.27.7/fs/compat.c 2008-11-18 03:38:45.000000000 -0500
51662 +@@ -51,6 +51,7 @@
51663 + #include <linux/poll.h>
51664 + #include <linux/mm.h>
51665 + #include <linux/eventpoll.h>
51666 ++#include <linux/grsecurity.h>
51667 +
51668 + #include <asm/uaccess.h>
51669 + #include <asm/mmu_context.h>
51670 +@@ -1298,14 +1299,12 @@ static int compat_copy_strings(int argc,
51671 + if (!kmapped_page || kpos != (pos & PAGE_MASK)) {
51672 + struct page *page;
51673 +
51674 +-#ifdef CONFIG_STACK_GROWSUP
51675 + ret = expand_stack_downwards(bprm->vma, pos);
51676 + if (ret < 0) {
51677 + /* We've exceed the stack rlimit. */
51678 + ret = -E2BIG;
51679 + goto out;
51680 + }
51681 +-#endif
51682 + ret = get_user_pages(current, bprm->mm, pos,
51683 + 1, 1, 1, &page, NULL);
51684 + if (ret <= 0) {
51685 +@@ -1351,6 +1350,11 @@ int compat_do_execve(char * filename,
51686 + compat_uptr_t __user *envp,
51687 + struct pt_regs * regs)
51688 + {
51689 ++#ifdef CONFIG_GRKERNSEC
51690 ++ struct file *old_exec_file;
51691 ++ struct acl_subject_label *old_acl;
51692 ++ struct rlimit old_rlim[RLIM_NLIMITS];
51693 ++#endif
51694 + struct linux_binprm *bprm;
51695 + struct file *file;
51696 + int retval;
51697 +@@ -1371,6 +1375,14 @@ int compat_do_execve(char * filename,
51698 + bprm->filename = filename;
51699 + bprm->interp = filename;
51700 +
51701 ++ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
51702 ++ retval = -EAGAIN;
51703 ++ if (gr_handle_nproc())
51704 ++ goto out_file;
51705 ++ retval = -EACCES;
51706 ++ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
51707 ++ goto out_file;
51708 ++
51709 + retval = bprm_mm_init(bprm);
51710 + if (retval)
51711 + goto out_file;
51712 +@@ -1404,8 +1416,36 @@ int compat_do_execve(char * filename,
51713 + if (retval < 0)
51714 + goto out;
51715 +
51716 ++ if (!gr_tpe_allow(file)) {
51717 ++ retval = -EACCES;
51718 ++ goto out;
51719 ++ }
51720 ++
51721 ++ if (gr_check_crash_exec(file)) {
51722 ++ retval = -EACCES;
51723 ++ goto out;
51724 ++ }
51725 ++
51726 ++ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
51727 ++
51728 ++ gr_handle_exec_args(bprm, (char __user * __user *)argv);
51729 ++
51730 ++#ifdef CONFIG_GRKERNSEC
51731 ++ old_acl = current->acl;
51732 ++ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
51733 ++ old_exec_file = current->exec_file;
51734 ++ get_file(file);
51735 ++ current->exec_file = file;
51736 ++#endif
51737 ++
51738 ++ gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
51739 ++
51740 + retval = search_binary_handler(bprm, regs);
51741 + if (retval >= 0) {
51742 ++#ifdef CONFIG_GRKERNSEC
51743 ++ if (old_exec_file)
51744 ++ fput(old_exec_file);
51745 ++#endif
51746 + /* execve success */
51747 + security_bprm_free(bprm);
51748 + acct_update_integrals(current);
51749 +@@ -1413,6 +1453,13 @@ int compat_do_execve(char * filename,
51750 + return retval;
51751 + }
51752 +
51753 ++#ifdef CONFIG_GRKERNSEC
51754 ++ current->acl = old_acl;
51755 ++ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
51756 ++ fput(current->exec_file);
51757 ++ current->exec_file = old_exec_file;
51758 ++#endif
51759 ++
51760 + out:
51761 + if (bprm->security)
51762 + security_bprm_free(bprm);
51763 +diff -urNp linux-2.6.27.7/fs/compat_ioctl.c linux-2.6.27.7/fs/compat_ioctl.c
51764 +--- linux-2.6.27.7/fs/compat_ioctl.c 2008-11-07 12:55:34.000000000 -0500
51765 ++++ linux-2.6.27.7/fs/compat_ioctl.c 2008-11-18 03:38:45.000000000 -0500
51766 +@@ -1831,15 +1831,15 @@ struct ioctl_trans {
51767 + };
51768 +
51769 + #define HANDLE_IOCTL(cmd,handler) \
51770 +- { (cmd), (ioctl_trans_handler_t)(handler) },
51771 ++ { (cmd), (ioctl_trans_handler_t)(handler), NULL },
51772 +
51773 + /* pointer to compatible structure or no argument */
51774 + #define COMPATIBLE_IOCTL(cmd) \
51775 +- { (cmd), do_ioctl32_pointer },
51776 ++ { (cmd), do_ioctl32_pointer, NULL },
51777 +
51778 + /* argument is an unsigned long integer, not a pointer */
51779 + #define ULONG_IOCTL(cmd) \
51780 +- { (cmd), (ioctl_trans_handler_t)sys_ioctl },
51781 ++ { (cmd), (ioctl_trans_handler_t)sys_ioctl, NULL },
51782 +
51783 + /* ioctl should not be warned about even if it's not implemented.
51784 + Valid reasons to use this:
51785 +diff -urNp linux-2.6.27.7/fs/debugfs/inode.c linux-2.6.27.7/fs/debugfs/inode.c
51786 +--- linux-2.6.27.7/fs/debugfs/inode.c 2008-11-07 12:55:34.000000000 -0500
51787 ++++ linux-2.6.27.7/fs/debugfs/inode.c 2008-11-18 03:38:45.000000000 -0500
51788 +@@ -121,7 +121,7 @@ static inline int debugfs_positive(struc
51789 +
51790 + static int debug_fill_super(struct super_block *sb, void *data, int silent)
51791 + {
51792 +- static struct tree_descr debug_files[] = {{""}};
51793 ++ static struct tree_descr debug_files[] = {{"", NULL, 0}};
51794 +
51795 + return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
51796 + }
51797 +diff -urNp linux-2.6.27.7/fs/exec.c linux-2.6.27.7/fs/exec.c
51798 +--- linux-2.6.27.7/fs/exec.c 2008-11-07 12:55:34.000000000 -0500
51799 ++++ linux-2.6.27.7/fs/exec.c 2008-11-18 03:38:45.000000000 -0500
51800 +@@ -50,6 +50,13 @@
51801 + #include <linux/cn_proc.h>
51802 + #include <linux/audit.h>
51803 + #include <linux/tracehook.h>
51804 ++#include <linux/random.h>
51805 ++#include <linux/grsecurity.h>
51806 ++
51807 ++#ifdef CONFIG_PAX_REFCOUNT
51808 ++#include <linux/kallsyms.h>
51809 ++#include <linux/kdebug.h>
51810 ++#endif
51811 +
51812 + #include <asm/uaccess.h>
51813 + #include <asm/mmu_context.h>
51814 +@@ -64,6 +71,11 @@
51815 + #include <linux/a.out.h>
51816 + #endif
51817 +
51818 ++#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
51819 ++void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
51820 ++EXPORT_SYMBOL(pax_set_initial_flags_func);
51821 ++#endif
51822 ++
51823 + int core_uses_pid;
51824 + char core_pattern[CORENAME_MAX_SIZE] = "core";
51825 + int suid_dumpable = 0;
51826 +@@ -172,18 +184,10 @@ static struct page *get_arg_page(struct
51827 + int write)
51828 + {
51829 + struct page *page;
51830 +- int ret;
51831 +
51832 +-#ifdef CONFIG_STACK_GROWSUP
51833 +- if (write) {
51834 +- ret = expand_stack_downwards(bprm->vma, pos);
51835 +- if (ret < 0)
51836 +- return NULL;
51837 +- }
51838 +-#endif
51839 +- ret = get_user_pages(current, bprm->mm, pos,
51840 +- 1, write, 1, &page, NULL);
51841 +- if (ret <= 0)
51842 ++ if (0 > expand_stack_downwards(bprm->vma, pos))
51843 ++ return NULL;
51844 ++ if (0 >= get_user_pages(current, bprm->mm, pos, 1, write, 1, &page, NULL))
51845 + return NULL;
51846 +
51847 + if (write) {
51848 +@@ -256,6 +260,11 @@ static int __bprm_mm_init(struct linux_b
51849 + vma->vm_start = vma->vm_end - PAGE_SIZE;
51850 +
51851 + vma->vm_flags = VM_STACK_FLAGS;
51852 ++
51853 ++#ifdef CONFIG_PAX_SEGMEXEC
51854 ++ vma->vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
51855 ++#endif
51856 ++
51857 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
51858 + err = insert_vm_struct(mm, vma);
51859 + if (err) {
51860 +@@ -268,6 +277,11 @@ static int __bprm_mm_init(struct linux_b
51861 +
51862 + bprm->p = vma->vm_end - sizeof(void *);
51863 +
51864 ++#ifdef CONFIG_PAX_RANDUSTACK
51865 ++ if (randomize_va_space)
51866 ++ bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK;
51867 ++#endif
51868 ++
51869 + return 0;
51870 +
51871 + err:
51872 +@@ -391,7 +405,7 @@ static int count(char __user * __user *
51873 + if (!p)
51874 + break;
51875 + argv++;
51876 +- if(++i > max)
51877 ++ if (++i > max)
51878 + return -E2BIG;
51879 + cond_resched();
51880 + }
51881 +@@ -531,6 +545,10 @@ static int shift_arg_pages(struct vm_are
51882 + if (vma != find_vma(mm, new_start))
51883 + return -EFAULT;
51884 +
51885 ++#ifdef CONFIG_PAX_SEGMEXEC
51886 ++ BUG_ON(pax_find_mirror_vma(vma));
51887 ++#endif
51888 ++
51889 + /*
51890 + * cover the whole range: [new_start, old_end)
51891 + */
51892 +@@ -619,6 +637,14 @@ int setup_arg_pages(struct linux_binprm
51893 + bprm->exec -= stack_shift;
51894 +
51895 + down_write(&mm->mmap_sem);
51896 ++
51897 ++ /* Move stack pages down in memory. */
51898 ++ if (stack_shift) {
51899 ++ ret = shift_arg_pages(vma, stack_shift);
51900 ++ if (ret)
51901 ++ goto out_unlock;
51902 ++ }
51903 ++
51904 + vm_flags = VM_STACK_FLAGS;
51905 +
51906 + /*
51907 +@@ -632,21 +658,24 @@ int setup_arg_pages(struct linux_binprm
51908 + vm_flags &= ~VM_EXEC;
51909 + vm_flags |= mm->def_flags;
51910 +
51911 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
51912 ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
51913 ++ vm_flags &= ~VM_EXEC;
51914 ++
51915 ++#ifdef CONFIG_PAX_MPROTECT
51916 ++ if (mm->pax_flags & MF_PAX_MPROTECT)
51917 ++ vm_flags &= ~VM_MAYEXEC;
51918 ++#endif
51919 ++
51920 ++ }
51921 ++#endif
51922 ++
51923 + ret = mprotect_fixup(vma, &prev, vma->vm_start, vma->vm_end,
51924 + vm_flags);
51925 + if (ret)
51926 + goto out_unlock;
51927 + BUG_ON(prev != vma);
51928 +
51929 +- /* Move stack pages down in memory. */
51930 +- if (stack_shift) {
51931 +- ret = shift_arg_pages(vma, stack_shift);
51932 +- if (ret) {
51933 +- up_write(&mm->mmap_sem);
51934 +- return ret;
51935 +- }
51936 +- }
51937 +-
51938 + #ifdef CONFIG_STACK_GROWSUP
51939 + stack_base = vma->vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
51940 + #else
51941 +@@ -658,7 +687,7 @@ int setup_arg_pages(struct linux_binprm
51942 +
51943 + out_unlock:
51944 + up_write(&mm->mmap_sem);
51945 +- return 0;
51946 ++ return ret;
51947 + }
51948 + EXPORT_SYMBOL(setup_arg_pages);
51949 +
51950 +@@ -1278,6 +1307,11 @@ int do_execve(char * filename,
51951 + char __user *__user *envp,
51952 + struct pt_regs * regs)
51953 + {
51954 ++#ifdef CONFIG_GRKERNSEC
51955 ++ struct file *old_exec_file;
51956 ++ struct acl_subject_label *old_acl;
51957 ++ struct rlimit old_rlim[RLIM_NLIMITS];
51958 ++#endif
51959 + struct linux_binprm *bprm;
51960 + struct file *file;
51961 + struct files_struct *displaced;
51962 +@@ -1297,6 +1331,20 @@ int do_execve(char * filename,
51963 + if (IS_ERR(file))
51964 + goto out_kfree;
51965 +
51966 ++ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
51967 ++
51968 ++ if (gr_handle_nproc()) {
51969 ++ allow_write_access(file);
51970 ++ fput(file);
51971 ++ return -EAGAIN;
51972 ++ }
51973 ++
51974 ++ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
51975 ++ allow_write_access(file);
51976 ++ fput(file);
51977 ++ return -EACCES;
51978 ++ }
51979 ++
51980 + sched_exec();
51981 +
51982 + bprm->file = file;
51983 +@@ -1336,9 +1384,39 @@ int do_execve(char * filename,
51984 + if (retval < 0)
51985 + goto out;
51986 +
51987 ++ if (!gr_tpe_allow(file)) {
51988 ++ retval = -EACCES;
51989 ++ goto out;
51990 ++ }
51991 ++
51992 ++ if (gr_check_crash_exec(file)) {
51993 ++ retval = -EACCES;
51994 ++ goto out;
51995 ++ }
51996 ++
51997 ++ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
51998 ++
51999 ++ gr_handle_exec_args(bprm, argv);
52000 ++
52001 ++#ifdef CONFIG_GRKERNSEC
52002 ++ old_acl = current->acl;
52003 ++ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
52004 ++ old_exec_file = current->exec_file;
52005 ++ get_file(file);
52006 ++ current->exec_file = file;
52007 ++#endif
52008 ++
52009 ++ retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
52010 ++ if (retval < 0)
52011 ++ goto out_fail;
52012 ++
52013 + current->flags &= ~PF_KTHREAD;
52014 + retval = search_binary_handler(bprm,regs);
52015 + if (retval >= 0) {
52016 ++#ifdef CONFIG_GRKERNSEC
52017 ++ if (old_exec_file)
52018 ++ fput(old_exec_file);
52019 ++#endif
52020 + /* execve success */
52021 + security_bprm_free(bprm);
52022 + acct_update_integrals(current);
52023 +@@ -1348,6 +1426,14 @@ int do_execve(char * filename,
52024 + return retval;
52025 + }
52026 +
52027 ++out_fail:
52028 ++#ifdef CONFIG_GRKERNSEC
52029 ++ current->acl = old_acl;
52030 ++ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
52031 ++ fput(current->exec_file);
52032 ++ current->exec_file = old_exec_file;
52033 ++#endif
52034 ++
52035 + out:
52036 + if (bprm->security)
52037 + security_bprm_free(bprm);
52038 +@@ -1511,6 +1597,125 @@ out:
52039 + return ispipe;
52040 + }
52041 +
52042 ++int pax_check_flags(unsigned long *flags)
52043 ++{
52044 ++ int retval = 0;
52045 ++
52046 ++#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC)
52047 ++ if (*flags & MF_PAX_SEGMEXEC)
52048 ++ {
52049 ++ *flags &= ~MF_PAX_SEGMEXEC;
52050 ++ retval = -EINVAL;
52051 ++ }
52052 ++#endif
52053 ++
52054 ++ if ((*flags & MF_PAX_PAGEEXEC)
52055 ++
52056 ++#ifdef CONFIG_PAX_PAGEEXEC
52057 ++ && (*flags & MF_PAX_SEGMEXEC)
52058 ++#endif
52059 ++
52060 ++ )
52061 ++ {
52062 ++ *flags &= ~MF_PAX_PAGEEXEC;
52063 ++ retval = -EINVAL;
52064 ++ }
52065 ++
52066 ++ if ((*flags & MF_PAX_MPROTECT)
52067 ++
52068 ++#ifdef CONFIG_PAX_MPROTECT
52069 ++ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
52070 ++#endif
52071 ++
52072 ++ )
52073 ++ {
52074 ++ *flags &= ~MF_PAX_MPROTECT;
52075 ++ retval = -EINVAL;
52076 ++ }
52077 ++
52078 ++ if ((*flags & MF_PAX_EMUTRAMP)
52079 ++
52080 ++#ifdef CONFIG_PAX_EMUTRAMP
52081 ++ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
52082 ++#endif
52083 ++
52084 ++ )
52085 ++ {
52086 ++ *flags &= ~MF_PAX_EMUTRAMP;
52087 ++ retval = -EINVAL;
52088 ++ }
52089 ++
52090 ++ return retval;
52091 ++}
52092 ++
52093 ++EXPORT_SYMBOL(pax_check_flags);
52094 ++
52095 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
52096 ++void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
52097 ++{
52098 ++ struct task_struct *tsk = current;
52099 ++ struct mm_struct *mm = current->mm;
52100 ++ char *buffer_exec = (char *)__get_free_page(GFP_KERNEL);
52101 ++ char *buffer_fault = (char *)__get_free_page(GFP_KERNEL);
52102 ++ char *path_exec = NULL;
52103 ++ char *path_fault = NULL;
52104 ++ unsigned long start = 0UL, end = 0UL, offset = 0UL;
52105 ++
52106 ++ if (buffer_exec && buffer_fault) {
52107 ++ struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL;
52108 ++
52109 ++ down_read(&mm->mmap_sem);
52110 ++ vma = mm->mmap;
52111 ++ while (vma && (!vma_exec || !vma_fault)) {
52112 ++ if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
52113 ++ vma_exec = vma;
52114 ++ if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
52115 ++ vma_fault = vma;
52116 ++ vma = vma->vm_next;
52117 ++ }
52118 ++ if (vma_exec) {
52119 ++ path_exec = d_path(&vma_exec->vm_file->f_path, buffer_exec, PAGE_SIZE);
52120 ++ if (IS_ERR(path_exec))
52121 ++ path_exec = "<path too long>";
52122 ++ }
52123 ++ if (vma_fault) {
52124 ++ start = vma_fault->vm_start;
52125 ++ end = vma_fault->vm_end;
52126 ++ offset = vma_fault->vm_pgoff << PAGE_SHIFT;
52127 ++ if (vma_fault->vm_file) {
52128 ++ path_fault = d_path(&vma_fault->vm_file->f_path, buffer_fault, PAGE_SIZE);
52129 ++ if (IS_ERR(path_fault))
52130 ++ path_fault = "<path too long>";
52131 ++ } else
52132 ++ path_fault = "<anonymous mapping>";
52133 ++ }
52134 ++ up_read(&mm->mmap_sem);
52135 ++ }
52136 ++ if (tsk->signal->curr_ip)
52137 ++ 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);
52138 ++ else
52139 ++ printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
52140 ++ printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
52141 ++ "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
52142 ++ tsk->uid, tsk->euid, pc, sp);
52143 ++ free_page((unsigned long)buffer_exec);
52144 ++ free_page((unsigned long)buffer_fault);
52145 ++ pax_report_insns(pc, sp);
52146 ++ do_coredump(SIGKILL, SIGKILL, regs);
52147 ++}
52148 ++#endif
52149 ++
52150 ++#ifdef CONFIG_PAX_REFCOUNT
52151 ++void pax_report_refcount_overflow(struct pt_regs *regs)
52152 ++{
52153 ++ printk(KERN_ERR "PAX: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n",
52154 ++ current->comm, task_pid_nr(current), current->uid, current->euid);
52155 ++ print_symbol(KERN_ERR "PAX: refcount overflow occured at: %s\n", instruction_pointer(regs));
52156 ++ show_registers(regs);
52157 ++ force_sig_specific(SIGKILL, current);
52158 ++}
52159 ++#endif
52160 ++
52161 + static int zap_process(struct task_struct *start)
52162 + {
52163 + struct task_struct *t;
52164 +@@ -1757,6 +1962,10 @@ int do_coredump(long signr, int exit_cod
52165 + */
52166 + clear_thread_flag(TIF_SIGPENDING);
52167 +
52168 ++ if (signr == SIGKILL || signr == SIGILL)
52169 ++ gr_handle_brute_attach(current);
52170 ++ gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
52171 ++
52172 + /*
52173 + * lock_kernel() because format_corename() is controlled by sysctl, which
52174 + * uses lock_kernel()
52175 +@@ -1777,6 +1986,8 @@ int do_coredump(long signr, int exit_cod
52176 +
52177 + if (ispipe) {
52178 + helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc);
52179 ++ if (!helper_argv)
52180 ++ goto fail_unlock;
52181 + /* Terminate the string before the first option */
52182 + delimit = strchr(corename, ' ');
52183 + if (delimit)
52184 +diff -urNp linux-2.6.27.7/fs/ext2/balloc.c linux-2.6.27.7/fs/ext2/balloc.c
52185 +--- linux-2.6.27.7/fs/ext2/balloc.c 2008-11-07 12:55:34.000000000 -0500
52186 ++++ linux-2.6.27.7/fs/ext2/balloc.c 2008-11-18 03:38:45.000000000 -0500
52187 +@@ -1192,7 +1192,7 @@ static int ext2_has_free_blocks(struct e
52188 +
52189 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
52190 + root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
52191 +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
52192 ++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
52193 + sbi->s_resuid != current->fsuid &&
52194 + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
52195 + return 0;
52196 +diff -urNp linux-2.6.27.7/fs/ext3/balloc.c linux-2.6.27.7/fs/ext3/balloc.c
52197 +--- linux-2.6.27.7/fs/ext3/balloc.c 2008-11-07 12:55:34.000000000 -0500
52198 ++++ linux-2.6.27.7/fs/ext3/balloc.c 2008-11-18 03:38:45.000000000 -0500
52199 +@@ -1421,7 +1421,7 @@ static int ext3_has_free_blocks(struct e
52200 +
52201 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
52202 + root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
52203 +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
52204 ++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
52205 + sbi->s_resuid != current->fsuid &&
52206 + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
52207 + return 0;
52208 +diff -urNp linux-2.6.27.7/fs/ext3/namei.c linux-2.6.27.7/fs/ext3/namei.c
52209 +--- linux-2.6.27.7/fs/ext3/namei.c 2008-11-07 12:55:34.000000000 -0500
52210 ++++ linux-2.6.27.7/fs/ext3/namei.c 2008-11-18 03:38:45.000000000 -0500
52211 +@@ -1173,9 +1173,9 @@ static struct ext3_dir_entry_2 *do_split
52212 + u32 hash2;
52213 + struct dx_map_entry *map;
52214 + char *data1 = (*bh)->b_data, *data2;
52215 +- unsigned split, move, size, i;
52216 ++ unsigned split, move, size;
52217 + struct ext3_dir_entry_2 *de = NULL, *de2;
52218 +- int err = 0;
52219 ++ int i, err = 0;
52220 +
52221 + bh2 = ext3_append (handle, dir, &newblock, &err);
52222 + if (!(bh2)) {
52223 +diff -urNp linux-2.6.27.7/fs/ext3/xattr.c linux-2.6.27.7/fs/ext3/xattr.c
52224 +--- linux-2.6.27.7/fs/ext3/xattr.c 2008-11-07 12:55:34.000000000 -0500
52225 ++++ linux-2.6.27.7/fs/ext3/xattr.c 2008-11-18 03:38:45.000000000 -0500
52226 +@@ -89,8 +89,8 @@
52227 + printk("\n"); \
52228 + } while (0)
52229 + #else
52230 +-# define ea_idebug(f...)
52231 +-# define ea_bdebug(f...)
52232 ++# define ea_idebug(f...) do {} while (0)
52233 ++# define ea_bdebug(f...) do {} while (0)
52234 + #endif
52235 +
52236 + static void ext3_xattr_cache_insert(struct buffer_head *);
52237 +diff -urNp linux-2.6.27.7/fs/ext4/balloc.c linux-2.6.27.7/fs/ext4/balloc.c
52238 +--- linux-2.6.27.7/fs/ext4/balloc.c 2008-11-07 12:55:34.000000000 -0500
52239 ++++ linux-2.6.27.7/fs/ext4/balloc.c 2008-11-18 03:38:45.000000000 -0500
52240 +@@ -1617,7 +1617,7 @@ ext4_fsblk_t ext4_has_free_blocks(struct
52241 +
52242 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
52243 +
52244 +- if (!capable(CAP_SYS_RESOURCE) &&
52245 ++ if (!capable_nolog(CAP_SYS_RESOURCE) &&
52246 + sbi->s_resuid != current->fsuid &&
52247 + (sbi->s_resgid == 0 || !in_group_p(sbi->s_resgid)))
52248 + root_blocks = ext4_r_blocks_count(sbi->s_es);
52249 +diff -urNp linux-2.6.27.7/fs/ext4/namei.c linux-2.6.27.7/fs/ext4/namei.c
52250 +--- linux-2.6.27.7/fs/ext4/namei.c 2008-11-07 12:55:34.000000000 -0500
52251 ++++ linux-2.6.27.7/fs/ext4/namei.c 2008-11-18 03:38:45.000000000 -0500
52252 +@@ -1176,9 +1176,9 @@ static struct ext4_dir_entry_2 *do_split
52253 + u32 hash2;
52254 + struct dx_map_entry *map;
52255 + char *data1 = (*bh)->b_data, *data2;
52256 +- unsigned split, move, size, i;
52257 ++ unsigned split, move, size;
52258 + struct ext4_dir_entry_2 *de = NULL, *de2;
52259 +- int err = 0;
52260 ++ int i, err = 0;
52261 +
52262 + bh2 = ext4_append (handle, dir, &newblock, &err);
52263 + if (!(bh2)) {
52264 +diff -urNp linux-2.6.27.7/fs/fcntl.c linux-2.6.27.7/fs/fcntl.c
52265 +--- linux-2.6.27.7/fs/fcntl.c 2008-11-07 12:55:34.000000000 -0500
52266 ++++ linux-2.6.27.7/fs/fcntl.c 2008-11-18 03:38:45.000000000 -0500
52267 +@@ -19,6 +19,7 @@
52268 + #include <linux/signal.h>
52269 + #include <linux/rcupdate.h>
52270 + #include <linux/pid_namespace.h>
52271 ++#include <linux/grsecurity.h>
52272 +
52273 + #include <asm/poll.h>
52274 + #include <asm/siginfo.h>
52275 +@@ -259,6 +260,7 @@ static long do_fcntl(int fd, unsigned in
52276 + switch (cmd) {
52277 + case F_DUPFD:
52278 + case F_DUPFD_CLOEXEC:
52279 ++ gr_learn_resource(current, RLIMIT_NOFILE, arg, 0);
52280 + if (arg >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
52281 + break;
52282 + err = alloc_fd(arg, cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0);
52283 +@@ -403,7 +405,8 @@ static inline int sigio_perm(struct task
52284 + return (((fown->euid == 0) ||
52285 + (fown->euid == p->suid) || (fown->euid == p->uid) ||
52286 + (fown->uid == p->suid) || (fown->uid == p->uid)) &&
52287 +- !security_file_send_sigiotask(p, fown, sig));
52288 ++ !security_file_send_sigiotask(p, fown, sig) &&
52289 ++ !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
52290 + }
52291 +
52292 + static void send_sigio_to_task(struct task_struct *p,
52293 +diff -urNp linux-2.6.27.7/fs/file.c linux-2.6.27.7/fs/file.c
52294 +--- linux-2.6.27.7/fs/file.c 2008-11-07 12:55:34.000000000 -0500
52295 ++++ linux-2.6.27.7/fs/file.c 2008-11-18 03:38:45.000000000 -0500
52296 +@@ -19,6 +19,7 @@
52297 + #include <linux/spinlock.h>
52298 + #include <linux/rcupdate.h>
52299 + #include <linux/workqueue.h>
52300 ++#include <linux/grsecurity.h>
52301 +
52302 + struct fdtable_defer {
52303 + spinlock_t lock;
52304 +@@ -256,6 +257,8 @@ int expand_files(struct files_struct *fi
52305 + * N.B. For clone tasks sharing a files structure, this test
52306 + * will limit the total number of files that can be opened.
52307 + */
52308 ++
52309 ++ gr_learn_resource(current, RLIMIT_NOFILE, nr, 0);
52310 + if (nr >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
52311 + return -EMFILE;
52312 +
52313 +diff -urNp linux-2.6.27.7/fs/fuse/control.c linux-2.6.27.7/fs/fuse/control.c
52314 +--- linux-2.6.27.7/fs/fuse/control.c 2008-11-07 12:55:34.000000000 -0500
52315 ++++ linux-2.6.27.7/fs/fuse/control.c 2008-11-18 03:38:45.000000000 -0500
52316 +@@ -159,7 +159,7 @@ void fuse_ctl_remove_conn(struct fuse_co
52317 +
52318 + static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
52319 + {
52320 +- struct tree_descr empty_descr = {""};
52321 ++ struct tree_descr empty_descr = {"", NULL, 0};
52322 + struct fuse_conn *fc;
52323 + int err;
52324 +
52325 +diff -urNp linux-2.6.27.7/fs/fuse/dir.c linux-2.6.27.7/fs/fuse/dir.c
52326 +--- linux-2.6.27.7/fs/fuse/dir.c 2008-11-07 12:55:34.000000000 -0500
52327 ++++ linux-2.6.27.7/fs/fuse/dir.c 2008-11-18 03:38:45.000000000 -0500
52328 +@@ -1072,7 +1072,7 @@ static char *read_link(struct dentry *de
52329 + return link;
52330 + }
52331 +
52332 +-static void free_link(char *link)
52333 ++static void free_link(const char *link)
52334 + {
52335 + if (!IS_ERR(link))
52336 + free_page((unsigned long) link);
52337 +diff -urNp linux-2.6.27.7/fs/hfs/inode.c linux-2.6.27.7/fs/hfs/inode.c
52338 +--- linux-2.6.27.7/fs/hfs/inode.c 2008-11-07 12:55:34.000000000 -0500
52339 ++++ linux-2.6.27.7/fs/hfs/inode.c 2008-11-18 03:38:45.000000000 -0500
52340 +@@ -419,7 +419,7 @@ int hfs_write_inode(struct inode *inode,
52341 +
52342 + if (S_ISDIR(main_inode->i_mode)) {
52343 + if (fd.entrylength < sizeof(struct hfs_cat_dir))
52344 +- /* panic? */;
52345 ++ {/* panic? */}
52346 + hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
52347 + sizeof(struct hfs_cat_dir));
52348 + if (rec.type != HFS_CDR_DIR ||
52349 +@@ -440,7 +440,7 @@ int hfs_write_inode(struct inode *inode,
52350 + sizeof(struct hfs_cat_file));
52351 + } else {
52352 + if (fd.entrylength < sizeof(struct hfs_cat_file))
52353 +- /* panic? */;
52354 ++ {/* panic? */}
52355 + hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
52356 + sizeof(struct hfs_cat_file));
52357 + if (rec.type != HFS_CDR_FIL ||
52358 +diff -urNp linux-2.6.27.7/fs/hfsplus/inode.c linux-2.6.27.7/fs/hfsplus/inode.c
52359 +--- linux-2.6.27.7/fs/hfsplus/inode.c 2008-11-07 12:55:34.000000000 -0500
52360 ++++ linux-2.6.27.7/fs/hfsplus/inode.c 2008-11-18 03:38:45.000000000 -0500
52361 +@@ -417,7 +417,7 @@ int hfsplus_cat_read_inode(struct inode
52362 + struct hfsplus_cat_folder *folder = &entry.folder;
52363 +
52364 + if (fd->entrylength < sizeof(struct hfsplus_cat_folder))
52365 +- /* panic? */;
52366 ++ {/* panic? */}
52367 + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
52368 + sizeof(struct hfsplus_cat_folder));
52369 + hfsplus_get_perms(inode, &folder->permissions, 1);
52370 +@@ -434,7 +434,7 @@ int hfsplus_cat_read_inode(struct inode
52371 + struct hfsplus_cat_file *file = &entry.file;
52372 +
52373 + if (fd->entrylength < sizeof(struct hfsplus_cat_file))
52374 +- /* panic? */;
52375 ++ {/* panic? */}
52376 + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
52377 + sizeof(struct hfsplus_cat_file));
52378 +
52379 +@@ -490,7 +490,7 @@ int hfsplus_cat_write_inode(struct inode
52380 + struct hfsplus_cat_folder *folder = &entry.folder;
52381 +
52382 + if (fd.entrylength < sizeof(struct hfsplus_cat_folder))
52383 +- /* panic? */;
52384 ++ {/* panic? */}
52385 + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
52386 + sizeof(struct hfsplus_cat_folder));
52387 + /* simple node checks? */
52388 +@@ -512,7 +512,7 @@ int hfsplus_cat_write_inode(struct inode
52389 + struct hfsplus_cat_file *file = &entry.file;
52390 +
52391 + if (fd.entrylength < sizeof(struct hfsplus_cat_file))
52392 +- /* panic? */;
52393 ++ {/* panic? */}
52394 + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
52395 + sizeof(struct hfsplus_cat_file));
52396 + hfsplus_inode_write_fork(inode, &file->data_fork);
52397 +diff -urNp linux-2.6.27.7/fs/jffs2/debug.h linux-2.6.27.7/fs/jffs2/debug.h
52398 +--- linux-2.6.27.7/fs/jffs2/debug.h 2008-11-07 12:55:34.000000000 -0500
52399 ++++ linux-2.6.27.7/fs/jffs2/debug.h 2008-11-18 03:38:45.000000000 -0500
52400 +@@ -52,13 +52,13 @@
52401 + #if CONFIG_JFFS2_FS_DEBUG > 0
52402 + #define D1(x) x
52403 + #else
52404 +-#define D1(x)
52405 ++#define D1(x) do {} while (0);
52406 + #endif
52407 +
52408 + #if CONFIG_JFFS2_FS_DEBUG > 1
52409 + #define D2(x) x
52410 + #else
52411 +-#define D2(x)
52412 ++#define D2(x) do {} while (0);
52413 + #endif
52414 +
52415 + /* The prefixes of JFFS2 messages */
52416 +@@ -114,73 +114,73 @@
52417 + #ifdef JFFS2_DBG_READINODE_MESSAGES
52418 + #define dbg_readinode(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
52419 + #else
52420 +-#define dbg_readinode(fmt, ...)
52421 ++#define dbg_readinode(fmt, ...) do {} while (0)
52422 + #endif
52423 + #ifdef JFFS2_DBG_READINODE2_MESSAGES
52424 + #define dbg_readinode2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
52425 + #else
52426 +-#define dbg_readinode2(fmt, ...)
52427 ++#define dbg_readinode2(fmt, ...) do {} while (0)
52428 + #endif
52429 +
52430 + /* Fragtree build debugging messages */
52431 + #ifdef JFFS2_DBG_FRAGTREE_MESSAGES
52432 + #define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
52433 + #else
52434 +-#define dbg_fragtree(fmt, ...)
52435 ++#define dbg_fragtree(fmt, ...) do {} while (0)
52436 + #endif
52437 + #ifdef JFFS2_DBG_FRAGTREE2_MESSAGES
52438 + #define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
52439 + #else
52440 +-#define dbg_fragtree2(fmt, ...)
52441 ++#define dbg_fragtree2(fmt, ...) do {} while (0)
52442 + #endif
52443 +
52444 + /* Directory entry list manilulation debugging messages */
52445 + #ifdef JFFS2_DBG_DENTLIST_MESSAGES
52446 + #define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
52447 + #else
52448 +-#define dbg_dentlist(fmt, ...)
52449 ++#define dbg_dentlist(fmt, ...) do {} while (0)
52450 + #endif
52451 +
52452 + /* Print the messages about manipulating node_refs */
52453 + #ifdef JFFS2_DBG_NODEREF_MESSAGES
52454 + #define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
52455 + #else
52456 +-#define dbg_noderef(fmt, ...)
52457 ++#define dbg_noderef(fmt, ...) do {} while (0)
52458 + #endif
52459 +
52460 + /* Manipulations with the list of inodes (JFFS2 inocache) */
52461 + #ifdef JFFS2_DBG_INOCACHE_MESSAGES
52462 + #define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
52463 + #else
52464 +-#define dbg_inocache(fmt, ...)
52465 ++#define dbg_inocache(fmt, ...) do {} while (0)
52466 + #endif
52467 +
52468 + /* Summary debugging messages */
52469 + #ifdef JFFS2_DBG_SUMMARY_MESSAGES
52470 + #define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
52471 + #else
52472 +-#define dbg_summary(fmt, ...)
52473 ++#define dbg_summary(fmt, ...) do {} while (0)
52474 + #endif
52475 +
52476 + /* File system build messages */
52477 + #ifdef JFFS2_DBG_FSBUILD_MESSAGES
52478 + #define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
52479 + #else
52480 +-#define dbg_fsbuild(fmt, ...)
52481 ++#define dbg_fsbuild(fmt, ...) do {} while (0)
52482 + #endif
52483 +
52484 + /* Watch the object allocations */
52485 + #ifdef JFFS2_DBG_MEMALLOC_MESSAGES
52486 + #define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
52487 + #else
52488 +-#define dbg_memalloc(fmt, ...)
52489 ++#define dbg_memalloc(fmt, ...) do {} while (0)
52490 + #endif
52491 +
52492 + /* Watch the XATTR subsystem */
52493 + #ifdef JFFS2_DBG_XATTR_MESSAGES
52494 + #define dbg_xattr(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
52495 + #else
52496 +-#define dbg_xattr(fmt, ...)
52497 ++#define dbg_xattr(fmt, ...) do {} while (0)
52498 + #endif
52499 +
52500 + /* "Sanity" checks */
52501 +diff -urNp linux-2.6.27.7/fs/jffs2/erase.c linux-2.6.27.7/fs/jffs2/erase.c
52502 +--- linux-2.6.27.7/fs/jffs2/erase.c 2008-11-07 12:55:34.000000000 -0500
52503 ++++ linux-2.6.27.7/fs/jffs2/erase.c 2008-11-18 03:38:45.000000000 -0500
52504 +@@ -431,7 +431,8 @@ static void jffs2_mark_erased_block(stru
52505 + struct jffs2_unknown_node marker = {
52506 + .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
52507 + .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
52508 +- .totlen = cpu_to_je32(c->cleanmarker_size)
52509 ++ .totlen = cpu_to_je32(c->cleanmarker_size),
52510 ++ .hdr_crc = cpu_to_je32(0)
52511 + };
52512 +
52513 + jffs2_prealloc_raw_node_refs(c, jeb, 1);
52514 +diff -urNp linux-2.6.27.7/fs/jffs2/summary.h linux-2.6.27.7/fs/jffs2/summary.h
52515 +--- linux-2.6.27.7/fs/jffs2/summary.h 2008-11-07 12:55:34.000000000 -0500
52516 ++++ linux-2.6.27.7/fs/jffs2/summary.h 2008-11-18 03:38:45.000000000 -0500
52517 +@@ -194,18 +194,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_
52518 +
52519 + #define jffs2_sum_active() (0)
52520 + #define jffs2_sum_init(a) (0)
52521 +-#define jffs2_sum_exit(a)
52522 +-#define jffs2_sum_disable_collecting(a)
52523 ++#define jffs2_sum_exit(a) do {} while (0)
52524 ++#define jffs2_sum_disable_collecting(a) do {} while (0)
52525 + #define jffs2_sum_is_disabled(a) (0)
52526 +-#define jffs2_sum_reset_collected(a)
52527 ++#define jffs2_sum_reset_collected(a) do {} while (0)
52528 + #define jffs2_sum_add_kvec(a,b,c,d) (0)
52529 +-#define jffs2_sum_move_collected(a,b)
52530 ++#define jffs2_sum_move_collected(a,b) do {} while (0)
52531 + #define jffs2_sum_write_sumnode(a) (0)
52532 +-#define jffs2_sum_add_padding_mem(a,b)
52533 +-#define jffs2_sum_add_inode_mem(a,b,c)
52534 +-#define jffs2_sum_add_dirent_mem(a,b,c)
52535 +-#define jffs2_sum_add_xattr_mem(a,b,c)
52536 +-#define jffs2_sum_add_xref_mem(a,b,c)
52537 ++#define jffs2_sum_add_padding_mem(a,b) do {} while (0)
52538 ++#define jffs2_sum_add_inode_mem(a,b,c) do {} while (0)
52539 ++#define jffs2_sum_add_dirent_mem(a,b,c) do {} while (0)
52540 ++#define jffs2_sum_add_xattr_mem(a,b,c) do {} while (0)
52541 ++#define jffs2_sum_add_xref_mem(a,b,c) do {} while (0)
52542 + #define jffs2_sum_scan_sumnode(a,b,c,d,e) (0)
52543 +
52544 + #endif /* CONFIG_JFFS2_SUMMARY */
52545 +diff -urNp linux-2.6.27.7/fs/jffs2/wbuf.c linux-2.6.27.7/fs/jffs2/wbuf.c
52546 +--- linux-2.6.27.7/fs/jffs2/wbuf.c 2008-11-07 12:55:34.000000000 -0500
52547 ++++ linux-2.6.27.7/fs/jffs2/wbuf.c 2008-11-18 03:38:45.000000000 -0500
52548 +@@ -1015,7 +1015,8 @@ static const struct jffs2_unknown_node o
52549 + {
52550 + .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK),
52551 + .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
52552 +- .totlen = constant_cpu_to_je32(8)
52553 ++ .totlen = constant_cpu_to_je32(8),
52554 ++ .hdr_crc = constant_cpu_to_je32(0)
52555 + };
52556 +
52557 + /*
52558 +diff -urNp linux-2.6.27.7/fs/locks.c linux-2.6.27.7/fs/locks.c
52559 +--- linux-2.6.27.7/fs/locks.c 2008-11-07 12:55:34.000000000 -0500
52560 ++++ linux-2.6.27.7/fs/locks.c 2008-11-18 03:38:45.000000000 -0500
52561 +@@ -2005,16 +2005,16 @@ void locks_remove_flock(struct file *fil
52562 + return;
52563 +
52564 + if (filp->f_op && filp->f_op->flock) {
52565 +- struct file_lock fl = {
52566 ++ struct file_lock flock = {
52567 + .fl_pid = current->tgid,
52568 + .fl_file = filp,
52569 + .fl_flags = FL_FLOCK,
52570 + .fl_type = F_UNLCK,
52571 + .fl_end = OFFSET_MAX,
52572 + };
52573 +- filp->f_op->flock(filp, F_SETLKW, &fl);
52574 +- if (fl.fl_ops && fl.fl_ops->fl_release_private)
52575 +- fl.fl_ops->fl_release_private(&fl);
52576 ++ filp->f_op->flock(filp, F_SETLKW, &flock);
52577 ++ if (flock.fl_ops && flock.fl_ops->fl_release_private)
52578 ++ flock.fl_ops->fl_release_private(&flock);
52579 + }
52580 +
52581 + lock_kernel();
52582 +diff -urNp linux-2.6.27.7/fs/namei.c linux-2.6.27.7/fs/namei.c
52583 +--- linux-2.6.27.7/fs/namei.c 2008-11-07 12:55:34.000000000 -0500
52584 ++++ linux-2.6.27.7/fs/namei.c 2008-11-18 04:47:57.000000000 -0500
52585 +@@ -31,6 +31,8 @@
52586 + #include <linux/file.h>
52587 + #include <linux/fcntl.h>
52588 + #include <linux/device_cgroup.h>
52589 ++#include <linux/grsecurity.h>
52590 ++
52591 + #include <asm/uaccess.h>
52592 +
52593 + #define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
52594 +@@ -646,7 +648,7 @@ static __always_inline int __do_follow_l
52595 + cookie = dentry->d_inode->i_op->follow_link(dentry, nd);
52596 + error = PTR_ERR(cookie);
52597 + if (!IS_ERR(cookie)) {
52598 +- char *s = nd_get_link(nd);
52599 ++ const char *s = nd_get_link(nd);
52600 + error = 0;
52601 + if (s)
52602 + error = __vfs_follow_link(nd, s);
52603 +@@ -677,6 +679,13 @@ static inline int do_follow_link(struct
52604 + err = security_inode_follow_link(path->dentry, nd);
52605 + if (err)
52606 + goto loop;
52607 ++
52608 ++ if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
52609 ++ path->dentry->d_inode, path->dentry, nd->path.mnt)) {
52610 ++ err = -EACCES;
52611 ++ goto loop;
52612 ++ }
52613 ++
52614 + current->link_count++;
52615 + current->total_link_count++;
52616 + nd->depth++;
52617 +@@ -1025,11 +1034,18 @@ return_reval:
52618 + break;
52619 + }
52620 + return_base:
52621 ++ if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt)) {
52622 ++ path_put(&nd->path);
52623 ++ return -ENOENT;
52624 ++ }
52625 + return 0;
52626 + out_dput:
52627 + path_put_conditional(&next, nd);
52628 + break;
52629 + }
52630 ++ if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt))
52631 ++ err = -ENOENT;
52632 ++
52633 + path_put(&nd->path);
52634 + return_err:
52635 + return err;
52636 +@@ -1613,9 +1629,17 @@ static int __open_namei_create(struct na
52637 + int error;
52638 + struct dentry *dir = nd->path.dentry;
52639 +
52640 ++ if (!gr_acl_handle_creat(path->dentry, nd->path.dentry, nd->path.mnt, flag, mode)) {
52641 ++ error = -EACCES;
52642 ++ goto out_unlock_dput;
52643 ++ }
52644 ++
52645 + if (!IS_POSIXACL(dir->d_inode))
52646 + mode &= ~current->fs->umask;
52647 + error = vfs_create(dir->d_inode, path->dentry, mode, nd);
52648 ++ if (!error)
52649 ++ gr_handle_create(path->dentry, nd->path.mnt);
52650 ++out_unlock_dput:
52651 + mutex_unlock(&dir->d_inode->i_mutex);
52652 + dput(nd->path.dentry);
52653 + nd->path.dentry = path->dentry;
52654 +@@ -1696,6 +1720,17 @@ struct file *do_filp_open(int dfd, const
52655 + &nd, flag);
52656 + if (error)
52657 + return ERR_PTR(error);
52658 ++
52659 ++ if (gr_handle_rawio(nd.path.dentry->d_inode)) {
52660 ++ error = -EPERM;
52661 ++ goto exit;
52662 ++ }
52663 ++
52664 ++ if (!gr_acl_handle_open(nd.path.dentry, nd.path.mnt, flag)) {
52665 ++ error = -EACCES;
52666 ++ goto exit;
52667 ++ }
52668 ++
52669 + goto ok;
52670 + }
52671 +
52672 +@@ -1759,6 +1794,20 @@ do_last:
52673 + /*
52674 + * It already exists.
52675 + */
52676 ++
52677 ++ if (gr_handle_rawio(path.dentry->d_inode)) {
52678 ++ error = -EPERM;
52679 ++ goto exit_mutex_unlock;
52680 ++ }
52681 ++ if (!gr_acl_handle_open(path.dentry, nd.path.mnt, flag)) {
52682 ++ error = -EACCES;
52683 ++ goto exit_mutex_unlock;
52684 ++ }
52685 ++ if (gr_handle_fifo(path.dentry, nd.path.mnt, dir, flag, acc_mode)) {
52686 ++ error = -EACCES;
52687 ++ goto exit_mutex_unlock;
52688 ++ }
52689 ++
52690 + mutex_unlock(&dir->d_inode->i_mutex);
52691 + audit_inode(pathname, path.dentry);
52692 +
52693 +@@ -1843,6 +1892,13 @@ do_link:
52694 + error = security_inode_follow_link(path.dentry, &nd);
52695 + if (error)
52696 + goto exit_dput;
52697 ++
52698 ++ if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
52699 ++ path.dentry, nd.path.mnt)) {
52700 ++ error = -EACCES;
52701 ++ goto exit_dput;
52702 ++ }
52703 ++
52704 + error = __do_follow_link(&path, &nd);
52705 + if (error) {
52706 + /* Does someone understand code flow here? Or it is only
52707 +@@ -2015,9 +2071,21 @@ asmlinkage long sys_mknodat(int dfd, con
52708 + error = may_mknod(mode);
52709 + if (error)
52710 + goto out_dput;
52711 ++
52712 ++ if (gr_handle_chroot_mknod(dentry, nd.path.mnt, mode)) {
52713 ++ error = -EPERM;
52714 ++ goto out_dput;
52715 ++ }
52716 ++
52717 ++ if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
52718 ++ error = -EACCES;
52719 ++ goto out_dput;
52720 ++ }
52721 ++
52722 + error = mnt_want_write(nd.path.mnt);
52723 + if (error)
52724 + goto out_dput;
52725 ++
52726 + switch (mode & S_IFMT) {
52727 + case 0: case S_IFREG:
52728 + error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd);
52729 +@@ -2031,6 +2099,9 @@ asmlinkage long sys_mknodat(int dfd, con
52730 + break;
52731 + }
52732 + mnt_drop_write(nd.path.mnt);
52733 ++
52734 ++ if (!error)
52735 ++ gr_handle_create(dentry, nd.path.mnt);
52736 + out_dput:
52737 + dput(dentry);
52738 + out_unlock:
52739 +@@ -2084,6 +2155,11 @@ asmlinkage long sys_mkdirat(int dfd, con
52740 + if (IS_ERR(dentry))
52741 + goto out_unlock;
52742 +
52743 ++ if (!gr_acl_handle_mkdir(dentry, nd.path.dentry, nd.path.mnt)) {
52744 ++ error = -EACCES;
52745 ++ goto out_dput;
52746 ++ }
52747 ++
52748 + if (!IS_POSIXACL(nd.path.dentry->d_inode))
52749 + mode &= ~current->fs->umask;
52750 + error = mnt_want_write(nd.path.mnt);
52751 +@@ -2091,6 +2167,10 @@ asmlinkage long sys_mkdirat(int dfd, con
52752 + goto out_dput;
52753 + error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
52754 + mnt_drop_write(nd.path.mnt);
52755 ++
52756 ++ if (!error)
52757 ++ gr_handle_create(dentry, nd.path.mnt);
52758 ++
52759 + out_dput:
52760 + dput(dentry);
52761 + out_unlock:
52762 +@@ -2172,6 +2252,8 @@ static long do_rmdir(int dfd, const char
52763 + char * name;
52764 + struct dentry *dentry;
52765 + struct nameidata nd;
52766 ++ ino_t saved_ino = 0;
52767 ++ dev_t saved_dev = 0;
52768 +
52769 + error = user_path_parent(dfd, pathname, &nd, &name);
52770 + if (error)
52771 +@@ -2193,11 +2275,26 @@ static long do_rmdir(int dfd, const char
52772 + error = PTR_ERR(dentry);
52773 + if (IS_ERR(dentry))
52774 + goto exit2;
52775 ++
52776 ++ if (dentry->d_inode != NULL) {
52777 ++ if (dentry->d_inode->i_nlink <= 1) {
52778 ++ saved_ino = dentry->d_inode->i_ino;
52779 ++ saved_dev = dentry->d_inode->i_sb->s_dev;
52780 ++ }
52781 ++
52782 ++ if (!gr_acl_handle_rmdir(dentry, nd.path.mnt)) {
52783 ++ error = -EACCES;
52784 ++ goto exit3;
52785 ++ }
52786 ++ }
52787 ++
52788 + error = mnt_want_write(nd.path.mnt);
52789 + if (error)
52790 + goto exit3;
52791 + error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
52792 + mnt_drop_write(nd.path.mnt);
52793 ++ if (!error && (saved_dev || saved_ino))
52794 ++ gr_handle_delete(saved_ino, saved_dev);
52795 + exit3:
52796 + dput(dentry);
52797 + exit2:
52798 +@@ -2257,6 +2354,8 @@ static long do_unlinkat(int dfd, const c
52799 + struct dentry *dentry;
52800 + struct nameidata nd;
52801 + struct inode *inode = NULL;
52802 ++ ino_t saved_ino = 0;
52803 ++ dev_t saved_dev = 0;
52804 +
52805 + error = user_path_parent(dfd, pathname, &nd, &name);
52806 + if (error)
52807 +@@ -2273,12 +2372,25 @@ static long do_unlinkat(int dfd, const c
52808 + if (nd.last.name[nd.last.len])
52809 + goto slashes;
52810 + inode = dentry->d_inode;
52811 +- if (inode)
52812 ++ if (inode) {
52813 ++ if (inode->i_nlink <= 1) {
52814 ++ saved_ino = inode->i_ino;
52815 ++ saved_dev = inode->i_sb->s_dev;
52816 ++ }
52817 ++
52818 + atomic_inc(&inode->i_count);
52819 ++
52820 ++ if (!gr_acl_handle_unlink(dentry, nd.path.mnt)) {
52821 ++ error = -EACCES;
52822 ++ goto exit2;
52823 ++ }
52824 ++ }
52825 + error = mnt_want_write(nd.path.mnt);
52826 + if (error)
52827 + goto exit2;
52828 + error = vfs_unlink(nd.path.dentry->d_inode, dentry);
52829 ++ if (!error && (saved_ino || saved_dev))
52830 ++ gr_handle_delete(saved_ino, saved_dev);
52831 + mnt_drop_write(nd.path.mnt);
52832 + exit2:
52833 + dput(dentry);
52834 +@@ -2356,10 +2468,17 @@ asmlinkage long sys_symlinkat(const char
52835 + if (IS_ERR(dentry))
52836 + goto out_unlock;
52837 +
52838 ++ if (!gr_acl_handle_symlink(dentry, nd.path.dentry, nd.path.mnt, from)) {
52839 ++ error = -EACCES;
52840 ++ goto out_dput;
52841 ++ }
52842 ++
52843 + error = mnt_want_write(nd.path.mnt);
52844 + if (error)
52845 + goto out_dput;
52846 + error = vfs_symlink(nd.path.dentry->d_inode, dentry, from);
52847 ++ if (!error)
52848 ++ gr_handle_create(dentry, nd.path.mnt);
52849 + mnt_drop_write(nd.path.mnt);
52850 + out_dput:
52851 + dput(dentry);
52852 +@@ -2453,10 +2572,26 @@ asmlinkage long sys_linkat(int olddfd, c
52853 + error = PTR_ERR(new_dentry);
52854 + if (IS_ERR(new_dentry))
52855 + goto out_unlock;
52856 ++
52857 ++ if (gr_handle_hardlink(old_path.dentry, old_path.mnt,
52858 ++ old_path.dentry->d_inode,
52859 ++ old_path.dentry->d_inode->i_mode, to)) {
52860 ++ error = -EACCES;
52861 ++ goto out_dput;
52862 ++ }
52863 ++
52864 ++ if (!gr_acl_handle_link(new_dentry, nd.path.dentry, nd.path.mnt,
52865 ++ old_path.dentry, old_path.mnt, to)) {
52866 ++ error = -EACCES;
52867 ++ goto out_dput;
52868 ++ }
52869 ++
52870 + error = mnt_want_write(nd.path.mnt);
52871 + if (error)
52872 + goto out_dput;
52873 + error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry);
52874 ++ if (!error)
52875 ++ gr_handle_create(new_dentry, nd.path.mnt);
52876 + mnt_drop_write(nd.path.mnt);
52877 + out_dput:
52878 + dput(new_dentry);
52879 +@@ -2612,8 +2747,10 @@ int vfs_rename(struct inode *old_dir, st
52880 + error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
52881 + else
52882 + error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
52883 ++
52884 + if (!error) {
52885 + const char *new_name = old_dentry->d_name.name;
52886 ++
52887 + fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir,
52888 + new_dentry->d_inode, old_dentry);
52889 + }
52890 +@@ -2685,11 +2822,21 @@ asmlinkage long sys_renameat(int olddfd,
52891 + if (new_dentry == trap)
52892 + goto exit5;
52893 +
52894 ++ error = gr_acl_handle_rename(new_dentry, new_dir, newnd.path.mnt,
52895 ++ old_dentry, old_dir->d_inode, oldnd.path.mnt,
52896 ++ to);
52897 ++ if (error)
52898 ++ goto exit5;
52899 ++
52900 + error = mnt_want_write(oldnd.path.mnt);
52901 + if (error)
52902 + goto exit5;
52903 + error = vfs_rename(old_dir->d_inode, old_dentry,
52904 + new_dir->d_inode, new_dentry);
52905 ++ if (!error)
52906 ++ gr_handle_rename(old_dir->d_inode, new_dir->d_inode, old_dentry,
52907 ++ new_dentry, oldnd.path.mnt, new_dentry->d_inode ? 1 : 0);
52908 ++
52909 + mnt_drop_write(oldnd.path.mnt);
52910 + exit5:
52911 + dput(new_dentry);
52912 +diff -urNp linux-2.6.27.7/fs/namespace.c linux-2.6.27.7/fs/namespace.c
52913 +--- linux-2.6.27.7/fs/namespace.c 2008-11-18 11:38:40.000000000 -0500
52914 ++++ linux-2.6.27.7/fs/namespace.c 2008-11-18 11:40:53.000000000 -0500
52915 +@@ -27,6 +27,7 @@
52916 + #include <linux/ramfs.h>
52917 + #include <linux/log2.h>
52918 + #include <linux/idr.h>
52919 ++#include <linux/grsecurity.h>
52920 + #include <asm/uaccess.h>
52921 + #include <asm/unistd.h>
52922 + #include "pnode.h"
52923 +@@ -1094,6 +1095,8 @@ static int do_umount(struct vfsmount *mn
52924 + lock_kernel();
52925 + retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
52926 + unlock_kernel();
52927 ++
52928 ++ gr_log_remount(mnt->mnt_devname, retval);
52929 + }
52930 + up_write(&sb->s_umount);
52931 + return retval;
52932 +@@ -1117,6 +1120,9 @@ static int do_umount(struct vfsmount *mn
52933 + security_sb_umount_busy(mnt);
52934 + up_write(&namespace_sem);
52935 + release_mounts(&umount_list);
52936 ++
52937 ++ gr_log_unmount(mnt->mnt_devname, retval);
52938 ++
52939 + return retval;
52940 + }
52941 +
52942 +@@ -1954,6 +1960,11 @@ long do_mount(char *dev_name, char *dir_
52943 + if (retval)
52944 + goto dput_out;
52945 +
52946 ++ if (gr_handle_chroot_mount(nd.path.dentry, nd.path.mnt, dev_name)) {
52947 ++ retval = -EPERM;
52948 ++ goto dput_out;
52949 ++ }
52950 ++
52951 + if (flags & MS_REMOUNT)
52952 + retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
52953 + data_page);
52954 +@@ -1968,6 +1979,9 @@ long do_mount(char *dev_name, char *dir_
52955 + dev_name, data_page);
52956 + dput_out:
52957 + path_put(&nd.path);
52958 ++
52959 ++ gr_log_mount(dev_name, dir_name, retval);
52960 ++
52961 + return retval;
52962 + }
52963 +
52964 +@@ -2080,6 +2094,9 @@ asmlinkage long sys_mount(char __user *
52965 + if (retval < 0)
52966 + goto out3;
52967 +
52968 ++ if (gr_handle_chroot_pivot())
52969 ++ return -EPERM;
52970 ++
52971 + lock_kernel();
52972 + retval = do_mount((char *)dev_page, dir_page, (char *)type_page,
52973 + flags, (void *)data_page);
52974 +diff -urNp linux-2.6.27.7/fs/nfs/nfs4proc.c linux-2.6.27.7/fs/nfs/nfs4proc.c
52975 +--- linux-2.6.27.7/fs/nfs/nfs4proc.c 2008-11-07 12:55:34.000000000 -0500
52976 ++++ linux-2.6.27.7/fs/nfs/nfs4proc.c 2008-11-18 03:38:45.000000000 -0500
52977 +@@ -653,7 +653,7 @@ static int _nfs4_do_open_reclaim(struct
52978 + static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
52979 + {
52980 + struct nfs_server *server = NFS_SERVER(state->inode);
52981 +- struct nfs4_exception exception = { };
52982 ++ struct nfs4_exception exception = {0, 0};
52983 + int err;
52984 + do {
52985 + err = _nfs4_do_open_reclaim(ctx, state);
52986 +@@ -695,7 +695,7 @@ static int _nfs4_open_delegation_recall(
52987 +
52988 + int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
52989 + {
52990 +- struct nfs4_exception exception = { };
52991 ++ struct nfs4_exception exception = {0, 0};
52992 + struct nfs_server *server = NFS_SERVER(state->inode);
52993 + int err;
52994 + do {
52995 +@@ -988,7 +988,7 @@ static int _nfs4_open_expired(struct nfs
52996 + static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
52997 + {
52998 + struct nfs_server *server = NFS_SERVER(state->inode);
52999 +- struct nfs4_exception exception = { };
53000 ++ struct nfs4_exception exception = {0, 0};
53001 + int err;
53002 +
53003 + do {
53004 +@@ -1090,7 +1090,7 @@ out_err:
53005 +
53006 + static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred)
53007 + {
53008 +- struct nfs4_exception exception = { };
53009 ++ struct nfs4_exception exception = {0, 0};
53010 + struct nfs4_state *res;
53011 + int status;
53012 +
53013 +@@ -1181,7 +1181,7 @@ static int nfs4_do_setattr(struct inode
53014 + struct nfs4_state *state)
53015 + {
53016 + struct nfs_server *server = NFS_SERVER(inode);
53017 +- struct nfs4_exception exception = { };
53018 ++ struct nfs4_exception exception = {0, 0};
53019 + int err;
53020 + do {
53021 + err = nfs4_handle_exception(server,
53022 +@@ -1494,7 +1494,7 @@ static int _nfs4_server_capabilities(str
53023 +
53024 + int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
53025 + {
53026 +- struct nfs4_exception exception = { };
53027 ++ struct nfs4_exception exception = {0, 0};
53028 + int err;
53029 + do {
53030 + err = nfs4_handle_exception(server,
53031 +@@ -1527,7 +1527,7 @@ static int _nfs4_lookup_root(struct nfs_
53032 + static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
53033 + struct nfs_fsinfo *info)
53034 + {
53035 +- struct nfs4_exception exception = { };
53036 ++ struct nfs4_exception exception = {0, 0};
53037 + int err;
53038 + do {
53039 + err = nfs4_handle_exception(server,
53040 +@@ -1616,7 +1616,7 @@ static int _nfs4_proc_getattr(struct nfs
53041 +
53042 + static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
53043 + {
53044 +- struct nfs4_exception exception = { };
53045 ++ struct nfs4_exception exception = {0, 0};
53046 + int err;
53047 + do {
53048 + err = nfs4_handle_exception(server,
53049 +@@ -1702,7 +1702,7 @@ static int nfs4_proc_lookupfh(struct nfs
53050 + struct qstr *name, struct nfs_fh *fhandle,
53051 + struct nfs_fattr *fattr)
53052 + {
53053 +- struct nfs4_exception exception = { };
53054 ++ struct nfs4_exception exception = {0, 0};
53055 + int err;
53056 + do {
53057 + err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr);
53058 +@@ -1731,7 +1731,7 @@ static int _nfs4_proc_lookup(struct inod
53059 +
53060 + static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
53061 + {
53062 +- struct nfs4_exception exception = { };
53063 ++ struct nfs4_exception exception = {0, 0};
53064 + int err;
53065 + do {
53066 + err = nfs4_handle_exception(NFS_SERVER(dir),
53067 +@@ -1795,7 +1795,7 @@ static int _nfs4_proc_access(struct inod
53068 +
53069 + static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
53070 + {
53071 +- struct nfs4_exception exception = { };
53072 ++ struct nfs4_exception exception = {0, 0};
53073 + int err;
53074 + do {
53075 + err = nfs4_handle_exception(NFS_SERVER(inode),
53076 +@@ -1850,7 +1850,7 @@ static int _nfs4_proc_readlink(struct in
53077 + static int nfs4_proc_readlink(struct inode *inode, struct page *page,
53078 + unsigned int pgbase, unsigned int pglen)
53079 + {
53080 +- struct nfs4_exception exception = { };
53081 ++ struct nfs4_exception exception = {0, 0};
53082 + int err;
53083 + do {
53084 + err = nfs4_handle_exception(NFS_SERVER(inode),
53085 +@@ -1947,7 +1947,7 @@ static int _nfs4_proc_remove(struct inod
53086 +
53087 + static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
53088 + {
53089 +- struct nfs4_exception exception = { };
53090 ++ struct nfs4_exception exception = {0, 0};
53091 + int err;
53092 + do {
53093 + err = nfs4_handle_exception(NFS_SERVER(dir),
53094 +@@ -2019,7 +2019,7 @@ static int _nfs4_proc_rename(struct inod
53095 + static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
53096 + struct inode *new_dir, struct qstr *new_name)
53097 + {
53098 +- struct nfs4_exception exception = { };
53099 ++ struct nfs4_exception exception = {0, 0};
53100 + int err;
53101 + do {
53102 + err = nfs4_handle_exception(NFS_SERVER(old_dir),
53103 +@@ -2066,7 +2066,7 @@ static int _nfs4_proc_link(struct inode
53104 +
53105 + static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
53106 + {
53107 +- struct nfs4_exception exception = { };
53108 ++ struct nfs4_exception exception = {0, 0};
53109 + int err;
53110 + do {
53111 + err = nfs4_handle_exception(NFS_SERVER(inode),
53112 +@@ -2157,7 +2157,7 @@ out:
53113 + static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
53114 + struct page *page, unsigned int len, struct iattr *sattr)
53115 + {
53116 +- struct nfs4_exception exception = { };
53117 ++ struct nfs4_exception exception = {0, 0};
53118 + int err;
53119 + do {
53120 + err = nfs4_handle_exception(NFS_SERVER(dir),
53121 +@@ -2188,7 +2188,7 @@ out:
53122 + static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
53123 + struct iattr *sattr)
53124 + {
53125 +- struct nfs4_exception exception = { };
53126 ++ struct nfs4_exception exception = {0, 0};
53127 + int err;
53128 + do {
53129 + err = nfs4_handle_exception(NFS_SERVER(dir),
53130 +@@ -2237,7 +2237,7 @@ static int _nfs4_proc_readdir(struct den
53131 + static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
53132 + u64 cookie, struct page *page, unsigned int count, int plus)
53133 + {
53134 +- struct nfs4_exception exception = { };
53135 ++ struct nfs4_exception exception = {0, 0};
53136 + int err;
53137 + do {
53138 + err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode),
53139 +@@ -2285,7 +2285,7 @@ out:
53140 + static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
53141 + struct iattr *sattr, dev_t rdev)
53142 + {
53143 +- struct nfs4_exception exception = { };
53144 ++ struct nfs4_exception exception = {0, 0};
53145 + int err;
53146 + do {
53147 + err = nfs4_handle_exception(NFS_SERVER(dir),
53148 +@@ -2314,7 +2314,7 @@ static int _nfs4_proc_statfs(struct nfs_
53149 +
53150 + static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
53151 + {
53152 +- struct nfs4_exception exception = { };
53153 ++ struct nfs4_exception exception = {0, 0};
53154 + int err;
53155 + do {
53156 + err = nfs4_handle_exception(server,
53157 +@@ -2342,7 +2342,7 @@ static int _nfs4_do_fsinfo(struct nfs_se
53158 +
53159 + static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
53160 + {
53161 +- struct nfs4_exception exception = { };
53162 ++ struct nfs4_exception exception = {0, 0};
53163 + int err;
53164 +
53165 + do {
53166 +@@ -2385,7 +2385,7 @@ static int _nfs4_proc_pathconf(struct nf
53167 + static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
53168 + struct nfs_pathconf *pathconf)
53169 + {
53170 +- struct nfs4_exception exception = { };
53171 ++ struct nfs4_exception exception = {0, 0};
53172 + int err;
53173 +
53174 + do {
53175 +@@ -2672,7 +2672,7 @@ out_free:
53176 +
53177 + static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
53178 + {
53179 +- struct nfs4_exception exception = { };
53180 ++ struct nfs4_exception exception = {0, 0};
53181 + ssize_t ret;
53182 + do {
53183 + ret = __nfs4_get_acl_uncached(inode, buf, buflen);
53184 +@@ -2729,7 +2729,7 @@ static int __nfs4_proc_set_acl(struct in
53185 +
53186 + static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
53187 + {
53188 +- struct nfs4_exception exception = { };
53189 ++ struct nfs4_exception exception = {0, 0};
53190 + int err;
53191 + do {
53192 + err = nfs4_handle_exception(NFS_SERVER(inode),
53193 +@@ -3020,7 +3020,7 @@ out:
53194 + int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync)
53195 + {
53196 + struct nfs_server *server = NFS_SERVER(inode);
53197 +- struct nfs4_exception exception = { };
53198 ++ struct nfs4_exception exception = {0, 0};
53199 + int err;
53200 + do {
53201 + err = _nfs4_proc_delegreturn(inode, cred, stateid, issync);
53202 +@@ -3095,7 +3095,7 @@ out:
53203 +
53204 + static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
53205 + {
53206 +- struct nfs4_exception exception = { };
53207 ++ struct nfs4_exception exception = {0, 0};
53208 + int err;
53209 +
53210 + do {
53211 +@@ -3445,7 +3445,7 @@ static int _nfs4_do_setlk(struct nfs4_st
53212 + static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
53213 + {
53214 + struct nfs_server *server = NFS_SERVER(state->inode);
53215 +- struct nfs4_exception exception = { };
53216 ++ struct nfs4_exception exception = {0, 0};
53217 + int err;
53218 +
53219 + do {
53220 +@@ -3463,7 +3463,7 @@ static int nfs4_lock_reclaim(struct nfs4
53221 + static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
53222 + {
53223 + struct nfs_server *server = NFS_SERVER(state->inode);
53224 +- struct nfs4_exception exception = { };
53225 ++ struct nfs4_exception exception = {0, 0};
53226 + int err;
53227 +
53228 + err = nfs4_set_lock_state(state, request);
53229 +@@ -3524,7 +3524,7 @@ out:
53230 +
53231 + static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
53232 + {
53233 +- struct nfs4_exception exception = { };
53234 ++ struct nfs4_exception exception = {0, 0};
53235 + int err;
53236 +
53237 + do {
53238 +@@ -3574,7 +3574,7 @@ nfs4_proc_lock(struct file *filp, int cm
53239 + int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
53240 + {
53241 + struct nfs_server *server = NFS_SERVER(state->inode);
53242 +- struct nfs4_exception exception = { };
53243 ++ struct nfs4_exception exception = {0, 0};
53244 + int err;
53245 +
53246 + err = nfs4_set_lock_state(state, fl);
53247 +diff -urNp linux-2.6.27.7/fs/nfsd/export.c linux-2.6.27.7/fs/nfsd/export.c
53248 +--- linux-2.6.27.7/fs/nfsd/export.c 2008-11-07 12:55:34.000000000 -0500
53249 ++++ linux-2.6.27.7/fs/nfsd/export.c 2008-11-18 03:38:45.000000000 -0500
53250 +@@ -473,7 +473,7 @@ static int secinfo_parse(char **mesg, ch
53251 + * probably discover the problem when someone fails to
53252 + * authenticate.
53253 + */
53254 +- if (f->pseudoflavor < 0)
53255 ++ if ((s32)f->pseudoflavor < 0)
53256 + return -EINVAL;
53257 + err = get_int(mesg, &f->flags);
53258 + if (err)
53259 +diff -urNp linux-2.6.27.7/fs/nls/nls_base.c linux-2.6.27.7/fs/nls/nls_base.c
53260 +--- linux-2.6.27.7/fs/nls/nls_base.c 2008-11-07 12:55:34.000000000 -0500
53261 ++++ linux-2.6.27.7/fs/nls/nls_base.c 2008-11-18 03:38:45.000000000 -0500
53262 +@@ -42,7 +42,7 @@ static const struct utf8_table utf8_tabl
53263 + {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */},
53264 + {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */},
53265 + {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */},
53266 +- {0, /* end of table */}
53267 ++ {0, 0, 0, 0, 0, /* end of table */}
53268 + };
53269 +
53270 + int
53271 +diff -urNp linux-2.6.27.7/fs/ntfs/file.c linux-2.6.27.7/fs/ntfs/file.c
53272 +--- linux-2.6.27.7/fs/ntfs/file.c 2008-11-07 12:55:34.000000000 -0500
53273 ++++ linux-2.6.27.7/fs/ntfs/file.c 2008-11-18 03:38:45.000000000 -0500
53274 +@@ -2291,6 +2291,6 @@ const struct inode_operations ntfs_file_
53275 + #endif /* NTFS_RW */
53276 + };
53277 +
53278 +-const struct file_operations ntfs_empty_file_ops = {};
53279 ++const struct file_operations ntfs_empty_file_ops;
53280 +
53281 +-const struct inode_operations ntfs_empty_inode_ops = {};
53282 ++const struct inode_operations ntfs_empty_inode_ops;
53283 +diff -urNp linux-2.6.27.7/fs/open.c linux-2.6.27.7/fs/open.c
53284 +--- linux-2.6.27.7/fs/open.c 2008-11-07 12:55:34.000000000 -0500
53285 ++++ linux-2.6.27.7/fs/open.c 2008-11-18 03:38:45.000000000 -0500
53286 +@@ -29,6 +29,7 @@
53287 + #include <linux/rcupdate.h>
53288 + #include <linux/audit.h>
53289 + #include <linux/falloc.h>
53290 ++#include <linux/grsecurity.h>
53291 +
53292 + int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
53293 + {
53294 +@@ -207,6 +208,9 @@ int do_truncate(struct dentry *dentry, l
53295 + if (length < 0)
53296 + return -EINVAL;
53297 +
53298 ++ if (filp && !gr_acl_handle_truncate(dentry, filp->f_path.mnt))
53299 ++ return -EACCES;
53300 ++
53301 + newattrs.ia_size = length;
53302 + newattrs.ia_valid = ATTR_SIZE | time_attrs;
53303 + if (filp) {
53304 +@@ -491,6 +495,9 @@ asmlinkage long sys_faccessat(int dfd, c
53305 + if (__mnt_is_readonly(path.mnt))
53306 + res = -EROFS;
53307 +
53308 ++ if (!res && !gr_acl_handle_access(path.dentry, path.mnt, mode))
53309 ++ res = -EACCES;
53310 ++
53311 + out_path_release:
53312 + path_put(&path);
53313 + out:
53314 +@@ -521,6 +528,8 @@ asmlinkage long sys_chdir(const char __u
53315 + if (error)
53316 + goto dput_and_out;
53317 +
53318 ++ gr_log_chdir(path.dentry, path.mnt);
53319 ++
53320 + set_fs_pwd(current->fs, &path);
53321 +
53322 + dput_and_out:
53323 +@@ -547,6 +556,13 @@ asmlinkage long sys_fchdir(unsigned int
53324 + goto out_putf;
53325 +
53326 + error = inode_permission(inode, MAY_EXEC | MAY_ACCESS);
53327 ++
53328 ++ if (!error && !gr_chroot_fchdir(file->f_path.dentry, file->f_path.mnt))
53329 ++ error = -EPERM;
53330 ++
53331 ++ if (!error)
53332 ++ gr_log_chdir(file->f_path.dentry, file->f_path.mnt);
53333 ++
53334 + if (!error)
53335 + set_fs_pwd(current->fs, &file->f_path);
53336 + out_putf:
53337 +@@ -572,7 +588,14 @@ asmlinkage long sys_chroot(const char __
53338 + if (!capable(CAP_SYS_CHROOT))
53339 + goto dput_and_out;
53340 +
53341 ++ if (gr_handle_chroot_chroot(path.dentry, path.mnt))
53342 ++ goto dput_and_out;
53343 ++
53344 + set_fs_root(current->fs, &path);
53345 ++
53346 ++ gr_handle_chroot_caps(current);
53347 ++ gr_handle_chroot_chdir(&path);
53348 ++
53349 + error = 0;
53350 + dput_and_out:
53351 + path_put(&path);
53352 +@@ -600,13 +623,28 @@ asmlinkage long sys_fchmod(unsigned int
53353 + err = mnt_want_write(file->f_path.mnt);
53354 + if (err)
53355 + goto out_putf;
53356 ++
53357 ++ if (!gr_acl_handle_fchmod(dentry, file->f_path.mnt, mode)) {
53358 ++ err = -EACCES;
53359 ++ goto out_drop_write;
53360 ++ }
53361 ++
53362 + mutex_lock(&inode->i_mutex);
53363 + if (mode == (mode_t) -1)
53364 + mode = inode->i_mode;
53365 ++
53366 ++ if (gr_handle_chroot_chmod(dentry, file->f_path.mnt, mode)) {
53367 ++ err = -EPERM;
53368 ++ mutex_unlock(&inode->i_mutex);
53369 ++ goto out_drop_write;
53370 ++ }
53371 ++
53372 + newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
53373 + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
53374 + err = notify_change(dentry, &newattrs);
53375 + mutex_unlock(&inode->i_mutex);
53376 ++
53377 ++out_drop_write:
53378 + mnt_drop_write(file->f_path.mnt);
53379 + out_putf:
53380 + fput(file);
53381 +@@ -630,13 +668,28 @@ asmlinkage long sys_fchmodat(int dfd, co
53382 + error = mnt_want_write(path.mnt);
53383 + if (error)
53384 + goto dput_and_out;
53385 ++
53386 ++ if (!gr_acl_handle_chmod(path.dentry, path.mnt, mode)) {
53387 ++ error = -EACCES;
53388 ++ goto out_drop_write;
53389 ++ }
53390 ++
53391 + mutex_lock(&inode->i_mutex);
53392 + if (mode == (mode_t) -1)
53393 + mode = inode->i_mode;
53394 ++
53395 ++ if (gr_handle_chroot_chmod(path.dentry, path.mnt, mode)) {
53396 ++ error = -EACCES;
53397 ++ mutex_unlock(&inode->i_mutex);
53398 ++ goto out_drop_write;
53399 ++ }
53400 ++
53401 + newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
53402 + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
53403 + error = notify_change(path.dentry, &newattrs);
53404 + mutex_unlock(&inode->i_mutex);
53405 ++
53406 ++out_drop_write:
53407 + mnt_drop_write(path.mnt);
53408 + dput_and_out:
53409 + path_put(&path);
53410 +@@ -649,12 +702,15 @@ asmlinkage long sys_chmod(const char __u
53411 + return sys_fchmodat(AT_FDCWD, filename, mode);
53412 + }
53413 +
53414 +-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
53415 ++static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
53416 + {
53417 + struct inode *inode = dentry->d_inode;
53418 + int error;
53419 + struct iattr newattrs;
53420 +
53421 ++ if (!gr_acl_handle_chown(dentry, mnt))
53422 ++ return -EACCES;
53423 ++
53424 + newattrs.ia_valid = ATTR_CTIME;
53425 + if (user != (uid_t) -1) {
53426 + newattrs.ia_valid |= ATTR_UID;
53427 +@@ -685,7 +741,7 @@ asmlinkage long sys_chown(const char __u
53428 + error = mnt_want_write(path.mnt);
53429 + if (error)
53430 + goto out_release;
53431 +- error = chown_common(path.dentry, user, group);
53432 ++ error = chown_common(path.dentry, user, group, path.mnt);
53433 + mnt_drop_write(path.mnt);
53434 + out_release:
53435 + path_put(&path);
53436 +@@ -710,7 +766,7 @@ asmlinkage long sys_fchownat(int dfd, co
53437 + error = mnt_want_write(path.mnt);
53438 + if (error)
53439 + goto out_release;
53440 +- error = chown_common(path.dentry, user, group);
53441 ++ error = chown_common(path.dentry, user, group, path.mnt);
53442 + mnt_drop_write(path.mnt);
53443 + out_release:
53444 + path_put(&path);
53445 +@@ -729,7 +785,7 @@ asmlinkage long sys_lchown(const char __
53446 + error = mnt_want_write(path.mnt);
53447 + if (error)
53448 + goto out_release;
53449 +- error = chown_common(path.dentry, user, group);
53450 ++ error = chown_common(path.dentry, user, group, path.mnt);
53451 + mnt_drop_write(path.mnt);
53452 + out_release:
53453 + path_put(&path);
53454 +@@ -753,7 +809,7 @@ asmlinkage long sys_fchown(unsigned int
53455 + goto out_fput;
53456 + dentry = file->f_path.dentry;
53457 + audit_inode(NULL, dentry);
53458 +- error = chown_common(dentry, user, group);
53459 ++ error = chown_common(dentry, user, group, file->f_path.mnt);
53460 + mnt_drop_write(file->f_path.mnt);
53461 + out_fput:
53462 + fput(file);
53463 +diff -urNp linux-2.6.27.7/fs/pipe.c linux-2.6.27.7/fs/pipe.c
53464 +--- linux-2.6.27.7/fs/pipe.c 2008-11-07 12:55:34.000000000 -0500
53465 ++++ linux-2.6.27.7/fs/pipe.c 2008-11-18 03:38:45.000000000 -0500
53466 +@@ -851,7 +851,7 @@ void free_pipe_info(struct inode *inode)
53467 + inode->i_pipe = NULL;
53468 + }
53469 +
53470 +-static struct vfsmount *pipe_mnt __read_mostly;
53471 ++struct vfsmount *pipe_mnt __read_mostly;
53472 + static int pipefs_delete_dentry(struct dentry *dentry)
53473 + {
53474 + /*
53475 +diff -urNp linux-2.6.27.7/fs/proc/array.c linux-2.6.27.7/fs/proc/array.c
53476 +--- linux-2.6.27.7/fs/proc/array.c 2008-11-07 12:55:34.000000000 -0500
53477 ++++ linux-2.6.27.7/fs/proc/array.c 2008-11-18 03:38:45.000000000 -0500
53478 +@@ -315,6 +315,21 @@ static inline void task_context_switch_c
53479 + p->nivcsw);
53480 + }
53481 +
53482 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
53483 ++static inline void task_pax(struct seq_file *m, struct task_struct *p)
53484 ++{
53485 ++ if (p->mm)
53486 ++ seq_printf(m, "PaX:\t%c%c%c%c%c\n",
53487 ++ p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
53488 ++ p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
53489 ++ p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
53490 ++ p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
53491 ++ p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
53492 ++ else
53493 ++ seq_printf(m, "PaX:\t-----\n");
53494 ++}
53495 ++#endif
53496 ++
53497 + int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
53498 + struct pid *pid, struct task_struct *task)
53499 + {
53500 +@@ -334,9 +349,20 @@ int proc_pid_status(struct seq_file *m,
53501 + task_show_regs(m, task);
53502 + #endif
53503 + task_context_switch_counts(m, task);
53504 ++
53505 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
53506 ++ task_pax(m, task);
53507 ++#endif
53508 ++
53509 + return 0;
53510 + }
53511 +
53512 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
53513 ++#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
53514 ++ (_mm->pax_flags & MF_PAX_RANDMMAP || \
53515 ++ _mm->pax_flags & MF_PAX_SEGMEXEC))
53516 ++#endif
53517 ++
53518 + static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
53519 + struct pid *pid, struct task_struct *task, int whole)
53520 + {
53521 +@@ -429,6 +455,19 @@ static int do_task_stat(struct seq_file
53522 + gtime = task_gtime(task);
53523 + }
53524 +
53525 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
53526 ++ if (PAX_RAND_FLAGS(mm)) {
53527 ++ eip = 0;
53528 ++ esp = 0;
53529 ++ wchan = 0;
53530 ++ }
53531 ++#endif
53532 ++#ifdef CONFIG_GRKERNSEC_HIDESYM
53533 ++ wchan = 0;
53534 ++ eip =0;
53535 ++ esp =0;
53536 ++#endif
53537 ++
53538 + /* scale priority and nice values from timeslices to -20..20 */
53539 + /* to make it look like a "normal" Unix priority/nice value */
53540 + priority = task_prio(task);
53541 +@@ -469,9 +508,15 @@ static int do_task_stat(struct seq_file
53542 + vsize,
53543 + mm ? get_mm_rss(mm) : 0,
53544 + rsslim,
53545 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
53546 ++ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
53547 ++ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
53548 ++ PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0),
53549 ++#else
53550 + mm ? mm->start_code : 0,
53551 + mm ? mm->end_code : 0,
53552 + mm ? mm->start_stack : 0,
53553 ++#endif
53554 + esp,
53555 + eip,
53556 + /* The signal information here is obsolete.
53557 +@@ -524,3 +569,10 @@ int proc_pid_statm(struct seq_file *m, s
53558 +
53559 + return 0;
53560 + }
53561 ++
53562 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
53563 ++int proc_pid_ipaddr(struct task_struct *task, char *buffer)
53564 ++{
53565 ++ return sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
53566 ++}
53567 ++#endif
53568 +diff -urNp linux-2.6.27.7/fs/proc/base.c linux-2.6.27.7/fs/proc/base.c
53569 +--- linux-2.6.27.7/fs/proc/base.c 2008-11-07 12:55:34.000000000 -0500
53570 ++++ linux-2.6.27.7/fs/proc/base.c 2008-11-18 03:38:45.000000000 -0500
53571 +@@ -79,6 +79,8 @@
53572 + #include <linux/oom.h>
53573 + #include <linux/elf.h>
53574 + #include <linux/pid_namespace.h>
53575 ++#include <linux/grsecurity.h>
53576 ++
53577 + #include "internal.h"
53578 +
53579 + /* NOTE:
53580 +@@ -148,7 +150,7 @@ static unsigned int pid_entry_count_dirs
53581 + return count;
53582 + }
53583 +
53584 +-int maps_protect;
53585 ++int maps_protect = 1;
53586 + EXPORT_SYMBOL(maps_protect);
53587 +
53588 + static struct fs_struct *get_fs_struct(struct task_struct *task)
53589 +@@ -229,6 +231,9 @@ static int check_mem_permission(struct t
53590 + if (task == current)
53591 + return 0;
53592 +
53593 ++ if (gr_handle_proc_ptrace(task) || gr_acl_handle_procpidmem(task))
53594 ++ return -EPERM;
53595 ++
53596 + /*
53597 + * If current is actively ptrace'ing, and would also be
53598 + * permitted to freshly attach with ptrace now, permit it.
53599 +@@ -312,9 +317,9 @@ static int proc_pid_auxv(struct task_str
53600 + struct mm_struct *mm = get_task_mm(task);
53601 + if (mm) {
53602 + unsigned int nwords = 0;
53603 +- do
53604 ++ do {
53605 + nwords += 2;
53606 +- while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
53607 ++ } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
53608 + res = nwords * sizeof(mm->saved_auxv[0]);
53609 + if (res > PAGE_SIZE)
53610 + res = PAGE_SIZE;
53611 +@@ -1437,7 +1442,11 @@ static struct inode *proc_pid_make_inode
53612 + inode->i_gid = 0;
53613 + if (task_dumpable(task)) {
53614 + inode->i_uid = task->euid;
53615 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
53616 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
53617 ++#else
53618 + inode->i_gid = task->egid;
53619 ++#endif
53620 + }
53621 + security_task_to_inode(task, inode);
53622 +
53623 +@@ -1453,17 +1462,45 @@ static int pid_getattr(struct vfsmount *
53624 + {
53625 + struct inode *inode = dentry->d_inode;
53626 + struct task_struct *task;
53627 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
53628 ++ struct task_struct *tmp = current;
53629 ++#endif
53630 ++
53631 + generic_fillattr(inode, stat);
53632 +
53633 + rcu_read_lock();
53634 + stat->uid = 0;
53635 + stat->gid = 0;
53636 + task = pid_task(proc_pid(inode), PIDTYPE_PID);
53637 +- if (task) {
53638 ++
53639 ++ if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) {
53640 ++ rcu_read_unlock();
53641 ++ return -ENOENT;
53642 ++ }
53643 ++
53644 ++
53645 ++ if (task
53646 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
53647 ++ && (!tmp->uid || (tmp->uid == task->uid)
53648 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
53649 ++ || in_group_p(CONFIG_GRKERNSEC_PROC_GID)
53650 ++#endif
53651 ++ )
53652 ++#endif
53653 ++ ) {
53654 + if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
53655 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
53656 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
53657 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
53658 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
53659 ++#endif
53660 + task_dumpable(task)) {
53661 + stat->uid = task->euid;
53662 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
53663 ++ stat->gid = CONFIG_GRKERNSEC_PROC_GID;
53664 ++#else
53665 + stat->gid = task->egid;
53666 ++#endif
53667 + }
53668 + }
53669 + rcu_read_unlock();
53670 +@@ -1491,11 +1528,21 @@ static int pid_revalidate(struct dentry
53671 + {
53672 + struct inode *inode = dentry->d_inode;
53673 + struct task_struct *task = get_proc_task(inode);
53674 ++
53675 + if (task) {
53676 + if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
53677 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
53678 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
53679 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
53680 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
53681 ++#endif
53682 + task_dumpable(task)) {
53683 + inode->i_uid = task->euid;
53684 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
53685 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
53686 ++#else
53687 + inode->i_gid = task->egid;
53688 ++#endif
53689 + } else {
53690 + inode->i_uid = 0;
53691 + inode->i_gid = 0;
53692 +@@ -1863,12 +1910,22 @@ static const struct file_operations proc
53693 + static int proc_fd_permission(struct inode *inode, int mask)
53694 + {
53695 + int rv;
53696 ++ struct task_struct *task;
53697 +
53698 + rv = generic_permission(inode, mask, NULL);
53699 +- if (rv == 0)
53700 +- return 0;
53701 ++
53702 + if (task_pid(current) == proc_pid(inode))
53703 + rv = 0;
53704 ++
53705 ++ task = get_proc_task(inode);
53706 ++ if (task == NULL)
53707 ++ return rv;
53708 ++
53709 ++ if (gr_acl_handle_procpidmem(task))
53710 ++ rv = -EACCES;
53711 ++
53712 ++ put_task_struct(task);
53713 ++
53714 + return rv;
53715 + }
53716 +
53717 +@@ -1979,6 +2036,9 @@ static struct dentry *proc_pident_lookup
53718 + if (!task)
53719 + goto out_no_task;
53720 +
53721 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
53722 ++ goto out;
53723 ++
53724 + /*
53725 + * Yes, it does not scale. And it should not. Don't add
53726 + * new entries into /proc/<tgid>/ without very good reasons.
53727 +@@ -2023,6 +2083,9 @@ static int proc_pident_readdir(struct fi
53728 + if (!task)
53729 + goto out_no_task;
53730 +
53731 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
53732 ++ goto out;
53733 ++
53734 + ret = 0;
53735 + i = filp->f_pos;
53736 + switch (i) {
53737 +@@ -2385,6 +2448,9 @@ static struct dentry *proc_base_lookup(s
53738 + if (p > last)
53739 + goto out;
53740 +
53741 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
53742 ++ goto out;
53743 ++
53744 + error = proc_base_instantiate(dir, dentry, task, p);
53745 +
53746 + out:
53747 +@@ -2518,6 +2584,9 @@ static const struct pid_entry tgid_base_
53748 + #ifdef CONFIG_TASK_IO_ACCOUNTING
53749 + INF("io", S_IRUGO, tgid_io_accounting),
53750 + #endif
53751 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
53752 ++ INF("ipaddr", S_IRUSR, pid_ipaddr),
53753 ++#endif
53754 + };
53755 +
53756 + static int proc_tgid_base_readdir(struct file * filp,
53757 +@@ -2647,7 +2716,14 @@ static struct dentry *proc_pid_instantia
53758 + if (!inode)
53759 + goto out;
53760 +
53761 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
53762 ++ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
53763 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
53764 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
53765 ++ inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP;
53766 ++#else
53767 + inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
53768 ++#endif
53769 + inode->i_op = &proc_tgid_base_inode_operations;
53770 + inode->i_fop = &proc_tgid_base_operations;
53771 + inode->i_flags|=S_IMMUTABLE;
53772 +@@ -2689,7 +2765,11 @@ struct dentry *proc_pid_lookup(struct in
53773 + if (!task)
53774 + goto out;
53775 +
53776 ++ if (gr_check_hidden_task(task))
53777 ++ goto out_put_task;
53778 ++
53779 + result = proc_pid_instantiate(dir, dentry, task, NULL);
53780 ++out_put_task:
53781 + put_task_struct(task);
53782 + out:
53783 + return result;
53784 +@@ -2754,6 +2834,9 @@ int proc_pid_readdir(struct file * filp,
53785 + {
53786 + unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
53787 + struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode);
53788 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
53789 ++ struct task_struct *tmp = current;
53790 ++#endif
53791 + struct tgid_iter iter;
53792 + struct pid_namespace *ns;
53793 +
53794 +@@ -2772,6 +2855,17 @@ int proc_pid_readdir(struct file * filp,
53795 + for (iter = next_tgid(ns, iter);
53796 + iter.task;
53797 + iter.tgid += 1, iter = next_tgid(ns, iter)) {
53798 ++ if (gr_pid_is_chrooted(iter.task) || gr_check_hidden_task(iter.task)
53799 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
53800 ++ || (tmp->uid && (iter.task->uid != tmp->uid)
53801 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
53802 ++ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
53803 ++#endif
53804 ++ )
53805 ++#endif
53806 ++ )
53807 ++ continue;
53808 ++
53809 + filp->f_pos = iter.tgid + TGID_OFFSET;
53810 + if (proc_pid_fill_cache(filp, dirent, filldir, iter) < 0) {
53811 + put_task_struct(iter.task);
53812 +diff -urNp linux-2.6.27.7/fs/proc/inode.c linux-2.6.27.7/fs/proc/inode.c
53813 +--- linux-2.6.27.7/fs/proc/inode.c 2008-11-07 12:55:34.000000000 -0500
53814 ++++ linux-2.6.27.7/fs/proc/inode.c 2008-11-18 03:38:45.000000000 -0500
53815 +@@ -467,7 +467,11 @@ struct inode *proc_get_inode(struct supe
53816 + if (de->mode) {
53817 + inode->i_mode = de->mode;
53818 + inode->i_uid = de->uid;
53819 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
53820 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
53821 ++#else
53822 + inode->i_gid = de->gid;
53823 ++#endif
53824 + }
53825 + if (de->size)
53826 + inode->i_size = de->size;
53827 +diff -urNp linux-2.6.27.7/fs/proc/internal.h linux-2.6.27.7/fs/proc/internal.h
53828 +--- linux-2.6.27.7/fs/proc/internal.h 2008-11-07 12:55:34.000000000 -0500
53829 ++++ linux-2.6.27.7/fs/proc/internal.h 2008-11-18 03:38:45.000000000 -0500
53830 +@@ -55,6 +55,9 @@ extern int proc_pid_status(struct seq_fi
53831 + struct pid *pid, struct task_struct *task);
53832 + extern int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
53833 + struct pid *pid, struct task_struct *task);
53834 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
53835 ++extern int proc_pid_ipaddr(struct task_struct *task, char *buffer);
53836 ++#endif
53837 + extern loff_t mem_lseek(struct file *file, loff_t offset, int orig);
53838 +
53839 + extern const struct file_operations proc_maps_operations;
53840 +diff -urNp linux-2.6.27.7/fs/proc/Kconfig linux-2.6.27.7/fs/proc/Kconfig
53841 +--- linux-2.6.27.7/fs/proc/Kconfig 2008-11-07 12:55:34.000000000 -0500
53842 ++++ linux-2.6.27.7/fs/proc/Kconfig 2008-11-18 03:38:45.000000000 -0500
53843 +@@ -30,12 +30,12 @@ config PROC_FS
53844 +
53845 + config PROC_KCORE
53846 + bool "/proc/kcore support" if !ARM
53847 +- depends on PROC_FS && MMU
53848 ++ depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
53849 +
53850 + config PROC_VMCORE
53851 + bool "/proc/vmcore support (EXPERIMENTAL)"
53852 +- depends on PROC_FS && CRASH_DUMP
53853 +- default y
53854 ++ depends on PROC_FS && CRASH_DUMP && !GRKERNSEC
53855 ++ default n
53856 + help
53857 + Exports the dump image of crashed kernel in ELF format.
53858 +
53859 +diff -urNp linux-2.6.27.7/fs/proc/proc_misc.c linux-2.6.27.7/fs/proc/proc_misc.c
53860 +--- linux-2.6.27.7/fs/proc/proc_misc.c 2008-11-07 12:55:34.000000000 -0500
53861 ++++ linux-2.6.27.7/fs/proc/proc_misc.c 2008-11-18 03:38:45.000000000 -0500
53862 +@@ -860,6 +860,8 @@ struct proc_dir_entry *proc_root_kcore;
53863 +
53864 + void __init proc_misc_init(void)
53865 + {
53866 ++ int gr_mode = 0;
53867 ++
53868 + static struct {
53869 + char *name;
53870 + int (*read_proc)(char*,char**,off_t,int,int*,void*);
53871 +@@ -875,13 +877,24 @@ void __init proc_misc_init(void)
53872 + {"stram", stram_read_proc},
53873 + #endif
53874 + {"filesystems", filesystems_read_proc},
53875 ++#ifndef CONFIG_GRKERNSEC_PROC_ADD
53876 + {"cmdline", cmdline_read_proc},
53877 ++#endif
53878 + {"execdomains", execdomains_read_proc},
53879 + {NULL,}
53880 + };
53881 + for (p = simple_ones; p->name; p++)
53882 + create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
53883 +
53884 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
53885 ++ gr_mode = S_IRUSR;
53886 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
53887 ++ gr_mode = S_IRUSR | S_IRGRP;
53888 ++#endif
53889 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
53890 ++ create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
53891 ++#endif
53892 ++
53893 + proc_symlink("mounts", NULL, "self/mounts");
53894 +
53895 + /* And now for trickier ones */
53896 +@@ -889,14 +902,18 @@ void __init proc_misc_init(void)
53897 + proc_create("kmsg", S_IRUSR, NULL, &proc_kmsg_operations);
53898 + #endif
53899 + proc_create("locks", 0, NULL, &proc_locks_operations);
53900 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
53901 ++ proc_create("devices", gr_mode, NULL, &proc_devinfo_operations);
53902 ++#else
53903 + proc_create("devices", 0, NULL, &proc_devinfo_operations);
53904 ++#endif
53905 + proc_create("cpuinfo", 0, NULL, &proc_cpuinfo_operations);
53906 + #ifdef CONFIG_BLOCK
53907 + proc_create("partitions", 0, NULL, &proc_partitions_operations);
53908 + #endif
53909 + proc_create("stat", 0, NULL, &proc_stat_operations);
53910 + proc_create("interrupts", 0, NULL, &proc_interrupts_operations);
53911 +-#ifdef CONFIG_SLABINFO
53912 ++#if defined(CONFIG_SLABINFO) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
53913 + proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
53914 + #ifdef CONFIG_DEBUG_SLAB_LEAK
53915 + proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations);
53916 +@@ -918,7 +935,7 @@ void __init proc_misc_init(void)
53917 + #ifdef CONFIG_SCHEDSTATS
53918 + proc_create("schedstat", 0, NULL, &proc_schedstat_operations);
53919 + #endif
53920 +-#ifdef CONFIG_PROC_KCORE
53921 ++#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
53922 + proc_root_kcore = proc_create("kcore", S_IRUSR, NULL, &proc_kcore_operations);
53923 + if (proc_root_kcore)
53924 + proc_root_kcore->size =
53925 +diff -urNp linux-2.6.27.7/fs/proc/proc_net.c linux-2.6.27.7/fs/proc/proc_net.c
53926 +--- linux-2.6.27.7/fs/proc/proc_net.c 2008-11-07 12:55:34.000000000 -0500
53927 ++++ linux-2.6.27.7/fs/proc/proc_net.c 2008-11-18 03:38:45.000000000 -0500
53928 +@@ -106,6 +106,14 @@ static struct net *get_proc_task_net(str
53929 + struct nsproxy *ns;
53930 + struct net *net = NULL;
53931 +
53932 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
53933 ++ if (current->fsuid)
53934 ++ return net;
53935 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
53936 ++ if (current->fsuid && !in_group_p(CONFIG_GRKERNSEC_PROC_GID))
53937 ++ return net;
53938 ++#endif
53939 ++
53940 + rcu_read_lock();
53941 + task = pid_task(proc_pid(dir), PIDTYPE_PID);
53942 + if (task != NULL) {
53943 +diff -urNp linux-2.6.27.7/fs/proc/proc_sysctl.c linux-2.6.27.7/fs/proc/proc_sysctl.c
53944 +--- linux-2.6.27.7/fs/proc/proc_sysctl.c 2008-11-18 11:38:40.000000000 -0500
53945 ++++ linux-2.6.27.7/fs/proc/proc_sysctl.c 2008-11-18 11:40:53.000000000 -0500
53946 +@@ -7,6 +7,8 @@
53947 + #include <linux/security.h>
53948 + #include "internal.h"
53949 +
53950 ++extern __u32 gr_handle_sysctl(const struct ctl_table *table, const int op);
53951 ++
53952 + static struct dentry_operations proc_sys_dentry_operations;
53953 + static const struct file_operations proc_sys_file_operations;
53954 + static const struct inode_operations proc_sys_inode_operations;
53955 +@@ -110,6 +112,9 @@ static struct dentry *proc_sys_lookup(st
53956 + if (!p)
53957 + goto out;
53958 +
53959 ++ if (gr_handle_sysctl(p, MAY_EXEC))
53960 ++ goto out;
53961 ++
53962 + err = ERR_PTR(-ENOMEM);
53963 + inode = proc_sys_make_inode(dir->i_sb, h ? h : head, p);
53964 + if (h)
53965 +@@ -229,6 +234,9 @@ static int scan(struct ctl_table_header
53966 + if (*pos < file->f_pos)
53967 + continue;
53968 +
53969 ++ if (gr_handle_sysctl(table, 0))
53970 ++ continue;
53971 ++
53972 + res = proc_sys_fill_cache(file, dirent, filldir, head, table);
53973 + if (res)
53974 + return res;
53975 +@@ -339,6 +347,9 @@ static int proc_sys_getattr(struct vfsmo
53976 + if (IS_ERR(head))
53977 + return PTR_ERR(head);
53978 +
53979 ++ if (table && gr_handle_sysctl(table, MAY_EXEC))
53980 ++ return -ENOENT;
53981 ++
53982 + generic_fillattr(inode, stat);
53983 + if (table)
53984 + stat->mode = (stat->mode & S_IFMT) | table->mode;
53985 +diff -urNp linux-2.6.27.7/fs/proc/root.c linux-2.6.27.7/fs/proc/root.c
53986 +--- linux-2.6.27.7/fs/proc/root.c 2008-11-07 12:55:34.000000000 -0500
53987 ++++ linux-2.6.27.7/fs/proc/root.c 2008-11-18 03:38:45.000000000 -0500
53988 +@@ -135,7 +135,15 @@ void __init proc_root_init(void)
53989 + #ifdef CONFIG_PROC_DEVICETREE
53990 + proc_device_tree_init();
53991 + #endif
53992 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
53993 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
53994 ++ proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
53995 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
53996 ++ proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
53997 ++#endif
53998 ++#else
53999 + proc_mkdir("bus", NULL);
54000 ++#endif
54001 + proc_sys_init();
54002 + }
54003 +
54004 +diff -urNp linux-2.6.27.7/fs/proc/task_mmu.c linux-2.6.27.7/fs/proc/task_mmu.c
54005 +--- linux-2.6.27.7/fs/proc/task_mmu.c 2008-11-07 12:55:34.000000000 -0500
54006 ++++ linux-2.6.27.7/fs/proc/task_mmu.c 2008-11-18 03:38:45.000000000 -0500
54007 +@@ -46,15 +46,26 @@ void task_mem(struct seq_file *m, struct
54008 + "VmStk:\t%8lu kB\n"
54009 + "VmExe:\t%8lu kB\n"
54010 + "VmLib:\t%8lu kB\n"
54011 +- "VmPTE:\t%8lu kB\n",
54012 +- hiwater_vm << (PAGE_SHIFT-10),
54013 ++ "VmPTE:\t%8lu kB\n"
54014 ++
54015 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
54016 ++ "CsBase:\t%8lx\nCsLim:\t%8lx\n"
54017 ++#endif
54018 ++
54019 ++ ,hiwater_vm << (PAGE_SHIFT-10),
54020 + (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
54021 + mm->locked_vm << (PAGE_SHIFT-10),
54022 + hiwater_rss << (PAGE_SHIFT-10),
54023 + total_rss << (PAGE_SHIFT-10),
54024 + data << (PAGE_SHIFT-10),
54025 + mm->stack_vm << (PAGE_SHIFT-10), text, lib,
54026 +- (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
54027 ++ (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
54028 ++
54029 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
54030 ++ , mm->context.user_cs_base, mm->context.user_cs_limit
54031 ++#endif
54032 ++
54033 ++ );
54034 + }
54035 +
54036 + unsigned long task_vsize(struct mm_struct *mm)
54037 +@@ -198,6 +209,12 @@ static int do_maps_open(struct inode *in
54038 + return ret;
54039 + }
54040 +
54041 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
54042 ++#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
54043 ++ (_mm->pax_flags & MF_PAX_RANDMMAP || \
54044 ++ _mm->pax_flags & MF_PAX_SEGMEXEC))
54045 ++#endif
54046 ++
54047 + static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
54048 + {
54049 + struct mm_struct *mm = vma->vm_mm;
54050 +@@ -214,13 +231,22 @@ static void show_map_vma(struct seq_file
54051 + }
54052 +
54053 + seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n",
54054 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
54055 ++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
54056 ++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
54057 ++#else
54058 + vma->vm_start,
54059 + vma->vm_end,
54060 ++#endif
54061 + flags & VM_READ ? 'r' : '-',
54062 + flags & VM_WRITE ? 'w' : '-',
54063 + flags & VM_EXEC ? 'x' : '-',
54064 + flags & VM_MAYSHARE ? 's' : 'p',
54065 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
54066 ++ PAX_RAND_FLAGS(mm) ? 0UL : ((loff_t)vma->vm_pgoff) << PAGE_SHIFT,
54067 ++#else
54068 + ((loff_t)vma->vm_pgoff) << PAGE_SHIFT,
54069 ++#endif
54070 + MAJOR(dev), MINOR(dev), ino, &len);
54071 +
54072 + /*
54073 +@@ -234,11 +260,11 @@ static void show_map_vma(struct seq_file
54074 + const char *name = arch_vma_name(vma);
54075 + if (!name) {
54076 + if (mm) {
54077 +- if (vma->vm_start <= mm->start_brk &&
54078 +- vma->vm_end >= mm->brk) {
54079 ++ if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
54080 + name = "[heap]";
54081 +- } else if (vma->vm_start <= mm->start_stack &&
54082 +- vma->vm_end >= mm->start_stack) {
54083 ++ } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
54084 ++ (vma->vm_start <= mm->start_stack &&
54085 ++ vma->vm_end >= mm->start_stack)) {
54086 + name = "[stack]";
54087 + }
54088 + } else {
54089 +@@ -387,9 +413,16 @@ static int show_smap(struct seq_file *m,
54090 + return -EACCES;
54091 +
54092 + memset(&mss, 0, sizeof mss);
54093 +- mss.vma = vma;
54094 +- if (vma->vm_mm && !is_vm_hugetlb_page(vma))
54095 +- walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
54096 ++
54097 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
54098 ++ if (!PAX_RAND_FLAGS(vma->vm_mm)) {
54099 ++#endif
54100 ++ mss.vma = vma;
54101 ++ if (vma->vm_mm && !is_vm_hugetlb_page(vma))
54102 ++ walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
54103 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
54104 ++ }
54105 ++#endif
54106 +
54107 + show_map_vma(m, vma);
54108 +
54109 +@@ -403,7 +436,11 @@ static int show_smap(struct seq_file *m,
54110 + "Private_Dirty: %8lu kB\n"
54111 + "Referenced: %8lu kB\n"
54112 + "Swap: %8lu kB\n",
54113 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
54114 ++ PAX_RAND_FLAGS(vma->vm_mm) ? 0UL : (vma->vm_end - vma->vm_start) >> 10,
54115 ++#else
54116 + (vma->vm_end - vma->vm_start) >> 10,
54117 ++#endif
54118 + mss.resident >> 10,
54119 + (unsigned long)(mss.pss >> (10 + PSS_SHIFT)),
54120 + mss.shared_clean >> 10,
54121 +@@ -757,6 +794,11 @@ static int show_numa_map_checked(struct
54122 + struct proc_maps_private *priv = m->private;
54123 + struct task_struct *task = priv->task;
54124 +
54125 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
54126 ++ if (!ptrace_may_access(task, PTRACE_MODE_READ))
54127 ++ return -EACCES;
54128 ++#endif
54129 ++
54130 + if (maps_protect && !ptrace_may_access(task, PTRACE_MODE_READ))
54131 + return -EACCES;
54132 +
54133 +diff -urNp linux-2.6.27.7/fs/readdir.c linux-2.6.27.7/fs/readdir.c
54134 +--- linux-2.6.27.7/fs/readdir.c 2008-11-07 12:55:34.000000000 -0500
54135 ++++ linux-2.6.27.7/fs/readdir.c 2008-11-18 03:38:45.000000000 -0500
54136 +@@ -16,6 +16,8 @@
54137 + #include <linux/security.h>
54138 + #include <linux/syscalls.h>
54139 + #include <linux/unistd.h>
54140 ++#include <linux/namei.h>
54141 ++#include <linux/grsecurity.h>
54142 +
54143 + #include <asm/uaccess.h>
54144 +
54145 +@@ -67,6 +69,7 @@ struct old_linux_dirent {
54146 +
54147 + struct readdir_callback {
54148 + struct old_linux_dirent __user * dirent;
54149 ++ struct file * file;
54150 + int result;
54151 + };
54152 +
54153 +@@ -84,6 +87,10 @@ static int fillonedir(void * __buf, cons
54154 + buf->result = -EOVERFLOW;
54155 + return -EOVERFLOW;
54156 + }
54157 ++
54158 ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
54159 ++ return 0;
54160 ++
54161 + buf->result++;
54162 + dirent = buf->dirent;
54163 + if (!access_ok(VERIFY_WRITE, dirent,
54164 +@@ -115,6 +122,7 @@ asmlinkage long old_readdir(unsigned int
54165 +
54166 + buf.result = 0;
54167 + buf.dirent = dirent;
54168 ++ buf.file = file;
54169 +
54170 + error = vfs_readdir(file, fillonedir, &buf);
54171 + if (error >= 0)
54172 +@@ -141,6 +149,7 @@ struct linux_dirent {
54173 + struct getdents_callback {
54174 + struct linux_dirent __user * current_dir;
54175 + struct linux_dirent __user * previous;
54176 ++ struct file * file;
54177 + int count;
54178 + int error;
54179 + };
54180 +@@ -161,6 +170,10 @@ static int filldir(void * __buf, const c
54181 + buf->error = -EOVERFLOW;
54182 + return -EOVERFLOW;
54183 + }
54184 ++
54185 ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
54186 ++ return 0;
54187 ++
54188 + dirent = buf->previous;
54189 + if (dirent) {
54190 + if (__put_user(offset, &dirent->d_off))
54191 +@@ -207,6 +220,7 @@ asmlinkage long sys_getdents(unsigned in
54192 + buf.previous = NULL;
54193 + buf.count = count;
54194 + buf.error = 0;
54195 ++ buf.file = file;
54196 +
54197 + error = vfs_readdir(file, filldir, &buf);
54198 + if (error < 0)
54199 +@@ -229,6 +243,7 @@ out:
54200 + struct getdents_callback64 {
54201 + struct linux_dirent64 __user * current_dir;
54202 + struct linux_dirent64 __user * previous;
54203 ++ struct file *file;
54204 + int count;
54205 + int error;
54206 + };
54207 +@@ -243,6 +258,10 @@ static int filldir64(void * __buf, const
54208 + buf->error = -EINVAL; /* only used if we fail.. */
54209 + if (reclen > buf->count)
54210 + return -EINVAL;
54211 ++
54212 ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
54213 ++ return 0;
54214 ++
54215 + dirent = buf->previous;
54216 + if (dirent) {
54217 + if (__put_user(offset, &dirent->d_off))
54218 +@@ -289,6 +308,7 @@ asmlinkage long sys_getdents64(unsigned
54219 +
54220 + buf.current_dir = dirent;
54221 + buf.previous = NULL;
54222 ++ buf.file = file;
54223 + buf.count = count;
54224 + buf.error = 0;
54225 +
54226 +diff -urNp linux-2.6.27.7/fs/select.c linux-2.6.27.7/fs/select.c
54227 +--- linux-2.6.27.7/fs/select.c 2008-11-07 12:55:34.000000000 -0500
54228 ++++ linux-2.6.27.7/fs/select.c 2008-11-18 03:38:45.000000000 -0500
54229 +@@ -24,6 +24,7 @@
54230 + #include <linux/fdtable.h>
54231 + #include <linux/fs.h>
54232 + #include <linux/rcupdate.h>
54233 ++#include <linux/grsecurity.h>
54234 +
54235 + #include <asm/uaccess.h>
54236 +
54237 +@@ -658,6 +659,7 @@ int do_sys_poll(struct pollfd __user *uf
54238 + struct poll_list *walk = head;
54239 + unsigned long todo = nfds;
54240 +
54241 ++ gr_learn_resource(current, RLIMIT_NOFILE, nfds, 1);
54242 + if (nfds > current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
54243 + return -EINVAL;
54244 +
54245 +diff -urNp linux-2.6.27.7/fs/smbfs/symlink.c linux-2.6.27.7/fs/smbfs/symlink.c
54246 +--- linux-2.6.27.7/fs/smbfs/symlink.c 2008-11-07 12:55:34.000000000 -0500
54247 ++++ linux-2.6.27.7/fs/smbfs/symlink.c 2008-11-18 03:38:45.000000000 -0500
54248 +@@ -55,7 +55,7 @@ static void *smb_follow_link(struct dent
54249 +
54250 + static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
54251 + {
54252 +- char *s = nd_get_link(nd);
54253 ++ const char *s = nd_get_link(nd);
54254 + if (!IS_ERR(s))
54255 + __putname(s);
54256 + }
54257 +diff -urNp linux-2.6.27.7/fs/sysfs/symlink.c linux-2.6.27.7/fs/sysfs/symlink.c
54258 +--- linux-2.6.27.7/fs/sysfs/symlink.c 2008-11-07 12:55:34.000000000 -0500
54259 ++++ linux-2.6.27.7/fs/sysfs/symlink.c 2008-11-18 03:38:45.000000000 -0500
54260 +@@ -200,7 +200,7 @@ static void *sysfs_follow_link(struct de
54261 +
54262 + static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
54263 + {
54264 +- char *page = nd_get_link(nd);
54265 ++ const char *page = nd_get_link(nd);
54266 + if (!IS_ERR(page))
54267 + free_page((unsigned long)page);
54268 + }
54269 +diff -urNp linux-2.6.27.7/fs/udf/balloc.c linux-2.6.27.7/fs/udf/balloc.c
54270 +--- linux-2.6.27.7/fs/udf/balloc.c 2008-11-07 12:55:34.000000000 -0500
54271 ++++ linux-2.6.27.7/fs/udf/balloc.c 2008-11-18 03:38:45.000000000 -0500
54272 +@@ -169,9 +169,7 @@ static void udf_bitmap_free_blocks(struc
54273 + unsigned long overflow;
54274 +
54275 + mutex_lock(&sbi->s_alloc_mutex);
54276 +- if (bloc.logicalBlockNum < 0 ||
54277 +- (bloc.logicalBlockNum + count) >
54278 +- sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
54279 ++ if (bloc.logicalBlockNum + count > sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
54280 + udf_debug("%d < %d || %d + %d > %d\n",
54281 + bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
54282 + sbi->s_partmaps[bloc.partitionReferenceNum].
54283 +@@ -239,7 +237,7 @@ static int udf_bitmap_prealloc_blocks(st
54284 +
54285 + mutex_lock(&sbi->s_alloc_mutex);
54286 + part_len = sbi->s_partmaps[partition].s_partition_len;
54287 +- if (first_block < 0 || first_block >= part_len)
54288 ++ if (first_block >= part_len)
54289 + goto out;
54290 +
54291 + if (first_block + block_count > part_len)
54292 +@@ -300,7 +298,7 @@ static int udf_bitmap_new_block(struct s
54293 + mutex_lock(&sbi->s_alloc_mutex);
54294 +
54295 + repeat:
54296 +- if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
54297 ++ if (goal >= sbi->s_partmaps[partition].s_partition_len)
54298 + goal = 0;
54299 +
54300 + nr_groups = bitmap->s_nr_groups;
54301 +@@ -438,9 +436,7 @@ static void udf_table_free_blocks(struct
54302 + struct udf_inode_info *iinfo;
54303 +
54304 + mutex_lock(&sbi->s_alloc_mutex);
54305 +- if (bloc.logicalBlockNum < 0 ||
54306 +- (bloc.logicalBlockNum + count) >
54307 +- sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
54308 ++ if (bloc.logicalBlockNum + count > sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
54309 + udf_debug("%d < %d || %d + %d > %d\n",
54310 + bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
54311 + sbi->s_partmaps[bloc.partitionReferenceNum].
54312 +@@ -671,8 +667,7 @@ static int udf_table_prealloc_blocks(str
54313 + int8_t etype = -1;
54314 + struct udf_inode_info *iinfo;
54315 +
54316 +- if (first_block < 0 ||
54317 +- first_block >= sbi->s_partmaps[partition].s_partition_len)
54318 ++ if (first_block >= sbi->s_partmaps[partition].s_partition_len)
54319 + return 0;
54320 +
54321 + iinfo = UDF_I(table);
54322 +@@ -750,7 +745,7 @@ static int udf_table_new_block(struct su
54323 + return newblock;
54324 +
54325 + mutex_lock(&sbi->s_alloc_mutex);
54326 +- if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
54327 ++ if (goal >= sbi->s_partmaps[partition].s_partition_len)
54328 + goal = 0;
54329 +
54330 + /* We search for the closest matching block to goal. If we find
54331 +diff -urNp linux-2.6.27.7/fs/ufs/inode.c linux-2.6.27.7/fs/ufs/inode.c
54332 +--- linux-2.6.27.7/fs/ufs/inode.c 2008-11-07 12:55:34.000000000 -0500
54333 ++++ linux-2.6.27.7/fs/ufs/inode.c 2008-11-18 03:38:45.000000000 -0500
54334 +@@ -56,9 +56,7 @@ static int ufs_block_to_path(struct inod
54335 +
54336 +
54337 + UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
54338 +- if (i_block < 0) {
54339 +- ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
54340 +- } else if (i_block < direct_blocks) {
54341 ++ if (i_block < direct_blocks) {
54342 + offsets[n++] = i_block;
54343 + } else if ((i_block -= direct_blocks) < indirect_blocks) {
54344 + offsets[n++] = UFS_IND_BLOCK;
54345 +@@ -440,8 +438,6 @@ int ufs_getfrag_block(struct inode *inod
54346 + lock_kernel();
54347 +
54348 + UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
54349 +- if (fragment < 0)
54350 +- goto abort_negative;
54351 + if (fragment >
54352 + ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
54353 + << uspi->s_fpbshift))
54354 +@@ -504,10 +500,6 @@ abort:
54355 + unlock_kernel();
54356 + return err;
54357 +
54358 +-abort_negative:
54359 +- ufs_warning(sb, "ufs_get_block", "block < 0");
54360 +- goto abort;
54361 +-
54362 + abort_too_big:
54363 + ufs_warning(sb, "ufs_get_block", "block > big");
54364 + goto abort;
54365 +diff -urNp linux-2.6.27.7/fs/utimes.c linux-2.6.27.7/fs/utimes.c
54366 +--- linux-2.6.27.7/fs/utimes.c 2008-11-07 12:55:34.000000000 -0500
54367 ++++ linux-2.6.27.7/fs/utimes.c 2008-11-18 03:38:45.000000000 -0500
54368 +@@ -8,6 +8,7 @@
54369 + #include <linux/stat.h>
54370 + #include <linux/utime.h>
54371 + #include <linux/syscalls.h>
54372 ++#include <linux/grsecurity.h>
54373 + #include <asm/uaccess.h>
54374 + #include <asm/unistd.h>
54375 +
54376 +@@ -101,6 +102,12 @@ static int utimes_common(struct path *pa
54377 + goto mnt_drop_write_and_out;
54378 + }
54379 + }
54380 ++
54381 ++ if (!gr_acl_handle_utime(path->dentry, path->mnt)) {
54382 ++ error = -EACCES;
54383 ++ goto mnt_drop_write_and_out;
54384 ++ }
54385 ++
54386 + mutex_lock(&inode->i_mutex);
54387 + error = notify_change(path->dentry, &newattrs);
54388 + mutex_unlock(&inode->i_mutex);
54389 +diff -urNp linux-2.6.27.7/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.27.7/fs/xfs/linux-2.6/xfs_iops.c
54390 +--- linux-2.6.27.7/fs/xfs/linux-2.6/xfs_iops.c 2008-11-07 12:55:34.000000000 -0500
54391 ++++ linux-2.6.27.7/fs/xfs/linux-2.6/xfs_iops.c 2008-11-18 03:38:45.000000000 -0500
54392 +@@ -500,7 +500,7 @@ xfs_vn_put_link(
54393 + struct nameidata *nd,
54394 + void *p)
54395 + {
54396 +- char *s = nd_get_link(nd);
54397 ++ const char *s = nd_get_link(nd);
54398 +
54399 + if (!IS_ERR(s))
54400 + kfree(s);
54401 +diff -urNp linux-2.6.27.7/fs/xfs/xfs_bmap.c linux-2.6.27.7/fs/xfs/xfs_bmap.c
54402 +--- linux-2.6.27.7/fs/xfs/xfs_bmap.c 2008-11-07 12:55:34.000000000 -0500
54403 ++++ linux-2.6.27.7/fs/xfs/xfs_bmap.c 2008-11-18 03:38:45.000000000 -0500
54404 +@@ -360,7 +360,7 @@ xfs_bmap_validate_ret(
54405 + int nmap,
54406 + int ret_nmap);
54407 + #else
54408 +-#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
54409 ++#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
54410 + #endif /* DEBUG */
54411 +
54412 + #if defined(XFS_RW_TRACE)
54413 +diff -urNp linux-2.6.27.7/grsecurity/gracl_alloc.c linux-2.6.27.7/grsecurity/gracl_alloc.c
54414 +--- linux-2.6.27.7/grsecurity/gracl_alloc.c 1969-12-31 19:00:00.000000000 -0500
54415 ++++ linux-2.6.27.7/grsecurity/gracl_alloc.c 2008-11-18 03:38:45.000000000 -0500
54416 +@@ -0,0 +1,91 @@
54417 ++#include <linux/kernel.h>
54418 ++#include <linux/mm.h>
54419 ++#include <linux/slab.h>
54420 ++#include <linux/vmalloc.h>
54421 ++#include <linux/gracl.h>
54422 ++#include <linux/grsecurity.h>
54423 ++
54424 ++static unsigned long alloc_stack_next = 1;
54425 ++static unsigned long alloc_stack_size = 1;
54426 ++static void **alloc_stack;
54427 ++
54428 ++static __inline__ int
54429 ++alloc_pop(void)
54430 ++{
54431 ++ if (alloc_stack_next == 1)
54432 ++ return 0;
54433 ++
54434 ++ kfree(alloc_stack[alloc_stack_next - 2]);
54435 ++
54436 ++ alloc_stack_next--;
54437 ++
54438 ++ return 1;
54439 ++}
54440 ++
54441 ++static __inline__ void
54442 ++alloc_push(void *buf)
54443 ++{
54444 ++ if (alloc_stack_next >= alloc_stack_size)
54445 ++ BUG();
54446 ++
54447 ++ alloc_stack[alloc_stack_next - 1] = buf;
54448 ++
54449 ++ alloc_stack_next++;
54450 ++
54451 ++ return;
54452 ++}
54453 ++
54454 ++void *
54455 ++acl_alloc(unsigned long len)
54456 ++{
54457 ++ void *ret;
54458 ++
54459 ++ if (len > PAGE_SIZE)
54460 ++ BUG();
54461 ++
54462 ++ ret = kmalloc(len, GFP_KERNEL);
54463 ++
54464 ++ if (ret)
54465 ++ alloc_push(ret);
54466 ++
54467 ++ return ret;
54468 ++}
54469 ++
54470 ++void
54471 ++acl_free_all(void)
54472 ++{
54473 ++ if (gr_acl_is_enabled() || !alloc_stack)
54474 ++ return;
54475 ++
54476 ++ while (alloc_pop()) ;
54477 ++
54478 ++ if (alloc_stack) {
54479 ++ if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
54480 ++ kfree(alloc_stack);
54481 ++ else
54482 ++ vfree(alloc_stack);
54483 ++ }
54484 ++
54485 ++ alloc_stack = NULL;
54486 ++ alloc_stack_size = 1;
54487 ++ alloc_stack_next = 1;
54488 ++
54489 ++ return;
54490 ++}
54491 ++
54492 ++int
54493 ++acl_alloc_stack_init(unsigned long size)
54494 ++{
54495 ++ if ((size * sizeof (void *)) <= PAGE_SIZE)
54496 ++ alloc_stack =
54497 ++ (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
54498 ++ else
54499 ++ alloc_stack = (void **) vmalloc(size * sizeof (void *));
54500 ++
54501 ++ alloc_stack_size = size;
54502 ++
54503 ++ if (!alloc_stack)
54504 ++ return 0;
54505 ++ else
54506 ++ return 1;
54507 ++}
54508 +diff -urNp linux-2.6.27.7/grsecurity/gracl.c linux-2.6.27.7/grsecurity/gracl.c
54509 +--- linux-2.6.27.7/grsecurity/gracl.c 1969-12-31 19:00:00.000000000 -0500
54510 ++++ linux-2.6.27.7/grsecurity/gracl.c 2008-11-18 03:38:45.000000000 -0500
54511 +@@ -0,0 +1,3722 @@
54512 ++#include <linux/kernel.h>
54513 ++#include <linux/module.h>
54514 ++#include <linux/sched.h>
54515 ++#include <linux/mm.h>
54516 ++#include <linux/file.h>
54517 ++#include <linux/fs.h>
54518 ++#include <linux/namei.h>
54519 ++#include <linux/mount.h>
54520 ++#include <linux/tty.h>
54521 ++#include <linux/proc_fs.h>
54522 ++#include <linux/smp_lock.h>
54523 ++#include <linux/slab.h>
54524 ++#include <linux/vmalloc.h>
54525 ++#include <linux/types.h>
54526 ++#include <linux/sysctl.h>
54527 ++#include <linux/netdevice.h>
54528 ++#include <linux/ptrace.h>
54529 ++#include <linux/gracl.h>
54530 ++#include <linux/gralloc.h>
54531 ++#include <linux/grsecurity.h>
54532 ++#include <linux/grinternal.h>
54533 ++#include <linux/pid_namespace.h>
54534 ++#include <linux/fdtable.h>
54535 ++#include <linux/percpu.h>
54536 ++
54537 ++#include <asm/uaccess.h>
54538 ++#include <asm/errno.h>
54539 ++#include <asm/mman.h>
54540 ++
54541 ++static struct acl_role_db acl_role_set;
54542 ++static struct name_db name_set;
54543 ++static struct inodev_db inodev_set;
54544 ++
54545 ++/* for keeping track of userspace pointers used for subjects, so we
54546 ++ can share references in the kernel as well
54547 ++*/
54548 ++
54549 ++static struct dentry *real_root;
54550 ++static struct vfsmount *real_root_mnt;
54551 ++
54552 ++static struct acl_subj_map_db subj_map_set;
54553 ++
54554 ++static struct acl_role_label *default_role;
54555 ++
54556 ++static u16 acl_sp_role_value;
54557 ++
54558 ++extern char *gr_shared_page[4];
54559 ++static DECLARE_MUTEX(gr_dev_sem);
54560 ++DEFINE_RWLOCK(gr_inode_lock);
54561 ++
54562 ++struct gr_arg *gr_usermode;
54563 ++
54564 ++static unsigned int gr_status = GR_STATUS_INIT;
54565 ++
54566 ++extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
54567 ++extern void gr_clear_learn_entries(void);
54568 ++
54569 ++#ifdef CONFIG_GRKERNSEC_RESLOG
54570 ++extern void gr_log_resource(const struct task_struct *task,
54571 ++ const int res, const unsigned long wanted, const int gt);
54572 ++#endif
54573 ++
54574 ++unsigned char *gr_system_salt;
54575 ++unsigned char *gr_system_sum;
54576 ++
54577 ++static struct sprole_pw **acl_special_roles = NULL;
54578 ++static __u16 num_sprole_pws = 0;
54579 ++
54580 ++static struct acl_role_label *kernel_role = NULL;
54581 ++
54582 ++static unsigned int gr_auth_attempts = 0;
54583 ++static unsigned long gr_auth_expires = 0UL;
54584 ++
54585 ++extern struct vfsmount *sock_mnt;
54586 ++extern struct vfsmount *pipe_mnt;
54587 ++extern struct vfsmount *shm_mnt;
54588 ++static struct acl_object_label *fakefs_obj;
54589 ++
54590 ++extern int gr_init_uidset(void);
54591 ++extern void gr_free_uidset(void);
54592 ++extern void gr_remove_uid(uid_t uid);
54593 ++extern int gr_find_uid(uid_t uid);
54594 ++
54595 ++__inline__ int
54596 ++gr_acl_is_enabled(void)
54597 ++{
54598 ++ return (gr_status & GR_READY);
54599 ++}
54600 ++
54601 ++char gr_roletype_to_char(void)
54602 ++{
54603 ++ switch (current->role->roletype &
54604 ++ (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
54605 ++ GR_ROLE_SPECIAL)) {
54606 ++ case GR_ROLE_DEFAULT:
54607 ++ return 'D';
54608 ++ case GR_ROLE_USER:
54609 ++ return 'U';
54610 ++ case GR_ROLE_GROUP:
54611 ++ return 'G';
54612 ++ case GR_ROLE_SPECIAL:
54613 ++ return 'S';
54614 ++ }
54615 ++
54616 ++ return 'X';
54617 ++}
54618 ++
54619 ++__inline__ int
54620 ++gr_acl_tpe_check(void)
54621 ++{
54622 ++ if (unlikely(!(gr_status & GR_READY)))
54623 ++ return 0;
54624 ++ if (current->role->roletype & GR_ROLE_TPE)
54625 ++ return 1;
54626 ++ else
54627 ++ return 0;
54628 ++}
54629 ++
54630 ++int
54631 ++gr_handle_rawio(const struct inode *inode)
54632 ++{
54633 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
54634 ++ if (inode && S_ISBLK(inode->i_mode) &&
54635 ++ grsec_enable_chroot_caps && proc_is_chrooted(current) &&
54636 ++ !capable(CAP_SYS_RAWIO))
54637 ++ return 1;
54638 ++#endif
54639 ++ return 0;
54640 ++}
54641 ++
54642 ++static int
54643 ++gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
54644 ++{
54645 ++ int i;
54646 ++ unsigned long *l1;
54647 ++ unsigned long *l2;
54648 ++ unsigned char *c1;
54649 ++ unsigned char *c2;
54650 ++ int num_longs;
54651 ++
54652 ++ if (likely(lena != lenb))
54653 ++ return 0;
54654 ++
54655 ++ l1 = (unsigned long *)a;
54656 ++ l2 = (unsigned long *)b;
54657 ++
54658 ++ num_longs = lena / sizeof(unsigned long);
54659 ++
54660 ++ for (i = num_longs; i--; l1++, l2++) {
54661 ++ if (unlikely(*l1 != *l2))
54662 ++ return 0;
54663 ++ }
54664 ++
54665 ++ c1 = (unsigned char *) l1;
54666 ++ c2 = (unsigned char *) l2;
54667 ++
54668 ++ i = lena - (num_longs * sizeof(unsigned long));
54669 ++
54670 ++ for (; i--; c1++, c2++) {
54671 ++ if (unlikely(*c1 != *c2))
54672 ++ return 0;
54673 ++ }
54674 ++
54675 ++ return 1;
54676 ++}
54677 ++
54678 ++static char * __our_d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
54679 ++ struct dentry *root, struct vfsmount *rootmnt,
54680 ++ char *buffer, int buflen)
54681 ++{
54682 ++ char * end = buffer+buflen;
54683 ++ char * retval;
54684 ++ int namelen;
54685 ++
54686 ++ *--end = '\0';
54687 ++ buflen--;
54688 ++
54689 ++ if (buflen < 1)
54690 ++ goto Elong;
54691 ++ /* Get '/' right */
54692 ++ retval = end-1;
54693 ++ *retval = '/';
54694 ++
54695 ++ for (;;) {
54696 ++ struct dentry * parent;
54697 ++
54698 ++ if (dentry == root && vfsmnt == rootmnt)
54699 ++ break;
54700 ++ if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
54701 ++ /* Global root? */
54702 ++ spin_lock(&vfsmount_lock);
54703 ++ if (vfsmnt->mnt_parent == vfsmnt) {
54704 ++ spin_unlock(&vfsmount_lock);
54705 ++ goto global_root;
54706 ++ }
54707 ++ dentry = vfsmnt->mnt_mountpoint;
54708 ++ vfsmnt = vfsmnt->mnt_parent;
54709 ++ spin_unlock(&vfsmount_lock);
54710 ++ continue;
54711 ++ }
54712 ++ parent = dentry->d_parent;
54713 ++ prefetch(parent);
54714 ++ namelen = dentry->d_name.len;
54715 ++ buflen -= namelen + 1;
54716 ++ if (buflen < 0)
54717 ++ goto Elong;
54718 ++ end -= namelen;
54719 ++ memcpy(end, dentry->d_name.name, namelen);
54720 ++ *--end = '/';
54721 ++ retval = end;
54722 ++ dentry = parent;
54723 ++ }
54724 ++
54725 ++ return retval;
54726 ++
54727 ++global_root:
54728 ++ namelen = dentry->d_name.len;
54729 ++ buflen -= namelen;
54730 ++ if (buflen < 0)
54731 ++ goto Elong;
54732 ++ retval -= namelen-1; /* hit the slash */
54733 ++ memcpy(retval, dentry->d_name.name, namelen);
54734 ++ return retval;
54735 ++Elong:
54736 ++ return ERR_PTR(-ENAMETOOLONG);
54737 ++}
54738 ++
54739 ++static char *
54740 ++gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
54741 ++ struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
54742 ++{
54743 ++ char *retval;
54744 ++
54745 ++ retval = __our_d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
54746 ++ if (unlikely(IS_ERR(retval)))
54747 ++ retval = strcpy(buf, "<path too long>");
54748 ++ else if (unlikely(retval[1] == '/' && retval[2] == '\0'))
54749 ++ retval[1] = '\0';
54750 ++
54751 ++ return retval;
54752 ++}
54753 ++
54754 ++static char *
54755 ++__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
54756 ++ char *buf, int buflen)
54757 ++{
54758 ++ char *res;
54759 ++
54760 ++ /* we can use real_root, real_root_mnt, because this is only called
54761 ++ by the RBAC system */
54762 ++ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
54763 ++
54764 ++ return res;
54765 ++}
54766 ++
54767 ++static char *
54768 ++d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
54769 ++ char *buf, int buflen)
54770 ++{
54771 ++ char *res;
54772 ++ struct dentry *root;
54773 ++ struct vfsmount *rootmnt;
54774 ++ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
54775 ++
54776 ++ /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
54777 ++ read_lock(&reaper->fs->lock);
54778 ++ root = dget(reaper->fs->root.dentry);
54779 ++ rootmnt = mntget(reaper->fs->root.mnt);
54780 ++ read_unlock(&reaper->fs->lock);
54781 ++
54782 ++ spin_lock(&dcache_lock);
54783 ++ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
54784 ++ spin_unlock(&dcache_lock);
54785 ++
54786 ++ dput(root);
54787 ++ mntput(rootmnt);
54788 ++ return res;
54789 ++}
54790 ++
54791 ++static char *
54792 ++gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
54793 ++{
54794 ++ char *ret;
54795 ++ spin_lock(&dcache_lock);
54796 ++ ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
54797 ++ PAGE_SIZE);
54798 ++ spin_unlock(&dcache_lock);
54799 ++ return ret;
54800 ++}
54801 ++
54802 ++char *
54803 ++gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
54804 ++{
54805 ++ return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
54806 ++ PAGE_SIZE);
54807 ++}
54808 ++
54809 ++char *
54810 ++gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
54811 ++{
54812 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
54813 ++ PAGE_SIZE);
54814 ++}
54815 ++
54816 ++char *
54817 ++gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
54818 ++{
54819 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
54820 ++ PAGE_SIZE);
54821 ++}
54822 ++
54823 ++char *
54824 ++gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
54825 ++{
54826 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
54827 ++ PAGE_SIZE);
54828 ++}
54829 ++
54830 ++char *
54831 ++gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
54832 ++{
54833 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
54834 ++ PAGE_SIZE);
54835 ++}
54836 ++
54837 ++__inline__ __u32
54838 ++to_gr_audit(const __u32 reqmode)
54839 ++{
54840 ++ /* masks off auditable permission flags, then shifts them to create
54841 ++ auditing flags, and adds the special case of append auditing if
54842 ++ we're requesting write */
54843 ++ return (((reqmode & ~GR_AUDITS) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
54844 ++}
54845 ++
54846 ++struct acl_subject_label *
54847 ++lookup_subject_map(const struct acl_subject_label *userp)
54848 ++{
54849 ++ unsigned int index = shash(userp, subj_map_set.s_size);
54850 ++ struct subject_map *match;
54851 ++
54852 ++ match = subj_map_set.s_hash[index];
54853 ++
54854 ++ while (match && match->user != userp)
54855 ++ match = match->next;
54856 ++
54857 ++ if (match != NULL)
54858 ++ return match->kernel;
54859 ++ else
54860 ++ return NULL;
54861 ++}
54862 ++
54863 ++static void
54864 ++insert_subj_map_entry(struct subject_map *subjmap)
54865 ++{
54866 ++ unsigned int index = shash(subjmap->user, subj_map_set.s_size);
54867 ++ struct subject_map **curr;
54868 ++
54869 ++ subjmap->prev = NULL;
54870 ++
54871 ++ curr = &subj_map_set.s_hash[index];
54872 ++ if (*curr != NULL)
54873 ++ (*curr)->prev = subjmap;
54874 ++
54875 ++ subjmap->next = *curr;
54876 ++ *curr = subjmap;
54877 ++
54878 ++ return;
54879 ++}
54880 ++
54881 ++static struct acl_role_label *
54882 ++lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
54883 ++ const gid_t gid)
54884 ++{
54885 ++ unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
54886 ++ struct acl_role_label *match;
54887 ++ struct role_allowed_ip *ipp;
54888 ++ unsigned int x;
54889 ++
54890 ++ match = acl_role_set.r_hash[index];
54891 ++
54892 ++ while (match) {
54893 ++ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
54894 ++ for (x = 0; x < match->domain_child_num; x++) {
54895 ++ if (match->domain_children[x] == uid)
54896 ++ goto found;
54897 ++ }
54898 ++ } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
54899 ++ break;
54900 ++ match = match->next;
54901 ++ }
54902 ++found:
54903 ++ if (match == NULL) {
54904 ++ try_group:
54905 ++ index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
54906 ++ match = acl_role_set.r_hash[index];
54907 ++
54908 ++ while (match) {
54909 ++ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
54910 ++ for (x = 0; x < match->domain_child_num; x++) {
54911 ++ if (match->domain_children[x] == gid)
54912 ++ goto found2;
54913 ++ }
54914 ++ } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
54915 ++ break;
54916 ++ match = match->next;
54917 ++ }
54918 ++found2:
54919 ++ if (match == NULL)
54920 ++ match = default_role;
54921 ++ if (match->allowed_ips == NULL)
54922 ++ return match;
54923 ++ else {
54924 ++ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
54925 ++ if (likely
54926 ++ ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
54927 ++ (ntohl(ipp->addr) & ipp->netmask)))
54928 ++ return match;
54929 ++ }
54930 ++ match = default_role;
54931 ++ }
54932 ++ } else if (match->allowed_ips == NULL) {
54933 ++ return match;
54934 ++ } else {
54935 ++ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
54936 ++ if (likely
54937 ++ ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
54938 ++ (ntohl(ipp->addr) & ipp->netmask)))
54939 ++ return match;
54940 ++ }
54941 ++ goto try_group;
54942 ++ }
54943 ++
54944 ++ return match;
54945 ++}
54946 ++
54947 ++struct acl_subject_label *
54948 ++lookup_acl_subj_label(const ino_t ino, const dev_t dev,
54949 ++ const struct acl_role_label *role)
54950 ++{
54951 ++ unsigned int index = fhash(ino, dev, role->subj_hash_size);
54952 ++ struct acl_subject_label *match;
54953 ++
54954 ++ match = role->subj_hash[index];
54955 ++
54956 ++ while (match && (match->inode != ino || match->device != dev ||
54957 ++ (match->mode & GR_DELETED))) {
54958 ++ match = match->next;
54959 ++ }
54960 ++
54961 ++ if (match && !(match->mode & GR_DELETED))
54962 ++ return match;
54963 ++ else
54964 ++ return NULL;
54965 ++}
54966 ++
54967 ++static struct acl_object_label *
54968 ++lookup_acl_obj_label(const ino_t ino, const dev_t dev,
54969 ++ const struct acl_subject_label *subj)
54970 ++{
54971 ++ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
54972 ++ struct acl_object_label *match;
54973 ++
54974 ++ match = subj->obj_hash[index];
54975 ++
54976 ++ while (match && (match->inode != ino || match->device != dev ||
54977 ++ (match->mode & GR_DELETED))) {
54978 ++ match = match->next;
54979 ++ }
54980 ++
54981 ++ if (match && !(match->mode & GR_DELETED))
54982 ++ return match;
54983 ++ else
54984 ++ return NULL;
54985 ++}
54986 ++
54987 ++static struct acl_object_label *
54988 ++lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
54989 ++ const struct acl_subject_label *subj)
54990 ++{
54991 ++ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
54992 ++ struct acl_object_label *match;
54993 ++
54994 ++ match = subj->obj_hash[index];
54995 ++
54996 ++ while (match && (match->inode != ino || match->device != dev ||
54997 ++ !(match->mode & GR_DELETED))) {
54998 ++ match = match->next;
54999 ++ }
55000 ++
55001 ++ if (match && (match->mode & GR_DELETED))
55002 ++ return match;
55003 ++
55004 ++ match = subj->obj_hash[index];
55005 ++
55006 ++ while (match && (match->inode != ino || match->device != dev ||
55007 ++ (match->mode & GR_DELETED))) {
55008 ++ match = match->next;
55009 ++ }
55010 ++
55011 ++ if (match && !(match->mode & GR_DELETED))
55012 ++ return match;
55013 ++ else
55014 ++ return NULL;
55015 ++}
55016 ++
55017 ++static struct name_entry *
55018 ++lookup_name_entry(const char *name)
55019 ++{
55020 ++ unsigned int len = strlen(name);
55021 ++ unsigned int key = full_name_hash(name, len);
55022 ++ unsigned int index = key % name_set.n_size;
55023 ++ struct name_entry *match;
55024 ++
55025 ++ match = name_set.n_hash[index];
55026 ++
55027 ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
55028 ++ match = match->next;
55029 ++
55030 ++ return match;
55031 ++}
55032 ++
55033 ++static struct name_entry *
55034 ++lookup_name_entry_create(const char *name)
55035 ++{
55036 ++ unsigned int len = strlen(name);
55037 ++ unsigned int key = full_name_hash(name, len);
55038 ++ unsigned int index = key % name_set.n_size;
55039 ++ struct name_entry *match;
55040 ++
55041 ++ match = name_set.n_hash[index];
55042 ++
55043 ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
55044 ++ !match->deleted))
55045 ++ match = match->next;
55046 ++
55047 ++ if (match && match->deleted)
55048 ++ return match;
55049 ++
55050 ++ match = name_set.n_hash[index];
55051 ++
55052 ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
55053 ++ match->deleted))
55054 ++ match = match->next;
55055 ++
55056 ++ if (match && !match->deleted)
55057 ++ return match;
55058 ++ else
55059 ++ return NULL;
55060 ++}
55061 ++
55062 ++static struct inodev_entry *
55063 ++lookup_inodev_entry(const ino_t ino, const dev_t dev)
55064 ++{
55065 ++ unsigned int index = fhash(ino, dev, inodev_set.i_size);
55066 ++ struct inodev_entry *match;
55067 ++
55068 ++ match = inodev_set.i_hash[index];
55069 ++
55070 ++ while (match && (match->nentry->inode != ino || match->nentry->device != dev))
55071 ++ match = match->next;
55072 ++
55073 ++ return match;
55074 ++}
55075 ++
55076 ++static void
55077 ++insert_inodev_entry(struct inodev_entry *entry)
55078 ++{
55079 ++ unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
55080 ++ inodev_set.i_size);
55081 ++ struct inodev_entry **curr;
55082 ++
55083 ++ entry->prev = NULL;
55084 ++
55085 ++ curr = &inodev_set.i_hash[index];
55086 ++ if (*curr != NULL)
55087 ++ (*curr)->prev = entry;
55088 ++
55089 ++ entry->next = *curr;
55090 ++ *curr = entry;
55091 ++
55092 ++ return;
55093 ++}
55094 ++
55095 ++static void
55096 ++__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
55097 ++{
55098 ++ unsigned int index =
55099 ++ rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
55100 ++ struct acl_role_label **curr;
55101 ++
55102 ++ role->prev = NULL;
55103 ++
55104 ++ curr = &acl_role_set.r_hash[index];
55105 ++ if (*curr != NULL)
55106 ++ (*curr)->prev = role;
55107 ++
55108 ++ role->next = *curr;
55109 ++ *curr = role;
55110 ++
55111 ++ return;
55112 ++}
55113 ++
55114 ++static void
55115 ++insert_acl_role_label(struct acl_role_label *role)
55116 ++{
55117 ++ int i;
55118 ++
55119 ++ if (role->roletype & GR_ROLE_DOMAIN) {
55120 ++ for (i = 0; i < role->domain_child_num; i++)
55121 ++ __insert_acl_role_label(role, role->domain_children[i]);
55122 ++ } else
55123 ++ __insert_acl_role_label(role, role->uidgid);
55124 ++}
55125 ++
55126 ++static int
55127 ++insert_name_entry(char *name, const ino_t inode, const dev_t device, __u8 deleted)
55128 ++{
55129 ++ struct name_entry **curr, *nentry;
55130 ++ struct inodev_entry *ientry;
55131 ++ unsigned int len = strlen(name);
55132 ++ unsigned int key = full_name_hash(name, len);
55133 ++ unsigned int index = key % name_set.n_size;
55134 ++
55135 ++ curr = &name_set.n_hash[index];
55136 ++
55137 ++ while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
55138 ++ curr = &((*curr)->next);
55139 ++
55140 ++ if (*curr != NULL)
55141 ++ return 1;
55142 ++
55143 ++ nentry = acl_alloc(sizeof (struct name_entry));
55144 ++ if (nentry == NULL)
55145 ++ return 0;
55146 ++ ientry = acl_alloc(sizeof (struct inodev_entry));
55147 ++ if (ientry == NULL)
55148 ++ return 0;
55149 ++ ientry->nentry = nentry;
55150 ++
55151 ++ nentry->key = key;
55152 ++ nentry->name = name;
55153 ++ nentry->inode = inode;
55154 ++ nentry->device = device;
55155 ++ nentry->len = len;
55156 ++ nentry->deleted = deleted;
55157 ++
55158 ++ nentry->prev = NULL;
55159 ++ curr = &name_set.n_hash[index];
55160 ++ if (*curr != NULL)
55161 ++ (*curr)->prev = nentry;
55162 ++ nentry->next = *curr;
55163 ++ *curr = nentry;
55164 ++
55165 ++ /* insert us into the table searchable by inode/dev */
55166 ++ insert_inodev_entry(ientry);
55167 ++
55168 ++ return 1;
55169 ++}
55170 ++
55171 ++static void
55172 ++insert_acl_obj_label(struct acl_object_label *obj,
55173 ++ struct acl_subject_label *subj)
55174 ++{
55175 ++ unsigned int index =
55176 ++ fhash(obj->inode, obj->device, subj->obj_hash_size);
55177 ++ struct acl_object_label **curr;
55178 ++
55179 ++
55180 ++ obj->prev = NULL;
55181 ++
55182 ++ curr = &subj->obj_hash[index];
55183 ++ if (*curr != NULL)
55184 ++ (*curr)->prev = obj;
55185 ++
55186 ++ obj->next = *curr;
55187 ++ *curr = obj;
55188 ++
55189 ++ return;
55190 ++}
55191 ++
55192 ++static void
55193 ++insert_acl_subj_label(struct acl_subject_label *obj,
55194 ++ struct acl_role_label *role)
55195 ++{
55196 ++ unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
55197 ++ struct acl_subject_label **curr;
55198 ++
55199 ++ obj->prev = NULL;
55200 ++
55201 ++ curr = &role->subj_hash[index];
55202 ++ if (*curr != NULL)
55203 ++ (*curr)->prev = obj;
55204 ++
55205 ++ obj->next = *curr;
55206 ++ *curr = obj;
55207 ++
55208 ++ return;
55209 ++}
55210 ++
55211 ++/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
55212 ++
55213 ++static void *
55214 ++create_table(__u32 * len, int elementsize)
55215 ++{
55216 ++ unsigned int table_sizes[] = {
55217 ++ 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
55218 ++ 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
55219 ++ 4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
55220 ++ 268435399, 536870909, 1073741789, 2147483647
55221 ++ };
55222 ++ void *newtable = NULL;
55223 ++ unsigned int pwr = 0;
55224 ++
55225 ++ while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
55226 ++ table_sizes[pwr] <= *len)
55227 ++ pwr++;
55228 ++
55229 ++ if (table_sizes[pwr] <= *len)
55230 ++ return newtable;
55231 ++
55232 ++ if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
55233 ++ newtable =
55234 ++ kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
55235 ++ else
55236 ++ newtable = vmalloc(table_sizes[pwr] * elementsize);
55237 ++
55238 ++ *len = table_sizes[pwr];
55239 ++
55240 ++ return newtable;
55241 ++}
55242 ++
55243 ++static int
55244 ++init_variables(const struct gr_arg *arg)
55245 ++{
55246 ++ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
55247 ++ unsigned int stacksize;
55248 ++
55249 ++ subj_map_set.s_size = arg->role_db.num_subjects;
55250 ++ acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
55251 ++ name_set.n_size = arg->role_db.num_objects;
55252 ++ inodev_set.i_size = arg->role_db.num_objects;
55253 ++
55254 ++ if (!subj_map_set.s_size || !acl_role_set.r_size ||
55255 ++ !name_set.n_size || !inodev_set.i_size)
55256 ++ return 1;
55257 ++
55258 ++ if (!gr_init_uidset())
55259 ++ return 1;
55260 ++
55261 ++ /* set up the stack that holds allocation info */
55262 ++
55263 ++ stacksize = arg->role_db.num_pointers + 5;
55264 ++
55265 ++ if (!acl_alloc_stack_init(stacksize))
55266 ++ return 1;
55267 ++
55268 ++ /* grab reference for the real root dentry and vfsmount */
55269 ++ read_lock(&reaper->fs->lock);
55270 ++ real_root_mnt = mntget(reaper->fs->root.mnt);
55271 ++ real_root = dget(reaper->fs->root.dentry);
55272 ++ read_unlock(&reaper->fs->lock);
55273 ++
55274 ++ fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
55275 ++ if (fakefs_obj == NULL)
55276 ++ return 1;
55277 ++ fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
55278 ++
55279 ++ subj_map_set.s_hash =
55280 ++ (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
55281 ++ acl_role_set.r_hash =
55282 ++ (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
55283 ++ name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
55284 ++ inodev_set.i_hash =
55285 ++ (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
55286 ++
55287 ++ if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
55288 ++ !name_set.n_hash || !inodev_set.i_hash)
55289 ++ return 1;
55290 ++
55291 ++ memset(subj_map_set.s_hash, 0,
55292 ++ sizeof(struct subject_map *) * subj_map_set.s_size);
55293 ++ memset(acl_role_set.r_hash, 0,
55294 ++ sizeof (struct acl_role_label *) * acl_role_set.r_size);
55295 ++ memset(name_set.n_hash, 0,
55296 ++ sizeof (struct name_entry *) * name_set.n_size);
55297 ++ memset(inodev_set.i_hash, 0,
55298 ++ sizeof (struct inodev_entry *) * inodev_set.i_size);
55299 ++
55300 ++ return 0;
55301 ++}
55302 ++
55303 ++/* free information not needed after startup
55304 ++ currently contains user->kernel pointer mappings for subjects
55305 ++*/
55306 ++
55307 ++static void
55308 ++free_init_variables(void)
55309 ++{
55310 ++ __u32 i;
55311 ++
55312 ++ if (subj_map_set.s_hash) {
55313 ++ for (i = 0; i < subj_map_set.s_size; i++) {
55314 ++ if (subj_map_set.s_hash[i]) {
55315 ++ kfree(subj_map_set.s_hash[i]);
55316 ++ subj_map_set.s_hash[i] = NULL;
55317 ++ }
55318 ++ }
55319 ++
55320 ++ if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
55321 ++ PAGE_SIZE)
55322 ++ kfree(subj_map_set.s_hash);
55323 ++ else
55324 ++ vfree(subj_map_set.s_hash);
55325 ++ }
55326 ++
55327 ++ return;
55328 ++}
55329 ++
55330 ++static void
55331 ++free_variables(void)
55332 ++{
55333 ++ struct acl_subject_label *s;
55334 ++ struct acl_role_label *r;
55335 ++ struct task_struct *task, *task2;
55336 ++ unsigned int i, x;
55337 ++
55338 ++ gr_clear_learn_entries();
55339 ++
55340 ++ read_lock(&tasklist_lock);
55341 ++ do_each_thread(task2, task) {
55342 ++ task->acl_sp_role = 0;
55343 ++ task->acl_role_id = 0;
55344 ++ task->acl = NULL;
55345 ++ task->role = NULL;
55346 ++ } while_each_thread(task2, task);
55347 ++ read_unlock(&tasklist_lock);
55348 ++
55349 ++ /* release the reference to the real root dentry and vfsmount */
55350 ++ if (real_root)
55351 ++ dput(real_root);
55352 ++ real_root = NULL;
55353 ++ if (real_root_mnt)
55354 ++ mntput(real_root_mnt);
55355 ++ real_root_mnt = NULL;
55356 ++
55357 ++ /* free all object hash tables */
55358 ++
55359 ++ FOR_EACH_ROLE_START(r, i)
55360 ++ if (r->subj_hash == NULL)
55361 ++ break;
55362 ++ FOR_EACH_SUBJECT_START(r, s, x)
55363 ++ if (s->obj_hash == NULL)
55364 ++ break;
55365 ++ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
55366 ++ kfree(s->obj_hash);
55367 ++ else
55368 ++ vfree(s->obj_hash);
55369 ++ FOR_EACH_SUBJECT_END(s, x)
55370 ++ FOR_EACH_NESTED_SUBJECT_START(r, s)
55371 ++ if (s->obj_hash == NULL)
55372 ++ break;
55373 ++ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
55374 ++ kfree(s->obj_hash);
55375 ++ else
55376 ++ vfree(s->obj_hash);
55377 ++ FOR_EACH_NESTED_SUBJECT_END(s)
55378 ++ if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
55379 ++ kfree(r->subj_hash);
55380 ++ else
55381 ++ vfree(r->subj_hash);
55382 ++ r->subj_hash = NULL;
55383 ++ FOR_EACH_ROLE_END(r,i)
55384 ++
55385 ++ acl_free_all();
55386 ++
55387 ++ if (acl_role_set.r_hash) {
55388 ++ if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
55389 ++ PAGE_SIZE)
55390 ++ kfree(acl_role_set.r_hash);
55391 ++ else
55392 ++ vfree(acl_role_set.r_hash);
55393 ++ }
55394 ++ if (name_set.n_hash) {
55395 ++ if ((name_set.n_size * sizeof (struct name_entry *)) <=
55396 ++ PAGE_SIZE)
55397 ++ kfree(name_set.n_hash);
55398 ++ else
55399 ++ vfree(name_set.n_hash);
55400 ++ }
55401 ++
55402 ++ if (inodev_set.i_hash) {
55403 ++ if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
55404 ++ PAGE_SIZE)
55405 ++ kfree(inodev_set.i_hash);
55406 ++ else
55407 ++ vfree(inodev_set.i_hash);
55408 ++ }
55409 ++
55410 ++ gr_free_uidset();
55411 ++
55412 ++ memset(&name_set, 0, sizeof (struct name_db));
55413 ++ memset(&inodev_set, 0, sizeof (struct inodev_db));
55414 ++ memset(&acl_role_set, 0, sizeof (struct acl_role_db));
55415 ++ memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
55416 ++
55417 ++ default_role = NULL;
55418 ++
55419 ++ return;
55420 ++}
55421 ++
55422 ++static __u32
55423 ++count_user_objs(struct acl_object_label *userp)
55424 ++{
55425 ++ struct acl_object_label o_tmp;
55426 ++ __u32 num = 0;
55427 ++
55428 ++ while (userp) {
55429 ++ if (copy_from_user(&o_tmp, userp,
55430 ++ sizeof (struct acl_object_label)))
55431 ++ break;
55432 ++
55433 ++ userp = o_tmp.prev;
55434 ++ num++;
55435 ++ }
55436 ++
55437 ++ return num;
55438 ++}
55439 ++
55440 ++static struct acl_subject_label *
55441 ++do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
55442 ++
55443 ++static int
55444 ++copy_user_glob(struct acl_object_label *obj)
55445 ++{
55446 ++ struct acl_object_label *g_tmp, **guser;
55447 ++ unsigned int len;
55448 ++ char *tmp;
55449 ++
55450 ++ if (obj->globbed == NULL)
55451 ++ return 0;
55452 ++
55453 ++ guser = &obj->globbed;
55454 ++ while (*guser) {
55455 ++ g_tmp = (struct acl_object_label *)
55456 ++ acl_alloc(sizeof (struct acl_object_label));
55457 ++ if (g_tmp == NULL)
55458 ++ return -ENOMEM;
55459 ++
55460 ++ if (copy_from_user(g_tmp, *guser,
55461 ++ sizeof (struct acl_object_label)))
55462 ++ return -EFAULT;
55463 ++
55464 ++ len = strnlen_user(g_tmp->filename, PATH_MAX);
55465 ++
55466 ++ if (!len || len >= PATH_MAX)
55467 ++ return -EINVAL;
55468 ++
55469 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
55470 ++ return -ENOMEM;
55471 ++
55472 ++ if (copy_from_user(tmp, g_tmp->filename, len))
55473 ++ return -EFAULT;
55474 ++
55475 ++ g_tmp->filename = tmp;
55476 ++
55477 ++ *guser = g_tmp;
55478 ++ guser = &(g_tmp->next);
55479 ++ }
55480 ++
55481 ++ return 0;
55482 ++}
55483 ++
55484 ++static int
55485 ++copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
55486 ++ struct acl_role_label *role)
55487 ++{
55488 ++ struct acl_object_label *o_tmp;
55489 ++ unsigned int len;
55490 ++ int ret;
55491 ++ char *tmp;
55492 ++
55493 ++ while (userp) {
55494 ++ if ((o_tmp = (struct acl_object_label *)
55495 ++ acl_alloc(sizeof (struct acl_object_label))) == NULL)
55496 ++ return -ENOMEM;
55497 ++
55498 ++ if (copy_from_user(o_tmp, userp,
55499 ++ sizeof (struct acl_object_label)))
55500 ++ return -EFAULT;
55501 ++
55502 ++ userp = o_tmp->prev;
55503 ++
55504 ++ len = strnlen_user(o_tmp->filename, PATH_MAX);
55505 ++
55506 ++ if (!len || len >= PATH_MAX)
55507 ++ return -EINVAL;
55508 ++
55509 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
55510 ++ return -ENOMEM;
55511 ++
55512 ++ if (copy_from_user(tmp, o_tmp->filename, len))
55513 ++ return -EFAULT;
55514 ++
55515 ++ o_tmp->filename = tmp;
55516 ++
55517 ++ insert_acl_obj_label(o_tmp, subj);
55518 ++ if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
55519 ++ o_tmp->device, (o_tmp->mode & GR_DELETED) ? 1 : 0))
55520 ++ return -ENOMEM;
55521 ++
55522 ++ ret = copy_user_glob(o_tmp);
55523 ++ if (ret)
55524 ++ return ret;
55525 ++
55526 ++ if (o_tmp->nested) {
55527 ++ o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
55528 ++ if (IS_ERR(o_tmp->nested))
55529 ++ return PTR_ERR(o_tmp->nested);
55530 ++
55531 ++ /* insert into nested subject list */
55532 ++ o_tmp->nested->next = role->hash->first;
55533 ++ role->hash->first = o_tmp->nested;
55534 ++ }
55535 ++ }
55536 ++
55537 ++ return 0;
55538 ++}
55539 ++
55540 ++static __u32
55541 ++count_user_subjs(struct acl_subject_label *userp)
55542 ++{
55543 ++ struct acl_subject_label s_tmp;
55544 ++ __u32 num = 0;
55545 ++
55546 ++ while (userp) {
55547 ++ if (copy_from_user(&s_tmp, userp,
55548 ++ sizeof (struct acl_subject_label)))
55549 ++ break;
55550 ++
55551 ++ userp = s_tmp.prev;
55552 ++ /* do not count nested subjects against this count, since
55553 ++ they are not included in the hash table, but are
55554 ++ attached to objects. We have already counted
55555 ++ the subjects in userspace for the allocation
55556 ++ stack
55557 ++ */
55558 ++ if (!(s_tmp.mode & GR_NESTED))
55559 ++ num++;
55560 ++ }
55561 ++
55562 ++ return num;
55563 ++}
55564 ++
55565 ++static int
55566 ++copy_user_allowedips(struct acl_role_label *rolep)
55567 ++{
55568 ++ struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
55569 ++
55570 ++ ruserip = rolep->allowed_ips;
55571 ++
55572 ++ while (ruserip) {
55573 ++ rlast = rtmp;
55574 ++
55575 ++ if ((rtmp = (struct role_allowed_ip *)
55576 ++ acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
55577 ++ return -ENOMEM;
55578 ++
55579 ++ if (copy_from_user(rtmp, ruserip,
55580 ++ sizeof (struct role_allowed_ip)))
55581 ++ return -EFAULT;
55582 ++
55583 ++ ruserip = rtmp->prev;
55584 ++
55585 ++ if (!rlast) {
55586 ++ rtmp->prev = NULL;
55587 ++ rolep->allowed_ips = rtmp;
55588 ++ } else {
55589 ++ rlast->next = rtmp;
55590 ++ rtmp->prev = rlast;
55591 ++ }
55592 ++
55593 ++ if (!ruserip)
55594 ++ rtmp->next = NULL;
55595 ++ }
55596 ++
55597 ++ return 0;
55598 ++}
55599 ++
55600 ++static int
55601 ++copy_user_transitions(struct acl_role_label *rolep)
55602 ++{
55603 ++ struct role_transition *rusertp, *rtmp = NULL, *rlast;
55604 ++
55605 ++ unsigned int len;
55606 ++ char *tmp;
55607 ++
55608 ++ rusertp = rolep->transitions;
55609 ++
55610 ++ while (rusertp) {
55611 ++ rlast = rtmp;
55612 ++
55613 ++ if ((rtmp = (struct role_transition *)
55614 ++ acl_alloc(sizeof (struct role_transition))) == NULL)
55615 ++ return -ENOMEM;
55616 ++
55617 ++ if (copy_from_user(rtmp, rusertp,
55618 ++ sizeof (struct role_transition)))
55619 ++ return -EFAULT;
55620 ++
55621 ++ rusertp = rtmp->prev;
55622 ++
55623 ++ len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
55624 ++
55625 ++ if (!len || len >= GR_SPROLE_LEN)
55626 ++ return -EINVAL;
55627 ++
55628 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
55629 ++ return -ENOMEM;
55630 ++
55631 ++ if (copy_from_user(tmp, rtmp->rolename, len))
55632 ++ return -EFAULT;
55633 ++
55634 ++ rtmp->rolename = tmp;
55635 ++
55636 ++ if (!rlast) {
55637 ++ rtmp->prev = NULL;
55638 ++ rolep->transitions = rtmp;
55639 ++ } else {
55640 ++ rlast->next = rtmp;
55641 ++ rtmp->prev = rlast;
55642 ++ }
55643 ++
55644 ++ if (!rusertp)
55645 ++ rtmp->next = NULL;
55646 ++ }
55647 ++
55648 ++ return 0;
55649 ++}
55650 ++
55651 ++static struct acl_subject_label *
55652 ++do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
55653 ++{
55654 ++ struct acl_subject_label *s_tmp = NULL, *s_tmp2;
55655 ++ unsigned int len;
55656 ++ char *tmp;
55657 ++ __u32 num_objs;
55658 ++ struct acl_ip_label **i_tmp, *i_utmp2;
55659 ++ struct gr_hash_struct ghash;
55660 ++ struct subject_map *subjmap;
55661 ++ unsigned int i_num;
55662 ++ int err;
55663 ++
55664 ++ s_tmp = lookup_subject_map(userp);
55665 ++
55666 ++ /* we've already copied this subject into the kernel, just return
55667 ++ the reference to it, and don't copy it over again
55668 ++ */
55669 ++ if (s_tmp)
55670 ++ return(s_tmp);
55671 ++
55672 ++ if ((s_tmp = (struct acl_subject_label *)
55673 ++ acl_alloc(sizeof (struct acl_subject_label))) == NULL)
55674 ++ return ERR_PTR(-ENOMEM);
55675 ++
55676 ++ subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
55677 ++ if (subjmap == NULL)
55678 ++ return ERR_PTR(-ENOMEM);
55679 ++
55680 ++ subjmap->user = userp;
55681 ++ subjmap->kernel = s_tmp;
55682 ++ insert_subj_map_entry(subjmap);
55683 ++
55684 ++ if (copy_from_user(s_tmp, userp,
55685 ++ sizeof (struct acl_subject_label)))
55686 ++ return ERR_PTR(-EFAULT);
55687 ++
55688 ++ len = strnlen_user(s_tmp->filename, PATH_MAX);
55689 ++
55690 ++ if (!len || len >= PATH_MAX)
55691 ++ return ERR_PTR(-EINVAL);
55692 ++
55693 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
55694 ++ return ERR_PTR(-ENOMEM);
55695 ++
55696 ++ if (copy_from_user(tmp, s_tmp->filename, len))
55697 ++ return ERR_PTR(-EFAULT);
55698 ++
55699 ++ s_tmp->filename = tmp;
55700 ++
55701 ++ if (!strcmp(s_tmp->filename, "/"))
55702 ++ role->root_label = s_tmp;
55703 ++
55704 ++ if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
55705 ++ return ERR_PTR(-EFAULT);
55706 ++
55707 ++ /* copy user and group transition tables */
55708 ++
55709 ++ if (s_tmp->user_trans_num) {
55710 ++ uid_t *uidlist;
55711 ++
55712 ++ uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
55713 ++ if (uidlist == NULL)
55714 ++ return ERR_PTR(-ENOMEM);
55715 ++ if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
55716 ++ return ERR_PTR(-EFAULT);
55717 ++
55718 ++ s_tmp->user_transitions = uidlist;
55719 ++ }
55720 ++
55721 ++ if (s_tmp->group_trans_num) {
55722 ++ gid_t *gidlist;
55723 ++
55724 ++ gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
55725 ++ if (gidlist == NULL)
55726 ++ return ERR_PTR(-ENOMEM);
55727 ++ if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
55728 ++ return ERR_PTR(-EFAULT);
55729 ++
55730 ++ s_tmp->group_transitions = gidlist;
55731 ++ }
55732 ++
55733 ++ /* set up object hash table */
55734 ++ num_objs = count_user_objs(ghash.first);
55735 ++
55736 ++ s_tmp->obj_hash_size = num_objs;
55737 ++ s_tmp->obj_hash =
55738 ++ (struct acl_object_label **)
55739 ++ create_table(&(s_tmp->obj_hash_size), sizeof(void *));
55740 ++
55741 ++ if (!s_tmp->obj_hash)
55742 ++ return ERR_PTR(-ENOMEM);
55743 ++
55744 ++ memset(s_tmp->obj_hash, 0,
55745 ++ s_tmp->obj_hash_size *
55746 ++ sizeof (struct acl_object_label *));
55747 ++
55748 ++ /* add in objects */
55749 ++ err = copy_user_objs(ghash.first, s_tmp, role);
55750 ++
55751 ++ if (err)
55752 ++ return ERR_PTR(err);
55753 ++
55754 ++ /* set pointer for parent subject */
55755 ++ if (s_tmp->parent_subject) {
55756 ++ s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
55757 ++
55758 ++ if (IS_ERR(s_tmp2))
55759 ++ return s_tmp2;
55760 ++
55761 ++ s_tmp->parent_subject = s_tmp2;
55762 ++ }
55763 ++
55764 ++ /* add in ip acls */
55765 ++
55766 ++ if (!s_tmp->ip_num) {
55767 ++ s_tmp->ips = NULL;
55768 ++ goto insert;
55769 ++ }
55770 ++
55771 ++ i_tmp =
55772 ++ (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
55773 ++ sizeof (struct
55774 ++ acl_ip_label *));
55775 ++
55776 ++ if (!i_tmp)
55777 ++ return ERR_PTR(-ENOMEM);
55778 ++
55779 ++ for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
55780 ++ *(i_tmp + i_num) =
55781 ++ (struct acl_ip_label *)
55782 ++ acl_alloc(sizeof (struct acl_ip_label));
55783 ++ if (!*(i_tmp + i_num))
55784 ++ return ERR_PTR(-ENOMEM);
55785 ++
55786 ++ if (copy_from_user
55787 ++ (&i_utmp2, s_tmp->ips + i_num,
55788 ++ sizeof (struct acl_ip_label *)))
55789 ++ return ERR_PTR(-EFAULT);
55790 ++
55791 ++ if (copy_from_user
55792 ++ (*(i_tmp + i_num), i_utmp2,
55793 ++ sizeof (struct acl_ip_label)))
55794 ++ return ERR_PTR(-EFAULT);
55795 ++
55796 ++ if ((*(i_tmp + i_num))->iface == NULL)
55797 ++ continue;
55798 ++
55799 ++ len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
55800 ++ if (!len || len >= IFNAMSIZ)
55801 ++ return ERR_PTR(-EINVAL);
55802 ++ tmp = acl_alloc(len);
55803 ++ if (tmp == NULL)
55804 ++ return ERR_PTR(-ENOMEM);
55805 ++ if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
55806 ++ return ERR_PTR(-EFAULT);
55807 ++ (*(i_tmp + i_num))->iface = tmp;
55808 ++ }
55809 ++
55810 ++ s_tmp->ips = i_tmp;
55811 ++
55812 ++insert:
55813 ++ if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
55814 ++ s_tmp->device, (s_tmp->mode & GR_DELETED) ? 1 : 0))
55815 ++ return ERR_PTR(-ENOMEM);
55816 ++
55817 ++ return s_tmp;
55818 ++}
55819 ++
55820 ++static int
55821 ++copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
55822 ++{
55823 ++ struct acl_subject_label s_pre;
55824 ++ struct acl_subject_label * ret;
55825 ++ int err;
55826 ++
55827 ++ while (userp) {
55828 ++ if (copy_from_user(&s_pre, userp,
55829 ++ sizeof (struct acl_subject_label)))
55830 ++ return -EFAULT;
55831 ++
55832 ++ /* do not add nested subjects here, add
55833 ++ while parsing objects
55834 ++ */
55835 ++
55836 ++ if (s_pre.mode & GR_NESTED) {
55837 ++ userp = s_pre.prev;
55838 ++ continue;
55839 ++ }
55840 ++
55841 ++ ret = do_copy_user_subj(userp, role);
55842 ++
55843 ++ err = PTR_ERR(ret);
55844 ++ if (IS_ERR(ret))
55845 ++ return err;
55846 ++
55847 ++ insert_acl_subj_label(ret, role);
55848 ++
55849 ++ userp = s_pre.prev;
55850 ++ }
55851 ++
55852 ++ return 0;
55853 ++}
55854 ++
55855 ++static int
55856 ++copy_user_acl(struct gr_arg *arg)
55857 ++{
55858 ++ struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
55859 ++ struct sprole_pw *sptmp;
55860 ++ struct gr_hash_struct *ghash;
55861 ++ uid_t *domainlist;
55862 ++ unsigned int r_num;
55863 ++ unsigned int len;
55864 ++ char *tmp;
55865 ++ int err = 0;
55866 ++ __u16 i;
55867 ++ __u32 num_subjs;
55868 ++
55869 ++ /* we need a default and kernel role */
55870 ++ if (arg->role_db.num_roles < 2)
55871 ++ return -EINVAL;
55872 ++
55873 ++ /* copy special role authentication info from userspace */
55874 ++
55875 ++ num_sprole_pws = arg->num_sprole_pws;
55876 ++ acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
55877 ++
55878 ++ if (!acl_special_roles) {
55879 ++ err = -ENOMEM;
55880 ++ goto cleanup;
55881 ++ }
55882 ++
55883 ++ for (i = 0; i < num_sprole_pws; i++) {
55884 ++ sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
55885 ++ if (!sptmp) {
55886 ++ err = -ENOMEM;
55887 ++ goto cleanup;
55888 ++ }
55889 ++ if (copy_from_user(sptmp, arg->sprole_pws + i,
55890 ++ sizeof (struct sprole_pw))) {
55891 ++ err = -EFAULT;
55892 ++ goto cleanup;
55893 ++ }
55894 ++
55895 ++ len =
55896 ++ strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
55897 ++
55898 ++ if (!len || len >= GR_SPROLE_LEN) {
55899 ++ err = -EINVAL;
55900 ++ goto cleanup;
55901 ++ }
55902 ++
55903 ++ if ((tmp = (char *) acl_alloc(len)) == NULL) {
55904 ++ err = -ENOMEM;
55905 ++ goto cleanup;
55906 ++ }
55907 ++
55908 ++ if (copy_from_user(tmp, sptmp->rolename, len)) {
55909 ++ err = -EFAULT;
55910 ++ goto cleanup;
55911 ++ }
55912 ++
55913 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
55914 ++ printk(KERN_ALERT "Copying special role %s\n", tmp);
55915 ++#endif
55916 ++ sptmp->rolename = tmp;
55917 ++ acl_special_roles[i] = sptmp;
55918 ++ }
55919 ++
55920 ++ r_utmp = (struct acl_role_label **) arg->role_db.r_table;
55921 ++
55922 ++ for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
55923 ++ r_tmp = acl_alloc(sizeof (struct acl_role_label));
55924 ++
55925 ++ if (!r_tmp) {
55926 ++ err = -ENOMEM;
55927 ++ goto cleanup;
55928 ++ }
55929 ++
55930 ++ if (copy_from_user(&r_utmp2, r_utmp + r_num,
55931 ++ sizeof (struct acl_role_label *))) {
55932 ++ err = -EFAULT;
55933 ++ goto cleanup;
55934 ++ }
55935 ++
55936 ++ if (copy_from_user(r_tmp, r_utmp2,
55937 ++ sizeof (struct acl_role_label))) {
55938 ++ err = -EFAULT;
55939 ++ goto cleanup;
55940 ++ }
55941 ++
55942 ++ len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
55943 ++
55944 ++ if (!len || len >= PATH_MAX) {
55945 ++ err = -EINVAL;
55946 ++ goto cleanup;
55947 ++ }
55948 ++
55949 ++ if ((tmp = (char *) acl_alloc(len)) == NULL) {
55950 ++ err = -ENOMEM;
55951 ++ goto cleanup;
55952 ++ }
55953 ++ if (copy_from_user(tmp, r_tmp->rolename, len)) {
55954 ++ err = -EFAULT;
55955 ++ goto cleanup;
55956 ++ }
55957 ++ r_tmp->rolename = tmp;
55958 ++
55959 ++ if (!strcmp(r_tmp->rolename, "default")
55960 ++ && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
55961 ++ default_role = r_tmp;
55962 ++ } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
55963 ++ kernel_role = r_tmp;
55964 ++ }
55965 ++
55966 ++ if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
55967 ++ err = -ENOMEM;
55968 ++ goto cleanup;
55969 ++ }
55970 ++ if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
55971 ++ err = -EFAULT;
55972 ++ goto cleanup;
55973 ++ }
55974 ++
55975 ++ r_tmp->hash = ghash;
55976 ++
55977 ++ num_subjs = count_user_subjs(r_tmp->hash->first);
55978 ++
55979 ++ r_tmp->subj_hash_size = num_subjs;
55980 ++ r_tmp->subj_hash =
55981 ++ (struct acl_subject_label **)
55982 ++ create_table(&(r_tmp->subj_hash_size), sizeof(void *));
55983 ++
55984 ++ if (!r_tmp->subj_hash) {
55985 ++ err = -ENOMEM;
55986 ++ goto cleanup;
55987 ++ }
55988 ++
55989 ++ err = copy_user_allowedips(r_tmp);
55990 ++ if (err)
55991 ++ goto cleanup;
55992 ++
55993 ++ /* copy domain info */
55994 ++ if (r_tmp->domain_children != NULL) {
55995 ++ domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
55996 ++ if (domainlist == NULL) {
55997 ++ err = -ENOMEM;
55998 ++ goto cleanup;
55999 ++ }
56000 ++ if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
56001 ++ err = -EFAULT;
56002 ++ goto cleanup;
56003 ++ }
56004 ++ r_tmp->domain_children = domainlist;
56005 ++ }
56006 ++
56007 ++ err = copy_user_transitions(r_tmp);
56008 ++ if (err)
56009 ++ goto cleanup;
56010 ++
56011 ++ memset(r_tmp->subj_hash, 0,
56012 ++ r_tmp->subj_hash_size *
56013 ++ sizeof (struct acl_subject_label *));
56014 ++
56015 ++ err = copy_user_subjs(r_tmp->hash->first, r_tmp);
56016 ++
56017 ++ if (err)
56018 ++ goto cleanup;
56019 ++
56020 ++ /* set nested subject list to null */
56021 ++ r_tmp->hash->first = NULL;
56022 ++
56023 ++ insert_acl_role_label(r_tmp);
56024 ++ }
56025 ++
56026 ++ goto return_err;
56027 ++ cleanup:
56028 ++ free_variables();
56029 ++ return_err:
56030 ++ return err;
56031 ++
56032 ++}
56033 ++
56034 ++static int
56035 ++gracl_init(struct gr_arg *args)
56036 ++{
56037 ++ int error = 0;
56038 ++
56039 ++ memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
56040 ++ memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
56041 ++
56042 ++ if (init_variables(args)) {
56043 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
56044 ++ error = -ENOMEM;
56045 ++ free_variables();
56046 ++ goto out;
56047 ++ }
56048 ++
56049 ++ error = copy_user_acl(args);
56050 ++ free_init_variables();
56051 ++ if (error) {
56052 ++ free_variables();
56053 ++ goto out;
56054 ++ }
56055 ++
56056 ++ if ((error = gr_set_acls(0))) {
56057 ++ free_variables();
56058 ++ goto out;
56059 ++ }
56060 ++
56061 ++ gr_status |= GR_READY;
56062 ++ out:
56063 ++ return error;
56064 ++}
56065 ++
56066 ++/* derived from glibc fnmatch() 0: match, 1: no match*/
56067 ++
56068 ++static int
56069 ++glob_match(const char *p, const char *n)
56070 ++{
56071 ++ char c;
56072 ++
56073 ++ while ((c = *p++) != '\0') {
56074 ++ switch (c) {
56075 ++ case '?':
56076 ++ if (*n == '\0')
56077 ++ return 1;
56078 ++ else if (*n == '/')
56079 ++ return 1;
56080 ++ break;
56081 ++ case '\\':
56082 ++ if (*n != c)
56083 ++ return 1;
56084 ++ break;
56085 ++ case '*':
56086 ++ for (c = *p++; c == '?' || c == '*'; c = *p++) {
56087 ++ if (*n == '/')
56088 ++ return 1;
56089 ++ else if (c == '?') {
56090 ++ if (*n == '\0')
56091 ++ return 1;
56092 ++ else
56093 ++ ++n;
56094 ++ }
56095 ++ }
56096 ++ if (c == '\0') {
56097 ++ return 0;
56098 ++ } else {
56099 ++ const char *endp;
56100 ++
56101 ++ if ((endp = strchr(n, '/')) == NULL)
56102 ++ endp = n + strlen(n);
56103 ++
56104 ++ if (c == '[') {
56105 ++ for (--p; n < endp; ++n)
56106 ++ if (!glob_match(p, n))
56107 ++ return 0;
56108 ++ } else if (c == '/') {
56109 ++ while (*n != '\0' && *n != '/')
56110 ++ ++n;
56111 ++ if (*n == '/' && !glob_match(p, n + 1))
56112 ++ return 0;
56113 ++ } else {
56114 ++ for (--p; n < endp; ++n)
56115 ++ if (*n == c && !glob_match(p, n))
56116 ++ return 0;
56117 ++ }
56118 ++
56119 ++ return 1;
56120 ++ }
56121 ++ case '[':
56122 ++ {
56123 ++ int not;
56124 ++ char cold;
56125 ++
56126 ++ if (*n == '\0' || *n == '/')
56127 ++ return 1;
56128 ++
56129 ++ not = (*p == '!' || *p == '^');
56130 ++ if (not)
56131 ++ ++p;
56132 ++
56133 ++ c = *p++;
56134 ++ for (;;) {
56135 ++ unsigned char fn = (unsigned char)*n;
56136 ++
56137 ++ if (c == '\0')
56138 ++ return 1;
56139 ++ else {
56140 ++ if (c == fn)
56141 ++ goto matched;
56142 ++ cold = c;
56143 ++ c = *p++;
56144 ++
56145 ++ if (c == '-' && *p != ']') {
56146 ++ unsigned char cend = *p++;
56147 ++
56148 ++ if (cend == '\0')
56149 ++ return 1;
56150 ++
56151 ++ if (cold <= fn && fn <= cend)
56152 ++ goto matched;
56153 ++
56154 ++ c = *p++;
56155 ++ }
56156 ++ }
56157 ++
56158 ++ if (c == ']')
56159 ++ break;
56160 ++ }
56161 ++ if (!not)
56162 ++ return 1;
56163 ++ break;
56164 ++ matched:
56165 ++ while (c != ']') {
56166 ++ if (c == '\0')
56167 ++ return 1;
56168 ++
56169 ++ c = *p++;
56170 ++ }
56171 ++ if (not)
56172 ++ return 1;
56173 ++ }
56174 ++ break;
56175 ++ default:
56176 ++ if (c != *n)
56177 ++ return 1;
56178 ++ }
56179 ++
56180 ++ ++n;
56181 ++ }
56182 ++
56183 ++ if (*n == '\0')
56184 ++ return 0;
56185 ++
56186 ++ if (*n == '/')
56187 ++ return 0;
56188 ++
56189 ++ return 1;
56190 ++}
56191 ++
56192 ++static struct acl_object_label *
56193 ++chk_glob_label(struct acl_object_label *globbed,
56194 ++ struct dentry *dentry, struct vfsmount *mnt, char **path)
56195 ++{
56196 ++ struct acl_object_label *tmp;
56197 ++
56198 ++ if (*path == NULL)
56199 ++ *path = gr_to_filename_nolock(dentry, mnt);
56200 ++
56201 ++ tmp = globbed;
56202 ++
56203 ++ while (tmp) {
56204 ++ if (!glob_match(tmp->filename, *path))
56205 ++ return tmp;
56206 ++ tmp = tmp->next;
56207 ++ }
56208 ++
56209 ++ return NULL;
56210 ++}
56211 ++
56212 ++static struct acl_object_label *
56213 ++__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
56214 ++ const ino_t curr_ino, const dev_t curr_dev,
56215 ++ const struct acl_subject_label *subj, char **path)
56216 ++{
56217 ++ struct acl_subject_label *tmpsubj;
56218 ++ struct acl_object_label *retval;
56219 ++ struct acl_object_label *retval2;
56220 ++
56221 ++ tmpsubj = (struct acl_subject_label *) subj;
56222 ++ read_lock(&gr_inode_lock);
56223 ++ do {
56224 ++ retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
56225 ++ if (retval) {
56226 ++ if (retval->globbed) {
56227 ++ retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
56228 ++ (struct vfsmount *)orig_mnt, path);
56229 ++ if (retval2)
56230 ++ retval = retval2;
56231 ++ }
56232 ++ break;
56233 ++ }
56234 ++ } while ((tmpsubj = tmpsubj->parent_subject));
56235 ++ read_unlock(&gr_inode_lock);
56236 ++
56237 ++ return retval;
56238 ++}
56239 ++
56240 ++static __inline__ struct acl_object_label *
56241 ++full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
56242 ++ const struct dentry *curr_dentry,
56243 ++ const struct acl_subject_label *subj, char **path)
56244 ++{
56245 ++ return __full_lookup(orig_dentry, orig_mnt,
56246 ++ curr_dentry->d_inode->i_ino,
56247 ++ curr_dentry->d_inode->i_sb->s_dev, subj, path);
56248 ++}
56249 ++
56250 ++static struct acl_object_label *
56251 ++__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
56252 ++ const struct acl_subject_label *subj, char *path)
56253 ++{
56254 ++ struct dentry *dentry = (struct dentry *) l_dentry;
56255 ++ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
56256 ++ struct acl_object_label *retval;
56257 ++
56258 ++ spin_lock(&dcache_lock);
56259 ++
56260 ++ if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt ||
56261 ++ /* ignore Eric Biederman */
56262 ++ IS_PRIVATE(l_dentry->d_inode))) {
56263 ++ retval = fakefs_obj;
56264 ++ goto out;
56265 ++ }
56266 ++
56267 ++ for (;;) {
56268 ++ if (dentry == real_root && mnt == real_root_mnt)
56269 ++ break;
56270 ++
56271 ++ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
56272 ++ if (mnt->mnt_parent == mnt)
56273 ++ break;
56274 ++
56275 ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
56276 ++ if (retval != NULL)
56277 ++ goto out;
56278 ++
56279 ++ dentry = mnt->mnt_mountpoint;
56280 ++ mnt = mnt->mnt_parent;
56281 ++ continue;
56282 ++ }
56283 ++
56284 ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
56285 ++ if (retval != NULL)
56286 ++ goto out;
56287 ++
56288 ++ dentry = dentry->d_parent;
56289 ++ }
56290 ++
56291 ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
56292 ++
56293 ++ if (retval == NULL)
56294 ++ retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
56295 ++out:
56296 ++ spin_unlock(&dcache_lock);
56297 ++ return retval;
56298 ++}
56299 ++
56300 ++static __inline__ struct acl_object_label *
56301 ++chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
56302 ++ const struct acl_subject_label *subj)
56303 ++{
56304 ++ char *path = NULL;
56305 ++ return __chk_obj_label(l_dentry, l_mnt, subj, path);
56306 ++}
56307 ++
56308 ++static __inline__ struct acl_object_label *
56309 ++chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
56310 ++ const struct acl_subject_label *subj, char *path)
56311 ++{
56312 ++ return __chk_obj_label(l_dentry, l_mnt, subj, path);
56313 ++}
56314 ++
56315 ++static struct acl_subject_label *
56316 ++chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
56317 ++ const struct acl_role_label *role)
56318 ++{
56319 ++ struct dentry *dentry = (struct dentry *) l_dentry;
56320 ++ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
56321 ++ struct acl_subject_label *retval;
56322 ++
56323 ++ spin_lock(&dcache_lock);
56324 ++
56325 ++ for (;;) {
56326 ++ if (dentry == real_root && mnt == real_root_mnt)
56327 ++ break;
56328 ++ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
56329 ++ if (mnt->mnt_parent == mnt)
56330 ++ break;
56331 ++
56332 ++ read_lock(&gr_inode_lock);
56333 ++ retval =
56334 ++ lookup_acl_subj_label(dentry->d_inode->i_ino,
56335 ++ dentry->d_inode->i_sb->s_dev, role);
56336 ++ read_unlock(&gr_inode_lock);
56337 ++ if (retval != NULL)
56338 ++ goto out;
56339 ++
56340 ++ dentry = mnt->mnt_mountpoint;
56341 ++ mnt = mnt->mnt_parent;
56342 ++ continue;
56343 ++ }
56344 ++
56345 ++ read_lock(&gr_inode_lock);
56346 ++ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
56347 ++ dentry->d_inode->i_sb->s_dev, role);
56348 ++ read_unlock(&gr_inode_lock);
56349 ++ if (retval != NULL)
56350 ++ goto out;
56351 ++
56352 ++ dentry = dentry->d_parent;
56353 ++ }
56354 ++
56355 ++ read_lock(&gr_inode_lock);
56356 ++ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
56357 ++ dentry->d_inode->i_sb->s_dev, role);
56358 ++ read_unlock(&gr_inode_lock);
56359 ++
56360 ++ if (unlikely(retval == NULL)) {
56361 ++ read_lock(&gr_inode_lock);
56362 ++ retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
56363 ++ real_root->d_inode->i_sb->s_dev, role);
56364 ++ read_unlock(&gr_inode_lock);
56365 ++ }
56366 ++out:
56367 ++ spin_unlock(&dcache_lock);
56368 ++
56369 ++ return retval;
56370 ++}
56371 ++
56372 ++static void
56373 ++gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
56374 ++{
56375 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
56376 ++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
56377 ++ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
56378 ++ 1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
56379 ++
56380 ++ return;
56381 ++}
56382 ++
56383 ++static void
56384 ++gr_log_learn_sysctl(const struct task_struct *task, const char *path, const __u32 mode)
56385 ++{
56386 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
56387 ++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
56388 ++ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
56389 ++ 1, 1, path, (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
56390 ++
56391 ++ return;
56392 ++}
56393 ++
56394 ++static void
56395 ++gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real,
56396 ++ const unsigned int effective, const unsigned int fs)
56397 ++{
56398 ++ security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
56399 ++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
56400 ++ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
56401 ++ type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
56402 ++
56403 ++ return;
56404 ++}
56405 ++
56406 ++__u32
56407 ++gr_check_link(const struct dentry * new_dentry,
56408 ++ const struct dentry * parent_dentry,
56409 ++ const struct vfsmount * parent_mnt,
56410 ++ const struct dentry * old_dentry, const struct vfsmount * old_mnt)
56411 ++{
56412 ++ struct acl_object_label *obj;
56413 ++ __u32 oldmode, newmode;
56414 ++ __u32 needmode;
56415 ++
56416 ++ if (unlikely(!(gr_status & GR_READY)))
56417 ++ return (GR_CREATE | GR_LINK);
56418 ++
56419 ++ obj = chk_obj_label(old_dentry, old_mnt, current->acl);
56420 ++ oldmode = obj->mode;
56421 ++
56422 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
56423 ++ oldmode |= (GR_CREATE | GR_LINK);
56424 ++
56425 ++ needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
56426 ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
56427 ++ needmode |= GR_SETID | GR_AUDIT_SETID;
56428 ++
56429 ++ newmode =
56430 ++ gr_check_create(new_dentry, parent_dentry, parent_mnt,
56431 ++ oldmode | needmode);
56432 ++
56433 ++ needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
56434 ++ GR_SETID | GR_READ | GR_FIND | GR_DELETE |
56435 ++ GR_INHERIT | GR_AUDIT_INHERIT);
56436 ++
56437 ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
56438 ++ goto bad;
56439 ++
56440 ++ if ((oldmode & needmode) != needmode)
56441 ++ goto bad;
56442 ++
56443 ++ needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
56444 ++ if ((newmode & needmode) != needmode)
56445 ++ goto bad;
56446 ++
56447 ++ if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
56448 ++ return newmode;
56449 ++bad:
56450 ++ needmode = oldmode;
56451 ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
56452 ++ needmode |= GR_SETID;
56453 ++
56454 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
56455 ++ gr_log_learn(current, old_dentry, old_mnt, needmode);
56456 ++ return (GR_CREATE | GR_LINK);
56457 ++ } else if (newmode & GR_SUPPRESS)
56458 ++ return GR_SUPPRESS;
56459 ++ else
56460 ++ return 0;
56461 ++}
56462 ++
56463 ++__u32
56464 ++gr_search_file(const struct dentry * dentry, const __u32 mode,
56465 ++ const struct vfsmount * mnt)
56466 ++{
56467 ++ __u32 retval = mode;
56468 ++ struct acl_subject_label *curracl;
56469 ++ struct acl_object_label *currobj;
56470 ++
56471 ++ if (unlikely(!(gr_status & GR_READY)))
56472 ++ return (mode & ~GR_AUDITS);
56473 ++
56474 ++ curracl = current->acl;
56475 ++
56476 ++ currobj = chk_obj_label(dentry, mnt, curracl);
56477 ++ retval = currobj->mode & mode;
56478 ++
56479 ++ if (unlikely
56480 ++ ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
56481 ++ && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
56482 ++ __u32 new_mode = mode;
56483 ++
56484 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
56485 ++
56486 ++ retval = new_mode;
56487 ++
56488 ++ if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
56489 ++ new_mode |= GR_INHERIT;
56490 ++
56491 ++ if (!(mode & GR_NOLEARN))
56492 ++ gr_log_learn(current, dentry, mnt, new_mode);
56493 ++ }
56494 ++
56495 ++ return retval;
56496 ++}
56497 ++
56498 ++__u32
56499 ++gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
56500 ++ const struct vfsmount * mnt, const __u32 mode)
56501 ++{
56502 ++ struct name_entry *match;
56503 ++ struct acl_object_label *matchpo;
56504 ++ struct acl_subject_label *curracl;
56505 ++ char *path;
56506 ++ __u32 retval;
56507 ++
56508 ++ if (unlikely(!(gr_status & GR_READY)))
56509 ++ return (mode & ~GR_AUDITS);
56510 ++
56511 ++ preempt_disable();
56512 ++ path = gr_to_filename_rbac(new_dentry, mnt);
56513 ++ match = lookup_name_entry_create(path);
56514 ++
56515 ++ if (!match)
56516 ++ goto check_parent;
56517 ++
56518 ++ curracl = current->acl;
56519 ++
56520 ++ read_lock(&gr_inode_lock);
56521 ++ matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
56522 ++ read_unlock(&gr_inode_lock);
56523 ++
56524 ++ if (matchpo) {
56525 ++ if ((matchpo->mode & mode) !=
56526 ++ (mode & ~(GR_AUDITS | GR_SUPPRESS))
56527 ++ && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
56528 ++ __u32 new_mode = mode;
56529 ++
56530 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
56531 ++
56532 ++ gr_log_learn(current, new_dentry, mnt, new_mode);
56533 ++
56534 ++ preempt_enable();
56535 ++ return new_mode;
56536 ++ }
56537 ++ preempt_enable();
56538 ++ return (matchpo->mode & mode);
56539 ++ }
56540 ++
56541 ++ check_parent:
56542 ++ curracl = current->acl;
56543 ++
56544 ++ matchpo = chk_obj_create_label(parent, mnt, curracl, path);
56545 ++ retval = matchpo->mode & mode;
56546 ++
56547 ++ if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
56548 ++ && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
56549 ++ __u32 new_mode = mode;
56550 ++
56551 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
56552 ++
56553 ++ gr_log_learn(current, new_dentry, mnt, new_mode);
56554 ++ preempt_enable();
56555 ++ return new_mode;
56556 ++ }
56557 ++
56558 ++ preempt_enable();
56559 ++ return retval;
56560 ++}
56561 ++
56562 ++int
56563 ++gr_check_hidden_task(const struct task_struct *task)
56564 ++{
56565 ++ if (unlikely(!(gr_status & GR_READY)))
56566 ++ return 0;
56567 ++
56568 ++ if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
56569 ++ return 1;
56570 ++
56571 ++ return 0;
56572 ++}
56573 ++
56574 ++int
56575 ++gr_check_protected_task(const struct task_struct *task)
56576 ++{
56577 ++ if (unlikely(!(gr_status & GR_READY) || !task))
56578 ++ return 0;
56579 ++
56580 ++ if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
56581 ++ task->acl != current->acl)
56582 ++ return 1;
56583 ++
56584 ++ return 0;
56585 ++}
56586 ++
56587 ++void
56588 ++gr_copy_label(struct task_struct *tsk)
56589 ++{
56590 ++ tsk->signal->used_accept = 0;
56591 ++ tsk->acl_sp_role = 0;
56592 ++ tsk->acl_role_id = current->acl_role_id;
56593 ++ tsk->acl = current->acl;
56594 ++ tsk->role = current->role;
56595 ++ tsk->signal->curr_ip = current->signal->curr_ip;
56596 ++ if (current->exec_file)
56597 ++ get_file(current->exec_file);
56598 ++ tsk->exec_file = current->exec_file;
56599 ++ tsk->is_writable = current->is_writable;
56600 ++ if (unlikely(current->signal->used_accept))
56601 ++ current->signal->curr_ip = 0;
56602 ++
56603 ++ return;
56604 ++}
56605 ++
56606 ++static void
56607 ++gr_set_proc_res(struct task_struct *task)
56608 ++{
56609 ++ struct acl_subject_label *proc;
56610 ++ unsigned short i;
56611 ++
56612 ++ proc = task->acl;
56613 ++
56614 ++ if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
56615 ++ return;
56616 ++
56617 ++ for (i = 0; i < (GR_NLIMITS - 1); i++) {
56618 ++ if (!(proc->resmask & (1 << i)))
56619 ++ continue;
56620 ++
56621 ++ task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
56622 ++ task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
56623 ++ }
56624 ++
56625 ++ return;
56626 ++}
56627 ++
56628 ++int
56629 ++gr_check_user_change(int real, int effective, int fs)
56630 ++{
56631 ++ unsigned int i;
56632 ++ __u16 num;
56633 ++ uid_t *uidlist;
56634 ++ int curuid;
56635 ++ int realok = 0;
56636 ++ int effectiveok = 0;
56637 ++ int fsok = 0;
56638 ++
56639 ++ if (unlikely(!(gr_status & GR_READY)))
56640 ++ return 0;
56641 ++
56642 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
56643 ++ gr_log_learn_id_change(current, 'u', real, effective, fs);
56644 ++
56645 ++ num = current->acl->user_trans_num;
56646 ++ uidlist = current->acl->user_transitions;
56647 ++
56648 ++ if (uidlist == NULL)
56649 ++ return 0;
56650 ++
56651 ++ if (real == -1)
56652 ++ realok = 1;
56653 ++ if (effective == -1)
56654 ++ effectiveok = 1;
56655 ++ if (fs == -1)
56656 ++ fsok = 1;
56657 ++
56658 ++ if (current->acl->user_trans_type & GR_ID_ALLOW) {
56659 ++ for (i = 0; i < num; i++) {
56660 ++ curuid = (int)uidlist[i];
56661 ++ if (real == curuid)
56662 ++ realok = 1;
56663 ++ if (effective == curuid)
56664 ++ effectiveok = 1;
56665 ++ if (fs == curuid)
56666 ++ fsok = 1;
56667 ++ }
56668 ++ } else if (current->acl->user_trans_type & GR_ID_DENY) {
56669 ++ for (i = 0; i < num; i++) {
56670 ++ curuid = (int)uidlist[i];
56671 ++ if (real == curuid)
56672 ++ break;
56673 ++ if (effective == curuid)
56674 ++ break;
56675 ++ if (fs == curuid)
56676 ++ break;
56677 ++ }
56678 ++ /* not in deny list */
56679 ++ if (i == num) {
56680 ++ realok = 1;
56681 ++ effectiveok = 1;
56682 ++ fsok = 1;
56683 ++ }
56684 ++ }
56685 ++
56686 ++ if (realok && effectiveok && fsok)
56687 ++ return 0;
56688 ++ else {
56689 ++ gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
56690 ++ return 1;
56691 ++ }
56692 ++}
56693 ++
56694 ++int
56695 ++gr_check_group_change(int real, int effective, int fs)
56696 ++{
56697 ++ unsigned int i;
56698 ++ __u16 num;
56699 ++ gid_t *gidlist;
56700 ++ int curgid;
56701 ++ int realok = 0;
56702 ++ int effectiveok = 0;
56703 ++ int fsok = 0;
56704 ++
56705 ++ if (unlikely(!(gr_status & GR_READY)))
56706 ++ return 0;
56707 ++
56708 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
56709 ++ gr_log_learn_id_change(current, 'g', real, effective, fs);
56710 ++
56711 ++ num = current->acl->group_trans_num;
56712 ++ gidlist = current->acl->group_transitions;
56713 ++
56714 ++ if (gidlist == NULL)
56715 ++ return 0;
56716 ++
56717 ++ if (real == -1)
56718 ++ realok = 1;
56719 ++ if (effective == -1)
56720 ++ effectiveok = 1;
56721 ++ if (fs == -1)
56722 ++ fsok = 1;
56723 ++
56724 ++ if (current->acl->group_trans_type & GR_ID_ALLOW) {
56725 ++ for (i = 0; i < num; i++) {
56726 ++ curgid = (int)gidlist[i];
56727 ++ if (real == curgid)
56728 ++ realok = 1;
56729 ++ if (effective == curgid)
56730 ++ effectiveok = 1;
56731 ++ if (fs == curgid)
56732 ++ fsok = 1;
56733 ++ }
56734 ++ } else if (current->acl->group_trans_type & GR_ID_DENY) {
56735 ++ for (i = 0; i < num; i++) {
56736 ++ curgid = (int)gidlist[i];
56737 ++ if (real == curgid)
56738 ++ break;
56739 ++ if (effective == curgid)
56740 ++ break;
56741 ++ if (fs == curgid)
56742 ++ break;
56743 ++ }
56744 ++ /* not in deny list */
56745 ++ if (i == num) {
56746 ++ realok = 1;
56747 ++ effectiveok = 1;
56748 ++ fsok = 1;
56749 ++ }
56750 ++ }
56751 ++
56752 ++ if (realok && effectiveok && fsok)
56753 ++ return 0;
56754 ++ else {
56755 ++ gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
56756 ++ return 1;
56757 ++ }
56758 ++}
56759 ++
56760 ++void
56761 ++gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
56762 ++{
56763 ++ struct acl_role_label *role = task->role;
56764 ++ struct acl_subject_label *subj = NULL;
56765 ++ struct acl_object_label *obj;
56766 ++ struct file *filp;
56767 ++
56768 ++ if (unlikely(!(gr_status & GR_READY)))
56769 ++ return;
56770 ++
56771 ++ filp = task->exec_file;
56772 ++
56773 ++ /* kernel process, we'll give them the kernel role */
56774 ++ if (unlikely(!filp)) {
56775 ++ task->role = kernel_role;
56776 ++ task->acl = kernel_role->root_label;
56777 ++ return;
56778 ++ } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
56779 ++ role = lookup_acl_role_label(task, uid, gid);
56780 ++
56781 ++ /* perform subject lookup in possibly new role
56782 ++ we can use this result below in the case where role == task->role
56783 ++ */
56784 ++ subj = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, role);
56785 ++
56786 ++ /* if we changed uid/gid, but result in the same role
56787 ++ and are using inheritance, don't lose the inherited subject
56788 ++ if current subject is other than what normal lookup
56789 ++ would result in, we arrived via inheritance, don't
56790 ++ lose subject
56791 ++ */
56792 ++ if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
56793 ++ (subj == task->acl)))
56794 ++ task->acl = subj;
56795 ++
56796 ++ task->role = role;
56797 ++
56798 ++ task->is_writable = 0;
56799 ++
56800 ++ /* ignore additional mmap checks for processes that are writable
56801 ++ by the default ACL */
56802 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
56803 ++ if (unlikely(obj->mode & GR_WRITE))
56804 ++ task->is_writable = 1;
56805 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
56806 ++ if (unlikely(obj->mode & GR_WRITE))
56807 ++ task->is_writable = 1;
56808 ++
56809 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
56810 ++ printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
56811 ++#endif
56812 ++
56813 ++ gr_set_proc_res(task);
56814 ++
56815 ++ return;
56816 ++}
56817 ++
56818 ++int
56819 ++gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
56820 ++{
56821 ++ struct task_struct *task = current;
56822 ++ struct acl_subject_label *newacl;
56823 ++ struct acl_object_label *obj;
56824 ++ __u32 retmode;
56825 ++
56826 ++ if (unlikely(!(gr_status & GR_READY)))
56827 ++ return 0;
56828 ++
56829 ++ newacl = chk_subj_label(dentry, mnt, task->role);
56830 ++
56831 ++ task_lock(task);
56832 ++ if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
56833 ++ GR_POVERRIDE) && (task->acl != newacl) &&
56834 ++ !(task->role->roletype & GR_ROLE_GOD) &&
56835 ++ !gr_search_file(dentry, GR_PTRACERD, mnt) &&
56836 ++ !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
56837 ++ (atomic_read(&task->fs->count) > 1 ||
56838 ++ atomic_read(&task->files->count) > 1 ||
56839 ++ atomic_read(&task->sighand->count) > 1)) {
56840 ++ task_unlock(task);
56841 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
56842 ++ return -EACCES;
56843 ++ }
56844 ++ task_unlock(task);
56845 ++
56846 ++ obj = chk_obj_label(dentry, mnt, task->acl);
56847 ++ retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
56848 ++
56849 ++ if (!(task->acl->mode & GR_INHERITLEARN) &&
56850 ++ ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
56851 ++ if (obj->nested)
56852 ++ task->acl = obj->nested;
56853 ++ else
56854 ++ task->acl = newacl;
56855 ++ } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
56856 ++ gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
56857 ++
56858 ++ task->is_writable = 0;
56859 ++
56860 ++ /* ignore additional mmap checks for processes that are writable
56861 ++ by the default ACL */
56862 ++ obj = chk_obj_label(dentry, mnt, default_role->root_label);
56863 ++ if (unlikely(obj->mode & GR_WRITE))
56864 ++ task->is_writable = 1;
56865 ++ obj = chk_obj_label(dentry, mnt, task->role->root_label);
56866 ++ if (unlikely(obj->mode & GR_WRITE))
56867 ++ task->is_writable = 1;
56868 ++
56869 ++ gr_set_proc_res(task);
56870 ++
56871 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
56872 ++ printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
56873 ++#endif
56874 ++ return 0;
56875 ++}
56876 ++
56877 ++/* always called with valid inodev ptr */
56878 ++static void
56879 ++do_handle_delete(struct inodev_entry *inodev, const ino_t ino, const dev_t dev)
56880 ++{
56881 ++ struct acl_object_label *matchpo;
56882 ++ struct acl_subject_label *matchps;
56883 ++ struct acl_subject_label *subj;
56884 ++ struct acl_role_label *role;
56885 ++ unsigned int i, x;
56886 ++
56887 ++ FOR_EACH_ROLE_START(role, i)
56888 ++ FOR_EACH_SUBJECT_START(role, subj, x)
56889 ++ if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
56890 ++ matchpo->mode |= GR_DELETED;
56891 ++ FOR_EACH_SUBJECT_END(subj,x)
56892 ++ FOR_EACH_NESTED_SUBJECT_START(role, subj)
56893 ++ if (subj->inode == ino && subj->device == dev)
56894 ++ subj->mode |= GR_DELETED;
56895 ++ FOR_EACH_NESTED_SUBJECT_END(subj)
56896 ++ if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
56897 ++ matchps->mode |= GR_DELETED;
56898 ++ FOR_EACH_ROLE_END(role,i)
56899 ++
56900 ++ inodev->nentry->deleted = 1;
56901 ++
56902 ++ return;
56903 ++}
56904 ++
56905 ++void
56906 ++gr_handle_delete(const ino_t ino, const dev_t dev)
56907 ++{
56908 ++ struct inodev_entry *inodev;
56909 ++
56910 ++ if (unlikely(!(gr_status & GR_READY)))
56911 ++ return;
56912 ++
56913 ++ write_lock(&gr_inode_lock);
56914 ++ inodev = lookup_inodev_entry(ino, dev);
56915 ++ if (inodev != NULL)
56916 ++ do_handle_delete(inodev, ino, dev);
56917 ++ write_unlock(&gr_inode_lock);
56918 ++
56919 ++ return;
56920 ++}
56921 ++
56922 ++static void
56923 ++update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
56924 ++ const ino_t newinode, const dev_t newdevice,
56925 ++ struct acl_subject_label *subj)
56926 ++{
56927 ++ unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
56928 ++ struct acl_object_label *match;
56929 ++
56930 ++ match = subj->obj_hash[index];
56931 ++
56932 ++ while (match && (match->inode != oldinode ||
56933 ++ match->device != olddevice ||
56934 ++ !(match->mode & GR_DELETED)))
56935 ++ match = match->next;
56936 ++
56937 ++ if (match && (match->inode == oldinode)
56938 ++ && (match->device == olddevice)
56939 ++ && (match->mode & GR_DELETED)) {
56940 ++ if (match->prev == NULL) {
56941 ++ subj->obj_hash[index] = match->next;
56942 ++ if (match->next != NULL)
56943 ++ match->next->prev = NULL;
56944 ++ } else {
56945 ++ match->prev->next = match->next;
56946 ++ if (match->next != NULL)
56947 ++ match->next->prev = match->prev;
56948 ++ }
56949 ++ match->prev = NULL;
56950 ++ match->next = NULL;
56951 ++ match->inode = newinode;
56952 ++ match->device = newdevice;
56953 ++ match->mode &= ~GR_DELETED;
56954 ++
56955 ++ insert_acl_obj_label(match, subj);
56956 ++ }
56957 ++
56958 ++ return;
56959 ++}
56960 ++
56961 ++static void
56962 ++update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
56963 ++ const ino_t newinode, const dev_t newdevice,
56964 ++ struct acl_role_label *role)
56965 ++{
56966 ++ unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
56967 ++ struct acl_subject_label *match;
56968 ++
56969 ++ match = role->subj_hash[index];
56970 ++
56971 ++ while (match && (match->inode != oldinode ||
56972 ++ match->device != olddevice ||
56973 ++ !(match->mode & GR_DELETED)))
56974 ++ match = match->next;
56975 ++
56976 ++ if (match && (match->inode == oldinode)
56977 ++ && (match->device == olddevice)
56978 ++ && (match->mode & GR_DELETED)) {
56979 ++ if (match->prev == NULL) {
56980 ++ role->subj_hash[index] = match->next;
56981 ++ if (match->next != NULL)
56982 ++ match->next->prev = NULL;
56983 ++ } else {
56984 ++ match->prev->next = match->next;
56985 ++ if (match->next != NULL)
56986 ++ match->next->prev = match->prev;
56987 ++ }
56988 ++ match->prev = NULL;
56989 ++ match->next = NULL;
56990 ++ match->inode = newinode;
56991 ++ match->device = newdevice;
56992 ++ match->mode &= ~GR_DELETED;
56993 ++
56994 ++ insert_acl_subj_label(match, role);
56995 ++ }
56996 ++
56997 ++ return;
56998 ++}
56999 ++
57000 ++static void
57001 ++update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
57002 ++ const ino_t newinode, const dev_t newdevice)
57003 ++{
57004 ++ unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
57005 ++ struct inodev_entry *match;
57006 ++
57007 ++ match = inodev_set.i_hash[index];
57008 ++
57009 ++ while (match && (match->nentry->inode != oldinode ||
57010 ++ match->nentry->device != olddevice || !match->nentry->deleted))
57011 ++ match = match->next;
57012 ++
57013 ++ if (match && (match->nentry->inode == oldinode)
57014 ++ && (match->nentry->device == olddevice) &&
57015 ++ match->nentry->deleted) {
57016 ++ if (match->prev == NULL) {
57017 ++ inodev_set.i_hash[index] = match->next;
57018 ++ if (match->next != NULL)
57019 ++ match->next->prev = NULL;
57020 ++ } else {
57021 ++ match->prev->next = match->next;
57022 ++ if (match->next != NULL)
57023 ++ match->next->prev = match->prev;
57024 ++ }
57025 ++ match->prev = NULL;
57026 ++ match->next = NULL;
57027 ++ match->nentry->inode = newinode;
57028 ++ match->nentry->device = newdevice;
57029 ++ match->nentry->deleted = 0;
57030 ++
57031 ++ insert_inodev_entry(match);
57032 ++ }
57033 ++
57034 ++ return;
57035 ++}
57036 ++
57037 ++static void
57038 ++do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
57039 ++ const struct vfsmount *mnt)
57040 ++{
57041 ++ struct acl_subject_label *subj;
57042 ++ struct acl_role_label *role;
57043 ++ unsigned int i, x;
57044 ++
57045 ++ FOR_EACH_ROLE_START(role, i)
57046 ++ update_acl_subj_label(matchn->inode, matchn->device,
57047 ++ dentry->d_inode->i_ino,
57048 ++ dentry->d_inode->i_sb->s_dev, role);
57049 ++
57050 ++ FOR_EACH_NESTED_SUBJECT_START(role, subj)
57051 ++ if ((subj->inode == dentry->d_inode->i_ino) &&
57052 ++ (subj->device == dentry->d_inode->i_sb->s_dev)) {
57053 ++ subj->inode = dentry->d_inode->i_ino;
57054 ++ subj->device = dentry->d_inode->i_sb->s_dev;
57055 ++ }
57056 ++ FOR_EACH_NESTED_SUBJECT_END(subj)
57057 ++ FOR_EACH_SUBJECT_START(role, subj, x)
57058 ++ update_acl_obj_label(matchn->inode, matchn->device,
57059 ++ dentry->d_inode->i_ino,
57060 ++ dentry->d_inode->i_sb->s_dev, subj);
57061 ++ FOR_EACH_SUBJECT_END(subj,x)
57062 ++ FOR_EACH_ROLE_END(role,i)
57063 ++
57064 ++ update_inodev_entry(matchn->inode, matchn->device,
57065 ++ dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
57066 ++
57067 ++ return;
57068 ++}
57069 ++
57070 ++void
57071 ++gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
57072 ++{
57073 ++ struct name_entry *matchn;
57074 ++
57075 ++ if (unlikely(!(gr_status & GR_READY)))
57076 ++ return;
57077 ++
57078 ++ preempt_disable();
57079 ++ matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
57080 ++
57081 ++ if (unlikely((unsigned long)matchn)) {
57082 ++ write_lock(&gr_inode_lock);
57083 ++ do_handle_create(matchn, dentry, mnt);
57084 ++ write_unlock(&gr_inode_lock);
57085 ++ }
57086 ++ preempt_enable();
57087 ++
57088 ++ return;
57089 ++}
57090 ++
57091 ++void
57092 ++gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
57093 ++ struct dentry *old_dentry,
57094 ++ struct dentry *new_dentry,
57095 ++ struct vfsmount *mnt, const __u8 replace)
57096 ++{
57097 ++ struct name_entry *matchn;
57098 ++ struct inodev_entry *inodev;
57099 ++
57100 ++ /* vfs_rename swaps the name and parent link for old_dentry and
57101 ++ new_dentry
57102 ++ at this point, old_dentry has the new name, parent link, and inode
57103 ++ for the renamed file
57104 ++ if a file is being replaced by a rename, new_dentry has the inode
57105 ++ and name for the replaced file
57106 ++ */
57107 ++
57108 ++ if (unlikely(!(gr_status & GR_READY)))
57109 ++ return;
57110 ++
57111 ++ preempt_disable();
57112 ++ matchn = lookup_name_entry(gr_to_filename_rbac(old_dentry, mnt));
57113 ++
57114 ++ /* we wouldn't have to check d_inode if it weren't for
57115 ++ NFS silly-renaming
57116 ++ */
57117 ++
57118 ++ write_lock(&gr_inode_lock);
57119 ++ if (unlikely(replace && new_dentry->d_inode)) {
57120 ++ inodev = lookup_inodev_entry(new_dentry->d_inode->i_ino,
57121 ++ new_dentry->d_inode->i_sb->s_dev);
57122 ++ if (inodev != NULL && (new_dentry->d_inode->i_nlink <= 1))
57123 ++ do_handle_delete(inodev, new_dentry->d_inode->i_ino,
57124 ++ new_dentry->d_inode->i_sb->s_dev);
57125 ++ }
57126 ++
57127 ++ inodev = lookup_inodev_entry(old_dentry->d_inode->i_ino,
57128 ++ old_dentry->d_inode->i_sb->s_dev);
57129 ++ if (inodev != NULL && (old_dentry->d_inode->i_nlink <= 1))
57130 ++ do_handle_delete(inodev, old_dentry->d_inode->i_ino,
57131 ++ old_dentry->d_inode->i_sb->s_dev);
57132 ++
57133 ++ if (unlikely((unsigned long)matchn))
57134 ++ do_handle_create(matchn, old_dentry, mnt);
57135 ++
57136 ++ write_unlock(&gr_inode_lock);
57137 ++ preempt_enable();
57138 ++
57139 ++ return;
57140 ++}
57141 ++
57142 ++static int
57143 ++lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
57144 ++ unsigned char **sum)
57145 ++{
57146 ++ struct acl_role_label *r;
57147 ++ struct role_allowed_ip *ipp;
57148 ++ struct role_transition *trans;
57149 ++ unsigned int i;
57150 ++ int found = 0;
57151 ++
57152 ++ /* check transition table */
57153 ++
57154 ++ for (trans = current->role->transitions; trans; trans = trans->next) {
57155 ++ if (!strcmp(rolename, trans->rolename)) {
57156 ++ found = 1;
57157 ++ break;
57158 ++ }
57159 ++ }
57160 ++
57161 ++ if (!found)
57162 ++ return 0;
57163 ++
57164 ++ /* handle special roles that do not require authentication
57165 ++ and check ip */
57166 ++
57167 ++ FOR_EACH_ROLE_START(r, i)
57168 ++ if (!strcmp(rolename, r->rolename) &&
57169 ++ (r->roletype & GR_ROLE_SPECIAL)) {
57170 ++ found = 0;
57171 ++ if (r->allowed_ips != NULL) {
57172 ++ for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
57173 ++ if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
57174 ++ (ntohl(ipp->addr) & ipp->netmask))
57175 ++ found = 1;
57176 ++ }
57177 ++ } else
57178 ++ found = 2;
57179 ++ if (!found)
57180 ++ return 0;
57181 ++
57182 ++ if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
57183 ++ ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
57184 ++ *salt = NULL;
57185 ++ *sum = NULL;
57186 ++ return 1;
57187 ++ }
57188 ++ }
57189 ++ FOR_EACH_ROLE_END(r,i)
57190 ++
57191 ++ for (i = 0; i < num_sprole_pws; i++) {
57192 ++ if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
57193 ++ *salt = acl_special_roles[i]->salt;
57194 ++ *sum = acl_special_roles[i]->sum;
57195 ++ return 1;
57196 ++ }
57197 ++ }
57198 ++
57199 ++ return 0;
57200 ++}
57201 ++
57202 ++static void
57203 ++assign_special_role(char *rolename)
57204 ++{
57205 ++ struct acl_object_label *obj;
57206 ++ struct acl_role_label *r;
57207 ++ struct acl_role_label *assigned = NULL;
57208 ++ struct task_struct *tsk;
57209 ++ struct file *filp;
57210 ++ unsigned int i;
57211 ++
57212 ++ FOR_EACH_ROLE_START(r, i)
57213 ++ if (!strcmp(rolename, r->rolename) &&
57214 ++ (r->roletype & GR_ROLE_SPECIAL))
57215 ++ assigned = r;
57216 ++ FOR_EACH_ROLE_END(r,i)
57217 ++
57218 ++ if (!assigned)
57219 ++ return;
57220 ++
57221 ++ read_lock(&tasklist_lock);
57222 ++ read_lock(&grsec_exec_file_lock);
57223 ++
57224 ++ tsk = current->parent;
57225 ++ if (tsk == NULL)
57226 ++ goto out_unlock;
57227 ++
57228 ++ filp = tsk->exec_file;
57229 ++ if (filp == NULL)
57230 ++ goto out_unlock;
57231 ++
57232 ++ tsk->is_writable = 0;
57233 ++
57234 ++ tsk->acl_sp_role = 1;
57235 ++ tsk->acl_role_id = ++acl_sp_role_value;
57236 ++ tsk->role = assigned;
57237 ++ tsk->acl = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role);
57238 ++
57239 ++ /* ignore additional mmap checks for processes that are writable
57240 ++ by the default ACL */
57241 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
57242 ++ if (unlikely(obj->mode & GR_WRITE))
57243 ++ tsk->is_writable = 1;
57244 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role->root_label);
57245 ++ if (unlikely(obj->mode & GR_WRITE))
57246 ++ tsk->is_writable = 1;
57247 ++
57248 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
57249 ++ printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
57250 ++#endif
57251 ++
57252 ++out_unlock:
57253 ++ read_unlock(&grsec_exec_file_lock);
57254 ++ read_unlock(&tasklist_lock);
57255 ++ return;
57256 ++}
57257 ++
57258 ++int gr_check_secure_terminal(struct task_struct *task)
57259 ++{
57260 ++ struct task_struct *p, *p2, *p3;
57261 ++ struct files_struct *files;
57262 ++ struct fdtable *fdt;
57263 ++ struct file *our_file = NULL, *file;
57264 ++ int i;
57265 ++
57266 ++ if (task->signal->tty == NULL)
57267 ++ return 1;
57268 ++
57269 ++ files = get_files_struct(task);
57270 ++ if (files != NULL) {
57271 ++ rcu_read_lock();
57272 ++ fdt = files_fdtable(files);
57273 ++ for (i=0; i < fdt->max_fds; i++) {
57274 ++ file = fcheck_files(files, i);
57275 ++ if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
57276 ++ get_file(file);
57277 ++ our_file = file;
57278 ++ }
57279 ++ }
57280 ++ rcu_read_unlock();
57281 ++ put_files_struct(files);
57282 ++ }
57283 ++
57284 ++ if (our_file == NULL)
57285 ++ return 1;
57286 ++
57287 ++ read_lock(&tasklist_lock);
57288 ++ do_each_thread(p2, p) {
57289 ++ files = get_files_struct(p);
57290 ++ if (files == NULL ||
57291 ++ (p->signal && p->signal->tty == task->signal->tty)) {
57292 ++ if (files != NULL)
57293 ++ put_files_struct(files);
57294 ++ continue;
57295 ++ }
57296 ++ rcu_read_lock();
57297 ++ fdt = files_fdtable(files);
57298 ++ for (i=0; i < fdt->max_fds; i++) {
57299 ++ file = fcheck_files(files, i);
57300 ++ if (file && S_ISCHR(file->f_path.dentry->d_inode->i_mode) &&
57301 ++ file->f_path.dentry->d_inode->i_rdev == our_file->f_path.dentry->d_inode->i_rdev) {
57302 ++ p3 = task;
57303 ++ while (p3->pid > 0) {
57304 ++ if (p3 == p)
57305 ++ break;
57306 ++ p3 = p3->parent;
57307 ++ }
57308 ++ if (p3 == p)
57309 ++ break;
57310 ++ gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
57311 ++ gr_handle_alertkill(p);
57312 ++ rcu_read_unlock();
57313 ++ put_files_struct(files);
57314 ++ read_unlock(&tasklist_lock);
57315 ++ fput(our_file);
57316 ++ return 0;
57317 ++ }
57318 ++ }
57319 ++ rcu_read_unlock();
57320 ++ put_files_struct(files);
57321 ++ } while_each_thread(p2, p);
57322 ++ read_unlock(&tasklist_lock);
57323 ++
57324 ++ fput(our_file);
57325 ++ return 1;
57326 ++}
57327 ++
57328 ++ssize_t
57329 ++write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
57330 ++{
57331 ++ struct gr_arg_wrapper uwrap;
57332 ++ unsigned char *sprole_salt;
57333 ++ unsigned char *sprole_sum;
57334 ++ int error = sizeof (struct gr_arg_wrapper);
57335 ++ int error2 = 0;
57336 ++
57337 ++ down(&gr_dev_sem);
57338 ++
57339 ++ if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
57340 ++ error = -EPERM;
57341 ++ goto out;
57342 ++ }
57343 ++
57344 ++ if (count != sizeof (struct gr_arg_wrapper)) {
57345 ++ gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
57346 ++ error = -EINVAL;
57347 ++ goto out;
57348 ++ }
57349 ++
57350 ++
57351 ++ if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
57352 ++ gr_auth_expires = 0;
57353 ++ gr_auth_attempts = 0;
57354 ++ }
57355 ++
57356 ++ if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
57357 ++ error = -EFAULT;
57358 ++ goto out;
57359 ++ }
57360 ++
57361 ++ if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
57362 ++ error = -EINVAL;
57363 ++ goto out;
57364 ++ }
57365 ++
57366 ++ if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
57367 ++ error = -EFAULT;
57368 ++ goto out;
57369 ++ }
57370 ++
57371 ++ if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM &&
57372 ++ gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
57373 ++ time_after(gr_auth_expires, get_seconds())) {
57374 ++ error = -EBUSY;
57375 ++ goto out;
57376 ++ }
57377 ++
57378 ++ /* if non-root trying to do anything other than use a special role,
57379 ++ do not attempt authentication, do not count towards authentication
57380 ++ locking
57381 ++ */
57382 ++
57383 ++ if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS &&
57384 ++ gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM &&
57385 ++ current->uid) {
57386 ++ error = -EPERM;
57387 ++ goto out;
57388 ++ }
57389 ++
57390 ++ /* ensure pw and special role name are null terminated */
57391 ++
57392 ++ gr_usermode->pw[GR_PW_LEN - 1] = '\0';
57393 ++ gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
57394 ++
57395 ++ /* Okay.
57396 ++ * We have our enough of the argument structure..(we have yet
57397 ++ * to copy_from_user the tables themselves) . Copy the tables
57398 ++ * only if we need them, i.e. for loading operations. */
57399 ++
57400 ++ switch (gr_usermode->mode) {
57401 ++ case STATUS:
57402 ++ if (gr_status & GR_READY) {
57403 ++ error = 1;
57404 ++ if (!gr_check_secure_terminal(current))
57405 ++ error = 3;
57406 ++ } else
57407 ++ error = 2;
57408 ++ goto out;
57409 ++ case SHUTDOWN:
57410 ++ if ((gr_status & GR_READY)
57411 ++ && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
57412 ++ gr_status &= ~GR_READY;
57413 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
57414 ++ free_variables();
57415 ++ memset(gr_usermode, 0, sizeof (struct gr_arg));
57416 ++ memset(gr_system_salt, 0, GR_SALT_LEN);
57417 ++ memset(gr_system_sum, 0, GR_SHA_LEN);
57418 ++ } else if (gr_status & GR_READY) {
57419 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
57420 ++ error = -EPERM;
57421 ++ } else {
57422 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
57423 ++ error = -EAGAIN;
57424 ++ }
57425 ++ break;
57426 ++ case ENABLE:
57427 ++ if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
57428 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
57429 ++ else {
57430 ++ if (gr_status & GR_READY)
57431 ++ error = -EAGAIN;
57432 ++ else
57433 ++ error = error2;
57434 ++ gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
57435 ++ }
57436 ++ break;
57437 ++ case RELOAD:
57438 ++ if (!(gr_status & GR_READY)) {
57439 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
57440 ++ error = -EAGAIN;
57441 ++ } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
57442 ++ lock_kernel();
57443 ++ gr_status &= ~GR_READY;
57444 ++ free_variables();
57445 ++ if (!(error2 = gracl_init(gr_usermode))) {
57446 ++ unlock_kernel();
57447 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
57448 ++ } else {
57449 ++ unlock_kernel();
57450 ++ error = error2;
57451 ++ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
57452 ++ }
57453 ++ } else {
57454 ++ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
57455 ++ error = -EPERM;
57456 ++ }
57457 ++ break;
57458 ++ case SEGVMOD:
57459 ++ if (unlikely(!(gr_status & GR_READY))) {
57460 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
57461 ++ error = -EAGAIN;
57462 ++ break;
57463 ++ }
57464 ++
57465 ++ if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
57466 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
57467 ++ if (gr_usermode->segv_device && gr_usermode->segv_inode) {
57468 ++ struct acl_subject_label *segvacl;
57469 ++ segvacl =
57470 ++ lookup_acl_subj_label(gr_usermode->segv_inode,
57471 ++ gr_usermode->segv_device,
57472 ++ current->role);
57473 ++ if (segvacl) {
57474 ++ segvacl->crashes = 0;
57475 ++ segvacl->expires = 0;
57476 ++ }
57477 ++ } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
57478 ++ gr_remove_uid(gr_usermode->segv_uid);
57479 ++ }
57480 ++ } else {
57481 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
57482 ++ error = -EPERM;
57483 ++ }
57484 ++ break;
57485 ++ case SPROLE:
57486 ++ case SPROLEPAM:
57487 ++ if (unlikely(!(gr_status & GR_READY))) {
57488 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
57489 ++ error = -EAGAIN;
57490 ++ break;
57491 ++ }
57492 ++
57493 ++ if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
57494 ++ current->role->expires = 0;
57495 ++ current->role->auth_attempts = 0;
57496 ++ }
57497 ++
57498 ++ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
57499 ++ time_after(current->role->expires, get_seconds())) {
57500 ++ error = -EBUSY;
57501 ++ goto out;
57502 ++ }
57503 ++
57504 ++ if (lookup_special_role_auth
57505 ++ (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
57506 ++ && ((!sprole_salt && !sprole_sum)
57507 ++ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
57508 ++ char *p = "";
57509 ++ assign_special_role(gr_usermode->sp_role);
57510 ++ read_lock(&tasklist_lock);
57511 ++ if (current->parent)
57512 ++ p = current->parent->role->rolename;
57513 ++ read_unlock(&tasklist_lock);
57514 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
57515 ++ p, acl_sp_role_value);
57516 ++ } else {
57517 ++ gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
57518 ++ error = -EPERM;
57519 ++ if(!(current->role->auth_attempts++))
57520 ++ current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
57521 ++
57522 ++ goto out;
57523 ++ }
57524 ++ break;
57525 ++ case UNSPROLE:
57526 ++ if (unlikely(!(gr_status & GR_READY))) {
57527 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
57528 ++ error = -EAGAIN;
57529 ++ break;
57530 ++ }
57531 ++
57532 ++ if (current->role->roletype & GR_ROLE_SPECIAL) {
57533 ++ char *p = "";
57534 ++ int i = 0;
57535 ++
57536 ++ read_lock(&tasklist_lock);
57537 ++ if (current->parent) {
57538 ++ p = current->parent->role->rolename;
57539 ++ i = current->parent->acl_role_id;
57540 ++ }
57541 ++ read_unlock(&tasklist_lock);
57542 ++
57543 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
57544 ++ gr_set_acls(1);
57545 ++ } else {
57546 ++ gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
57547 ++ error = -EPERM;
57548 ++ goto out;
57549 ++ }
57550 ++ break;
57551 ++ default:
57552 ++ gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
57553 ++ error = -EINVAL;
57554 ++ break;
57555 ++ }
57556 ++
57557 ++ if (error != -EPERM)
57558 ++ goto out;
57559 ++
57560 ++ if(!(gr_auth_attempts++))
57561 ++ gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
57562 ++
57563 ++ out:
57564 ++ up(&gr_dev_sem);
57565 ++ return error;
57566 ++}
57567 ++
57568 ++int
57569 ++gr_set_acls(const int type)
57570 ++{
57571 ++ struct acl_object_label *obj;
57572 ++ struct task_struct *task, *task2;
57573 ++ struct file *filp;
57574 ++ struct acl_role_label *role = current->role;
57575 ++ __u16 acl_role_id = current->acl_role_id;
57576 ++
57577 ++ read_lock(&tasklist_lock);
57578 ++ read_lock(&grsec_exec_file_lock);
57579 ++ do_each_thread(task2, task) {
57580 ++ /* check to see if we're called from the exit handler,
57581 ++ if so, only replace ACLs that have inherited the admin
57582 ++ ACL */
57583 ++
57584 ++ if (type && (task->role != role ||
57585 ++ task->acl_role_id != acl_role_id))
57586 ++ continue;
57587 ++
57588 ++ task->acl_role_id = 0;
57589 ++ task->acl_sp_role = 0;
57590 ++
57591 ++ if ((filp = task->exec_file)) {
57592 ++ task->role = lookup_acl_role_label(task, task->uid, task->gid);
57593 ++
57594 ++ task->acl =
57595 ++ chk_subj_label(filp->f_path.dentry, filp->f_path.mnt,
57596 ++ task->role);
57597 ++ if (task->acl) {
57598 ++ struct acl_subject_label *curr;
57599 ++ curr = task->acl;
57600 ++
57601 ++ task->is_writable = 0;
57602 ++ /* ignore additional mmap checks for processes that are writable
57603 ++ by the default ACL */
57604 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
57605 ++ if (unlikely(obj->mode & GR_WRITE))
57606 ++ task->is_writable = 1;
57607 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
57608 ++ if (unlikely(obj->mode & GR_WRITE))
57609 ++ task->is_writable = 1;
57610 ++
57611 ++ gr_set_proc_res(task);
57612 ++
57613 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
57614 ++ printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
57615 ++#endif
57616 ++ } else {
57617 ++ read_unlock(&grsec_exec_file_lock);
57618 ++ read_unlock(&tasklist_lock);
57619 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
57620 ++ return 1;
57621 ++ }
57622 ++ } else {
57623 ++ // it's a kernel process
57624 ++ task->role = kernel_role;
57625 ++ task->acl = kernel_role->root_label;
57626 ++#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
57627 ++ task->acl->mode &= ~GR_PROCFIND;
57628 ++#endif
57629 ++ }
57630 ++ } while_each_thread(task2, task);
57631 ++ read_unlock(&grsec_exec_file_lock);
57632 ++ read_unlock(&tasklist_lock);
57633 ++ return 0;
57634 ++}
57635 ++
57636 ++void
57637 ++gr_learn_resource(const struct task_struct *task,
57638 ++ const int res, const unsigned long wanted, const int gt)
57639 ++{
57640 ++ struct acl_subject_label *acl;
57641 ++
57642 ++ if (unlikely((gr_status & GR_READY) &&
57643 ++ task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
57644 ++ goto skip_reslog;
57645 ++
57646 ++#ifdef CONFIG_GRKERNSEC_RESLOG
57647 ++ gr_log_resource(task, res, wanted, gt);
57648 ++#endif
57649 ++ skip_reslog:
57650 ++
57651 ++ if (unlikely(!(gr_status & GR_READY) || !wanted))
57652 ++ return;
57653 ++
57654 ++ acl = task->acl;
57655 ++
57656 ++ if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
57657 ++ !(acl->resmask & (1 << (unsigned short) res))))
57658 ++ return;
57659 ++
57660 ++ if (wanted >= acl->res[res].rlim_cur) {
57661 ++ unsigned long res_add;
57662 ++
57663 ++ res_add = wanted;
57664 ++ switch (res) {
57665 ++ case RLIMIT_CPU:
57666 ++ res_add += GR_RLIM_CPU_BUMP;
57667 ++ break;
57668 ++ case RLIMIT_FSIZE:
57669 ++ res_add += GR_RLIM_FSIZE_BUMP;
57670 ++ break;
57671 ++ case RLIMIT_DATA:
57672 ++ res_add += GR_RLIM_DATA_BUMP;
57673 ++ break;
57674 ++ case RLIMIT_STACK:
57675 ++ res_add += GR_RLIM_STACK_BUMP;
57676 ++ break;
57677 ++ case RLIMIT_CORE:
57678 ++ res_add += GR_RLIM_CORE_BUMP;
57679 ++ break;
57680 ++ case RLIMIT_RSS:
57681 ++ res_add += GR_RLIM_RSS_BUMP;
57682 ++ break;
57683 ++ case RLIMIT_NPROC:
57684 ++ res_add += GR_RLIM_NPROC_BUMP;
57685 ++ break;
57686 ++ case RLIMIT_NOFILE:
57687 ++ res_add += GR_RLIM_NOFILE_BUMP;
57688 ++ break;
57689 ++ case RLIMIT_MEMLOCK:
57690 ++ res_add += GR_RLIM_MEMLOCK_BUMP;
57691 ++ break;
57692 ++ case RLIMIT_AS:
57693 ++ res_add += GR_RLIM_AS_BUMP;
57694 ++ break;
57695 ++ case RLIMIT_LOCKS:
57696 ++ res_add += GR_RLIM_LOCKS_BUMP;
57697 ++ break;
57698 ++ }
57699 ++
57700 ++ acl->res[res].rlim_cur = res_add;
57701 ++
57702 ++ if (wanted > acl->res[res].rlim_max)
57703 ++ acl->res[res].rlim_max = res_add;
57704 ++
57705 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
57706 ++ task->role->roletype, acl->filename,
57707 ++ acl->res[res].rlim_cur, acl->res[res].rlim_max,
57708 ++ "", (unsigned long) res);
57709 ++ }
57710 ++
57711 ++ return;
57712 ++}
57713 ++
57714 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
57715 ++void
57716 ++pax_set_initial_flags(struct linux_binprm *bprm)
57717 ++{
57718 ++ struct task_struct *task = current;
57719 ++ struct acl_subject_label *proc;
57720 ++ unsigned long flags;
57721 ++
57722 ++ if (unlikely(!(gr_status & GR_READY)))
57723 ++ return;
57724 ++
57725 ++ flags = pax_get_flags(task);
57726 ++
57727 ++ proc = task->acl;
57728 ++
57729 ++ if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
57730 ++ flags &= ~MF_PAX_PAGEEXEC;
57731 ++ if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
57732 ++ flags &= ~MF_PAX_SEGMEXEC;
57733 ++ if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
57734 ++ flags &= ~MF_PAX_RANDMMAP;
57735 ++ if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
57736 ++ flags &= ~MF_PAX_EMUTRAMP;
57737 ++ if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
57738 ++ flags &= ~MF_PAX_MPROTECT;
57739 ++
57740 ++ if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
57741 ++ flags |= MF_PAX_PAGEEXEC;
57742 ++ if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
57743 ++ flags |= MF_PAX_SEGMEXEC;
57744 ++ if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
57745 ++ flags |= MF_PAX_RANDMMAP;
57746 ++ if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
57747 ++ flags |= MF_PAX_EMUTRAMP;
57748 ++ if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
57749 ++ flags |= MF_PAX_MPROTECT;
57750 ++
57751 ++ pax_set_flags(task, flags);
57752 ++
57753 ++ return;
57754 ++}
57755 ++#endif
57756 ++
57757 ++#ifdef CONFIG_SYSCTL
57758 ++/* Eric Biederman likes breaking userland ABI and every inode-based security
57759 ++ system to save 35kb of memory */
57760 ++
57761 ++/* we modify the passed in filename, but adjust it back before returning */
57762 ++static struct acl_object_label *gr_lookup_by_name(char *name, unsigned int len)
57763 ++{
57764 ++ struct name_entry *nmatch;
57765 ++ char *p, *lastp = NULL;
57766 ++ struct acl_object_label *obj = NULL, *tmp;
57767 ++ struct acl_subject_label *tmpsubj;
57768 ++ char c = '\0';
57769 ++
57770 ++ read_lock(&gr_inode_lock);
57771 ++
57772 ++ p = name + len - 1;
57773 ++ do {
57774 ++ nmatch = lookup_name_entry(name);
57775 ++ if (lastp != NULL)
57776 ++ *lastp = c;
57777 ++
57778 ++ if (nmatch == NULL)
57779 ++ goto next_component;
57780 ++ tmpsubj = current->acl;
57781 ++ do {
57782 ++ obj = lookup_acl_obj_label(nmatch->inode, nmatch->device, tmpsubj);
57783 ++ if (obj != NULL) {
57784 ++ tmp = obj->globbed;
57785 ++ while (tmp) {
57786 ++ if (!glob_match(tmp->filename, name)) {
57787 ++ obj = tmp;
57788 ++ goto found_obj;
57789 ++ }
57790 ++ tmp = tmp->next;
57791 ++ }
57792 ++ goto found_obj;
57793 ++ }
57794 ++ } while ((tmpsubj = tmpsubj->parent_subject));
57795 ++next_component:
57796 ++ /* end case */
57797 ++ if (p == name)
57798 ++ break;
57799 ++
57800 ++ while (*p != '/')
57801 ++ p--;
57802 ++ if (p == name)
57803 ++ lastp = p + 1;
57804 ++ else {
57805 ++ lastp = p;
57806 ++ p--;
57807 ++ }
57808 ++ c = *lastp;
57809 ++ *lastp = '\0';
57810 ++ } while (1);
57811 ++found_obj:
57812 ++ read_unlock(&gr_inode_lock);
57813 ++ /* obj returned will always be non-null */
57814 ++ return obj;
57815 ++}
57816 ++
57817 ++/* returns 0 when allowing, non-zero on error
57818 ++ op of 0 is used for readdir, so we don't log the names of hidden files
57819 ++*/
57820 ++__u32
57821 ++gr_handle_sysctl(const struct ctl_table *table, const int op)
57822 ++{
57823 ++ ctl_table *tmp;
57824 ++ const char *proc_sys = "/proc/sys";
57825 ++ char *path;
57826 ++ struct acl_object_label *obj;
57827 ++ unsigned short len = 0, pos = 0, depth = 0, i;
57828 ++ __u32 err = 0;
57829 ++ __u32 mode = 0;
57830 ++
57831 ++ if (unlikely(!(gr_status & GR_READY)))
57832 ++ return 0;
57833 ++
57834 ++ /* for now, ignore operations on non-sysctl entries if it's not a
57835 ++ readdir*/
57836 ++ if (table->child != NULL && op != 0)
57837 ++ return 0;
57838 ++
57839 ++ mode |= GR_FIND;
57840 ++ /* it's only a read if it's an entry, read on dirs is for readdir */
57841 ++ if (op & MAY_READ)
57842 ++ mode |= GR_READ;
57843 ++ if (op & MAY_WRITE)
57844 ++ mode |= GR_WRITE;
57845 ++
57846 ++ preempt_disable();
57847 ++
57848 ++ path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
57849 ++
57850 ++ /* it's only a read/write if it's an actual entry, not a dir
57851 ++ (which are opened for readdir)
57852 ++ */
57853 ++
57854 ++ /* convert the requested sysctl entry into a pathname */
57855 ++
57856 ++ for (tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
57857 ++ len += strlen(tmp->procname);
57858 ++ len++;
57859 ++ depth++;
57860 ++ }
57861 ++
57862 ++ if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE) {
57863 ++ /* deny */
57864 ++ goto out;
57865 ++ }
57866 ++
57867 ++ memset(path, 0, PAGE_SIZE);
57868 ++
57869 ++ memcpy(path, proc_sys, strlen(proc_sys));
57870 ++
57871 ++ pos += strlen(proc_sys);
57872 ++
57873 ++ for (; depth > 0; depth--) {
57874 ++ path[pos] = '/';
57875 ++ pos++;
57876 ++ for (i = 1, tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
57877 ++ if (depth == i) {
57878 ++ memcpy(path + pos, tmp->procname,
57879 ++ strlen(tmp->procname));
57880 ++ pos += strlen(tmp->procname);
57881 ++ }
57882 ++ i++;
57883 ++ }
57884 ++ }
57885 ++
57886 ++ obj = gr_lookup_by_name(path, pos);
57887 ++ err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
57888 ++
57889 ++ if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
57890 ++ ((err & mode) != mode))) {
57891 ++ __u32 new_mode = mode;
57892 ++
57893 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
57894 ++
57895 ++ err = 0;
57896 ++ gr_log_learn_sysctl(current, path, new_mode);
57897 ++ } else if (!(err & GR_FIND) && !(err & GR_SUPPRESS) && op != 0) {
57898 ++ gr_log_hidden_sysctl(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, path);
57899 ++ err = -ENOENT;
57900 ++ } else if (!(err & GR_FIND)) {
57901 ++ err = -ENOENT;
57902 ++ } else if (((err & mode) & ~GR_FIND) != (mode & ~GR_FIND) && !(err & GR_SUPPRESS)) {
57903 ++ gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
57904 ++ path, (mode & GR_READ) ? " reading" : "",
57905 ++ (mode & GR_WRITE) ? " writing" : "");
57906 ++ err = -EACCES;
57907 ++ } else if ((err & mode) != mode) {
57908 ++ err = -EACCES;
57909 ++ } else if ((((err & mode) & ~GR_FIND) == (mode & ~GR_FIND)) && (err & GR_AUDITS)) {
57910 ++ gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
57911 ++ path, (mode & GR_READ) ? " reading" : "",
57912 ++ (mode & GR_WRITE) ? " writing" : "");
57913 ++ err = 0;
57914 ++ } else
57915 ++ err = 0;
57916 ++
57917 ++ out:
57918 ++ preempt_enable();
57919 ++
57920 ++ return err;
57921 ++}
57922 ++#endif
57923 ++
57924 ++int
57925 ++gr_handle_proc_ptrace(struct task_struct *task)
57926 ++{
57927 ++ struct file *filp;
57928 ++ struct task_struct *tmp = task;
57929 ++ struct task_struct *curtemp = current;
57930 ++ __u32 retmode;
57931 ++
57932 ++ if (unlikely(!(gr_status & GR_READY)))
57933 ++ return 0;
57934 ++
57935 ++ read_lock(&tasklist_lock);
57936 ++ read_lock(&grsec_exec_file_lock);
57937 ++ filp = task->exec_file;
57938 ++
57939 ++ while (tmp->pid > 0) {
57940 ++ if (tmp == curtemp)
57941 ++ break;
57942 ++ tmp = tmp->parent;
57943 ++ }
57944 ++
57945 ++ if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
57946 ++ read_unlock(&grsec_exec_file_lock);
57947 ++ read_unlock(&tasklist_lock);
57948 ++ return 1;
57949 ++ }
57950 ++
57951 ++ retmode = gr_search_file(filp->f_path.dentry, GR_NOPTRACE, filp->f_path.mnt);
57952 ++ read_unlock(&grsec_exec_file_lock);
57953 ++ read_unlock(&tasklist_lock);
57954 ++
57955 ++ if (retmode & GR_NOPTRACE)
57956 ++ return 1;
57957 ++
57958 ++ if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
57959 ++ && (current->acl != task->acl || (current->acl != current->role->root_label
57960 ++ && current->pid != task->pid)))
57961 ++ return 1;
57962 ++
57963 ++ return 0;
57964 ++}
57965 ++
57966 ++int
57967 ++gr_handle_ptrace(struct task_struct *task, const long request)
57968 ++{
57969 ++ struct task_struct *tmp = task;
57970 ++ struct task_struct *curtemp = current;
57971 ++ __u32 retmode;
57972 ++
57973 ++ if (unlikely(!(gr_status & GR_READY)))
57974 ++ return 0;
57975 ++
57976 ++ read_lock(&tasklist_lock);
57977 ++ while (tmp->pid > 0) {
57978 ++ if (tmp == curtemp)
57979 ++ break;
57980 ++ tmp = tmp->parent;
57981 ++ }
57982 ++
57983 ++ if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
57984 ++ read_unlock(&tasklist_lock);
57985 ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
57986 ++ return 1;
57987 ++ }
57988 ++ read_unlock(&tasklist_lock);
57989 ++
57990 ++ read_lock(&grsec_exec_file_lock);
57991 ++ if (unlikely(!task->exec_file)) {
57992 ++ read_unlock(&grsec_exec_file_lock);
57993 ++ return 0;
57994 ++ }
57995 ++
57996 ++ retmode = gr_search_file(task->exec_file->f_path.dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_path.mnt);
57997 ++ read_unlock(&grsec_exec_file_lock);
57998 ++
57999 ++ if (retmode & GR_NOPTRACE) {
58000 ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
58001 ++ return 1;
58002 ++ }
58003 ++
58004 ++ if (retmode & GR_PTRACERD) {
58005 ++ switch (request) {
58006 ++ case PTRACE_POKETEXT:
58007 ++ case PTRACE_POKEDATA:
58008 ++ case PTRACE_POKEUSR:
58009 ++#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
58010 ++ case PTRACE_SETREGS:
58011 ++ case PTRACE_SETFPREGS:
58012 ++#endif
58013 ++#ifdef CONFIG_X86
58014 ++ case PTRACE_SETFPXREGS:
58015 ++#endif
58016 ++#ifdef CONFIG_ALTIVEC
58017 ++ case PTRACE_SETVRREGS:
58018 ++#endif
58019 ++ return 1;
58020 ++ default:
58021 ++ return 0;
58022 ++ }
58023 ++ } else if (!(current->acl->mode & GR_POVERRIDE) &&
58024 ++ !(current->role->roletype & GR_ROLE_GOD) &&
58025 ++ (current->acl != task->acl)) {
58026 ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
58027 ++ return 1;
58028 ++ }
58029 ++
58030 ++ return 0;
58031 ++}
58032 ++
58033 ++static int is_writable_mmap(const struct file *filp)
58034 ++{
58035 ++ struct task_struct *task = current;
58036 ++ struct acl_object_label *obj, *obj2;
58037 ++
58038 ++ if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
58039 ++ !task->is_writable && S_ISREG(filp->f_path.dentry->d_inode->i_mode)) {
58040 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
58041 ++ obj2 = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt,
58042 ++ task->role->root_label);
58043 ++ if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
58044 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_path.dentry, filp->f_path.mnt);
58045 ++ return 1;
58046 ++ }
58047 ++ }
58048 ++ return 0;
58049 ++}
58050 ++
58051 ++int
58052 ++gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
58053 ++{
58054 ++ __u32 mode;
58055 ++
58056 ++ if (unlikely(!file || !(prot & PROT_EXEC)))
58057 ++ return 1;
58058 ++
58059 ++ if (is_writable_mmap(file))
58060 ++ return 0;
58061 ++
58062 ++ mode =
58063 ++ gr_search_file(file->f_path.dentry,
58064 ++ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
58065 ++ file->f_path.mnt);
58066 ++
58067 ++ if (!gr_tpe_allow(file))
58068 ++ return 0;
58069 ++
58070 ++ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
58071 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
58072 ++ return 0;
58073 ++ } else if (unlikely(!(mode & GR_EXEC))) {
58074 ++ return 0;
58075 ++ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
58076 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
58077 ++ return 1;
58078 ++ }
58079 ++
58080 ++ return 1;
58081 ++}
58082 ++
58083 ++int
58084 ++gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
58085 ++{
58086 ++ __u32 mode;
58087 ++
58088 ++ if (unlikely(!file || !(prot & PROT_EXEC)))
58089 ++ return 1;
58090 ++
58091 ++ if (is_writable_mmap(file))
58092 ++ return 0;
58093 ++
58094 ++ mode =
58095 ++ gr_search_file(file->f_path.dentry,
58096 ++ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
58097 ++ file->f_path.mnt);
58098 ++
58099 ++ if (!gr_tpe_allow(file))
58100 ++ return 0;
58101 ++
58102 ++ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
58103 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
58104 ++ return 0;
58105 ++ } else if (unlikely(!(mode & GR_EXEC))) {
58106 ++ return 0;
58107 ++ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
58108 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
58109 ++ return 1;
58110 ++ }
58111 ++
58112 ++ return 1;
58113 ++}
58114 ++
58115 ++void
58116 ++gr_acl_handle_psacct(struct task_struct *task, const long code)
58117 ++{
58118 ++ unsigned long runtime;
58119 ++ unsigned long cputime;
58120 ++ unsigned int wday, cday;
58121 ++ __u8 whr, chr;
58122 ++ __u8 wmin, cmin;
58123 ++ __u8 wsec, csec;
58124 ++ struct timespec timeval;
58125 ++
58126 ++ if (unlikely(!(gr_status & GR_READY) || !task->acl ||
58127 ++ !(task->acl->mode & GR_PROCACCT)))
58128 ++ return;
58129 ++
58130 ++ do_posix_clock_monotonic_gettime(&timeval);
58131 ++ runtime = timeval.tv_sec - task->start_time.tv_sec;
58132 ++ wday = runtime / (3600 * 24);
58133 ++ runtime -= wday * (3600 * 24);
58134 ++ whr = runtime / 3600;
58135 ++ runtime -= whr * 3600;
58136 ++ wmin = runtime / 60;
58137 ++ runtime -= wmin * 60;
58138 ++ wsec = runtime;
58139 ++
58140 ++ cputime = (task->utime + task->stime) / HZ;
58141 ++ cday = cputime / (3600 * 24);
58142 ++ cputime -= cday * (3600 * 24);
58143 ++ chr = cputime / 3600;
58144 ++ cputime -= chr * 3600;
58145 ++ cmin = cputime / 60;
58146 ++ cputime -= cmin * 60;
58147 ++ csec = cputime;
58148 ++
58149 ++ gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
58150 ++
58151 ++ return;
58152 ++}
58153 ++
58154 ++void gr_set_kernel_label(struct task_struct *task)
58155 ++{
58156 ++ if (gr_status & GR_READY) {
58157 ++ task->role = kernel_role;
58158 ++ task->acl = kernel_role->root_label;
58159 ++ }
58160 ++ return;
58161 ++}
58162 ++
58163 ++int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
58164 ++{
58165 ++ struct task_struct *task = current;
58166 ++ struct dentry *dentry = file->f_path.dentry;
58167 ++ struct vfsmount *mnt = file->f_path.mnt;
58168 ++ struct acl_object_label *obj, *tmp;
58169 ++ struct acl_subject_label *subj;
58170 ++ unsigned int bufsize;
58171 ++ int is_not_root;
58172 ++ char *path;
58173 ++
58174 ++ if (unlikely(!(gr_status & GR_READY)))
58175 ++ return 1;
58176 ++
58177 ++ if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
58178 ++ return 1;
58179 ++
58180 ++ /* ignore Eric Biederman */
58181 ++ if (IS_PRIVATE(dentry->d_inode))
58182 ++ return 1;
58183 ++
58184 ++ subj = task->acl;
58185 ++ do {
58186 ++ obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
58187 ++ if (obj != NULL)
58188 ++ return (obj->mode & GR_FIND) ? 1 : 0;
58189 ++ } while ((subj = subj->parent_subject));
58190 ++
58191 ++ obj = chk_obj_label(dentry, mnt, task->acl);
58192 ++ if (obj->globbed == NULL)
58193 ++ return (obj->mode & GR_FIND) ? 1 : 0;
58194 ++
58195 ++ is_not_root = ((obj->filename[0] == '/') &&
58196 ++ (obj->filename[1] == '\0')) ? 0 : 1;
58197 ++ bufsize = PAGE_SIZE - namelen - is_not_root;
58198 ++
58199 ++ /* check bufsize > PAGE_SIZE || bufsize == 0 */
58200 ++ if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
58201 ++ return 1;
58202 ++
58203 ++ preempt_disable();
58204 ++ path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
58205 ++ bufsize);
58206 ++
58207 ++ bufsize = strlen(path);
58208 ++
58209 ++ /* if base is "/", don't append an additional slash */
58210 ++ if (is_not_root)
58211 ++ *(path + bufsize) = '/';
58212 ++ memcpy(path + bufsize + is_not_root, name, namelen);
58213 ++ *(path + bufsize + namelen + is_not_root) = '\0';
58214 ++
58215 ++ tmp = obj->globbed;
58216 ++ while (tmp) {
58217 ++ if (!glob_match(tmp->filename, path)) {
58218 ++ preempt_enable();
58219 ++ return (tmp->mode & GR_FIND) ? 1 : 0;
58220 ++ }
58221 ++ tmp = tmp->next;
58222 ++ }
58223 ++ preempt_enable();
58224 ++ return (obj->mode & GR_FIND) ? 1 : 0;
58225 ++}
58226 ++
58227 ++EXPORT_SYMBOL(gr_learn_resource);
58228 ++EXPORT_SYMBOL(gr_set_kernel_label);
58229 ++#ifdef CONFIG_SECURITY
58230 ++EXPORT_SYMBOL(gr_check_user_change);
58231 ++EXPORT_SYMBOL(gr_check_group_change);
58232 ++#endif
58233 ++
58234 +diff -urNp linux-2.6.27.7/grsecurity/gracl_cap.c linux-2.6.27.7/grsecurity/gracl_cap.c
58235 +--- linux-2.6.27.7/grsecurity/gracl_cap.c 1969-12-31 19:00:00.000000000 -0500
58236 ++++ linux-2.6.27.7/grsecurity/gracl_cap.c 2008-11-18 03:38:45.000000000 -0500
58237 +@@ -0,0 +1,129 @@
58238 ++#include <linux/kernel.h>
58239 ++#include <linux/module.h>
58240 ++#include <linux/sched.h>
58241 ++#include <linux/gracl.h>
58242 ++#include <linux/grsecurity.h>
58243 ++#include <linux/grinternal.h>
58244 ++
58245 ++static const char *captab_log[] = {
58246 ++ "CAP_CHOWN",
58247 ++ "CAP_DAC_OVERRIDE",
58248 ++ "CAP_DAC_READ_SEARCH",
58249 ++ "CAP_FOWNER",
58250 ++ "CAP_FSETID",
58251 ++ "CAP_KILL",
58252 ++ "CAP_SETGID",
58253 ++ "CAP_SETUID",
58254 ++ "CAP_SETPCAP",
58255 ++ "CAP_LINUX_IMMUTABLE",
58256 ++ "CAP_NET_BIND_SERVICE",
58257 ++ "CAP_NET_BROADCAST",
58258 ++ "CAP_NET_ADMIN",
58259 ++ "CAP_NET_RAW",
58260 ++ "CAP_IPC_LOCK",
58261 ++ "CAP_IPC_OWNER",
58262 ++ "CAP_SYS_MODULE",
58263 ++ "CAP_SYS_RAWIO",
58264 ++ "CAP_SYS_CHROOT",
58265 ++ "CAP_SYS_PTRACE",
58266 ++ "CAP_SYS_PACCT",
58267 ++ "CAP_SYS_ADMIN",
58268 ++ "CAP_SYS_BOOT",
58269 ++ "CAP_SYS_NICE",
58270 ++ "CAP_SYS_RESOURCE",
58271 ++ "CAP_SYS_TIME",
58272 ++ "CAP_SYS_TTY_CONFIG",
58273 ++ "CAP_MKNOD",
58274 ++ "CAP_LEASE",
58275 ++ "CAP_AUDIT_WRITE",
58276 ++ "CAP_AUDIT_CONTROL",
58277 ++ "CAP_SETFCAP",
58278 ++ "CAP_MAC_OVERRIDE",
58279 ++ "CAP_MAC_ADMIN"
58280 ++};
58281 ++
58282 ++EXPORT_SYMBOL(gr_task_is_capable);
58283 ++EXPORT_SYMBOL(gr_is_capable_nolog);
58284 ++
58285 ++int
58286 ++gr_task_is_capable(struct task_struct *task, const int cap)
58287 ++{
58288 ++ struct acl_subject_label *curracl;
58289 ++ kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
58290 ++
58291 ++ if (!gr_acl_is_enabled())
58292 ++ return 1;
58293 ++
58294 ++ curracl = task->acl;
58295 ++
58296 ++ cap_drop = curracl->cap_lower;
58297 ++ cap_mask = curracl->cap_mask;
58298 ++
58299 ++ while ((curracl = curracl->parent_subject)) {
58300 ++ /* if the cap isn't specified in the current computed mask but is specified in the
58301 ++ current level subject, and is lowered in the current level subject, then add
58302 ++ it to the set of dropped capabilities
58303 ++ otherwise, add the current level subject's mask to the current computed mask
58304 ++ */
58305 ++ if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
58306 ++ cap_raise(cap_mask, cap);
58307 ++ if (cap_raised(curracl->cap_lower, cap))
58308 ++ cap_raise(cap_drop, cap);
58309 ++ }
58310 ++ }
58311 ++
58312 ++ if (!cap_raised(cap_drop, cap))
58313 ++ return 1;
58314 ++
58315 ++ curracl = task->acl;
58316 ++
58317 ++ if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
58318 ++ && cap_raised(task->cap_effective, cap)) {
58319 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
58320 ++ task->role->roletype, task->uid,
58321 ++ task->gid, task->exec_file ?
58322 ++ gr_to_filename(task->exec_file->f_path.dentry,
58323 ++ task->exec_file->f_path.mnt) : curracl->filename,
58324 ++ curracl->filename, 0UL,
58325 ++ 0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
58326 ++ return 1;
58327 ++ }
58328 ++
58329 ++ if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap))
58330 ++ gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
58331 ++ return 0;
58332 ++}
58333 ++
58334 ++int
58335 ++gr_is_capable_nolog(const int cap)
58336 ++{
58337 ++ struct acl_subject_label *curracl;
58338 ++ kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
58339 ++
58340 ++ if (!gr_acl_is_enabled())
58341 ++ return 1;
58342 ++
58343 ++ curracl = current->acl;
58344 ++
58345 ++ cap_drop = curracl->cap_lower;
58346 ++ cap_mask = curracl->cap_mask;
58347 ++
58348 ++ while ((curracl = curracl->parent_subject)) {
58349 ++ /* if the cap isn't specified in the current computed mask but is specified in the
58350 ++ current level subject, and is lowered in the current level subject, then add
58351 ++ it to the set of dropped capabilities
58352 ++ otherwise, add the current level subject's mask to the current computed mask
58353 ++ */
58354 ++ if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
58355 ++ cap_raise(cap_mask, cap);
58356 ++ if (cap_raised(curracl->cap_lower, cap))
58357 ++ cap_raise(cap_drop, cap);
58358 ++ }
58359 ++ }
58360 ++
58361 ++ if (!cap_raised(cap_drop, cap))
58362 ++ return 1;
58363 ++
58364 ++ return 0;
58365 ++}
58366 ++
58367 +diff -urNp linux-2.6.27.7/grsecurity/gracl_fs.c linux-2.6.27.7/grsecurity/gracl_fs.c
58368 +--- linux-2.6.27.7/grsecurity/gracl_fs.c 1969-12-31 19:00:00.000000000 -0500
58369 ++++ linux-2.6.27.7/grsecurity/gracl_fs.c 2008-11-18 03:38:45.000000000 -0500
58370 +@@ -0,0 +1,423 @@
58371 ++#include <linux/kernel.h>
58372 ++#include <linux/sched.h>
58373 ++#include <linux/types.h>
58374 ++#include <linux/fs.h>
58375 ++#include <linux/file.h>
58376 ++#include <linux/stat.h>
58377 ++#include <linux/grsecurity.h>
58378 ++#include <linux/grinternal.h>
58379 ++#include <linux/gracl.h>
58380 ++
58381 ++__u32
58382 ++gr_acl_handle_hidden_file(const struct dentry * dentry,
58383 ++ const struct vfsmount * mnt)
58384 ++{
58385 ++ __u32 mode;
58386 ++
58387 ++ if (unlikely(!dentry->d_inode))
58388 ++ return GR_FIND;
58389 ++
58390 ++ mode =
58391 ++ gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
58392 ++
58393 ++ if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
58394 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
58395 ++ return mode;
58396 ++ } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
58397 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
58398 ++ return 0;
58399 ++ } else if (unlikely(!(mode & GR_FIND)))
58400 ++ return 0;
58401 ++
58402 ++ return GR_FIND;
58403 ++}
58404 ++
58405 ++__u32
58406 ++gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
58407 ++ const int fmode)
58408 ++{
58409 ++ __u32 reqmode = GR_FIND;
58410 ++ __u32 mode;
58411 ++
58412 ++ if (unlikely(!dentry->d_inode))
58413 ++ return reqmode;
58414 ++
58415 ++ if (unlikely(fmode & O_APPEND))
58416 ++ reqmode |= GR_APPEND;
58417 ++ else if (unlikely(fmode & FMODE_WRITE))
58418 ++ reqmode |= GR_WRITE;
58419 ++ if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
58420 ++ reqmode |= GR_READ;
58421 ++
58422 ++ mode =
58423 ++ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
58424 ++ mnt);
58425 ++
58426 ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
58427 ++ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
58428 ++ reqmode & GR_READ ? " reading" : "",
58429 ++ reqmode & GR_WRITE ? " writing" : reqmode &
58430 ++ GR_APPEND ? " appending" : "");
58431 ++ return reqmode;
58432 ++ } else
58433 ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
58434 ++ {
58435 ++ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
58436 ++ reqmode & GR_READ ? " reading" : "",
58437 ++ reqmode & GR_WRITE ? " writing" : reqmode &
58438 ++ GR_APPEND ? " appending" : "");
58439 ++ return 0;
58440 ++ } else if (unlikely((mode & reqmode) != reqmode))
58441 ++ return 0;
58442 ++
58443 ++ return reqmode;
58444 ++}
58445 ++
58446 ++__u32
58447 ++gr_acl_handle_creat(const struct dentry * dentry,
58448 ++ const struct dentry * p_dentry,
58449 ++ const struct vfsmount * p_mnt, const int fmode,
58450 ++ const int imode)
58451 ++{
58452 ++ __u32 reqmode = GR_WRITE | GR_CREATE;
58453 ++ __u32 mode;
58454 ++
58455 ++ if (unlikely(fmode & O_APPEND))
58456 ++ reqmode |= GR_APPEND;
58457 ++ if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
58458 ++ reqmode |= GR_READ;
58459 ++ if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
58460 ++ reqmode |= GR_SETID;
58461 ++
58462 ++ mode =
58463 ++ gr_check_create(dentry, p_dentry, p_mnt,
58464 ++ reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
58465 ++
58466 ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
58467 ++ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
58468 ++ reqmode & GR_READ ? " reading" : "",
58469 ++ reqmode & GR_WRITE ? " writing" : reqmode &
58470 ++ GR_APPEND ? " appending" : "");
58471 ++ return reqmode;
58472 ++ } else
58473 ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
58474 ++ {
58475 ++ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
58476 ++ reqmode & GR_READ ? " reading" : "",
58477 ++ reqmode & GR_WRITE ? " writing" : reqmode &
58478 ++ GR_APPEND ? " appending" : "");
58479 ++ return 0;
58480 ++ } else if (unlikely((mode & reqmode) != reqmode))
58481 ++ return 0;
58482 ++
58483 ++ return reqmode;
58484 ++}
58485 ++
58486 ++__u32
58487 ++gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
58488 ++ const int fmode)
58489 ++{
58490 ++ __u32 mode, reqmode = GR_FIND;
58491 ++
58492 ++ if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
58493 ++ reqmode |= GR_EXEC;
58494 ++ if (fmode & S_IWOTH)
58495 ++ reqmode |= GR_WRITE;
58496 ++ if (fmode & S_IROTH)
58497 ++ reqmode |= GR_READ;
58498 ++
58499 ++ mode =
58500 ++ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
58501 ++ mnt);
58502 ++
58503 ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
58504 ++ gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
58505 ++ reqmode & GR_READ ? " reading" : "",
58506 ++ reqmode & GR_WRITE ? " writing" : "",
58507 ++ reqmode & GR_EXEC ? " executing" : "");
58508 ++ return reqmode;
58509 ++ } else
58510 ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
58511 ++ {
58512 ++ gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
58513 ++ reqmode & GR_READ ? " reading" : "",
58514 ++ reqmode & GR_WRITE ? " writing" : "",
58515 ++ reqmode & GR_EXEC ? " executing" : "");
58516 ++ return 0;
58517 ++ } else if (unlikely((mode & reqmode) != reqmode))
58518 ++ return 0;
58519 ++
58520 ++ return reqmode;
58521 ++}
58522 ++
58523 ++static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
58524 ++{
58525 ++ __u32 mode;
58526 ++
58527 ++ mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
58528 ++
58529 ++ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
58530 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
58531 ++ return mode;
58532 ++ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
58533 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
58534 ++ return 0;
58535 ++ } else if (unlikely((mode & (reqmode)) != (reqmode)))
58536 ++ return 0;
58537 ++
58538 ++ return (reqmode);
58539 ++}
58540 ++
58541 ++__u32
58542 ++gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
58543 ++{
58544 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
58545 ++}
58546 ++
58547 ++__u32
58548 ++gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
58549 ++{
58550 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
58551 ++}
58552 ++
58553 ++__u32
58554 ++gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
58555 ++{
58556 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
58557 ++}
58558 ++
58559 ++__u32
58560 ++gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
58561 ++{
58562 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
58563 ++}
58564 ++
58565 ++__u32
58566 ++gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
58567 ++ mode_t mode)
58568 ++{
58569 ++ if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
58570 ++ return 1;
58571 ++
58572 ++ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
58573 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
58574 ++ GR_FCHMOD_ACL_MSG);
58575 ++ } else {
58576 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
58577 ++ }
58578 ++}
58579 ++
58580 ++__u32
58581 ++gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
58582 ++ mode_t mode)
58583 ++{
58584 ++ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
58585 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
58586 ++ GR_CHMOD_ACL_MSG);
58587 ++ } else {
58588 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
58589 ++ }
58590 ++}
58591 ++
58592 ++__u32
58593 ++gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
58594 ++{
58595 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
58596 ++}
58597 ++
58598 ++__u32
58599 ++gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
58600 ++{
58601 ++ return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
58602 ++}
58603 ++
58604 ++__u32
58605 ++gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
58606 ++{
58607 ++ return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
58608 ++ GR_UNIXCONNECT_ACL_MSG);
58609 ++}
58610 ++
58611 ++/* hardlinks require at minimum create permission,
58612 ++ any additional privilege required is based on the
58613 ++ privilege of the file being linked to
58614 ++*/
58615 ++__u32
58616 ++gr_acl_handle_link(const struct dentry * new_dentry,
58617 ++ const struct dentry * parent_dentry,
58618 ++ const struct vfsmount * parent_mnt,
58619 ++ const struct dentry * old_dentry,
58620 ++ const struct vfsmount * old_mnt, const char *to)
58621 ++{
58622 ++ __u32 mode;
58623 ++ __u32 needmode = GR_CREATE | GR_LINK;
58624 ++ __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
58625 ++
58626 ++ mode =
58627 ++ gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
58628 ++ old_mnt);
58629 ++
58630 ++ if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
58631 ++ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
58632 ++ return mode;
58633 ++ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
58634 ++ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
58635 ++ return 0;
58636 ++ } else if (unlikely((mode & needmode) != needmode))
58637 ++ return 0;
58638 ++
58639 ++ return 1;
58640 ++}
58641 ++
58642 ++__u32
58643 ++gr_acl_handle_symlink(const struct dentry * new_dentry,
58644 ++ const struct dentry * parent_dentry,
58645 ++ const struct vfsmount * parent_mnt, const char *from)
58646 ++{
58647 ++ __u32 needmode = GR_WRITE | GR_CREATE;
58648 ++ __u32 mode;
58649 ++
58650 ++ mode =
58651 ++ gr_check_create(new_dentry, parent_dentry, parent_mnt,
58652 ++ GR_CREATE | GR_AUDIT_CREATE |
58653 ++ GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
58654 ++
58655 ++ if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
58656 ++ gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
58657 ++ return mode;
58658 ++ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
58659 ++ gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
58660 ++ return 0;
58661 ++ } else if (unlikely((mode & needmode) != needmode))
58662 ++ return 0;
58663 ++
58664 ++ return (GR_WRITE | GR_CREATE);
58665 ++}
58666 ++
58667 ++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)
58668 ++{
58669 ++ __u32 mode;
58670 ++
58671 ++ mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
58672 ++
58673 ++ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
58674 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
58675 ++ return mode;
58676 ++ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
58677 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
58678 ++ return 0;
58679 ++ } else if (unlikely((mode & (reqmode)) != (reqmode)))
58680 ++ return 0;
58681 ++
58682 ++ return (reqmode);
58683 ++}
58684 ++
58685 ++__u32
58686 ++gr_acl_handle_mknod(const struct dentry * new_dentry,
58687 ++ const struct dentry * parent_dentry,
58688 ++ const struct vfsmount * parent_mnt,
58689 ++ const int mode)
58690 ++{
58691 ++ __u32 reqmode = GR_WRITE | GR_CREATE;
58692 ++ if (unlikely(mode & (S_ISUID | S_ISGID)))
58693 ++ reqmode |= GR_SETID;
58694 ++
58695 ++ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
58696 ++ reqmode, GR_MKNOD_ACL_MSG);
58697 ++}
58698 ++
58699 ++__u32
58700 ++gr_acl_handle_mkdir(const struct dentry *new_dentry,
58701 ++ const struct dentry *parent_dentry,
58702 ++ const struct vfsmount *parent_mnt)
58703 ++{
58704 ++ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
58705 ++ GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
58706 ++}
58707 ++
58708 ++#define RENAME_CHECK_SUCCESS(old, new) \
58709 ++ (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
58710 ++ ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
58711 ++
58712 ++int
58713 ++gr_acl_handle_rename(struct dentry *new_dentry,
58714 ++ struct dentry *parent_dentry,
58715 ++ const struct vfsmount *parent_mnt,
58716 ++ struct dentry *old_dentry,
58717 ++ struct inode *old_parent_inode,
58718 ++ struct vfsmount *old_mnt, const char *newname)
58719 ++{
58720 ++ __u32 comp1, comp2;
58721 ++ int error = 0;
58722 ++
58723 ++ if (unlikely(!gr_acl_is_enabled()))
58724 ++ return 0;
58725 ++
58726 ++ if (!new_dentry->d_inode) {
58727 ++ comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
58728 ++ GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
58729 ++ GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
58730 ++ comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
58731 ++ GR_DELETE | GR_AUDIT_DELETE |
58732 ++ GR_AUDIT_READ | GR_AUDIT_WRITE |
58733 ++ GR_SUPPRESS, old_mnt);
58734 ++ } else {
58735 ++ comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
58736 ++ GR_CREATE | GR_DELETE |
58737 ++ GR_AUDIT_CREATE | GR_AUDIT_DELETE |
58738 ++ GR_AUDIT_READ | GR_AUDIT_WRITE |
58739 ++ GR_SUPPRESS, parent_mnt);
58740 ++ comp2 =
58741 ++ gr_search_file(old_dentry,
58742 ++ GR_READ | GR_WRITE | GR_AUDIT_READ |
58743 ++ GR_DELETE | GR_AUDIT_DELETE |
58744 ++ GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
58745 ++ }
58746 ++
58747 ++ if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
58748 ++ ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
58749 ++ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
58750 ++ else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
58751 ++ && !(comp2 & GR_SUPPRESS)) {
58752 ++ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
58753 ++ error = -EACCES;
58754 ++ } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
58755 ++ error = -EACCES;
58756 ++
58757 ++ return error;
58758 ++}
58759 ++
58760 ++void
58761 ++gr_acl_handle_exit(void)
58762 ++{
58763 ++ u16 id;
58764 ++ char *rolename;
58765 ++ struct file *exec_file;
58766 ++
58767 ++ if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
58768 ++ id = current->acl_role_id;
58769 ++ rolename = current->role->rolename;
58770 ++ gr_set_acls(1);
58771 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
58772 ++ }
58773 ++
58774 ++ write_lock(&grsec_exec_file_lock);
58775 ++ exec_file = current->exec_file;
58776 ++ current->exec_file = NULL;
58777 ++ write_unlock(&grsec_exec_file_lock);
58778 ++
58779 ++ if (exec_file)
58780 ++ fput(exec_file);
58781 ++}
58782 ++
58783 ++int
58784 ++gr_acl_handle_procpidmem(const struct task_struct *task)
58785 ++{
58786 ++ if (unlikely(!gr_acl_is_enabled()))
58787 ++ return 0;
58788 ++
58789 ++ if (task != current && task->acl->mode & GR_PROTPROCFD)
58790 ++ return -EACCES;
58791 ++
58792 ++ return 0;
58793 ++}
58794 +diff -urNp linux-2.6.27.7/grsecurity/gracl_ip.c linux-2.6.27.7/grsecurity/gracl_ip.c
58795 +--- linux-2.6.27.7/grsecurity/gracl_ip.c 1969-12-31 19:00:00.000000000 -0500
58796 ++++ linux-2.6.27.7/grsecurity/gracl_ip.c 2008-11-18 03:38:45.000000000 -0500
58797 +@@ -0,0 +1,313 @@
58798 ++#include <linux/kernel.h>
58799 ++#include <asm/uaccess.h>
58800 ++#include <asm/errno.h>
58801 ++#include <net/sock.h>
58802 ++#include <linux/file.h>
58803 ++#include <linux/fs.h>
58804 ++#include <linux/net.h>
58805 ++#include <linux/in.h>
58806 ++#include <linux/skbuff.h>
58807 ++#include <linux/ip.h>
58808 ++#include <linux/udp.h>
58809 ++#include <linux/smp_lock.h>
58810 ++#include <linux/types.h>
58811 ++#include <linux/sched.h>
58812 ++#include <linux/netdevice.h>
58813 ++#include <linux/inetdevice.h>
58814 ++#include <linux/gracl.h>
58815 ++#include <linux/grsecurity.h>
58816 ++#include <linux/grinternal.h>
58817 ++
58818 ++#define GR_BIND 0x01
58819 ++#define GR_CONNECT 0x02
58820 ++#define GR_INVERT 0x04
58821 ++
58822 ++static const char * gr_protocols[256] = {
58823 ++ "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
58824 ++ "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
58825 ++ "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
58826 ++ "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
58827 ++ "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
58828 ++ "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
58829 ++ "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
58830 ++ "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
58831 ++ "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
58832 ++ "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
58833 ++ "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
58834 ++ "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
58835 ++ "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
58836 ++ "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
58837 ++ "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
58838 ++ "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
58839 ++ "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
58840 ++ "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
58841 ++ "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
58842 ++ "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
58843 ++ "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
58844 ++ "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
58845 ++ "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
58846 ++ "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
58847 ++ "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
58848 ++ "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
58849 ++ "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
58850 ++ "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
58851 ++ "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
58852 ++ "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
58853 ++ "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
58854 ++ "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
58855 ++ };
58856 ++
58857 ++static const char * gr_socktypes[11] = {
58858 ++ "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
58859 ++ "unknown:7", "unknown:8", "unknown:9", "packet"
58860 ++ };
58861 ++
58862 ++const char *
58863 ++gr_proto_to_name(unsigned char proto)
58864 ++{
58865 ++ return gr_protocols[proto];
58866 ++}
58867 ++
58868 ++const char *
58869 ++gr_socktype_to_name(unsigned char type)
58870 ++{
58871 ++ return gr_socktypes[type];
58872 ++}
58873 ++
58874 ++int
58875 ++gr_search_socket(const int domain, const int type, const int protocol)
58876 ++{
58877 ++ struct acl_subject_label *curr;
58878 ++
58879 ++ if (unlikely(!gr_acl_is_enabled()))
58880 ++ goto exit;
58881 ++
58882 ++ if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
58883 ++ || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
58884 ++ goto exit; // let the kernel handle it
58885 ++
58886 ++ curr = current->acl;
58887 ++
58888 ++ if (!curr->ips)
58889 ++ goto exit;
58890 ++
58891 ++ if ((curr->ip_type & (1 << type)) &&
58892 ++ (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
58893 ++ goto exit;
58894 ++
58895 ++ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
58896 ++ /* we don't place acls on raw sockets , and sometimes
58897 ++ dgram/ip sockets are opened for ioctl and not
58898 ++ bind/connect, so we'll fake a bind learn log */
58899 ++ if (type == SOCK_RAW || type == SOCK_PACKET) {
58900 ++ __u32 fakeip = 0;
58901 ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
58902 ++ current->role->roletype, current->uid,
58903 ++ current->gid, current->exec_file ?
58904 ++ gr_to_filename(current->exec_file->f_path.dentry,
58905 ++ current->exec_file->f_path.mnt) :
58906 ++ curr->filename, curr->filename,
58907 ++ NIPQUAD(fakeip), 0, type,
58908 ++ protocol, GR_CONNECT,
58909 ++NIPQUAD(current->signal->curr_ip));
58910 ++ } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
58911 ++ __u32 fakeip = 0;
58912 ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
58913 ++ current->role->roletype, current->uid,
58914 ++ current->gid, current->exec_file ?
58915 ++ gr_to_filename(current->exec_file->f_path.dentry,
58916 ++ current->exec_file->f_path.mnt) :
58917 ++ curr->filename, curr->filename,
58918 ++ NIPQUAD(fakeip), 0, type,
58919 ++ protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
58920 ++ }
58921 ++ /* we'll log when they use connect or bind */
58922 ++ goto exit;
58923 ++ }
58924 ++
58925 ++ gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet",
58926 ++ gr_socktype_to_name(type), gr_proto_to_name(protocol));
58927 ++
58928 ++ return 0;
58929 ++ exit:
58930 ++ return 1;
58931 ++}
58932 ++
58933 ++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)
58934 ++{
58935 ++ if ((ip->mode & mode) &&
58936 ++ (ip_port >= ip->low) &&
58937 ++ (ip_port <= ip->high) &&
58938 ++ ((ntohl(ip_addr) & our_netmask) ==
58939 ++ (ntohl(our_addr) & our_netmask))
58940 ++ && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
58941 ++ && (ip->type & (1 << type))) {
58942 ++ if (ip->mode & GR_INVERT)
58943 ++ return 2; // specifically denied
58944 ++ else
58945 ++ return 1; // allowed
58946 ++ }
58947 ++
58948 ++ return 0; // not specifically allowed, may continue parsing
58949 ++}
58950 ++
58951 ++static int
58952 ++gr_search_connectbind(const int mode, const struct sock *sk,
58953 ++ const struct sockaddr_in *addr, const int type)
58954 ++{
58955 ++ char iface[IFNAMSIZ] = {0};
58956 ++ struct acl_subject_label *curr;
58957 ++ struct acl_ip_label *ip;
58958 ++ struct net_device *dev;
58959 ++ struct in_device *idev;
58960 ++ unsigned long i;
58961 ++ int ret;
58962 ++ __u32 ip_addr = 0;
58963 ++ __u32 our_addr;
58964 ++ __u32 our_netmask;
58965 ++ char *p;
58966 ++ __u16 ip_port = 0;
58967 ++
58968 ++ if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
58969 ++ return 1;
58970 ++
58971 ++ curr = current->acl;
58972 ++
58973 ++ if (!curr->ips)
58974 ++ return 1;
58975 ++
58976 ++ ip_addr = addr->sin_addr.s_addr;
58977 ++ ip_port = ntohs(addr->sin_port);
58978 ++
58979 ++ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
58980 ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
58981 ++ current->role->roletype, current->uid,
58982 ++ current->gid, current->exec_file ?
58983 ++ gr_to_filename(current->exec_file->f_path.dentry,
58984 ++ current->exec_file->f_path.mnt) :
58985 ++ curr->filename, curr->filename,
58986 ++ NIPQUAD(ip_addr), ip_port, type,
58987 ++ sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
58988 ++ return 1;
58989 ++ }
58990 ++
58991 ++ for (i = 0; i < curr->ip_num; i++) {
58992 ++ ip = *(curr->ips + i);
58993 ++ if (ip->iface != NULL) {
58994 ++ strncpy(iface, ip->iface, IFNAMSIZ - 1);
58995 ++ p = strchr(iface, ':');
58996 ++ if (p != NULL)
58997 ++ *p = '\0';
58998 ++ dev = dev_get_by_name(sock_net(sk), iface);
58999 ++ if (dev == NULL)
59000 ++ continue;
59001 ++ idev = in_dev_get(dev);
59002 ++ if (idev == NULL) {
59003 ++ dev_put(dev);
59004 ++ continue;
59005 ++ }
59006 ++ rcu_read_lock();
59007 ++ for_ifa(idev) {
59008 ++ if (!strcmp(ip->iface, ifa->ifa_label)) {
59009 ++ our_addr = ifa->ifa_address;
59010 ++ our_netmask = 0xffffffff;
59011 ++ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
59012 ++ if (ret == 1) {
59013 ++ rcu_read_unlock();
59014 ++ in_dev_put(idev);
59015 ++ dev_put(dev);
59016 ++ return 1;
59017 ++ } else if (ret == 2) {
59018 ++ rcu_read_unlock();
59019 ++ in_dev_put(idev);
59020 ++ dev_put(dev);
59021 ++ goto denied;
59022 ++ }
59023 ++ }
59024 ++ } endfor_ifa(idev);
59025 ++ rcu_read_unlock();
59026 ++ in_dev_put(idev);
59027 ++ dev_put(dev);
59028 ++ } else {
59029 ++ our_addr = ip->addr;
59030 ++ our_netmask = ip->netmask;
59031 ++ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
59032 ++ if (ret == 1)
59033 ++ return 1;
59034 ++ else if (ret == 2)
59035 ++ goto denied;
59036 ++ }
59037 ++ }
59038 ++
59039 ++denied:
59040 ++ if (mode == GR_BIND)
59041 ++ 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));
59042 ++ else if (mode == GR_CONNECT)
59043 ++ 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));
59044 ++
59045 ++ return 0;
59046 ++}
59047 ++
59048 ++int
59049 ++gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
59050 ++{
59051 ++ return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
59052 ++}
59053 ++
59054 ++int
59055 ++gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
59056 ++{
59057 ++ return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
59058 ++}
59059 ++
59060 ++int gr_search_listen(const struct socket *sock)
59061 ++{
59062 ++ struct sock *sk = sock->sk;
59063 ++ struct sockaddr_in addr;
59064 ++
59065 ++ addr.sin_addr.s_addr = inet_sk(sk)->saddr;
59066 ++ addr.sin_port = inet_sk(sk)->sport;
59067 ++
59068 ++ return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
59069 ++}
59070 ++
59071 ++int gr_search_accept(const struct socket *sock)
59072 ++{
59073 ++ struct sock *sk = sock->sk;
59074 ++ struct sockaddr_in addr;
59075 ++
59076 ++ addr.sin_addr.s_addr = inet_sk(sk)->saddr;
59077 ++ addr.sin_port = inet_sk(sk)->sport;
59078 ++
59079 ++ return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
59080 ++}
59081 ++
59082 ++int
59083 ++gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
59084 ++{
59085 ++ if (addr)
59086 ++ return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
59087 ++ else {
59088 ++ struct sockaddr_in sin;
59089 ++ const struct inet_sock *inet = inet_sk(sk);
59090 ++
59091 ++ sin.sin_addr.s_addr = inet->daddr;
59092 ++ sin.sin_port = inet->dport;
59093 ++
59094 ++ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
59095 ++ }
59096 ++}
59097 ++
59098 ++int
59099 ++gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
59100 ++{
59101 ++ struct sockaddr_in sin;
59102 ++
59103 ++ if (unlikely(skb->len < sizeof (struct udphdr)))
59104 ++ return 1; // skip this packet
59105 ++
59106 ++ sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
59107 ++ sin.sin_port = udp_hdr(skb)->source;
59108 ++
59109 ++ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
59110 ++}
59111 +diff -urNp linux-2.6.27.7/grsecurity/gracl_learn.c linux-2.6.27.7/grsecurity/gracl_learn.c
59112 +--- linux-2.6.27.7/grsecurity/gracl_learn.c 1969-12-31 19:00:00.000000000 -0500
59113 ++++ linux-2.6.27.7/grsecurity/gracl_learn.c 2008-11-18 03:38:45.000000000 -0500
59114 +@@ -0,0 +1,211 @@
59115 ++#include <linux/kernel.h>
59116 ++#include <linux/mm.h>
59117 ++#include <linux/sched.h>
59118 ++#include <linux/poll.h>
59119 ++#include <linux/smp_lock.h>
59120 ++#include <linux/string.h>
59121 ++#include <linux/file.h>
59122 ++#include <linux/types.h>
59123 ++#include <linux/vmalloc.h>
59124 ++#include <linux/grinternal.h>
59125 ++
59126 ++extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
59127 ++ size_t count, loff_t *ppos);
59128 ++extern int gr_acl_is_enabled(void);
59129 ++
59130 ++static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
59131 ++static int gr_learn_attached;
59132 ++
59133 ++/* use a 512k buffer */
59134 ++#define LEARN_BUFFER_SIZE (512 * 1024)
59135 ++
59136 ++static DEFINE_SPINLOCK(gr_learn_lock);
59137 ++static DECLARE_MUTEX(gr_learn_user_sem);
59138 ++
59139 ++/* we need to maintain two buffers, so that the kernel context of grlearn
59140 ++ uses a semaphore around the userspace copying, and the other kernel contexts
59141 ++ use a spinlock when copying into the buffer, since they cannot sleep
59142 ++*/
59143 ++static char *learn_buffer;
59144 ++static char *learn_buffer_user;
59145 ++static int learn_buffer_len;
59146 ++static int learn_buffer_user_len;
59147 ++
59148 ++static ssize_t
59149 ++read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
59150 ++{
59151 ++ DECLARE_WAITQUEUE(wait, current);
59152 ++ ssize_t retval = 0;
59153 ++
59154 ++ add_wait_queue(&learn_wait, &wait);
59155 ++ set_current_state(TASK_INTERRUPTIBLE);
59156 ++ do {
59157 ++ down(&gr_learn_user_sem);
59158 ++ spin_lock(&gr_learn_lock);
59159 ++ if (learn_buffer_len)
59160 ++ break;
59161 ++ spin_unlock(&gr_learn_lock);
59162 ++ up(&gr_learn_user_sem);
59163 ++ if (file->f_flags & O_NONBLOCK) {
59164 ++ retval = -EAGAIN;
59165 ++ goto out;
59166 ++ }
59167 ++ if (signal_pending(current)) {
59168 ++ retval = -ERESTARTSYS;
59169 ++ goto out;
59170 ++ }
59171 ++
59172 ++ schedule();
59173 ++ } while (1);
59174 ++
59175 ++ memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
59176 ++ learn_buffer_user_len = learn_buffer_len;
59177 ++ retval = learn_buffer_len;
59178 ++ learn_buffer_len = 0;
59179 ++
59180 ++ spin_unlock(&gr_learn_lock);
59181 ++
59182 ++ if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
59183 ++ retval = -EFAULT;
59184 ++
59185 ++ up(&gr_learn_user_sem);
59186 ++out:
59187 ++ set_current_state(TASK_RUNNING);
59188 ++ remove_wait_queue(&learn_wait, &wait);
59189 ++ return retval;
59190 ++}
59191 ++
59192 ++static unsigned int
59193 ++poll_learn(struct file * file, poll_table * wait)
59194 ++{
59195 ++ poll_wait(file, &learn_wait, wait);
59196 ++
59197 ++ if (learn_buffer_len)
59198 ++ return (POLLIN | POLLRDNORM);
59199 ++
59200 ++ return 0;
59201 ++}
59202 ++
59203 ++void
59204 ++gr_clear_learn_entries(void)
59205 ++{
59206 ++ char *tmp;
59207 ++
59208 ++ down(&gr_learn_user_sem);
59209 ++ if (learn_buffer != NULL) {
59210 ++ spin_lock(&gr_learn_lock);
59211 ++ tmp = learn_buffer;
59212 ++ learn_buffer = NULL;
59213 ++ spin_unlock(&gr_learn_lock);
59214 ++ vfree(learn_buffer);
59215 ++ }
59216 ++ if (learn_buffer_user != NULL) {
59217 ++ vfree(learn_buffer_user);
59218 ++ learn_buffer_user = NULL;
59219 ++ }
59220 ++ learn_buffer_len = 0;
59221 ++ up(&gr_learn_user_sem);
59222 ++
59223 ++ return;
59224 ++}
59225 ++
59226 ++void
59227 ++gr_add_learn_entry(const char *fmt, ...)
59228 ++{
59229 ++ va_list args;
59230 ++ unsigned int len;
59231 ++
59232 ++ if (!gr_learn_attached)
59233 ++ return;
59234 ++
59235 ++ spin_lock(&gr_learn_lock);
59236 ++
59237 ++ /* leave a gap at the end so we know when it's "full" but don't have to
59238 ++ compute the exact length of the string we're trying to append
59239 ++ */
59240 ++ if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
59241 ++ spin_unlock(&gr_learn_lock);
59242 ++ wake_up_interruptible(&learn_wait);
59243 ++ return;
59244 ++ }
59245 ++ if (learn_buffer == NULL) {
59246 ++ spin_unlock(&gr_learn_lock);
59247 ++ return;
59248 ++ }
59249 ++
59250 ++ va_start(args, fmt);
59251 ++ len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
59252 ++ va_end(args);
59253 ++
59254 ++ learn_buffer_len += len + 1;
59255 ++
59256 ++ spin_unlock(&gr_learn_lock);
59257 ++ wake_up_interruptible(&learn_wait);
59258 ++
59259 ++ return;
59260 ++}
59261 ++
59262 ++static int
59263 ++open_learn(struct inode *inode, struct file *file)
59264 ++{
59265 ++ if (file->f_mode & FMODE_READ && gr_learn_attached)
59266 ++ return -EBUSY;
59267 ++ if (file->f_mode & FMODE_READ) {
59268 ++ int retval = 0;
59269 ++ down(&gr_learn_user_sem);
59270 ++ if (learn_buffer == NULL)
59271 ++ learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
59272 ++ if (learn_buffer_user == NULL)
59273 ++ learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
59274 ++ if (learn_buffer == NULL) {
59275 ++ retval = -ENOMEM;
59276 ++ goto out_error;
59277 ++ }
59278 ++ if (learn_buffer_user == NULL) {
59279 ++ retval = -ENOMEM;
59280 ++ goto out_error;
59281 ++ }
59282 ++ learn_buffer_len = 0;
59283 ++ learn_buffer_user_len = 0;
59284 ++ gr_learn_attached = 1;
59285 ++out_error:
59286 ++ up(&gr_learn_user_sem);
59287 ++ return retval;
59288 ++ }
59289 ++ return 0;
59290 ++}
59291 ++
59292 ++static int
59293 ++close_learn(struct inode *inode, struct file *file)
59294 ++{
59295 ++ char *tmp;
59296 ++
59297 ++ if (file->f_mode & FMODE_READ) {
59298 ++ down(&gr_learn_user_sem);
59299 ++ if (learn_buffer != NULL) {
59300 ++ spin_lock(&gr_learn_lock);
59301 ++ tmp = learn_buffer;
59302 ++ learn_buffer = NULL;
59303 ++ spin_unlock(&gr_learn_lock);
59304 ++ vfree(tmp);
59305 ++ }
59306 ++ if (learn_buffer_user != NULL) {
59307 ++ vfree(learn_buffer_user);
59308 ++ learn_buffer_user = NULL;
59309 ++ }
59310 ++ learn_buffer_len = 0;
59311 ++ learn_buffer_user_len = 0;
59312 ++ gr_learn_attached = 0;
59313 ++ up(&gr_learn_user_sem);
59314 ++ }
59315 ++
59316 ++ return 0;
59317 ++}
59318 ++
59319 ++struct file_operations grsec_fops = {
59320 ++ .read = read_learn,
59321 ++ .write = write_grsec_handler,
59322 ++ .open = open_learn,
59323 ++ .release = close_learn,
59324 ++ .poll = poll_learn,
59325 ++};
59326 +diff -urNp linux-2.6.27.7/grsecurity/gracl_res.c linux-2.6.27.7/grsecurity/gracl_res.c
59327 +--- linux-2.6.27.7/grsecurity/gracl_res.c 1969-12-31 19:00:00.000000000 -0500
59328 ++++ linux-2.6.27.7/grsecurity/gracl_res.c 2008-11-18 03:38:45.000000000 -0500
59329 +@@ -0,0 +1,45 @@
59330 ++#include <linux/kernel.h>
59331 ++#include <linux/sched.h>
59332 ++#include <linux/gracl.h>
59333 ++#include <linux/grinternal.h>
59334 ++
59335 ++static const char *restab_log[] = {
59336 ++ [RLIMIT_CPU] = "RLIMIT_CPU",
59337 ++ [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
59338 ++ [RLIMIT_DATA] = "RLIMIT_DATA",
59339 ++ [RLIMIT_STACK] = "RLIMIT_STACK",
59340 ++ [RLIMIT_CORE] = "RLIMIT_CORE",
59341 ++ [RLIMIT_RSS] = "RLIMIT_RSS",
59342 ++ [RLIMIT_NPROC] = "RLIMIT_NPROC",
59343 ++ [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
59344 ++ [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
59345 ++ [RLIMIT_AS] = "RLIMIT_AS",
59346 ++ [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
59347 ++ [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH"
59348 ++};
59349 ++
59350 ++void
59351 ++gr_log_resource(const struct task_struct *task,
59352 ++ const int res, const unsigned long wanted, const int gt)
59353 ++{
59354 ++ if (res == RLIMIT_NPROC &&
59355 ++ (cap_raised(task->cap_effective, CAP_SYS_ADMIN) ||
59356 ++ cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
59357 ++ return;
59358 ++ else if (res == RLIMIT_MEMLOCK &&
59359 ++ cap_raised(task->cap_effective, CAP_IPC_LOCK))
59360 ++ return;
59361 ++
59362 ++ if (!gr_acl_is_enabled() && !grsec_resource_logging)
59363 ++ return;
59364 ++
59365 ++ preempt_disable();
59366 ++
59367 ++ if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
59368 ++ (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
59369 ++ task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
59370 ++ gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
59371 ++ preempt_enable_no_resched();
59372 ++
59373 ++ return;
59374 ++}
59375 +diff -urNp linux-2.6.27.7/grsecurity/gracl_segv.c linux-2.6.27.7/grsecurity/gracl_segv.c
59376 +--- linux-2.6.27.7/grsecurity/gracl_segv.c 1969-12-31 19:00:00.000000000 -0500
59377 ++++ linux-2.6.27.7/grsecurity/gracl_segv.c 2008-11-18 03:38:45.000000000 -0500
59378 +@@ -0,0 +1,304 @@
59379 ++#include <linux/kernel.h>
59380 ++#include <linux/mm.h>
59381 ++#include <asm/uaccess.h>
59382 ++#include <asm/errno.h>
59383 ++#include <asm/mman.h>
59384 ++#include <net/sock.h>
59385 ++#include <linux/file.h>
59386 ++#include <linux/fs.h>
59387 ++#include <linux/net.h>
59388 ++#include <linux/in.h>
59389 ++#include <linux/smp_lock.h>
59390 ++#include <linux/slab.h>
59391 ++#include <linux/types.h>
59392 ++#include <linux/sched.h>
59393 ++#include <linux/timer.h>
59394 ++#include <linux/gracl.h>
59395 ++#include <linux/grsecurity.h>
59396 ++#include <linux/grinternal.h>
59397 ++
59398 ++static struct crash_uid *uid_set;
59399 ++static unsigned short uid_used;
59400 ++static DEFINE_SPINLOCK(gr_uid_lock);
59401 ++extern rwlock_t gr_inode_lock;
59402 ++extern struct acl_subject_label *
59403 ++ lookup_acl_subj_label(const ino_t inode, const dev_t dev,
59404 ++ struct acl_role_label *role);
59405 ++extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
59406 ++
59407 ++int
59408 ++gr_init_uidset(void)
59409 ++{
59410 ++ uid_set =
59411 ++ kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
59412 ++ uid_used = 0;
59413 ++
59414 ++ return uid_set ? 1 : 0;
59415 ++}
59416 ++
59417 ++void
59418 ++gr_free_uidset(void)
59419 ++{
59420 ++ if (uid_set)
59421 ++ kfree(uid_set);
59422 ++
59423 ++ return;
59424 ++}
59425 ++
59426 ++int
59427 ++gr_find_uid(const uid_t uid)
59428 ++{
59429 ++ struct crash_uid *tmp = uid_set;
59430 ++ uid_t buid;
59431 ++ int low = 0, high = uid_used - 1, mid;
59432 ++
59433 ++ while (high >= low) {
59434 ++ mid = (low + high) >> 1;
59435 ++ buid = tmp[mid].uid;
59436 ++ if (buid == uid)
59437 ++ return mid;
59438 ++ if (buid > uid)
59439 ++ high = mid - 1;
59440 ++ if (buid < uid)
59441 ++ low = mid + 1;
59442 ++ }
59443 ++
59444 ++ return -1;
59445 ++}
59446 ++
59447 ++static __inline__ void
59448 ++gr_insertsort(void)
59449 ++{
59450 ++ unsigned short i, j;
59451 ++ struct crash_uid index;
59452 ++
59453 ++ for (i = 1; i < uid_used; i++) {
59454 ++ index = uid_set[i];
59455 ++ j = i;
59456 ++ while ((j > 0) && uid_set[j - 1].uid > index.uid) {
59457 ++ uid_set[j] = uid_set[j - 1];
59458 ++ j--;
59459 ++ }
59460 ++ uid_set[j] = index;
59461 ++ }
59462 ++
59463 ++ return;
59464 ++}
59465 ++
59466 ++static __inline__ void
59467 ++gr_insert_uid(const uid_t uid, const unsigned long expires)
59468 ++{
59469 ++ int loc;
59470 ++
59471 ++ if (uid_used == GR_UIDTABLE_MAX)
59472 ++ return;
59473 ++
59474 ++ loc = gr_find_uid(uid);
59475 ++
59476 ++ if (loc >= 0) {
59477 ++ uid_set[loc].expires = expires;
59478 ++ return;
59479 ++ }
59480 ++
59481 ++ uid_set[uid_used].uid = uid;
59482 ++ uid_set[uid_used].expires = expires;
59483 ++ uid_used++;
59484 ++
59485 ++ gr_insertsort();
59486 ++
59487 ++ return;
59488 ++}
59489 ++
59490 ++void
59491 ++gr_remove_uid(const unsigned short loc)
59492 ++{
59493 ++ unsigned short i;
59494 ++
59495 ++ for (i = loc + 1; i < uid_used; i++)
59496 ++ uid_set[i - 1] = uid_set[i];
59497 ++
59498 ++ uid_used--;
59499 ++
59500 ++ return;
59501 ++}
59502 ++
59503 ++int
59504 ++gr_check_crash_uid(const uid_t uid)
59505 ++{
59506 ++ int loc;
59507 ++ int ret = 0;
59508 ++
59509 ++ if (unlikely(!gr_acl_is_enabled()))
59510 ++ return 0;
59511 ++
59512 ++ spin_lock(&gr_uid_lock);
59513 ++ loc = gr_find_uid(uid);
59514 ++
59515 ++ if (loc < 0)
59516 ++ goto out_unlock;
59517 ++
59518 ++ if (time_before_eq(uid_set[loc].expires, get_seconds()))
59519 ++ gr_remove_uid(loc);
59520 ++ else
59521 ++ ret = 1;
59522 ++
59523 ++out_unlock:
59524 ++ spin_unlock(&gr_uid_lock);
59525 ++ return ret;
59526 ++}
59527 ++
59528 ++static __inline__ int
59529 ++proc_is_setxid(const struct task_struct *task)
59530 ++{
59531 ++ if (task->uid != task->euid || task->uid != task->suid ||
59532 ++ task->uid != task->fsuid)
59533 ++ return 1;
59534 ++ if (task->gid != task->egid || task->gid != task->sgid ||
59535 ++ task->gid != task->fsgid)
59536 ++ return 1;
59537 ++
59538 ++ return 0;
59539 ++}
59540 ++static __inline__ int
59541 ++gr_fake_force_sig(int sig, struct task_struct *t)
59542 ++{
59543 ++ unsigned long int flags;
59544 ++ int ret, blocked, ignored;
59545 ++ struct k_sigaction *action;
59546 ++
59547 ++ spin_lock_irqsave(&t->sighand->siglock, flags);
59548 ++ action = &t->sighand->action[sig-1];
59549 ++ ignored = action->sa.sa_handler == SIG_IGN;
59550 ++ blocked = sigismember(&t->blocked, sig);
59551 ++ if (blocked || ignored) {
59552 ++ action->sa.sa_handler = SIG_DFL;
59553 ++ if (blocked) {
59554 ++ sigdelset(&t->blocked, sig);
59555 ++ recalc_sigpending_and_wake(t);
59556 ++ }
59557 ++ }
59558 ++ if (action->sa.sa_handler == SIG_DFL)
59559 ++ t->signal->flags &= ~SIGNAL_UNKILLABLE;
59560 ++ ret = specific_send_sig_info(sig, SEND_SIG_PRIV, t);
59561 ++
59562 ++ spin_unlock_irqrestore(&t->sighand->siglock, flags);
59563 ++
59564 ++ return ret;
59565 ++}
59566 ++
59567 ++void
59568 ++gr_handle_crash(struct task_struct *task, const int sig)
59569 ++{
59570 ++ struct acl_subject_label *curr;
59571 ++ struct acl_subject_label *curr2;
59572 ++ struct task_struct *tsk, *tsk2;
59573 ++
59574 ++ if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
59575 ++ return;
59576 ++
59577 ++ if (unlikely(!gr_acl_is_enabled()))
59578 ++ return;
59579 ++
59580 ++ curr = task->acl;
59581 ++
59582 ++ if (!(curr->resmask & (1 << GR_CRASH_RES)))
59583 ++ return;
59584 ++
59585 ++ if (time_before_eq(curr->expires, get_seconds())) {
59586 ++ curr->expires = 0;
59587 ++ curr->crashes = 0;
59588 ++ }
59589 ++
59590 ++ curr->crashes++;
59591 ++
59592 ++ if (!curr->expires)
59593 ++ curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
59594 ++
59595 ++ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
59596 ++ time_after(curr->expires, get_seconds())) {
59597 ++ if (task->uid && proc_is_setxid(task)) {
59598 ++ gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
59599 ++ spin_lock(&gr_uid_lock);
59600 ++ gr_insert_uid(task->uid, curr->expires);
59601 ++ spin_unlock(&gr_uid_lock);
59602 ++ curr->expires = 0;
59603 ++ curr->crashes = 0;
59604 ++ read_lock(&tasklist_lock);
59605 ++ do_each_thread(tsk2, tsk) {
59606 ++ if (tsk != task && tsk->uid == task->uid)
59607 ++ gr_fake_force_sig(SIGKILL, tsk);
59608 ++ } while_each_thread(tsk2, tsk);
59609 ++ read_unlock(&tasklist_lock);
59610 ++ } else {
59611 ++ gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
59612 ++ read_lock(&tasklist_lock);
59613 ++ do_each_thread(tsk2, tsk) {
59614 ++ if (likely(tsk != task)) {
59615 ++ curr2 = tsk->acl;
59616 ++
59617 ++ if (curr2->device == curr->device &&
59618 ++ curr2->inode == curr->inode)
59619 ++ gr_fake_force_sig(SIGKILL, tsk);
59620 ++ }
59621 ++ } while_each_thread(tsk2, tsk);
59622 ++ read_unlock(&tasklist_lock);
59623 ++ }
59624 ++ }
59625 ++
59626 ++ return;
59627 ++}
59628 ++
59629 ++int
59630 ++gr_check_crash_exec(const struct file *filp)
59631 ++{
59632 ++ struct acl_subject_label *curr;
59633 ++
59634 ++ if (unlikely(!gr_acl_is_enabled()))
59635 ++ return 0;
59636 ++
59637 ++ read_lock(&gr_inode_lock);
59638 ++ curr = lookup_acl_subj_label(filp->f_path.dentry->d_inode->i_ino,
59639 ++ filp->f_path.dentry->d_inode->i_sb->s_dev,
59640 ++ current->role);
59641 ++ read_unlock(&gr_inode_lock);
59642 ++
59643 ++ if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
59644 ++ (!curr->crashes && !curr->expires))
59645 ++ return 0;
59646 ++
59647 ++ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
59648 ++ time_after(curr->expires, get_seconds()))
59649 ++ return 1;
59650 ++ else if (time_before_eq(curr->expires, get_seconds())) {
59651 ++ curr->crashes = 0;
59652 ++ curr->expires = 0;
59653 ++ }
59654 ++
59655 ++ return 0;
59656 ++}
59657 ++
59658 ++void
59659 ++gr_handle_alertkill(struct task_struct *task)
59660 ++{
59661 ++ struct acl_subject_label *curracl;
59662 ++ __u32 curr_ip;
59663 ++ struct task_struct *p, *p2;
59664 ++
59665 ++ if (unlikely(!gr_acl_is_enabled()))
59666 ++ return;
59667 ++
59668 ++ curracl = task->acl;
59669 ++ curr_ip = task->signal->curr_ip;
59670 ++
59671 ++ if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
59672 ++ read_lock(&tasklist_lock);
59673 ++ do_each_thread(p2, p) {
59674 ++ if (p->signal->curr_ip == curr_ip)
59675 ++ gr_fake_force_sig(SIGKILL, p);
59676 ++ } while_each_thread(p2, p);
59677 ++ read_unlock(&tasklist_lock);
59678 ++ } else if (curracl->mode & GR_KILLPROC)
59679 ++ gr_fake_force_sig(SIGKILL, task);
59680 ++
59681 ++ return;
59682 ++}
59683 +diff -urNp linux-2.6.27.7/grsecurity/gracl_shm.c linux-2.6.27.7/grsecurity/gracl_shm.c
59684 +--- linux-2.6.27.7/grsecurity/gracl_shm.c 1969-12-31 19:00:00.000000000 -0500
59685 ++++ linux-2.6.27.7/grsecurity/gracl_shm.c 2008-11-18 03:38:45.000000000 -0500
59686 +@@ -0,0 +1,33 @@
59687 ++#include <linux/kernel.h>
59688 ++#include <linux/mm.h>
59689 ++#include <linux/sched.h>
59690 ++#include <linux/file.h>
59691 ++#include <linux/ipc.h>
59692 ++#include <linux/gracl.h>
59693 ++#include <linux/grsecurity.h>
59694 ++#include <linux/grinternal.h>
59695 ++
59696 ++int
59697 ++gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
59698 ++ const time_t shm_createtime, const uid_t cuid, const int shmid)
59699 ++{
59700 ++ struct task_struct *task;
59701 ++
59702 ++ if (!gr_acl_is_enabled())
59703 ++ return 1;
59704 ++
59705 ++ task = find_task_by_vpid(shm_cprid);
59706 ++
59707 ++ if (unlikely(!task))
59708 ++ task = find_task_by_vpid(shm_lapid);
59709 ++
59710 ++ if (unlikely(task && (time_before_eq((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
59711 ++ (task->pid == shm_lapid)) &&
59712 ++ (task->acl->mode & GR_PROTSHM) &&
59713 ++ (task->acl != current->acl))) {
59714 ++ gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
59715 ++ return 0;
59716 ++ }
59717 ++
59718 ++ return 1;
59719 ++}
59720 +diff -urNp linux-2.6.27.7/grsecurity/grsec_chdir.c linux-2.6.27.7/grsecurity/grsec_chdir.c
59721 +--- linux-2.6.27.7/grsecurity/grsec_chdir.c 1969-12-31 19:00:00.000000000 -0500
59722 ++++ linux-2.6.27.7/grsecurity/grsec_chdir.c 2008-11-18 03:38:45.000000000 -0500
59723 +@@ -0,0 +1,19 @@
59724 ++#include <linux/kernel.h>
59725 ++#include <linux/sched.h>
59726 ++#include <linux/fs.h>
59727 ++#include <linux/file.h>
59728 ++#include <linux/grsecurity.h>
59729 ++#include <linux/grinternal.h>
59730 ++
59731 ++void
59732 ++gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
59733 ++{
59734 ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
59735 ++ if ((grsec_enable_chdir && grsec_enable_group &&
59736 ++ in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
59737 ++ !grsec_enable_group)) {
59738 ++ gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
59739 ++ }
59740 ++#endif
59741 ++ return;
59742 ++}
59743 +diff -urNp linux-2.6.27.7/grsecurity/grsec_chroot.c linux-2.6.27.7/grsecurity/grsec_chroot.c
59744 +--- linux-2.6.27.7/grsecurity/grsec_chroot.c 1969-12-31 19:00:00.000000000 -0500
59745 ++++ linux-2.6.27.7/grsecurity/grsec_chroot.c 2008-11-18 03:38:45.000000000 -0500
59746 +@@ -0,0 +1,336 @@
59747 ++#include <linux/kernel.h>
59748 ++#include <linux/module.h>
59749 ++#include <linux/sched.h>
59750 ++#include <linux/file.h>
59751 ++#include <linux/fs.h>
59752 ++#include <linux/mount.h>
59753 ++#include <linux/types.h>
59754 ++#include <linux/pid_namespace.h>
59755 ++#include <linux/grsecurity.h>
59756 ++#include <linux/grinternal.h>
59757 ++
59758 ++int
59759 ++gr_handle_chroot_unix(const pid_t pid)
59760 ++{
59761 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
59762 ++ struct pid *spid = NULL;
59763 ++
59764 ++ if (unlikely(!grsec_enable_chroot_unix))
59765 ++ return 1;
59766 ++
59767 ++ if (likely(!proc_is_chrooted(current)))
59768 ++ return 1;
59769 ++
59770 ++ read_lock(&tasklist_lock);
59771 ++
59772 ++ spid = find_vpid(pid);
59773 ++ if (spid) {
59774 ++ struct task_struct *p;
59775 ++ p = pid_task(spid, PIDTYPE_PID);
59776 ++ task_lock(p);
59777 ++ if (unlikely(!have_same_root(current, p))) {
59778 ++ task_unlock(p);
59779 ++ read_unlock(&tasklist_lock);
59780 ++ gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
59781 ++ return 0;
59782 ++ }
59783 ++ task_unlock(p);
59784 ++ }
59785 ++ read_unlock(&tasklist_lock);
59786 ++#endif
59787 ++ return 1;
59788 ++}
59789 ++
59790 ++int
59791 ++gr_handle_chroot_nice(void)
59792 ++{
59793 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
59794 ++ if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
59795 ++ gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
59796 ++ return -EPERM;
59797 ++ }
59798 ++#endif
59799 ++ return 0;
59800 ++}
59801 ++
59802 ++int
59803 ++gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
59804 ++{
59805 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
59806 ++ if (grsec_enable_chroot_nice && (niceval < task_nice(p))
59807 ++ && proc_is_chrooted(current)) {
59808 ++ gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
59809 ++ return -EACCES;
59810 ++ }
59811 ++#endif
59812 ++ return 0;
59813 ++}
59814 ++
59815 ++int
59816 ++gr_handle_chroot_rawio(const struct inode *inode)
59817 ++{
59818 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
59819 ++ if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
59820 ++ inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
59821 ++ return 1;
59822 ++#endif
59823 ++ return 0;
59824 ++}
59825 ++
59826 ++int
59827 ++gr_pid_is_chrooted(struct task_struct *p)
59828 ++{
59829 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
59830 ++ if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL)
59831 ++ return 0;
59832 ++
59833 ++ task_lock(p);
59834 ++ if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
59835 ++ !have_same_root(current, p)) {
59836 ++ task_unlock(p);
59837 ++ return 1;
59838 ++ }
59839 ++ task_unlock(p);
59840 ++#endif
59841 ++ return 0;
59842 ++}
59843 ++
59844 ++EXPORT_SYMBOL(gr_pid_is_chrooted);
59845 ++
59846 ++#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
59847 ++int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
59848 ++{
59849 ++ struct dentry *dentry = (struct dentry *)u_dentry;
59850 ++ struct vfsmount *mnt = (struct vfsmount *)u_mnt;
59851 ++ struct dentry *realroot;
59852 ++ struct vfsmount *realrootmnt;
59853 ++ struct dentry *currentroot;
59854 ++ struct vfsmount *currentmnt;
59855 ++ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
59856 ++ int ret = 1;
59857 ++
59858 ++ read_lock(&reaper->fs->lock);
59859 ++ realrootmnt = mntget(reaper->fs->root.mnt);
59860 ++ realroot = dget(reaper->fs->root.dentry);
59861 ++ read_unlock(&reaper->fs->lock);
59862 ++
59863 ++ read_lock(&current->fs->lock);
59864 ++ currentmnt = mntget(current->fs->root.mnt);
59865 ++ currentroot = dget(current->fs->root.dentry);
59866 ++ read_unlock(&current->fs->lock);
59867 ++
59868 ++ spin_lock(&dcache_lock);
59869 ++ for (;;) {
59870 ++ if (unlikely((dentry == realroot && mnt == realrootmnt)
59871 ++ || (dentry == currentroot && mnt == currentmnt)))
59872 ++ break;
59873 ++ if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
59874 ++ if (mnt->mnt_parent == mnt)
59875 ++ break;
59876 ++ dentry = mnt->mnt_mountpoint;
59877 ++ mnt = mnt->mnt_parent;
59878 ++ continue;
59879 ++ }
59880 ++ dentry = dentry->d_parent;
59881 ++ }
59882 ++ spin_unlock(&dcache_lock);
59883 ++
59884 ++ dput(currentroot);
59885 ++ mntput(currentmnt);
59886 ++
59887 ++ /* access is outside of chroot */
59888 ++ if (dentry == realroot && mnt == realrootmnt)
59889 ++ ret = 0;
59890 ++
59891 ++ dput(realroot);
59892 ++ mntput(realrootmnt);
59893 ++ return ret;
59894 ++}
59895 ++#endif
59896 ++
59897 ++int
59898 ++gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
59899 ++{
59900 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
59901 ++ if (!grsec_enable_chroot_fchdir)
59902 ++ return 1;
59903 ++
59904 ++ if (!proc_is_chrooted(current))
59905 ++ return 1;
59906 ++ else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
59907 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
59908 ++ return 0;
59909 ++ }
59910 ++#endif
59911 ++ return 1;
59912 ++}
59913 ++
59914 ++int
59915 ++gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
59916 ++ const time_t shm_createtime)
59917 ++{
59918 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
59919 ++ struct pid *pid = NULL;
59920 ++ time_t starttime;
59921 ++
59922 ++ if (unlikely(!grsec_enable_chroot_shmat))
59923 ++ return 1;
59924 ++
59925 ++ if (likely(!proc_is_chrooted(current)))
59926 ++ return 1;
59927 ++
59928 ++ read_lock(&tasklist_lock);
59929 ++
59930 ++ pid = find_vpid(shm_cprid);
59931 ++ if (pid) {
59932 ++ struct task_struct *p;
59933 ++ p = pid_task(pid, PIDTYPE_PID);
59934 ++ task_lock(p);
59935 ++ starttime = p->start_time.tv_sec;
59936 ++ if (unlikely(!have_same_root(current, p) &&
59937 ++ time_before_eq((unsigned long)starttime, (unsigned long)shm_createtime))) {
59938 ++ task_unlock(p);
59939 ++ read_unlock(&tasklist_lock);
59940 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
59941 ++ return 0;
59942 ++ }
59943 ++ task_unlock(p);
59944 ++ } else {
59945 ++ pid = find_vpid(shm_lapid);
59946 ++ if (pid) {
59947 ++ struct task_struct *p;
59948 ++ p = pid_task(pid, PIDTYPE_PID);
59949 ++ task_lock(p);
59950 ++ if (unlikely(!have_same_root(current, p))) {
59951 ++ task_unlock(p);
59952 ++ read_unlock(&tasklist_lock);
59953 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
59954 ++ return 0;
59955 ++ }
59956 ++ task_unlock(p);
59957 ++ }
59958 ++ }
59959 ++
59960 ++ read_unlock(&tasklist_lock);
59961 ++#endif
59962 ++ return 1;
59963 ++}
59964 ++
59965 ++void
59966 ++gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
59967 ++{
59968 ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
59969 ++ if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
59970 ++ gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
59971 ++#endif
59972 ++ return;
59973 ++}
59974 ++
59975 ++int
59976 ++gr_handle_chroot_mknod(const struct dentry *dentry,
59977 ++ const struct vfsmount *mnt, const int mode)
59978 ++{
59979 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
59980 ++ if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) &&
59981 ++ proc_is_chrooted(current)) {
59982 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
59983 ++ return -EPERM;
59984 ++ }
59985 ++#endif
59986 ++ return 0;
59987 ++}
59988 ++
59989 ++int
59990 ++gr_handle_chroot_mount(const struct dentry *dentry,
59991 ++ const struct vfsmount *mnt, const char *dev_name)
59992 ++{
59993 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
59994 ++ if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
59995 ++ gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
59996 ++ return -EPERM;
59997 ++ }
59998 ++#endif
59999 ++ return 0;
60000 ++}
60001 ++
60002 ++int
60003 ++gr_handle_chroot_pivot(void)
60004 ++{
60005 ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
60006 ++ if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
60007 ++ gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
60008 ++ return -EPERM;
60009 ++ }
60010 ++#endif
60011 ++ return 0;
60012 ++}
60013 ++
60014 ++int
60015 ++gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
60016 ++{
60017 ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
60018 ++ if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
60019 ++ !gr_is_outside_chroot(dentry, mnt)) {
60020 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
60021 ++ return -EPERM;
60022 ++ }
60023 ++#endif
60024 ++ return 0;
60025 ++}
60026 ++
60027 ++void
60028 ++gr_handle_chroot_caps(struct task_struct *task)
60029 ++{
60030 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
60031 ++ if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
60032 ++ kernel_cap_t chroot_caps = GR_CHROOT_CAPS;
60033 ++ task->cap_permitted =
60034 ++ cap_drop(task->cap_permitted, chroot_caps);
60035 ++ task->cap_inheritable =
60036 ++ cap_drop(task->cap_inheritable, chroot_caps);
60037 ++ task->cap_effective =
60038 ++ cap_drop(task->cap_effective, chroot_caps);
60039 ++ }
60040 ++#endif
60041 ++ return;
60042 ++}
60043 ++
60044 ++int
60045 ++gr_handle_chroot_sysctl(const int op)
60046 ++{
60047 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
60048 ++ if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
60049 ++ && (op & MAY_WRITE))
60050 ++ return -EACCES;
60051 ++#endif
60052 ++ return 0;
60053 ++}
60054 ++
60055 ++void
60056 ++gr_handle_chroot_chdir(struct path *path)
60057 ++{
60058 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
60059 ++ if (grsec_enable_chroot_chdir)
60060 ++ set_fs_pwd(current->fs, path);
60061 ++#endif
60062 ++ return;
60063 ++}
60064 ++
60065 ++int
60066 ++gr_handle_chroot_chmod(const struct dentry *dentry,
60067 ++ const struct vfsmount *mnt, const int mode)
60068 ++{
60069 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
60070 ++ if (grsec_enable_chroot_chmod &&
60071 ++ ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
60072 ++ proc_is_chrooted(current)) {
60073 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
60074 ++ return -EPERM;
60075 ++ }
60076 ++#endif
60077 ++ return 0;
60078 ++}
60079 ++
60080 ++#ifdef CONFIG_SECURITY
60081 ++EXPORT_SYMBOL(gr_handle_chroot_caps);
60082 ++#endif
60083 +diff -urNp linux-2.6.27.7/grsecurity/grsec_disabled.c linux-2.6.27.7/grsecurity/grsec_disabled.c
60084 +--- linux-2.6.27.7/grsecurity/grsec_disabled.c 1969-12-31 19:00:00.000000000 -0500
60085 ++++ linux-2.6.27.7/grsecurity/grsec_disabled.c 2008-11-18 03:38:45.000000000 -0500
60086 +@@ -0,0 +1,418 @@
60087 ++#include <linux/kernel.h>
60088 ++#include <linux/module.h>
60089 ++#include <linux/sched.h>
60090 ++#include <linux/file.h>
60091 ++#include <linux/fs.h>
60092 ++#include <linux/kdev_t.h>
60093 ++#include <linux/net.h>
60094 ++#include <linux/in.h>
60095 ++#include <linux/ip.h>
60096 ++#include <linux/skbuff.h>
60097 ++#include <linux/sysctl.h>
60098 ++
60099 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
60100 ++void
60101 ++pax_set_initial_flags(struct linux_binprm *bprm)
60102 ++{
60103 ++ return;
60104 ++}
60105 ++#endif
60106 ++
60107 ++#ifdef CONFIG_SYSCTL
60108 ++__u32
60109 ++gr_handle_sysctl(const struct ctl_table * table, const int op)
60110 ++{
60111 ++ return 0;
60112 ++}
60113 ++#endif
60114 ++
60115 ++int
60116 ++gr_acl_is_enabled(void)
60117 ++{
60118 ++ return 0;
60119 ++}
60120 ++
60121 ++int
60122 ++gr_handle_rawio(const struct inode *inode)
60123 ++{
60124 ++ return 0;
60125 ++}
60126 ++
60127 ++void
60128 ++gr_acl_handle_psacct(struct task_struct *task, const long code)
60129 ++{
60130 ++ return;
60131 ++}
60132 ++
60133 ++int
60134 ++gr_handle_ptrace(struct task_struct *task, const long request)
60135 ++{
60136 ++ return 0;
60137 ++}
60138 ++
60139 ++int
60140 ++gr_handle_proc_ptrace(struct task_struct *task)
60141 ++{
60142 ++ return 0;
60143 ++}
60144 ++
60145 ++void
60146 ++gr_learn_resource(const struct task_struct *task,
60147 ++ const int res, const unsigned long wanted, const int gt)
60148 ++{
60149 ++ return;
60150 ++}
60151 ++
60152 ++int
60153 ++gr_set_acls(const int type)
60154 ++{
60155 ++ return 0;
60156 ++}
60157 ++
60158 ++int
60159 ++gr_check_hidden_task(const struct task_struct *tsk)
60160 ++{
60161 ++ return 0;
60162 ++}
60163 ++
60164 ++int
60165 ++gr_check_protected_task(const struct task_struct *task)
60166 ++{
60167 ++ return 0;
60168 ++}
60169 ++
60170 ++void
60171 ++gr_copy_label(struct task_struct *tsk)
60172 ++{
60173 ++ return;
60174 ++}
60175 ++
60176 ++void
60177 ++gr_set_pax_flags(struct task_struct *task)
60178 ++{
60179 ++ return;
60180 ++}
60181 ++
60182 ++int
60183 ++gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
60184 ++{
60185 ++ return 0;
60186 ++}
60187 ++
60188 ++void
60189 ++gr_handle_delete(const ino_t ino, const dev_t dev)
60190 ++{
60191 ++ return;
60192 ++}
60193 ++
60194 ++void
60195 ++gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
60196 ++{
60197 ++ return;
60198 ++}
60199 ++
60200 ++void
60201 ++gr_handle_crash(struct task_struct *task, const int sig)
60202 ++{
60203 ++ return;
60204 ++}
60205 ++
60206 ++int
60207 ++gr_check_crash_exec(const struct file *filp)
60208 ++{
60209 ++ return 0;
60210 ++}
60211 ++
60212 ++int
60213 ++gr_check_crash_uid(const uid_t uid)
60214 ++{
60215 ++ return 0;
60216 ++}
60217 ++
60218 ++void
60219 ++gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
60220 ++ struct dentry *old_dentry,
60221 ++ struct dentry *new_dentry,
60222 ++ struct vfsmount *mnt, const __u8 replace)
60223 ++{
60224 ++ return;
60225 ++}
60226 ++
60227 ++int
60228 ++gr_search_socket(const int family, const int type, const int protocol)
60229 ++{
60230 ++ return 1;
60231 ++}
60232 ++
60233 ++int
60234 ++gr_search_connectbind(const int mode, const struct socket *sock,
60235 ++ const struct sockaddr_in *addr)
60236 ++{
60237 ++ return 1;
60238 ++}
60239 ++
60240 ++int
60241 ++gr_task_is_capable(struct task_struct *task, const int cap)
60242 ++{
60243 ++ return 1;
60244 ++}
60245 ++
60246 ++int
60247 ++gr_is_capable_nolog(const int cap)
60248 ++{
60249 ++ return 1;
60250 ++}
60251 ++
60252 ++void
60253 ++gr_handle_alertkill(struct task_struct *task)
60254 ++{
60255 ++ return;
60256 ++}
60257 ++
60258 ++__u32
60259 ++gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
60260 ++{
60261 ++ return 1;
60262 ++}
60263 ++
60264 ++__u32
60265 ++gr_acl_handle_hidden_file(const struct dentry * dentry,
60266 ++ const struct vfsmount * mnt)
60267 ++{
60268 ++ return 1;
60269 ++}
60270 ++
60271 ++__u32
60272 ++gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
60273 ++ const int fmode)
60274 ++{
60275 ++ return 1;
60276 ++}
60277 ++
60278 ++__u32
60279 ++gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
60280 ++{
60281 ++ return 1;
60282 ++}
60283 ++
60284 ++__u32
60285 ++gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
60286 ++{
60287 ++ return 1;
60288 ++}
60289 ++
60290 ++int
60291 ++gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
60292 ++ unsigned int *vm_flags)
60293 ++{
60294 ++ return 1;
60295 ++}
60296 ++
60297 ++__u32
60298 ++gr_acl_handle_truncate(const struct dentry * dentry,
60299 ++ const struct vfsmount * mnt)
60300 ++{
60301 ++ return 1;
60302 ++}
60303 ++
60304 ++__u32
60305 ++gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
60306 ++{
60307 ++ return 1;
60308 ++}
60309 ++
60310 ++__u32
60311 ++gr_acl_handle_access(const struct dentry * dentry,
60312 ++ const struct vfsmount * mnt, const int fmode)
60313 ++{
60314 ++ return 1;
60315 ++}
60316 ++
60317 ++__u32
60318 ++gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
60319 ++ mode_t mode)
60320 ++{
60321 ++ return 1;
60322 ++}
60323 ++
60324 ++__u32
60325 ++gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
60326 ++ mode_t mode)
60327 ++{
60328 ++ return 1;
60329 ++}
60330 ++
60331 ++__u32
60332 ++gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
60333 ++{
60334 ++ return 1;
60335 ++}
60336 ++
60337 ++void
60338 ++grsecurity_init(void)
60339 ++{
60340 ++ return;
60341 ++}
60342 ++
60343 ++__u32
60344 ++gr_acl_handle_mknod(const struct dentry * new_dentry,
60345 ++ const struct dentry * parent_dentry,
60346 ++ const struct vfsmount * parent_mnt,
60347 ++ const int mode)
60348 ++{
60349 ++ return 1;
60350 ++}
60351 ++
60352 ++__u32
60353 ++gr_acl_handle_mkdir(const struct dentry * new_dentry,
60354 ++ const struct dentry * parent_dentry,
60355 ++ const struct vfsmount * parent_mnt)
60356 ++{
60357 ++ return 1;
60358 ++}
60359 ++
60360 ++__u32
60361 ++gr_acl_handle_symlink(const struct dentry * new_dentry,
60362 ++ const struct dentry * parent_dentry,
60363 ++ const struct vfsmount * parent_mnt, const char *from)
60364 ++{
60365 ++ return 1;
60366 ++}
60367 ++
60368 ++__u32
60369 ++gr_acl_handle_link(const struct dentry * new_dentry,
60370 ++ const struct dentry * parent_dentry,
60371 ++ const struct vfsmount * parent_mnt,
60372 ++ const struct dentry * old_dentry,
60373 ++ const struct vfsmount * old_mnt, const char *to)
60374 ++{
60375 ++ return 1;
60376 ++}
60377 ++
60378 ++int
60379 ++gr_acl_handle_rename(const struct dentry *new_dentry,
60380 ++ const struct dentry *parent_dentry,
60381 ++ const struct vfsmount *parent_mnt,
60382 ++ const struct dentry *old_dentry,
60383 ++ const struct inode *old_parent_inode,
60384 ++ const struct vfsmount *old_mnt, const char *newname)
60385 ++{
60386 ++ return 0;
60387 ++}
60388 ++
60389 ++int
60390 ++gr_acl_handle_filldir(const struct file *file, const char *name,
60391 ++ const int namelen, const ino_t ino)
60392 ++{
60393 ++ return 1;
60394 ++}
60395 ++
60396 ++int
60397 ++gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
60398 ++ const time_t shm_createtime, const uid_t cuid, const int shmid)
60399 ++{
60400 ++ return 1;
60401 ++}
60402 ++
60403 ++int
60404 ++gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
60405 ++{
60406 ++ return 1;
60407 ++}
60408 ++
60409 ++int
60410 ++gr_search_accept(const struct socket *sock)
60411 ++{
60412 ++ return 1;
60413 ++}
60414 ++
60415 ++int
60416 ++gr_search_listen(const struct socket *sock)
60417 ++{
60418 ++ return 1;
60419 ++}
60420 ++
60421 ++int
60422 ++gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
60423 ++{
60424 ++ return 1;
60425 ++}
60426 ++
60427 ++__u32
60428 ++gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
60429 ++{
60430 ++ return 1;
60431 ++}
60432 ++
60433 ++__u32
60434 ++gr_acl_handle_creat(const struct dentry * dentry,
60435 ++ const struct dentry * p_dentry,
60436 ++ const struct vfsmount * p_mnt, const int fmode,
60437 ++ const int imode)
60438 ++{
60439 ++ return 1;
60440 ++}
60441 ++
60442 ++void
60443 ++gr_acl_handle_exit(void)
60444 ++{
60445 ++ return;
60446 ++}
60447 ++
60448 ++int
60449 ++gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
60450 ++{
60451 ++ return 1;
60452 ++}
60453 ++
60454 ++void
60455 ++gr_set_role_label(const uid_t uid, const gid_t gid)
60456 ++{
60457 ++ return;
60458 ++}
60459 ++
60460 ++int
60461 ++gr_acl_handle_procpidmem(const struct task_struct *task)
60462 ++{
60463 ++ return 0;
60464 ++}
60465 ++
60466 ++int
60467 ++gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
60468 ++{
60469 ++ return 1;
60470 ++}
60471 ++
60472 ++int
60473 ++gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
60474 ++{
60475 ++ return 1;
60476 ++}
60477 ++
60478 ++void
60479 ++gr_set_kernel_label(struct task_struct *task)
60480 ++{
60481 ++ return;
60482 ++}
60483 ++
60484 ++int
60485 ++gr_check_user_change(int real, int effective, int fs)
60486 ++{
60487 ++ return 0;
60488 ++}
60489 ++
60490 ++int
60491 ++gr_check_group_change(int real, int effective, int fs)
60492 ++{
60493 ++ return 0;
60494 ++}
60495 ++
60496 ++
60497 ++EXPORT_SYMBOL(gr_task_is_capable);
60498 ++EXPORT_SYMBOL(gr_is_capable_nolog);
60499 ++EXPORT_SYMBOL(gr_learn_resource);
60500 ++EXPORT_SYMBOL(gr_set_kernel_label);
60501 ++#ifdef CONFIG_SECURITY
60502 ++EXPORT_SYMBOL(gr_check_user_change);
60503 ++EXPORT_SYMBOL(gr_check_group_change);
60504 ++#endif
60505 +diff -urNp linux-2.6.27.7/grsecurity/grsec_exec.c linux-2.6.27.7/grsecurity/grsec_exec.c
60506 +--- linux-2.6.27.7/grsecurity/grsec_exec.c 1969-12-31 19:00:00.000000000 -0500
60507 ++++ linux-2.6.27.7/grsecurity/grsec_exec.c 2008-11-18 03:38:45.000000000 -0500
60508 +@@ -0,0 +1,88 @@
60509 ++#include <linux/kernel.h>
60510 ++#include <linux/sched.h>
60511 ++#include <linux/file.h>
60512 ++#include <linux/binfmts.h>
60513 ++#include <linux/smp_lock.h>
60514 ++#include <linux/fs.h>
60515 ++#include <linux/types.h>
60516 ++#include <linux/grdefs.h>
60517 ++#include <linux/grinternal.h>
60518 ++#include <linux/capability.h>
60519 ++
60520 ++#include <asm/uaccess.h>
60521 ++
60522 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
60523 ++static char gr_exec_arg_buf[132];
60524 ++static DECLARE_MUTEX(gr_exec_arg_sem);
60525 ++#endif
60526 ++
60527 ++int
60528 ++gr_handle_nproc(void)
60529 ++{
60530 ++#ifdef CONFIG_GRKERNSEC_EXECVE
60531 ++ if (grsec_enable_execve && current->user &&
60532 ++ (atomic_read(&current->user->processes) >
60533 ++ current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
60534 ++ !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
60535 ++ gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
60536 ++ return -EAGAIN;
60537 ++ }
60538 ++#endif
60539 ++ return 0;
60540 ++}
60541 ++
60542 ++void
60543 ++gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
60544 ++{
60545 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
60546 ++ char *grarg = gr_exec_arg_buf;
60547 ++ unsigned int i, x, execlen = 0;
60548 ++ char c;
60549 ++
60550 ++ if (!((grsec_enable_execlog && grsec_enable_group &&
60551 ++ in_group_p(grsec_audit_gid))
60552 ++ || (grsec_enable_execlog && !grsec_enable_group)))
60553 ++ return;
60554 ++
60555 ++ down(&gr_exec_arg_sem);
60556 ++ memset(grarg, 0, sizeof(gr_exec_arg_buf));
60557 ++
60558 ++ if (unlikely(argv == NULL))
60559 ++ goto log;
60560 ++
60561 ++ for (i = 0; i < bprm->argc && execlen < 128; i++) {
60562 ++ const char __user *p;
60563 ++ unsigned int len;
60564 ++
60565 ++ if (copy_from_user(&p, argv + i, sizeof(p)))
60566 ++ goto log;
60567 ++ if (!p)
60568 ++ goto log;
60569 ++ len = strnlen_user(p, 128 - execlen);
60570 ++ if (len > 128 - execlen)
60571 ++ len = 128 - execlen;
60572 ++ else if (len > 0)
60573 ++ len--;
60574 ++ if (copy_from_user(grarg + execlen, p, len))
60575 ++ goto log;
60576 ++
60577 ++ /* rewrite unprintable characters */
60578 ++ for (x = 0; x < len; x++) {
60579 ++ c = *(grarg + execlen + x);
60580 ++ if (c < 32 || c > 126)
60581 ++ *(grarg + execlen + x) = ' ';
60582 ++ }
60583 ++
60584 ++ execlen += len;
60585 ++ *(grarg + execlen) = ' ';
60586 ++ *(grarg + execlen + 1) = '\0';
60587 ++ execlen++;
60588 ++ }
60589 ++
60590 ++ log:
60591 ++ gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_path.dentry,
60592 ++ bprm->file->f_path.mnt, grarg);
60593 ++ up(&gr_exec_arg_sem);
60594 ++#endif
60595 ++ return;
60596 ++}
60597 +diff -urNp linux-2.6.27.7/grsecurity/grsec_fifo.c linux-2.6.27.7/grsecurity/grsec_fifo.c
60598 +--- linux-2.6.27.7/grsecurity/grsec_fifo.c 1969-12-31 19:00:00.000000000 -0500
60599 ++++ linux-2.6.27.7/grsecurity/grsec_fifo.c 2008-11-18 03:38:45.000000000 -0500
60600 +@@ -0,0 +1,22 @@
60601 ++#include <linux/kernel.h>
60602 ++#include <linux/sched.h>
60603 ++#include <linux/fs.h>
60604 ++#include <linux/file.h>
60605 ++#include <linux/grinternal.h>
60606 ++
60607 ++int
60608 ++gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
60609 ++ const struct dentry *dir, const int flag, const int acc_mode)
60610 ++{
60611 ++#ifdef CONFIG_GRKERNSEC_FIFO
60612 ++ if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
60613 ++ !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
60614 ++ (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
60615 ++ (current->fsuid != dentry->d_inode->i_uid)) {
60616 ++ if (!generic_permission(dentry->d_inode, acc_mode, NULL))
60617 ++ gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
60618 ++ return -EACCES;
60619 ++ }
60620 ++#endif
60621 ++ return 0;
60622 ++}
60623 +diff -urNp linux-2.6.27.7/grsecurity/grsec_fork.c linux-2.6.27.7/grsecurity/grsec_fork.c
60624 +--- linux-2.6.27.7/grsecurity/grsec_fork.c 1969-12-31 19:00:00.000000000 -0500
60625 ++++ linux-2.6.27.7/grsecurity/grsec_fork.c 2008-11-18 03:38:45.000000000 -0500
60626 +@@ -0,0 +1,15 @@
60627 ++#include <linux/kernel.h>
60628 ++#include <linux/sched.h>
60629 ++#include <linux/grsecurity.h>
60630 ++#include <linux/grinternal.h>
60631 ++#include <linux/errno.h>
60632 ++
60633 ++void
60634 ++gr_log_forkfail(const int retval)
60635 ++{
60636 ++#ifdef CONFIG_GRKERNSEC_FORKFAIL
60637 ++ if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
60638 ++ gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
60639 ++#endif
60640 ++ return;
60641 ++}
60642 +diff -urNp linux-2.6.27.7/grsecurity/grsec_init.c linux-2.6.27.7/grsecurity/grsec_init.c
60643 +--- linux-2.6.27.7/grsecurity/grsec_init.c 1969-12-31 19:00:00.000000000 -0500
60644 ++++ linux-2.6.27.7/grsecurity/grsec_init.c 2008-11-18 03:38:45.000000000 -0500
60645 +@@ -0,0 +1,230 @@
60646 ++#include <linux/kernel.h>
60647 ++#include <linux/sched.h>
60648 ++#include <linux/mm.h>
60649 ++#include <linux/smp_lock.h>
60650 ++#include <linux/gracl.h>
60651 ++#include <linux/slab.h>
60652 ++#include <linux/vmalloc.h>
60653 ++#include <linux/percpu.h>
60654 ++
60655 ++int grsec_enable_link;
60656 ++int grsec_enable_dmesg;
60657 ++int grsec_enable_fifo;
60658 ++int grsec_enable_execve;
60659 ++int grsec_enable_execlog;
60660 ++int grsec_enable_signal;
60661 ++int grsec_enable_forkfail;
60662 ++int grsec_enable_time;
60663 ++int grsec_enable_audit_textrel;
60664 ++int grsec_enable_group;
60665 ++int grsec_audit_gid;
60666 ++int grsec_enable_chdir;
60667 ++int grsec_enable_audit_ipc;
60668 ++int grsec_enable_mount;
60669 ++int grsec_enable_chroot_findtask;
60670 ++int grsec_enable_chroot_mount;
60671 ++int grsec_enable_chroot_shmat;
60672 ++int grsec_enable_chroot_fchdir;
60673 ++int grsec_enable_chroot_double;
60674 ++int grsec_enable_chroot_pivot;
60675 ++int grsec_enable_chroot_chdir;
60676 ++int grsec_enable_chroot_chmod;
60677 ++int grsec_enable_chroot_mknod;
60678 ++int grsec_enable_chroot_nice;
60679 ++int grsec_enable_chroot_execlog;
60680 ++int grsec_enable_chroot_caps;
60681 ++int grsec_enable_chroot_sysctl;
60682 ++int grsec_enable_chroot_unix;
60683 ++int grsec_enable_tpe;
60684 ++int grsec_tpe_gid;
60685 ++int grsec_enable_tpe_all;
60686 ++int grsec_enable_socket_all;
60687 ++int grsec_socket_all_gid;
60688 ++int grsec_enable_socket_client;
60689 ++int grsec_socket_client_gid;
60690 ++int grsec_enable_socket_server;
60691 ++int grsec_socket_server_gid;
60692 ++int grsec_resource_logging;
60693 ++int grsec_lock;
60694 ++
60695 ++DEFINE_SPINLOCK(grsec_alert_lock);
60696 ++unsigned long grsec_alert_wtime = 0;
60697 ++unsigned long grsec_alert_fyet = 0;
60698 ++
60699 ++DEFINE_SPINLOCK(grsec_audit_lock);
60700 ++
60701 ++DEFINE_RWLOCK(grsec_exec_file_lock);
60702 ++
60703 ++char *gr_shared_page[4];
60704 ++
60705 ++char *gr_alert_log_fmt;
60706 ++char *gr_audit_log_fmt;
60707 ++char *gr_alert_log_buf;
60708 ++char *gr_audit_log_buf;
60709 ++
60710 ++extern struct gr_arg *gr_usermode;
60711 ++extern unsigned char *gr_system_salt;
60712 ++extern unsigned char *gr_system_sum;
60713 ++
60714 ++void
60715 ++grsecurity_init(void)
60716 ++{
60717 ++ int j;
60718 ++ /* create the per-cpu shared pages */
60719 ++
60720 ++#ifdef CONFIG_X86
60721 ++ memset((char *)(0x41a + PAGE_OFFSET), 0, 36);
60722 ++#endif
60723 ++
60724 ++ for (j = 0; j < 4; j++) {
60725 ++ gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
60726 ++ if (gr_shared_page[j] == NULL) {
60727 ++ panic("Unable to allocate grsecurity shared page");
60728 ++ return;
60729 ++ }
60730 ++ }
60731 ++
60732 ++ /* allocate log buffers */
60733 ++ gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
60734 ++ if (!gr_alert_log_fmt) {
60735 ++ panic("Unable to allocate grsecurity alert log format buffer");
60736 ++ return;
60737 ++ }
60738 ++ gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
60739 ++ if (!gr_audit_log_fmt) {
60740 ++ panic("Unable to allocate grsecurity audit log format buffer");
60741 ++ return;
60742 ++ }
60743 ++ gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
60744 ++ if (!gr_alert_log_buf) {
60745 ++ panic("Unable to allocate grsecurity alert log buffer");
60746 ++ return;
60747 ++ }
60748 ++ gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
60749 ++ if (!gr_audit_log_buf) {
60750 ++ panic("Unable to allocate grsecurity audit log buffer");
60751 ++ return;
60752 ++ }
60753 ++
60754 ++ /* allocate memory for authentication structure */
60755 ++ gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
60756 ++ gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
60757 ++ gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
60758 ++
60759 ++ if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
60760 ++ panic("Unable to allocate grsecurity authentication structure");
60761 ++ return;
60762 ++ }
60763 ++
60764 ++#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
60765 ++#ifndef CONFIG_GRKERNSEC_SYSCTL
60766 ++ grsec_lock = 1;
60767 ++#endif
60768 ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
60769 ++ grsec_enable_audit_textrel = 1;
60770 ++#endif
60771 ++#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
60772 ++ grsec_enable_group = 1;
60773 ++ grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
60774 ++#endif
60775 ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
60776 ++ grsec_enable_chdir = 1;
60777 ++#endif
60778 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
60779 ++ grsec_enable_audit_ipc = 1;
60780 ++#endif
60781 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
60782 ++ grsec_enable_mount = 1;
60783 ++#endif
60784 ++#ifdef CONFIG_GRKERNSEC_LINK
60785 ++ grsec_enable_link = 1;
60786 ++#endif
60787 ++#ifdef CONFIG_GRKERNSEC_DMESG
60788 ++ grsec_enable_dmesg = 1;
60789 ++#endif
60790 ++#ifdef CONFIG_GRKERNSEC_FIFO
60791 ++ grsec_enable_fifo = 1;
60792 ++#endif
60793 ++#ifdef CONFIG_GRKERNSEC_EXECVE
60794 ++ grsec_enable_execve = 1;
60795 ++#endif
60796 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
60797 ++ grsec_enable_execlog = 1;
60798 ++#endif
60799 ++#ifdef CONFIG_GRKERNSEC_SIGNAL
60800 ++ grsec_enable_signal = 1;
60801 ++#endif
60802 ++#ifdef CONFIG_GRKERNSEC_FORKFAIL
60803 ++ grsec_enable_forkfail = 1;
60804 ++#endif
60805 ++#ifdef CONFIG_GRKERNSEC_TIME
60806 ++ grsec_enable_time = 1;
60807 ++#endif
60808 ++#ifdef CONFIG_GRKERNSEC_RESLOG
60809 ++ grsec_resource_logging = 1;
60810 ++#endif
60811 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
60812 ++ grsec_enable_chroot_findtask = 1;
60813 ++#endif
60814 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
60815 ++ grsec_enable_chroot_unix = 1;
60816 ++#endif
60817 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
60818 ++ grsec_enable_chroot_mount = 1;
60819 ++#endif
60820 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
60821 ++ grsec_enable_chroot_fchdir = 1;
60822 ++#endif
60823 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
60824 ++ grsec_enable_chroot_shmat = 1;
60825 ++#endif
60826 ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
60827 ++ grsec_enable_chroot_double = 1;
60828 ++#endif
60829 ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
60830 ++ grsec_enable_chroot_pivot = 1;
60831 ++#endif
60832 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
60833 ++ grsec_enable_chroot_chdir = 1;
60834 ++#endif
60835 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
60836 ++ grsec_enable_chroot_chmod = 1;
60837 ++#endif
60838 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
60839 ++ grsec_enable_chroot_mknod = 1;
60840 ++#endif
60841 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
60842 ++ grsec_enable_chroot_nice = 1;
60843 ++#endif
60844 ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
60845 ++ grsec_enable_chroot_execlog = 1;
60846 ++#endif
60847 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
60848 ++ grsec_enable_chroot_caps = 1;
60849 ++#endif
60850 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
60851 ++ grsec_enable_chroot_sysctl = 1;
60852 ++#endif
60853 ++#ifdef CONFIG_GRKERNSEC_TPE
60854 ++ grsec_enable_tpe = 1;
60855 ++ grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
60856 ++#ifdef CONFIG_GRKERNSEC_TPE_ALL
60857 ++ grsec_enable_tpe_all = 1;
60858 ++#endif
60859 ++#endif
60860 ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
60861 ++ grsec_enable_socket_all = 1;
60862 ++ grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
60863 ++#endif
60864 ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
60865 ++ grsec_enable_socket_client = 1;
60866 ++ grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
60867 ++#endif
60868 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
60869 ++ grsec_enable_socket_server = 1;
60870 ++ grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
60871 ++#endif
60872 ++#endif
60873 ++
60874 ++ return;
60875 ++}
60876 +diff -urNp linux-2.6.27.7/grsecurity/grsec_ipc.c linux-2.6.27.7/grsecurity/grsec_ipc.c
60877 +--- linux-2.6.27.7/grsecurity/grsec_ipc.c 1969-12-31 19:00:00.000000000 -0500
60878 ++++ linux-2.6.27.7/grsecurity/grsec_ipc.c 2008-11-18 03:38:45.000000000 -0500
60879 +@@ -0,0 +1,81 @@
60880 ++#include <linux/kernel.h>
60881 ++#include <linux/sched.h>
60882 ++#include <linux/types.h>
60883 ++#include <linux/ipc.h>
60884 ++#include <linux/grsecurity.h>
60885 ++#include <linux/grinternal.h>
60886 ++
60887 ++void
60888 ++gr_log_msgget(const int ret, const int msgflg)
60889 ++{
60890 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
60891 ++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
60892 ++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
60893 ++ !grsec_enable_group)) && (ret >= 0)
60894 ++ && (msgflg & IPC_CREAT))
60895 ++ gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
60896 ++#endif
60897 ++ return;
60898 ++}
60899 ++
60900 ++void
60901 ++gr_log_msgrm(const uid_t uid, const uid_t cuid)
60902 ++{
60903 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
60904 ++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
60905 ++ grsec_enable_audit_ipc) ||
60906 ++ (grsec_enable_audit_ipc && !grsec_enable_group))
60907 ++ gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
60908 ++#endif
60909 ++ return;
60910 ++}
60911 ++
60912 ++void
60913 ++gr_log_semget(const int err, const int semflg)
60914 ++{
60915 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
60916 ++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
60917 ++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
60918 ++ !grsec_enable_group)) && (err >= 0)
60919 ++ && (semflg & IPC_CREAT))
60920 ++ gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
60921 ++#endif
60922 ++ return;
60923 ++}
60924 ++
60925 ++void
60926 ++gr_log_semrm(const uid_t uid, const uid_t cuid)
60927 ++{
60928 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
60929 ++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
60930 ++ grsec_enable_audit_ipc) ||
60931 ++ (grsec_enable_audit_ipc && !grsec_enable_group))
60932 ++ gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
60933 ++#endif
60934 ++ return;
60935 ++}
60936 ++
60937 ++void
60938 ++gr_log_shmget(const int err, const int shmflg, const size_t size)
60939 ++{
60940 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
60941 ++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
60942 ++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
60943 ++ !grsec_enable_group)) && (err >= 0)
60944 ++ && (shmflg & IPC_CREAT))
60945 ++ gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
60946 ++#endif
60947 ++ return;
60948 ++}
60949 ++
60950 ++void
60951 ++gr_log_shmrm(const uid_t uid, const uid_t cuid)
60952 ++{
60953 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
60954 ++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
60955 ++ grsec_enable_audit_ipc) ||
60956 ++ (grsec_enable_audit_ipc && !grsec_enable_group))
60957 ++ gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
60958 ++#endif
60959 ++ return;
60960 ++}
60961 +diff -urNp linux-2.6.27.7/grsecurity/grsec_link.c linux-2.6.27.7/grsecurity/grsec_link.c
60962 +--- linux-2.6.27.7/grsecurity/grsec_link.c 1969-12-31 19:00:00.000000000 -0500
60963 ++++ linux-2.6.27.7/grsecurity/grsec_link.c 2008-11-18 03:38:45.000000000 -0500
60964 +@@ -0,0 +1,39 @@
60965 ++#include <linux/kernel.h>
60966 ++#include <linux/sched.h>
60967 ++#include <linux/fs.h>
60968 ++#include <linux/file.h>
60969 ++#include <linux/grinternal.h>
60970 ++
60971 ++int
60972 ++gr_handle_follow_link(const struct inode *parent,
60973 ++ const struct inode *inode,
60974 ++ const struct dentry *dentry, const struct vfsmount *mnt)
60975 ++{
60976 ++#ifdef CONFIG_GRKERNSEC_LINK
60977 ++ if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
60978 ++ (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
60979 ++ (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
60980 ++ gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
60981 ++ return -EACCES;
60982 ++ }
60983 ++#endif
60984 ++ return 0;
60985 ++}
60986 ++
60987 ++int
60988 ++gr_handle_hardlink(const struct dentry *dentry,
60989 ++ const struct vfsmount *mnt,
60990 ++ struct inode *inode, const int mode, const char *to)
60991 ++{
60992 ++#ifdef CONFIG_GRKERNSEC_LINK
60993 ++ if (grsec_enable_link && current->fsuid != inode->i_uid &&
60994 ++ (!S_ISREG(mode) || (mode & S_ISUID) ||
60995 ++ ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
60996 ++ (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
60997 ++ !capable(CAP_FOWNER) && current->uid) {
60998 ++ gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
60999 ++ return -EPERM;
61000 ++ }
61001 ++#endif
61002 ++ return 0;
61003 ++}
61004 +diff -urNp linux-2.6.27.7/grsecurity/grsec_log.c linux-2.6.27.7/grsecurity/grsec_log.c
61005 +--- linux-2.6.27.7/grsecurity/grsec_log.c 1969-12-31 19:00:00.000000000 -0500
61006 ++++ linux-2.6.27.7/grsecurity/grsec_log.c 2008-11-18 03:38:45.000000000 -0500
61007 +@@ -0,0 +1,269 @@
61008 ++#include <linux/kernel.h>
61009 ++#include <linux/sched.h>
61010 ++#include <linux/file.h>
61011 ++#include <linux/tty.h>
61012 ++#include <linux/fs.h>
61013 ++#include <linux/grinternal.h>
61014 ++
61015 ++#define BEGIN_LOCKS(x) \
61016 ++ read_lock(&tasklist_lock); \
61017 ++ read_lock(&grsec_exec_file_lock); \
61018 ++ if (x != GR_DO_AUDIT) \
61019 ++ spin_lock(&grsec_alert_lock); \
61020 ++ else \
61021 ++ spin_lock(&grsec_audit_lock)
61022 ++
61023 ++#define END_LOCKS(x) \
61024 ++ if (x != GR_DO_AUDIT) \
61025 ++ spin_unlock(&grsec_alert_lock); \
61026 ++ else \
61027 ++ spin_unlock(&grsec_audit_lock); \
61028 ++ read_unlock(&grsec_exec_file_lock); \
61029 ++ read_unlock(&tasklist_lock); \
61030 ++ if (x == GR_DONT_AUDIT) \
61031 ++ gr_handle_alertkill(current)
61032 ++
61033 ++enum {
61034 ++ FLOODING,
61035 ++ NO_FLOODING
61036 ++};
61037 ++
61038 ++extern char *gr_alert_log_fmt;
61039 ++extern char *gr_audit_log_fmt;
61040 ++extern char *gr_alert_log_buf;
61041 ++extern char *gr_audit_log_buf;
61042 ++
61043 ++static int gr_log_start(int audit)
61044 ++{
61045 ++ char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
61046 ++ char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
61047 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
61048 ++
61049 ++ if (audit == GR_DO_AUDIT)
61050 ++ goto set_fmt;
61051 ++
61052 ++ if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
61053 ++ grsec_alert_wtime = jiffies;
61054 ++ grsec_alert_fyet = 0;
61055 ++ } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
61056 ++ grsec_alert_fyet++;
61057 ++ } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
61058 ++ grsec_alert_wtime = jiffies;
61059 ++ grsec_alert_fyet++;
61060 ++ printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
61061 ++ return FLOODING;
61062 ++ } else return FLOODING;
61063 ++
61064 ++set_fmt:
61065 ++ memset(buf, 0, PAGE_SIZE);
61066 ++ if (current->signal->curr_ip && gr_acl_is_enabled()) {
61067 ++ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
61068 ++ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
61069 ++ } else if (current->signal->curr_ip) {
61070 ++ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
61071 ++ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
61072 ++ } else if (gr_acl_is_enabled()) {
61073 ++ sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
61074 ++ snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
61075 ++ } else {
61076 ++ sprintf(fmt, "%s%s", loglevel, "grsec: ");
61077 ++ strcpy(buf, fmt);
61078 ++ }
61079 ++
61080 ++ return NO_FLOODING;
61081 ++}
61082 ++
61083 ++static void gr_log_middle(int audit, const char *msg, va_list ap)
61084 ++{
61085 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
61086 ++ unsigned int len = strlen(buf);
61087 ++
61088 ++ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
61089 ++
61090 ++ return;
61091 ++}
61092 ++
61093 ++static void gr_log_middle_varargs(int audit, const char *msg, ...)
61094 ++{
61095 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
61096 ++ unsigned int len = strlen(buf);
61097 ++ va_list ap;
61098 ++
61099 ++ va_start(ap, msg);
61100 ++ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
61101 ++ va_end(ap);
61102 ++
61103 ++ return;
61104 ++}
61105 ++
61106 ++static void gr_log_end(int audit)
61107 ++{
61108 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
61109 ++ unsigned int len = strlen(buf);
61110 ++
61111 ++ snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
61112 ++ printk("%s\n", buf);
61113 ++
61114 ++ return;
61115 ++}
61116 ++
61117 ++void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
61118 ++{
61119 ++ int logtype;
61120 ++ char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
61121 ++ char *str1, *str2, *str3;
61122 ++ int num1, num2;
61123 ++ unsigned long ulong1, ulong2;
61124 ++ struct dentry *dentry;
61125 ++ struct vfsmount *mnt;
61126 ++ struct file *file;
61127 ++ struct task_struct *task;
61128 ++ va_list ap;
61129 ++
61130 ++ BEGIN_LOCKS(audit);
61131 ++ logtype = gr_log_start(audit);
61132 ++ if (logtype == FLOODING) {
61133 ++ END_LOCKS(audit);
61134 ++ return;
61135 ++ }
61136 ++ va_start(ap, argtypes);
61137 ++ switch (argtypes) {
61138 ++ case GR_TTYSNIFF:
61139 ++ task = va_arg(ap, struct task_struct *);
61140 ++ 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);
61141 ++ break;
61142 ++ case GR_SYSCTL_HIDDEN:
61143 ++ str1 = va_arg(ap, char *);
61144 ++ gr_log_middle_varargs(audit, msg, result, str1);
61145 ++ break;
61146 ++ case GR_RBAC:
61147 ++ dentry = va_arg(ap, struct dentry *);
61148 ++ mnt = va_arg(ap, struct vfsmount *);
61149 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
61150 ++ break;
61151 ++ case GR_RBAC_STR:
61152 ++ dentry = va_arg(ap, struct dentry *);
61153 ++ mnt = va_arg(ap, struct vfsmount *);
61154 ++ str1 = va_arg(ap, char *);
61155 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
61156 ++ break;
61157 ++ case GR_STR_RBAC:
61158 ++ str1 = va_arg(ap, char *);
61159 ++ dentry = va_arg(ap, struct dentry *);
61160 ++ mnt = va_arg(ap, struct vfsmount *);
61161 ++ gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
61162 ++ break;
61163 ++ case GR_RBAC_MODE2:
61164 ++ dentry = va_arg(ap, struct dentry *);
61165 ++ mnt = va_arg(ap, struct vfsmount *);
61166 ++ str1 = va_arg(ap, char *);
61167 ++ str2 = va_arg(ap, char *);
61168 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
61169 ++ break;
61170 ++ case GR_RBAC_MODE3:
61171 ++ dentry = va_arg(ap, struct dentry *);
61172 ++ mnt = va_arg(ap, struct vfsmount *);
61173 ++ str1 = va_arg(ap, char *);
61174 ++ str2 = va_arg(ap, char *);
61175 ++ str3 = va_arg(ap, char *);
61176 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
61177 ++ break;
61178 ++ case GR_FILENAME:
61179 ++ dentry = va_arg(ap, struct dentry *);
61180 ++ mnt = va_arg(ap, struct vfsmount *);
61181 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
61182 ++ break;
61183 ++ case GR_STR_FILENAME:
61184 ++ str1 = va_arg(ap, char *);
61185 ++ dentry = va_arg(ap, struct dentry *);
61186 ++ mnt = va_arg(ap, struct vfsmount *);
61187 ++ gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
61188 ++ break;
61189 ++ case GR_FILENAME_STR:
61190 ++ dentry = va_arg(ap, struct dentry *);
61191 ++ mnt = va_arg(ap, struct vfsmount *);
61192 ++ str1 = va_arg(ap, char *);
61193 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
61194 ++ break;
61195 ++ case GR_FILENAME_TWO_INT:
61196 ++ dentry = va_arg(ap, struct dentry *);
61197 ++ mnt = va_arg(ap, struct vfsmount *);
61198 ++ num1 = va_arg(ap, int);
61199 ++ num2 = va_arg(ap, int);
61200 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
61201 ++ break;
61202 ++ case GR_FILENAME_TWO_INT_STR:
61203 ++ dentry = va_arg(ap, struct dentry *);
61204 ++ mnt = va_arg(ap, struct vfsmount *);
61205 ++ num1 = va_arg(ap, int);
61206 ++ num2 = va_arg(ap, int);
61207 ++ str1 = va_arg(ap, char *);
61208 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
61209 ++ break;
61210 ++ case GR_TEXTREL:
61211 ++ file = va_arg(ap, struct file *);
61212 ++ ulong1 = va_arg(ap, unsigned long);
61213 ++ ulong2 = va_arg(ap, unsigned long);
61214 ++ gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_path.dentry, file->f_path.mnt) : "<anonymous mapping>", ulong1, ulong2);
61215 ++ break;
61216 ++ case GR_PTRACE:
61217 ++ task = va_arg(ap, struct task_struct *);
61218 ++ 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);
61219 ++ break;
61220 ++ case GR_RESOURCE:
61221 ++ task = va_arg(ap, struct task_struct *);
61222 ++ ulong1 = va_arg(ap, unsigned long);
61223 ++ str1 = va_arg(ap, char *);
61224 ++ ulong2 = va_arg(ap, unsigned long);
61225 ++ 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);
61226 ++ break;
61227 ++ case GR_CAP:
61228 ++ task = va_arg(ap, struct task_struct *);
61229 ++ str1 = va_arg(ap, char *);
61230 ++ 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);
61231 ++ break;
61232 ++ case GR_SIG:
61233 ++ task = va_arg(ap, struct task_struct *);
61234 ++ num1 = va_arg(ap, int);
61235 ++ 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);
61236 ++ break;
61237 ++ case GR_CRASH1:
61238 ++ task = va_arg(ap, struct task_struct *);
61239 ++ ulong1 = va_arg(ap, unsigned long);
61240 ++ 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);
61241 ++ break;
61242 ++ case GR_CRASH2:
61243 ++ task = va_arg(ap, struct task_struct *);
61244 ++ ulong1 = va_arg(ap, unsigned long);
61245 ++ 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);
61246 ++ break;
61247 ++ case GR_PSACCT:
61248 ++ {
61249 ++ unsigned int wday, cday;
61250 ++ __u8 whr, chr;
61251 ++ __u8 wmin, cmin;
61252 ++ __u8 wsec, csec;
61253 ++ char cur_tty[64] = { 0 };
61254 ++ char parent_tty[64] = { 0 };
61255 ++
61256 ++ task = va_arg(ap, struct task_struct *);
61257 ++ wday = va_arg(ap, unsigned int);
61258 ++ cday = va_arg(ap, unsigned int);
61259 ++ whr = va_arg(ap, int);
61260 ++ chr = va_arg(ap, int);
61261 ++ wmin = va_arg(ap, int);
61262 ++ cmin = va_arg(ap, int);
61263 ++ wsec = va_arg(ap, int);
61264 ++ csec = va_arg(ap, int);
61265 ++ ulong1 = va_arg(ap, unsigned long);
61266 ++
61267 ++ 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);
61268 ++ }
61269 ++ break;
61270 ++ default:
61271 ++ gr_log_middle(audit, msg, ap);
61272 ++ }
61273 ++ va_end(ap);
61274 ++ gr_log_end(audit);
61275 ++ END_LOCKS(audit);
61276 ++}
61277 +diff -urNp linux-2.6.27.7/grsecurity/grsec_mem.c linux-2.6.27.7/grsecurity/grsec_mem.c
61278 +--- linux-2.6.27.7/grsecurity/grsec_mem.c 1969-12-31 19:00:00.000000000 -0500
61279 ++++ linux-2.6.27.7/grsecurity/grsec_mem.c 2008-11-18 03:38:45.000000000 -0500
61280 +@@ -0,0 +1,71 @@
61281 ++#include <linux/kernel.h>
61282 ++#include <linux/sched.h>
61283 ++#include <linux/mm.h>
61284 ++#include <linux/mman.h>
61285 ++#include <linux/grinternal.h>
61286 ++
61287 ++void
61288 ++gr_handle_ioperm(void)
61289 ++{
61290 ++ gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
61291 ++ return;
61292 ++}
61293 ++
61294 ++void
61295 ++gr_handle_iopl(void)
61296 ++{
61297 ++ gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
61298 ++ return;
61299 ++}
61300 ++
61301 ++void
61302 ++gr_handle_mem_write(void)
61303 ++{
61304 ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
61305 ++ return;
61306 ++}
61307 ++
61308 ++void
61309 ++gr_handle_kmem_write(void)
61310 ++{
61311 ++ gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
61312 ++ return;
61313 ++}
61314 ++
61315 ++void
61316 ++gr_handle_open_port(void)
61317 ++{
61318 ++ gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
61319 ++ return;
61320 ++}
61321 ++
61322 ++int
61323 ++gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
61324 ++{
61325 ++ unsigned long start, end;
61326 ++
61327 ++ start = offset;
61328 ++ end = start + vma->vm_end - vma->vm_start;
61329 ++
61330 ++ if (start > end) {
61331 ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
61332 ++ return -EPERM;
61333 ++ }
61334 ++
61335 ++ /* allowed ranges : ISA I/O BIOS */
61336 ++ if ((start >= __pa(high_memory))
61337 ++#ifdef CONFIG_X86
61338 ++ || (start >= 0x000a0000 && end <= 0x00100000)
61339 ++ || (start >= 0x00000000 && end <= 0x00001000)
61340 ++#endif
61341 ++ )
61342 ++ return 0;
61343 ++
61344 ++ if (vma->vm_flags & VM_WRITE) {
61345 ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
61346 ++ return -EPERM;
61347 ++ } else
61348 ++ vma->vm_flags &= ~VM_MAYWRITE;
61349 ++
61350 ++ return 0;
61351 ++}
61352 +diff -urNp linux-2.6.27.7/grsecurity/grsec_mount.c linux-2.6.27.7/grsecurity/grsec_mount.c
61353 +--- linux-2.6.27.7/grsecurity/grsec_mount.c 1969-12-31 19:00:00.000000000 -0500
61354 ++++ linux-2.6.27.7/grsecurity/grsec_mount.c 2008-11-18 03:38:45.000000000 -0500
61355 +@@ -0,0 +1,34 @@
61356 ++#include <linux/kernel.h>
61357 ++#include <linux/sched.h>
61358 ++#include <linux/grsecurity.h>
61359 ++#include <linux/grinternal.h>
61360 ++
61361 ++void
61362 ++gr_log_remount(const char *devname, const int retval)
61363 ++{
61364 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
61365 ++ if (grsec_enable_mount && (retval >= 0))
61366 ++ gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
61367 ++#endif
61368 ++ return;
61369 ++}
61370 ++
61371 ++void
61372 ++gr_log_unmount(const char *devname, const int retval)
61373 ++{
61374 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
61375 ++ if (grsec_enable_mount && (retval >= 0))
61376 ++ gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
61377 ++#endif
61378 ++ return;
61379 ++}
61380 ++
61381 ++void
61382 ++gr_log_mount(const char *from, const char *to, const int retval)
61383 ++{
61384 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
61385 ++ if (grsec_enable_mount && (retval >= 0))
61386 ++ gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
61387 ++#endif
61388 ++ return;
61389 ++}
61390 +diff -urNp linux-2.6.27.7/grsecurity/grsec_sig.c linux-2.6.27.7/grsecurity/grsec_sig.c
61391 +--- linux-2.6.27.7/grsecurity/grsec_sig.c 1969-12-31 19:00:00.000000000 -0500
61392 ++++ linux-2.6.27.7/grsecurity/grsec_sig.c 2008-11-18 03:38:45.000000000 -0500
61393 +@@ -0,0 +1,58 @@
61394 ++#include <linux/kernel.h>
61395 ++#include <linux/sched.h>
61396 ++#include <linux/delay.h>
61397 ++#include <linux/grsecurity.h>
61398 ++#include <linux/grinternal.h>
61399 ++
61400 ++void
61401 ++gr_log_signal(const int sig, const struct task_struct *t)
61402 ++{
61403 ++#ifdef CONFIG_GRKERNSEC_SIGNAL
61404 ++ if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
61405 ++ (sig == SIGABRT) || (sig == SIGBUS))) {
61406 ++ if (t->pid == current->pid) {
61407 ++ gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
61408 ++ } else {
61409 ++ gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
61410 ++ }
61411 ++ }
61412 ++#endif
61413 ++ return;
61414 ++}
61415 ++
61416 ++int
61417 ++gr_handle_signal(const struct task_struct *p, const int sig)
61418 ++{
61419 ++#ifdef CONFIG_GRKERNSEC
61420 ++ if (current->pid > 1 && gr_check_protected_task(p)) {
61421 ++ gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
61422 ++ return -EPERM;
61423 ++ } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
61424 ++ return -EPERM;
61425 ++ }
61426 ++#endif
61427 ++ return 0;
61428 ++}
61429 ++
61430 ++void gr_handle_brute_attach(struct task_struct *p)
61431 ++{
61432 ++#ifdef CONFIG_GRKERNSEC_BRUTE
61433 ++ read_lock(&tasklist_lock);
61434 ++ read_lock(&grsec_exec_file_lock);
61435 ++ if (p->parent && p->parent->exec_file == p->exec_file)
61436 ++ p->parent->brute = 1;
61437 ++ read_unlock(&grsec_exec_file_lock);
61438 ++ read_unlock(&tasklist_lock);
61439 ++#endif
61440 ++ return;
61441 ++}
61442 ++
61443 ++void gr_handle_brute_check(void)
61444 ++{
61445 ++#ifdef CONFIG_GRKERNSEC_BRUTE
61446 ++ if (current->brute)
61447 ++ msleep(30 * 1000);
61448 ++#endif
61449 ++ return;
61450 ++}
61451 ++
61452 +diff -urNp linux-2.6.27.7/grsecurity/grsec_sock.c linux-2.6.27.7/grsecurity/grsec_sock.c
61453 +--- linux-2.6.27.7/grsecurity/grsec_sock.c 1969-12-31 19:00:00.000000000 -0500
61454 ++++ linux-2.6.27.7/grsecurity/grsec_sock.c 2008-11-18 11:35:13.000000000 -0500
61455 +@@ -0,0 +1,274 @@
61456 ++#include <linux/kernel.h>
61457 ++#include <linux/module.h>
61458 ++#include <linux/sched.h>
61459 ++#include <linux/file.h>
61460 ++#include <linux/net.h>
61461 ++#include <linux/in.h>
61462 ++#include <linux/ip.h>
61463 ++#include <net/sock.h>
61464 ++#include <net/inet_sock.h>
61465 ++#include <linux/grsecurity.h>
61466 ++#include <linux/grinternal.h>
61467 ++#include <linux/gracl.h>
61468 ++
61469 ++#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
61470 ++extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
61471 ++EXPORT_SYMBOL(udp_v4_lookup);
61472 ++#endif
61473 ++
61474 ++kernel_cap_t gr_cap_rtnetlink(struct sock *sock);
61475 ++EXPORT_SYMBOL(gr_cap_rtnetlink);
61476 ++
61477 ++extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
61478 ++extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
61479 ++
61480 ++EXPORT_SYMBOL(gr_search_udp_recvmsg);
61481 ++EXPORT_SYMBOL(gr_search_udp_sendmsg);
61482 ++
61483 ++#ifdef CONFIG_UNIX_MODULE
61484 ++EXPORT_SYMBOL(gr_acl_handle_unix);
61485 ++EXPORT_SYMBOL(gr_acl_handle_mknod);
61486 ++EXPORT_SYMBOL(gr_handle_chroot_unix);
61487 ++EXPORT_SYMBOL(gr_handle_create);
61488 ++#endif
61489 ++
61490 ++#ifdef CONFIG_GRKERNSEC
61491 ++#define gr_conn_table_size 32749
61492 ++struct conn_table_entry {
61493 ++ struct conn_table_entry *next;
61494 ++ struct signal_struct *sig;
61495 ++};
61496 ++
61497 ++struct conn_table_entry *gr_conn_table[gr_conn_table_size];
61498 ++DEFINE_SPINLOCK(gr_conn_table_lock);
61499 ++
61500 ++extern const char * gr_socktype_to_name(unsigned char type);
61501 ++extern const char * gr_proto_to_name(unsigned char proto);
61502 ++
61503 ++static __inline__ int
61504 ++conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
61505 ++{
61506 ++ return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
61507 ++}
61508 ++
61509 ++static __inline__ int
61510 ++conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr,
61511 ++ __u16 sport, __u16 dport)
61512 ++{
61513 ++ if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
61514 ++ sig->gr_sport == sport && sig->gr_dport == dport))
61515 ++ return 1;
61516 ++ else
61517 ++ return 0;
61518 ++}
61519 ++
61520 ++static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
61521 ++{
61522 ++ struct conn_table_entry **match;
61523 ++ unsigned int index;
61524 ++
61525 ++ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
61526 ++ sig->gr_sport, sig->gr_dport,
61527 ++ gr_conn_table_size);
61528 ++
61529 ++ newent->sig = sig;
61530 ++
61531 ++ match = &gr_conn_table[index];
61532 ++ newent->next = *match;
61533 ++ *match = newent;
61534 ++
61535 ++ return;
61536 ++}
61537 ++
61538 ++static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
61539 ++{
61540 ++ struct conn_table_entry *match, *last = NULL;
61541 ++ unsigned int index;
61542 ++
61543 ++ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
61544 ++ sig->gr_sport, sig->gr_dport,
61545 ++ gr_conn_table_size);
61546 ++
61547 ++ match = gr_conn_table[index];
61548 ++ while (match && !conn_match(match->sig,
61549 ++ sig->gr_saddr, sig->gr_daddr, sig->gr_sport,
61550 ++ sig->gr_dport)) {
61551 ++ last = match;
61552 ++ match = match->next;
61553 ++ }
61554 ++
61555 ++ if (match) {
61556 ++ if (last)
61557 ++ last->next = match->next;
61558 ++ else
61559 ++ gr_conn_table[index] = NULL;
61560 ++ kfree(match);
61561 ++ }
61562 ++
61563 ++ return;
61564 ++}
61565 ++
61566 ++static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
61567 ++ __u16 sport, __u16 dport)
61568 ++{
61569 ++ struct conn_table_entry *match;
61570 ++ unsigned int index;
61571 ++
61572 ++ index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
61573 ++
61574 ++ match = gr_conn_table[index];
61575 ++ while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
61576 ++ match = match->next;
61577 ++
61578 ++ if (match)
61579 ++ return match->sig;
61580 ++ else
61581 ++ return NULL;
61582 ++}
61583 ++
61584 ++#endif
61585 ++
61586 ++void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
61587 ++{
61588 ++#ifdef CONFIG_GRKERNSEC
61589 ++ struct signal_struct *sig = task->signal;
61590 ++ struct conn_table_entry *newent;
61591 ++
61592 ++ newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
61593 ++ if (newent == NULL)
61594 ++ return;
61595 ++ /* no bh lock needed since we are called with bh disabled */
61596 ++ spin_lock(&gr_conn_table_lock);
61597 ++ gr_del_task_from_ip_table_nolock(sig);
61598 ++ sig->gr_saddr = inet->rcv_saddr;
61599 ++ sig->gr_daddr = inet->daddr;
61600 ++ sig->gr_sport = inet->sport;
61601 ++ sig->gr_dport = inet->dport;
61602 ++ gr_add_to_task_ip_table_nolock(sig, newent);
61603 ++ spin_unlock(&gr_conn_table_lock);
61604 ++#endif
61605 ++ return;
61606 ++}
61607 ++
61608 ++void gr_del_task_from_ip_table(struct task_struct *task)
61609 ++{
61610 ++#ifdef CONFIG_GRKERNSEC
61611 ++ spin_lock_bh(&gr_conn_table_lock);
61612 ++ gr_del_task_from_ip_table_nolock(task->signal);
61613 ++ spin_unlock_bh(&gr_conn_table_lock);
61614 ++#endif
61615 ++ return;
61616 ++}
61617 ++
61618 ++void
61619 ++gr_attach_curr_ip(const struct sock *sk)
61620 ++{
61621 ++#ifdef CONFIG_GRKERNSEC
61622 ++ struct signal_struct *p, *set;
61623 ++ const struct inet_sock *inet = inet_sk(sk);
61624 ++
61625 ++ if (unlikely(sk->sk_protocol != IPPROTO_TCP))
61626 ++ return;
61627 ++
61628 ++ set = current->signal;
61629 ++
61630 ++ spin_lock_bh(&gr_conn_table_lock);
61631 ++ p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
61632 ++ inet->dport, inet->sport);
61633 ++ if (unlikely(p != NULL)) {
61634 ++ set->curr_ip = p->curr_ip;
61635 ++ set->used_accept = 1;
61636 ++ gr_del_task_from_ip_table_nolock(p);
61637 ++ spin_unlock_bh(&gr_conn_table_lock);
61638 ++ return;
61639 ++ }
61640 ++ spin_unlock_bh(&gr_conn_table_lock);
61641 ++
61642 ++ set->curr_ip = inet->daddr;
61643 ++ set->used_accept = 1;
61644 ++#endif
61645 ++ return;
61646 ++}
61647 ++
61648 ++int
61649 ++gr_handle_sock_all(const int family, const int type, const int protocol)
61650 ++{
61651 ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
61652 ++ if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
61653 ++ (family != AF_UNIX) && (family != AF_LOCAL)) {
61654 ++ gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
61655 ++ return -EACCES;
61656 ++ }
61657 ++#endif
61658 ++ return 0;
61659 ++}
61660 ++
61661 ++int
61662 ++gr_handle_sock_server(const struct sockaddr *sck)
61663 ++{
61664 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
61665 ++ if (grsec_enable_socket_server &&
61666 ++ in_group_p(grsec_socket_server_gid) &&
61667 ++ sck && (sck->sa_family != AF_UNIX) &&
61668 ++ (sck->sa_family != AF_LOCAL)) {
61669 ++ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
61670 ++ return -EACCES;
61671 ++ }
61672 ++#endif
61673 ++ return 0;
61674 ++}
61675 ++
61676 ++int
61677 ++gr_handle_sock_server_other(const struct sock *sck)
61678 ++{
61679 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
61680 ++ if (grsec_enable_socket_server &&
61681 ++ in_group_p(grsec_socket_server_gid) &&
61682 ++ sck && (sck->sk_family != AF_UNIX) &&
61683 ++ (sck->sk_family != AF_LOCAL)) {
61684 ++ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
61685 ++ return -EACCES;
61686 ++ }
61687 ++#endif
61688 ++ return 0;
61689 ++}
61690 ++
61691 ++int
61692 ++gr_handle_sock_client(const struct sockaddr *sck)
61693 ++{
61694 ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
61695 ++ if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
61696 ++ sck && (sck->sa_family != AF_UNIX) &&
61697 ++ (sck->sa_family != AF_LOCAL)) {
61698 ++ gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
61699 ++ return -EACCES;
61700 ++ }
61701 ++#endif
61702 ++ return 0;
61703 ++}
61704 ++
61705 ++kernel_cap_t
61706 ++gr_cap_rtnetlink(struct sock *sock)
61707 ++{
61708 ++#ifdef CONFIG_GRKERNSEC
61709 ++ if (!gr_acl_is_enabled())
61710 ++ return current->cap_effective;
61711 ++ else if (sock->sk_protocol == NETLINK_ISCSI &&
61712 ++ cap_raised(current->cap_effective, CAP_SYS_ADMIN) &&
61713 ++ gr_task_is_capable(current, CAP_SYS_ADMIN))
61714 ++ return current->cap_effective;
61715 ++ else if (sock->sk_protocol == NETLINK_AUDIT &&
61716 ++ cap_raised(current->cap_effective, CAP_AUDIT_WRITE) &&
61717 ++ gr_task_is_capable(current, CAP_AUDIT_WRITE) &&
61718 ++ cap_raised(current->cap_effective, CAP_AUDIT_CONTROL) &&
61719 ++ gr_task_is_capable(current, CAP_AUDIT_CONTROL))
61720 ++ return current->cap_effective;
61721 ++ else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
61722 ++ gr_task_is_capable(current, CAP_NET_ADMIN))
61723 ++ return current->cap_effective;
61724 ++ else
61725 ++ return __cap_empty_set;
61726 ++#else
61727 ++ return current->cap_effective;
61728 ++#endif
61729 ++}
61730 +diff -urNp linux-2.6.27.7/grsecurity/grsec_sysctl.c linux-2.6.27.7/grsecurity/grsec_sysctl.c
61731 +--- linux-2.6.27.7/grsecurity/grsec_sysctl.c 1969-12-31 19:00:00.000000000 -0500
61732 ++++ linux-2.6.27.7/grsecurity/grsec_sysctl.c 2008-11-18 03:38:45.000000000 -0500
61733 +@@ -0,0 +1,435 @@
61734 ++#include <linux/kernel.h>
61735 ++#include <linux/sched.h>
61736 ++#include <linux/sysctl.h>
61737 ++#include <linux/grsecurity.h>
61738 ++#include <linux/grinternal.h>
61739 ++
61740 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
61741 ++int grsec_modstop;
61742 ++#endif
61743 ++
61744 ++int
61745 ++gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
61746 ++{
61747 ++#ifdef CONFIG_GRKERNSEC_SYSCTL
61748 ++ if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & MAY_WRITE)) {
61749 ++ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
61750 ++ return -EACCES;
61751 ++ }
61752 ++#endif
61753 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
61754 ++ if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
61755 ++ grsec_modstop && (op & MAY_WRITE)) {
61756 ++ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
61757 ++ return -EACCES;
61758 ++ }
61759 ++#endif
61760 ++ return 0;
61761 ++}
61762 ++
61763 ++#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
61764 ++ctl_table grsecurity_table[] = {
61765 ++#ifdef CONFIG_GRKERNSEC_SYSCTL
61766 ++#ifdef CONFIG_GRKERNSEC_LINK
61767 ++ {
61768 ++ .ctl_name = CTL_UNNUMBERED,
61769 ++ .procname = "linking_restrictions",
61770 ++ .data = &grsec_enable_link,
61771 ++ .maxlen = sizeof(int),
61772 ++ .mode = 0600,
61773 ++ .proc_handler = &proc_dointvec,
61774 ++ },
61775 ++#endif
61776 ++#ifdef CONFIG_GRKERNSEC_FIFO
61777 ++ {
61778 ++ .ctl_name = CTL_UNNUMBERED,
61779 ++ .procname = "fifo_restrictions",
61780 ++ .data = &grsec_enable_fifo,
61781 ++ .maxlen = sizeof(int),
61782 ++ .mode = 0600,
61783 ++ .proc_handler = &proc_dointvec,
61784 ++ },
61785 ++#endif
61786 ++#ifdef CONFIG_GRKERNSEC_EXECVE
61787 ++ {
61788 ++ .ctl_name = CTL_UNNUMBERED,
61789 ++ .procname = "execve_limiting",
61790 ++ .data = &grsec_enable_execve,
61791 ++ .maxlen = sizeof(int),
61792 ++ .mode = 0600,
61793 ++ .proc_handler = &proc_dointvec,
61794 ++ },
61795 ++#endif
61796 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
61797 ++ {
61798 ++ .ctl_name = CTL_UNNUMBERED,
61799 ++ .procname = "exec_logging",
61800 ++ .data = &grsec_enable_execlog,
61801 ++ .maxlen = sizeof(int),
61802 ++ .mode = 0600,
61803 ++ .proc_handler = &proc_dointvec,
61804 ++ },
61805 ++#endif
61806 ++#ifdef CONFIG_GRKERNSEC_SIGNAL
61807 ++ {
61808 ++ .ctl_name = CTL_UNNUMBERED,
61809 ++ .procname = "signal_logging",
61810 ++ .data = &grsec_enable_signal,
61811 ++ .maxlen = sizeof(int),
61812 ++ .mode = 0600,
61813 ++ .proc_handler = &proc_dointvec,
61814 ++ },
61815 ++#endif
61816 ++#ifdef CONFIG_GRKERNSEC_FORKFAIL
61817 ++ {
61818 ++ .ctl_name = CTL_UNNUMBERED,
61819 ++ .procname = "forkfail_logging",
61820 ++ .data = &grsec_enable_forkfail,
61821 ++ .maxlen = sizeof(int),
61822 ++ .mode = 0600,
61823 ++ .proc_handler = &proc_dointvec,
61824 ++ },
61825 ++#endif
61826 ++#ifdef CONFIG_GRKERNSEC_TIME
61827 ++ {
61828 ++ .ctl_name = CTL_UNNUMBERED,
61829 ++ .procname = "timechange_logging",
61830 ++ .data = &grsec_enable_time,
61831 ++ .maxlen = sizeof(int),
61832 ++ .mode = 0600,
61833 ++ .proc_handler = &proc_dointvec,
61834 ++ },
61835 ++#endif
61836 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
61837 ++ {
61838 ++ .ctl_name = CTL_UNNUMBERED,
61839 ++ .procname = "chroot_deny_shmat",
61840 ++ .data = &grsec_enable_chroot_shmat,
61841 ++ .maxlen = sizeof(int),
61842 ++ .mode = 0600,
61843 ++ .proc_handler = &proc_dointvec,
61844 ++ },
61845 ++#endif
61846 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
61847 ++ {
61848 ++ .ctl_name = CTL_UNNUMBERED,
61849 ++ .procname = "chroot_deny_unix",
61850 ++ .data = &grsec_enable_chroot_unix,
61851 ++ .maxlen = sizeof(int),
61852 ++ .mode = 0600,
61853 ++ .proc_handler = &proc_dointvec,
61854 ++ },
61855 ++#endif
61856 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
61857 ++ {
61858 ++ .ctl_name = CTL_UNNUMBERED,
61859 ++ .procname = "chroot_deny_mount",
61860 ++ .data = &grsec_enable_chroot_mount,
61861 ++ .maxlen = sizeof(int),
61862 ++ .mode = 0600,
61863 ++ .proc_handler = &proc_dointvec,
61864 ++ },
61865 ++#endif
61866 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
61867 ++ {
61868 ++ .ctl_name = CTL_UNNUMBERED,
61869 ++ .procname = "chroot_deny_fchdir",
61870 ++ .data = &grsec_enable_chroot_fchdir,
61871 ++ .maxlen = sizeof(int),
61872 ++ .mode = 0600,
61873 ++ .proc_handler = &proc_dointvec,
61874 ++ },
61875 ++#endif
61876 ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
61877 ++ {
61878 ++ .ctl_name = CTL_UNNUMBERED,
61879 ++ .procname = "chroot_deny_chroot",
61880 ++ .data = &grsec_enable_chroot_double,
61881 ++ .maxlen = sizeof(int),
61882 ++ .mode = 0600,
61883 ++ .proc_handler = &proc_dointvec,
61884 ++ },
61885 ++#endif
61886 ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
61887 ++ {
61888 ++ .ctl_name = CTL_UNNUMBERED,
61889 ++ .procname = "chroot_deny_pivot",
61890 ++ .data = &grsec_enable_chroot_pivot,
61891 ++ .maxlen = sizeof(int),
61892 ++ .mode = 0600,
61893 ++ .proc_handler = &proc_dointvec,
61894 ++ },
61895 ++#endif
61896 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
61897 ++ {
61898 ++ .ctl_name = CTL_UNNUMBERED,
61899 ++ .procname = "chroot_enforce_chdir",
61900 ++ .data = &grsec_enable_chroot_chdir,
61901 ++ .maxlen = sizeof(int),
61902 ++ .mode = 0600,
61903 ++ .proc_handler = &proc_dointvec,
61904 ++ },
61905 ++#endif
61906 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
61907 ++ {
61908 ++ .ctl_name = CTL_UNNUMBERED,
61909 ++ .procname = "chroot_deny_chmod",
61910 ++ .data = &grsec_enable_chroot_chmod,
61911 ++ .maxlen = sizeof(int),
61912 ++ .mode = 0600,
61913 ++ .proc_handler = &proc_dointvec,
61914 ++ },
61915 ++#endif
61916 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
61917 ++ {
61918 ++ .ctl_name = CTL_UNNUMBERED,
61919 ++ .procname = "chroot_deny_mknod",
61920 ++ .data = &grsec_enable_chroot_mknod,
61921 ++ .maxlen = sizeof(int),
61922 ++ .mode = 0600,
61923 ++ .proc_handler = &proc_dointvec,
61924 ++ },
61925 ++#endif
61926 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
61927 ++ {
61928 ++ .ctl_name = CTL_UNNUMBERED,
61929 ++ .procname = "chroot_restrict_nice",
61930 ++ .data = &grsec_enable_chroot_nice,
61931 ++ .maxlen = sizeof(int),
61932 ++ .mode = 0600,
61933 ++ .proc_handler = &proc_dointvec,
61934 ++ },
61935 ++#endif
61936 ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
61937 ++ {
61938 ++ .ctl_name = CTL_UNNUMBERED,
61939 ++ .procname = "chroot_execlog",
61940 ++ .data = &grsec_enable_chroot_execlog,
61941 ++ .maxlen = sizeof(int),
61942 ++ .mode = 0600,
61943 ++ .proc_handler = &proc_dointvec,
61944 ++ },
61945 ++#endif
61946 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
61947 ++ {
61948 ++ .ctl_name = CTL_UNNUMBERED,
61949 ++ .procname = "chroot_caps",
61950 ++ .data = &grsec_enable_chroot_caps,
61951 ++ .maxlen = sizeof(int),
61952 ++ .mode = 0600,
61953 ++ .proc_handler = &proc_dointvec,
61954 ++ },
61955 ++#endif
61956 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
61957 ++ {
61958 ++ .ctl_name = CTL_UNNUMBERED,
61959 ++ .procname = "chroot_deny_sysctl",
61960 ++ .data = &grsec_enable_chroot_sysctl,
61961 ++ .maxlen = sizeof(int),
61962 ++ .mode = 0600,
61963 ++ .proc_handler = &proc_dointvec,
61964 ++ },
61965 ++#endif
61966 ++#ifdef CONFIG_GRKERNSEC_TPE
61967 ++ {
61968 ++ .ctl_name = CTL_UNNUMBERED,
61969 ++ .procname = "tpe",
61970 ++ .data = &grsec_enable_tpe,
61971 ++ .maxlen = sizeof(int),
61972 ++ .mode = 0600,
61973 ++ .proc_handler = &proc_dointvec,
61974 ++ },
61975 ++ {
61976 ++ .ctl_name = CTL_UNNUMBERED,
61977 ++ .procname = "tpe_gid",
61978 ++ .data = &grsec_tpe_gid,
61979 ++ .maxlen = sizeof(int),
61980 ++ .mode = 0600,
61981 ++ .proc_handler = &proc_dointvec,
61982 ++ },
61983 ++#endif
61984 ++#ifdef CONFIG_GRKERNSEC_TPE_ALL
61985 ++ {
61986 ++ .ctl_name = CTL_UNNUMBERED,
61987 ++ .procname = "tpe_restrict_all",
61988 ++ .data = &grsec_enable_tpe_all,
61989 ++ .maxlen = sizeof(int),
61990 ++ .mode = 0600,
61991 ++ .proc_handler = &proc_dointvec,
61992 ++ },
61993 ++#endif
61994 ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
61995 ++ {
61996 ++ .ctl_name = CTL_UNNUMBERED,
61997 ++ .procname = "socket_all",
61998 ++ .data = &grsec_enable_socket_all,
61999 ++ .maxlen = sizeof(int),
62000 ++ .mode = 0600,
62001 ++ .proc_handler = &proc_dointvec,
62002 ++ },
62003 ++ {
62004 ++ .ctl_name = CTL_UNNUMBERED,
62005 ++ .procname = "socket_all_gid",
62006 ++ .data = &grsec_socket_all_gid,
62007 ++ .maxlen = sizeof(int),
62008 ++ .mode = 0600,
62009 ++ .proc_handler = &proc_dointvec,
62010 ++ },
62011 ++#endif
62012 ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
62013 ++ {
62014 ++ .ctl_name = CTL_UNNUMBERED,
62015 ++ .procname = "socket_client",
62016 ++ .data = &grsec_enable_socket_client,
62017 ++ .maxlen = sizeof(int),
62018 ++ .mode = 0600,
62019 ++ .proc_handler = &proc_dointvec,
62020 ++ },
62021 ++ {
62022 ++ .ctl_name = CTL_UNNUMBERED,
62023 ++ .procname = "socket_client_gid",
62024 ++ .data = &grsec_socket_client_gid,
62025 ++ .maxlen = sizeof(int),
62026 ++ .mode = 0600,
62027 ++ .proc_handler = &proc_dointvec,
62028 ++ },
62029 ++#endif
62030 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
62031 ++ {
62032 ++ .ctl_name = CTL_UNNUMBERED,
62033 ++ .procname = "socket_server",
62034 ++ .data = &grsec_enable_socket_server,
62035 ++ .maxlen = sizeof(int),
62036 ++ .mode = 0600,
62037 ++ .proc_handler = &proc_dointvec,
62038 ++ },
62039 ++ {
62040 ++ .ctl_name = CTL_UNNUMBERED,
62041 ++ .procname = "socket_server_gid",
62042 ++ .data = &grsec_socket_server_gid,
62043 ++ .maxlen = sizeof(int),
62044 ++ .mode = 0600,
62045 ++ .proc_handler = &proc_dointvec,
62046 ++ },
62047 ++#endif
62048 ++#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
62049 ++ {
62050 ++ .ctl_name = CTL_UNNUMBERED,
62051 ++ .procname = "audit_group",
62052 ++ .data = &grsec_enable_group,
62053 ++ .maxlen = sizeof(int),
62054 ++ .mode = 0600,
62055 ++ .proc_handler = &proc_dointvec,
62056 ++ },
62057 ++ {
62058 ++ .ctl_name = CTL_UNNUMBERED,
62059 ++ .procname = "audit_gid",
62060 ++ .data = &grsec_audit_gid,
62061 ++ .maxlen = sizeof(int),
62062 ++ .mode = 0600,
62063 ++ .proc_handler = &proc_dointvec,
62064 ++ },
62065 ++#endif
62066 ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
62067 ++ {
62068 ++ .ctl_name = CTL_UNNUMBERED,
62069 ++ .procname = "audit_chdir",
62070 ++ .data = &grsec_enable_chdir,
62071 ++ .maxlen = sizeof(int),
62072 ++ .mode = 0600,
62073 ++ .proc_handler = &proc_dointvec,
62074 ++ },
62075 ++#endif
62076 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
62077 ++ {
62078 ++ .ctl_name = CTL_UNNUMBERED,
62079 ++ .procname = "audit_mount",
62080 ++ .data = &grsec_enable_mount,
62081 ++ .maxlen = sizeof(int),
62082 ++ .mode = 0600,
62083 ++ .proc_handler = &proc_dointvec,
62084 ++ },
62085 ++#endif
62086 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
62087 ++ {
62088 ++ .ctl_name = CTL_UNNUMBERED,
62089 ++ .procname = "audit_ipc",
62090 ++ .data = &grsec_enable_audit_ipc,
62091 ++ .maxlen = sizeof(int),
62092 ++ .mode = 0600,
62093 ++ .proc_handler = &proc_dointvec,
62094 ++ },
62095 ++#endif
62096 ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
62097 ++ {
62098 ++ .ctl_name = CTL_UNNUMBERED,
62099 ++ .procname = "audit_textrel",
62100 ++ .data = &grsec_enable_audit_textrel,
62101 ++ .maxlen = sizeof(int),
62102 ++ .mode = 0600,
62103 ++ .proc_handler = &proc_dointvec,
62104 ++ },
62105 ++#endif
62106 ++#ifdef CONFIG_GRKERNSEC_DMESG
62107 ++ {
62108 ++ .ctl_name = CTL_UNNUMBERED,
62109 ++ .procname = "dmesg",
62110 ++ .data = &grsec_enable_dmesg,
62111 ++ .maxlen = sizeof(int),
62112 ++ .mode = 0600,
62113 ++ .proc_handler = &proc_dointvec,
62114 ++ },
62115 ++#endif
62116 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
62117 ++ {
62118 ++ .ctl_name = CTL_UNNUMBERED,
62119 ++ .procname = "chroot_findtask",
62120 ++ .data = &grsec_enable_chroot_findtask,
62121 ++ .maxlen = sizeof(int),
62122 ++ .mode = 0600,
62123 ++ .proc_handler = &proc_dointvec,
62124 ++ },
62125 ++#endif
62126 ++#ifdef CONFIG_GRKERNSEC_RESLOG
62127 ++ {
62128 ++ .ctl_name = CTL_UNNUMBERED,
62129 ++ .procname = "resource_logging",
62130 ++ .data = &grsec_resource_logging,
62131 ++ .maxlen = sizeof(int),
62132 ++ .mode = 0600,
62133 ++ .proc_handler = &proc_dointvec,
62134 ++ },
62135 ++#endif
62136 ++ {
62137 ++ .ctl_name = CTL_UNNUMBERED,
62138 ++ .procname = "grsec_lock",
62139 ++ .data = &grsec_lock,
62140 ++ .maxlen = sizeof(int),
62141 ++ .mode = 0600,
62142 ++ .proc_handler = &proc_dointvec,
62143 ++ },
62144 ++#endif
62145 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
62146 ++ {
62147 ++ .ctl_name = CTL_UNNUMBERED,
62148 ++ .procname = "disable_modules",
62149 ++ .data = &grsec_modstop,
62150 ++ .maxlen = sizeof(int),
62151 ++ .mode = 0600,
62152 ++ .proc_handler = &proc_dointvec,
62153 ++ },
62154 ++#endif
62155 ++ { .ctl_name = 0 }
62156 ++};
62157 ++#endif
62158 ++
62159 ++int gr_check_modstop(void)
62160 ++{
62161 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
62162 ++ if (grsec_modstop == 1) {
62163 ++ gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
62164 ++ return 1;
62165 ++ }
62166 ++#endif
62167 ++ return 0;
62168 ++}
62169 +diff -urNp linux-2.6.27.7/grsecurity/grsec_textrel.c linux-2.6.27.7/grsecurity/grsec_textrel.c
62170 +--- linux-2.6.27.7/grsecurity/grsec_textrel.c 1969-12-31 19:00:00.000000000 -0500
62171 ++++ linux-2.6.27.7/grsecurity/grsec_textrel.c 2008-11-18 03:38:45.000000000 -0500
62172 +@@ -0,0 +1,16 @@
62173 ++#include <linux/kernel.h>
62174 ++#include <linux/sched.h>
62175 ++#include <linux/mm.h>
62176 ++#include <linux/file.h>
62177 ++#include <linux/grinternal.h>
62178 ++#include <linux/grsecurity.h>
62179 ++
62180 ++void
62181 ++gr_log_textrel(struct vm_area_struct * vma)
62182 ++{
62183 ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
62184 ++ if (grsec_enable_audit_textrel)
62185 ++ gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
62186 ++#endif
62187 ++ return;
62188 ++}
62189 +diff -urNp linux-2.6.27.7/grsecurity/grsec_time.c linux-2.6.27.7/grsecurity/grsec_time.c
62190 +--- linux-2.6.27.7/grsecurity/grsec_time.c 1969-12-31 19:00:00.000000000 -0500
62191 ++++ linux-2.6.27.7/grsecurity/grsec_time.c 2008-11-18 03:38:45.000000000 -0500
62192 +@@ -0,0 +1,13 @@
62193 ++#include <linux/kernel.h>
62194 ++#include <linux/sched.h>
62195 ++#include <linux/grinternal.h>
62196 ++
62197 ++void
62198 ++gr_log_timechange(void)
62199 ++{
62200 ++#ifdef CONFIG_GRKERNSEC_TIME
62201 ++ if (grsec_enable_time)
62202 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
62203 ++#endif
62204 ++ return;
62205 ++}
62206 +diff -urNp linux-2.6.27.7/grsecurity/grsec_tpe.c linux-2.6.27.7/grsecurity/grsec_tpe.c
62207 +--- linux-2.6.27.7/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500
62208 ++++ linux-2.6.27.7/grsecurity/grsec_tpe.c 2008-11-18 03:38:45.000000000 -0500
62209 +@@ -0,0 +1,37 @@
62210 ++#include <linux/kernel.h>
62211 ++#include <linux/sched.h>
62212 ++#include <linux/file.h>
62213 ++#include <linux/fs.h>
62214 ++#include <linux/grinternal.h>
62215 ++
62216 ++extern int gr_acl_tpe_check(void);
62217 ++
62218 ++int
62219 ++gr_tpe_allow(const struct file *file)
62220 ++{
62221 ++#ifdef CONFIG_GRKERNSEC
62222 ++ struct inode *inode = file->f_path.dentry->d_parent->d_inode;
62223 ++
62224 ++ if (current->uid && ((grsec_enable_tpe &&
62225 ++#ifdef CONFIG_GRKERNSEC_TPE_INVERT
62226 ++ !in_group_p(grsec_tpe_gid)
62227 ++#else
62228 ++ in_group_p(grsec_tpe_gid)
62229 ++#endif
62230 ++ ) || gr_acl_tpe_check()) &&
62231 ++ (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
62232 ++ (inode->i_mode & S_IWOTH))))) {
62233 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
62234 ++ return 0;
62235 ++ }
62236 ++#ifdef CONFIG_GRKERNSEC_TPE_ALL
62237 ++ if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
62238 ++ ((inode->i_uid && (inode->i_uid != current->uid)) ||
62239 ++ (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
62240 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
62241 ++ return 0;
62242 ++ }
62243 ++#endif
62244 ++#endif
62245 ++ return 1;
62246 ++}
62247 +diff -urNp linux-2.6.27.7/grsecurity/grsum.c linux-2.6.27.7/grsecurity/grsum.c
62248 +--- linux-2.6.27.7/grsecurity/grsum.c 1969-12-31 19:00:00.000000000 -0500
62249 ++++ linux-2.6.27.7/grsecurity/grsum.c 2008-11-18 03:38:45.000000000 -0500
62250 +@@ -0,0 +1,59 @@
62251 ++#include <linux/err.h>
62252 ++#include <linux/kernel.h>
62253 ++#include <linux/sched.h>
62254 ++#include <linux/mm.h>
62255 ++#include <linux/scatterlist.h>
62256 ++#include <linux/crypto.h>
62257 ++#include <linux/gracl.h>
62258 ++
62259 ++
62260 ++#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
62261 ++#error "crypto and sha256 must be built into the kernel"
62262 ++#endif
62263 ++
62264 ++int
62265 ++chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
62266 ++{
62267 ++ char *p;
62268 ++ struct crypto_hash *tfm;
62269 ++ struct hash_desc desc;
62270 ++ struct scatterlist sg;
62271 ++ unsigned char temp_sum[GR_SHA_LEN];
62272 ++ volatile int retval = 0;
62273 ++ volatile int dummy = 0;
62274 ++ unsigned int i;
62275 ++
62276 ++ tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
62277 ++ if (IS_ERR(tfm)) {
62278 ++ /* should never happen, since sha256 should be built in */
62279 ++ return 1;
62280 ++ }
62281 ++
62282 ++ desc.tfm = tfm;
62283 ++ desc.flags = 0;
62284 ++
62285 ++ crypto_hash_init(&desc);
62286 ++
62287 ++ p = salt;
62288 ++ sg_set_buf(&sg, p, GR_SALT_LEN);
62289 ++ crypto_hash_update(&desc, &sg, sg.length);
62290 ++
62291 ++ p = entry->pw;
62292 ++ sg_set_buf(&sg, p, strlen(p));
62293 ++
62294 ++ crypto_hash_update(&desc, &sg, sg.length);
62295 ++
62296 ++ crypto_hash_final(&desc, temp_sum);
62297 ++
62298 ++ memset(entry->pw, 0, GR_PW_LEN);
62299 ++
62300 ++ for (i = 0; i < GR_SHA_LEN; i++)
62301 ++ if (sum[i] != temp_sum[i])
62302 ++ retval = 1;
62303 ++ else
62304 ++ dummy = 1; // waste a cycle
62305 ++
62306 ++ crypto_free_hash(tfm);
62307 ++
62308 ++ return retval;
62309 ++}
62310 +diff -urNp linux-2.6.27.7/grsecurity/Kconfig linux-2.6.27.7/grsecurity/Kconfig
62311 +--- linux-2.6.27.7/grsecurity/Kconfig 1969-12-31 19:00:00.000000000 -0500
62312 ++++ linux-2.6.27.7/grsecurity/Kconfig 2008-11-18 11:18:57.000000000 -0500
62313 +@@ -0,0 +1,863 @@
62314 ++#
62315 ++# grecurity configuration
62316 ++#
62317 ++
62318 ++menu "Grsecurity"
62319 ++
62320 ++config GRKERNSEC
62321 ++ bool "Grsecurity"
62322 ++ select CRYPTO
62323 ++ select CRYPTO_SHA256
62324 ++ select SECURITY
62325 ++ select SECURITY_CAPABILITIES
62326 ++ help
62327 ++ If you say Y here, you will be able to configure many features
62328 ++ that will enhance the security of your system. It is highly
62329 ++ recommended that you say Y here and read through the help
62330 ++ for each option so that you fully understand the features and
62331 ++ can evaluate their usefulness for your machine.
62332 ++
62333 ++choice
62334 ++ prompt "Security Level"
62335 ++ depends on GRKERNSEC
62336 ++ default GRKERNSEC_CUSTOM
62337 ++
62338 ++config GRKERNSEC_LOW
62339 ++ bool "Low"
62340 ++ select GRKERNSEC_LINK
62341 ++ select GRKERNSEC_FIFO
62342 ++ select GRKERNSEC_EXECVE
62343 ++ select GRKERNSEC_RANDNET
62344 ++ select GRKERNSEC_DMESG
62345 ++ select GRKERNSEC_CHROOT_CHDIR
62346 ++ select GRKERNSEC_MODSTOP if (MODULES)
62347 ++
62348 ++ help
62349 ++ If you choose this option, several of the grsecurity options will
62350 ++ be enabled that will give you greater protection against a number
62351 ++ of attacks, while assuring that none of your software will have any
62352 ++ conflicts with the additional security measures. If you run a lot
62353 ++ of unusual software, or you are having problems with the higher
62354 ++ security levels, you should say Y here. With this option, the
62355 ++ following features are enabled:
62356 ++
62357 ++ - Linking restrictions
62358 ++ - FIFO restrictions
62359 ++ - Enforcing RLIMIT_NPROC on execve
62360 ++ - Restricted dmesg
62361 ++ - Enforced chdir("/") on chroot
62362 ++ - Runtime module disabling
62363 ++
62364 ++config GRKERNSEC_MEDIUM
62365 ++ bool "Medium"
62366 ++ select PAX
62367 ++ select PAX_EI_PAX
62368 ++ select PAX_PT_PAX_FLAGS
62369 ++ select PAX_HAVE_ACL_FLAGS
62370 ++ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
62371 ++ select GRKERNSEC_CHROOT_SYSCTL
62372 ++ select GRKERNSEC_LINK
62373 ++ select GRKERNSEC_FIFO
62374 ++ select GRKERNSEC_EXECVE
62375 ++ select GRKERNSEC_DMESG
62376 ++ select GRKERNSEC_RANDNET
62377 ++ select GRKERNSEC_FORKFAIL
62378 ++ select GRKERNSEC_TIME
62379 ++ select GRKERNSEC_SIGNAL
62380 ++ select GRKERNSEC_CHROOT
62381 ++ select GRKERNSEC_CHROOT_UNIX
62382 ++ select GRKERNSEC_CHROOT_MOUNT
62383 ++ select GRKERNSEC_CHROOT_PIVOT
62384 ++ select GRKERNSEC_CHROOT_DOUBLE
62385 ++ select GRKERNSEC_CHROOT_CHDIR
62386 ++ select GRKERNSEC_CHROOT_MKNOD
62387 ++ select GRKERNSEC_PROC
62388 ++ select GRKERNSEC_PROC_USERGROUP
62389 ++ select GRKERNSEC_MODSTOP if (MODULES)
62390 ++ select PAX_RANDUSTACK
62391 ++ select PAX_ASLR
62392 ++ select PAX_RANDMMAP
62393 ++ select PAX_REFCOUNT if (X86)
62394 ++
62395 ++ help
62396 ++ If you say Y here, several features in addition to those included
62397 ++ in the low additional security level will be enabled. These
62398 ++ features provide even more security to your system, though in rare
62399 ++ cases they may be incompatible with very old or poorly written
62400 ++ software. If you enable this option, make sure that your auth
62401 ++ service (identd) is running as gid 1001. With this option,
62402 ++ the following features (in addition to those provided in the
62403 ++ low additional security level) will be enabled:
62404 ++
62405 ++ - Failed fork logging
62406 ++ - Time change logging
62407 ++ - Signal logging
62408 ++ - Deny mounts in chroot
62409 ++ - Deny double chrooting
62410 ++ - Deny sysctl writes in chroot
62411 ++ - Deny mknod in chroot
62412 ++ - Deny access to abstract AF_UNIX sockets out of chroot
62413 ++ - Deny pivot_root in chroot
62414 ++ - Denied writes of /dev/kmem, /dev/mem, and /dev/port
62415 ++ - /proc restrictions with special GID set to 10 (usually wheel)
62416 ++ - Address Space Layout Randomization (ASLR)
62417 ++
62418 ++config GRKERNSEC_HIGH
62419 ++ bool "High"
62420 ++ select GRKERNSEC_LINK
62421 ++ select GRKERNSEC_FIFO
62422 ++ select GRKERNSEC_EXECVE
62423 ++ select GRKERNSEC_DMESG
62424 ++ select GRKERNSEC_FORKFAIL
62425 ++ select GRKERNSEC_TIME
62426 ++ select GRKERNSEC_SIGNAL
62427 ++ select GRKERNSEC_CHROOT_SHMAT
62428 ++ select GRKERNSEC_CHROOT_UNIX
62429 ++ select GRKERNSEC_CHROOT_MOUNT
62430 ++ select GRKERNSEC_CHROOT_FCHDIR
62431 ++ select GRKERNSEC_CHROOT_PIVOT
62432 ++ select GRKERNSEC_CHROOT_DOUBLE
62433 ++ select GRKERNSEC_CHROOT_CHDIR
62434 ++ select GRKERNSEC_CHROOT_MKNOD
62435 ++ select GRKERNSEC_CHROOT_CAPS
62436 ++ select GRKERNSEC_CHROOT_SYSCTL
62437 ++ select GRKERNSEC_CHROOT_FINDTASK
62438 ++ select GRKERNSEC_PROC
62439 ++ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
62440 ++ select GRKERNSEC_HIDESYM
62441 ++ select GRKERNSEC_BRUTE
62442 ++ select GRKERNSEC_PROC_USERGROUP
62443 ++ select GRKERNSEC_KMEM
62444 ++ select GRKERNSEC_RESLOG
62445 ++ select GRKERNSEC_RANDNET
62446 ++ select GRKERNSEC_PROC_ADD
62447 ++ select GRKERNSEC_CHROOT_CHMOD
62448 ++ select GRKERNSEC_CHROOT_NICE
62449 ++ select GRKERNSEC_AUDIT_MOUNT
62450 ++ select GRKERNSEC_MODSTOP if (MODULES)
62451 ++ select PAX
62452 ++ select PAX_RANDUSTACK
62453 ++ select PAX_ASLR
62454 ++ select PAX_RANDMMAP
62455 ++ select PAX_NOEXEC
62456 ++ select PAX_MPROTECT
62457 ++ select PAX_EI_PAX
62458 ++ select PAX_PT_PAX_FLAGS
62459 ++ select PAX_HAVE_ACL_FLAGS
62460 ++ select PAX_KERNEXEC if (X86 && !EFI && !COMPAT_VDSO && !PARAVIRT && (!X86_32 || X86_WP_WORKS_OK))
62461 ++ select PAX_MEMORY_UDEREF if (!X86_64 && !COMPAT_VDSO)
62462 ++ select PAX_RANDKSTACK if (X86_TSC && !X86_64)
62463 ++ select PAX_SEGMEXEC if (X86 && !X86_64)
62464 ++ select PAX_PAGEEXEC if (!X86)
62465 ++ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
62466 ++ select PAX_DLRESOLVE if (SPARC32 || SPARC64)
62467 ++ select PAX_SYSCALL if (PPC32)
62468 ++ select PAX_EMUTRAMP if (PARISC)
62469 ++ select PAX_EMUSIGRT if (PARISC)
62470 ++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
62471 ++ select PAX_REFCOUNT if (X86)
62472 ++ help
62473 ++ If you say Y here, many of the features of grsecurity will be
62474 ++ enabled, which will protect you against many kinds of attacks
62475 ++ against your system. The heightened security comes at a cost
62476 ++ of an increased chance of incompatibilities with rare software
62477 ++ on your machine. Since this security level enables PaX, you should
62478 ++ view <http://pax.grsecurity.net> and read about the PaX
62479 ++ project. While you are there, download chpax and run it on
62480 ++ binaries that cause problems with PaX. Also remember that
62481 ++ since the /proc restrictions are enabled, you must run your
62482 ++ identd as gid 1001. This security level enables the following
62483 ++ features in addition to those listed in the low and medium
62484 ++ security levels:
62485 ++
62486 ++ - Additional /proc restrictions
62487 ++ - Chmod restrictions in chroot
62488 ++ - No signals, ptrace, or viewing of processes outside of chroot
62489 ++ - Capability restrictions in chroot
62490 ++ - Deny fchdir out of chroot
62491 ++ - Priority restrictions in chroot
62492 ++ - Segmentation-based implementation of PaX
62493 ++ - Mprotect restrictions
62494 ++ - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
62495 ++ - Kernel stack randomization
62496 ++ - Mount/unmount/remount logging
62497 ++ - Kernel symbol hiding
62498 ++ - Prevention of memory exhaustion-based exploits
62499 ++config GRKERNSEC_CUSTOM
62500 ++ bool "Custom"
62501 ++ help
62502 ++ If you say Y here, you will be able to configure every grsecurity
62503 ++ option, which allows you to enable many more features that aren't
62504 ++ covered in the basic security levels. These additional features
62505 ++ include TPE, socket restrictions, and the sysctl system for
62506 ++ grsecurity. It is advised that you read through the help for
62507 ++ each option to determine its usefulness in your situation.
62508 ++
62509 ++endchoice
62510 ++
62511 ++menu "Address Space Protection"
62512 ++depends on GRKERNSEC
62513 ++
62514 ++config GRKERNSEC_KMEM
62515 ++ bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
62516 ++ help
62517 ++ If you say Y here, /dev/kmem and /dev/mem won't be allowed to
62518 ++ be written to via mmap or otherwise to modify the running kernel.
62519 ++ /dev/port will also not be allowed to be opened. If you have module
62520 ++ support disabled, enabling this will close up four ways that are
62521 ++ currently used to insert malicious code into the running kernel.
62522 ++ Even with all these features enabled, we still highly recommend that
62523 ++ you use the RBAC system, as it is still possible for an attacker to
62524 ++ modify the running kernel through privileged I/O granted by ioperm/iopl.
62525 ++ If you are not using XFree86, you may be able to stop this additional
62526 ++ case by enabling the 'Disable privileged I/O' option. Though nothing
62527 ++ legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
62528 ++ but only to video memory, which is the only writing we allow in this
62529 ++ case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
62530 ++ not be allowed to mprotect it with PROT_WRITE later.
62531 ++ It is highly recommended that you say Y here if you meet all the
62532 ++ conditions above.
62533 ++
62534 ++config GRKERNSEC_IO
62535 ++ bool "Disable privileged I/O"
62536 ++ depends on X86
62537 ++ select RTC
62538 ++ help
62539 ++ If you say Y here, all ioperm and iopl calls will return an error.
62540 ++ Ioperm and iopl can be used to modify the running kernel.
62541 ++ Unfortunately, some programs need this access to operate properly,
62542 ++ the most notable of which are XFree86 and hwclock. hwclock can be
62543 ++ remedied by having RTC support in the kernel, so CONFIG_RTC is
62544 ++ enabled if this option is enabled, to ensure that hwclock operates
62545 ++ correctly. XFree86 still will not operate correctly with this option
62546 ++ enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86
62547 ++ and you still want to protect your kernel against modification,
62548 ++ use the RBAC system.
62549 ++
62550 ++config GRKERNSEC_PROC_MEMMAP
62551 ++ bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
62552 ++ depends on PAX_NOEXEC || PAX_ASLR
62553 ++ help
62554 ++ If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
62555 ++ give no information about the addresses of its mappings if
62556 ++ PaX features that rely on random addresses are enabled on the task.
62557 ++ If you use PaX it is greatly recommended that you say Y here as it
62558 ++ closes up a hole that makes the full ASLR useless for suid
62559 ++ binaries.
62560 ++
62561 ++config GRKERNSEC_BRUTE
62562 ++ bool "Deter exploit bruteforcing"
62563 ++ help
62564 ++ If you say Y here, attempts to bruteforce exploits against forking
62565 ++ daemons such as apache or sshd will be deterred. When a child of a
62566 ++ forking daemon is killed by PaX or crashes due to an illegal
62567 ++ instruction, the parent process will be delayed 30 seconds upon every
62568 ++ subsequent fork until the administrator is able to assess the
62569 ++ situation and restart the daemon. It is recommended that you also
62570 ++ enable signal logging in the auditing section so that logs are
62571 ++ generated when a process performs an illegal instruction.
62572 ++
62573 ++config GRKERNSEC_MODSTOP
62574 ++ bool "Runtime module disabling"
62575 ++ depends on MODULES
62576 ++ help
62577 ++ If you say Y here, you will be able to disable the ability to (un)load
62578 ++ modules at runtime. This feature is useful if you need the ability
62579 ++ to load kernel modules at boot time, but do not want to allow an
62580 ++ attacker to load a rootkit kernel module into the system, or to remove
62581 ++ a loaded kernel module important to system functioning. You should
62582 ++ enable the /dev/mem protection feature as well, since rootkits can be
62583 ++ inserted into the kernel via other methods than kernel modules. Since
62584 ++ an untrusted module could still be loaded by modifying init scripts and
62585 ++ rebooting the system, it is also recommended that you enable the RBAC
62586 ++ system. If you enable this option, a sysctl option with name
62587 ++ "disable_modules" will be created. Setting this option to "1" disables
62588 ++ module loading. After this option is set, no further writes to it are
62589 ++ allowed until the system is rebooted.
62590 ++
62591 ++config GRKERNSEC_HIDESYM
62592 ++ bool "Hide kernel symbols"
62593 ++ help
62594 ++ If you say Y here, getting information on loaded modules, and
62595 ++ displaying all kernel symbols through a syscall will be restricted
62596 ++ to users with CAP_SYS_MODULE. This option is only effective
62597 ++ provided the following conditions are met:
62598 ++ 1) The kernel using grsecurity is not precompiled by some distribution
62599 ++ 2) You are using the RBAC system and hiding other files such as your
62600 ++ kernel image and System.map
62601 ++ 3) You have the additional /proc restrictions enabled, which removes
62602 ++ /proc/kcore
62603 ++ If the above conditions are met, this option will aid to provide a
62604 ++ useful protection against local and remote kernel exploitation of
62605 ++ overflows and arbitrary read/write vulnerabilities.
62606 ++
62607 ++endmenu
62608 ++menu "Role Based Access Control Options"
62609 ++depends on GRKERNSEC
62610 ++
62611 ++config GRKERNSEC_ACL_HIDEKERN
62612 ++ bool "Hide kernel processes"
62613 ++ help
62614 ++ If you say Y here, all kernel threads will be hidden to all
62615 ++ processes but those whose subject has the "view hidden processes"
62616 ++ flag.
62617 ++
62618 ++config GRKERNSEC_ACL_MAXTRIES
62619 ++ int "Maximum tries before password lockout"
62620 ++ default 3
62621 ++ help
62622 ++ This option enforces the maximum number of times a user can attempt
62623 ++ to authorize themselves with the grsecurity RBAC system before being
62624 ++ denied the ability to attempt authorization again for a specified time.
62625 ++ The lower the number, the harder it will be to brute-force a password.
62626 ++
62627 ++config GRKERNSEC_ACL_TIMEOUT
62628 ++ int "Time to wait after max password tries, in seconds"
62629 ++ default 30
62630 ++ help
62631 ++ This option specifies the time the user must wait after attempting to
62632 ++ authorize to the RBAC system with the maximum number of invalid
62633 ++ passwords. The higher the number, the harder it will be to brute-force
62634 ++ a password.
62635 ++
62636 ++endmenu
62637 ++menu "Filesystem Protections"
62638 ++depends on GRKERNSEC
62639 ++
62640 ++config GRKERNSEC_PROC
62641 ++ bool "Proc restrictions"
62642 ++ help
62643 ++ If you say Y here, the permissions of the /proc filesystem
62644 ++ will be altered to enhance system security and privacy. You MUST
62645 ++ choose either a user only restriction or a user and group restriction.
62646 ++ Depending upon the option you choose, you can either restrict users to
62647 ++ see only the processes they themselves run, or choose a group that can
62648 ++ view all processes and files normally restricted to root if you choose
62649 ++ the "restrict to user only" option. NOTE: If you're running identd as
62650 ++ a non-root user, you will have to run it as the group you specify here.
62651 ++
62652 ++config GRKERNSEC_PROC_USER
62653 ++ bool "Restrict /proc to user only"
62654 ++ depends on GRKERNSEC_PROC
62655 ++ help
62656 ++ If you say Y here, non-root users will only be able to view their own
62657 ++ processes, and restricts them from viewing network-related information,
62658 ++ and viewing kernel symbol and module information.
62659 ++
62660 ++config GRKERNSEC_PROC_USERGROUP
62661 ++ bool "Allow special group"
62662 ++ depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
62663 ++ help
62664 ++ If you say Y here, you will be able to select a group that will be
62665 ++ able to view all processes, network-related information, and
62666 ++ kernel and symbol information. This option is useful if you want
62667 ++ to run identd as a non-root user.
62668 ++
62669 ++config GRKERNSEC_PROC_GID
62670 ++ int "GID for special group"
62671 ++ depends on GRKERNSEC_PROC_USERGROUP
62672 ++ default 1001
62673 ++
62674 ++config GRKERNSEC_PROC_ADD
62675 ++ bool "Additional restrictions"
62676 ++ depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
62677 ++ help
62678 ++ If you say Y here, additional restrictions will be placed on
62679 ++ /proc that keep normal users from viewing device information and
62680 ++ slabinfo information that could be useful for exploits.
62681 ++
62682 ++config GRKERNSEC_LINK
62683 ++ bool "Linking restrictions"
62684 ++ help
62685 ++ If you say Y here, /tmp race exploits will be prevented, since users
62686 ++ will no longer be able to follow symlinks owned by other users in
62687 ++ world-writable +t directories (i.e. /tmp), unless the owner of the
62688 ++ symlink is the owner of the directory. users will also not be
62689 ++ able to hardlink to files they do not own. If the sysctl option is
62690 ++ enabled, a sysctl option with name "linking_restrictions" is created.
62691 ++
62692 ++config GRKERNSEC_FIFO
62693 ++ bool "FIFO restrictions"
62694 ++ help
62695 ++ If you say Y here, users will not be able to write to FIFOs they don't
62696 ++ own in world-writable +t directories (i.e. /tmp), unless the owner of
62697 ++ the FIFO is the same owner of the directory it's held in. If the sysctl
62698 ++ option is enabled, a sysctl option with name "fifo_restrictions" is
62699 ++ created.
62700 ++
62701 ++config GRKERNSEC_CHROOT
62702 ++ bool "Chroot jail restrictions"
62703 ++ help
62704 ++ If you say Y here, you will be able to choose several options that will
62705 ++ make breaking out of a chrooted jail much more difficult. If you
62706 ++ encounter no software incompatibilities with the following options, it
62707 ++ is recommended that you enable each one.
62708 ++
62709 ++config GRKERNSEC_CHROOT_MOUNT
62710 ++ bool "Deny mounts"
62711 ++ depends on GRKERNSEC_CHROOT
62712 ++ help
62713 ++ If you say Y here, processes inside a chroot will not be able to
62714 ++ mount or remount filesystems. If the sysctl option is enabled, a
62715 ++ sysctl option with name "chroot_deny_mount" is created.
62716 ++
62717 ++config GRKERNSEC_CHROOT_DOUBLE
62718 ++ bool "Deny double-chroots"
62719 ++ depends on GRKERNSEC_CHROOT
62720 ++ help
62721 ++ If you say Y here, processes inside a chroot will not be able to chroot
62722 ++ again outside the chroot. This is a widely used method of breaking
62723 ++ out of a chroot jail and should not be allowed. If the sysctl
62724 ++ option is enabled, a sysctl option with name
62725 ++ "chroot_deny_chroot" is created.
62726 ++
62727 ++config GRKERNSEC_CHROOT_PIVOT
62728 ++ bool "Deny pivot_root in chroot"
62729 ++ depends on GRKERNSEC_CHROOT
62730 ++ help
62731 ++ If you say Y here, processes inside a chroot will not be able to use
62732 ++ a function called pivot_root() that was introduced in Linux 2.3.41. It
62733 ++ works similar to chroot in that it changes the root filesystem. This
62734 ++ function could be misused in a chrooted process to attempt to break out
62735 ++ of the chroot, and therefore should not be allowed. If the sysctl
62736 ++ option is enabled, a sysctl option with name "chroot_deny_pivot" is
62737 ++ created.
62738 ++
62739 ++config GRKERNSEC_CHROOT_CHDIR
62740 ++ bool "Enforce chdir(\"/\") on all chroots"
62741 ++ depends on GRKERNSEC_CHROOT
62742 ++ help
62743 ++ If you say Y here, the current working directory of all newly-chrooted
62744 ++ applications will be set to the the root directory of the chroot.
62745 ++ The man page on chroot(2) states:
62746 ++ Note that this call does not change the current working
62747 ++ directory, so that `.' can be outside the tree rooted at
62748 ++ `/'. In particular, the super-user can escape from a
62749 ++ `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
62750 ++
62751 ++ It is recommended that you say Y here, since it's not known to break
62752 ++ any software. If the sysctl option is enabled, a sysctl option with
62753 ++ name "chroot_enforce_chdir" is created.
62754 ++
62755 ++config GRKERNSEC_CHROOT_CHMOD
62756 ++ bool "Deny (f)chmod +s"
62757 ++ depends on GRKERNSEC_CHROOT
62758 ++ help
62759 ++ If you say Y here, processes inside a chroot will not be able to chmod
62760 ++ or fchmod files to make them have suid or sgid bits. This protects
62761 ++ against another published method of breaking a chroot. If the sysctl
62762 ++ option is enabled, a sysctl option with name "chroot_deny_chmod" is
62763 ++ created.
62764 ++
62765 ++config GRKERNSEC_CHROOT_FCHDIR
62766 ++ bool "Deny fchdir out of chroot"
62767 ++ depends on GRKERNSEC_CHROOT
62768 ++ help
62769 ++ If you say Y here, a well-known method of breaking chroots by fchdir'ing
62770 ++ to a file descriptor of the chrooting process that points to a directory
62771 ++ outside the filesystem will be stopped. If the sysctl option
62772 ++ is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
62773 ++
62774 ++config GRKERNSEC_CHROOT_MKNOD
62775 ++ bool "Deny mknod"
62776 ++ depends on GRKERNSEC_CHROOT
62777 ++ help
62778 ++ If you say Y here, processes inside a chroot will not be allowed to
62779 ++ mknod. The problem with using mknod inside a chroot is that it
62780 ++ would allow an attacker to create a device entry that is the same
62781 ++ as one on the physical root of your system, which could range from
62782 ++ anything from the console device to a device for your harddrive (which
62783 ++ they could then use to wipe the drive or steal data). It is recommended
62784 ++ that you say Y here, unless you run into software incompatibilities.
62785 ++ If the sysctl option is enabled, a sysctl option with name
62786 ++ "chroot_deny_mknod" is created.
62787 ++
62788 ++config GRKERNSEC_CHROOT_SHMAT
62789 ++ bool "Deny shmat() out of chroot"
62790 ++ depends on GRKERNSEC_CHROOT
62791 ++ help
62792 ++ If you say Y here, processes inside a chroot will not be able to attach
62793 ++ to shared memory segments that were created outside of the chroot jail.
62794 ++ It is recommended that you say Y here. If the sysctl option is enabled,
62795 ++ a sysctl option with name "chroot_deny_shmat" is created.
62796 ++
62797 ++config GRKERNSEC_CHROOT_UNIX
62798 ++ bool "Deny access to abstract AF_UNIX sockets out of chroot"
62799 ++ depends on GRKERNSEC_CHROOT
62800 ++ help
62801 ++ If you say Y here, processes inside a chroot will not be able to
62802 ++ connect to abstract (meaning not belonging to a filesystem) Unix
62803 ++ domain sockets that were bound outside of a chroot. It is recommended
62804 ++ that you say Y here. If the sysctl option is enabled, a sysctl option
62805 ++ with name "chroot_deny_unix" is created.
62806 ++
62807 ++config GRKERNSEC_CHROOT_FINDTASK
62808 ++ bool "Protect outside processes"
62809 ++ depends on GRKERNSEC_CHROOT
62810 ++ help
62811 ++ If you say Y here, processes inside a chroot will not be able to
62812 ++ kill, send signals with fcntl, ptrace, capget, getpgid, getsid,
62813 ++ or view any process outside of the chroot. If the sysctl
62814 ++ option is enabled, a sysctl option with name "chroot_findtask" is
62815 ++ created.
62816 ++
62817 ++config GRKERNSEC_CHROOT_NICE
62818 ++ bool "Restrict priority changes"
62819 ++ depends on GRKERNSEC_CHROOT
62820 ++ help
62821 ++ If you say Y here, processes inside a chroot will not be able to raise
62822 ++ the priority of processes in the chroot, or alter the priority of
62823 ++ processes outside the chroot. This provides more security than simply
62824 ++ removing CAP_SYS_NICE from the process' capability set. If the
62825 ++ sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
62826 ++ is created.
62827 ++
62828 ++config GRKERNSEC_CHROOT_SYSCTL
62829 ++ bool "Deny sysctl writes"
62830 ++ depends on GRKERNSEC_CHROOT
62831 ++ help
62832 ++ If you say Y here, an attacker in a chroot will not be able to
62833 ++ write to sysctl entries, either by sysctl(2) or through a /proc
62834 ++ interface. It is strongly recommended that you say Y here. If the
62835 ++ sysctl option is enabled, a sysctl option with name
62836 ++ "chroot_deny_sysctl" is created.
62837 ++
62838 ++config GRKERNSEC_CHROOT_CAPS
62839 ++ bool "Capability restrictions"
62840 ++ depends on GRKERNSEC_CHROOT
62841 ++ help
62842 ++ If you say Y here, the capabilities on all root processes within a
62843 ++ chroot jail will be lowered to stop module insertion, raw i/o,
62844 ++ system and net admin tasks, rebooting the system, modifying immutable
62845 ++ files, modifying IPC owned by another, and changing the system time.
62846 ++ This is left an option because it can break some apps. Disable this
62847 ++ if your chrooted apps are having problems performing those kinds of
62848 ++ tasks. If the sysctl option is enabled, a sysctl option with
62849 ++ name "chroot_caps" is created.
62850 ++
62851 ++endmenu
62852 ++menu "Kernel Auditing"
62853 ++depends on GRKERNSEC
62854 ++
62855 ++config GRKERNSEC_AUDIT_GROUP
62856 ++ bool "Single group for auditing"
62857 ++ help
62858 ++ If you say Y here, the exec, chdir, (un)mount, and ipc logging features
62859 ++ will only operate on a group you specify. This option is recommended
62860 ++ if you only want to watch certain users instead of having a large
62861 ++ amount of logs from the entire system. If the sysctl option is enabled,
62862 ++ a sysctl option with name "audit_group" is created.
62863 ++
62864 ++config GRKERNSEC_AUDIT_GID
62865 ++ int "GID for auditing"
62866 ++ depends on GRKERNSEC_AUDIT_GROUP
62867 ++ default 1007
62868 ++
62869 ++config GRKERNSEC_EXECLOG
62870 ++ bool "Exec logging"
62871 ++ help
62872 ++ If you say Y here, all execve() calls will be logged (since the
62873 ++ other exec*() calls are frontends to execve(), all execution
62874 ++ will be logged). Useful for shell-servers that like to keep track
62875 ++ of their users. If the sysctl option is enabled, a sysctl option with
62876 ++ name "exec_logging" is created.
62877 ++ WARNING: This option when enabled will produce a LOT of logs, especially
62878 ++ on an active system.
62879 ++
62880 ++config GRKERNSEC_RESLOG
62881 ++ bool "Resource logging"
62882 ++ help
62883 ++ If you say Y here, all attempts to overstep resource limits will
62884 ++ be logged with the resource name, the requested size, and the current
62885 ++ limit. It is highly recommended that you say Y here. If the sysctl
62886 ++ option is enabled, a sysctl option with name "resource_logging" is
62887 ++ created. If the RBAC system is enabled, the sysctl value is ignored.
62888 ++
62889 ++config GRKERNSEC_CHROOT_EXECLOG
62890 ++ bool "Log execs within chroot"
62891 ++ help
62892 ++ If you say Y here, all executions inside a chroot jail will be logged
62893 ++ to syslog. This can cause a large amount of logs if certain
62894 ++ applications (eg. djb's daemontools) are installed on the system, and
62895 ++ is therefore left as an option. If the sysctl option is enabled, a
62896 ++ sysctl option with name "chroot_execlog" is created.
62897 ++
62898 ++config GRKERNSEC_AUDIT_CHDIR
62899 ++ bool "Chdir logging"
62900 ++ help
62901 ++ If you say Y here, all chdir() calls will be logged. If the sysctl
62902 ++ option is enabled, a sysctl option with name "audit_chdir" is created.
62903 ++
62904 ++config GRKERNSEC_AUDIT_MOUNT
62905 ++ bool "(Un)Mount logging"
62906 ++ help
62907 ++ If you say Y here, all mounts and unmounts will be logged. If the
62908 ++ sysctl option is enabled, a sysctl option with name "audit_mount" is
62909 ++ created.
62910 ++
62911 ++config GRKERNSEC_AUDIT_IPC
62912 ++ bool "IPC logging"
62913 ++ help
62914 ++ If you say Y here, creation and removal of message queues, semaphores,
62915 ++ and shared memory will be logged. If the sysctl option is enabled, a
62916 ++ sysctl option with name "audit_ipc" is created.
62917 ++
62918 ++config GRKERNSEC_SIGNAL
62919 ++ bool "Signal logging"
62920 ++ help
62921 ++ If you say Y here, certain important signals will be logged, such as
62922 ++ SIGSEGV, which will as a result inform you of when a error in a program
62923 ++ occurred, which in some cases could mean a possible exploit attempt.
62924 ++ If the sysctl option is enabled, a sysctl option with name
62925 ++ "signal_logging" is created.
62926 ++
62927 ++config GRKERNSEC_FORKFAIL
62928 ++ bool "Fork failure logging"
62929 ++ help
62930 ++ If you say Y here, all failed fork() attempts will be logged.
62931 ++ This could suggest a fork bomb, or someone attempting to overstep
62932 ++ their process limit. If the sysctl option is enabled, a sysctl option
62933 ++ with name "forkfail_logging" is created.
62934 ++
62935 ++config GRKERNSEC_TIME
62936 ++ bool "Time change logging"
62937 ++ help
62938 ++ If you say Y here, any changes of the system clock will be logged.
62939 ++ If the sysctl option is enabled, a sysctl option with name
62940 ++ "timechange_logging" is created.
62941 ++
62942 ++config GRKERNSEC_PROC_IPADDR
62943 ++ bool "/proc/<pid>/ipaddr support"
62944 ++ help
62945 ++ If you say Y here, a new entry will be added to each /proc/<pid>
62946 ++ directory that contains the IP address of the person using the task.
62947 ++ The IP is carried across local TCP and AF_UNIX stream sockets.
62948 ++ This information can be useful for IDS/IPSes to perform remote response
62949 ++ to a local attack. The entry is readable by only the owner of the
62950 ++ process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
62951 ++ the RBAC system), and thus does not create privacy concerns.
62952 ++
62953 ++config GRKERNSEC_AUDIT_TEXTREL
62954 ++ bool 'ELF text relocations logging (READ HELP)'
62955 ++ depends on PAX_MPROTECT
62956 ++ help
62957 ++ If you say Y here, text relocations will be logged with the filename
62958 ++ of the offending library or binary. The purpose of the feature is
62959 ++ to help Linux distribution developers get rid of libraries and
62960 ++ binaries that need text relocations which hinder the future progress
62961 ++ of PaX. Only Linux distribution developers should say Y here, and
62962 ++ never on a production machine, as this option creates an information
62963 ++ leak that could aid an attacker in defeating the randomization of
62964 ++ a single memory region. If the sysctl option is enabled, a sysctl
62965 ++ option with name "audit_textrel" is created.
62966 ++
62967 ++endmenu
62968 ++
62969 ++menu "Executable Protections"
62970 ++depends on GRKERNSEC
62971 ++
62972 ++config GRKERNSEC_EXECVE
62973 ++ bool "Enforce RLIMIT_NPROC on execs"
62974 ++ help
62975 ++ If you say Y here, users with a resource limit on processes will
62976 ++ have the value checked during execve() calls. The current system
62977 ++ only checks the system limit during fork() calls. If the sysctl option
62978 ++ is enabled, a sysctl option with name "execve_limiting" is created.
62979 ++
62980 ++config GRKERNSEC_DMESG
62981 ++ bool "Dmesg(8) restriction"
62982 ++ help
62983 ++ If you say Y here, non-root users will not be able to use dmesg(8)
62984 ++ to view up to the last 4kb of messages in the kernel's log buffer.
62985 ++ If the sysctl option is enabled, a sysctl option with name "dmesg" is
62986 ++ created.
62987 ++
62988 ++config GRKERNSEC_TPE
62989 ++ bool "Trusted Path Execution (TPE)"
62990 ++ help
62991 ++ If you say Y here, you will be able to choose a gid to add to the
62992 ++ supplementary groups of users you want to mark as "untrusted."
62993 ++ These users will not be able to execute any files that are not in
62994 ++ root-owned directories writable only by root. If the sysctl option
62995 ++ is enabled, a sysctl option with name "tpe" is created.
62996 ++
62997 ++config GRKERNSEC_TPE_ALL
62998 ++ bool "Partially restrict non-root users"
62999 ++ depends on GRKERNSEC_TPE
63000 ++ help
63001 ++ If you say Y here, All non-root users other than the ones in the
63002 ++ group specified in the main TPE option will only be allowed to
63003 ++ execute files in directories they own that are not group or
63004 ++ world-writable, or in directories owned by root and writable only by
63005 ++ root. If the sysctl option is enabled, a sysctl option with name
63006 ++ "tpe_restrict_all" is created.
63007 ++
63008 ++config GRKERNSEC_TPE_INVERT
63009 ++ bool "Invert GID option"
63010 ++ depends on GRKERNSEC_TPE
63011 ++ help
63012 ++ If you say Y here, the group you specify in the TPE configuration will
63013 ++ decide what group TPE restrictions will be *disabled* for. This
63014 ++ option is useful if you want TPE restrictions to be applied to most
63015 ++ users on the system.
63016 ++
63017 ++config GRKERNSEC_TPE_GID
63018 ++ int "GID for untrusted users"
63019 ++ depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
63020 ++ default 1005
63021 ++ help
63022 ++ If you have selected the "Invert GID option" above, setting this
63023 ++ GID determines what group TPE restrictions will be *disabled* for.
63024 ++ If you have not selected the "Invert GID option" above, setting this
63025 ++ GID determines what group TPE restrictions will be *enabled* for.
63026 ++ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
63027 ++ is created.
63028 ++
63029 ++config GRKERNSEC_TPE_GID
63030 ++ int "GID for trusted users"
63031 ++ depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
63032 ++ default 1005
63033 ++ help
63034 ++ If you have selected the "Invert GID option" above, setting this
63035 ++ GID determines what group TPE restrictions will be *disabled* for.
63036 ++ If you have not selected the "Invert GID option" above, setting this
63037 ++ GID determines what group TPE restrictions will be *enabled* for.
63038 ++ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
63039 ++ is created.
63040 ++
63041 ++endmenu
63042 ++menu "Network Protections"
63043 ++depends on GRKERNSEC
63044 ++
63045 ++config GRKERNSEC_RANDNET
63046 ++ bool "Larger entropy pools"
63047 ++ help
63048 ++ If you say Y here, the entropy pools used for many features of Linux
63049 ++ and grsecurity will be doubled in size. Since several grsecurity
63050 ++ features use additional randomness, it is recommended that you say Y
63051 ++ here. Saying Y here has a similar effect as modifying
63052 ++ /proc/sys/kernel/random/poolsize.
63053 ++
63054 ++config GRKERNSEC_SOCKET
63055 ++ bool "Socket restrictions"
63056 ++ help
63057 ++ If you say Y here, you will be able to choose from several options.
63058 ++ If you assign a GID on your system and add it to the supplementary
63059 ++ groups of users you want to restrict socket access to, this patch
63060 ++ will perform up to three things, based on the option(s) you choose.
63061 ++
63062 ++config GRKERNSEC_SOCKET_ALL
63063 ++ bool "Deny any sockets to group"
63064 ++ depends on GRKERNSEC_SOCKET
63065 ++ help
63066 ++ If you say Y here, you will be able to choose a GID of whose users will
63067 ++ be unable to connect to other hosts from your machine or run server
63068 ++ applications from your machine. If the sysctl option is enabled, a
63069 ++ sysctl option with name "socket_all" is created.
63070 ++
63071 ++config GRKERNSEC_SOCKET_ALL_GID
63072 ++ int "GID to deny all sockets for"
63073 ++ depends on GRKERNSEC_SOCKET_ALL
63074 ++ default 1004
63075 ++ help
63076 ++ Here you can choose the GID to disable socket access for. Remember to
63077 ++ add the users you want socket access disabled for to the GID
63078 ++ specified here. If the sysctl option is enabled, a sysctl option
63079 ++ with name "socket_all_gid" is created.
63080 ++
63081 ++config GRKERNSEC_SOCKET_CLIENT
63082 ++ bool "Deny client sockets to group"
63083 ++ depends on GRKERNSEC_SOCKET
63084 ++ help
63085 ++ If you say Y here, you will be able to choose a GID of whose users will
63086 ++ be unable to connect to other hosts from your machine, but will be
63087 ++ able to run servers. If this option is enabled, all users in the group
63088 ++ you specify will have to use passive mode when initiating ftp transfers
63089 ++ from the shell on your machine. If the sysctl option is enabled, a
63090 ++ sysctl option with name "socket_client" is created.
63091 ++
63092 ++config GRKERNSEC_SOCKET_CLIENT_GID
63093 ++ int "GID to deny client sockets for"
63094 ++ depends on GRKERNSEC_SOCKET_CLIENT
63095 ++ default 1003
63096 ++ help
63097 ++ Here you can choose the GID to disable client socket access for.
63098 ++ Remember to add the users you want client socket access disabled for to
63099 ++ the GID specified here. If the sysctl option is enabled, a sysctl
63100 ++ option with name "socket_client_gid" is created.
63101 ++
63102 ++config GRKERNSEC_SOCKET_SERVER
63103 ++ bool "Deny server sockets to group"
63104 ++ depends on GRKERNSEC_SOCKET
63105 ++ help
63106 ++ If you say Y here, you will be able to choose a GID of whose users will
63107 ++ be unable to run server applications from your machine. If the sysctl
63108 ++ option is enabled, a sysctl option with name "socket_server" is created.
63109 ++
63110 ++config GRKERNSEC_SOCKET_SERVER_GID
63111 ++ int "GID to deny server sockets for"
63112 ++ depends on GRKERNSEC_SOCKET_SERVER
63113 ++ default 1002
63114 ++ help
63115 ++ Here you can choose the GID to disable server socket access for.
63116 ++ Remember to add the users you want server socket access disabled for to
63117 ++ the GID specified here. If the sysctl option is enabled, a sysctl
63118 ++ option with name "socket_server_gid" is created.
63119 ++
63120 ++endmenu
63121 ++menu "Sysctl support"
63122 ++depends on GRKERNSEC && SYSCTL
63123 ++
63124 ++config GRKERNSEC_SYSCTL
63125 ++ bool "Sysctl support"
63126 ++ help
63127 ++ If you say Y here, you will be able to change the options that
63128 ++ grsecurity runs with at bootup, without having to recompile your
63129 ++ kernel. You can echo values to files in /proc/sys/kernel/grsecurity
63130 ++ to enable (1) or disable (0) various features. All the sysctl entries
63131 ++ are mutable until the "grsec_lock" entry is set to a non-zero value.
63132 ++ All features enabled in the kernel configuration are disabled at boot
63133 ++ if you do not say Y to the "Turn on features by default" option.
63134 ++ All options should be set at startup, and the grsec_lock entry should
63135 ++ be set to a non-zero value after all the options are set.
63136 ++ *THIS IS EXTREMELY IMPORTANT*
63137 ++
63138 ++config GRKERNSEC_SYSCTL_ON
63139 ++ bool "Turn on features by default"
63140 ++ depends on GRKERNSEC_SYSCTL
63141 ++ help
63142 ++ If you say Y here, instead of having all features enabled in the
63143 ++ kernel configuration disabled at boot time, the features will be
63144 ++ enabled at boot time. It is recommended you say Y here unless
63145 ++ there is some reason you would want all sysctl-tunable features to
63146 ++ be disabled by default. As mentioned elsewhere, it is important
63147 ++ to enable the grsec_lock entry once you have finished modifying
63148 ++ the sysctl entries.
63149 ++
63150 ++endmenu
63151 ++menu "Logging Options"
63152 ++depends on GRKERNSEC
63153 ++
63154 ++config GRKERNSEC_FLOODTIME
63155 ++ int "Seconds in between log messages (minimum)"
63156 ++ default 10
63157 ++ help
63158 ++ This option allows you to enforce the number of seconds between
63159 ++ grsecurity log messages. The default should be suitable for most
63160 ++ people, however, if you choose to change it, choose a value small enough
63161 ++ to allow informative logs to be produced, but large enough to
63162 ++ prevent flooding.
63163 ++
63164 ++config GRKERNSEC_FLOODBURST
63165 ++ int "Number of messages in a burst (maximum)"
63166 ++ default 4
63167 ++ help
63168 ++ This option allows you to choose the maximum number of messages allowed
63169 ++ within the flood time interval you chose in a separate option. The
63170 ++ default should be suitable for most people, however if you find that
63171 ++ many of your logs are being interpreted as flooding, you may want to
63172 ++ raise this value.
63173 ++
63174 ++endmenu
63175 ++
63176 ++endmenu
63177 +diff -urNp linux-2.6.27.7/grsecurity/Makefile linux-2.6.27.7/grsecurity/Makefile
63178 +--- linux-2.6.27.7/grsecurity/Makefile 1969-12-31 19:00:00.000000000 -0500
63179 ++++ linux-2.6.27.7/grsecurity/Makefile 2008-11-18 03:38:45.000000000 -0500
63180 +@@ -0,0 +1,20 @@
63181 ++# grsecurity's ACL system was originally written in 2001 by Michael Dalton
63182 ++# during 2001-2005 it has been completely redesigned by Brad Spengler
63183 ++# into an RBAC system
63184 ++#
63185 ++# All code in this directory and various hooks inserted throughout the kernel
63186 ++# are copyright Brad Spengler, and released under the GPL v2 or higher
63187 ++
63188 ++obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
63189 ++ grsec_mount.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
63190 ++ grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
63191 ++
63192 ++obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
63193 ++ gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
63194 ++ gracl_learn.o grsec_log.o
63195 ++obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
63196 ++
63197 ++ifndef CONFIG_GRKERNSEC
63198 ++obj-y += grsec_disabled.o
63199 ++endif
63200 ++
63201 +diff -urNp linux-2.6.27.7/include/asm-cris/kmap_types.h linux-2.6.27.7/include/asm-cris/kmap_types.h
63202 +--- linux-2.6.27.7/include/asm-cris/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
63203 ++++ linux-2.6.27.7/include/asm-cris/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
63204 +@@ -19,6 +19,7 @@ enum km_type {
63205 + KM_IRQ1,
63206 + KM_SOFTIRQ0,
63207 + KM_SOFTIRQ1,
63208 ++ KM_CLEARPAGE,
63209 + KM_TYPE_NR
63210 + };
63211 +
63212 +diff -urNp linux-2.6.27.7/include/asm-frv/kmap_types.h linux-2.6.27.7/include/asm-frv/kmap_types.h
63213 +--- linux-2.6.27.7/include/asm-frv/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
63214 ++++ linux-2.6.27.7/include/asm-frv/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
63215 +@@ -23,6 +23,7 @@ enum km_type {
63216 + KM_IRQ1,
63217 + KM_SOFTIRQ0,
63218 + KM_SOFTIRQ1,
63219 ++ KM_CLEARPAGE,
63220 + KM_TYPE_NR
63221 + };
63222 +
63223 +diff -urNp linux-2.6.27.7/include/asm-generic/futex.h linux-2.6.27.7/include/asm-generic/futex.h
63224 +--- linux-2.6.27.7/include/asm-generic/futex.h 2008-11-07 12:55:34.000000000 -0500
63225 ++++ linux-2.6.27.7/include/asm-generic/futex.h 2008-11-18 03:38:45.000000000 -0500
63226 +@@ -6,7 +6,7 @@
63227 + #include <asm/errno.h>
63228 +
63229 + static inline int
63230 +-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
63231 ++futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
63232 + {
63233 + int op = (encoded_op >> 28) & 7;
63234 + int cmp = (encoded_op >> 24) & 15;
63235 +@@ -48,7 +48,7 @@ futex_atomic_op_inuser (int encoded_op,
63236 + }
63237 +
63238 + static inline int
63239 +-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
63240 ++futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
63241 + {
63242 + return -ENOSYS;
63243 + }
63244 +diff -urNp linux-2.6.27.7/include/asm-generic/vmlinux.lds.h linux-2.6.27.7/include/asm-generic/vmlinux.lds.h
63245 +--- linux-2.6.27.7/include/asm-generic/vmlinux.lds.h 2008-11-07 12:55:34.000000000 -0500
63246 ++++ linux-2.6.27.7/include/asm-generic/vmlinux.lds.h 2008-11-18 03:38:45.000000000 -0500
63247 +@@ -59,6 +59,7 @@
63248 + .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
63249 + VMLINUX_SYMBOL(__start_rodata) = .; \
63250 + *(.rodata) *(.rodata.*) \
63251 ++ *(.data.read_only) \
63252 + *(__vermagic) /* Kernel version magic */ \
63253 + *(__markers_strings) /* Markers: strings */ \
63254 + } \
63255 +diff -urNp linux-2.6.27.7/include/asm-m32r/kmap_types.h linux-2.6.27.7/include/asm-m32r/kmap_types.h
63256 +--- linux-2.6.27.7/include/asm-m32r/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
63257 ++++ linux-2.6.27.7/include/asm-m32r/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
63258 +@@ -21,7 +21,8 @@ D(9) KM_IRQ0,
63259 + D(10) KM_IRQ1,
63260 + D(11) KM_SOFTIRQ0,
63261 + D(12) KM_SOFTIRQ1,
63262 +-D(13) KM_TYPE_NR
63263 ++D(13) KM_CLEARPAGE,
63264 ++D(14) KM_TYPE_NR
63265 + };
63266 +
63267 + #undef D
63268 +diff -urNp linux-2.6.27.7/include/asm-m68k/kmap_types.h linux-2.6.27.7/include/asm-m68k/kmap_types.h
63269 +--- linux-2.6.27.7/include/asm-m68k/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
63270 ++++ linux-2.6.27.7/include/asm-m68k/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
63271 +@@ -15,6 +15,7 @@ enum km_type {
63272 + KM_IRQ1,
63273 + KM_SOFTIRQ0,
63274 + KM_SOFTIRQ1,
63275 ++ KM_CLEARPAGE,
63276 + KM_TYPE_NR
63277 + };
63278 +
63279 +diff -urNp linux-2.6.27.7/include/asm-mips/elf.h linux-2.6.27.7/include/asm-mips/elf.h
63280 +--- linux-2.6.27.7/include/asm-mips/elf.h 2008-11-07 12:55:34.000000000 -0500
63281 ++++ linux-2.6.27.7/include/asm-mips/elf.h 2008-11-18 03:38:45.000000000 -0500
63282 +@@ -368,4 +368,11 @@ extern int dump_task_fpu(struct task_str
63283 + #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
63284 + #endif
63285 +
63286 ++#ifdef CONFIG_PAX_ASLR
63287 ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
63288 ++
63289 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
63290 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
63291 ++#endif
63292 ++
63293 + #endif /* _ASM_ELF_H */
63294 +diff -urNp linux-2.6.27.7/include/asm-mips/kmap_types.h linux-2.6.27.7/include/asm-mips/kmap_types.h
63295 +--- linux-2.6.27.7/include/asm-mips/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
63296 ++++ linux-2.6.27.7/include/asm-mips/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
63297 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
63298 + D(10) KM_IRQ1,
63299 + D(11) KM_SOFTIRQ0,
63300 + D(12) KM_SOFTIRQ1,
63301 +-D(13) KM_TYPE_NR
63302 ++D(13) KM_CLEARPAGE,
63303 ++D(14) KM_TYPE_NR
63304 + };
63305 +
63306 + #undef D
63307 +diff -urNp linux-2.6.27.7/include/asm-mips/page.h linux-2.6.27.7/include/asm-mips/page.h
63308 +--- linux-2.6.27.7/include/asm-mips/page.h 2008-11-07 12:55:34.000000000 -0500
63309 ++++ linux-2.6.27.7/include/asm-mips/page.h 2008-11-18 03:38:45.000000000 -0500
63310 +@@ -82,7 +82,7 @@ extern void copy_user_highpage(struct pa
63311 + #ifdef CONFIG_CPU_MIPS32
63312 + typedef struct { unsigned long pte_low, pte_high; } pte_t;
63313 + #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
63314 +- #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
63315 ++ #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
63316 + #else
63317 + typedef struct { unsigned long long pte; } pte_t;
63318 + #define pte_val(x) ((x).pte)
63319 +diff -urNp linux-2.6.27.7/include/asm-mips/system.h linux-2.6.27.7/include/asm-mips/system.h
63320 +--- linux-2.6.27.7/include/asm-mips/system.h 2008-11-07 12:55:34.000000000 -0500
63321 ++++ linux-2.6.27.7/include/asm-mips/system.h 2008-11-18 03:38:45.000000000 -0500
63322 +@@ -215,6 +215,6 @@ extern void per_cpu_trap_init(void);
63323 + */
63324 + #define __ARCH_WANT_UNLOCKED_CTXSW
63325 +
63326 +-extern unsigned long arch_align_stack(unsigned long sp);
63327 ++#define arch_align_stack(x) ((x) & ALMASK)
63328 +
63329 + #endif /* _ASM_SYSTEM_H */
63330 +diff -urNp linux-2.6.27.7/include/asm-mn10300/kmap_types.h linux-2.6.27.7/include/asm-mn10300/kmap_types.h
63331 +--- linux-2.6.27.7/include/asm-mn10300/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
63332 ++++ linux-2.6.27.7/include/asm-mn10300/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
63333 +@@ -25,6 +25,7 @@ enum km_type {
63334 + KM_IRQ1,
63335 + KM_SOFTIRQ0,
63336 + KM_SOFTIRQ1,
63337 ++ KM_CLEARPAGE,
63338 + KM_TYPE_NR
63339 + };
63340 +
63341 +diff -urNp linux-2.6.27.7/include/asm-parisc/elf.h linux-2.6.27.7/include/asm-parisc/elf.h
63342 +--- linux-2.6.27.7/include/asm-parisc/elf.h 2008-11-07 12:55:34.000000000 -0500
63343 ++++ linux-2.6.27.7/include/asm-parisc/elf.h 2008-11-18 03:38:45.000000000 -0500
63344 +@@ -333,6 +333,13 @@ struct pt_regs; /* forward declaration..
63345 +
63346 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
63347 +
63348 ++#ifdef CONFIG_PAX_ASLR
63349 ++#define PAX_ELF_ET_DYN_BASE 0x10000UL
63350 ++
63351 ++#define PAX_DELTA_MMAP_LEN 16
63352 ++#define PAX_DELTA_STACK_LEN 16
63353 ++#endif
63354 ++
63355 + /* This yields a mask that user programs can use to figure out what
63356 + instruction set this CPU supports. This could be done in user space,
63357 + but it's not easy, and we've already done it here. */
63358 +diff -urNp linux-2.6.27.7/include/asm-parisc/kmap_types.h linux-2.6.27.7/include/asm-parisc/kmap_types.h
63359 +--- linux-2.6.27.7/include/asm-parisc/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
63360 ++++ linux-2.6.27.7/include/asm-parisc/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
63361 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
63362 + D(10) KM_IRQ1,
63363 + D(11) KM_SOFTIRQ0,
63364 + D(12) KM_SOFTIRQ1,
63365 +-D(13) KM_TYPE_NR
63366 ++D(13) KM_CLEARPAGE,
63367 ++D(14) KM_TYPE_NR
63368 + };
63369 +
63370 + #undef D
63371 +diff -urNp linux-2.6.27.7/include/asm-parisc/pgtable.h linux-2.6.27.7/include/asm-parisc/pgtable.h
63372 +--- linux-2.6.27.7/include/asm-parisc/pgtable.h 2008-11-07 12:55:34.000000000 -0500
63373 ++++ linux-2.6.27.7/include/asm-parisc/pgtable.h 2008-11-18 03:38:45.000000000 -0500
63374 +@@ -202,6 +202,17 @@
63375 + #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
63376 + #define PAGE_COPY PAGE_EXECREAD
63377 + #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
63378 ++
63379 ++#ifdef CONFIG_PAX_PAGEEXEC
63380 ++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
63381 ++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
63382 ++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
63383 ++#else
63384 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
63385 ++# define PAGE_COPY_NOEXEC PAGE_COPY
63386 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
63387 ++#endif
63388 ++
63389 + #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
63390 + #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
63391 + #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
63392 +diff -urNp linux-2.6.27.7/include/asm-um/kmap_types.h linux-2.6.27.7/include/asm-um/kmap_types.h
63393 +--- linux-2.6.27.7/include/asm-um/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
63394 ++++ linux-2.6.27.7/include/asm-um/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
63395 +@@ -23,6 +23,7 @@ enum km_type {
63396 + KM_IRQ1,
63397 + KM_SOFTIRQ0,
63398 + KM_SOFTIRQ1,
63399 ++ KM_CLEARPAGE,
63400 + KM_TYPE_NR
63401 + };
63402 +
63403 +diff -urNp linux-2.6.27.7/include/asm-um/page.h linux-2.6.27.7/include/asm-um/page.h
63404 +--- linux-2.6.27.7/include/asm-um/page.h 2008-11-07 12:55:34.000000000 -0500
63405 ++++ linux-2.6.27.7/include/asm-um/page.h 2008-11-18 03:38:45.000000000 -0500
63406 +@@ -14,6 +14,9 @@
63407 + #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
63408 + #define PAGE_MASK (~(PAGE_SIZE-1))
63409 +
63410 ++#define ktla_ktva(addr) (addr)
63411 ++#define ktva_ktla(addr) (addr)
63412 ++
63413 + #ifndef __ASSEMBLY__
63414 +
63415 + struct page;
63416 +diff -urNp linux-2.6.27.7/include/asm-x86/alternative.h linux-2.6.27.7/include/asm-x86/alternative.h
63417 +--- linux-2.6.27.7/include/asm-x86/alternative.h 2008-11-07 12:55:34.000000000 -0500
63418 ++++ linux-2.6.27.7/include/asm-x86/alternative.h 2008-11-18 03:38:45.000000000 -0500
63419 +@@ -96,7 +96,7 @@ const unsigned char *const *find_nop_tab
63420 + " .byte 662b-661b\n" /* sourcelen */ \
63421 + " .byte 664f-663f\n" /* replacementlen */ \
63422 + ".previous\n" \
63423 +- ".section .altinstr_replacement,\"ax\"\n" \
63424 ++ ".section .altinstr_replacement,\"a\"\n" \
63425 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
63426 + ".previous" :: "i" (feature) : "memory")
63427 +
63428 +@@ -120,7 +120,7 @@ const unsigned char *const *find_nop_tab
63429 + " .byte 662b-661b\n" /* sourcelen */ \
63430 + " .byte 664f-663f\n" /* replacementlen */ \
63431 + ".previous\n" \
63432 +- ".section .altinstr_replacement,\"ax\"\n" \
63433 ++ ".section .altinstr_replacement,\"a\"\n" \
63434 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
63435 + ".previous" :: "i" (feature), ##input)
63436 +
63437 +@@ -135,7 +135,7 @@ const unsigned char *const *find_nop_tab
63438 + " .byte 662b-661b\n" /* sourcelen */ \
63439 + " .byte 664f-663f\n" /* replacementlen */ \
63440 + ".previous\n" \
63441 +- ".section .altinstr_replacement,\"ax\"\n" \
63442 ++ ".section .altinstr_replacement,\"a\"\n" \
63443 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
63444 + ".previous" : output : [feat] "i" (feature), ##input)
63445 +
63446 +diff -urNp linux-2.6.27.7/include/asm-x86/atomic_32.h linux-2.6.27.7/include/asm-x86/atomic_32.h
63447 +--- linux-2.6.27.7/include/asm-x86/atomic_32.h 2008-11-07 12:55:34.000000000 -0500
63448 ++++ linux-2.6.27.7/include/asm-x86/atomic_32.h 2008-11-18 03:38:45.000000000 -0500
63449 +@@ -47,7 +47,15 @@ typedef struct {
63450 + */
63451 + static inline void atomic_add(int i, atomic_t *v)
63452 + {
63453 +- asm volatile(LOCK_PREFIX "addl %1,%0"
63454 ++ asm volatile(LOCK_PREFIX "addl %1,%0\n"
63455 ++
63456 ++#ifdef CONFIG_PAX_REFCOUNT
63457 ++ "jno 0f\n"
63458 ++ LOCK_PREFIX "subl %1,%0\n"
63459 ++ "into\n0:\n"
63460 ++ _ASM_EXTABLE(0b, 0b)
63461 ++#endif
63462 ++
63463 + : "+m" (v->counter)
63464 + : "ir" (i));
63465 + }
63466 +@@ -61,7 +69,15 @@ static inline void atomic_add(int i, ato
63467 + */
63468 + static inline void atomic_sub(int i, atomic_t *v)
63469 + {
63470 +- asm volatile(LOCK_PREFIX "subl %1,%0"
63471 ++ asm volatile(LOCK_PREFIX "subl %1,%0\n"
63472 ++
63473 ++#ifdef CONFIG_PAX_REFCOUNT
63474 ++ "jno 0f\n"
63475 ++ LOCK_PREFIX "addl %1,%0\n"
63476 ++ "into\n0:\n"
63477 ++ _ASM_EXTABLE(0b, 0b)
63478 ++#endif
63479 ++
63480 + : "+m" (v->counter)
63481 + : "ir" (i));
63482 + }
63483 +@@ -79,7 +95,16 @@ static inline int atomic_sub_and_test(in
63484 + {
63485 + unsigned char c;
63486 +
63487 +- asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
63488 ++ asm volatile(LOCK_PREFIX "subl %2,%0\n"
63489 ++
63490 ++#ifdef CONFIG_PAX_REFCOUNT
63491 ++ "jno 0f\n"
63492 ++ LOCK_PREFIX "addl %2,%0\n"
63493 ++ "into\n0:\n"
63494 ++ _ASM_EXTABLE(0b, 0b)
63495 ++#endif
63496 ++
63497 ++ "sete %1\n"
63498 + : "+m" (v->counter), "=qm" (c)
63499 + : "ir" (i) : "memory");
63500 + return c;
63501 +@@ -93,7 +118,18 @@ static inline int atomic_sub_and_test(in
63502 + */
63503 + static inline void atomic_inc(atomic_t *v)
63504 + {
63505 +- asm volatile(LOCK_PREFIX "incl %0"
63506 ++ asm volatile(LOCK_PREFIX "incl %0\n"
63507 ++
63508 ++#ifdef CONFIG_PAX_REFCOUNT
63509 ++ "into\n0:\n"
63510 ++ ".pushsection .fixup,\"ax\"\n"
63511 ++ "1:\n"
63512 ++ LOCK_PREFIX "decl %0\n"
63513 ++ "jmp 0b\n"
63514 ++ ".popsection\n"
63515 ++ _ASM_EXTABLE(0b, 1b)
63516 ++#endif
63517 ++
63518 + : "+m" (v->counter));
63519 + }
63520 +
63521 +@@ -105,7 +141,18 @@ static inline void atomic_inc(atomic_t *
63522 + */
63523 + static inline void atomic_dec(atomic_t *v)
63524 + {
63525 +- asm volatile(LOCK_PREFIX "decl %0"
63526 ++ asm volatile(LOCK_PREFIX "decl %0\n"
63527 ++
63528 ++#ifdef CONFIG_PAX_REFCOUNT
63529 ++ "into\n0:\n"
63530 ++ ".pushsection .fixup,\"ax\"\n"
63531 ++ "1: \n"
63532 ++ LOCK_PREFIX "incl %0\n"
63533 ++ "jmp 0b\n"
63534 ++ ".popsection\n"
63535 ++ _ASM_EXTABLE(0b, 1b)
63536 ++#endif
63537 ++
63538 + : "+m" (v->counter));
63539 + }
63540 +
63541 +@@ -121,7 +168,19 @@ static inline int atomic_dec_and_test(at
63542 + {
63543 + unsigned char c;
63544 +
63545 +- asm volatile(LOCK_PREFIX "decl %0; sete %1"
63546 ++ asm volatile(LOCK_PREFIX "decl %0\n"
63547 ++
63548 ++#ifdef CONFIG_PAX_REFCOUNT
63549 ++ "into\n0:\n"
63550 ++ ".pushsection .fixup,\"ax\"\n"
63551 ++ "1: \n"
63552 ++ LOCK_PREFIX "incl %0\n"
63553 ++ "jmp 0b\n"
63554 ++ ".popsection\n"
63555 ++ _ASM_EXTABLE(0b, 1b)
63556 ++#endif
63557 ++
63558 ++ "sete %1\n"
63559 + : "+m" (v->counter), "=qm" (c)
63560 + : : "memory");
63561 + return c != 0;
63562 +@@ -139,7 +198,19 @@ static inline int atomic_inc_and_test(at
63563 + {
63564 + unsigned char c;
63565 +
63566 +- asm volatile(LOCK_PREFIX "incl %0; sete %1"
63567 ++ asm volatile(LOCK_PREFIX "incl %0\n"
63568 ++
63569 ++#ifdef CONFIG_PAX_REFCOUNT
63570 ++ "into\n0:\n"
63571 ++ ".pushsection .fixup,\"ax\"\n"
63572 ++ "1: \n"
63573 ++ LOCK_PREFIX "decl %0\n"
63574 ++ "jmp 0b\n"
63575 ++ ".popsection\n"
63576 ++ _ASM_EXTABLE(0b, 1b)
63577 ++#endif
63578 ++
63579 ++ "sete %1\n"
63580 + : "+m" (v->counter), "=qm" (c)
63581 + : : "memory");
63582 + return c != 0;
63583 +@@ -158,7 +229,16 @@ static inline int atomic_add_negative(in
63584 + {
63585 + unsigned char c;
63586 +
63587 +- asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
63588 ++ asm volatile(LOCK_PREFIX "addl %2,%0\n"
63589 ++
63590 ++#ifdef CONFIG_PAX_REFCOUNT
63591 ++ "jno 0f\n"
63592 ++ LOCK_PREFIX "subl %2,%0\n"
63593 ++ "into\n0:\n"
63594 ++ _ASM_EXTABLE(0b, 0b)
63595 ++#endif
63596 ++
63597 ++ "sets %1\n"
63598 + : "+m" (v->counter), "=qm" (c)
63599 + : "ir" (i) : "memory");
63600 + return c;
63601 +@@ -181,7 +261,15 @@ static inline int atomic_add_return(int
63602 + #endif
63603 + /* Modern 486+ processor */
63604 + __i = i;
63605 +- asm volatile(LOCK_PREFIX "xaddl %0, %1"
63606 ++ asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
63607 ++
63608 ++#ifdef CONFIG_PAX_REFCOUNT
63609 ++ "jno 0f\n"
63610 ++ "movl %0, %1\n"
63611 ++ "into\n0:\n"
63612 ++ _ASM_EXTABLE(0b, 0b)
63613 ++#endif
63614 ++
63615 + : "+r" (i), "+m" (v->counter)
63616 + : : "memory");
63617 + return i + __i;
63618 +diff -urNp linux-2.6.27.7/include/asm-x86/atomic_64.h linux-2.6.27.7/include/asm-x86/atomic_64.h
63619 +--- linux-2.6.27.7/include/asm-x86/atomic_64.h 2008-11-07 12:55:34.000000000 -0500
63620 ++++ linux-2.6.27.7/include/asm-x86/atomic_64.h 2008-11-18 03:38:45.000000000 -0500
63621 +@@ -48,7 +48,15 @@ typedef struct {
63622 + */
63623 + static inline void atomic_add(int i, atomic_t *v)
63624 + {
63625 +- asm volatile(LOCK_PREFIX "addl %1,%0"
63626 ++ asm volatile(LOCK_PREFIX "addl %1,%0\n"
63627 ++
63628 ++#ifdef CONFIG_PAX_REFCOUNT
63629 ++ "jno 0f\n"
63630 ++ LOCK_PREFIX "subl %1,%0\n"
63631 ++ "int $4\n0:\n"
63632 ++ _ASM_EXTABLE(0b, 0b)
63633 ++#endif
63634 ++
63635 + : "=m" (v->counter)
63636 + : "ir" (i), "m" (v->counter));
63637 + }
63638 +@@ -62,7 +70,15 @@ static inline void atomic_add(int i, ato
63639 + */
63640 + static inline void atomic_sub(int i, atomic_t *v)
63641 + {
63642 +- asm volatile(LOCK_PREFIX "subl %1,%0"
63643 ++ asm volatile(LOCK_PREFIX "subl %1,%0\n"
63644 ++
63645 ++#ifdef CONFIG_PAX_REFCOUNT
63646 ++ "jno 0f\n"
63647 ++ LOCK_PREFIX "addl %1,%0\n"
63648 ++ "int $4\n0:\n"
63649 ++ _ASM_EXTABLE(0b, 0b)
63650 ++#endif
63651 ++
63652 + : "=m" (v->counter)
63653 + : "ir" (i), "m" (v->counter));
63654 + }
63655 +@@ -80,7 +96,16 @@ static inline int atomic_sub_and_test(in
63656 + {
63657 + unsigned char c;
63658 +
63659 +- asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
63660 ++ asm volatile(LOCK_PREFIX "subl %2,%0\n"
63661 ++
63662 ++#ifdef CONFIG_PAX_REFCOUNT
63663 ++ "jno 0f\n"
63664 ++ LOCK_PREFIX "addl %2,%0\n"
63665 ++ "int $4\n0:\n"
63666 ++ _ASM_EXTABLE(0b, 0b)
63667 ++#endif
63668 ++
63669 ++ "sete %1\n"
63670 + : "=m" (v->counter), "=qm" (c)
63671 + : "ir" (i), "m" (v->counter) : "memory");
63672 + return c;
63673 +@@ -94,7 +119,19 @@ static inline int atomic_sub_and_test(in
63674 + */
63675 + static inline void atomic_inc(atomic_t *v)
63676 + {
63677 +- asm volatile(LOCK_PREFIX "incl %0"
63678 ++ asm volatile(LOCK_PREFIX "incl %0\n"
63679 ++
63680 ++#ifdef CONFIG_PAX_REFCOUNT
63681 ++ "jno 0f\n"
63682 ++ "int $4\n0:\n"
63683 ++ ".pushsection .fixup,\"ax\"\n"
63684 ++ "1:\n"
63685 ++ LOCK_PREFIX "decl %0\n"
63686 ++ "jmp 0b\n"
63687 ++ ".popsection\n"
63688 ++ _ASM_EXTABLE(0b, 1b)
63689 ++#endif
63690 ++
63691 + : "=m" (v->counter)
63692 + : "m" (v->counter));
63693 + }
63694 +@@ -107,7 +144,19 @@ static inline void atomic_inc(atomic_t *
63695 + */
63696 + static inline void atomic_dec(atomic_t *v)
63697 + {
63698 +- asm volatile(LOCK_PREFIX "decl %0"
63699 ++ asm volatile(LOCK_PREFIX "decl %0\n"
63700 ++
63701 ++#ifdef CONFIG_PAX_REFCOUNT
63702 ++ "jno 0f\n"
63703 ++ "int $4\n0:\n"
63704 ++ ".pushsection .fixup,\"ax\"\n"
63705 ++ "1: \n"
63706 ++ LOCK_PREFIX "incl %0\n"
63707 ++ "jmp 0b\n"
63708 ++ ".popsection\n"
63709 ++ _ASM_EXTABLE(0b, 1b)
63710 ++#endif
63711 ++
63712 + : "=m" (v->counter)
63713 + : "m" (v->counter));
63714 + }
63715 +@@ -124,7 +173,20 @@ static inline int atomic_dec_and_test(at
63716 + {
63717 + unsigned char c;
63718 +
63719 +- asm volatile(LOCK_PREFIX "decl %0; sete %1"
63720 ++ asm volatile(LOCK_PREFIX "decl %0\n"
63721 ++
63722 ++#ifdef CONFIG_PAX_REFCOUNT
63723 ++ "jno 0f\n"
63724 ++ "int $4\n0:\n"
63725 ++ ".pushsection .fixup,\"ax\"\n"
63726 ++ "1: \n"
63727 ++ LOCK_PREFIX "incl %0\n"
63728 ++ "jmp 0b\n"
63729 ++ ".popsection\n"
63730 ++ _ASM_EXTABLE(0b, 1b)
63731 ++#endif
63732 ++
63733 ++ "sete %1\n"
63734 + : "=m" (v->counter), "=qm" (c)
63735 + : "m" (v->counter) : "memory");
63736 + return c != 0;
63737 +@@ -142,7 +204,20 @@ static inline int atomic_inc_and_test(at
63738 + {
63739 + unsigned char c;
63740 +
63741 +- asm volatile(LOCK_PREFIX "incl %0; sete %1"
63742 ++ asm volatile(LOCK_PREFIX "incl %0\n"
63743 ++
63744 ++#ifdef CONFIG_PAX_REFCOUNT
63745 ++ "jno 0f\n"
63746 ++ "int $4\n0:\n"
63747 ++ ".pushsection .fixup,\"ax\"\n"
63748 ++ "1: \n"
63749 ++ LOCK_PREFIX "decl %0\n"
63750 ++ "jmp 0b\n"
63751 ++ ".popsection\n"
63752 ++ _ASM_EXTABLE(0b, 1b)
63753 ++#endif
63754 ++
63755 ++ "sete %1\n"
63756 + : "=m" (v->counter), "=qm" (c)
63757 + : "m" (v->counter) : "memory");
63758 + return c != 0;
63759 +@@ -161,7 +236,16 @@ static inline int atomic_add_negative(in
63760 + {
63761 + unsigned char c;
63762 +
63763 +- asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
63764 ++ asm volatile(LOCK_PREFIX "addl %2,%0\n"
63765 ++
63766 ++#ifdef CONFIG_PAX_REFCOUNT
63767 ++ "jno 0f\n"
63768 ++ LOCK_PREFIX "subl %2,%0\n"
63769 ++ "int $4\n0:\n"
63770 ++ _ASM_EXTABLE(0b, 0b)
63771 ++#endif
63772 ++
63773 ++ "sets %1\n"
63774 + : "=m" (v->counter), "=qm" (c)
63775 + : "ir" (i), "m" (v->counter) : "memory");
63776 + return c;
63777 +@@ -177,7 +261,15 @@ static inline int atomic_add_negative(in
63778 + static inline int atomic_add_return(int i, atomic_t *v)
63779 + {
63780 + int __i = i;
63781 +- asm volatile(LOCK_PREFIX "xaddl %0, %1"
63782 ++ asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
63783 ++
63784 ++#ifdef CONFIG_PAX_REFCOUNT
63785 ++ "jno 0f\n"
63786 ++ "movl %0, %1\n"
63787 ++ "int $4\n0:\n"
63788 ++ _ASM_EXTABLE(0b, 0b)
63789 ++#endif
63790 ++
63791 + : "+r" (i), "+m" (v->counter)
63792 + : : "memory");
63793 + return i + __i;
63794 +@@ -226,7 +318,15 @@ typedef struct {
63795 + */
63796 + static inline void atomic64_add(long i, atomic64_t *v)
63797 + {
63798 +- asm volatile(LOCK_PREFIX "addq %1,%0"
63799 ++ asm volatile(LOCK_PREFIX "addq %1,%0\n"
63800 ++
63801 ++#ifdef CONFIG_PAX_REFCOUNT
63802 ++ "jno 0f\n"
63803 ++ LOCK_PREFIX "subq %1,%0\n"
63804 ++ "int $4\n0:\n"
63805 ++ _ASM_EXTABLE(0b, 0b)
63806 ++#endif
63807 ++
63808 + : "=m" (v->counter)
63809 + : "er" (i), "m" (v->counter));
63810 + }
63811 +@@ -240,7 +340,15 @@ static inline void atomic64_add(long i,
63812 + */
63813 + static inline void atomic64_sub(long i, atomic64_t *v)
63814 + {
63815 +- asm volatile(LOCK_PREFIX "subq %1,%0"
63816 ++ asm volatile(LOCK_PREFIX "subq %1,%0\n"
63817 ++
63818 ++#ifdef CONFIG_PAX_REFCOUNT
63819 ++ "jno 0f\n"
63820 ++ LOCK_PREFIX "addq %1,%0\n"
63821 ++ "int $4\n0:\n"
63822 ++ _ASM_EXTABLE(0b, 0b)
63823 ++#endif
63824 ++
63825 + : "=m" (v->counter)
63826 + : "er" (i), "m" (v->counter));
63827 + }
63828 +@@ -258,7 +366,16 @@ static inline int atomic64_sub_and_test(
63829 + {
63830 + unsigned char c;
63831 +
63832 +- asm volatile(LOCK_PREFIX "subq %2,%0; sete %1"
63833 ++ asm volatile(LOCK_PREFIX "subq %2,%0\n"
63834 ++
63835 ++#ifdef CONFIG_PAX_REFCOUNT
63836 ++ "jno 0f\n"
63837 ++ LOCK_PREFIX "addq %2,%0\n"
63838 ++ "int $4\n0:\n"
63839 ++ _ASM_EXTABLE(0b, 0b)
63840 ++#endif
63841 ++
63842 ++ "sete %1\n"
63843 + : "=m" (v->counter), "=qm" (c)
63844 + : "er" (i), "m" (v->counter) : "memory");
63845 + return c;
63846 +@@ -272,7 +389,19 @@ static inline int atomic64_sub_and_test(
63847 + */
63848 + static inline void atomic64_inc(atomic64_t *v)
63849 + {
63850 +- asm volatile(LOCK_PREFIX "incq %0"
63851 ++ asm volatile(LOCK_PREFIX "incq %0\n"
63852 ++
63853 ++#ifdef CONFIG_PAX_REFCOUNT
63854 ++ "jno 0f\n"
63855 ++ "int $4\n0:\n"
63856 ++ ".pushsection .fixup,\"ax\"\n"
63857 ++ "1:\n"
63858 ++ LOCK_PREFIX "decq %0\n"
63859 ++ "jmp 0b\n"
63860 ++ ".popsection\n"
63861 ++ _ASM_EXTABLE(0b, 1b)
63862 ++#endif
63863 ++
63864 + : "=m" (v->counter)
63865 + : "m" (v->counter));
63866 + }
63867 +@@ -285,7 +414,19 @@ static inline void atomic64_inc(atomic64
63868 + */
63869 + static inline void atomic64_dec(atomic64_t *v)
63870 + {
63871 +- asm volatile(LOCK_PREFIX "decq %0"
63872 ++ asm volatile(LOCK_PREFIX "decq %0\n"
63873 ++
63874 ++#ifdef CONFIG_PAX_REFCOUNT
63875 ++ "jno 0f\n"
63876 ++ "int $4\n0:\n"
63877 ++ ".pushsection .fixup,\"ax\"\n"
63878 ++ "1: \n"
63879 ++ LOCK_PREFIX "incq %0\n"
63880 ++ "jmp 0b\n"
63881 ++ ".popsection\n"
63882 ++ _ASM_EXTABLE(0b, 1b)
63883 ++#endif
63884 ++
63885 + : "=m" (v->counter)
63886 + : "m" (v->counter));
63887 + }
63888 +@@ -302,7 +443,20 @@ static inline int atomic64_dec_and_test(
63889 + {
63890 + unsigned char c;
63891 +
63892 +- asm volatile(LOCK_PREFIX "decq %0; sete %1"
63893 ++ asm volatile(LOCK_PREFIX "decq %0\n"
63894 ++
63895 ++#ifdef CONFIG_PAX_REFCOUNT
63896 ++ "jno 0f\n"
63897 ++ "int $4\n0:\n"
63898 ++ ".pushsection .fixup,\"ax\"\n"
63899 ++ "1: \n"
63900 ++ LOCK_PREFIX "incq %0\n"
63901 ++ "jmp 0b\n"
63902 ++ ".popsection\n"
63903 ++ _ASM_EXTABLE(0b, 1b)
63904 ++#endif
63905 ++
63906 ++ "sete %1\n"
63907 + : "=m" (v->counter), "=qm" (c)
63908 + : "m" (v->counter) : "memory");
63909 + return c != 0;
63910 +@@ -320,7 +474,20 @@ static inline int atomic64_inc_and_test(
63911 + {
63912 + unsigned char c;
63913 +
63914 +- asm volatile(LOCK_PREFIX "incq %0; sete %1"
63915 ++ asm volatile(LOCK_PREFIX "incq %0\n"
63916 ++
63917 ++#ifdef CONFIG_PAX_REFCOUNT
63918 ++ "jno 0f\n"
63919 ++ "int $4\n0:\n"
63920 ++ ".pushsection .fixup,\"ax\"\n"
63921 ++ "1: \n"
63922 ++ LOCK_PREFIX "decq %0\n"
63923 ++ "jmp 0b\n"
63924 ++ ".popsection\n"
63925 ++ _ASM_EXTABLE(0b, 1b)
63926 ++#endif
63927 ++
63928 ++ "sete %1\n"
63929 + : "=m" (v->counter), "=qm" (c)
63930 + : "m" (v->counter) : "memory");
63931 + return c != 0;
63932 +@@ -339,7 +506,16 @@ static inline int atomic64_add_negative(
63933 + {
63934 + unsigned char c;
63935 +
63936 +- asm volatile(LOCK_PREFIX "addq %2,%0; sets %1"
63937 ++ asm volatile(LOCK_PREFIX "addq %2,%0\n"
63938 ++
63939 ++#ifdef CONFIG_PAX_REFCOUNT
63940 ++ "jno 0f\n"
63941 ++ LOCK_PREFIX "subq %2,%0\n"
63942 ++ "int $4\n0:\n"
63943 ++ _ASM_EXTABLE(0b, 0b)
63944 ++#endif
63945 ++
63946 ++ "sets %1\n"
63947 + : "=m" (v->counter), "=qm" (c)
63948 + : "er" (i), "m" (v->counter) : "memory");
63949 + return c;
63950 +@@ -355,7 +531,15 @@ static inline int atomic64_add_negative(
63951 + static inline long atomic64_add_return(long i, atomic64_t *v)
63952 + {
63953 + long __i = i;
63954 +- asm volatile(LOCK_PREFIX "xaddq %0, %1;"
63955 ++ asm volatile(LOCK_PREFIX "xaddq %0, %1\n"
63956 ++
63957 ++#ifdef CONFIG_PAX_REFCOUNT
63958 ++ "jno 0f\n"
63959 ++ "movq %0, %1\n"
63960 ++ "int $4\n0:\n"
63961 ++ _ASM_EXTABLE(0b, 0b)
63962 ++#endif
63963 ++
63964 + : "+r" (i), "+m" (v->counter)
63965 + : : "memory");
63966 + return i + __i;
63967 +diff -urNp linux-2.6.27.7/include/asm-x86/boot.h linux-2.6.27.7/include/asm-x86/boot.h
63968 +--- linux-2.6.27.7/include/asm-x86/boot.h 2008-11-07 12:55:34.000000000 -0500
63969 ++++ linux-2.6.27.7/include/asm-x86/boot.h 2008-11-18 03:38:45.000000000 -0500
63970 +@@ -13,10 +13,15 @@
63971 + #define ASK_VGA 0xfffd /* ask for it at bootup */
63972 +
63973 + /* Physical address where kernel should be loaded. */
63974 +-#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
63975 ++#define ____LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
63976 + + (CONFIG_PHYSICAL_ALIGN - 1)) \
63977 + & ~(CONFIG_PHYSICAL_ALIGN - 1))
63978 +
63979 ++#ifndef __ASSEMBLY__
63980 ++extern unsigned char __LOAD_PHYSICAL_ADDR[];
63981 ++#define LOAD_PHYSICAL_ADDR ((unsigned long)__LOAD_PHYSICAL_ADDR)
63982 ++#endif
63983 ++
63984 + #ifdef CONFIG_X86_64
63985 + #define BOOT_HEAP_SIZE 0x7000
63986 + #define BOOT_STACK_SIZE 0x4000
63987 +diff -urNp linux-2.6.27.7/include/asm-x86/cache.h linux-2.6.27.7/include/asm-x86/cache.h
63988 +--- linux-2.6.27.7/include/asm-x86/cache.h 2008-11-07 12:55:34.000000000 -0500
63989 ++++ linux-2.6.27.7/include/asm-x86/cache.h 2008-11-18 03:38:45.000000000 -0500
63990 +@@ -6,6 +6,7 @@
63991 + #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
63992 +
63993 + #define __read_mostly __attribute__((__section__(".data.read_mostly")))
63994 ++#define __read_only __attribute__((__section__(".data.read_only")))
63995 +
63996 + #ifdef CONFIG_X86_VSMP
63997 + /* vSMP Internode cacheline shift */
63998 +diff -urNp linux-2.6.27.7/include/asm-x86/checksum_32.h linux-2.6.27.7/include/asm-x86/checksum_32.h
63999 +--- linux-2.6.27.7/include/asm-x86/checksum_32.h 2008-11-07 12:55:34.000000000 -0500
64000 ++++ linux-2.6.27.7/include/asm-x86/checksum_32.h 2008-11-18 03:38:45.000000000 -0500
64001 +@@ -31,6 +31,14 @@ asmlinkage __wsum csum_partial_copy_gene
64002 + int len, __wsum sum,
64003 + int *src_err_ptr, int *dst_err_ptr);
64004 +
64005 ++asmlinkage __wsum csum_partial_copy_generic_to_user(const void *src, void *dst,
64006 ++ int len, __wsum sum,
64007 ++ int *src_err_ptr, int *dst_err_ptr);
64008 ++
64009 ++asmlinkage __wsum csum_partial_copy_generic_from_user(const void *src, void *dst,
64010 ++ int len, __wsum sum,
64011 ++ int *src_err_ptr, int *dst_err_ptr);
64012 ++
64013 + /*
64014 + * Note: when you get a NULL pointer exception here this means someone
64015 + * passed in an incorrect kernel address to one of these functions.
64016 +@@ -50,7 +58,7 @@ static inline __wsum csum_partial_copy_f
64017 + int *err_ptr)
64018 + {
64019 + might_sleep();
64020 +- return csum_partial_copy_generic((__force void *)src, dst,
64021 ++ return csum_partial_copy_generic_from_user((__force void *)src, dst,
64022 + len, sum, err_ptr, NULL);
64023 + }
64024 +
64025 +@@ -177,7 +185,7 @@ static inline __wsum csum_and_copy_to_us
64026 + {
64027 + might_sleep();
64028 + if (access_ok(VERIFY_WRITE, dst, len))
64029 +- return csum_partial_copy_generic(src, (__force void *)dst,
64030 ++ return csum_partial_copy_generic_to_user(src, (__force void *)dst,
64031 + len, sum, NULL, err_ptr);
64032 +
64033 + if (len)
64034 +diff -urNp linux-2.6.27.7/include/asm-x86/desc.h linux-2.6.27.7/include/asm-x86/desc.h
64035 +--- linux-2.6.27.7/include/asm-x86/desc.h 2008-11-07 12:55:34.000000000 -0500
64036 ++++ linux-2.6.27.7/include/asm-x86/desc.h 2008-11-18 03:38:45.000000000 -0500
64037 +@@ -16,6 +16,7 @@ static inline void fill_ldt(struct desc_
64038 + desc->base1 = (info->base_addr & 0x00ff0000) >> 16;
64039 + desc->type = (info->read_exec_only ^ 1) << 1;
64040 + desc->type |= info->contents << 2;
64041 ++ desc->type |= info->seg_not_present ^ 1;
64042 + desc->s = 1;
64043 + desc->dpl = 0x3;
64044 + desc->p = info->seg_not_present ^ 1;
64045 +@@ -27,16 +28,12 @@ static inline void fill_ldt(struct desc_
64046 + }
64047 +
64048 + extern struct desc_ptr idt_descr;
64049 +-extern gate_desc idt_table[];
64050 +-
64051 +-struct gdt_page {
64052 +- struct desc_struct gdt[GDT_ENTRIES];
64053 +-} __attribute__((aligned(PAGE_SIZE)));
64054 +-DECLARE_PER_CPU(struct gdt_page, gdt_page);
64055 ++extern gate_desc idt_table[256];
64056 +
64057 ++extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
64058 + static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
64059 + {
64060 +- return per_cpu(gdt_page, cpu).gdt;
64061 ++ return cpu_gdt_table[cpu];
64062 + }
64063 +
64064 + #ifdef CONFIG_X86_64
64065 +@@ -65,7 +62,6 @@ static inline void pack_gate(gate_desc *
64066 + gate->b = (base & 0xffff0000) |
64067 + (((0x80 | type | (dpl << 5)) & 0xff) << 8);
64068 + }
64069 +-
64070 + #endif
64071 +
64072 + static inline int desc_empty(const void *ptr)
64073 +@@ -102,19 +98,48 @@ static inline int desc_empty(const void
64074 + static inline void native_write_idt_entry(gate_desc *idt, int entry,
64075 + const gate_desc *gate)
64076 + {
64077 ++
64078 ++#ifdef CONFIG_PAX_KERNEXEC
64079 ++ unsigned long cr0;
64080 ++
64081 ++ pax_open_kernel(cr0);
64082 ++#endif
64083 ++
64084 + memcpy(&idt[entry], gate, sizeof(*gate));
64085 ++
64086 ++#ifdef CONFIG_PAX_KERNEXEC
64087 ++ pax_close_kernel(cr0);
64088 ++#endif
64089 ++
64090 + }
64091 +
64092 + static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry,
64093 + const void *desc)
64094 + {
64095 ++
64096 ++#ifdef CONFIG_PAX_KERNEXEC
64097 ++ unsigned long cr0;
64098 ++
64099 ++ pax_open_kernel(cr0);
64100 ++#endif
64101 ++
64102 + memcpy(&ldt[entry], desc, 8);
64103 ++
64104 ++#ifdef CONFIG_PAX_KERNEXEC
64105 ++ pax_close_kernel(cr0);
64106 ++#endif
64107 ++
64108 + }
64109 +
64110 + static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry,
64111 + const void *desc, int type)
64112 + {
64113 + unsigned int size;
64114 ++
64115 ++#ifdef CONFIG_PAX_KERNEXEC
64116 ++ unsigned long cr0;
64117 ++#endif
64118 ++
64119 + switch (type) {
64120 + case DESC_TSS:
64121 + size = sizeof(tss_desc);
64122 +@@ -126,7 +151,17 @@ static inline void native_write_gdt_entr
64123 + size = sizeof(struct desc_struct);
64124 + break;
64125 + }
64126 ++
64127 ++#ifdef CONFIG_PAX_KERNEXEC
64128 ++ pax_open_kernel(cr0);
64129 ++#endif
64130 ++
64131 + memcpy(&gdt[entry], desc, size);
64132 ++
64133 ++#ifdef CONFIG_PAX_KERNEXEC
64134 ++ pax_close_kernel(cr0);
64135 ++#endif
64136 ++
64137 + }
64138 +
64139 + static inline void pack_descriptor(struct desc_struct *desc, unsigned long base,
64140 +@@ -198,7 +233,19 @@ static inline void native_set_ldt(const
64141 +
64142 + static inline void native_load_tr_desc(void)
64143 + {
64144 ++
64145 ++#ifdef CONFIG_PAX_KERNEXEC
64146 ++ unsigned long cr0;
64147 ++
64148 ++ pax_open_kernel(cr0);
64149 ++#endif
64150 ++
64151 + asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
64152 ++
64153 ++#ifdef CONFIG_PAX_KERNEXEC
64154 ++ pax_close_kernel(cr0);
64155 ++#endif
64156 ++
64157 + }
64158 +
64159 + static inline void native_load_gdt(const struct desc_ptr *dtr)
64160 +@@ -233,8 +280,19 @@ static inline void native_load_tls(struc
64161 + unsigned int i;
64162 + struct desc_struct *gdt = get_cpu_gdt_table(cpu);
64163 +
64164 ++#ifdef CONFIG_PAX_KERNEXEC
64165 ++ unsigned long cr0;
64166 ++
64167 ++ pax_open_kernel(cr0);
64168 ++#endif
64169 ++
64170 + for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
64171 + gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
64172 ++
64173 ++#ifdef CONFIG_PAX_KERNEXEC
64174 ++ pax_close_kernel(cr0);
64175 ++#endif
64176 ++
64177 + }
64178 +
64179 + #define _LDT_empty(info) \
64180 +@@ -372,6 +430,18 @@ static inline void set_system_gate_ist(i
64181 + _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS);
64182 + }
64183 +
64184 ++#ifdef CONFIG_X86_32
64185 ++static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
64186 ++{
64187 ++ struct desc_struct d;
64188 ++
64189 ++ if (likely(limit))
64190 ++ limit = (limit - 1UL) >> PAGE_SHIFT;
64191 ++ pack_descriptor(&d, base, limit, 0xFB, 0xC);
64192 ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, &d, DESCTYPE_S);
64193 ++}
64194 ++#endif
64195 ++
64196 + #else
64197 + /*
64198 + * GET_DESC_BASE reads the descriptor base of the specified segment.
64199 +diff -urNp linux-2.6.27.7/include/asm-x86/e820.h linux-2.6.27.7/include/asm-x86/e820.h
64200 +--- linux-2.6.27.7/include/asm-x86/e820.h 2008-11-07 12:55:34.000000000 -0500
64201 ++++ linux-2.6.27.7/include/asm-x86/e820.h 2008-11-18 03:38:45.000000000 -0500
64202 +@@ -131,7 +131,7 @@ extern char *memory_setup(void);
64203 + #define ISA_END_ADDRESS 0x100000
64204 + #define is_ISA_range(s, e) ((s) >= ISA_START_ADDRESS && (e) < ISA_END_ADDRESS)
64205 +
64206 +-#define BIOS_BEGIN 0x000a0000
64207 ++#define BIOS_BEGIN 0x000c0000
64208 + #define BIOS_END 0x00100000
64209 +
64210 + #ifdef __KERNEL__
64211 +diff -urNp linux-2.6.27.7/include/asm-x86/elf.h linux-2.6.27.7/include/asm-x86/elf.h
64212 +--- linux-2.6.27.7/include/asm-x86/elf.h 2008-11-07 12:55:34.000000000 -0500
64213 ++++ linux-2.6.27.7/include/asm-x86/elf.h 2008-11-18 03:38:45.000000000 -0500
64214 +@@ -251,7 +251,25 @@ extern int force_personality32;
64215 + the loader. We need to make sure that it is out of the way of the program
64216 + that it will "exec", and that there is sufficient room for the brk. */
64217 +
64218 ++#ifdef CONFIG_PAX_SEGMEXEC
64219 ++#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
64220 ++#else
64221 + #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
64222 ++#endif
64223 ++
64224 ++#ifdef CONFIG_PAX_ASLR
64225 ++#ifdef CONFIG_X86_32
64226 ++#define PAX_ELF_ET_DYN_BASE 0x10000000UL
64227 ++
64228 ++#define PAX_DELTA_MMAP_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
64229 ++#define PAX_DELTA_STACK_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
64230 ++#else
64231 ++#define PAX_ELF_ET_DYN_BASE 0x400000UL
64232 ++
64233 ++#define PAX_DELTA_MMAP_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
64234 ++#define PAX_DELTA_STACK_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
64235 ++#endif
64236 ++#endif
64237 +
64238 + /* This yields a mask that user programs can use to figure out what
64239 + instruction set this CPU supports. This could be done in user space,
64240 +@@ -303,8 +321,7 @@ do { \
64241 + #define ARCH_DLINFO \
64242 + do { \
64243 + if (vdso_enabled) \
64244 +- NEW_AUX_ENT(AT_SYSINFO_EHDR, \
64245 +- (unsigned long)current->mm->context.vdso); \
64246 ++ NEW_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso);\
64247 + } while (0)
64248 +
64249 + #define AT_SYSINFO 32
64250 +@@ -315,7 +332,7 @@ do { \
64251 +
64252 + #endif /* !CONFIG_X86_32 */
64253 +
64254 +-#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
64255 ++#define VDSO_CURRENT_BASE (current->mm->context.vdso)
64256 +
64257 + #define VDSO_ENTRY \
64258 + ((unsigned long)VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall))
64259 +@@ -329,7 +346,4 @@ extern int arch_setup_additional_pages(s
64260 + extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
64261 + #define compat_arch_setup_additional_pages syscall32_setup_pages
64262 +
64263 +-extern unsigned long arch_randomize_brk(struct mm_struct *mm);
64264 +-#define arch_randomize_brk arch_randomize_brk
64265 +-
64266 + #endif
64267 +diff -urNp linux-2.6.27.7/include/asm-x86/futex.h linux-2.6.27.7/include/asm-x86/futex.h
64268 +--- linux-2.6.27.7/include/asm-x86/futex.h 2008-11-07 12:55:34.000000000 -0500
64269 ++++ linux-2.6.27.7/include/asm-x86/futex.h 2008-11-18 03:38:45.000000000 -0500
64270 +@@ -11,6 +11,40 @@
64271 + #include <asm/processor.h>
64272 + #include <asm/system.h>
64273 +
64274 ++#ifdef CONFIG_X86_32
64275 ++#define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
64276 ++ asm volatile( \
64277 ++ "movw\t%w6, %%ds\n" \
64278 ++ "1:\t" insn "\n" \
64279 ++ "2:\tpushl\t%%ss\n" \
64280 ++ "\tpopl\t%%ds\n" \
64281 ++ "\t.section .fixup,\"ax\"\n" \
64282 ++ "3:\tmov\t%3, %1\n" \
64283 ++ "\tjmp\t2b\n" \
64284 ++ "\t.previous\n" \
64285 ++ _ASM_EXTABLE(1b, 3b) \
64286 ++ : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
64287 ++ : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS))
64288 ++
64289 ++#define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
64290 ++ asm volatile("movw\t%w7, %%es\n" \
64291 ++ "1:\tmovl\t%%es:%2, %0\n" \
64292 ++ "\tmovl\t%0, %3\n" \
64293 ++ "\t" insn "\n" \
64294 ++ "2:\tlock; cmpxchgl %3, %%es:%2\n" \
64295 ++ "\tjnz\t1b\n" \
64296 ++ "3:\tpushl\t%%ss\n" \
64297 ++ "\tpopl\t%%es\n" \
64298 ++ "\t.section .fixup,\"ax\"\n" \
64299 ++ "4:\tmov\t%5, %1\n" \
64300 ++ "\tjmp\t3b\n" \
64301 ++ "\t.previous\n" \
64302 ++ _ASM_EXTABLE(1b, 4b) \
64303 ++ _ASM_EXTABLE(2b, 4b) \
64304 ++ : "=&a" (oldval), "=&r" (ret), \
64305 ++ "+m" (*uaddr), "=&r" (tem) \
64306 ++ : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS))
64307 ++#else
64308 + #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
64309 + asm volatile("1:\t" insn "\n" \
64310 + "2:\t.section .fixup,\"ax\"\n" \
64311 +@@ -36,8 +70,9 @@
64312 + : "=&a" (oldval), "=&r" (ret), \
64313 + "+m" (*uaddr), "=&r" (tem) \
64314 + : "r" (oparg), "i" (-EFAULT), "1" (0))
64315 ++#endif
64316 +
64317 +-static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
64318 ++static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
64319 + {
64320 + int op = (encoded_op >> 28) & 7;
64321 + int cmp = (encoded_op >> 24) & 15;
64322 +@@ -61,11 +96,20 @@ static inline int futex_atomic_op_inuser
64323 +
64324 + switch (op) {
64325 + case FUTEX_OP_SET:
64326 ++#ifdef CONFIG_X86_32
64327 ++ __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg);
64328 ++#else
64329 + __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
64330 ++#endif
64331 + break;
64332 + case FUTEX_OP_ADD:
64333 ++#ifdef CONFIG_X86_32
64334 ++ __futex_atomic_op1("lock ; xaddl %0, %%ds:%2", ret, oldval,
64335 ++ uaddr, oparg);
64336 ++#else
64337 + __futex_atomic_op1("lock; xaddl %0, %2", ret, oldval,
64338 + uaddr, oparg);
64339 ++#endif
64340 + break;
64341 + case FUTEX_OP_OR:
64342 + __futex_atomic_op2("orl %4, %3", ret, oldval, uaddr, oparg);
64343 +@@ -109,7 +153,7 @@ static inline int futex_atomic_op_inuser
64344 + return ret;
64345 + }
64346 +
64347 +-static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval,
64348 ++static inline int futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval,
64349 + int newval)
64350 + {
64351 +
64352 +@@ -122,14 +166,27 @@ static inline int futex_atomic_cmpxchg_i
64353 + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
64354 + return -EFAULT;
64355 +
64356 +- asm volatile("1:\tlock; cmpxchgl %3, %1\n"
64357 ++ asm volatile(
64358 ++#ifdef CONFIG_X86_32
64359 ++ "\tmovw %w5, %%ds\n"
64360 ++ "1:\tlock; cmpxchgl %3, %1\n"
64361 ++ "2:\tpushl %%ss\n"
64362 ++ "\tpopl %%ds\n"
64363 ++ "\t.section .fixup, \"ax\"\n"
64364 ++#else
64365 ++ "1:\tlock; cmpxchgl %3, %1\n"
64366 + "2:\t.section .fixup, \"ax\"\n"
64367 ++#endif
64368 + "3:\tmov %2, %0\n"
64369 + "\tjmp 2b\n"
64370 + "\t.previous\n"
64371 + _ASM_EXTABLE(1b, 3b)
64372 + : "=a" (oldval), "+m" (*uaddr)
64373 ++#ifdef CONFIG_X86_32
64374 ++ : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS)
64375 ++#else
64376 + : "i" (-EFAULT), "r" (newval), "0" (oldval)
64377 ++#endif
64378 + : "memory"
64379 + );
64380 +
64381 +diff -urNp linux-2.6.27.7/include/asm-x86/i387.h linux-2.6.27.7/include/asm-x86/i387.h
64382 +--- linux-2.6.27.7/include/asm-x86/i387.h 2008-11-07 12:55:34.000000000 -0500
64383 ++++ linux-2.6.27.7/include/asm-x86/i387.h 2008-11-18 03:38:45.000000000 -0500
64384 +@@ -159,13 +159,8 @@ static inline void restore_fpu(struct ta
64385 + }
64386 +
64387 + /* We need a safe address that is cheap to find and that is already
64388 +- in L1 during context switch. The best choices are unfortunately
64389 +- different for UP and SMP */
64390 +-#ifdef CONFIG_SMP
64391 +-#define safe_address (__per_cpu_offset[0])
64392 +-#else
64393 +-#define safe_address (kstat_cpu(0).cpustat.user)
64394 +-#endif
64395 ++ in L1 during context switch. */
64396 ++#define safe_address (init_tss[smp_processor_id()].x86_tss.sp0)
64397 +
64398 + /*
64399 + * These must be called with preempt disabled
64400 +diff -urNp linux-2.6.27.7/include/asm-x86/io_64.h linux-2.6.27.7/include/asm-x86/io_64.h
64401 +--- linux-2.6.27.7/include/asm-x86/io_64.h 2008-11-07 12:55:34.000000000 -0500
64402 ++++ linux-2.6.27.7/include/asm-x86/io_64.h 2008-11-18 03:38:45.000000000 -0500
64403 +@@ -158,6 +158,17 @@ static inline void *phys_to_virt(unsigne
64404 + }
64405 + #endif
64406 +
64407 ++#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
64408 ++static inline int valid_phys_addr_range (unsigned long addr, size_t count)
64409 ++{
64410 ++ return ((addr + count + PAGE_SIZE - 1) >> PAGE_SHIFT) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
64411 ++}
64412 ++
64413 ++static inline int valid_mmap_phys_addr_range (unsigned long pfn, size_t count)
64414 ++{
64415 ++ return (pfn + (count >> PAGE_SHIFT)) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
64416 ++}
64417 ++
64418 + /*
64419 + * Change "struct page" to physical address.
64420 + */
64421 +diff -urNp linux-2.6.27.7/include/asm-x86/irqflags.h linux-2.6.27.7/include/asm-x86/irqflags.h
64422 +--- linux-2.6.27.7/include/asm-x86/irqflags.h 2008-11-07 12:55:34.000000000 -0500
64423 ++++ linux-2.6.27.7/include/asm-x86/irqflags.h 2008-11-18 03:38:45.000000000 -0500
64424 +@@ -141,6 +141,8 @@ static inline unsigned long __raw_local_
64425 + #define INTERRUPT_RETURN iret
64426 + #define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit
64427 + #define GET_CR0_INTO_EAX movl %cr0, %eax
64428 ++#define GET_CR0_INTO_EDX movl %cr0, %edx
64429 ++#define SET_CR0_FROM_EDX movl %edx, %cr0
64430 + #endif
64431 +
64432 +
64433 +diff -urNp linux-2.6.27.7/include/asm-x86/kmap_types.h linux-2.6.27.7/include/asm-x86/kmap_types.h
64434 +--- linux-2.6.27.7/include/asm-x86/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
64435 ++++ linux-2.6.27.7/include/asm-x86/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
64436 +@@ -21,7 +21,8 @@ D(9) KM_IRQ0,
64437 + D(10) KM_IRQ1,
64438 + D(11) KM_SOFTIRQ0,
64439 + D(12) KM_SOFTIRQ1,
64440 +-D(13) KM_TYPE_NR
64441 ++D(13) KM_CLEARPAGE,
64442 ++D(14) KM_TYPE_NR
64443 + };
64444 +
64445 + #undef D
64446 +diff -urNp linux-2.6.27.7/include/asm-x86/linkage.h linux-2.6.27.7/include/asm-x86/linkage.h
64447 +--- linux-2.6.27.7/include/asm-x86/linkage.h 2008-11-07 12:55:34.000000000 -0500
64448 ++++ linux-2.6.27.7/include/asm-x86/linkage.h 2008-11-18 03:38:45.000000000 -0500
64449 +@@ -7,6 +7,11 @@
64450 + #ifdef CONFIG_X86_64
64451 + #define __ALIGN .p2align 4,,15
64452 + #define __ALIGN_STR ".p2align 4,,15"
64453 ++#else
64454 ++#ifdef CONFIG_X86_ALIGNMENT_16
64455 ++#define __ALIGN .align 16,0x90
64456 ++#define __ALIGN_STR ".align 16,0x90"
64457 ++#endif
64458 + #endif
64459 +
64460 + #ifdef CONFIG_X86_32
64461 +@@ -52,10 +57,5 @@
64462 +
64463 + #endif
64464 +
64465 +-#ifdef CONFIG_X86_ALIGNMENT_16
64466 +-#define __ALIGN .align 16,0x90
64467 +-#define __ALIGN_STR ".align 16,0x90"
64468 +-#endif
64469 +-
64470 + #endif
64471 +
64472 +diff -urNp linux-2.6.27.7/include/asm-x86/local.h linux-2.6.27.7/include/asm-x86/local.h
64473 +--- linux-2.6.27.7/include/asm-x86/local.h 2008-11-07 12:55:34.000000000 -0500
64474 ++++ linux-2.6.27.7/include/asm-x86/local.h 2008-11-18 03:38:45.000000000 -0500
64475 +@@ -18,26 +18,90 @@ typedef struct {
64476 +
64477 + static inline void local_inc(local_t *l)
64478 + {
64479 +- asm volatile(_ASM_INC "%0"
64480 ++ asm volatile(_ASM_INC "%0\n"
64481 ++
64482 ++#ifdef CONFIG_PAX_REFCOUNT
64483 ++#ifdef CONFIG_X86_32
64484 ++ "into\n0:\n"
64485 ++#else
64486 ++ "jno 0f\n"
64487 ++ "int $4\n0:\n"
64488 ++#endif
64489 ++ ".pushsection .fixup,\"ax\"\n"
64490 ++ "1:\n"
64491 ++ _ASM_DEC "%0\n"
64492 ++ "jmp 0b\n"
64493 ++ ".popsection\n"
64494 ++ _ASM_EXTABLE(0b, 1b)
64495 ++#endif
64496 ++
64497 + : "+m" (l->a.counter));
64498 + }
64499 +
64500 + static inline void local_dec(local_t *l)
64501 + {
64502 +- asm volatile(_ASM_DEC "%0"
64503 ++ asm volatile(_ASM_DEC "%0\n"
64504 ++
64505 ++#ifdef CONFIG_PAX_REFCOUNT
64506 ++#ifdef CONFIG_X86_32
64507 ++ "into\n0:\n"
64508 ++#else
64509 ++ "jno 0f\n"
64510 ++ "int $4\n0:\n"
64511 ++#endif
64512 ++ ".pushsection .fixup,\"ax\"\n"
64513 ++ "1:\n"
64514 ++ _ASM_INC "%0\n"
64515 ++ "jmp 0b\n"
64516 ++ ".popsection\n"
64517 ++ _ASM_EXTABLE(0b, 1b)
64518 ++#endif
64519 ++
64520 + : "+m" (l->a.counter));
64521 + }
64522 +
64523 + static inline void local_add(long i, local_t *l)
64524 + {
64525 +- asm volatile(_ASM_ADD "%1,%0"
64526 ++ asm volatile(_ASM_ADD "%1,%0\n"
64527 ++
64528 ++#ifdef CONFIG_PAX_REFCOUNT
64529 ++#ifdef CONFIG_X86_32
64530 ++ "into\n0:\n"
64531 ++#else
64532 ++ "jno 0f\n"
64533 ++ "int $4\n0:\n"
64534 ++#endif
64535 ++ ".pushsection .fixup,\"ax\"\n"
64536 ++ "1:\n"
64537 ++ _ASM_SUB "%1,%0\n"
64538 ++ "jmp 0b\n"
64539 ++ ".popsection\n"
64540 ++ _ASM_EXTABLE(0b, 1b)
64541 ++#endif
64542 ++
64543 + : "+m" (l->a.counter)
64544 + : "ir" (i));
64545 + }
64546 +
64547 + static inline void local_sub(long i, local_t *l)
64548 + {
64549 +- asm volatile(_ASM_SUB "%1,%0"
64550 ++ asm volatile(_ASM_SUB "%1,%0\n"
64551 ++
64552 ++#ifdef CONFIG_PAX_REFCOUNT
64553 ++#ifdef CONFIG_X86_32
64554 ++ "into\n0:\n"
64555 ++#else
64556 ++ "jno 0f\n"
64557 ++ "int $4\n0:\n"
64558 ++#endif
64559 ++ ".pushsection .fixup,\"ax\"\n"
64560 ++ "1:\n"
64561 ++ _ASM_ADD "%1,%0\n"
64562 ++ "jmp 0b\n"
64563 ++ ".popsection\n"
64564 ++ _ASM_EXTABLE(0b, 1b)
64565 ++#endif
64566 ++
64567 + : "+m" (l->a.counter)
64568 + : "ir" (i));
64569 + }
64570 +@@ -55,7 +119,24 @@ static inline int local_sub_and_test(lon
64571 + {
64572 + unsigned char c;
64573 +
64574 +- asm volatile(_ASM_SUB "%2,%0; sete %1"
64575 ++ asm volatile(_ASM_SUB "%2,%0\n"
64576 ++
64577 ++#ifdef CONFIG_PAX_REFCOUNT
64578 ++#ifdef CONFIG_X86_32
64579 ++ "into\n0:\n"
64580 ++#else
64581 ++ "jno 0f\n"
64582 ++ "int $4\n0:\n"
64583 ++#endif
64584 ++ ".pushsection .fixup,\"ax\"\n"
64585 ++ "1:\n"
64586 ++ _ASM_ADD "%2,%0\n"
64587 ++ "jmp 0b\n"
64588 ++ ".popsection\n"
64589 ++ _ASM_EXTABLE(0b, 1b)
64590 ++#endif
64591 ++
64592 ++ "sete %1\n"
64593 + : "+m" (l->a.counter), "=qm" (c)
64594 + : "ir" (i) : "memory");
64595 + return c;
64596 +@@ -73,7 +154,24 @@ static inline int local_dec_and_test(loc
64597 + {
64598 + unsigned char c;
64599 +
64600 +- asm volatile(_ASM_DEC "%0; sete %1"
64601 ++ asm volatile(_ASM_DEC "%0\n"
64602 ++
64603 ++#ifdef CONFIG_PAX_REFCOUNT
64604 ++#ifdef CONFIG_X86_32
64605 ++ "into\n0:\n"
64606 ++#else
64607 ++ "jno 0f\n"
64608 ++ "int $4\n0:\n"
64609 ++#endif
64610 ++ ".pushsection .fixup,\"ax\"\n"
64611 ++ "1:\n"
64612 ++ _ASM_INC "%0\n"
64613 ++ "jmp 0b\n"
64614 ++ ".popsection\n"
64615 ++ _ASM_EXTABLE(0b, 1b)
64616 ++#endif
64617 ++
64618 ++ "sete %1\n"
64619 + : "+m" (l->a.counter), "=qm" (c)
64620 + : : "memory");
64621 + return c != 0;
64622 +@@ -91,7 +189,24 @@ static inline int local_inc_and_test(loc
64623 + {
64624 + unsigned char c;
64625 +
64626 +- asm volatile(_ASM_INC "%0; sete %1"
64627 ++ asm volatile(_ASM_INC "%0\n"
64628 ++
64629 ++#ifdef CONFIG_PAX_REFCOUNT
64630 ++#ifdef CONFIG_X86_32
64631 ++ "into\n0:\n"
64632 ++#else
64633 ++ "jno 0f\n"
64634 ++ "int $4\n0:\n"
64635 ++#endif
64636 ++ ".pushsection .fixup,\"ax\"\n"
64637 ++ "1:\n"
64638 ++ _ASM_DEC "%0\n"
64639 ++ "jmp 0b\n"
64640 ++ ".popsection\n"
64641 ++ _ASM_EXTABLE(0b, 1b)
64642 ++#endif
64643 ++
64644 ++ "sete %1\n"
64645 + : "+m" (l->a.counter), "=qm" (c)
64646 + : : "memory");
64647 + return c != 0;
64648 +@@ -110,7 +225,24 @@ static inline int local_add_negative(lon
64649 + {
64650 + unsigned char c;
64651 +
64652 +- asm volatile(_ASM_ADD "%2,%0; sets %1"
64653 ++ asm volatile(_ASM_ADD "%2,%0\n"
64654 ++
64655 ++#ifdef CONFIG_PAX_REFCOUNT
64656 ++#ifdef CONFIG_X86_32
64657 ++ "into\n0:\n"
64658 ++#else
64659 ++ "jno 0f\n"
64660 ++ "int $4\n0:\n"
64661 ++#endif
64662 ++ ".pushsection .fixup,\"ax\"\n"
64663 ++ "1:\n"
64664 ++ _ASM_SUB "%2,%0\n"
64665 ++ "jmp 0b\n"
64666 ++ ".popsection\n"
64667 ++ _ASM_EXTABLE(0b, 1b)
64668 ++#endif
64669 ++
64670 ++ "sets %1\n"
64671 + : "+m" (l->a.counter), "=qm" (c)
64672 + : "ir" (i) : "memory");
64673 + return c;
64674 +@@ -133,7 +265,23 @@ static inline long local_add_return(long
64675 + #endif
64676 + /* Modern 486+ processor */
64677 + __i = i;
64678 +- asm volatile(_ASM_XADD "%0, %1;"
64679 ++ asm volatile(_ASM_XADD "%0, %1\n"
64680 ++
64681 ++#ifdef CONFIG_PAX_REFCOUNT
64682 ++#ifdef CONFIG_X86_32
64683 ++ "into\n0:\n"
64684 ++#else
64685 ++ "jno 0f\n"
64686 ++ "int $4\n0:\n"
64687 ++#endif
64688 ++ ".pushsection .fixup,\"ax\"\n"
64689 ++ "1:\n"
64690 ++ _ASM_MOV_UL "%0,%1\n"
64691 ++ "jmp 0b\n"
64692 ++ ".popsection\n"
64693 ++ _ASM_EXTABLE(0b, 1b)
64694 ++#endif
64695 ++
64696 + : "+r" (i), "+m" (l->a.counter)
64697 + : : "memory");
64698 + return i + __i;
64699 +diff -urNp linux-2.6.27.7/include/asm-x86/mach-default/apm.h linux-2.6.27.7/include/asm-x86/mach-default/apm.h
64700 +--- linux-2.6.27.7/include/asm-x86/mach-default/apm.h 2008-11-07 12:55:34.000000000 -0500
64701 ++++ linux-2.6.27.7/include/asm-x86/mach-default/apm.h 2008-11-18 03:38:45.000000000 -0500
64702 +@@ -34,7 +34,7 @@ static inline void apm_bios_call_asm(u32
64703 + __asm__ __volatile__(APM_DO_ZERO_SEGS
64704 + "pushl %%edi\n\t"
64705 + "pushl %%ebp\n\t"
64706 +- "lcall *%%cs:apm_bios_entry\n\t"
64707 ++ "lcall *%%ss:apm_bios_entry\n\t"
64708 + "setc %%al\n\t"
64709 + "popl %%ebp\n\t"
64710 + "popl %%edi\n\t"
64711 +@@ -58,7 +58,7 @@ static inline u8 apm_bios_call_simple_as
64712 + __asm__ __volatile__(APM_DO_ZERO_SEGS
64713 + "pushl %%edi\n\t"
64714 + "pushl %%ebp\n\t"
64715 +- "lcall *%%cs:apm_bios_entry\n\t"
64716 ++ "lcall *%%ss:apm_bios_entry\n\t"
64717 + "setc %%bl\n\t"
64718 + "popl %%ebp\n\t"
64719 + "popl %%edi\n\t"
64720 +diff -urNp linux-2.6.27.7/include/asm-x86/mman.h linux-2.6.27.7/include/asm-x86/mman.h
64721 +--- linux-2.6.27.7/include/asm-x86/mman.h 2008-11-07 12:55:34.000000000 -0500
64722 ++++ linux-2.6.27.7/include/asm-x86/mman.h 2008-11-18 03:38:45.000000000 -0500
64723 +@@ -17,4 +17,14 @@
64724 + #define MCL_CURRENT 1 /* lock all current mappings */
64725 + #define MCL_FUTURE 2 /* lock all future mappings */
64726 +
64727 ++#ifdef __KERNEL__
64728 ++#ifndef __ASSEMBLY__
64729 ++#ifdef CONFIG_X86_32
64730 ++#define arch_mmap_check i386_mmap_check
64731 ++int i386_mmap_check(unsigned long addr, unsigned long len,
64732 ++ unsigned long flags);
64733 ++#endif
64734 ++#endif
64735 ++#endif
64736 ++
64737 + #endif /* _ASM_X86_MMAN_H */
64738 +diff -urNp linux-2.6.27.7/include/asm-x86/mmu_context_32.h linux-2.6.27.7/include/asm-x86/mmu_context_32.h
64739 +--- linux-2.6.27.7/include/asm-x86/mmu_context_32.h 2008-11-07 12:55:34.000000000 -0500
64740 ++++ linux-2.6.27.7/include/asm-x86/mmu_context_32.h 2008-11-18 03:38:45.000000000 -0500
64741 +@@ -33,6 +33,22 @@ static inline void switch_mm(struct mm_s
64742 + */
64743 + if (unlikely(prev->context.ldt != next->context.ldt))
64744 + load_LDT_nolock(&next->context);
64745 ++
64746 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
64747 ++ if (!nx_enabled) {
64748 ++ smp_mb__before_clear_bit();
64749 ++ cpu_clear(cpu, prev->context.cpu_user_cs_mask);
64750 ++ smp_mb__after_clear_bit();
64751 ++ cpu_set(cpu, next->context.cpu_user_cs_mask);
64752 ++ }
64753 ++#endif
64754 ++
64755 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
64756 ++ if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
64757 ++ prev->context.user_cs_limit != next->context.user_cs_limit))
64758 ++ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
64759 ++#endif
64760 ++
64761 + }
64762 + #ifdef CONFIG_SMP
64763 + else {
64764 +@@ -45,6 +61,19 @@ static inline void switch_mm(struct mm_s
64765 + */
64766 + load_cr3(next->pgd);
64767 + load_LDT_nolock(&next->context);
64768 ++
64769 ++#ifdef CONFIG_PAX_PAGEEXEC
64770 ++ if (!nx_enabled)
64771 ++ cpu_set(cpu, next->context.cpu_user_cs_mask);
64772 ++#endif
64773 ++
64774 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
64775 ++#ifdef CONFIG_PAX_PAGEEXEC
64776 ++ if (!((next->pax_flags & MF_PAX_PAGEEXEC) && nx_enabled))
64777 ++#endif
64778 ++ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
64779 ++#endif
64780 ++
64781 + }
64782 + }
64783 + #endif
64784 +diff -urNp linux-2.6.27.7/include/asm-x86/mmu.h linux-2.6.27.7/include/asm-x86/mmu.h
64785 +--- linux-2.6.27.7/include/asm-x86/mmu.h 2008-11-07 12:55:34.000000000 -0500
64786 ++++ linux-2.6.27.7/include/asm-x86/mmu.h 2008-11-18 03:38:45.000000000 -0500
64787 +@@ -11,13 +11,26 @@
64788 + * cpu_vm_mask is used to optimize ldt flushing.
64789 + */
64790 + typedef struct {
64791 +- void *ldt;
64792 ++ struct desc_struct *ldt;
64793 + #ifdef CONFIG_X86_64
64794 + rwlock_t ldtlock;
64795 + #endif
64796 + int size;
64797 + struct mutex lock;
64798 +- void *vdso;
64799 ++ unsigned long vdso;
64800 ++
64801 ++#ifdef CONFIG_X86_32
64802 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
64803 ++ unsigned long user_cs_base;
64804 ++ unsigned long user_cs_limit;
64805 ++
64806 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
64807 ++ cpumask_t cpu_user_cs_mask;
64808 ++#endif
64809 ++
64810 ++#endif
64811 ++#endif
64812 ++
64813 + } mm_context_t;
64814 +
64815 + #ifdef CONFIG_SMP
64816 +diff -urNp linux-2.6.27.7/include/asm-x86/module.h linux-2.6.27.7/include/asm-x86/module.h
64817 +--- linux-2.6.27.7/include/asm-x86/module.h 2008-11-07 12:55:34.000000000 -0500
64818 ++++ linux-2.6.27.7/include/asm-x86/module.h 2008-11-18 03:38:45.000000000 -0500
64819 +@@ -76,7 +76,12 @@ struct mod_arch_specific {};
64820 + # else
64821 + # define MODULE_STACKSIZE ""
64822 + # endif
64823 +-# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
64824 ++# ifdef CONFIG_GRKERNSEC
64825 ++# define MODULE_GRSEC "GRSECURITY "
64826 ++# else
64827 ++# define MODULE_GRSEC ""
64828 ++# endif
64829 ++# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE MODULE_GRSEC
64830 + #endif
64831 +
64832 + #endif /* _ASM_MODULE_H */
64833 +diff -urNp linux-2.6.27.7/include/asm-x86/page_32.h linux-2.6.27.7/include/asm-x86/page_32.h
64834 +--- linux-2.6.27.7/include/asm-x86/page_32.h 2008-11-07 12:55:34.000000000 -0500
64835 ++++ linux-2.6.27.7/include/asm-x86/page_32.h 2008-11-18 03:38:45.000000000 -0500
64836 +@@ -13,6 +13,23 @@
64837 + */
64838 + #define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL)
64839 +
64840 ++#ifdef CONFIG_PAX_KERNEXEC
64841 ++#ifndef __ASSEMBLY__
64842 ++extern unsigned char MODULES_VADDR[];
64843 ++extern unsigned char MODULES_END[];
64844 ++extern unsigned char KERNEL_TEXT_OFFSET[];
64845 ++#define ktla_ktva(addr) (addr + (unsigned long)KERNEL_TEXT_OFFSET)
64846 ++#define ktva_ktla(addr) (addr - (unsigned long)KERNEL_TEXT_OFFSET)
64847 ++#endif
64848 ++#else
64849 ++#define ktla_ktva(addr) (addr)
64850 ++#define ktva_ktla(addr) (addr)
64851 ++#endif
64852 ++
64853 ++#ifdef CONFIG_PAX_PAGEEXEC
64854 ++#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
64855 ++#endif
64856 ++
64857 + #ifdef CONFIG_4KSTACKS
64858 + #define THREAD_ORDER 0
64859 + #else
64860 +diff -urNp linux-2.6.27.7/include/asm-x86/page_64.h linux-2.6.27.7/include/asm-x86/page_64.h
64861 +--- linux-2.6.27.7/include/asm-x86/page_64.h 2008-11-07 12:55:34.000000000 -0500
64862 ++++ linux-2.6.27.7/include/asm-x86/page_64.h 2008-11-18 03:38:45.000000000 -0500
64863 +@@ -49,6 +49,9 @@
64864 + #define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START)
64865 + #define __START_KERNEL_map _AC(0xffffffff80000000, UL)
64866 +
64867 ++#define ktla_ktva(addr) (addr)
64868 ++#define ktva_ktla(addr) (addr)
64869 ++
64870 + /* See Documentation/x86_64/mm.txt for a description of the memory map. */
64871 + #define __PHYSICAL_MASK_SHIFT 46
64872 + #define __VIRTUAL_MASK_SHIFT 48
64873 +@@ -101,5 +104,6 @@ extern void init_extra_mapping_wb(unsign
64874 + #define pfn_valid(pfn) ((pfn) < max_pfn)
64875 + #endif
64876 +
64877 ++#define nx_enabled (1)
64878 +
64879 + #endif /* _X86_64_PAGE_H */
64880 +diff -urNp linux-2.6.27.7/include/asm-x86/paravirt.h linux-2.6.27.7/include/asm-x86/paravirt.h
64881 +--- linux-2.6.27.7/include/asm-x86/paravirt.h 2008-11-07 12:55:34.000000000 -0500
64882 ++++ linux-2.6.27.7/include/asm-x86/paravirt.h 2008-11-18 03:38:45.000000000 -0500
64883 +@@ -1557,7 +1557,7 @@ static inline unsigned long __raw_local_
64884 + #define PV_RESTORE_REGS popl %edx; popl %ecx; popl %edi; popl %eax
64885 + #define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 4)
64886 + #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .long, 4)
64887 +-#define PARA_INDIRECT(addr) *%cs:addr
64888 ++#define PARA_INDIRECT(addr) *%ss:addr
64889 + #endif
64890 +
64891 + #define INTERRUPT_RETURN \
64892 +diff -urNp linux-2.6.27.7/include/asm-x86/pda.h linux-2.6.27.7/include/asm-x86/pda.h
64893 +--- linux-2.6.27.7/include/asm-x86/pda.h 2008-11-07 12:55:34.000000000 -0500
64894 ++++ linux-2.6.27.7/include/asm-x86/pda.h 2008-11-18 03:38:45.000000000 -0500
64895 +@@ -16,11 +16,9 @@ struct x8664_pda {
64896 + unsigned long oldrsp; /* 24 user rsp for system call */
64897 + int irqcount; /* 32 Irq nesting counter. Starts -1 */
64898 + unsigned int cpunumber; /* 36 Logical CPU number */
64899 +-#ifdef CONFIG_CC_STACKPROTECTOR
64900 + unsigned long stack_canary; /* 40 stack canary value */
64901 + /* gcc-ABI: this canary MUST be at
64902 + offset 40!!! */
64903 +-#endif
64904 + char *irqstackptr;
64905 + short nodenumber; /* number of current node (32k max) */
64906 + short in_bootmem; /* pda lives in bootmem */
64907 +diff -urNp linux-2.6.27.7/include/asm-x86/percpu.h linux-2.6.27.7/include/asm-x86/percpu.h
64908 +--- linux-2.6.27.7/include/asm-x86/percpu.h 2008-11-07 12:55:34.000000000 -0500
64909 ++++ linux-2.6.27.7/include/asm-x86/percpu.h 2008-11-18 03:38:45.000000000 -0500
64910 +@@ -93,6 +93,12 @@ DECLARE_PER_CPU(struct x8664_pda, pda);
64911 +
64912 + #define __my_cpu_offset x86_read_percpu(this_cpu_off)
64913 +
64914 ++#include <asm-generic/sections.h>
64915 ++#include <linux/threads.h>
64916 ++#define __per_cpu_offset __per_cpu_offset
64917 ++extern unsigned long __per_cpu_offset[NR_CPUS];
64918 ++#define per_cpu_offset(x) (__per_cpu_offset[x] + (unsigned long)__per_cpu_start)
64919 ++
64920 + /* fs segment starts at (positive) offset == __per_cpu_offset[cpu] */
64921 + #define __percpu_seg "%%fs:"
64922 +
64923 +diff -urNp linux-2.6.27.7/include/asm-x86/pgalloc.h linux-2.6.27.7/include/asm-x86/pgalloc.h
64924 +--- linux-2.6.27.7/include/asm-x86/pgalloc.h 2008-11-07 12:55:34.000000000 -0500
64925 ++++ linux-2.6.27.7/include/asm-x86/pgalloc.h 2008-11-18 03:38:45.000000000 -0500
64926 +@@ -51,7 +51,7 @@ static inline void pmd_populate_kernel(s
64927 + pmd_t *pmd, pte_t *pte)
64928 + {
64929 + paravirt_alloc_pte(mm, __pa(pte) >> PAGE_SHIFT);
64930 +- set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
64931 ++ set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE));
64932 + }
64933 +
64934 + static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
64935 +diff -urNp linux-2.6.27.7/include/asm-x86/pgtable-2level.h linux-2.6.27.7/include/asm-x86/pgtable-2level.h
64936 +--- linux-2.6.27.7/include/asm-x86/pgtable-2level.h 2008-11-07 12:55:34.000000000 -0500
64937 ++++ linux-2.6.27.7/include/asm-x86/pgtable-2level.h 2008-11-18 03:38:45.000000000 -0500
64938 +@@ -18,7 +18,19 @@ static inline void native_set_pte(pte_t
64939 +
64940 + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
64941 + {
64942 ++
64943 ++#ifdef CONFIG_PAX_KERNEXEC
64944 ++ unsigned long cr0;
64945 ++
64946 ++ pax_open_kernel(cr0);
64947 ++#endif
64948 ++
64949 + *pmdp = pmd;
64950 ++
64951 ++#ifdef CONFIG_PAX_KERNEXEC
64952 ++ pax_close_kernel(cr0);
64953 ++#endif
64954 ++
64955 + }
64956 +
64957 + static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
64958 +diff -urNp linux-2.6.27.7/include/asm-x86/pgtable_32.h linux-2.6.27.7/include/asm-x86/pgtable_32.h
64959 +--- linux-2.6.27.7/include/asm-x86/pgtable_32.h 2008-11-07 12:55:34.000000000 -0500
64960 ++++ linux-2.6.27.7/include/asm-x86/pgtable_32.h 2008-11-18 03:38:45.000000000 -0500
64961 +@@ -25,8 +25,6 @@
64962 + struct mm_struct;
64963 + struct vm_area_struct;
64964 +
64965 +-extern pgd_t swapper_pg_dir[1024];
64966 +-
64967 + static inline void pgtable_cache_init(void) { }
64968 + static inline void check_pgt_cache(void) { }
64969 + void paging_init(void);
64970 +@@ -45,6 +43,11 @@ void paging_init(void);
64971 + # include <asm/pgtable-2level-defs.h>
64972 + #endif
64973 +
64974 ++extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
64975 ++#ifdef CONFIG_X86_PAE
64976 ++extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
64977 ++#endif
64978 ++
64979 + #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
64980 + #define PGDIR_MASK (~(PGDIR_SIZE - 1))
64981 +
64982 +@@ -81,7 +84,7 @@ void paging_init(void);
64983 + #undef TEST_ACCESS_OK
64984 +
64985 + /* The boot page tables (all created as a single array) */
64986 +-extern unsigned long pg0[];
64987 ++extern pte_t pg0[];
64988 +
64989 + #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
64990 +
64991 +@@ -173,6 +176,9 @@ do { \
64992 +
64993 + #endif /* !__ASSEMBLY__ */
64994 +
64995 ++#define HAVE_ARCH_UNMAPPED_AREA
64996 ++#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
64997 ++
64998 + /*
64999 + * kern_addr_valid() is (1) for FLATMEM and (0) for
65000 + * SPARSEMEM and DISCONTIGMEM
65001 +diff -urNp linux-2.6.27.7/include/asm-x86/pgtable-3level.h linux-2.6.27.7/include/asm-x86/pgtable-3level.h
65002 +--- linux-2.6.27.7/include/asm-x86/pgtable-3level.h 2008-11-07 12:55:34.000000000 -0500
65003 ++++ linux-2.6.27.7/include/asm-x86/pgtable-3level.h 2008-11-18 03:38:45.000000000 -0500
65004 +@@ -70,12 +70,36 @@ static inline void native_set_pte_atomic
65005 +
65006 + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
65007 + {
65008 ++
65009 ++#ifdef CONFIG_PAX_KERNEXEC
65010 ++ unsigned long cr0;
65011 ++
65012 ++ pax_open_kernel(cr0);
65013 ++#endif
65014 ++
65015 + set_64bit((unsigned long long *)(pmdp), native_pmd_val(pmd));
65016 ++
65017 ++#ifdef CONFIG_PAX_KERNEXEC
65018 ++ pax_close_kernel(cr0);
65019 ++#endif
65020 ++
65021 + }
65022 +
65023 + static inline void native_set_pud(pud_t *pudp, pud_t pud)
65024 + {
65025 ++
65026 ++#ifdef CONFIG_PAX_KERNEXEC
65027 ++ unsigned long cr0;
65028 ++
65029 ++ pax_open_kernel(cr0);
65030 ++#endif
65031 ++
65032 + set_64bit((unsigned long long *)(pudp), native_pud_val(pud));
65033 ++
65034 ++#ifdef CONFIG_PAX_KERNEXEC
65035 ++ pax_close_kernel(cr0);
65036 ++#endif
65037 ++
65038 + }
65039 +
65040 + /*
65041 +diff -urNp linux-2.6.27.7/include/asm-x86/pgtable_64.h linux-2.6.27.7/include/asm-x86/pgtable_64.h
65042 +--- linux-2.6.27.7/include/asm-x86/pgtable_64.h 2008-11-07 12:55:34.000000000 -0500
65043 ++++ linux-2.6.27.7/include/asm-x86/pgtable_64.h 2008-11-18 03:38:45.000000000 -0500
65044 +@@ -15,9 +15,12 @@
65045 +
65046 + extern pud_t level3_kernel_pgt[512];
65047 + extern pud_t level3_ident_pgt[512];
65048 ++extern pud_t level3_vmalloc_pgt[512];
65049 ++extern pud_t level3_vmemmap_pgt[512];
65050 + extern pmd_t level2_kernel_pgt[512];
65051 + extern pmd_t level2_fixmap_pgt[512];
65052 + extern pmd_t level2_ident_pgt[512];
65053 ++extern pte_t level1_fixmap_pgt[512];
65054 + extern pgd_t init_level4_pgt[];
65055 +
65056 + #define swapper_pg_dir init_level4_pgt
65057 +@@ -106,7 +109,19 @@ static inline pte_t native_ptep_get_and_
65058 +
65059 + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
65060 + {
65061 ++
65062 ++#ifdef CONFIG_PAX_KERNEXEC
65063 ++ unsigned long cr0;
65064 ++
65065 ++ pax_open_kernel(cr0);
65066 ++#endif
65067 ++
65068 + *pmdp = pmd;
65069 ++
65070 ++#ifdef CONFIG_PAX_KERNEXEC
65071 ++ pax_close_kernel(cr0);
65072 ++#endif
65073 ++
65074 + }
65075 +
65076 + static inline void native_pmd_clear(pmd_t *pmd)
65077 +@@ -158,17 +173,17 @@ static inline void native_pgd_clear(pgd_
65078 +
65079 + static inline int pgd_bad(pgd_t pgd)
65080 + {
65081 +- return (pgd_val(pgd) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
65082 ++ return (pgd_val(pgd) & ~(PTE_PFN_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
65083 + }
65084 +
65085 + static inline int pud_bad(pud_t pud)
65086 + {
65087 +- return (pud_val(pud) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
65088 ++ return (pud_val(pud) & ~(PTE_PFN_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
65089 + }
65090 +
65091 + static inline int pmd_bad(pmd_t pmd)
65092 + {
65093 +- return (pmd_val(pmd) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
65094 ++ return (pmd_val(pmd) & ~(PTE_PFN_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
65095 + }
65096 +
65097 + #define pte_none(x) (!pte_val((x)))
65098 +diff -urNp linux-2.6.27.7/include/asm-x86/pgtable.h linux-2.6.27.7/include/asm-x86/pgtable.h
65099 +--- linux-2.6.27.7/include/asm-x86/pgtable.h 2008-11-07 12:55:34.000000000 -0500
65100 ++++ linux-2.6.27.7/include/asm-x86/pgtable.h 2008-11-18 03:38:45.000000000 -0500
65101 +@@ -41,7 +41,7 @@
65102 + #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
65103 + #define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_NX)
65104 + #else
65105 +-#define _PAGE_NX (_AT(pteval_t, 0))
65106 ++#define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED3)
65107 + #endif
65108 +
65109 + /* If _PAGE_PRESENT is clear, we use these: */
65110 +@@ -81,6 +81,9 @@
65111 + #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \
65112 + _PAGE_ACCESSED)
65113 +
65114 ++#define PAGE_READONLY_NOEXEC PAGE_READONLY
65115 ++#define PAGE_SHARED_NOEXEC PAGE_SHARED
65116 ++
65117 + #define __PAGE_KERNEL_EXEC \
65118 + (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL)
65119 + #define __PAGE_KERNEL (__PAGE_KERNEL_EXEC | _PAGE_NX)
65120 +@@ -92,7 +95,7 @@
65121 + #define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
65122 + #define __PAGE_KERNEL_UC_MINUS (__PAGE_KERNEL | _PAGE_PCD)
65123 + #define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER)
65124 +-#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
65125 ++#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_RO | _PAGE_PCD | _PAGE_PWT | _PAGE_USER)
65126 + #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE)
65127 + #define __PAGE_KERNEL_LARGE_NOCACHE (__PAGE_KERNEL | _PAGE_CACHE_UC | _PAGE_PSE)
65128 + #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE)
65129 +@@ -142,10 +145,17 @@ extern unsigned long empty_zero_page[PAG
65130 + extern spinlock_t pgd_lock;
65131 + extern struct list_head pgd_list;
65132 +
65133 ++extern pteval_t __supported_pte_mask;
65134 ++
65135 + /*
65136 + * The following only work if pte_present() is true.
65137 + * Undefined behaviour if not..
65138 + */
65139 ++static inline int pte_user(pte_t pte)
65140 ++{
65141 ++ return pte_val(pte) & _PAGE_USER;
65142 ++}
65143 ++
65144 + static inline int pte_dirty(pte_t pte)
65145 + {
65146 + return pte_flags(pte) & _PAGE_DIRTY;
65147 +@@ -207,9 +217,29 @@ static inline pte_t pte_wrprotect(pte_t
65148 + return __pte(pte_val(pte) & ~_PAGE_RW);
65149 + }
65150 +
65151 ++static inline pte_t pte_mkread(pte_t pte)
65152 ++{
65153 ++ return __pte(pte_val(pte) | _PAGE_USER);
65154 ++}
65155 ++
65156 + static inline pte_t pte_mkexec(pte_t pte)
65157 + {
65158 +- return __pte(pte_val(pte) & ~_PAGE_NX);
65159 ++#ifdef CONFIG_X86_PAE
65160 ++ if (__supported_pte_mask & _PAGE_NX)
65161 ++ return __pte(pte_val(pte) & ~(pteval_t)_PAGE_NX);
65162 ++ else
65163 ++#endif
65164 ++ return __pte(pte_val(pte) | _PAGE_USER);
65165 ++}
65166 ++
65167 ++static inline pte_t pte_exprotect(pte_t pte)
65168 ++{
65169 ++#ifdef CONFIG_X86_PAE
65170 ++ if (__supported_pte_mask & _PAGE_NX)
65171 ++ return __pte(pte_val(pte) | _PAGE_NX);
65172 ++ else
65173 ++#endif
65174 ++ return __pte(pte_val(pte) & ~_PAGE_USER);
65175 + }
65176 +
65177 + static inline pte_t pte_mkdirty(pte_t pte)
65178 +@@ -252,8 +282,6 @@ static inline pte_t pte_mkspecial(pte_t
65179 + return __pte(pte_val(pte) | _PAGE_SPECIAL);
65180 + }
65181 +
65182 +-extern pteval_t __supported_pte_mask;
65183 +-
65184 + static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
65185 + {
65186 + return __pte((((phys_addr_t)page_nr << PAGE_SHIFT) |
65187 +@@ -514,7 +542,19 @@ static inline void ptep_set_wrprotect(st
65188 + */
65189 + static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
65190 + {
65191 +- memcpy(dst, src, count * sizeof(pgd_t));
65192 ++
65193 ++#ifdef CONFIG_PAX_KERNEXEC
65194 ++ unsigned long cr0;
65195 ++
65196 ++ pax_open_kernel(cr0);
65197 ++#endif
65198 ++
65199 ++ memcpy(dst, src, count * sizeof(pgd_t));
65200 ++
65201 ++#ifdef CONFIG_PAX_KERNEXEC
65202 ++ pax_close_kernel(cr0);
65203 ++#endif
65204 ++
65205 + }
65206 +
65207 +
65208 +diff -urNp linux-2.6.27.7/include/asm-x86/processor.h linux-2.6.27.7/include/asm-x86/processor.h
65209 +--- linux-2.6.27.7/include/asm-x86/processor.h 2008-11-07 12:55:34.000000000 -0500
65210 ++++ linux-2.6.27.7/include/asm-x86/processor.h 2008-11-18 03:38:45.000000000 -0500
65211 +@@ -269,7 +269,7 @@ struct tss_struct {
65212 +
65213 + } ____cacheline_aligned;
65214 +
65215 +-DECLARE_PER_CPU(struct tss_struct, init_tss);
65216 ++extern struct tss_struct init_tss[NR_CPUS];
65217 +
65218 + /*
65219 + * Save the original ist values for checking stack pointers during debugging
65220 +@@ -832,11 +832,20 @@ static inline void spin_lock_prefetch(co
65221 + * User space process size: 3GB (default).
65222 + */
65223 + #define TASK_SIZE PAGE_OFFSET
65224 ++
65225 ++#ifdef CONFIG_PAX_SEGMEXEC
65226 ++#define SEGMEXEC_TASK_SIZE (TASK_SIZE / 2)
65227 ++#endif
65228 ++
65229 ++#ifdef CONFIG_PAX_SEGMEXEC
65230 ++#define STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE:TASK_SIZE)
65231 ++#else
65232 + #define STACK_TOP TASK_SIZE
65233 +-#define STACK_TOP_MAX STACK_TOP
65234 ++#endif
65235 ++#define STACK_TOP_MAX TASK_SIZE
65236 +
65237 + #define INIT_THREAD { \
65238 +- .sp0 = sizeof(init_stack) + (long)&init_stack, \
65239 ++ .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
65240 + .vm86_info = NULL, \
65241 + .sysenter_cs = __KERNEL_CS, \
65242 + .io_bitmap_ptr = NULL, \
65243 +@@ -851,7 +860,7 @@ static inline void spin_lock_prefetch(co
65244 + */
65245 + #define INIT_TSS { \
65246 + .x86_tss = { \
65247 +- .sp0 = sizeof(init_stack) + (long)&init_stack, \
65248 ++ .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
65249 + .ss0 = __KERNEL_DS, \
65250 + .ss1 = __KERNEL_CS, \
65251 + .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
65252 +@@ -862,11 +871,7 @@ static inline void spin_lock_prefetch(co
65253 + extern unsigned long thread_saved_pc(struct task_struct *tsk);
65254 +
65255 + #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
65256 +-#define KSTK_TOP(info) \
65257 +-({ \
65258 +- unsigned long *__ptr = (unsigned long *)(info); \
65259 +- (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
65260 +-})
65261 ++#define KSTK_TOP(info) ((info)->task.thread.sp0)
65262 +
65263 + /*
65264 + * The below -8 is to reserve 8 bytes on top of the ring0 stack.
65265 +@@ -881,7 +886,7 @@ extern unsigned long thread_saved_pc(str
65266 + #define task_pt_regs(task) \
65267 + ({ \
65268 + struct pt_regs *__regs__; \
65269 +- __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
65270 ++ __regs__ = (struct pt_regs *)((task)->thread.sp0); \
65271 + __regs__ - 1; \
65272 + })
65273 +
65274 +@@ -897,7 +902,7 @@ extern unsigned long thread_saved_pc(str
65275 + * space during mmap's.
65276 + */
65277 + #define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? \
65278 +- 0xc0000000 : 0xFFFFe000)
65279 ++ 0xc0000000 : 0xFFFFf000)
65280 +
65281 + #define TASK_SIZE (test_thread_flag(TIF_IA32) ? \
65282 + IA32_PAGE_OFFSET : TASK_SIZE64)
65283 +@@ -934,6 +939,10 @@ extern void start_thread(struct pt_regs
65284 + */
65285 + #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
65286 +
65287 ++#ifdef CONFIG_PAX_SEGMEXEC
65288 ++#define SEGMEXEC_TASK_UNMAPPED_BASE (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3))
65289 ++#endif
65290 ++
65291 + #define KSTK_EIP(task) (task_pt_regs(task)->ip)
65292 +
65293 + /* Get/set a process' ability to use the timestamp counter instruction */
65294 +diff -urNp linux-2.6.27.7/include/asm-x86/ptrace.h linux-2.6.27.7/include/asm-x86/ptrace.h
65295 +--- linux-2.6.27.7/include/asm-x86/ptrace.h 2008-11-07 12:55:34.000000000 -0500
65296 ++++ linux-2.6.27.7/include/asm-x86/ptrace.h 2008-11-18 03:38:45.000000000 -0500
65297 +@@ -131,6 +131,7 @@ struct pt_regs {
65298 +
65299 + /* the DS BTS struct is used for ptrace as well */
65300 + #include <asm/ds.h>
65301 ++#include <asm/segment.h>
65302 +
65303 + struct task_struct;
65304 +
65305 +@@ -154,28 +155,29 @@ static inline unsigned long regs_return_
65306 + }
65307 +
65308 + /*
65309 +- * user_mode_vm(regs) determines whether a register set came from user mode.
65310 ++ * user_mode(regs) determines whether a register set came from user mode.
65311 + * This is true if V8086 mode was enabled OR if the register set was from
65312 + * protected mode with RPL-3 CS value. This tricky test checks that with
65313 + * one comparison. Many places in the kernel can bypass this full check
65314 +- * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
65315 ++ * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
65316 ++ * be used.
65317 + */
65318 +-static inline int user_mode(struct pt_regs *regs)
65319 ++static inline int user_mode_novm(struct pt_regs *regs)
65320 + {
65321 + #ifdef CONFIG_X86_32
65322 + return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL;
65323 + #else
65324 +- return !!(regs->cs & 3);
65325 ++ return !!(regs->cs & SEGMENT_RPL_MASK);
65326 + #endif
65327 + }
65328 +
65329 +-static inline int user_mode_vm(struct pt_regs *regs)
65330 ++static inline int user_mode(struct pt_regs *regs)
65331 + {
65332 + #ifdef CONFIG_X86_32
65333 + return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >=
65334 + USER_RPL;
65335 + #else
65336 +- return user_mode(regs);
65337 ++ return user_mode_novm(regs);
65338 + #endif
65339 + }
65340 +
65341 +diff -urNp linux-2.6.27.7/include/asm-x86/reboot.h linux-2.6.27.7/include/asm-x86/reboot.h
65342 +--- linux-2.6.27.7/include/asm-x86/reboot.h 2008-11-07 12:55:34.000000000 -0500
65343 ++++ linux-2.6.27.7/include/asm-x86/reboot.h 2008-11-18 03:38:45.000000000 -0500
65344 +@@ -16,6 +16,6 @@ extern struct machine_ops machine_ops;
65345 +
65346 + void native_machine_crash_shutdown(struct pt_regs *regs);
65347 + void native_machine_shutdown(void);
65348 +-void machine_real_restart(const unsigned char *code, int length);
65349 ++void machine_real_restart(const unsigned char *code, unsigned int length);
65350 +
65351 + #endif /* _ASM_REBOOT_H */
65352 +diff -urNp linux-2.6.27.7/include/asm-x86/rwsem.h linux-2.6.27.7/include/asm-x86/rwsem.h
65353 +--- linux-2.6.27.7/include/asm-x86/rwsem.h 2008-11-07 12:55:34.000000000 -0500
65354 ++++ linux-2.6.27.7/include/asm-x86/rwsem.h 2008-11-18 03:38:45.000000000 -0500
65355 +@@ -106,10 +106,26 @@ static inline void __down_read(struct rw
65356 + {
65357 + asm volatile("# beginning down_read\n\t"
65358 + LOCK_PREFIX " incl (%%eax)\n\t"
65359 ++
65360 ++#ifdef CONFIG_PAX_REFCOUNT
65361 ++#ifdef CONFIG_X86_32
65362 ++ "into\n0:\n"
65363 ++#else
65364 ++ "jno 0f\n"
65365 ++ "int $4\n0:\n"
65366 ++#endif
65367 ++ ".pushsection .fixup,\"ax\"\n"
65368 ++ "1:\n"
65369 ++ LOCK_PREFIX "decl (%%eax)\n"
65370 ++ "jmp 0b\n"
65371 ++ ".popsection\n"
65372 ++ _ASM_EXTABLE(0b, 1b)
65373 ++#endif
65374 ++
65375 + /* adds 0x00000001, returns the old value */
65376 +- " jns 1f\n"
65377 ++ " jns 2f\n"
65378 + " call call_rwsem_down_read_failed\n"
65379 +- "1:\n\t"
65380 ++ "2:\n\t"
65381 + "# ending down_read\n\t"
65382 + : "+m" (sem->count)
65383 + : "a" (sem)
65384 +@@ -124,13 +140,29 @@ static inline int __down_read_trylock(st
65385 + __s32 result, tmp;
65386 + asm volatile("# beginning __down_read_trylock\n\t"
65387 + " movl %0,%1\n\t"
65388 +- "1:\n\t"
65389 ++ "2:\n\t"
65390 + " movl %1,%2\n\t"
65391 + " addl %3,%2\n\t"
65392 +- " jle 2f\n\t"
65393 ++
65394 ++#ifdef CONFIG_PAX_REFCOUNT
65395 ++#ifdef CONFIG_X86_32
65396 ++ "into\n0:\n"
65397 ++#else
65398 ++ "jno 0f\n"
65399 ++ "int $4\n0:\n"
65400 ++#endif
65401 ++ ".pushsection .fixup,\"ax\"\n"
65402 ++ "1:\n"
65403 ++ "subl %3,%2\n"
65404 ++ "jmp 0b\n"
65405 ++ ".popsection\n"
65406 ++ _ASM_EXTABLE(0b, 1b)
65407 ++#endif
65408 ++
65409 ++ " jle 3f\n\t"
65410 + LOCK_PREFIX " cmpxchgl %2,%0\n\t"
65411 +- " jnz 1b\n\t"
65412 +- "2:\n\t"
65413 ++ " jnz 2b\n\t"
65414 ++ "3:\n\t"
65415 + "# ending __down_read_trylock\n\t"
65416 + : "+m" (sem->count), "=&a" (result), "=&r" (tmp)
65417 + : "i" (RWSEM_ACTIVE_READ_BIAS)
65418 +@@ -148,12 +180,28 @@ static inline void __down_write_nested(s
65419 + tmp = RWSEM_ACTIVE_WRITE_BIAS;
65420 + asm volatile("# beginning down_write\n\t"
65421 + LOCK_PREFIX " xadd %%edx,(%%eax)\n\t"
65422 ++
65423 ++#ifdef CONFIG_PAX_REFCOUNT
65424 ++#ifdef CONFIG_X86_32
65425 ++ "into\n0:\n"
65426 ++#else
65427 ++ "jno 0f\n"
65428 ++ "int $4\n0:\n"
65429 ++#endif
65430 ++ ".pushsection .fixup,\"ax\"\n"
65431 ++ "1:\n"
65432 ++ "movl %%edx,(%%eax)\n"
65433 ++ "jmp 0b\n"
65434 ++ ".popsection\n"
65435 ++ _ASM_EXTABLE(0b, 1b)
65436 ++#endif
65437 ++
65438 + /* subtract 0x0000ffff, returns the old value */
65439 + " testl %%edx,%%edx\n\t"
65440 + /* was the count 0 before? */
65441 +- " jz 1f\n"
65442 ++ " jz 2f\n"
65443 + " call call_rwsem_down_write_failed\n"
65444 +- "1:\n"
65445 ++ "2:\n"
65446 + "# ending down_write"
65447 + : "+m" (sem->count), "=d" (tmp)
65448 + : "a" (sem), "1" (tmp)
65449 +@@ -186,10 +234,26 @@ static inline void __up_read(struct rw_s
65450 + __s32 tmp = -RWSEM_ACTIVE_READ_BIAS;
65451 + asm volatile("# beginning __up_read\n\t"
65452 + LOCK_PREFIX " xadd %%edx,(%%eax)\n\t"
65453 ++
65454 ++#ifdef CONFIG_PAX_REFCOUNT
65455 ++#ifdef CONFIG_X86_32
65456 ++ "into\n0:\n"
65457 ++#else
65458 ++ "jno 0f\n"
65459 ++ "int $4\n0:\n"
65460 ++#endif
65461 ++ ".pushsection .fixup,\"ax\"\n"
65462 ++ "1:\n"
65463 ++ "movl %%edx,(%%eax)\n"
65464 ++ "jmp 0b\n"
65465 ++ ".popsection\n"
65466 ++ _ASM_EXTABLE(0b, 1b)
65467 ++#endif
65468 ++
65469 + /* subtracts 1, returns the old value */
65470 +- " jns 1f\n\t"
65471 ++ " jns 2f\n\t"
65472 + " call call_rwsem_wake\n"
65473 +- "1:\n"
65474 ++ "2:\n"
65475 + "# ending __up_read\n"
65476 + : "+m" (sem->count), "=d" (tmp)
65477 + : "a" (sem), "1" (tmp)
65478 +@@ -204,11 +268,27 @@ static inline void __up_write(struct rw_
65479 + asm volatile("# beginning __up_write\n\t"
65480 + " movl %2,%%edx\n\t"
65481 + LOCK_PREFIX " xaddl %%edx,(%%eax)\n\t"
65482 ++
65483 ++#ifdef CONFIG_PAX_REFCOUNT
65484 ++#ifdef CONFIG_X86_32
65485 ++ "into\n0:\n"
65486 ++#else
65487 ++ "jno 0f\n"
65488 ++ "int $4\n0:\n"
65489 ++#endif
65490 ++ ".pushsection .fixup,\"ax\"\n"
65491 ++ "1:\n"
65492 ++ "movl %%edx,(%%eax)\n"
65493 ++ "jmp 0b\n"
65494 ++ ".popsection\n"
65495 ++ _ASM_EXTABLE(0b, 1b)
65496 ++#endif
65497 ++
65498 + /* tries to transition
65499 + 0xffff0001 -> 0x00000000 */
65500 +- " jz 1f\n"
65501 ++ " jz 2f\n"
65502 + " call call_rwsem_wake\n"
65503 +- "1:\n\t"
65504 ++ "2:\n\t"
65505 + "# ending __up_write\n"
65506 + : "+m" (sem->count)
65507 + : "a" (sem), "i" (-RWSEM_ACTIVE_WRITE_BIAS)
65508 +@@ -222,10 +302,26 @@ static inline void __downgrade_write(str
65509 + {
65510 + asm volatile("# beginning __downgrade_write\n\t"
65511 + LOCK_PREFIX " addl %2,(%%eax)\n\t"
65512 ++
65513 ++#ifdef CONFIG_PAX_REFCOUNT
65514 ++#ifdef CONFIG_X86_32
65515 ++ "into\n0:\n"
65516 ++#else
65517 ++ "jno 0f\n"
65518 ++ "int $4\n0:\n"
65519 ++#endif
65520 ++ ".pushsection .fixup,\"ax\"\n"
65521 ++ "1:\n"
65522 ++ LOCK_PREFIX "subl %2,(%%eax)\n"
65523 ++ "jmp 0b\n"
65524 ++ ".popsection\n"
65525 ++ _ASM_EXTABLE(0b, 1b)
65526 ++#endif
65527 ++
65528 + /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
65529 +- " jns 1f\n\t"
65530 ++ " jns 2f\n\t"
65531 + " call call_rwsem_downgrade_wake\n"
65532 +- "1:\n\t"
65533 ++ "2:\n\t"
65534 + "# ending __downgrade_write\n"
65535 + : "+m" (sem->count)
65536 + : "a" (sem), "i" (-RWSEM_WAITING_BIAS)
65537 +@@ -237,7 +333,23 @@ static inline void __downgrade_write(str
65538 + */
65539 + static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
65540 + {
65541 +- asm volatile(LOCK_PREFIX "addl %1,%0"
65542 ++ asm volatile(LOCK_PREFIX "addl %1,%0\n"
65543 ++
65544 ++#ifdef CONFIG_PAX_REFCOUNT
65545 ++#ifdef CONFIG_X86_32
65546 ++ "into\n0:\n"
65547 ++#else
65548 ++ "jno 0f\n"
65549 ++ "int $4\n0:\n"
65550 ++#endif
65551 ++ ".pushsection .fixup,\"ax\"\n"
65552 ++ "1:\n"
65553 ++ LOCK_PREFIX "subl %1,%0\n"
65554 ++ "jmp 0b\n"
65555 ++ ".popsection\n"
65556 ++ _ASM_EXTABLE(0b, 1b)
65557 ++#endif
65558 ++
65559 + : "+m" (sem->count)
65560 + : "ir" (delta));
65561 + }
65562 +@@ -249,7 +361,23 @@ static inline int rwsem_atomic_update(in
65563 + {
65564 + int tmp = delta;
65565 +
65566 +- asm volatile(LOCK_PREFIX "xadd %0,%1"
65567 ++ asm volatile(LOCK_PREFIX "xadd %0,%1\n"
65568 ++
65569 ++#ifdef CONFIG_PAX_REFCOUNT
65570 ++#ifdef CONFIG_X86_32
65571 ++ "into\n0:\n"
65572 ++#else
65573 ++ "jno 0f\n"
65574 ++ "int $4\n0:\n"
65575 ++#endif
65576 ++ ".pushsection .fixup,\"ax\"\n"
65577 ++ "1:\n"
65578 ++ "movl %0,%1\n"
65579 ++ "jmp 0b\n"
65580 ++ ".popsection\n"
65581 ++ _ASM_EXTABLE(0b, 1b)
65582 ++#endif
65583 ++
65584 + : "+r" (tmp), "+m" (sem->count)
65585 + : : "memory");
65586 +
65587 +diff -urNp linux-2.6.27.7/include/asm-x86/segment.h linux-2.6.27.7/include/asm-x86/segment.h
65588 +--- linux-2.6.27.7/include/asm-x86/segment.h 2008-11-07 12:55:34.000000000 -0500
65589 ++++ linux-2.6.27.7/include/asm-x86/segment.h 2008-11-18 03:38:45.000000000 -0500
65590 +@@ -88,13 +88,19 @@
65591 + #define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14)
65592 + #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
65593 +
65594 +-#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
65595 ++#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
65596 + #ifdef CONFIG_SMP
65597 + #define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
65598 + #else
65599 + #define __KERNEL_PERCPU 0
65600 + #endif
65601 +
65602 ++#define GDT_ENTRY_PCIBIOS_CS (GDT_ENTRY_KERNEL_BASE + 16)
65603 ++#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8)
65604 ++
65605 ++#define GDT_ENTRY_PCIBIOS_DS (GDT_ENTRY_KERNEL_BASE + 17)
65606 ++#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8)
65607 ++
65608 + #define GDT_ENTRY_DOUBLEFAULT_TSS 31
65609 +
65610 + /*
65611 +@@ -135,10 +141,10 @@
65612 + #define SEGMENT_IS_KERNEL_CODE(x) (((x) & 0xfc) == GDT_ENTRY_KERNEL_CS * 8)
65613 +
65614 + /* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */
65615 +-#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8)
65616 ++#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xFFFCU) == __KERNEL_CS || ((x) & 0xFFFCU) == __USER_CS)
65617 +
65618 + /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
65619 +-#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
65620 ++#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
65621 +
65622 +
65623 + #else
65624 +diff -urNp linux-2.6.27.7/include/asm-x86/spinlock.h linux-2.6.27.7/include/asm-x86/spinlock.h
65625 +--- linux-2.6.27.7/include/asm-x86/spinlock.h 2008-11-07 12:55:34.000000000 -0500
65626 ++++ linux-2.6.27.7/include/asm-x86/spinlock.h 2008-11-18 03:38:45.000000000 -0500
65627 +@@ -315,18 +315,50 @@ static inline int __raw_write_can_lock(r
65628 + static inline void __raw_read_lock(raw_rwlock_t *rw)
65629 + {
65630 + asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t"
65631 +- "jns 1f\n"
65632 +- "call __read_lock_failed\n\t"
65633 ++
65634 ++#ifdef CONFIG_PAX_REFCOUNT
65635 ++#ifdef CONFIG_X86_32
65636 ++ "into\n0:\n"
65637 ++#else
65638 ++ "jno 0f\n"
65639 ++ "int $4\n0:\n"
65640 ++#endif
65641 ++ ".pushsection .fixup,\"ax\"\n"
65642 + "1:\n"
65643 ++ LOCK_PREFIX " addl $1,(%0)\n"
65644 ++ "jmp 0b\n"
65645 ++ ".popsection\n"
65646 ++ _ASM_EXTABLE(0b, 1b)
65647 ++#endif
65648 ++
65649 ++ "jns 2f\n"
65650 ++ "call __read_lock_failed\n\t"
65651 ++ "2:\n"
65652 + ::LOCK_PTR_REG (rw) : "memory");
65653 + }
65654 +
65655 + static inline void __raw_write_lock(raw_rwlock_t *rw)
65656 + {
65657 + asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t"
65658 +- "jz 1f\n"
65659 +- "call __write_lock_failed\n\t"
65660 ++
65661 ++#ifdef CONFIG_PAX_REFCOUNT
65662 ++#ifdef CONFIG_X86_32
65663 ++ "into\n0:\n"
65664 ++#else
65665 ++ "jno 0f\n"
65666 ++ "int $4\n0:\n"
65667 ++#endif
65668 ++ ".pushsection .fixup,\"ax\"\n"
65669 + "1:\n"
65670 ++ LOCK_PREFIX " addl %1,(%0)\n"
65671 ++ "jmp 0b\n"
65672 ++ ".popsection\n"
65673 ++ _ASM_EXTABLE(0b, 1b)
65674 ++#endif
65675 ++
65676 ++ "jz 2f\n"
65677 ++ "call __write_lock_failed\n\t"
65678 ++ "2:\n"
65679 + ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory");
65680 + }
65681 +
65682 +@@ -353,12 +385,45 @@ static inline int __raw_write_trylock(ra
65683 +
65684 + static inline void __raw_read_unlock(raw_rwlock_t *rw)
65685 + {
65686 +- asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory");
65687 ++ asm volatile(LOCK_PREFIX "incl %0\n"
65688 ++
65689 ++#ifdef CONFIG_PAX_REFCOUNT
65690 ++#ifdef CONFIG_X86_32
65691 ++ "into\n0:\n"
65692 ++#else
65693 ++ "jno 0f\n"
65694 ++ "int $4\n0:\n"
65695 ++#endif
65696 ++ ".pushsection .fixup,\"ax\"\n"
65697 ++ "1:\n"
65698 ++ LOCK_PREFIX "decl %0\n"
65699 ++ "jmp 0b\n"
65700 ++ ".popsection\n"
65701 ++ _ASM_EXTABLE(0b, 1b)
65702 ++#endif
65703 ++
65704 ++ :"+m" (rw->lock) : : "memory");
65705 + }
65706 +
65707 + static inline void __raw_write_unlock(raw_rwlock_t *rw)
65708 + {
65709 +- asm volatile(LOCK_PREFIX "addl %1, %0"
65710 ++ asm volatile(LOCK_PREFIX "addl %1, %0\n"
65711 ++
65712 ++#ifdef CONFIG_PAX_REFCOUNT
65713 ++#ifdef CONFIG_X86_32
65714 ++ "into\n0:\n"
65715 ++#else
65716 ++ "jno 0f\n"
65717 ++ "int $4\n0:\n"
65718 ++#endif
65719 ++ ".pushsection .fixup,\"ax\"\n"
65720 ++ "1:\n"
65721 ++ LOCK_PREFIX "subl %1,%0\n"
65722 ++ "jmp 0b\n"
65723 ++ ".popsection\n"
65724 ++ _ASM_EXTABLE(0b, 1b)
65725 ++#endif
65726 ++
65727 + : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory");
65728 + }
65729 +
65730 +diff -urNp linux-2.6.27.7/include/asm-x86/system.h linux-2.6.27.7/include/asm-x86/system.h
65731 +--- linux-2.6.27.7/include/asm-x86/system.h 2008-11-07 12:55:34.000000000 -0500
65732 ++++ linux-2.6.27.7/include/asm-x86/system.h 2008-11-18 03:38:45.000000000 -0500
65733 +@@ -92,6 +92,8 @@ do { \
65734 + ".globl thread_return\n" \
65735 + "thread_return:\n\t" \
65736 + "movq %%gs:%P[pda_pcurrent],%%rsi\n\t" \
65737 ++ "movq %P[task_canary](%%rsi),%%r8\n\t" \
65738 ++ "movq %%r8,%%gs:%P[pda_canary]\n\t" \
65739 + "movq %P[thread_info](%%rsi),%%r8\n\t" \
65740 + LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \
65741 + "movq %%rax,%%rdi\n\t" \
65742 +@@ -103,7 +105,9 @@ do { \
65743 + [ti_flags] "i" (offsetof(struct thread_info, flags)), \
65744 + [tif_fork] "i" (TIF_FORK), \
65745 + [thread_info] "i" (offsetof(struct task_struct, stack)), \
65746 +- [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \
65747 ++ [task_canary] "i" (offsetof(struct task_struct, stack_canary)), \
65748 ++ [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)), \
65749 ++ [pda_canary] "i" (offsetof(struct x8664_pda, stack_canary))\
65750 + : "memory", "cc" __EXTRA_CLOBBER)
65751 + #endif
65752 +
65753 +@@ -166,7 +170,7 @@ static inline unsigned long get_limit(un
65754 + {
65755 + unsigned long __limit;
65756 + asm("lsll %1,%0" : "=r" (__limit) : "r" (segment));
65757 +- return __limit + 1;
65758 ++ return __limit;
65759 + }
65760 +
65761 + static inline void native_clts(void)
65762 +@@ -292,6 +296,21 @@ static inline void native_wbinvd(void)
65763 +
65764 + #define stts() write_cr0(read_cr0() | X86_CR0_TS)
65765 +
65766 ++#define pax_open_kernel(cr0) \
65767 ++do { \
65768 ++ typecheck(unsigned long, cr0); \
65769 ++ preempt_disable(); \
65770 ++ cr0 = read_cr0(); \
65771 ++ write_cr0(cr0 & ~X86_CR0_WP); \
65772 ++} while (0)
65773 ++
65774 ++#define pax_close_kernel(cr0) \
65775 ++do { \
65776 ++ typecheck(unsigned long, cr0); \
65777 ++ write_cr0(cr0); \
65778 ++ preempt_enable_no_resched(); \
65779 ++} while (0)
65780 ++
65781 + #endif /* __KERNEL__ */
65782 +
65783 + static inline void clflush(volatile void *__p)
65784 +@@ -306,7 +325,7 @@ void enable_hlt(void);
65785 +
65786 + void cpu_idle_wait(void);
65787 +
65788 +-extern unsigned long arch_align_stack(unsigned long sp);
65789 ++#define arch_align_stack(x) ((x) & ~0xfUL)
65790 + extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
65791 +
65792 + void default_idle(void);
65793 +diff -urNp linux-2.6.27.7/include/asm-x86/uaccess_64.h linux-2.6.27.7/include/asm-x86/uaccess_64.h
65794 +--- linux-2.6.27.7/include/asm-x86/uaccess_64.h 2008-11-07 12:55:34.000000000 -0500
65795 ++++ linux-2.6.27.7/include/asm-x86/uaccess_64.h 2008-11-18 03:38:45.000000000 -0500
65796 +@@ -10,6 +10,8 @@
65797 + #include <linux/lockdep.h>
65798 + #include <asm/page.h>
65799 +
65800 ++#define set_fs(x) (current_thread_info()->addr_limit = (x))
65801 ++
65802 + /*
65803 + * Copy To/From Userspace
65804 + */
65805 +diff -urNp linux-2.6.27.7/include/asm-x86/uaccess.h linux-2.6.27.7/include/asm-x86/uaccess.h
65806 +--- linux-2.6.27.7/include/asm-x86/uaccess.h 2008-11-07 12:55:34.000000000 -0500
65807 ++++ linux-2.6.27.7/include/asm-x86/uaccess.h 2008-11-18 03:38:45.000000000 -0500
65808 +@@ -10,6 +10,7 @@
65809 + #include <linux/string.h>
65810 + #include <asm/asm.h>
65811 + #include <asm/page.h>
65812 ++#include <asm/segment.h>
65813 +
65814 + #define VERIFY_READ 0
65815 + #define VERIFY_WRITE 1
65816 +@@ -29,7 +30,12 @@
65817 +
65818 + #define get_ds() (KERNEL_DS)
65819 + #define get_fs() (current_thread_info()->addr_limit)
65820 ++#ifdef CONFIG_X86_32
65821 ++void __set_fs(mm_segment_t x, int cpu);
65822 ++void set_fs(mm_segment_t x);
65823 ++#else
65824 + #define set_fs(x) (current_thread_info()->addr_limit = (x))
65825 ++#endif
65826 +
65827 + #define segment_eq(a, b) ((a).seg == (b).seg)
65828 +
65829 +@@ -97,6 +103,7 @@ struct exception_table_entry {
65830 + };
65831 +
65832 + extern int fixup_exception(struct pt_regs *regs);
65833 ++#define ARCH_HAS_SORT_EXTABLE
65834 +
65835 + /*
65836 + * These are the main single-value transfer routines. They automatically
65837 +@@ -186,9 +193,12 @@ extern int __get_user_bad(void);
65838 +
65839 + #ifdef CONFIG_X86_32
65840 + #define __put_user_u64(x, addr, err) \
65841 +- asm volatile("1: movl %%eax,0(%2)\n" \
65842 +- "2: movl %%edx,4(%2)\n" \
65843 ++ asm volatile(" movw %w5,%%ds\n" \
65844 ++ "1: movl %%eax,%%ds:0(%2)\n" \
65845 ++ "2: movl %%edx,%%ds:4(%2)\n" \
65846 + "3:\n" \
65847 ++ " pushl %%ss\n" \
65848 ++ " popl %%ds\n" \
65849 + ".section .fixup,\"ax\"\n" \
65850 + "4: movl %3,%0\n" \
65851 + " jmp 3b\n" \
65852 +@@ -196,7 +206,8 @@ extern int __get_user_bad(void);
65853 + _ASM_EXTABLE(1b, 4b) \
65854 + _ASM_EXTABLE(2b, 4b) \
65855 + : "=r" (err) \
65856 +- : "A" (x), "r" (addr), "i" (-EFAULT), "0" (err))
65857 ++ : "A" (x), "r" (addr), "i" (-EFAULT), "0" (err), \
65858 ++ "r"(__USER_DS))
65859 +
65860 + #define __put_user_x8(x, ptr, __ret_pu) \
65861 + asm volatile("call __put_user_8" : "=a" (__ret_pu) \
65862 +@@ -336,6 +347,22 @@ do { \
65863 + } \
65864 + } while (0)
65865 +
65866 ++#ifdef CONFIG_X86_32
65867 ++#define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
65868 ++ asm volatile(" movw %w5,%%ds\n" \
65869 ++ "1: mov"itype" %%ds:%2,%"rtype"1\n" \
65870 ++ "2:\n" \
65871 ++ " pushl %%ss\n" \
65872 ++ " popl %%ds\n" \
65873 ++ ".section .fixup,\"ax\"\n" \
65874 ++ "3: movl %3,%0\n" \
65875 ++ " xor"itype" %"rtype"1,%"rtype"1\n" \
65876 ++ " jmp 2b\n" \
65877 ++ ".previous\n" \
65878 ++ _ASM_EXTABLE(1b, 3b) \
65879 ++ : "=r" (err), ltype (x) \
65880 ++ : "m" (__m(addr)), "i" (errret), "0" (err), "r"(__USER_DS))
65881 ++#else
65882 + #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
65883 + asm volatile("1: mov"itype" %2,%"rtype"1\n" \
65884 + "2:\n" \
65885 +@@ -347,6 +374,7 @@ do { \
65886 + _ASM_EXTABLE(1b, 3b) \
65887 + : "=r" (err), ltype(x) \
65888 + : "m" (__m(addr)), "i" (errret), "0" (err))
65889 ++#endif
65890 +
65891 + #define __put_user_nocheck(x, ptr, size) \
65892 + ({ \
65893 +@@ -373,6 +401,22 @@ struct __large_struct { unsigned long bu
65894 + * we do not write to any memory gcc knows about, so there are no
65895 + * aliasing issues.
65896 + */
65897 ++#ifdef CONFIG_X86_32
65898 ++#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
65899 ++ asm volatile(" movw %w5,%%ds\n" \
65900 ++ "1: mov"itype" %"rtype"1,%%ds:%2\n" \
65901 ++ "2:\n" \
65902 ++ " pushl %%ss\n" \
65903 ++ " popl %%ds\n" \
65904 ++ ".section .fixup,\"ax\"\n" \
65905 ++ "3: movl %3,%0\n" \
65906 ++ " jmp 2b\n" \
65907 ++ ".previous\n" \
65908 ++ _ASM_EXTABLE(1b, 3b) \
65909 ++ : "=r"(err) \
65910 ++ : ltype (x), "m" (__m(addr)), "i" (errret), "0" (err),\
65911 ++ "r"(__USER_DS))
65912 ++#else
65913 + #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
65914 + asm volatile("1: mov"itype" %"rtype"1,%2\n" \
65915 + "2:\n" \
65916 +@@ -383,6 +427,7 @@ struct __large_struct { unsigned long bu
65917 + _ASM_EXTABLE(1b, 3b) \
65918 + : "=r"(err) \
65919 + : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err))
65920 ++#endif
65921 + /**
65922 + * __get_user: - Get a simple variable from user space, with less checking.
65923 + * @x: Variable to store result.
65924 +@@ -447,6 +492,7 @@ extern struct movsl_mask {
65925 + # include "uaccess_32.h"
65926 + #else
65927 + # define ARCH_HAS_SEARCH_EXTABLE
65928 ++# define ARCH_HAS_SORT_EXTABLE
65929 + # include "uaccess_64.h"
65930 + #endif
65931 +
65932 +diff -urNp linux-2.6.27.7/include/asm-xtensa/kmap_types.h linux-2.6.27.7/include/asm-xtensa/kmap_types.h
65933 +--- linux-2.6.27.7/include/asm-xtensa/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
65934 ++++ linux-2.6.27.7/include/asm-xtensa/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
65935 +@@ -25,6 +25,7 @@ enum km_type {
65936 + KM_IRQ1,
65937 + KM_SOFTIRQ0,
65938 + KM_SOFTIRQ1,
65939 ++ KM_CLEARPAGE,
65940 + KM_TYPE_NR
65941 + };
65942 +
65943 +diff -urNp linux-2.6.27.7/include/drm/drm_pciids.h linux-2.6.27.7/include/drm/drm_pciids.h
65944 +--- linux-2.6.27.7/include/drm/drm_pciids.h 2008-11-07 12:55:34.000000000 -0500
65945 ++++ linux-2.6.27.7/include/drm/drm_pciids.h 2008-11-18 03:38:45.000000000 -0500
65946 +@@ -237,7 +237,7 @@
65947 + {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
65948 + {0x1002, 0x791e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
65949 + {0x1002, 0x791f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
65950 +- {0, 0, 0}
65951 ++ {0, 0, 0, 0, 0, 0}
65952 +
65953 + #define r128_PCI_IDS \
65954 + {0x1002, 0x4c45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
65955 +@@ -277,14 +277,14 @@
65956 + {0x1002, 0x5446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
65957 + {0x1002, 0x544C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
65958 + {0x1002, 0x5452, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
65959 +- {0, 0, 0}
65960 ++ {0, 0, 0, 0, 0, 0}
65961 +
65962 + #define mga_PCI_IDS \
65963 + {0x102b, 0x0520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \
65964 + {0x102b, 0x0521, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \
65965 + {0x102b, 0x0525, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G400}, \
65966 + {0x102b, 0x2527, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G550}, \
65967 +- {0, 0, 0}
65968 ++ {0, 0, 0, 0, 0, 0}
65969 +
65970 + #define mach64_PCI_IDS \
65971 + {0x1002, 0x4749, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
65972 +@@ -307,7 +307,7 @@
65973 + {0x1002, 0x4c53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
65974 + {0x1002, 0x4c4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
65975 + {0x1002, 0x4c4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
65976 +- {0, 0, 0}
65977 ++ {0, 0, 0, 0, 0, 0}
65978 +
65979 + #define sisdrv_PCI_IDS \
65980 + {0x1039, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
65981 +@@ -318,7 +318,7 @@
65982 + {0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
65983 + {0x18CA, 0x0040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
65984 + {0x18CA, 0x0042, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
65985 +- {0, 0, 0}
65986 ++ {0, 0, 0, 0, 0, 0}
65987 +
65988 + #define tdfx_PCI_IDS \
65989 + {0x121a, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
65990 +@@ -327,7 +327,7 @@
65991 + {0x121a, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
65992 + {0x121a, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
65993 + {0x121a, 0x000b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
65994 +- {0, 0, 0}
65995 ++ {0, 0, 0, 0, 0, 0}
65996 +
65997 + #define viadrv_PCI_IDS \
65998 + {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
65999 +@@ -339,25 +339,25 @@
66000 + {0x1106, 0x3343, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
66001 + {0x1106, 0x3230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_DX9_0}, \
66002 + {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \
66003 +- {0, 0, 0}
66004 ++ {0, 0, 0, 0, 0, 0}
66005 +
66006 + #define i810_PCI_IDS \
66007 + {0x8086, 0x7121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
66008 + {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
66009 + {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
66010 + {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
66011 +- {0, 0, 0}
66012 ++ {0, 0, 0, 0, 0, 0}
66013 +
66014 + #define i830_PCI_IDS \
66015 + {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
66016 + {0x8086, 0x2562, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
66017 + {0x8086, 0x3582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
66018 + {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
66019 +- {0, 0, 0}
66020 ++ {0, 0, 0, 0, 0, 0}
66021 +
66022 + #define gamma_PCI_IDS \
66023 + {0x3d3d, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
66024 +- {0, 0, 0}
66025 ++ {0, 0, 0, 0, 0, 0}
66026 +
66027 + #define savage_PCI_IDS \
66028 + {0x5333, 0x8a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \
66029 +@@ -383,10 +383,10 @@
66030 + {0x5333, 0x8d02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_TWISTER}, \
66031 + {0x5333, 0x8d03, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \
66032 + {0x5333, 0x8d04, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \
66033 +- {0, 0, 0}
66034 ++ {0, 0, 0, 0, 0, 0}
66035 +
66036 + #define ffb_PCI_IDS \
66037 +- {0, 0, 0}
66038 ++ {0, 0, 0, 0, 0, 0}
66039 +
66040 + #define i915_PCI_IDS \
66041 + {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
66042 +@@ -412,4 +412,4 @@
66043 + {0x8086, 0x2e02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
66044 + {0x8086, 0x2e12, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
66045 + {0x8086, 0x2e22, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
66046 +- {0, 0, 0}
66047 ++ {0, 0, 0, 0, 0, 0}
66048 +diff -urNp linux-2.6.27.7/include/linux/a.out.h linux-2.6.27.7/include/linux/a.out.h
66049 +--- linux-2.6.27.7/include/linux/a.out.h 2008-11-07 12:55:34.000000000 -0500
66050 ++++ linux-2.6.27.7/include/linux/a.out.h 2008-11-18 03:38:45.000000000 -0500
66051 +@@ -39,6 +39,14 @@ enum machine_type {
66052 + M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
66053 + };
66054 +
66055 ++/* Constants for the N_FLAGS field */
66056 ++#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
66057 ++#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
66058 ++#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
66059 ++#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
66060 ++/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
66061 ++#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
66062 ++
66063 + #if !defined (N_MAGIC)
66064 + #define N_MAGIC(exec) ((exec).a_info & 0xffff)
66065 + #endif
66066 +diff -urNp linux-2.6.27.7/include/linux/cache.h linux-2.6.27.7/include/linux/cache.h
66067 +--- linux-2.6.27.7/include/linux/cache.h 2008-11-07 12:55:34.000000000 -0500
66068 ++++ linux-2.6.27.7/include/linux/cache.h 2008-11-18 03:38:45.000000000 -0500
66069 +@@ -16,6 +16,10 @@
66070 + #define __read_mostly
66071 + #endif
66072 +
66073 ++#ifndef __read_only
66074 ++#define __read_only __read_mostly
66075 ++#endif
66076 ++
66077 + #ifndef ____cacheline_aligned
66078 + #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
66079 + #endif
66080 +diff -urNp linux-2.6.27.7/include/linux/capability.h linux-2.6.27.7/include/linux/capability.h
66081 +--- linux-2.6.27.7/include/linux/capability.h 2008-11-07 12:55:34.000000000 -0500
66082 ++++ linux-2.6.27.7/include/linux/capability.h 2008-11-18 03:38:45.000000000 -0500
66083 +@@ -516,6 +516,7 @@ kernel_cap_t cap_set_effective(const ker
66084 + #define has_capability(t, cap) (security_capable((t), (cap)) == 0)
66085 +
66086 + extern int capable(int cap);
66087 ++int capable_nolog(int cap);
66088 +
66089 + #endif /* __KERNEL__ */
66090 +
66091 +diff -urNp linux-2.6.27.7/include/linux/cpumask.h linux-2.6.27.7/include/linux/cpumask.h
66092 +--- linux-2.6.27.7/include/linux/cpumask.h 2008-11-07 12:55:34.000000000 -0500
66093 ++++ linux-2.6.27.7/include/linux/cpumask.h 2008-11-18 03:38:45.000000000 -0500
66094 +@@ -139,7 +139,6 @@
66095 + #include <linux/bitmap.h>
66096 +
66097 + typedef struct { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;
66098 +-extern cpumask_t _unused_cpumask_arg_;
66099 +
66100 + #define cpu_set(cpu, dst) __cpu_set((cpu), &(dst))
66101 + static inline void __cpu_set(int cpu, volatile cpumask_t *dstp)
66102 +diff -urNp linux-2.6.27.7/include/linux/elf.h linux-2.6.27.7/include/linux/elf.h
66103 +--- linux-2.6.27.7/include/linux/elf.h 2008-11-07 12:55:34.000000000 -0500
66104 ++++ linux-2.6.27.7/include/linux/elf.h 2008-11-18 03:38:45.000000000 -0500
66105 +@@ -50,6 +50,16 @@ typedef __s64 Elf64_Sxword;
66106 +
66107 + #define PT_GNU_STACK (PT_LOOS + 0x474e551)
66108 +
66109 ++#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
66110 ++
66111 ++/* Constants for the e_flags field */
66112 ++#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
66113 ++#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
66114 ++#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
66115 ++#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
66116 ++/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
66117 ++#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
66118 ++
66119 + /* These constants define the different elf file types */
66120 + #define ET_NONE 0
66121 + #define ET_REL 1
66122 +@@ -84,6 +94,8 @@ typedef __s64 Elf64_Sxword;
66123 + #define DT_DEBUG 21
66124 + #define DT_TEXTREL 22
66125 + #define DT_JMPREL 23
66126 ++#define DT_FLAGS 30
66127 ++ #define DF_TEXTREL 0x00000004
66128 + #define DT_ENCODING 32
66129 + #define OLD_DT_LOOS 0x60000000
66130 + #define DT_LOOS 0x6000000d
66131 +@@ -230,6 +242,19 @@ typedef struct elf64_hdr {
66132 + #define PF_W 0x2
66133 + #define PF_X 0x1
66134 +
66135 ++#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */
66136 ++#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */
66137 ++#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */
66138 ++#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */
66139 ++#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */
66140 ++#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */
66141 ++/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */
66142 ++/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */
66143 ++#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */
66144 ++#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */
66145 ++#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */
66146 ++#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */
66147 ++
66148 + typedef struct elf32_phdr{
66149 + Elf32_Word p_type;
66150 + Elf32_Off p_offset;
66151 +@@ -322,6 +347,8 @@ typedef struct elf64_shdr {
66152 + #define EI_OSABI 7
66153 + #define EI_PAD 8
66154 +
66155 ++#define EI_PAX 14
66156 ++
66157 + #define ELFMAG0 0x7f /* EI_MAG */
66158 + #define ELFMAG1 'E'
66159 + #define ELFMAG2 'L'
66160 +@@ -383,6 +410,7 @@ extern Elf32_Dyn _DYNAMIC [];
66161 + #define elf_phdr elf32_phdr
66162 + #define elf_note elf32_note
66163 + #define elf_addr_t Elf32_Off
66164 ++#define elf_dyn Elf32_Dyn
66165 +
66166 + #else
66167 +
66168 +@@ -391,6 +419,7 @@ extern Elf64_Dyn _DYNAMIC [];
66169 + #define elf_phdr elf64_phdr
66170 + #define elf_note elf64_note
66171 + #define elf_addr_t Elf64_Off
66172 ++#define elf_dyn Elf64_Dyn
66173 +
66174 + #endif
66175 +
66176 +diff -urNp linux-2.6.27.7/include/linux/gracl.h linux-2.6.27.7/include/linux/gracl.h
66177 +--- linux-2.6.27.7/include/linux/gracl.h 1969-12-31 19:00:00.000000000 -0500
66178 ++++ linux-2.6.27.7/include/linux/gracl.h 2008-11-18 03:38:45.000000000 -0500
66179 +@@ -0,0 +1,318 @@
66180 ++#ifndef GR_ACL_H
66181 ++#define GR_ACL_H
66182 ++
66183 ++#include <linux/grdefs.h>
66184 ++#include <linux/resource.h>
66185 ++#include <linux/capability.h>
66186 ++#include <linux/dcache.h>
66187 ++#include <asm/resource.h>
66188 ++
66189 ++/* Major status information */
66190 ++
66191 ++#define GR_VERSION "grsecurity 2.1.12"
66192 ++#define GRSECURITY_VERSION 0x2112
66193 ++
66194 ++enum {
66195 ++
66196 ++ SHUTDOWN = 0,
66197 ++ ENABLE = 1,
66198 ++ SPROLE = 2,
66199 ++ RELOAD = 3,
66200 ++ SEGVMOD = 4,
66201 ++ STATUS = 5,
66202 ++ UNSPROLE = 6,
66203 ++ PASSSET = 7,
66204 ++ SPROLEPAM = 8
66205 ++};
66206 ++
66207 ++/* Password setup definitions
66208 ++ * kernel/grhash.c */
66209 ++enum {
66210 ++ GR_PW_LEN = 128,
66211 ++ GR_SALT_LEN = 16,
66212 ++ GR_SHA_LEN = 32,
66213 ++};
66214 ++
66215 ++enum {
66216 ++ GR_SPROLE_LEN = 64,
66217 ++};
66218 ++
66219 ++#define GR_NLIMITS (RLIMIT_LOCKS + 2)
66220 ++
66221 ++/* Begin Data Structures */
66222 ++
66223 ++struct sprole_pw {
66224 ++ unsigned char *rolename;
66225 ++ unsigned char salt[GR_SALT_LEN];
66226 ++ unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
66227 ++};
66228 ++
66229 ++struct name_entry {
66230 ++ __u32 key;
66231 ++ ino_t inode;
66232 ++ dev_t device;
66233 ++ char *name;
66234 ++ __u16 len;
66235 ++ __u8 deleted;
66236 ++ struct name_entry *prev;
66237 ++ struct name_entry *next;
66238 ++};
66239 ++
66240 ++struct inodev_entry {
66241 ++ struct name_entry *nentry;
66242 ++ struct inodev_entry *prev;
66243 ++ struct inodev_entry *next;
66244 ++};
66245 ++
66246 ++struct acl_role_db {
66247 ++ struct acl_role_label **r_hash;
66248 ++ __u32 r_size;
66249 ++};
66250 ++
66251 ++struct inodev_db {
66252 ++ struct inodev_entry **i_hash;
66253 ++ __u32 i_size;
66254 ++};
66255 ++
66256 ++struct name_db {
66257 ++ struct name_entry **n_hash;
66258 ++ __u32 n_size;
66259 ++};
66260 ++
66261 ++struct crash_uid {
66262 ++ uid_t uid;
66263 ++ unsigned long expires;
66264 ++};
66265 ++
66266 ++struct gr_hash_struct {
66267 ++ void **table;
66268 ++ void **nametable;
66269 ++ void *first;
66270 ++ __u32 table_size;
66271 ++ __u32 used_size;
66272 ++ int type;
66273 ++};
66274 ++
66275 ++/* Userspace Grsecurity ACL data structures */
66276 ++
66277 ++struct acl_subject_label {
66278 ++ char *filename;
66279 ++ ino_t inode;
66280 ++ dev_t device;
66281 ++ __u32 mode;
66282 ++ kernel_cap_t cap_mask;
66283 ++ kernel_cap_t cap_lower;
66284 ++
66285 ++ struct rlimit res[GR_NLIMITS];
66286 ++ __u16 resmask;
66287 ++
66288 ++ __u8 user_trans_type;
66289 ++ __u8 group_trans_type;
66290 ++ uid_t *user_transitions;
66291 ++ gid_t *group_transitions;
66292 ++ __u16 user_trans_num;
66293 ++ __u16 group_trans_num;
66294 ++
66295 ++ __u32 ip_proto[8];
66296 ++ __u32 ip_type;
66297 ++ struct acl_ip_label **ips;
66298 ++ __u32 ip_num;
66299 ++
66300 ++ __u32 crashes;
66301 ++ unsigned long expires;
66302 ++
66303 ++ struct acl_subject_label *parent_subject;
66304 ++ struct gr_hash_struct *hash;
66305 ++ struct acl_subject_label *prev;
66306 ++ struct acl_subject_label *next;
66307 ++
66308 ++ struct acl_object_label **obj_hash;
66309 ++ __u32 obj_hash_size;
66310 ++ __u16 pax_flags;
66311 ++};
66312 ++
66313 ++struct role_allowed_ip {
66314 ++ __u32 addr;
66315 ++ __u32 netmask;
66316 ++
66317 ++ struct role_allowed_ip *prev;
66318 ++ struct role_allowed_ip *next;
66319 ++};
66320 ++
66321 ++struct role_transition {
66322 ++ char *rolename;
66323 ++
66324 ++ struct role_transition *prev;
66325 ++ struct role_transition *next;
66326 ++};
66327 ++
66328 ++struct acl_role_label {
66329 ++ char *rolename;
66330 ++ uid_t uidgid;
66331 ++ __u16 roletype;
66332 ++
66333 ++ __u16 auth_attempts;
66334 ++ unsigned long expires;
66335 ++
66336 ++ struct acl_subject_label *root_label;
66337 ++ struct gr_hash_struct *hash;
66338 ++
66339 ++ struct acl_role_label *prev;
66340 ++ struct acl_role_label *next;
66341 ++
66342 ++ struct role_transition *transitions;
66343 ++ struct role_allowed_ip *allowed_ips;
66344 ++ uid_t *domain_children;
66345 ++ __u16 domain_child_num;
66346 ++
66347 ++ struct acl_subject_label **subj_hash;
66348 ++ __u32 subj_hash_size;
66349 ++};
66350 ++
66351 ++struct user_acl_role_db {
66352 ++ struct acl_role_label **r_table;
66353 ++ __u32 num_pointers; /* Number of allocations to track */
66354 ++ __u32 num_roles; /* Number of roles */
66355 ++ __u32 num_domain_children; /* Number of domain children */
66356 ++ __u32 num_subjects; /* Number of subjects */
66357 ++ __u32 num_objects; /* Number of objects */
66358 ++};
66359 ++
66360 ++struct acl_object_label {
66361 ++ char *filename;
66362 ++ ino_t inode;
66363 ++ dev_t device;
66364 ++ __u32 mode;
66365 ++
66366 ++ struct acl_subject_label *nested;
66367 ++ struct acl_object_label *globbed;
66368 ++
66369 ++ /* next two structures not used */
66370 ++
66371 ++ struct acl_object_label *prev;
66372 ++ struct acl_object_label *next;
66373 ++};
66374 ++
66375 ++struct acl_ip_label {
66376 ++ char *iface;
66377 ++ __u32 addr;
66378 ++ __u32 netmask;
66379 ++ __u16 low, high;
66380 ++ __u8 mode;
66381 ++ __u32 type;
66382 ++ __u32 proto[8];
66383 ++
66384 ++ /* next two structures not used */
66385 ++
66386 ++ struct acl_ip_label *prev;
66387 ++ struct acl_ip_label *next;
66388 ++};
66389 ++
66390 ++struct gr_arg {
66391 ++ struct user_acl_role_db role_db;
66392 ++ unsigned char pw[GR_PW_LEN];
66393 ++ unsigned char salt[GR_SALT_LEN];
66394 ++ unsigned char sum[GR_SHA_LEN];
66395 ++ unsigned char sp_role[GR_SPROLE_LEN];
66396 ++ struct sprole_pw *sprole_pws;
66397 ++ dev_t segv_device;
66398 ++ ino_t segv_inode;
66399 ++ uid_t segv_uid;
66400 ++ __u16 num_sprole_pws;
66401 ++ __u16 mode;
66402 ++};
66403 ++
66404 ++struct gr_arg_wrapper {
66405 ++ struct gr_arg *arg;
66406 ++ __u32 version;
66407 ++ __u32 size;
66408 ++};
66409 ++
66410 ++struct subject_map {
66411 ++ struct acl_subject_label *user;
66412 ++ struct acl_subject_label *kernel;
66413 ++ struct subject_map *prev;
66414 ++ struct subject_map *next;
66415 ++};
66416 ++
66417 ++struct acl_subj_map_db {
66418 ++ struct subject_map **s_hash;
66419 ++ __u32 s_size;
66420 ++};
66421 ++
66422 ++/* End Data Structures Section */
66423 ++
66424 ++/* Hash functions generated by empirical testing by Brad Spengler
66425 ++ Makes good use of the low bits of the inode. Generally 0-1 times
66426 ++ in loop for successful match. 0-3 for unsuccessful match.
66427 ++ Shift/add algorithm with modulus of table size and an XOR*/
66428 ++
66429 ++static __inline__ unsigned int
66430 ++rhash(const uid_t uid, const __u16 type, const unsigned int sz)
66431 ++{
66432 ++ return (((uid << type) + (uid ^ type)) % sz);
66433 ++}
66434 ++
66435 ++ static __inline__ unsigned int
66436 ++shash(const struct acl_subject_label *userp, const unsigned int sz)
66437 ++{
66438 ++ return ((const unsigned long)userp % sz);
66439 ++}
66440 ++
66441 ++static __inline__ unsigned int
66442 ++fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
66443 ++{
66444 ++ return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
66445 ++}
66446 ++
66447 ++static __inline__ unsigned int
66448 ++nhash(const char *name, const __u16 len, const unsigned int sz)
66449 ++{
66450 ++ return full_name_hash(name, len) % sz;
66451 ++}
66452 ++
66453 ++#define FOR_EACH_ROLE_START(role,iter) \
66454 ++ role = NULL; \
66455 ++ iter = 0; \
66456 ++ while (iter < acl_role_set.r_size) { \
66457 ++ if (role == NULL) \
66458 ++ role = acl_role_set.r_hash[iter]; \
66459 ++ if (role == NULL) { \
66460 ++ iter++; \
66461 ++ continue; \
66462 ++ }
66463 ++
66464 ++#define FOR_EACH_ROLE_END(role,iter) \
66465 ++ role = role->next; \
66466 ++ if (role == NULL) \
66467 ++ iter++; \
66468 ++ }
66469 ++
66470 ++#define FOR_EACH_SUBJECT_START(role,subj,iter) \
66471 ++ subj = NULL; \
66472 ++ iter = 0; \
66473 ++ while (iter < role->subj_hash_size) { \
66474 ++ if (subj == NULL) \
66475 ++ subj = role->subj_hash[iter]; \
66476 ++ if (subj == NULL) { \
66477 ++ iter++; \
66478 ++ continue; \
66479 ++ }
66480 ++
66481 ++#define FOR_EACH_SUBJECT_END(subj,iter) \
66482 ++ subj = subj->next; \
66483 ++ if (subj == NULL) \
66484 ++ iter++; \
66485 ++ }
66486 ++
66487 ++
66488 ++#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
66489 ++ subj = role->hash->first; \
66490 ++ while (subj != NULL) {
66491 ++
66492 ++#define FOR_EACH_NESTED_SUBJECT_END(subj) \
66493 ++ subj = subj->next; \
66494 ++ }
66495 ++
66496 ++#endif
66497 ++
66498 +diff -urNp linux-2.6.27.7/include/linux/gralloc.h linux-2.6.27.7/include/linux/gralloc.h
66499 +--- linux-2.6.27.7/include/linux/gralloc.h 1969-12-31 19:00:00.000000000 -0500
66500 ++++ linux-2.6.27.7/include/linux/gralloc.h 2008-11-18 03:38:45.000000000 -0500
66501 +@@ -0,0 +1,8 @@
66502 ++#ifndef __GRALLOC_H
66503 ++#define __GRALLOC_H
66504 ++
66505 ++void acl_free_all(void);
66506 ++int acl_alloc_stack_init(unsigned long size);
66507 ++void *acl_alloc(unsigned long len);
66508 ++
66509 ++#endif
66510 +diff -urNp linux-2.6.27.7/include/linux/grdefs.h linux-2.6.27.7/include/linux/grdefs.h
66511 +--- linux-2.6.27.7/include/linux/grdefs.h 1969-12-31 19:00:00.000000000 -0500
66512 ++++ linux-2.6.27.7/include/linux/grdefs.h 2008-11-18 03:38:45.000000000 -0500
66513 +@@ -0,0 +1,131 @@
66514 ++#ifndef GRDEFS_H
66515 ++#define GRDEFS_H
66516 ++
66517 ++/* Begin grsecurity status declarations */
66518 ++
66519 ++enum {
66520 ++ GR_READY = 0x01,
66521 ++ GR_STATUS_INIT = 0x00 // disabled state
66522 ++};
66523 ++
66524 ++/* Begin ACL declarations */
66525 ++
66526 ++/* Role flags */
66527 ++
66528 ++enum {
66529 ++ GR_ROLE_USER = 0x0001,
66530 ++ GR_ROLE_GROUP = 0x0002,
66531 ++ GR_ROLE_DEFAULT = 0x0004,
66532 ++ GR_ROLE_SPECIAL = 0x0008,
66533 ++ GR_ROLE_AUTH = 0x0010,
66534 ++ GR_ROLE_NOPW = 0x0020,
66535 ++ GR_ROLE_GOD = 0x0040,
66536 ++ GR_ROLE_LEARN = 0x0080,
66537 ++ GR_ROLE_TPE = 0x0100,
66538 ++ GR_ROLE_DOMAIN = 0x0200,
66539 ++ GR_ROLE_PAM = 0x0400
66540 ++};
66541 ++
66542 ++/* ACL Subject and Object mode flags */
66543 ++enum {
66544 ++ GR_DELETED = 0x80000000
66545 ++};
66546 ++
66547 ++/* ACL Object-only mode flags */
66548 ++enum {
66549 ++ GR_READ = 0x00000001,
66550 ++ GR_APPEND = 0x00000002,
66551 ++ GR_WRITE = 0x00000004,
66552 ++ GR_EXEC = 0x00000008,
66553 ++ GR_FIND = 0x00000010,
66554 ++ GR_INHERIT = 0x00000020,
66555 ++ GR_SETID = 0x00000040,
66556 ++ GR_CREATE = 0x00000080,
66557 ++ GR_DELETE = 0x00000100,
66558 ++ GR_LINK = 0x00000200,
66559 ++ GR_AUDIT_READ = 0x00000400,
66560 ++ GR_AUDIT_APPEND = 0x00000800,
66561 ++ GR_AUDIT_WRITE = 0x00001000,
66562 ++ GR_AUDIT_EXEC = 0x00002000,
66563 ++ GR_AUDIT_FIND = 0x00004000,
66564 ++ GR_AUDIT_INHERIT= 0x00008000,
66565 ++ GR_AUDIT_SETID = 0x00010000,
66566 ++ GR_AUDIT_CREATE = 0x00020000,
66567 ++ GR_AUDIT_DELETE = 0x00040000,
66568 ++ GR_AUDIT_LINK = 0x00080000,
66569 ++ GR_PTRACERD = 0x00100000,
66570 ++ GR_NOPTRACE = 0x00200000,
66571 ++ GR_SUPPRESS = 0x00400000,
66572 ++ GR_NOLEARN = 0x00800000
66573 ++};
66574 ++
66575 ++#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
66576 ++ GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
66577 ++ GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
66578 ++
66579 ++/* ACL subject-only mode flags */
66580 ++enum {
66581 ++ GR_KILL = 0x00000001,
66582 ++ GR_VIEW = 0x00000002,
66583 ++ GR_PROTECTED = 0x00000004,
66584 ++ GR_LEARN = 0x00000008,
66585 ++ GR_OVERRIDE = 0x00000010,
66586 ++ /* just a placeholder, this mode is only used in userspace */
66587 ++ GR_DUMMY = 0x00000020,
66588 ++ GR_PROTSHM = 0x00000040,
66589 ++ GR_KILLPROC = 0x00000080,
66590 ++ GR_KILLIPPROC = 0x00000100,
66591 ++ /* just a placeholder, this mode is only used in userspace */
66592 ++ GR_NOTROJAN = 0x00000200,
66593 ++ GR_PROTPROCFD = 0x00000400,
66594 ++ GR_PROCACCT = 0x00000800,
66595 ++ GR_RELAXPTRACE = 0x00001000,
66596 ++ GR_NESTED = 0x00002000,
66597 ++ GR_INHERITLEARN = 0x00004000,
66598 ++ GR_PROCFIND = 0x00008000,
66599 ++ GR_POVERRIDE = 0x00010000,
66600 ++ GR_KERNELAUTH = 0x00020000,
66601 ++};
66602 ++
66603 ++enum {
66604 ++ GR_PAX_ENABLE_SEGMEXEC = 0x0001,
66605 ++ GR_PAX_ENABLE_PAGEEXEC = 0x0002,
66606 ++ GR_PAX_ENABLE_MPROTECT = 0x0004,
66607 ++ GR_PAX_ENABLE_RANDMMAP = 0x0008,
66608 ++ GR_PAX_ENABLE_EMUTRAMP = 0x0010,
66609 ++ GR_PAX_DISABLE_SEGMEXEC = 0x0100,
66610 ++ GR_PAX_DISABLE_PAGEEXEC = 0x0200,
66611 ++ GR_PAX_DISABLE_MPROTECT = 0x0400,
66612 ++ GR_PAX_DISABLE_RANDMMAP = 0x0800,
66613 ++ GR_PAX_DISABLE_EMUTRAMP = 0x1000,
66614 ++};
66615 ++
66616 ++enum {
66617 ++ GR_ID_USER = 0x01,
66618 ++ GR_ID_GROUP = 0x02,
66619 ++};
66620 ++
66621 ++enum {
66622 ++ GR_ID_ALLOW = 0x01,
66623 ++ GR_ID_DENY = 0x02,
66624 ++};
66625 ++
66626 ++#define GR_CRASH_RES 11
66627 ++#define GR_UIDTABLE_MAX 500
66628 ++
66629 ++/* begin resource learning section */
66630 ++enum {
66631 ++ GR_RLIM_CPU_BUMP = 60,
66632 ++ GR_RLIM_FSIZE_BUMP = 50000,
66633 ++ GR_RLIM_DATA_BUMP = 10000,
66634 ++ GR_RLIM_STACK_BUMP = 1000,
66635 ++ GR_RLIM_CORE_BUMP = 10000,
66636 ++ GR_RLIM_RSS_BUMP = 500000,
66637 ++ GR_RLIM_NPROC_BUMP = 1,
66638 ++ GR_RLIM_NOFILE_BUMP = 5,
66639 ++ GR_RLIM_MEMLOCK_BUMP = 50000,
66640 ++ GR_RLIM_AS_BUMP = 500000,
66641 ++ GR_RLIM_LOCKS_BUMP = 2
66642 ++};
66643 ++
66644 ++#endif
66645 +diff -urNp linux-2.6.27.7/include/linux/grinternal.h linux-2.6.27.7/include/linux/grinternal.h
66646 +--- linux-2.6.27.7/include/linux/grinternal.h 1969-12-31 19:00:00.000000000 -0500
66647 ++++ linux-2.6.27.7/include/linux/grinternal.h 2008-11-18 03:38:45.000000000 -0500
66648 +@@ -0,0 +1,210 @@
66649 ++#ifndef __GRINTERNAL_H
66650 ++#define __GRINTERNAL_H
66651 ++
66652 ++#ifdef CONFIG_GRKERNSEC
66653 ++
66654 ++#include <linux/fs.h>
66655 ++#include <linux/gracl.h>
66656 ++#include <linux/grdefs.h>
66657 ++#include <linux/grmsg.h>
66658 ++
66659 ++void gr_add_learn_entry(const char *fmt, ...);
66660 ++__u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
66661 ++ const struct vfsmount *mnt);
66662 ++__u32 gr_check_create(const struct dentry *new_dentry,
66663 ++ const struct dentry *parent,
66664 ++ const struct vfsmount *mnt, const __u32 mode);
66665 ++int gr_check_protected_task(const struct task_struct *task);
66666 ++__u32 to_gr_audit(const __u32 reqmode);
66667 ++int gr_set_acls(const int type);
66668 ++
66669 ++int gr_acl_is_enabled(void);
66670 ++char gr_roletype_to_char(void);
66671 ++
66672 ++void gr_handle_alertkill(struct task_struct *task);
66673 ++char *gr_to_filename(const struct dentry *dentry,
66674 ++ const struct vfsmount *mnt);
66675 ++char *gr_to_filename1(const struct dentry *dentry,
66676 ++ const struct vfsmount *mnt);
66677 ++char *gr_to_filename2(const struct dentry *dentry,
66678 ++ const struct vfsmount *mnt);
66679 ++char *gr_to_filename3(const struct dentry *dentry,
66680 ++ const struct vfsmount *mnt);
66681 ++
66682 ++extern int grsec_enable_link;
66683 ++extern int grsec_enable_fifo;
66684 ++extern int grsec_enable_execve;
66685 ++extern int grsec_enable_shm;
66686 ++extern int grsec_enable_execlog;
66687 ++extern int grsec_enable_signal;
66688 ++extern int grsec_enable_forkfail;
66689 ++extern int grsec_enable_time;
66690 ++extern int grsec_enable_chroot_shmat;
66691 ++extern int grsec_enable_chroot_findtask;
66692 ++extern int grsec_enable_chroot_mount;
66693 ++extern int grsec_enable_chroot_double;
66694 ++extern int grsec_enable_chroot_pivot;
66695 ++extern int grsec_enable_chroot_chdir;
66696 ++extern int grsec_enable_chroot_chmod;
66697 ++extern int grsec_enable_chroot_mknod;
66698 ++extern int grsec_enable_chroot_fchdir;
66699 ++extern int grsec_enable_chroot_nice;
66700 ++extern int grsec_enable_chroot_execlog;
66701 ++extern int grsec_enable_chroot_caps;
66702 ++extern int grsec_enable_chroot_sysctl;
66703 ++extern int grsec_enable_chroot_unix;
66704 ++extern int grsec_enable_tpe;
66705 ++extern int grsec_tpe_gid;
66706 ++extern int grsec_enable_tpe_all;
66707 ++extern int grsec_enable_sidcaps;
66708 ++extern int grsec_enable_socket_all;
66709 ++extern int grsec_socket_all_gid;
66710 ++extern int grsec_enable_socket_client;
66711 ++extern int grsec_socket_client_gid;
66712 ++extern int grsec_enable_socket_server;
66713 ++extern int grsec_socket_server_gid;
66714 ++extern int grsec_audit_gid;
66715 ++extern int grsec_enable_group;
66716 ++extern int grsec_enable_audit_ipc;
66717 ++extern int grsec_enable_audit_textrel;
66718 ++extern int grsec_enable_mount;
66719 ++extern int grsec_enable_chdir;
66720 ++extern int grsec_resource_logging;
66721 ++extern int grsec_lock;
66722 ++
66723 ++extern spinlock_t grsec_alert_lock;
66724 ++extern unsigned long grsec_alert_wtime;
66725 ++extern unsigned long grsec_alert_fyet;
66726 ++
66727 ++extern spinlock_t grsec_audit_lock;
66728 ++
66729 ++extern rwlock_t grsec_exec_file_lock;
66730 ++
66731 ++#define gr_task_fullpath(tsk) (tsk->exec_file ? \
66732 ++ gr_to_filename2(tsk->exec_file->f_path.dentry, \
66733 ++ tsk->exec_file->f_vfsmnt) : "/")
66734 ++
66735 ++#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
66736 ++ gr_to_filename3(tsk->parent->exec_file->f_path.dentry, \
66737 ++ tsk->parent->exec_file->f_vfsmnt) : "/")
66738 ++
66739 ++#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
66740 ++ gr_to_filename(tsk->exec_file->f_path.dentry, \
66741 ++ tsk->exec_file->f_vfsmnt) : "/")
66742 ++
66743 ++#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
66744 ++ gr_to_filename1(tsk->parent->exec_file->f_path.dentry, \
66745 ++ tsk->parent->exec_file->f_vfsmnt) : "/")
66746 ++
66747 ++#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
66748 ++ ((tsk_a->fs->root.dentry->d_inode->i_sb->s_dev != \
66749 ++ tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_sb->s_dev) || \
66750 ++ (tsk_a->fs->root.dentry->d_inode->i_ino != \
66751 ++ tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_ino)))
66752 ++
66753 ++#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
66754 ++ (tsk_a->fs->root.dentry->d_inode->i_sb->s_dev == \
66755 ++ tsk_b->fs->root.dentry->d_inode->i_sb->s_dev) && \
66756 ++ (tsk_a->fs->root.dentry->d_inode->i_ino == \
66757 ++ tsk_b->fs->root.dentry->d_inode->i_ino))
66758 ++
66759 ++#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
66760 ++ task->pid, task->uid, \
66761 ++ task->euid, task->gid, task->egid, \
66762 ++ gr_parent_task_fullpath(task), \
66763 ++ task->parent->comm, task->parent->pid, \
66764 ++ task->parent->uid, task->parent->euid, \
66765 ++ task->parent->gid, task->parent->egid
66766 ++
66767 ++#define GR_CHROOT_CAPS {{ \
66768 ++ CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
66769 ++ CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
66770 ++ CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
66771 ++ CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
66772 ++ CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
66773 ++ CAP_TO_MASK(CAP_IPC_OWNER) , 0 }}
66774 ++
66775 ++#define security_learn(normal_msg,args...) \
66776 ++({ \
66777 ++ read_lock(&grsec_exec_file_lock); \
66778 ++ gr_add_learn_entry(normal_msg "\n", ## args); \
66779 ++ read_unlock(&grsec_exec_file_lock); \
66780 ++})
66781 ++
66782 ++enum {
66783 ++ GR_DO_AUDIT,
66784 ++ GR_DONT_AUDIT,
66785 ++ GR_DONT_AUDIT_GOOD
66786 ++};
66787 ++
66788 ++enum {
66789 ++ GR_TTYSNIFF,
66790 ++ GR_RBAC,
66791 ++ GR_RBAC_STR,
66792 ++ GR_STR_RBAC,
66793 ++ GR_RBAC_MODE2,
66794 ++ GR_RBAC_MODE3,
66795 ++ GR_FILENAME,
66796 ++ GR_SYSCTL_HIDDEN,
66797 ++ GR_NOARGS,
66798 ++ GR_ONE_INT,
66799 ++ GR_ONE_INT_TWO_STR,
66800 ++ GR_ONE_STR,
66801 ++ GR_STR_INT,
66802 ++ GR_TWO_INT,
66803 ++ GR_THREE_INT,
66804 ++ GR_FIVE_INT_TWO_STR,
66805 ++ GR_TWO_STR,
66806 ++ GR_THREE_STR,
66807 ++ GR_FOUR_STR,
66808 ++ GR_STR_FILENAME,
66809 ++ GR_FILENAME_STR,
66810 ++ GR_FILENAME_TWO_INT,
66811 ++ GR_FILENAME_TWO_INT_STR,
66812 ++ GR_TEXTREL,
66813 ++ GR_PTRACE,
66814 ++ GR_RESOURCE,
66815 ++ GR_CAP,
66816 ++ GR_SIG,
66817 ++ GR_CRASH1,
66818 ++ GR_CRASH2,
66819 ++ GR_PSACCT
66820 ++};
66821 ++
66822 ++#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str)
66823 ++#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
66824 ++#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
66825 ++#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
66826 ++#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
66827 ++#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
66828 ++#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)
66829 ++#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
66830 ++#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
66831 ++#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
66832 ++#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
66833 ++#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
66834 ++#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
66835 ++#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
66836 ++#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
66837 ++#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)
66838 ++#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
66839 ++#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
66840 ++#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
66841 ++#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
66842 ++#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
66843 ++#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
66844 ++#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)
66845 ++#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
66846 ++#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
66847 ++#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
66848 ++#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
66849 ++#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
66850 ++#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
66851 ++#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
66852 ++#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)
66853 ++
66854 ++void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
66855 ++
66856 ++#endif
66857 ++
66858 ++#endif
66859 +diff -urNp linux-2.6.27.7/include/linux/grmsg.h linux-2.6.27.7/include/linux/grmsg.h
66860 +--- linux-2.6.27.7/include/linux/grmsg.h 1969-12-31 19:00:00.000000000 -0500
66861 ++++ linux-2.6.27.7/include/linux/grmsg.h 2008-11-18 03:38:45.000000000 -0500
66862 +@@ -0,0 +1,108 @@
66863 ++#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"
66864 ++#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"
66865 ++#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
66866 ++#define GR_STOPMOD_MSG "denied modification of module state by "
66867 ++#define GR_IOPERM_MSG "denied use of ioperm() by "
66868 ++#define GR_IOPL_MSG "denied use of iopl() by "
66869 ++#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
66870 ++#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
66871 ++#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
66872 ++#define GR_KMEM_MSG "denied write of /dev/kmem by "
66873 ++#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
66874 ++#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
66875 ++#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
66876 ++#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
66877 ++#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"
66878 ++#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"
66879 ++#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
66880 ++#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
66881 ++#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
66882 ++#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
66883 ++#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
66884 ++#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
66885 ++#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
66886 ++#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
66887 ++#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
66888 ++#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
66889 ++#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
66890 ++#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
66891 ++#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
66892 ++#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
66893 ++#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
66894 ++#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
66895 ++#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
66896 ++#define GR_NPROC_MSG "denied overstep of process limit by "
66897 ++#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
66898 ++#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
66899 ++#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
66900 ++#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
66901 ++#define GR_MOUNT_CHROOT_MSG "denied mount of %.256s as %.930s from chroot by "
66902 ++#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
66903 ++#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
66904 ++#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
66905 ++#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
66906 ++#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
66907 ++#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
66908 ++#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
66909 ++#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
66910 ++#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
66911 ++#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
66912 ++#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
66913 ++#define GR_INITF_ACL_MSG "init_variables() failed %s by "
66914 ++#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"
66915 ++#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
66916 ++#define GR_SHUTS_ACL_MSG "shutdown auth success for "
66917 ++#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
66918 ++#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
66919 ++#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
66920 ++#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
66921 ++#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
66922 ++#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
66923 ++#define GR_ENABLEF_ACL_MSG "unable to load %s for "
66924 ++#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
66925 ++#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
66926 ++#define GR_RELOADF_ACL_MSG "failed reload of %s for "
66927 ++#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
66928 ++#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
66929 ++#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
66930 ++#define GR_SPROLEF_ACL_MSG "special role %s failure for "
66931 ++#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
66932 ++#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
66933 ++#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
66934 ++#define GR_INVMODE_ACL_MSG "invalid mode %d by "
66935 ++#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
66936 ++#define GR_FAILFORK_MSG "failed fork with errno %d by "
66937 ++#define GR_NICE_CHROOT_MSG "denied priority change by "
66938 ++#define GR_UNISIGLOG_MSG "signal %d sent to "
66939 ++#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
66940 ++#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
66941 ++#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
66942 ++#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
66943 ++#define GR_TIME_MSG "time set by "
66944 ++#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
66945 ++#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
66946 ++#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
66947 ++#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
66948 ++#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
66949 ++#define GR_BIND_MSG "denied bind() by "
66950 ++#define GR_CONNECT_MSG "denied connect() by "
66951 ++#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
66952 ++#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
66953 ++#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"
66954 ++#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
66955 ++#define GR_CAP_ACL_MSG "use of %s denied for "
66956 ++#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
66957 ++#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
66958 ++#define GR_REMOUNT_AUDIT_MSG "remount of %.256s by "
66959 ++#define GR_UNMOUNT_AUDIT_MSG "unmount of %.256s by "
66960 ++#define GR_MOUNT_AUDIT_MSG "mount of %.256s to %.256s by "
66961 ++#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
66962 ++#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
66963 ++#define GR_MSGQ_AUDIT_MSG "message queue created by "
66964 ++#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
66965 ++#define GR_SEM_AUDIT_MSG "semaphore created by "
66966 ++#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
66967 ++#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
66968 ++#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
66969 ++#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
66970 ++#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
66971 +diff -urNp linux-2.6.27.7/include/linux/grsecurity.h linux-2.6.27.7/include/linux/grsecurity.h
66972 +--- linux-2.6.27.7/include/linux/grsecurity.h 1969-12-31 19:00:00.000000000 -0500
66973 ++++ linux-2.6.27.7/include/linux/grsecurity.h 2008-11-18 03:38:45.000000000 -0500
66974 +@@ -0,0 +1,200 @@
66975 ++#ifndef GR_SECURITY_H
66976 ++#define GR_SECURITY_H
66977 ++#include <linux/fs.h>
66978 ++#include <linux/binfmts.h>
66979 ++#include <linux/gracl.h>
66980 ++
66981 ++/* notify of brain-dead configs */
66982 ++#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC)
66983 ++#error "CONFIG_PAX_NOEXEC enabled, but PAGEEXEC, SEGMEXEC, and KERNEXEC are disabled."
66984 ++#endif
66985 ++#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
66986 ++#error "CONFIG_PAX_NOEXEC enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
66987 ++#endif
66988 ++#if defined(CONFIG_PAX_ASLR) && (defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
66989 ++#error "CONFIG_PAX_ASLR enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
66990 ++#endif
66991 ++#if defined(CONFIG_PAX_ASLR) && !defined(CONFIG_PAX_RANDKSTACK) && !defined(CONFIG_PAX_RANDUSTACK) && !defined(CONFIG_PAX_RANDMMAP)
66992 ++#error "CONFIG_PAX_ASLR enabled, but RANDKSTACK, RANDUSTACK, and RANDMMAP are disabled."
66993 ++#endif
66994 ++#if defined(CONFIG_PAX) && !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_ASLR)
66995 ++#error "CONFIG_PAX enabled, but no PaX options are enabled."
66996 ++#endif
66997 ++
66998 ++void gr_handle_brute_attach(struct task_struct *p);
66999 ++void gr_handle_brute_check(void);
67000 ++
67001 ++char gr_roletype_to_char(void);
67002 ++
67003 ++int gr_check_user_change(int real, int effective, int fs);
67004 ++int gr_check_group_change(int real, int effective, int fs);
67005 ++
67006 ++void gr_del_task_from_ip_table(struct task_struct *p);
67007 ++
67008 ++int gr_pid_is_chrooted(struct task_struct *p);
67009 ++int gr_handle_chroot_nice(void);
67010 ++int gr_handle_chroot_sysctl(const int op);
67011 ++int gr_handle_chroot_setpriority(struct task_struct *p,
67012 ++ const int niceval);
67013 ++int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
67014 ++int gr_handle_chroot_chroot(const struct dentry *dentry,
67015 ++ const struct vfsmount *mnt);
67016 ++void gr_handle_chroot_caps(struct task_struct *task);
67017 ++void gr_handle_chroot_chdir(struct path *path);
67018 ++int gr_handle_chroot_chmod(const struct dentry *dentry,
67019 ++ const struct vfsmount *mnt, const int mode);
67020 ++int gr_handle_chroot_mknod(const struct dentry *dentry,
67021 ++ const struct vfsmount *mnt, const int mode);
67022 ++int gr_handle_chroot_mount(const struct dentry *dentry,
67023 ++ const struct vfsmount *mnt,
67024 ++ const char *dev_name);
67025 ++int gr_handle_chroot_pivot(void);
67026 ++int gr_handle_chroot_unix(const pid_t pid);
67027 ++
67028 ++int gr_handle_rawio(const struct inode *inode);
67029 ++int gr_handle_nproc(void);
67030 ++
67031 ++void gr_handle_ioperm(void);
67032 ++void gr_handle_iopl(void);
67033 ++
67034 ++int gr_tpe_allow(const struct file *file);
67035 ++
67036 ++int gr_random_pid(void);
67037 ++
67038 ++void gr_log_forkfail(const int retval);
67039 ++void gr_log_timechange(void);
67040 ++void gr_log_signal(const int sig, const struct task_struct *t);
67041 ++void gr_log_chdir(const struct dentry *dentry,
67042 ++ const struct vfsmount *mnt);
67043 ++void gr_log_chroot_exec(const struct dentry *dentry,
67044 ++ const struct vfsmount *mnt);
67045 ++void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
67046 ++void gr_log_remount(const char *devname, const int retval);
67047 ++void gr_log_unmount(const char *devname, const int retval);
67048 ++void gr_log_mount(const char *from, const char *to, const int retval);
67049 ++void gr_log_msgget(const int ret, const int msgflg);
67050 ++void gr_log_msgrm(const uid_t uid, const uid_t cuid);
67051 ++void gr_log_semget(const int err, const int semflg);
67052 ++void gr_log_semrm(const uid_t uid, const uid_t cuid);
67053 ++void gr_log_shmget(const int err, const int shmflg, const size_t size);
67054 ++void gr_log_shmrm(const uid_t uid, const uid_t cuid);
67055 ++void gr_log_textrel(struct vm_area_struct *vma);
67056 ++
67057 ++int gr_handle_follow_link(const struct inode *parent,
67058 ++ const struct inode *inode,
67059 ++ const struct dentry *dentry,
67060 ++ const struct vfsmount *mnt);
67061 ++int gr_handle_fifo(const struct dentry *dentry,
67062 ++ const struct vfsmount *mnt,
67063 ++ const struct dentry *dir, const int flag,
67064 ++ const int acc_mode);
67065 ++int gr_handle_hardlink(const struct dentry *dentry,
67066 ++ const struct vfsmount *mnt,
67067 ++ struct inode *inode,
67068 ++ const int mode, const char *to);
67069 ++
67070 ++int gr_task_is_capable(struct task_struct *task, const int cap);
67071 ++int gr_is_capable_nolog(const int cap);
67072 ++void gr_learn_resource(const struct task_struct *task, const int limit,
67073 ++ const unsigned long wanted, const int gt);
67074 ++void gr_copy_label(struct task_struct *tsk);
67075 ++void gr_handle_crash(struct task_struct *task, const int sig);
67076 ++int gr_handle_signal(const struct task_struct *p, const int sig);
67077 ++int gr_check_crash_uid(const uid_t uid);
67078 ++int gr_check_protected_task(const struct task_struct *task);
67079 ++int gr_acl_handle_mmap(const struct file *file,
67080 ++ const unsigned long prot);
67081 ++int gr_acl_handle_mprotect(const struct file *file,
67082 ++ const unsigned long prot);
67083 ++int gr_check_hidden_task(const struct task_struct *tsk);
67084 ++__u32 gr_acl_handle_truncate(const struct dentry *dentry,
67085 ++ const struct vfsmount *mnt);
67086 ++__u32 gr_acl_handle_utime(const struct dentry *dentry,
67087 ++ const struct vfsmount *mnt);
67088 ++__u32 gr_acl_handle_access(const struct dentry *dentry,
67089 ++ const struct vfsmount *mnt, const int fmode);
67090 ++__u32 gr_acl_handle_fchmod(const struct dentry *dentry,
67091 ++ const struct vfsmount *mnt, mode_t mode);
67092 ++__u32 gr_acl_handle_chmod(const struct dentry *dentry,
67093 ++ const struct vfsmount *mnt, mode_t mode);
67094 ++__u32 gr_acl_handle_chown(const struct dentry *dentry,
67095 ++ const struct vfsmount *mnt);
67096 ++int gr_handle_ptrace(struct task_struct *task, const long request);
67097 ++int gr_handle_proc_ptrace(struct task_struct *task);
67098 ++__u32 gr_acl_handle_execve(const struct dentry *dentry,
67099 ++ const struct vfsmount *mnt);
67100 ++int gr_check_crash_exec(const struct file *filp);
67101 ++int gr_acl_is_enabled(void);
67102 ++void gr_set_kernel_label(struct task_struct *task);
67103 ++void gr_set_role_label(struct task_struct *task, const uid_t uid,
67104 ++ const gid_t gid);
67105 ++int gr_set_proc_label(const struct dentry *dentry,
67106 ++ const struct vfsmount *mnt);
67107 ++__u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
67108 ++ const struct vfsmount *mnt);
67109 ++__u32 gr_acl_handle_open(const struct dentry *dentry,
67110 ++ const struct vfsmount *mnt, const int fmode);
67111 ++__u32 gr_acl_handle_creat(const struct dentry *dentry,
67112 ++ const struct dentry *p_dentry,
67113 ++ const struct vfsmount *p_mnt, const int fmode,
67114 ++ const int imode);
67115 ++void gr_handle_create(const struct dentry *dentry,
67116 ++ const struct vfsmount *mnt);
67117 ++__u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
67118 ++ const struct dentry *parent_dentry,
67119 ++ const struct vfsmount *parent_mnt,
67120 ++ const int mode);
67121 ++__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
67122 ++ const struct dentry *parent_dentry,
67123 ++ const struct vfsmount *parent_mnt);
67124 ++__u32 gr_acl_handle_rmdir(const struct dentry *dentry,
67125 ++ const struct vfsmount *mnt);
67126 ++void gr_handle_delete(const ino_t ino, const dev_t dev);
67127 ++__u32 gr_acl_handle_unlink(const struct dentry *dentry,
67128 ++ const struct vfsmount *mnt);
67129 ++__u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
67130 ++ const struct dentry *parent_dentry,
67131 ++ const struct vfsmount *parent_mnt,
67132 ++ const char *from);
67133 ++__u32 gr_acl_handle_link(const struct dentry *new_dentry,
67134 ++ const struct dentry *parent_dentry,
67135 ++ const struct vfsmount *parent_mnt,
67136 ++ const struct dentry *old_dentry,
67137 ++ const struct vfsmount *old_mnt, const char *to);
67138 ++int gr_acl_handle_rename(struct dentry *new_dentry,
67139 ++ struct dentry *parent_dentry,
67140 ++ const struct vfsmount *parent_mnt,
67141 ++ struct dentry *old_dentry,
67142 ++ struct inode *old_parent_inode,
67143 ++ struct vfsmount *old_mnt, const char *newname);
67144 ++void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
67145 ++ struct dentry *old_dentry,
67146 ++ struct dentry *new_dentry,
67147 ++ struct vfsmount *mnt, const __u8 replace);
67148 ++__u32 gr_check_link(const struct dentry *new_dentry,
67149 ++ const struct dentry *parent_dentry,
67150 ++ const struct vfsmount *parent_mnt,
67151 ++ const struct dentry *old_dentry,
67152 ++ const struct vfsmount *old_mnt);
67153 ++int gr_acl_handle_filldir(const struct file *file, const char *name,
67154 ++ const unsigned int namelen, const ino_t ino);
67155 ++
67156 ++__u32 gr_acl_handle_unix(const struct dentry *dentry,
67157 ++ const struct vfsmount *mnt);
67158 ++void gr_acl_handle_exit(void);
67159 ++void gr_acl_handle_psacct(struct task_struct *task, const long code);
67160 ++int gr_acl_handle_procpidmem(const struct task_struct *task);
67161 ++
67162 ++#ifdef CONFIG_GRKERNSEC
67163 ++void gr_handle_mem_write(void);
67164 ++void gr_handle_kmem_write(void);
67165 ++void gr_handle_open_port(void);
67166 ++int gr_handle_mem_mmap(const unsigned long offset,
67167 ++ struct vm_area_struct *vma);
67168 ++
67169 ++extern int grsec_enable_dmesg;
67170 ++extern int grsec_enable_randsrc;
67171 ++extern int grsec_enable_shm;
67172 ++#endif
67173 ++
67174 ++#endif
67175 +diff -urNp linux-2.6.27.7/include/linux/highmem.h linux-2.6.27.7/include/linux/highmem.h
67176 +--- linux-2.6.27.7/include/linux/highmem.h 2008-11-07 12:55:34.000000000 -0500
67177 ++++ linux-2.6.27.7/include/linux/highmem.h 2008-11-18 03:38:45.000000000 -0500
67178 +@@ -122,6 +122,13 @@ static inline void clear_highpage(struct
67179 + kunmap_atomic(kaddr, KM_USER0);
67180 + }
67181 +
67182 ++static inline void sanitize_highpage(struct page *page)
67183 ++{
67184 ++ void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
67185 ++ clear_page(kaddr);
67186 ++ kunmap_atomic(kaddr, KM_CLEARPAGE);
67187 ++}
67188 ++
67189 + static inline void zero_user_segments(struct page *page,
67190 + unsigned start1, unsigned end1,
67191 + unsigned start2, unsigned end2)
67192 +diff -urNp linux-2.6.27.7/include/linux/jbd2.h linux-2.6.27.7/include/linux/jbd2.h
67193 +--- linux-2.6.27.7/include/linux/jbd2.h 2008-11-07 12:55:34.000000000 -0500
67194 ++++ linux-2.6.27.7/include/linux/jbd2.h 2008-11-18 03:38:45.000000000 -0500
67195 +@@ -66,7 +66,7 @@ extern u8 jbd2_journal_enable_debug;
67196 + } \
67197 + } while (0)
67198 + #else
67199 +-#define jbd_debug(f, a...) /**/
67200 ++#define jbd_debug(f, a...) do {} while (0)
67201 + #endif
67202 +
67203 + static inline void *jbd2_alloc(size_t size, gfp_t flags)
67204 +diff -urNp linux-2.6.27.7/include/linux/jbd.h linux-2.6.27.7/include/linux/jbd.h
67205 +--- linux-2.6.27.7/include/linux/jbd.h 2008-11-07 12:55:34.000000000 -0500
67206 ++++ linux-2.6.27.7/include/linux/jbd.h 2008-11-18 03:38:45.000000000 -0500
67207 +@@ -66,7 +66,7 @@ extern u8 journal_enable_debug;
67208 + } \
67209 + } while (0)
67210 + #else
67211 +-#define jbd_debug(f, a...) /**/
67212 ++#define jbd_debug(f, a...) do {} while (0)
67213 + #endif
67214 +
67215 + static inline void *jbd_alloc(size_t size, gfp_t flags)
67216 +diff -urNp linux-2.6.27.7/include/linux/libata.h linux-2.6.27.7/include/linux/libata.h
67217 +--- linux-2.6.27.7/include/linux/libata.h 2008-11-07 12:55:34.000000000 -0500
67218 ++++ linux-2.6.27.7/include/linux/libata.h 2008-11-18 03:38:45.000000000 -0500
67219 +@@ -64,11 +64,11 @@
67220 + #ifdef ATA_VERBOSE_DEBUG
67221 + #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args)
67222 + #else
67223 +-#define VPRINTK(fmt, args...)
67224 ++#define VPRINTK(fmt, args...) do {} while (0)
67225 + #endif /* ATA_VERBOSE_DEBUG */
67226 + #else
67227 +-#define DPRINTK(fmt, args...)
67228 +-#define VPRINTK(fmt, args...)
67229 ++#define DPRINTK(fmt, args...) do {} while (0)
67230 ++#define VPRINTK(fmt, args...) do {} while (0)
67231 + #endif /* ATA_DEBUG */
67232 +
67233 + #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __func__, ## args)
67234 +diff -urNp linux-2.6.27.7/include/linux/mm.h linux-2.6.27.7/include/linux/mm.h
67235 +--- linux-2.6.27.7/include/linux/mm.h 2008-11-07 12:55:34.000000000 -0500
67236 ++++ linux-2.6.27.7/include/linux/mm.h 2008-11-18 03:38:45.000000000 -0500
67237 +@@ -38,6 +38,7 @@ extern unsigned long mmap_min_addr;
67238 + #include <asm/page.h>
67239 + #include <asm/pgtable.h>
67240 + #include <asm/processor.h>
67241 ++#include <asm/mman.h>
67242 +
67243 + #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
67244 +
67245 +@@ -114,6 +115,14 @@ extern unsigned int kobjsize(const void
67246 + #define VM_MIXEDMAP 0x10000000 /* Can contain "struct page" and pure PFN pages */
67247 + #define VM_SAO 0x20000000 /* Strong Access Ordering (powerpc) */
67248 +
67249 ++#ifdef CONFIG_PAX_PAGEEXEC
67250 ++#define VM_PAGEEXEC 0x40000000 /* vma->vm_page_prot needs special handling */
67251 ++#endif
67252 ++
67253 ++#ifdef CONFIG_PAX_MPROTECT
67254 ++#define VM_MAYNOTWRITE 0x80000000 /* vma cannot be granted VM_WRITE any more */
67255 ++#endif
67256 ++
67257 + #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
67258 + #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
67259 + #endif
67260 +@@ -874,6 +883,8 @@ struct shrinker {
67261 + extern void register_shrinker(struct shrinker *);
67262 + extern void unregister_shrinker(struct shrinker *);
67263 +
67264 ++pgprot_t vm_get_page_prot(unsigned long vm_flags);
67265 ++
67266 + int vma_wants_writenotify(struct vm_area_struct *vma);
67267 +
67268 + extern pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl);
67269 +@@ -1129,6 +1140,7 @@ out:
67270 + }
67271 +
67272 + extern int do_munmap(struct mm_struct *, unsigned long, size_t);
67273 ++extern int __do_munmap(struct mm_struct *, unsigned long, size_t);
67274 +
67275 + extern unsigned long do_brk(unsigned long, unsigned long);
67276 +
67277 +@@ -1181,6 +1193,10 @@ extern struct vm_area_struct * find_vma(
67278 + extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
67279 + struct vm_area_struct **pprev);
67280 +
67281 ++extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma);
67282 ++extern void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma);
67283 ++extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl);
67284 ++
67285 + /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
67286 + NULL if none. Assume start_addr < end_addr. */
67287 + static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
67288 +@@ -1197,7 +1213,6 @@ static inline unsigned long vma_pages(st
67289 + return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
67290 + }
67291 +
67292 +-pgprot_t vm_get_page_prot(unsigned long vm_flags);
67293 + struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
67294 + int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
67295 + unsigned long pfn, unsigned long size, pgprot_t);
67296 +@@ -1286,5 +1301,11 @@ int vmemmap_populate_basepages(struct pa
67297 + int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
67298 + void vmemmap_populate_print_last(void);
67299 +
67300 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
67301 ++extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
67302 ++#else
67303 ++static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
67304 ++#endif
67305 ++
67306 + #endif /* __KERNEL__ */
67307 + #endif /* _LINUX_MM_H */
67308 +diff -urNp linux-2.6.27.7/include/linux/mm_types.h linux-2.6.27.7/include/linux/mm_types.h
67309 +--- linux-2.6.27.7/include/linux/mm_types.h 2008-11-07 12:55:34.000000000 -0500
67310 ++++ linux-2.6.27.7/include/linux/mm_types.h 2008-11-18 03:38:45.000000000 -0500
67311 +@@ -158,6 +158,8 @@ struct vm_area_struct {
67312 + #ifdef CONFIG_NUMA
67313 + struct mempolicy *vm_policy; /* NUMA policy for the VMA */
67314 + #endif
67315 ++
67316 ++ struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */
67317 + };
67318 +
67319 + struct core_thread {
67320 +@@ -257,6 +259,24 @@ struct mm_struct {
67321 + #ifdef CONFIG_MMU_NOTIFIER
67322 + struct mmu_notifier_mm *mmu_notifier_mm;
67323 + #endif
67324 ++
67325 ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
67326 ++ unsigned long pax_flags;
67327 ++#endif
67328 ++
67329 ++#ifdef CONFIG_PAX_DLRESOLVE
67330 ++ unsigned long call_dl_resolve;
67331 ++#endif
67332 ++
67333 ++#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
67334 ++ unsigned long call_syscall;
67335 ++#endif
67336 ++
67337 ++#ifdef CONFIG_PAX_ASLR
67338 ++ unsigned long delta_mmap; /* randomized offset */
67339 ++ unsigned long delta_stack; /* randomized offset */
67340 ++#endif
67341 ++
67342 + };
67343 +
67344 + #endif /* _LINUX_MM_TYPES_H */
67345 +diff -urNp linux-2.6.27.7/include/linux/module.h linux-2.6.27.7/include/linux/module.h
67346 +--- linux-2.6.27.7/include/linux/module.h 2008-11-07 12:55:34.000000000 -0500
67347 ++++ linux-2.6.27.7/include/linux/module.h 2008-11-18 03:38:45.000000000 -0500
67348 +@@ -282,16 +282,16 @@ struct module
67349 + int (*init)(void);
67350 +
67351 + /* If this is non-NULL, vfree after init() returns */
67352 +- void *module_init;
67353 ++ void *module_init_rx, *module_init_rw;
67354 +
67355 + /* Here is the actual code + data, vfree'd on unload. */
67356 +- void *module_core;
67357 ++ void *module_core_rx, *module_core_rw;
67358 +
67359 + /* Here are the sizes of the init and core sections */
67360 +- unsigned int init_size, core_size;
67361 ++ unsigned int init_size_rw, core_size_rw;
67362 +
67363 + /* The size of the executable code in each section. */
67364 +- unsigned int init_text_size, core_text_size;
67365 ++ unsigned int init_size_rx, core_size_rx;
67366 +
67367 + /* The handle returned from unwind_add_table. */
67368 + void *unwind_info;
67369 +diff -urNp linux-2.6.27.7/include/linux/moduleloader.h linux-2.6.27.7/include/linux/moduleloader.h
67370 +--- linux-2.6.27.7/include/linux/moduleloader.h 2008-11-07 12:55:34.000000000 -0500
67371 ++++ linux-2.6.27.7/include/linux/moduleloader.h 2008-11-18 03:38:45.000000000 -0500
67372 +@@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
67373 + sections. Returns NULL on failure. */
67374 + void *module_alloc(unsigned long size);
67375 +
67376 ++#ifdef CONFIG_PAX_KERNEXEC
67377 ++void *module_alloc_exec(unsigned long size);
67378 ++#else
67379 ++#define module_alloc_exec(x) module_alloc(x)
67380 ++#endif
67381 ++
67382 + /* Free memory returned from module_alloc. */
67383 + void module_free(struct module *mod, void *module_region);
67384 +
67385 ++#ifdef CONFIG_PAX_KERNEXEC
67386 ++void module_free_exec(struct module *mod, void *module_region);
67387 ++#else
67388 ++#define module_free_exec(x, y) module_free(x, y)
67389 ++#endif
67390 ++
67391 + /* Apply the given relocation to the (simplified) ELF. Return -error
67392 + or 0. */
67393 + int apply_relocate(Elf_Shdr *sechdrs,
67394 +diff -urNp linux-2.6.27.7/include/linux/namei.h linux-2.6.27.7/include/linux/namei.h
67395 +--- linux-2.6.27.7/include/linux/namei.h 2008-11-07 12:55:34.000000000 -0500
67396 ++++ linux-2.6.27.7/include/linux/namei.h 2008-11-18 03:38:45.000000000 -0500
67397 +@@ -21,7 +21,7 @@ struct nameidata {
67398 + unsigned int flags;
67399 + int last_type;
67400 + unsigned depth;
67401 +- char *saved_names[MAX_NESTED_LINKS + 1];
67402 ++ const char *saved_names[MAX_NESTED_LINKS + 1];
67403 +
67404 + /* Intent data */
67405 + union {
67406 +@@ -80,12 +80,12 @@ extern int follow_up(struct vfsmount **,
67407 + extern struct dentry *lock_rename(struct dentry *, struct dentry *);
67408 + extern void unlock_rename(struct dentry *, struct dentry *);
67409 +
67410 +-static inline void nd_set_link(struct nameidata *nd, char *path)
67411 ++static inline void nd_set_link(struct nameidata *nd, const char *path)
67412 + {
67413 + nd->saved_names[nd->depth] = path;
67414 + }
67415 +
67416 +-static inline char *nd_get_link(struct nameidata *nd)
67417 ++static inline const char *nd_get_link(struct nameidata *nd)
67418 + {
67419 + return nd->saved_names[nd->depth];
67420 + }
67421 +diff -urNp linux-2.6.27.7/include/linux/nodemask.h linux-2.6.27.7/include/linux/nodemask.h
67422 +--- linux-2.6.27.7/include/linux/nodemask.h 2008-11-07 12:55:34.000000000 -0500
67423 ++++ linux-2.6.27.7/include/linux/nodemask.h 2008-11-18 03:38:45.000000000 -0500
67424 +@@ -442,11 +442,11 @@ static inline int num_node_state(enum no
67425 +
67426 + #define any_online_node(mask) \
67427 + ({ \
67428 +- int node; \
67429 +- for_each_node_mask(node, (mask)) \
67430 +- if (node_online(node)) \
67431 ++ int __node; \
67432 ++ for_each_node_mask(__node, (mask)) \
67433 ++ if (node_online(__node)) \
67434 + break; \
67435 +- node; \
67436 ++ __node; \
67437 + })
67438 +
67439 + #define num_online_nodes() num_node_state(N_ONLINE)
67440 +diff -urNp linux-2.6.27.7/include/linux/percpu.h linux-2.6.27.7/include/linux/percpu.h
67441 +--- linux-2.6.27.7/include/linux/percpu.h 2008-11-07 12:55:34.000000000 -0500
67442 ++++ linux-2.6.27.7/include/linux/percpu.h 2008-11-18 03:38:45.000000000 -0500
67443 +@@ -43,7 +43,7 @@
67444 + #endif
67445 +
67446 + #define PERCPU_ENOUGH_ROOM \
67447 +- (__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE)
67448 ++ ((unsigned long)(__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE))
67449 + #endif /* PERCPU_ENOUGH_ROOM */
67450 +
67451 + /*
67452 +diff -urNp linux-2.6.27.7/include/linux/poison.h linux-2.6.27.7/include/linux/poison.h
67453 +--- linux-2.6.27.7/include/linux/poison.h 2008-11-07 12:55:34.000000000 -0500
67454 ++++ linux-2.6.27.7/include/linux/poison.h 2008-11-18 03:38:45.000000000 -0500
67455 +@@ -7,8 +7,8 @@
67456 + * under normal circumstances, used to verify that nobody uses
67457 + * non-initialized list entries.
67458 + */
67459 +-#define LIST_POISON1 ((void *) 0x00100100)
67460 +-#define LIST_POISON2 ((void *) 0x00200200)
67461 ++#define LIST_POISON1 ((void *) 0xFF1001FFFF1001FFULL)
67462 ++#define LIST_POISON2 ((void *) 0xFF2002FFFF2002FFULL)
67463 +
67464 + /********** include/linux/timer.h **********/
67465 + /*
67466 +diff -urNp linux-2.6.27.7/include/linux/random.h linux-2.6.27.7/include/linux/random.h
67467 +--- linux-2.6.27.7/include/linux/random.h 2008-11-07 12:55:34.000000000 -0500
67468 ++++ linux-2.6.27.7/include/linux/random.h 2008-11-18 03:38:45.000000000 -0500
67469 +@@ -72,6 +72,11 @@ unsigned long randomize_range(unsigned l
67470 + u32 random32(void);
67471 + void srandom32(u32 seed);
67472 +
67473 ++static inline unsigned long pax_get_random_long(void)
67474 ++{
67475 ++ return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0);
67476 ++}
67477 ++
67478 + #endif /* __KERNEL___ */
67479 +
67480 + #endif /* _LINUX_RANDOM_H */
67481 +diff -urNp linux-2.6.27.7/include/linux/sched.h linux-2.6.27.7/include/linux/sched.h
67482 +--- linux-2.6.27.7/include/linux/sched.h 2008-11-07 12:55:34.000000000 -0500
67483 ++++ linux-2.6.27.7/include/linux/sched.h 2008-11-18 03:38:45.000000000 -0500
67484 +@@ -96,6 +96,7 @@ struct exec_domain;
67485 + struct futex_pi_state;
67486 + struct robust_list_head;
67487 + struct bio;
67488 ++struct linux_binprm;
67489 +
67490 + /*
67491 + * List of flags we want to share for kernel threads,
67492 +@@ -545,6 +546,15 @@ struct signal_struct {
67493 + unsigned audit_tty;
67494 + struct tty_audit_buf *tty_audit_buf;
67495 + #endif
67496 ++
67497 ++#ifdef CONFIG_GRKERNSEC
67498 ++ u32 curr_ip;
67499 ++ u32 gr_saddr;
67500 ++ u32 gr_daddr;
67501 ++ u16 gr_sport;
67502 ++ u16 gr_dport;
67503 ++ u8 used_accept:1;
67504 ++#endif
67505 + };
67506 +
67507 + /* Context switch must be unlocked if interrupts are to be enabled */
67508 +@@ -1026,7 +1036,7 @@ struct sched_rt_entity {
67509 +
67510 + struct task_struct {
67511 + volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
67512 +- void *stack;
67513 ++ struct thread_info *stack;
67514 + atomic_t usage;
67515 + unsigned int flags; /* per process flags, defined below */
67516 + unsigned int ptrace;
67517 +@@ -1091,10 +1101,9 @@ struct task_struct {
67518 + pid_t pid;
67519 + pid_t tgid;
67520 +
67521 +-#ifdef CONFIG_CC_STACKPROTECTOR
67522 + /* Canary value for the -fstack-protector gcc feature */
67523 + unsigned long stack_canary;
67524 +-#endif
67525 ++
67526 + /*
67527 + * pointers to (original) parent process, youngest child, younger sibling,
67528 + * older sibling, respectively. (p->father can be replaced with
67529 +@@ -1122,8 +1131,8 @@ struct task_struct {
67530 + struct list_head thread_group;
67531 +
67532 + struct completion *vfork_done; /* for vfork() */
67533 +- int __user *set_child_tid; /* CLONE_CHILD_SETTID */
67534 +- int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
67535 ++ pid_t __user *set_child_tid; /* CLONE_CHILD_SETTID */
67536 ++ pid_t __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
67537 +
67538 + cputime_t utime, stime, utimescaled, stimescaled;
67539 + cputime_t gtime;
67540 +@@ -1303,8 +1312,64 @@ struct task_struct {
67541 + int latency_record_count;
67542 + struct latency_record latency_record[LT_SAVECOUNT];
67543 + #endif
67544 ++
67545 ++#ifdef CONFIG_GRKERNSEC
67546 ++ /* grsecurity */
67547 ++ struct acl_subject_label *acl;
67548 ++ struct acl_role_label *role;
67549 ++ struct file *exec_file;
67550 ++ u16 acl_role_id;
67551 ++ u8 acl_sp_role;
67552 ++ u8 is_writable;
67553 ++ u8 brute;
67554 ++#endif
67555 ++
67556 + };
67557 +
67558 ++#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
67559 ++#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
67560 ++#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
67561 ++#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
67562 ++/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */
67563 ++#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
67564 ++
67565 ++#ifdef CONFIG_PAX_SOFTMODE
67566 ++extern unsigned int pax_softmode;
67567 ++#endif
67568 ++
67569 ++extern int pax_check_flags(unsigned long *);
67570 ++
67571 ++/* if tsk != current then task_lock must be held on it */
67572 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
67573 ++static inline unsigned long pax_get_flags(struct task_struct *tsk)
67574 ++{
67575 ++ if (likely(tsk->mm))
67576 ++ return tsk->mm->pax_flags;
67577 ++ else
67578 ++ return 0UL;
67579 ++}
67580 ++
67581 ++/* if tsk != current then task_lock must be held on it */
67582 ++static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
67583 ++{
67584 ++ if (likely(tsk->mm)) {
67585 ++ tsk->mm->pax_flags = flags;
67586 ++ return 0;
67587 ++ }
67588 ++ return -EINVAL;
67589 ++}
67590 ++#endif
67591 ++
67592 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
67593 ++extern void pax_set_initial_flags(struct linux_binprm *bprm);
67594 ++#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
67595 ++extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
67596 ++#endif
67597 ++
67598 ++void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
67599 ++void pax_report_insns(void *pc, void *sp);
67600 ++void pax_report_refcount_overflow(struct pt_regs *regs);
67601 ++
67602 + /*
67603 + * Priority of a process goes from 0..MAX_PRIO-1, valid RT
67604 + * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
67605 +@@ -1845,7 +1910,7 @@ extern void __cleanup_sighand(struct sig
67606 + extern void exit_itimers(struct signal_struct *);
67607 + extern void flush_itimer_signals(void);
67608 +
67609 +-extern NORET_TYPE void do_group_exit(int);
67610 ++extern NORET_TYPE void do_group_exit(int) ATTRIB_NORET;
67611 +
67612 + extern void daemonize(const char *, ...);
67613 + extern int allow_signal(int);
67614 +@@ -1948,8 +2013,8 @@ static inline void unlock_task_sighand(s
67615 +
67616 + #ifndef __HAVE_THREAD_FUNCTIONS
67617 +
67618 +-#define task_thread_info(task) ((struct thread_info *)(task)->stack)
67619 +-#define task_stack_page(task) ((task)->stack)
67620 ++#define task_thread_info(task) ((task)->stack)
67621 ++#define task_stack_page(task) ((void *)(task)->stack)
67622 +
67623 + static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
67624 + {
67625 +diff -urNp linux-2.6.27.7/include/linux/screen_info.h linux-2.6.27.7/include/linux/screen_info.h
67626 +--- linux-2.6.27.7/include/linux/screen_info.h 2008-11-07 12:55:34.000000000 -0500
67627 ++++ linux-2.6.27.7/include/linux/screen_info.h 2008-11-18 03:38:45.000000000 -0500
67628 +@@ -42,7 +42,8 @@ struct screen_info {
67629 + __u16 pages; /* 0x32 */
67630 + __u16 vesa_attributes; /* 0x34 */
67631 + __u32 capabilities; /* 0x36 */
67632 +- __u8 _reserved[6]; /* 0x3a */
67633 ++ __u16 vesapm_size; /* 0x3a */
67634 ++ __u8 _reserved[4]; /* 0x3c */
67635 + } __attribute__((packed));
67636 +
67637 + #define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
67638 +diff -urNp linux-2.6.27.7/include/linux/shm.h linux-2.6.27.7/include/linux/shm.h
67639 +--- linux-2.6.27.7/include/linux/shm.h 2008-11-07 12:55:34.000000000 -0500
67640 ++++ linux-2.6.27.7/include/linux/shm.h 2008-11-18 03:38:45.000000000 -0500
67641 +@@ -95,6 +95,10 @@ struct shmid_kernel /* private to the ke
67642 + pid_t shm_cprid;
67643 + pid_t shm_lprid;
67644 + struct user_struct *mlock_user;
67645 ++#ifdef CONFIG_GRKERNSEC
67646 ++ time_t shm_createtime;
67647 ++ pid_t shm_lapid;
67648 ++#endif
67649 + };
67650 +
67651 + /* shm_mode upper byte flags */
67652 +diff -urNp linux-2.6.27.7/include/linux/slab.h linux-2.6.27.7/include/linux/slab.h
67653 +--- linux-2.6.27.7/include/linux/slab.h 2008-11-07 12:55:34.000000000 -0500
67654 ++++ linux-2.6.27.7/include/linux/slab.h 2008-11-18 03:38:45.000000000 -0500
67655 +@@ -45,10 +45,9 @@
67656 + * ZERO_SIZE_PTR can be passed to kfree though in the same way that NULL can.
67657 + * Both make kfree a no-op.
67658 + */
67659 +-#define ZERO_SIZE_PTR ((void *)16)
67660 ++#define ZERO_SIZE_PTR ((void *)-1024L)
67661 +
67662 +-#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= \
67663 +- (unsigned long)ZERO_SIZE_PTR)
67664 ++#define ZERO_OR_NULL_PTR(x) (!(x) || (x) == ZERO_SIZE_PTR)
67665 +
67666 + /*
67667 + * struct kmem_cache related prototypes
67668 +diff -urNp linux-2.6.27.7/include/linux/sysctl.h linux-2.6.27.7/include/linux/sysctl.h
67669 +--- linux-2.6.27.7/include/linux/sysctl.h 2008-11-07 12:55:34.000000000 -0500
67670 ++++ linux-2.6.27.7/include/linux/sysctl.h 2008-11-18 03:38:45.000000000 -0500
67671 +@@ -165,7 +165,11 @@ enum
67672 + KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
67673 + };
67674 +
67675 +-
67676 ++#ifdef CONFIG_PAX_SOFTMODE
67677 ++enum {
67678 ++ PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */
67679 ++};
67680 ++#endif
67681 +
67682 + /* CTL_VM names: */
67683 + enum
67684 +diff -urNp linux-2.6.27.7/include/linux/thread_info.h linux-2.6.27.7/include/linux/thread_info.h
67685 +--- linux-2.6.27.7/include/linux/thread_info.h 2008-11-07 12:55:34.000000000 -0500
67686 ++++ linux-2.6.27.7/include/linux/thread_info.h 2008-11-18 03:38:45.000000000 -0500
67687 +@@ -23,7 +23,7 @@ struct restart_block {
67688 + };
67689 + /* For futex_wait */
67690 + struct {
67691 +- u32 *uaddr;
67692 ++ u32 __user *uaddr;
67693 + u32 val;
67694 + u32 flags;
67695 + u32 bitset;
67696 +diff -urNp linux-2.6.27.7/include/linux/uaccess.h linux-2.6.27.7/include/linux/uaccess.h
67697 +--- linux-2.6.27.7/include/linux/uaccess.h 2008-11-07 12:55:34.000000000 -0500
67698 ++++ linux-2.6.27.7/include/linux/uaccess.h 2008-11-18 03:38:45.000000000 -0500
67699 +@@ -76,11 +76,11 @@ static inline unsigned long __copy_from_
67700 + long ret; \
67701 + mm_segment_t old_fs = get_fs(); \
67702 + \
67703 +- set_fs(KERNEL_DS); \
67704 + pagefault_disable(); \
67705 ++ set_fs(KERNEL_DS); \
67706 + ret = __get_user(retval, (__force typeof(retval) __user *)(addr)); \
67707 +- pagefault_enable(); \
67708 + set_fs(old_fs); \
67709 ++ pagefault_enable(); \
67710 + ret; \
67711 + })
67712 +
67713 +diff -urNp linux-2.6.27.7/include/linux/vmalloc.h linux-2.6.27.7/include/linux/vmalloc.h
67714 +--- linux-2.6.27.7/include/linux/vmalloc.h 2008-11-07 12:55:34.000000000 -0500
67715 ++++ linux-2.6.27.7/include/linux/vmalloc.h 2008-11-18 03:38:45.000000000 -0500
67716 +@@ -12,6 +12,11 @@ struct vm_area_struct; /* vma defining
67717 + #define VM_MAP 0x00000004 /* vmap()ed pages */
67718 + #define VM_USERMAP 0x00000008 /* suitable for remap_vmalloc_range */
67719 + #define VM_VPAGES 0x00000010 /* buffer for pages was vmalloc'ed */
67720 ++
67721 ++#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
67722 ++#define VM_KERNEXEC 0x00000020 /* allocate from executable kernel memory range */
67723 ++#endif
67724 ++
67725 + /* bits [20..32] reserved for arch specific ioremap internals */
67726 +
67727 + /*
67728 +diff -urNp linux-2.6.27.7/include/net/sctp/sctp.h linux-2.6.27.7/include/net/sctp/sctp.h
67729 +--- linux-2.6.27.7/include/net/sctp/sctp.h 2008-11-07 12:55:34.000000000 -0500
67730 ++++ linux-2.6.27.7/include/net/sctp/sctp.h 2008-11-18 03:38:45.000000000 -0500
67731 +@@ -309,8 +309,8 @@ extern int sctp_debug_flag;
67732 +
67733 + #else /* SCTP_DEBUG */
67734 +
67735 +-#define SCTP_DEBUG_PRINTK(whatever...)
67736 +-#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
67737 ++#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
67738 ++#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
67739 + #define SCTP_ENABLE_DEBUG
67740 + #define SCTP_DISABLE_DEBUG
67741 + #define SCTP_ASSERT(expr, str, func)
67742 +diff -urNp linux-2.6.27.7/include/sound/core.h linux-2.6.27.7/include/sound/core.h
67743 +--- linux-2.6.27.7/include/sound/core.h 2008-11-07 12:55:34.000000000 -0500
67744 ++++ linux-2.6.27.7/include/sound/core.h 2008-11-18 03:38:45.000000000 -0500
67745 +@@ -406,9 +406,9 @@ void snd_verbose_printd(const char *file
67746 +
67747 + #else /* !CONFIG_SND_DEBUG */
67748 +
67749 +-#define snd_printd(fmt, args...) /* nothing */
67750 ++#define snd_printd(fmt, args...) do {} while (0)
67751 + #define snd_assert(expr, args...) (void)(expr)
67752 +-#define snd_BUG() /* nothing */
67753 ++#define snd_BUG() do {} while (0)
67754 +
67755 + #endif /* CONFIG_SND_DEBUG */
67756 +
67757 +@@ -422,7 +422,7 @@ void snd_verbose_printd(const char *file
67758 + */
67759 + #define snd_printdd(format, args...) snd_printk(format, ##args)
67760 + #else
67761 +-#define snd_printdd(format, args...) /* nothing */
67762 ++#define snd_printdd(format, args...) do {} while (0)
67763 + #endif
67764 +
67765 +
67766 +diff -urNp linux-2.6.27.7/include/video/uvesafb.h linux-2.6.27.7/include/video/uvesafb.h
67767 +--- linux-2.6.27.7/include/video/uvesafb.h 2008-11-07 12:55:34.000000000 -0500
67768 ++++ linux-2.6.27.7/include/video/uvesafb.h 2008-11-18 03:38:45.000000000 -0500
67769 +@@ -175,6 +175,7 @@ struct uvesafb_par {
67770 + u8 ypan; /* 0 - nothing, 1 - ypan, 2 - ywrap */
67771 + u8 pmi_setpal; /* PMI for palette changes */
67772 + u16 *pmi_base; /* protected mode interface location */
67773 ++ u8 *pmi_code; /* protected mode code location */
67774 + void *pmi_start;
67775 + void *pmi_pal;
67776 + u8 *vbe_state_orig; /*
67777 +diff -urNp linux-2.6.27.7/init/do_mounts.c linux-2.6.27.7/init/do_mounts.c
67778 +--- linux-2.6.27.7/init/do_mounts.c 2008-11-07 12:55:34.000000000 -0500
67779 ++++ linux-2.6.27.7/init/do_mounts.c 2008-11-18 03:38:45.000000000 -0500
67780 +@@ -214,11 +214,11 @@ static void __init get_fs_names(char *pa
67781 +
67782 + static int __init do_mount_root(char *name, char *fs, int flags, void *data)
67783 + {
67784 +- int err = sys_mount(name, "/root", fs, flags, data);
67785 ++ int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data);
67786 + if (err)
67787 + return err;
67788 +
67789 +- sys_chdir("/root");
67790 ++ sys_chdir((char __user *)"/root");
67791 + ROOT_DEV = current->fs->pwd.mnt->mnt_sb->s_dev;
67792 + printk("VFS: Mounted root (%s filesystem)%s.\n",
67793 + current->fs->pwd.mnt->mnt_sb->s_type->name,
67794 +@@ -304,18 +304,18 @@ void __init change_floppy(char *fmt, ...
67795 + va_start(args, fmt);
67796 + vsprintf(buf, fmt, args);
67797 + va_end(args);
67798 +- fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
67799 ++ fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
67800 + if (fd >= 0) {
67801 + sys_ioctl(fd, FDEJECT, 0);
67802 + sys_close(fd);
67803 + }
67804 + printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
67805 +- fd = sys_open("/dev/console", O_RDWR, 0);
67806 ++ fd = sys_open((char __user *)"/dev/console", O_RDWR, 0);
67807 + if (fd >= 0) {
67808 + sys_ioctl(fd, TCGETS, (long)&termios);
67809 + termios.c_lflag &= ~ICANON;
67810 + sys_ioctl(fd, TCSETSF, (long)&termios);
67811 +- sys_read(fd, &c, 1);
67812 ++ sys_read(fd, (char __user *)&c, 1);
67813 + termios.c_lflag |= ICANON;
67814 + sys_ioctl(fd, TCSETSF, (long)&termios);
67815 + sys_close(fd);
67816 +@@ -402,7 +402,7 @@ void __init prepare_namespace(void)
67817 +
67818 + mount_root();
67819 + out:
67820 +- sys_mount(".", "/", NULL, MS_MOVE, NULL);
67821 +- sys_chroot(".");
67822 ++ sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
67823 ++ sys_chroot((char __user *)".");
67824 + }
67825 +
67826 +diff -urNp linux-2.6.27.7/init/do_mounts.h linux-2.6.27.7/init/do_mounts.h
67827 +--- linux-2.6.27.7/init/do_mounts.h 2008-11-07 12:55:34.000000000 -0500
67828 ++++ linux-2.6.27.7/init/do_mounts.h 2008-11-18 03:38:45.000000000 -0500
67829 +@@ -14,15 +14,15 @@ extern int root_mountflags;
67830 +
67831 + static inline int create_dev(char *name, dev_t dev)
67832 + {
67833 +- sys_unlink(name);
67834 +- return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
67835 ++ sys_unlink((char __user *)name);
67836 ++ return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
67837 + }
67838 +
67839 + #if BITS_PER_LONG == 32
67840 + static inline u32 bstat(char *name)
67841 + {
67842 + struct stat64 stat;
67843 +- if (sys_stat64(name, &stat) != 0)
67844 ++ if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0)
67845 + return 0;
67846 + if (!S_ISBLK(stat.st_mode))
67847 + return 0;
67848 +diff -urNp linux-2.6.27.7/init/do_mounts_initrd.c linux-2.6.27.7/init/do_mounts_initrd.c
67849 +--- linux-2.6.27.7/init/do_mounts_initrd.c 2008-11-07 12:55:34.000000000 -0500
67850 ++++ linux-2.6.27.7/init/do_mounts_initrd.c 2008-11-18 03:38:45.000000000 -0500
67851 +@@ -32,7 +32,7 @@ static int __init do_linuxrc(void * shel
67852 + sys_close(old_fd);sys_close(root_fd);
67853 + sys_close(0);sys_close(1);sys_close(2);
67854 + sys_setsid();
67855 +- (void) sys_open("/dev/console",O_RDWR,0);
67856 ++ (void) sys_open((const char __user *)"/dev/console",O_RDWR,0);
67857 + (void) sys_dup(0);
67858 + (void) sys_dup(0);
67859 + return kernel_execve(shell, argv, envp_init);
67860 +@@ -47,13 +47,13 @@ static void __init handle_initrd(void)
67861 + create_dev("/dev/root.old", Root_RAM0);
67862 + /* mount initrd on rootfs' /root */
67863 + mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
67864 +- sys_mkdir("/old", 0700);
67865 +- root_fd = sys_open("/", 0, 0);
67866 +- old_fd = sys_open("/old", 0, 0);
67867 ++ sys_mkdir((const char __user *)"/old", 0700);
67868 ++ root_fd = sys_open((const char __user *)"/", 0, 0);
67869 ++ old_fd = sys_open((const char __user *)"/old", 0, 0);
67870 + /* move initrd over / and chdir/chroot in initrd root */
67871 +- sys_chdir("/root");
67872 +- sys_mount(".", "/", NULL, MS_MOVE, NULL);
67873 +- sys_chroot(".");
67874 ++ sys_chdir((const char __user *)"/root");
67875 ++ sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
67876 ++ sys_chroot((const char __user *)".");
67877 +
67878 + /*
67879 + * In case that a resume from disk is carried out by linuxrc or one of
67880 +@@ -70,15 +70,15 @@ static void __init handle_initrd(void)
67881 +
67882 + /* move initrd to rootfs' /old */
67883 + sys_fchdir(old_fd);
67884 +- sys_mount("/", ".", NULL, MS_MOVE, NULL);
67885 ++ sys_mount((char __user *)"/", (char __user *)".", NULL, MS_MOVE, NULL);
67886 + /* switch root and cwd back to / of rootfs */
67887 + sys_fchdir(root_fd);
67888 +- sys_chroot(".");
67889 ++ sys_chroot((const char __user *)".");
67890 + sys_close(old_fd);
67891 + sys_close(root_fd);
67892 +
67893 + if (new_decode_dev(real_root_dev) == Root_RAM0) {
67894 +- sys_chdir("/old");
67895 ++ sys_chdir((const char __user *)"/old");
67896 + return;
67897 + }
67898 +
67899 +@@ -86,17 +86,17 @@ static void __init handle_initrd(void)
67900 + mount_root();
67901 +
67902 + printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
67903 +- error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
67904 ++ error = sys_mount((char __user *)"/old", (char __user *)"/root/initrd", NULL, MS_MOVE, NULL);
67905 + if (!error)
67906 + printk("okay\n");
67907 + else {
67908 +- int fd = sys_open("/dev/root.old", O_RDWR, 0);
67909 ++ int fd = sys_open((const char __user *)"/dev/root.old", O_RDWR, 0);
67910 + if (error == -ENOENT)
67911 + printk("/initrd does not exist. Ignored.\n");
67912 + else
67913 + printk("failed\n");
67914 + printk(KERN_NOTICE "Unmounting old root\n");
67915 +- sys_umount("/old", MNT_DETACH);
67916 ++ sys_umount((char __user *)"/old", MNT_DETACH);
67917 + printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
67918 + if (fd < 0) {
67919 + error = fd;
67920 +@@ -119,11 +119,11 @@ int __init initrd_load(void)
67921 + * mounted in the normal path.
67922 + */
67923 + if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) {
67924 +- sys_unlink("/initrd.image");
67925 ++ sys_unlink((const char __user *)"/initrd.image");
67926 + handle_initrd();
67927 + return 1;
67928 + }
67929 + }
67930 +- sys_unlink("/initrd.image");
67931 ++ sys_unlink((const char __user *)"/initrd.image");
67932 + return 0;
67933 + }
67934 +diff -urNp linux-2.6.27.7/init/do_mounts_md.c linux-2.6.27.7/init/do_mounts_md.c
67935 +--- linux-2.6.27.7/init/do_mounts_md.c 2008-11-07 12:55:34.000000000 -0500
67936 ++++ linux-2.6.27.7/init/do_mounts_md.c 2008-11-18 03:38:45.000000000 -0500
67937 +@@ -166,7 +166,7 @@ static void __init md_setup_drive(void)
67938 + partitioned ? "_d" : "", minor,
67939 + md_setup_args[ent].device_names);
67940 +
67941 +- fd = sys_open(name, 0, 0);
67942 ++ fd = sys_open((char __user *)name, 0, 0);
67943 + if (fd < 0) {
67944 + printk(KERN_ERR "md: open failed - cannot start "
67945 + "array %s\n", name);
67946 +@@ -229,7 +229,7 @@ static void __init md_setup_drive(void)
67947 + * array without it
67948 + */
67949 + sys_close(fd);
67950 +- fd = sys_open(name, 0, 0);
67951 ++ fd = sys_open((char __user *)name, 0, 0);
67952 + sys_ioctl(fd, BLKRRPART, 0);
67953 + }
67954 + sys_close(fd);
67955 +@@ -270,7 +270,7 @@ void __init md_run_setup(void)
67956 + if (raid_noautodetect)
67957 + printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
67958 + else {
67959 +- int fd = sys_open("/dev/md0", 0, 0);
67960 ++ int fd = sys_open((char __user *)"/dev/md0", 0, 0);
67961 + if (fd >= 0) {
67962 + sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
67963 + sys_close(fd);
67964 +diff -urNp linux-2.6.27.7/init/initramfs.c linux-2.6.27.7/init/initramfs.c
67965 +--- linux-2.6.27.7/init/initramfs.c 2008-11-07 12:55:34.000000000 -0500
67966 ++++ linux-2.6.27.7/init/initramfs.c 2008-11-18 03:38:45.000000000 -0500
67967 +@@ -230,7 +230,7 @@ static int __init maybe_link(void)
67968 + if (nlink >= 2) {
67969 + char *old = find_link(major, minor, ino, mode, collected);
67970 + if (old)
67971 +- return (sys_link(old, collected) < 0) ? -1 : 1;
67972 ++ return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1;
67973 + }
67974 + return 0;
67975 + }
67976 +@@ -239,11 +239,11 @@ static void __init clean_path(char *path
67977 + {
67978 + struct stat st;
67979 +
67980 +- if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
67981 ++ if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
67982 + if (S_ISDIR(st.st_mode))
67983 +- sys_rmdir(path);
67984 ++ sys_rmdir((char __user *)path);
67985 + else
67986 +- sys_unlink(path);
67987 ++ sys_unlink((char __user *)path);
67988 + }
67989 + }
67990 +
67991 +@@ -266,7 +266,7 @@ static int __init do_name(void)
67992 + int openflags = O_WRONLY|O_CREAT;
67993 + if (ml != 1)
67994 + openflags |= O_TRUNC;
67995 +- wfd = sys_open(collected, openflags, mode);
67996 ++ wfd = sys_open((char __user *)collected, openflags, mode);
67997 +
67998 + if (wfd >= 0) {
67999 + sys_fchown(wfd, uid, gid);
68000 +@@ -275,15 +275,15 @@ static int __init do_name(void)
68001 + }
68002 + }
68003 + } else if (S_ISDIR(mode)) {
68004 +- sys_mkdir(collected, mode);
68005 +- sys_chown(collected, uid, gid);
68006 +- sys_chmod(collected, mode);
68007 ++ sys_mkdir((char __user *)collected, mode);
68008 ++ sys_chown((char __user *)collected, uid, gid);
68009 ++ sys_chmod((char __user *)collected, mode);
68010 + } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
68011 + S_ISFIFO(mode) || S_ISSOCK(mode)) {
68012 + if (maybe_link() == 0) {
68013 +- sys_mknod(collected, mode, rdev);
68014 +- sys_chown(collected, uid, gid);
68015 +- sys_chmod(collected, mode);
68016 ++ sys_mknod((char __user *)collected, mode, rdev);
68017 ++ sys_chown((char __user *)collected, uid, gid);
68018 ++ sys_chmod((char __user *)collected, mode);
68019 + }
68020 + }
68021 + return 0;
68022 +@@ -292,13 +292,13 @@ static int __init do_name(void)
68023 + static int __init do_copy(void)
68024 + {
68025 + if (count >= body_len) {
68026 +- sys_write(wfd, victim, body_len);
68027 ++ sys_write(wfd, (char __user *)victim, body_len);
68028 + sys_close(wfd);
68029 + eat(body_len);
68030 + state = SkipIt;
68031 + return 0;
68032 + } else {
68033 +- sys_write(wfd, victim, count);
68034 ++ sys_write(wfd, (char __user *)victim, count);
68035 + body_len -= count;
68036 + eat(count);
68037 + return 1;
68038 +@@ -309,8 +309,8 @@ static int __init do_symlink(void)
68039 + {
68040 + collected[N_ALIGN(name_len) + body_len] = '\0';
68041 + clean_path(collected, 0);
68042 +- sys_symlink(collected + N_ALIGN(name_len), collected);
68043 +- sys_lchown(collected, uid, gid);
68044 ++ sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected);
68045 ++ sys_lchown((char __user *)collected, uid, gid);
68046 + state = SkipIt;
68047 + next_state = Reset;
68048 + return 0;
68049 +diff -urNp linux-2.6.27.7/init/Kconfig linux-2.6.27.7/init/Kconfig
68050 +--- linux-2.6.27.7/init/Kconfig 2008-11-07 12:55:34.000000000 -0500
68051 ++++ linux-2.6.27.7/init/Kconfig 2008-11-18 03:38:45.000000000 -0500
68052 +@@ -561,6 +561,7 @@ config SYSCTL_SYSCALL
68053 + config KALLSYMS
68054 + bool "Load all symbols for debugging/ksymoops" if EMBEDDED
68055 + default y
68056 ++ depends on !GRKERNSEC_HIDESYM
68057 + help
68058 + Say Y here to let the kernel print out symbolic crash information and
68059 + symbolic stack backtraces. This increases the size of the kernel
68060 +@@ -780,8 +781,8 @@ config MARKERS
68061 + source "arch/Kconfig"
68062 +
68063 + config PROC_PAGE_MONITOR
68064 +- default y
68065 +- depends on PROC_FS && MMU
68066 ++ default n
68067 ++ depends on PROC_FS && MMU && !GRKERNSEC
68068 + bool "Enable /proc page monitoring" if EMBEDDED
68069 + help
68070 + Various /proc files exist to monitor process memory utilization:
68071 +@@ -797,9 +798,9 @@ config HAVE_GENERIC_DMA_COHERENT
68072 +
68073 + config SLABINFO
68074 + bool
68075 +- depends on PROC_FS
68076 ++ depends on PROC_FS && !GRKERNSEC_PROC_ADD
68077 + depends on SLAB || SLUB_DEBUG
68078 +- default y
68079 ++ default n
68080 +
68081 + config RT_MUTEXES
68082 + boolean
68083 +diff -urNp linux-2.6.27.7/init/main.c linux-2.6.27.7/init/main.c
68084 +--- linux-2.6.27.7/init/main.c 2008-11-07 12:55:34.000000000 -0500
68085 ++++ linux-2.6.27.7/init/main.c 2008-11-18 03:38:45.000000000 -0500
68086 +@@ -101,6 +101,7 @@ static inline void mark_rodata_ro(void)
68087 + #ifdef CONFIG_TC
68088 + extern void tc_init(void);
68089 + #endif
68090 ++extern void grsecurity_init(void);
68091 +
68092 + enum system_states system_state;
68093 + EXPORT_SYMBOL(system_state);
68094 +@@ -187,6 +188,40 @@ static int __init set_reset_devices(char
68095 +
68096 + __setup("reset_devices", set_reset_devices);
68097 +
68098 ++#if defined(CONFIG_PAX_MEMORY_UDEREF) && defined(CONFIG_X86_32)
68099 ++static int __init setup_pax_nouderef(char *str)
68100 ++{
68101 ++ unsigned int cpu;
68102 ++
68103 ++#ifdef CONFIG_PAX_KERNEXEC
68104 ++ unsigned long cr0;
68105 ++
68106 ++ pax_open_kernel(cr0);
68107 ++#endif
68108 ++
68109 ++ for (cpu = 0; cpu < NR_CPUS; cpu++)
68110 ++ get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_DS].b = 0x00cf9300;
68111 ++
68112 ++#ifdef CONFIG_PAX_KERNEXEC
68113 ++ pax_close_kernel(cr0);
68114 ++#endif
68115 ++
68116 ++ return 1;
68117 ++}
68118 ++__setup("pax_nouderef", setup_pax_nouderef);
68119 ++#endif
68120 ++
68121 ++#ifdef CONFIG_PAX_SOFTMODE
68122 ++unsigned int pax_softmode;
68123 ++
68124 ++static int __init setup_pax_softmode(char *str)
68125 ++{
68126 ++ get_option(&str, &pax_softmode);
68127 ++ return 1;
68128 ++}
68129 ++__setup("pax_softmode=", setup_pax_softmode);
68130 ++#endif
68131 ++
68132 + static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
68133 + char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
68134 + static const char *panic_later, *panic_param;
68135 +@@ -385,7 +420,7 @@ static void __init setup_nr_cpu_ids(void
68136 + }
68137 +
68138 + #ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
68139 +-unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
68140 ++unsigned long __per_cpu_offset[NR_CPUS] __read_only;
68141 +
68142 + EXPORT_SYMBOL(__per_cpu_offset);
68143 +
68144 +@@ -704,6 +739,7 @@ int do_one_initcall(initcall_t fn)
68145 + {
68146 + int count = preempt_count();
68147 + ktime_t t0, t1, delta;
68148 ++ const char *msg1 = "", *msg2 = "";
68149 + char msgbuf[64];
68150 + int result;
68151 +
68152 +@@ -729,15 +765,15 @@ int do_one_initcall(initcall_t fn)
68153 + sprintf(msgbuf, "error code %d ", result);
68154 +
68155 + if (preempt_count() != count) {
68156 +- strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf));
68157 ++ msg1 = " preemption imbalance";
68158 + preempt_count() = count;
68159 + }
68160 + if (irqs_disabled()) {
68161 +- strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf));
68162 ++ msg2 = " disabled interrupts";
68163 + local_irq_enable();
68164 + }
68165 +- if (msgbuf[0]) {
68166 +- printk("initcall %pF returned with %s\n", fn, msgbuf);
68167 ++ if (msgbuf[0] || *msg1 || *msg2) {
68168 ++ printk("initcall %pF returned with %s%s%s\n", fn, msgbuf, msg1, msg2);
68169 + }
68170 +
68171 + return result;
68172 +@@ -876,6 +912,8 @@ static int __init kernel_init(void * unu
68173 + prepare_namespace();
68174 + }
68175 +
68176 ++ grsecurity_init();
68177 ++
68178 + /*
68179 + * Ok, we have completed the initial bootup, and
68180 + * we're essentially up and running. Get rid of the
68181 +diff -urNp linux-2.6.27.7/init/noinitramfs.c linux-2.6.27.7/init/noinitramfs.c
68182 +--- linux-2.6.27.7/init/noinitramfs.c 2008-11-07 12:55:34.000000000 -0500
68183 ++++ linux-2.6.27.7/init/noinitramfs.c 2008-11-18 03:38:45.000000000 -0500
68184 +@@ -29,7 +29,7 @@ static int __init default_rootfs(void)
68185 + {
68186 + int err;
68187 +
68188 +- err = sys_mkdir("/dev", 0755);
68189 ++ err = sys_mkdir((const char __user *)"/dev", 0755);
68190 + if (err < 0)
68191 + goto out;
68192 +
68193 +@@ -39,7 +39,7 @@ static int __init default_rootfs(void)
68194 + if (err < 0)
68195 + goto out;
68196 +
68197 +- err = sys_mkdir("/root", 0700);
68198 ++ err = sys_mkdir((const char __user *)"/root", 0700);
68199 + if (err < 0)
68200 + goto out;
68201 +
68202 +diff -urNp linux-2.6.27.7/ipc/ipc_sysctl.c linux-2.6.27.7/ipc/ipc_sysctl.c
68203 +--- linux-2.6.27.7/ipc/ipc_sysctl.c 2008-11-07 12:55:34.000000000 -0500
68204 ++++ linux-2.6.27.7/ipc/ipc_sysctl.c 2008-11-18 03:38:45.000000000 -0500
68205 +@@ -268,7 +268,7 @@ static struct ctl_table ipc_kern_table[]
68206 + .extra1 = &zero,
68207 + .extra2 = &one,
68208 + },
68209 +- {}
68210 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
68211 + };
68212 +
68213 + static struct ctl_table ipc_root_table[] = {
68214 +@@ -278,7 +278,7 @@ static struct ctl_table ipc_root_table[]
68215 + .mode = 0555,
68216 + .child = ipc_kern_table,
68217 + },
68218 +- {}
68219 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
68220 + };
68221 +
68222 + static int __init ipc_sysctl_init(void)
68223 +diff -urNp linux-2.6.27.7/ipc/msg.c linux-2.6.27.7/ipc/msg.c
68224 +--- linux-2.6.27.7/ipc/msg.c 2008-11-07 12:55:34.000000000 -0500
68225 ++++ linux-2.6.27.7/ipc/msg.c 2008-11-18 03:38:45.000000000 -0500
68226 +@@ -38,6 +38,7 @@
68227 + #include <linux/rwsem.h>
68228 + #include <linux/nsproxy.h>
68229 + #include <linux/ipc_namespace.h>
68230 ++#include <linux/grsecurity.h>
68231 +
68232 + #include <asm/current.h>
68233 + #include <asm/uaccess.h>
68234 +@@ -314,6 +315,7 @@ asmlinkage long sys_msgget(key_t key, in
68235 + struct ipc_namespace *ns;
68236 + struct ipc_ops msg_ops;
68237 + struct ipc_params msg_params;
68238 ++ long err;
68239 +
68240 + ns = current->nsproxy->ipc_ns;
68241 +
68242 +@@ -324,7 +326,11 @@ asmlinkage long sys_msgget(key_t key, in
68243 + msg_params.key = key;
68244 + msg_params.flg = msgflg;
68245 +
68246 +- return ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
68247 ++ err = ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
68248 ++
68249 ++ gr_log_msgget(err, msgflg);
68250 ++
68251 ++ return err;
68252 + }
68253 +
68254 + static inline unsigned long
68255 +@@ -434,6 +440,7 @@ static int msgctl_down(struct ipc_namesp
68256 +
68257 + switch (cmd) {
68258 + case IPC_RMID:
68259 ++ gr_log_msgrm(ipcp->uid, ipcp->cuid);
68260 + freeque(ns, ipcp);
68261 + goto out_up;
68262 + case IPC_SET:
68263 +diff -urNp linux-2.6.27.7/ipc/sem.c linux-2.6.27.7/ipc/sem.c
68264 +--- linux-2.6.27.7/ipc/sem.c 2008-11-07 12:55:34.000000000 -0500
68265 ++++ linux-2.6.27.7/ipc/sem.c 2008-11-18 03:38:45.000000000 -0500
68266 +@@ -83,6 +83,7 @@
68267 + #include <linux/rwsem.h>
68268 + #include <linux/nsproxy.h>
68269 + #include <linux/ipc_namespace.h>
68270 ++#include <linux/grsecurity.h>
68271 +
68272 + #include <asm/uaccess.h>
68273 + #include "util.h"
68274 +@@ -313,6 +314,7 @@ asmlinkage long sys_semget(key_t key, in
68275 + struct ipc_namespace *ns;
68276 + struct ipc_ops sem_ops;
68277 + struct ipc_params sem_params;
68278 ++ long err;
68279 +
68280 + ns = current->nsproxy->ipc_ns;
68281 +
68282 +@@ -327,7 +329,11 @@ asmlinkage long sys_semget(key_t key, in
68283 + sem_params.flg = semflg;
68284 + sem_params.u.nsems = nsems;
68285 +
68286 +- return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
68287 ++ err = ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
68288 ++
68289 ++ gr_log_semget(err, semflg);
68290 ++
68291 ++ return err;
68292 + }
68293 +
68294 + /*
68295 +@@ -870,6 +876,7 @@ static int semctl_down(struct ipc_namesp
68296 +
68297 + switch(cmd){
68298 + case IPC_RMID:
68299 ++ gr_log_semrm(ipcp->uid, ipcp->cuid);
68300 + freeary(ns, ipcp);
68301 + goto out_up;
68302 + case IPC_SET:
68303 +diff -urNp linux-2.6.27.7/ipc/shm.c linux-2.6.27.7/ipc/shm.c
68304 +--- linux-2.6.27.7/ipc/shm.c 2008-11-07 12:55:34.000000000 -0500
68305 ++++ linux-2.6.27.7/ipc/shm.c 2008-11-18 03:38:45.000000000 -0500
68306 +@@ -39,6 +39,7 @@
68307 + #include <linux/nsproxy.h>
68308 + #include <linux/mount.h>
68309 + #include <linux/ipc_namespace.h>
68310 ++#include <linux/grsecurity.h>
68311 +
68312 + #include <asm/uaccess.h>
68313 +
68314 +@@ -69,6 +70,14 @@ static void shm_destroy (struct ipc_name
68315 + static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
68316 + #endif
68317 +
68318 ++#ifdef CONFIG_GRKERNSEC
68319 ++extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
68320 ++ const time_t shm_createtime, const uid_t cuid,
68321 ++ const int shmid);
68322 ++extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
68323 ++ const time_t shm_createtime);
68324 ++#endif
68325 ++
68326 + void shm_init_ns(struct ipc_namespace *ns)
68327 + {
68328 + ns->shm_ctlmax = SHMMAX;
68329 +@@ -87,6 +96,8 @@ static void do_shm_rmid(struct ipc_names
68330 + struct shmid_kernel *shp;
68331 + shp = container_of(ipcp, struct shmid_kernel, shm_perm);
68332 +
68333 ++ gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
68334 ++
68335 + if (shp->shm_nattch){
68336 + shp->shm_perm.mode |= SHM_DEST;
68337 + /* Do not find it any more */
68338 +@@ -392,6 +403,14 @@ static int newseg(struct ipc_namespace *
68339 + shp->shm_lprid = 0;
68340 + shp->shm_atim = shp->shm_dtim = 0;
68341 + shp->shm_ctim = get_seconds();
68342 ++#ifdef CONFIG_GRKERNSEC
68343 ++ {
68344 ++ struct timespec timeval;
68345 ++ do_posix_clock_monotonic_gettime(&timeval);
68346 ++
68347 ++ shp->shm_createtime = timeval.tv_sec;
68348 ++ }
68349 ++#endif
68350 + shp->shm_segsz = size;
68351 + shp->shm_nattch = 0;
68352 + shp->shm_file = file;
68353 +@@ -445,6 +464,7 @@ asmlinkage long sys_shmget (key_t key, s
68354 + struct ipc_namespace *ns;
68355 + struct ipc_ops shm_ops;
68356 + struct ipc_params shm_params;
68357 ++ long err;
68358 +
68359 + ns = current->nsproxy->ipc_ns;
68360 +
68361 +@@ -456,7 +476,11 @@ asmlinkage long sys_shmget (key_t key, s
68362 + shm_params.flg = shmflg;
68363 + shm_params.u.size = size;
68364 +
68365 +- return ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
68366 ++ err = ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
68367 ++
68368 ++ gr_log_shmget(err, shmflg, size);
68369 ++
68370 ++ return err;
68371 + }
68372 +
68373 + static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version)
68374 +@@ -869,9 +893,21 @@ long do_shmat(int shmid, char __user *sh
68375 + if (err)
68376 + goto out_unlock;
68377 +
68378 ++#ifdef CONFIG_GRKERNSEC
68379 ++ if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
68380 ++ shp->shm_perm.cuid, shmid) ||
68381 ++ !gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
68382 ++ err = -EACCES;
68383 ++ goto out_unlock;
68384 ++ }
68385 ++#endif
68386 ++
68387 + path.dentry = dget(shp->shm_file->f_path.dentry);
68388 + path.mnt = shp->shm_file->f_path.mnt;
68389 + shp->shm_nattch++;
68390 ++#ifdef CONFIG_GRKERNSEC
68391 ++ shp->shm_lapid = current->pid;
68392 ++#endif
68393 + size = i_size_read(path.dentry->d_inode);
68394 + shm_unlock(shp);
68395 +
68396 +diff -urNp linux-2.6.27.7/kernel/acct.c linux-2.6.27.7/kernel/acct.c
68397 +--- linux-2.6.27.7/kernel/acct.c 2008-11-07 12:55:34.000000000 -0500
68398 ++++ linux-2.6.27.7/kernel/acct.c 2008-11-18 03:38:45.000000000 -0500
68399 +@@ -573,7 +573,7 @@ static void do_acct_process(struct bsd_a
68400 + */
68401 + flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
68402 + current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
68403 +- file->f_op->write(file, (char *)&ac,
68404 ++ file->f_op->write(file, (char __user *)&ac,
68405 + sizeof(acct_t), &file->f_pos);
68406 + current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
68407 + set_fs(fs);
68408 +diff -urNp linux-2.6.27.7/kernel/capability.c linux-2.6.27.7/kernel/capability.c
68409 +--- linux-2.6.27.7/kernel/capability.c 2008-11-07 12:55:34.000000000 -0500
68410 ++++ linux-2.6.27.7/kernel/capability.c 2008-11-18 03:38:45.000000000 -0500
68411 +@@ -13,6 +13,7 @@
68412 + #include <linux/security.h>
68413 + #include <linux/syscalls.h>
68414 + #include <linux/pid_namespace.h>
68415 ++#include <linux/grsecurity.h>
68416 + #include <asm/uaccess.h>
68417 +
68418 + /*
68419 +@@ -498,10 +499,21 @@ asmlinkage long sys_capset(cap_user_head
68420 + */
68421 + int capable(int cap)
68422 + {
68423 +- if (has_capability(current, cap)) {
68424 ++ if (has_capability(current, cap) && gr_task_is_capable(current, cap)) {
68425 + current->flags |= PF_SUPERPRIV;
68426 + return 1;
68427 + }
68428 + return 0;
68429 + }
68430 ++
68431 ++int capable_nolog(int cap)
68432 ++{
68433 ++ if (has_capability(current, cap) && gr_is_capable_nolog(cap)) {
68434 ++ current->flags |= PF_SUPERPRIV;
68435 ++ return 1;
68436 ++ }
68437 ++ return 0;
68438 ++}
68439 ++
68440 + EXPORT_SYMBOL(capable);
68441 ++EXPORT_SYMBOL(capable_nolog);
68442 +diff -urNp linux-2.6.27.7/kernel/configs.c linux-2.6.27.7/kernel/configs.c
68443 +--- linux-2.6.27.7/kernel/configs.c 2008-11-07 12:55:34.000000000 -0500
68444 ++++ linux-2.6.27.7/kernel/configs.c 2008-11-18 03:38:45.000000000 -0500
68445 +@@ -79,8 +79,19 @@ static int __init ikconfig_init(void)
68446 + struct proc_dir_entry *entry;
68447 +
68448 + /* create the current config file */
68449 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
68450 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
68451 ++ entry = proc_create("config.gz", S_IFREG | S_IRUSR, NULL,
68452 ++ &ikconfig_file_ops);
68453 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
68454 ++ entry = proc_create("config.gz", S_IFREG | S_IRUSR | S_IRGRP, NULL,
68455 ++ &ikconfig_file_ops);
68456 ++#endif
68457 ++#else
68458 + entry = proc_create("config.gz", S_IFREG | S_IRUGO, NULL,
68459 + &ikconfig_file_ops);
68460 ++#endif
68461 ++
68462 + if (!entry)
68463 + return -ENOMEM;
68464 +
68465 +diff -urNp linux-2.6.27.7/kernel/cpu.c linux-2.6.27.7/kernel/cpu.c
68466 +--- linux-2.6.27.7/kernel/cpu.c 2008-11-07 12:55:34.000000000 -0500
68467 ++++ linux-2.6.27.7/kernel/cpu.c 2008-11-18 03:38:45.000000000 -0500
68468 +@@ -40,7 +40,7 @@ EXPORT_SYMBOL(cpu_possible_map);
68469 + /* Serializes the updates to cpu_online_map, cpu_present_map */
68470 + static DEFINE_MUTEX(cpu_add_remove_lock);
68471 +
68472 +-static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain);
68473 ++static RAW_NOTIFIER_HEAD(cpu_chain);
68474 +
68475 + /* If set, cpu_up and cpu_down will return -EBUSY and do nothing.
68476 + * Should always be manipulated under cpu_add_remove_lock
68477 +diff -urNp linux-2.6.27.7/kernel/exit.c linux-2.6.27.7/kernel/exit.c
68478 +--- linux-2.6.27.7/kernel/exit.c 2008-11-07 12:55:34.000000000 -0500
68479 ++++ linux-2.6.27.7/kernel/exit.c 2008-11-18 11:34:28.000000000 -0500
68480 +@@ -47,6 +47,11 @@
68481 + #include <linux/blkdev.h>
68482 + #include <linux/task_io_accounting_ops.h>
68483 + #include <linux/tracehook.h>
68484 ++#include <linux/grsecurity.h>
68485 ++
68486 ++#ifdef CONFIG_GRKERNSEC
68487 ++extern rwlock_t grsec_exec_file_lock;
68488 ++#endif
68489 +
68490 + #include <asm/uaccess.h>
68491 + #include <asm/unistd.h>
68492 +@@ -133,7 +138,6 @@ static void __exit_signal(struct task_st
68493 + * doing sigqueue_free() if we have SIGQUEUE_PREALLOC signals.
68494 + */
68495 + flush_sigqueue(&tsk->pending);
68496 +-
68497 + tsk->signal = NULL;
68498 + tsk->sighand = NULL;
68499 + spin_unlock(&sighand->siglock);
68500 +@@ -158,6 +162,8 @@ void release_task(struct task_struct * p
68501 + struct task_struct *leader;
68502 + int zap_leader;
68503 + repeat:
68504 ++ gr_del_task_from_ip_table(p);
68505 ++
68506 + tracehook_prepare_release_task(p);
68507 + atomic_dec(&p->user->processes);
68508 + proc_flush_task(p);
68509 +@@ -321,11 +327,22 @@ static void reparent_to_kthreadd(void)
68510 + {
68511 + write_lock_irq(&tasklist_lock);
68512 +
68513 ++#ifdef CONFIG_GRKERNSEC
68514 ++ write_lock(&grsec_exec_file_lock);
68515 ++ if (current->exec_file) {
68516 ++ fput(current->exec_file);
68517 ++ current->exec_file = NULL;
68518 ++ }
68519 ++ write_unlock(&grsec_exec_file_lock);
68520 ++#endif
68521 ++
68522 + ptrace_unlink(current);
68523 + /* Reparent to init */
68524 + current->real_parent = current->parent = kthreadd_task;
68525 + list_move_tail(&current->sibling, &current->real_parent->children);
68526 +
68527 ++ gr_set_kernel_label(current);
68528 ++
68529 + /* Set the exit signal to SIGCHLD so we signal init on exit */
68530 + current->exit_signal = SIGCHLD;
68531 +
68532 +@@ -419,6 +436,17 @@ void daemonize(const char *name, ...)
68533 + vsnprintf(current->comm, sizeof(current->comm), name, args);
68534 + va_end(args);
68535 +
68536 ++#ifdef CONFIG_GRKERNSEC
68537 ++ write_lock(&grsec_exec_file_lock);
68538 ++ if (current->exec_file) {
68539 ++ fput(current->exec_file);
68540 ++ current->exec_file = NULL;
68541 ++ }
68542 ++ write_unlock(&grsec_exec_file_lock);
68543 ++#endif
68544 ++
68545 ++ gr_set_kernel_label(current);
68546 ++
68547 + /*
68548 + * If we were started as result of loading a module, close all of the
68549 + * user space pages. We don't need them, and if we didn't close them
68550 +@@ -1070,6 +1098,9 @@ NORET_TYPE void do_exit(long code)
68551 + tsk->exit_code = code;
68552 + taskstats_exit(tsk, group_dead);
68553 +
68554 ++ gr_acl_handle_psacct(tsk, code);
68555 ++ gr_acl_handle_exit();
68556 ++
68557 + exit_mm(tsk);
68558 +
68559 + if (group_dead)
68560 +@@ -1272,7 +1303,7 @@ static int wait_task_zombie(struct task_
68561 + if (unlikely(options & WNOWAIT)) {
68562 + uid_t uid = p->uid;
68563 + int exit_code = p->exit_code;
68564 +- int why, status;
68565 ++ int why;
68566 +
68567 + get_task_struct(p);
68568 + read_unlock(&tasklist_lock);
68569 +diff -urNp linux-2.6.27.7/kernel/fork.c linux-2.6.27.7/kernel/fork.c
68570 +--- linux-2.6.27.7/kernel/fork.c 2008-11-07 12:55:34.000000000 -0500
68571 ++++ linux-2.6.27.7/kernel/fork.c 2008-11-18 03:38:45.000000000 -0500
68572 +@@ -58,6 +58,7 @@
68573 + #include <linux/tty.h>
68574 + #include <linux/proc_fs.h>
68575 + #include <linux/blkdev.h>
68576 ++#include <linux/grsecurity.h>
68577 +
68578 + #include <asm/pgtable.h>
68579 + #include <asm/pgalloc.h>
68580 +@@ -234,7 +235,7 @@ static struct task_struct *dup_task_stru
68581 + setup_thread_stack(tsk, orig);
68582 +
68583 + #ifdef CONFIG_CC_STACKPROTECTOR
68584 +- tsk->stack_canary = get_random_int();
68585 ++ tsk->stack_canary = pax_get_random_long();
68586 + #endif
68587 +
68588 + /* One for us, one for whoever does the "release_task()" (usually parent) */
68589 +@@ -271,8 +272,8 @@ static int dup_mmap(struct mm_struct *mm
68590 + mm->locked_vm = 0;
68591 + mm->mmap = NULL;
68592 + mm->mmap_cache = NULL;
68593 +- mm->free_area_cache = oldmm->mmap_base;
68594 +- mm->cached_hole_size = ~0UL;
68595 ++ mm->free_area_cache = oldmm->free_area_cache;
68596 ++ mm->cached_hole_size = oldmm->cached_hole_size;
68597 + mm->map_count = 0;
68598 + cpus_clear(mm->cpu_vm_mask);
68599 + mm->mm_rb = RB_ROOT;
68600 +@@ -309,6 +310,7 @@ static int dup_mmap(struct mm_struct *mm
68601 + tmp->vm_flags &= ~VM_LOCKED;
68602 + tmp->vm_mm = mm;
68603 + tmp->vm_next = NULL;
68604 ++ tmp->vm_mirror = NULL;
68605 + anon_vma_link(tmp);
68606 + file = tmp->vm_file;
68607 + if (file) {
68608 +@@ -353,6 +355,31 @@ static int dup_mmap(struct mm_struct *mm
68609 + if (retval)
68610 + goto out;
68611 + }
68612 ++
68613 ++#ifdef CONFIG_PAX_SEGMEXEC
68614 ++ if (oldmm->pax_flags & MF_PAX_SEGMEXEC) {
68615 ++ struct vm_area_struct *mpnt_m;
68616 ++
68617 ++ for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) {
68618 ++ BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm);
68619 ++
68620 ++ if (!mpnt->vm_mirror)
68621 ++ continue;
68622 ++
68623 ++ if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) {
68624 ++ BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt);
68625 ++ mpnt->vm_mirror = mpnt_m;
68626 ++ } else {
68627 ++ BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm);
68628 ++ mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror;
68629 ++ mpnt_m->vm_mirror->vm_mirror = mpnt_m;
68630 ++ mpnt->vm_mirror->vm_mirror = mpnt;
68631 ++ }
68632 ++ }
68633 ++ BUG_ON(mpnt_m);
68634 ++ }
68635 ++#endif
68636 ++
68637 + /* a new mm has just been created */
68638 + arch_dup_mmap(oldmm, mm);
68639 + retval = 0;
68640 +@@ -536,7 +563,7 @@ void mm_release(struct task_struct *tsk,
68641 + if (tsk->clear_child_tid
68642 + && !(tsk->flags & PF_SIGNALED)
68643 + && atomic_read(&mm->mm_users) > 1) {
68644 +- u32 __user * tidptr = tsk->clear_child_tid;
68645 ++ pid_t __user * tidptr = tsk->clear_child_tid;
68646 + tsk->clear_child_tid = NULL;
68647 +
68648 + /*
68649 +@@ -544,7 +571,7 @@ void mm_release(struct task_struct *tsk,
68650 + * not set up a proper pointer then tough luck.
68651 + */
68652 + put_user(0, tidptr);
68653 +- sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
68654 ++ sys_futex((u32 __user *)tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
68655 + }
68656 + }
68657 +
68658 +@@ -939,6 +966,9 @@ static struct task_struct *copy_process(
68659 + DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
68660 + #endif
68661 + retval = -EAGAIN;
68662 ++
68663 ++ gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
68664 ++
68665 + if (atomic_read(&p->user->processes) >=
68666 + p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
68667 + if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
68668 +@@ -1105,6 +1135,8 @@ static struct task_struct *copy_process(
68669 + goto bad_fork_free_pid;
68670 + }
68671 +
68672 ++ gr_copy_label(p);
68673 ++
68674 + p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
68675 + /*
68676 + * Clear TID on mm_release()?
68677 +@@ -1290,6 +1322,8 @@ bad_fork_cleanup_count:
68678 + bad_fork_free:
68679 + free_task(p);
68680 + fork_out:
68681 ++ gr_log_forkfail(retval);
68682 ++
68683 + return ERR_PTR(retval);
68684 + }
68685 +
68686 +@@ -1366,6 +1400,8 @@ long do_fork(unsigned long clone_flags,
68687 + if (clone_flags & CLONE_PARENT_SETTID)
68688 + put_user(nr, parent_tidptr);
68689 +
68690 ++ gr_handle_brute_check();
68691 ++
68692 + if (clone_flags & CLONE_VFORK) {
68693 + p->vfork_done = &vfork;
68694 + init_completion(&vfork);
68695 +diff -urNp linux-2.6.27.7/kernel/futex.c linux-2.6.27.7/kernel/futex.c
68696 +--- linux-2.6.27.7/kernel/futex.c 2008-11-07 12:55:34.000000000 -0500
68697 ++++ linux-2.6.27.7/kernel/futex.c 2008-11-18 03:38:45.000000000 -0500
68698 +@@ -188,6 +188,11 @@ static int get_futex_key(u32 __user *uad
68699 + struct page *page;
68700 + int err;
68701 +
68702 ++#ifdef CONFIG_PAX_SEGMEXEC
68703 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && address >= SEGMEXEC_TASK_SIZE)
68704 ++ return -EFAULT;
68705 ++#endif
68706 ++
68707 + /*
68708 + * The futex address must be "naturally" aligned.
68709 + */
68710 +@@ -214,8 +219,8 @@ static int get_futex_key(u32 __user *uad
68711 + * The futex is hashed differently depending on whether
68712 + * it's in a shared or private mapping. So check vma first.
68713 + */
68714 +- vma = find_extend_vma(mm, address);
68715 +- if (unlikely(!vma))
68716 ++ vma = find_vma(mm, address);
68717 ++ if (unlikely(!vma || address < vma->vm_start))
68718 + return -EFAULT;
68719 +
68720 + /*
68721 +@@ -1345,7 +1350,7 @@ static int futex_wait(u32 __user *uaddr,
68722 + struct restart_block *restart;
68723 + restart = &current_thread_info()->restart_block;
68724 + restart->fn = futex_wait_restart;
68725 +- restart->futex.uaddr = (u32 *)uaddr;
68726 ++ restart->futex.uaddr = uaddr;
68727 + restart->futex.val = val;
68728 + restart->futex.time = abs_time->tv64;
68729 + restart->futex.bitset = bitset;
68730 +@@ -1906,7 +1911,7 @@ retry:
68731 + */
68732 + static inline int fetch_robust_entry(struct robust_list __user **entry,
68733 + struct robust_list __user * __user *head,
68734 +- int *pi)
68735 ++ unsigned int *pi)
68736 + {
68737 + unsigned long uentry;
68738 +
68739 +diff -urNp linux-2.6.27.7/kernel/irq/handle.c linux-2.6.27.7/kernel/irq/handle.c
68740 +--- linux-2.6.27.7/kernel/irq/handle.c 2008-11-07 12:55:34.000000000 -0500
68741 ++++ linux-2.6.27.7/kernel/irq/handle.c 2008-11-18 03:38:45.000000000 -0500
68742 +@@ -55,7 +55,8 @@ struct irq_desc irq_desc[NR_IRQS] __cach
68743 + .depth = 1,
68744 + .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
68745 + #ifdef CONFIG_SMP
68746 +- .affinity = CPU_MASK_ALL
68747 ++ .affinity = CPU_MASK_ALL,
68748 ++ .cpu = 0,
68749 + #endif
68750 + }
68751 + };
68752 +diff -urNp linux-2.6.27.7/kernel/kallsyms.c linux-2.6.27.7/kernel/kallsyms.c
68753 +--- linux-2.6.27.7/kernel/kallsyms.c 2008-11-07 12:55:34.000000000 -0500
68754 ++++ linux-2.6.27.7/kernel/kallsyms.c 2008-11-18 03:38:45.000000000 -0500
68755 +@@ -62,6 +62,19 @@ static inline int is_kernel_text(unsigne
68756 +
68757 + static inline int is_kernel(unsigned long addr)
68758 + {
68759 ++
68760 ++#ifdef CONFIG_PAX_KERNEXEC
68761 ++
68762 ++#ifdef CONFIG_MODULES
68763 ++ if ((unsigned long)MODULES_VADDR <= ktla_ktva(addr) &&
68764 ++ ktla_ktva(addr) < (unsigned long)MODULES_END)
68765 ++ return 0;
68766 ++#endif
68767 ++
68768 ++ if (is_kernel_inittext(addr))
68769 ++ return 1;
68770 ++#endif
68771 ++
68772 + if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
68773 + return 1;
68774 + return in_gate_area_no_task(addr);
68775 +@@ -366,7 +379,6 @@ static unsigned long get_ksymbol_core(st
68776 +
68777 + static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
68778 + {
68779 +- iter->name[0] = '\0';
68780 + iter->nameoff = get_symbol_offset(new_pos);
68781 + iter->pos = new_pos;
68782 + }
68783 +@@ -450,7 +462,7 @@ static int kallsyms_open(struct inode *i
68784 + struct kallsym_iter *iter;
68785 + int ret;
68786 +
68787 +- iter = kmalloc(sizeof(*iter), GFP_KERNEL);
68788 ++ iter = kzalloc(sizeof(*iter), GFP_KERNEL);
68789 + if (!iter)
68790 + return -ENOMEM;
68791 + reset_iter(iter, 0);
68792 +@@ -472,7 +484,15 @@ static const struct file_operations kall
68793 +
68794 + static int __init kallsyms_init(void)
68795 + {
68796 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
68797 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
68798 ++ proc_create("kallsyms", S_IFREG | S_IRUSR, NULL, &kallsyms_operations);
68799 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
68800 ++ proc_create("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL, &kallsyms_operations);
68801 ++#endif
68802 ++#else
68803 + proc_create("kallsyms", 0444, NULL, &kallsyms_operations);
68804 ++#endif
68805 + return 0;
68806 + }
68807 + __initcall(kallsyms_init);
68808 +diff -urNp linux-2.6.27.7/kernel/kmod.c linux-2.6.27.7/kernel/kmod.c
68809 +--- linux-2.6.27.7/kernel/kmod.c 2008-11-07 12:55:34.000000000 -0500
68810 ++++ linux-2.6.27.7/kernel/kmod.c 2008-11-18 03:38:45.000000000 -0500
68811 +@@ -108,7 +108,7 @@ int request_module(const char *fmt, ...)
68812 + return -ENOMEM;
68813 + }
68814 +
68815 +- ret = call_usermodehelper(modprobe_path, argv, envp, 1);
68816 ++ ret = call_usermodehelper(modprobe_path, argv, envp, UMH_WAIT_PROC);
68817 + atomic_dec(&kmod_concurrent);
68818 + return ret;
68819 + }
68820 +diff -urNp linux-2.6.27.7/kernel/kprobes.c linux-2.6.27.7/kernel/kprobes.c
68821 +--- linux-2.6.27.7/kernel/kprobes.c 2008-11-07 12:55:34.000000000 -0500
68822 ++++ linux-2.6.27.7/kernel/kprobes.c 2008-11-18 03:38:45.000000000 -0500
68823 +@@ -182,7 +182,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
68824 + * kernel image and loaded module images reside. This is required
68825 + * so x86_64 can correctly handle the %rip-relative fixups.
68826 + */
68827 +- kip->insns = module_alloc(PAGE_SIZE);
68828 ++ kip->insns = module_alloc_exec(PAGE_SIZE);
68829 + if (!kip->insns) {
68830 + kfree(kip);
68831 + return NULL;
68832 +@@ -214,7 +214,7 @@ static int __kprobes collect_one_slot(st
68833 + hlist_add_head(&kip->hlist,
68834 + &kprobe_insn_pages);
68835 + } else {
68836 +- module_free(NULL, kip->insns);
68837 ++ module_free_exec(NULL, kip->insns);
68838 + kfree(kip);
68839 + }
68840 + return 1;
68841 +diff -urNp linux-2.6.27.7/kernel/lockdep.c linux-2.6.27.7/kernel/lockdep.c
68842 +--- linux-2.6.27.7/kernel/lockdep.c 2008-11-07 12:55:34.000000000 -0500
68843 ++++ linux-2.6.27.7/kernel/lockdep.c 2008-11-18 03:38:45.000000000 -0500
68844 +@@ -627,6 +627,10 @@ static int static_obj(void *obj)
68845 + int i;
68846 + #endif
68847 +
68848 ++#ifdef CONFIG_PAX_KERNEXEC
68849 ++ start = (unsigned long )&_data;
68850 ++#endif
68851 ++
68852 + /*
68853 + * static variable?
68854 + */
68855 +@@ -638,9 +642,12 @@ static int static_obj(void *obj)
68856 + * percpu var?
68857 + */
68858 + for_each_possible_cpu(i) {
68859 ++#ifdef CONFIG_X86_32
68860 ++ start = per_cpu_offset(i);
68861 ++#else
68862 + start = (unsigned long) &__per_cpu_start + per_cpu_offset(i);
68863 +- end = (unsigned long) &__per_cpu_start + PERCPU_ENOUGH_ROOM
68864 +- + per_cpu_offset(i);
68865 ++#endif
68866 ++ end = start + PERCPU_ENOUGH_ROOM;
68867 +
68868 + if ((addr >= start) && (addr < end))
68869 + return 1;
68870 +diff -urNp linux-2.6.27.7/kernel/module.c linux-2.6.27.7/kernel/module.c
68871 +--- linux-2.6.27.7/kernel/module.c 2008-11-07 12:55:34.000000000 -0500
68872 ++++ linux-2.6.27.7/kernel/module.c 2008-11-18 04:48:35.000000000 -0500
68873 +@@ -44,6 +44,11 @@
68874 + #include <linux/unwind.h>
68875 + #include <asm/uaccess.h>
68876 + #include <asm/cacheflush.h>
68877 ++
68878 ++#ifdef CONFIG_PAX_KERNEXEC
68879 ++#include <asm/desc.h>
68880 ++#endif
68881 ++
68882 + #include <linux/license.h>
68883 + #include <asm/sections.h>
68884 +
68885 +@@ -71,7 +76,10 @@ static DECLARE_WAIT_QUEUE_HEAD(module_wq
68886 + static BLOCKING_NOTIFIER_HEAD(module_notify_list);
68887 +
68888 + /* Bounds of module allocation, for speeding __module_text_address */
68889 +-static unsigned long module_addr_min = -1UL, module_addr_max = 0;
68890 ++static unsigned long module_addr_min_rw = -1UL, module_addr_max_rw = 0;
68891 ++static unsigned long module_addr_min_rx = -1UL, module_addr_max_rx = 0;
68892 ++
68893 ++extern int gr_check_modstop(void);
68894 +
68895 + int register_module_notifier(struct notifier_block * nb)
68896 + {
68897 +@@ -217,7 +225,7 @@ static bool each_symbol(bool (*fn)(const
68898 + return true;
68899 +
68900 + list_for_each_entry(mod, &modules, list) {
68901 +- struct symsearch arr[] = {
68902 ++ struct symsearch modarr[] = {
68903 + { mod->syms, mod->syms + mod->num_syms, mod->crcs,
68904 + NOT_GPL_ONLY, false },
68905 + { mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms,
68906 +@@ -239,7 +247,7 @@ static bool each_symbol(bool (*fn)(const
68907 + #endif
68908 + };
68909 +
68910 +- if (each_symbol_in_section(arr, ARRAY_SIZE(arr), mod, fn, data))
68911 ++ if (each_symbol_in_section(modarr, ARRAY_SIZE(modarr), mod, fn, data))
68912 + return true;
68913 + }
68914 + return false;
68915 +@@ -375,6 +383,8 @@ static inline unsigned int block_size(in
68916 + return val;
68917 + }
68918 +
68919 ++EXPORT_SYMBOL(__per_cpu_start);
68920 ++
68921 + static void *percpu_modalloc(unsigned long size, unsigned long align,
68922 + const char *name)
68923 + {
68924 +@@ -382,7 +392,7 @@ static void *percpu_modalloc(unsigned lo
68925 + unsigned int i;
68926 + void *ptr;
68927 +
68928 +- if (align > PAGE_SIZE) {
68929 ++ if (align-1 >= PAGE_SIZE) {
68930 + printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
68931 + name, align, PAGE_SIZE);
68932 + align = PAGE_SIZE;
68933 +@@ -464,7 +474,11 @@ static void percpu_modcopy(void *pcpudes
68934 + int cpu;
68935 +
68936 + for_each_possible_cpu(cpu)
68937 ++#ifdef CONFIG_X86_32
68938 ++ memcpy(pcpudest + __per_cpu_offset[cpu], from, size);
68939 ++#else
68940 + memcpy(pcpudest + per_cpu_offset(cpu), from, size);
68941 ++#endif
68942 + }
68943 +
68944 + static int percpu_modinit(void)
68945 +@@ -722,6 +736,9 @@ sys_delete_module(const char __user *nam
68946 + char name[MODULE_NAME_LEN];
68947 + int ret, forced = 0;
68948 +
68949 ++ if (gr_check_modstop())
68950 ++ return -EPERM;
68951 ++
68952 + if (!capable(CAP_SYS_MODULE))
68953 + return -EPERM;
68954 +
68955 +@@ -1430,16 +1447,19 @@ static void free_module(struct module *m
68956 + module_unload_free(mod);
68957 +
68958 + /* This may be NULL, but that's OK */
68959 +- module_free(mod, mod->module_init);
68960 ++ module_free(mod, mod->module_init_rw);
68961 ++ module_free_exec(mod, mod->module_init_rx);
68962 + kfree(mod->args);
68963 + if (mod->percpu)
68964 + percpu_modfree(mod->percpu);
68965 +
68966 + /* Free lock-classes: */
68967 +- lockdep_free_key_range(mod->module_core, mod->core_size);
68968 ++ lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
68969 ++ lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
68970 +
68971 + /* Finally, free the core (containing the module structure) */
68972 +- module_free(mod, mod->module_core);
68973 ++ module_free_exec(mod, mod->module_core_rx);
68974 ++ module_free(mod, mod->module_core_rw);
68975 + }
68976 +
68977 + void *__symbol_get(const char *symbol)
68978 +@@ -1505,10 +1525,14 @@ static int simplify_symbols(Elf_Shdr *se
68979 + struct module *mod)
68980 + {
68981 + Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
68982 +- unsigned long secbase;
68983 ++ unsigned long secbase, symbol;
68984 + unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
68985 + int ret = 0;
68986 +
68987 ++#ifdef CONFIG_PAX_KERNEXEC
68988 ++ unsigned long cr0;
68989 ++#endif
68990 ++
68991 + for (i = 1; i < n; i++) {
68992 + switch (sym[i].st_shndx) {
68993 + case SHN_COMMON:
68994 +@@ -1527,10 +1551,19 @@ static int simplify_symbols(Elf_Shdr *se
68995 + break;
68996 +
68997 + case SHN_UNDEF:
68998 +- sym[i].st_value
68999 +- = resolve_symbol(sechdrs, versindex,
69000 ++ symbol = resolve_symbol(sechdrs, versindex,
69001 + strtab + sym[i].st_name, mod);
69002 +
69003 ++#ifdef CONFIG_PAX_KERNEXEC
69004 ++ pax_open_kernel(cr0);
69005 ++#endif
69006 ++
69007 ++ sym[i].st_value = symbol;
69008 ++
69009 ++#ifdef CONFIG_PAX_KERNEXEC
69010 ++ pax_close_kernel(cr0);
69011 ++#endif
69012 ++
69013 + /* Ok if resolved. */
69014 + if (!IS_ERR_VALUE(sym[i].st_value))
69015 + break;
69016 +@@ -1545,11 +1578,27 @@ static int simplify_symbols(Elf_Shdr *se
69017 +
69018 + default:
69019 + /* Divert to percpu allocation if a percpu var. */
69020 +- if (sym[i].st_shndx == pcpuindex)
69021 ++ if (sym[i].st_shndx == pcpuindex) {
69022 ++
69023 ++#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
69024 ++ secbase = (unsigned long)mod->percpu - (unsigned long)__per_cpu_start;
69025 ++#else
69026 + secbase = (unsigned long)mod->percpu;
69027 +- else
69028 ++#endif
69029 ++
69030 ++ } else
69031 + secbase = sechdrs[sym[i].st_shndx].sh_addr;
69032 ++
69033 ++#ifdef CONFIG_PAX_KERNEXEC
69034 ++ pax_open_kernel(cr0);
69035 ++#endif
69036 ++
69037 + sym[i].st_value += secbase;
69038 ++
69039 ++#ifdef CONFIG_PAX_KERNEXEC
69040 ++ pax_close_kernel(cr0);
69041 ++#endif
69042 ++
69043 + break;
69044 + }
69045 + }
69046 +@@ -1601,11 +1650,12 @@ static void layout_sections(struct modul
69047 + || strncmp(secstrings + s->sh_name,
69048 + ".init", 5) == 0)
69049 + continue;
69050 +- s->sh_entsize = get_offset(&mod->core_size, s);
69051 ++ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
69052 ++ s->sh_entsize = get_offset(&mod->core_size_rw, s);
69053 ++ else
69054 ++ s->sh_entsize = get_offset(&mod->core_size_rx, s);
69055 + DEBUGP("\t%s\n", secstrings + s->sh_name);
69056 + }
69057 +- if (m == 0)
69058 +- mod->core_text_size = mod->core_size;
69059 + }
69060 +
69061 + DEBUGP("Init section allocation order:\n");
69062 +@@ -1619,12 +1669,13 @@ static void layout_sections(struct modul
69063 + || strncmp(secstrings + s->sh_name,
69064 + ".init", 5) != 0)
69065 + continue;
69066 +- s->sh_entsize = (get_offset(&mod->init_size, s)
69067 +- | INIT_OFFSET_MASK);
69068 ++ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
69069 ++ s->sh_entsize = get_offset(&mod->init_size_rw, s);
69070 ++ else
69071 ++ s->sh_entsize = get_offset(&mod->init_size_rx, s);
69072 ++ s->sh_entsize |= INIT_OFFSET_MASK;
69073 + DEBUGP("\t%s\n", secstrings + s->sh_name);
69074 + }
69075 +- if (m == 0)
69076 +- mod->init_text_size = mod->init_size;
69077 + }
69078 + }
69079 +
69080 +@@ -1764,14 +1815,31 @@ static void add_kallsyms(struct module *
69081 + {
69082 + unsigned int i;
69083 +
69084 ++#ifdef CONFIG_PAX_KERNEXEC
69085 ++ unsigned long cr0;
69086 ++#endif
69087 ++
69088 + mod->symtab = (void *)sechdrs[symindex].sh_addr;
69089 + mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
69090 + mod->strtab = (void *)sechdrs[strindex].sh_addr;
69091 +
69092 + /* Set types up while we still have access to sections. */
69093 +- for (i = 0; i < mod->num_symtab; i++)
69094 +- mod->symtab[i].st_info
69095 +- = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
69096 ++
69097 ++ for (i = 0; i < mod->num_symtab; i++) {
69098 ++ char type = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
69099 ++
69100 ++#ifdef CONFIG_PAX_KERNEXEC
69101 ++ pax_open_kernel(cr0);
69102 ++#endif
69103 ++
69104 ++ mod->symtab[i].st_info = type;
69105 ++
69106 ++#ifdef CONFIG_PAX_KERNEXEC
69107 ++ pax_close_kernel(cr0);
69108 ++#endif
69109 ++
69110 ++ }
69111 ++
69112 + }
69113 + #else
69114 + static inline void add_kallsyms(struct module *mod,
69115 +@@ -1783,16 +1851,30 @@ static inline void add_kallsyms(struct m
69116 + }
69117 + #endif /* CONFIG_KALLSYMS */
69118 +
69119 +-static void *module_alloc_update_bounds(unsigned long size)
69120 ++static void *module_alloc_update_bounds_rw(unsigned long size)
69121 + {
69122 + void *ret = module_alloc(size);
69123 +
69124 + if (ret) {
69125 + /* Update module bounds. */
69126 +- if ((unsigned long)ret < module_addr_min)
69127 +- module_addr_min = (unsigned long)ret;
69128 +- if ((unsigned long)ret + size > module_addr_max)
69129 +- module_addr_max = (unsigned long)ret + size;
69130 ++ if ((unsigned long)ret < module_addr_min_rw)
69131 ++ module_addr_min_rw = (unsigned long)ret;
69132 ++ if ((unsigned long)ret + size > module_addr_max_rw)
69133 ++ module_addr_max_rw = (unsigned long)ret + size;
69134 ++ }
69135 ++ return ret;
69136 ++}
69137 ++
69138 ++static void *module_alloc_update_bounds_rx(unsigned long size)
69139 ++{
69140 ++ void *ret = module_alloc_exec(size);
69141 ++
69142 ++ if (ret) {
69143 ++ /* Update module bounds. */
69144 ++ if ((unsigned long)ret < module_addr_min_rx)
69145 ++ module_addr_min_rx = (unsigned long)ret;
69146 ++ if ((unsigned long)ret + size > module_addr_max_rx)
69147 ++ module_addr_max_rx = (unsigned long)ret + size;
69148 + }
69149 + return ret;
69150 + }
69151 +@@ -1837,6 +1919,10 @@ static noinline struct module *load_modu
69152 + struct exception_table_entry *extable;
69153 + mm_segment_t old_fs;
69154 +
69155 ++#ifdef CONFIG_PAX_KERNEXEC
69156 ++ unsigned long cr0;
69157 ++#endif
69158 ++
69159 + DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
69160 + umod, len, uargs);
69161 + if (len < sizeof(*hdr))
69162 +@@ -1998,22 +2084,57 @@ static noinline struct module *load_modu
69163 + layout_sections(mod, hdr, sechdrs, secstrings);
69164 +
69165 + /* Do the allocs. */
69166 +- ptr = module_alloc_update_bounds(mod->core_size);
69167 ++ ptr = module_alloc_update_bounds_rw(mod->core_size_rw);
69168 + if (!ptr) {
69169 + err = -ENOMEM;
69170 + goto free_percpu;
69171 + }
69172 +- memset(ptr, 0, mod->core_size);
69173 +- mod->module_core = ptr;
69174 ++ memset(ptr, 0, mod->core_size_rw);
69175 ++ mod->module_core_rw = ptr;
69176 ++
69177 ++ ptr = module_alloc_update_bounds_rw(mod->init_size_rw);
69178 ++ if (!ptr && mod->init_size_rw) {
69179 ++ err = -ENOMEM;
69180 ++ goto free_core_rw;
69181 ++ }
69182 ++ memset(ptr, 0, mod->init_size_rw);
69183 ++ mod->module_init_rw = ptr;
69184 ++
69185 ++ ptr = module_alloc_update_bounds_rx(mod->core_size_rx);
69186 ++ if (!ptr) {
69187 ++ err = -ENOMEM;
69188 ++ goto free_init_rw;
69189 ++ }
69190 ++
69191 ++#ifdef CONFIG_PAX_KERNEXEC
69192 ++ pax_open_kernel(cr0);
69193 ++#endif
69194 ++
69195 ++ memset(ptr, 0, mod->core_size_rx);
69196 +
69197 +- ptr = module_alloc_update_bounds(mod->init_size);
69198 +- if (!ptr && mod->init_size) {
69199 ++#ifdef CONFIG_PAX_KERNEXEC
69200 ++ pax_close_kernel(cr0);
69201 ++#endif
69202 ++
69203 ++ mod->module_core_rx = ptr;
69204 ++
69205 ++ ptr = module_alloc_update_bounds_rx(mod->init_size_rx);
69206 ++ if (!ptr && mod->init_size_rx) {
69207 + err = -ENOMEM;
69208 +- goto free_core;
69209 ++ goto free_core_rx;
69210 + }
69211 +- memset(ptr, 0, mod->init_size);
69212 +- mod->module_init = ptr;
69213 +
69214 ++#ifdef CONFIG_PAX_KERNEXEC
69215 ++ pax_open_kernel(cr0);
69216 ++#endif
69217 ++
69218 ++ memset(ptr, 0, mod->init_size_rx);
69219 ++
69220 ++#ifdef CONFIG_PAX_KERNEXEC
69221 ++ pax_close_kernel(cr0);
69222 ++#endif
69223 ++
69224 ++ mod->module_init_rx = ptr;
69225 + /* Transfer each section which specifies SHF_ALLOC */
69226 + DEBUGP("final section addresses:\n");
69227 + for (i = 0; i < hdr->e_shnum; i++) {
69228 +@@ -2022,17 +2143,41 @@ static noinline struct module *load_modu
69229 + if (!(sechdrs[i].sh_flags & SHF_ALLOC))
69230 + continue;
69231 +
69232 +- if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
69233 +- dest = mod->module_init
69234 +- + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
69235 +- else
69236 +- dest = mod->module_core + sechdrs[i].sh_entsize;
69237 ++ if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
69238 ++ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
69239 ++ dest = mod->module_init_rw
69240 ++ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
69241 ++ else
69242 ++ dest = mod->module_init_rx
69243 ++ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
69244 ++ } else {
69245 ++ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
69246 ++ dest = mod->module_core_rw + sechdrs[i].sh_entsize;
69247 ++ else
69248 ++ dest = mod->module_core_rx + sechdrs[i].sh_entsize;
69249 ++ }
69250 ++
69251 ++ if (sechdrs[i].sh_type != SHT_NOBITS) {
69252 +
69253 +- if (sechdrs[i].sh_type != SHT_NOBITS)
69254 +- memcpy(dest, (void *)sechdrs[i].sh_addr,
69255 +- sechdrs[i].sh_size);
69256 ++#ifdef CONFIG_PAX_KERNEXEC
69257 ++ if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC)) {
69258 ++ pax_open_kernel(cr0);
69259 ++ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
69260 ++ pax_close_kernel(cr0);
69261 ++ } else
69262 ++#endif
69263 ++
69264 ++ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
69265 ++ }
69266 + /* Update sh_addr to point to copy in image. */
69267 +- sechdrs[i].sh_addr = (unsigned long)dest;
69268 ++
69269 ++#ifdef CONFIG_PAX_KERNEXEC
69270 ++ if (sechdrs[i].sh_flags & SHF_EXECINSTR)
69271 ++ sechdrs[i].sh_addr = ktva_ktla((unsigned long)dest);
69272 ++ else
69273 ++#endif
69274 ++
69275 ++ sechdrs[i].sh_addr = (unsigned long)dest;
69276 + DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
69277 + }
69278 + /* Module has been moved. */
69279 +@@ -2120,8 +2265,8 @@ static noinline struct module *load_modu
69280 +
69281 + /* Now do relocations. */
69282 + for (i = 1; i < hdr->e_shnum; i++) {
69283 +- const char *strtab = (char *)sechdrs[strindex].sh_addr;
69284 + unsigned int info = sechdrs[i].sh_info;
69285 ++ strtab = (char *)sechdrs[strindex].sh_addr;
69286 +
69287 + /* Not a valid relocation section? */
69288 + if (info >= hdr->e_shnum)
69289 +@@ -2180,12 +2325,12 @@ static noinline struct module *load_modu
69290 + * Do it before processing of module parameters, so the module
69291 + * can provide parameter accessor functions of its own.
69292 + */
69293 +- if (mod->module_init)
69294 +- flush_icache_range((unsigned long)mod->module_init,
69295 +- (unsigned long)mod->module_init
69296 +- + mod->init_size);
69297 +- flush_icache_range((unsigned long)mod->module_core,
69298 +- (unsigned long)mod->module_core + mod->core_size);
69299 ++ if (mod->module_init_rx)
69300 ++ flush_icache_range((unsigned long)mod->module_init_rx,
69301 ++ (unsigned long)mod->module_init_rx
69302 ++ + mod->init_size_rx);
69303 ++ flush_icache_range((unsigned long)mod->module_core_rx,
69304 ++ (unsigned long)mod->module_core_rx + mod->core_size_rx);
69305 +
69306 + set_fs(old_fs);
69307 +
69308 +@@ -2238,9 +2383,13 @@ static noinline struct module *load_modu
69309 + kobject_put(&mod->mkobj.kobj);
69310 + free_unload:
69311 + module_unload_free(mod);
69312 +- module_free(mod, mod->module_init);
69313 +- free_core:
69314 +- module_free(mod, mod->module_core);
69315 ++ module_free_exec(mod, mod->module_init_rx);
69316 ++ free_core_rx:
69317 ++ module_free_exec(mod, mod->module_core_rx);
69318 ++ free_init_rw:
69319 ++ module_free(mod, mod->module_init_rw);
69320 ++ free_core_rw:
69321 ++ module_free(mod, mod->module_core_rw);
69322 + free_percpu:
69323 + if (percpu)
69324 + percpu_modfree(percpu);
69325 +@@ -2265,6 +2414,9 @@ sys_init_module(void __user *umod,
69326 + struct module *mod;
69327 + int ret = 0;
69328 +
69329 ++ if (gr_check_modstop())
69330 ++ return -EPERM;
69331 ++
69332 + /* Must have permission */
69333 + if (!capable(CAP_SYS_MODULE))
69334 + return -EPERM;
69335 +@@ -2320,10 +2472,12 @@ sys_init_module(void __user *umod,
69336 + /* Drop initial reference. */
69337 + module_put(mod);
69338 + unwind_remove_table(mod->unwind_info, 1);
69339 +- module_free(mod, mod->module_init);
69340 +- mod->module_init = NULL;
69341 +- mod->init_size = 0;
69342 +- mod->init_text_size = 0;
69343 ++ module_free(mod, mod->module_init_rw);
69344 ++ module_free_exec(mod, mod->module_init_rx);
69345 ++ mod->module_init_rw = NULL;
69346 ++ mod->module_init_rx = NULL;
69347 ++ mod->init_size_rw = 0;
69348 ++ mod->init_size_rx = 0;
69349 + mutex_unlock(&module_mutex);
69350 +
69351 + return 0;
69352 +@@ -2331,6 +2485,13 @@ sys_init_module(void __user *umod,
69353 +
69354 + static inline int within(unsigned long addr, void *start, unsigned long size)
69355 + {
69356 ++
69357 ++#ifdef CONFIG_PAX_KERNEXEC
69358 ++ if (ktla_ktva(addr) >= (unsigned long)start &&
69359 ++ ktla_ktva(addr) < (unsigned long)start + size)
69360 ++ return 1;
69361 ++#endif
69362 ++
69363 + return ((void *)addr >= start && (void *)addr < start + size);
69364 + }
69365 +
69366 +@@ -2354,10 +2515,14 @@ static const char *get_ksymbol(struct mo
69367 + unsigned long nextval;
69368 +
69369 + /* At worse, next value is at end of module */
69370 +- if (within(addr, mod->module_init, mod->init_size))
69371 +- nextval = (unsigned long)mod->module_init+mod->init_text_size;
69372 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx))
69373 ++ nextval = (unsigned long)mod->module_init_rx+mod->init_size_rx;
69374 ++ else if (within(addr, mod->module_init_rw, mod->init_size_rw))
69375 ++ nextval = (unsigned long)mod->module_init_rw+mod->init_size_rw;
69376 ++ else if (within(addr, mod->module_core_rx, mod->core_size_rx))
69377 ++ nextval = (unsigned long)mod->module_core_rx+mod->core_size_rx;
69378 + else
69379 +- nextval = (unsigned long)mod->module_core+mod->core_text_size;
69380 ++ nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
69381 +
69382 + /* Scan for closest preceeding symbol, and next symbol. (ELF
69383 + starts real symbols at 1). */
69384 +@@ -2402,8 +2567,10 @@ const char *module_address_lookup(unsign
69385 +
69386 + preempt_disable();
69387 + list_for_each_entry(mod, &modules, list) {
69388 +- if (within(addr, mod->module_init, mod->init_size)
69389 +- || within(addr, mod->module_core, mod->core_size)) {
69390 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
69391 ++ within(addr, mod->module_init_rw, mod->init_size_rw) ||
69392 ++ within(addr, mod->module_core_rx, mod->core_size_rx) ||
69393 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
69394 + if (modname)
69395 + *modname = mod->name;
69396 + ret = get_ksymbol(mod, addr, size, offset);
69397 +@@ -2425,8 +2592,10 @@ int lookup_module_symbol_name(unsigned l
69398 +
69399 + preempt_disable();
69400 + list_for_each_entry(mod, &modules, list) {
69401 +- if (within(addr, mod->module_init, mod->init_size) ||
69402 +- within(addr, mod->module_core, mod->core_size)) {
69403 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
69404 ++ within(addr, mod->module_init_rw, mod->init_size_rw) ||
69405 ++ within(addr, mod->module_core_rx, mod->core_size_rx) ||
69406 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
69407 + const char *sym;
69408 +
69409 + sym = get_ksymbol(mod, addr, NULL, NULL);
69410 +@@ -2449,8 +2618,10 @@ int lookup_module_symbol_attrs(unsigned
69411 +
69412 + preempt_disable();
69413 + list_for_each_entry(mod, &modules, list) {
69414 +- if (within(addr, mod->module_init, mod->init_size) ||
69415 +- within(addr, mod->module_core, mod->core_size)) {
69416 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
69417 ++ within(addr, mod->module_init_rw, mod->init_size_rw) ||
69418 ++ within(addr, mod->module_core_rx, mod->core_size_rx) ||
69419 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
69420 + const char *sym;
69421 +
69422 + sym = get_ksymbol(mod, addr, size, offset);
69423 +@@ -2581,7 +2752,7 @@ static int m_show(struct seq_file *m, vo
69424 + char buf[8];
69425 +
69426 + seq_printf(m, "%s %u",
69427 +- mod->name, mod->init_size + mod->core_size);
69428 ++ mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
69429 + print_unload_info(m, mod);
69430 +
69431 + /* Informative for users. */
69432 +@@ -2590,7 +2761,7 @@ static int m_show(struct seq_file *m, vo
69433 + mod->state == MODULE_STATE_COMING ? "Loading":
69434 + "Live");
69435 + /* Used by oprofile and other similar tools. */
69436 +- seq_printf(m, " 0x%p", mod->module_core);
69437 ++ seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
69438 +
69439 + /* Taints info */
69440 + if (mod->taints)
69441 +@@ -2646,7 +2817,8 @@ int is_module_address(unsigned long addr
69442 + preempt_disable();
69443 +
69444 + list_for_each_entry(mod, &modules, list) {
69445 +- if (within(addr, mod->module_core, mod->core_size)) {
69446 ++ if (within(addr, mod->module_core_rx, mod->core_size_rx) ||
69447 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
69448 + preempt_enable();
69449 + return 1;
69450 + }
69451 +@@ -2663,12 +2835,12 @@ struct module *__module_text_address(uns
69452 + {
69453 + struct module *mod;
69454 +
69455 +- if (addr < module_addr_min || addr > module_addr_max)
69456 ++ if (addr < module_addr_min_rx || addr > module_addr_max_rx)
69457 + return NULL;
69458 +
69459 + list_for_each_entry(mod, &modules, list)
69460 +- if (within(addr, mod->module_init, mod->init_text_size)
69461 +- || within(addr, mod->module_core, mod->core_text_size))
69462 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx)
69463 ++ || within(addr, mod->module_core_rx, mod->core_size_rx))
69464 + return mod;
69465 + return NULL;
69466 + }
69467 +diff -urNp linux-2.6.27.7/kernel/mutex.c linux-2.6.27.7/kernel/mutex.c
69468 +--- linux-2.6.27.7/kernel/mutex.c 2008-11-07 12:55:34.000000000 -0500
69469 ++++ linux-2.6.27.7/kernel/mutex.c 2008-11-18 03:38:45.000000000 -0500
69470 +@@ -83,7 +83,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou
69471 + *
69472 + * This function is similar to (but not equivalent to) down().
69473 + */
69474 +-void inline __sched mutex_lock(struct mutex *lock)
69475 ++inline void __sched mutex_lock(struct mutex *lock)
69476 + {
69477 + might_sleep();
69478 + /*
69479 +diff -urNp linux-2.6.27.7/kernel/panic.c linux-2.6.27.7/kernel/panic.c
69480 +--- linux-2.6.27.7/kernel/panic.c 2008-11-07 12:55:34.000000000 -0500
69481 ++++ linux-2.6.27.7/kernel/panic.c 2008-11-18 03:38:45.000000000 -0500
69482 +@@ -349,6 +349,8 @@ EXPORT_SYMBOL(warn_slowpath);
69483 + */
69484 + void __stack_chk_fail(void)
69485 + {
69486 ++ print_symbol("stack corrupted in: %s\n", (unsigned long)__builtin_return_address(0));
69487 ++ dump_stack();
69488 + panic("stack-protector: Kernel stack is corrupted");
69489 + }
69490 + EXPORT_SYMBOL(__stack_chk_fail);
69491 +diff -urNp linux-2.6.27.7/kernel/pid.c linux-2.6.27.7/kernel/pid.c
69492 +--- linux-2.6.27.7/kernel/pid.c 2008-11-07 12:55:34.000000000 -0500
69493 ++++ linux-2.6.27.7/kernel/pid.c 2008-11-18 03:38:45.000000000 -0500
69494 +@@ -36,6 +36,7 @@
69495 + #include <linux/pid_namespace.h>
69496 + #include <linux/init_task.h>
69497 + #include <linux/syscalls.h>
69498 ++#include <linux/grsecurity.h>
69499 +
69500 + #define pid_hashfn(nr, ns) \
69501 + hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
69502 +@@ -45,7 +46,7 @@ struct pid init_struct_pid = INIT_STRUCT
69503 +
69504 + int pid_max = PID_MAX_DEFAULT;
69505 +
69506 +-#define RESERVED_PIDS 300
69507 ++#define RESERVED_PIDS 500
69508 +
69509 + int pid_max_min = RESERVED_PIDS + 1;
69510 + int pid_max_max = PID_MAX_LIMIT;
69511 +@@ -381,7 +382,14 @@ EXPORT_SYMBOL(pid_task);
69512 + struct task_struct *find_task_by_pid_type_ns(int type, int nr,
69513 + struct pid_namespace *ns)
69514 + {
69515 +- return pid_task(find_pid_ns(nr, ns), type);
69516 ++ struct task_struct *task;
69517 ++
69518 ++ task = pid_task(find_pid_ns(nr, ns), type);
69519 ++
69520 ++ if (gr_pid_is_chrooted(task))
69521 ++ return NULL;
69522 ++
69523 ++ return task;
69524 + }
69525 +
69526 + EXPORT_SYMBOL(find_task_by_pid_type_ns);
69527 +diff -urNp linux-2.6.27.7/kernel/posix-cpu-timers.c linux-2.6.27.7/kernel/posix-cpu-timers.c
69528 +--- linux-2.6.27.7/kernel/posix-cpu-timers.c 2008-11-07 12:55:34.000000000 -0500
69529 ++++ linux-2.6.27.7/kernel/posix-cpu-timers.c 2008-11-18 03:38:45.000000000 -0500
69530 +@@ -6,6 +6,7 @@
69531 + #include <linux/posix-timers.h>
69532 + #include <linux/errno.h>
69533 + #include <linux/math64.h>
69534 ++#include <linux/grsecurity.h>
69535 + #include <asm/uaccess.h>
69536 +
69537 + static int check_clock(const clockid_t which_clock)
69538 +@@ -1176,6 +1177,7 @@ static void check_process_timers(struct
69539 + __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
69540 + return;
69541 + }
69542 ++ gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1);
69543 + if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
69544 + /*
69545 + * At the soft limit, send a SIGXCPU every second.
69546 +@@ -1370,17 +1372,17 @@ void run_posix_cpu_timers(struct task_st
69547 + * timer call will interfere.
69548 + */
69549 + list_for_each_entry_safe(timer, next, &firing, it.cpu.entry) {
69550 +- int firing;
69551 ++ int __firing;
69552 + spin_lock(&timer->it_lock);
69553 + list_del_init(&timer->it.cpu.entry);
69554 +- firing = timer->it.cpu.firing;
69555 ++ __firing = timer->it.cpu.firing;
69556 + timer->it.cpu.firing = 0;
69557 + /*
69558 + * The firing flag is -1 if we collided with a reset
69559 + * of the timer, which already reported this
69560 + * almost-firing as an overrun. So don't generate an event.
69561 + */
69562 +- if (likely(firing >= 0)) {
69563 ++ if (likely(__firing >= 0)) {
69564 + cpu_timer_fire(timer);
69565 + }
69566 + spin_unlock(&timer->it_lock);
69567 +diff -urNp linux-2.6.27.7/kernel/power/poweroff.c linux-2.6.27.7/kernel/power/poweroff.c
69568 +--- linux-2.6.27.7/kernel/power/poweroff.c 2008-11-07 12:55:34.000000000 -0500
69569 ++++ linux-2.6.27.7/kernel/power/poweroff.c 2008-11-18 03:38:45.000000000 -0500
69570 +@@ -37,7 +37,7 @@ static struct sysrq_key_op sysrq_powerof
69571 + .enable_mask = SYSRQ_ENABLE_BOOT,
69572 + };
69573 +
69574 +-static int pm_sysrq_init(void)
69575 ++static int __init pm_sysrq_init(void)
69576 + {
69577 + register_sysrq_key('o', &sysrq_poweroff_op);
69578 + return 0;
69579 +diff -urNp linux-2.6.27.7/kernel/printk.c linux-2.6.27.7/kernel/printk.c
69580 +--- linux-2.6.27.7/kernel/printk.c 2008-11-07 12:55:34.000000000 -0500
69581 ++++ linux-2.6.27.7/kernel/printk.c 2008-11-18 03:38:45.000000000 -0500
69582 +@@ -32,6 +32,7 @@
69583 + #include <linux/security.h>
69584 + #include <linux/bootmem.h>
69585 + #include <linux/syscalls.h>
69586 ++#include <linux/grsecurity.h>
69587 +
69588 + #include <asm/uaccess.h>
69589 +
69590 +@@ -293,6 +294,11 @@ int do_syslog(int type, char __user *buf
69591 + char c;
69592 + int error = 0;
69593 +
69594 ++#ifdef CONFIG_GRKERNSEC_DMESG
69595 ++ if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
69596 ++ return -EPERM;
69597 ++#endif
69598 ++
69599 + error = security_syslog(type);
69600 + if (error)
69601 + return error;
69602 +diff -urNp linux-2.6.27.7/kernel/ptrace.c linux-2.6.27.7/kernel/ptrace.c
69603 +--- linux-2.6.27.7/kernel/ptrace.c 2008-11-07 12:55:34.000000000 -0500
69604 ++++ linux-2.6.27.7/kernel/ptrace.c 2008-11-18 03:38:45.000000000 -0500
69605 +@@ -21,6 +21,7 @@
69606 + #include <linux/audit.h>
69607 + #include <linux/pid_namespace.h>
69608 + #include <linux/syscalls.h>
69609 ++#include <linux/grsecurity.h>
69610 +
69611 + #include <asm/pgtable.h>
69612 + #include <asm/uaccess.h>
69613 +@@ -132,12 +133,12 @@ int __ptrace_may_access(struct task_stru
69614 + (current->uid != task->uid) ||
69615 + (current->gid != task->egid) ||
69616 + (current->gid != task->sgid) ||
69617 +- (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
69618 ++ (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
69619 + return -EPERM;
69620 + smp_rmb();
69621 + if (task->mm)
69622 + dumpable = get_dumpable(task->mm);
69623 +- if (!dumpable && !capable(CAP_SYS_PTRACE))
69624 ++ if (!dumpable && !capable_nolog(CAP_SYS_PTRACE))
69625 + return -EPERM;
69626 +
69627 + return security_ptrace_may_access(task, mode);
69628 +@@ -193,7 +194,7 @@ repeat:
69629 +
69630 + /* Go */
69631 + task->ptrace |= PT_PTRACED;
69632 +- if (capable(CAP_SYS_PTRACE))
69633 ++ if (capable_nolog(CAP_SYS_PTRACE))
69634 + task->ptrace |= PT_PTRACE_CAP;
69635 +
69636 + __ptrace_link(task, current);
69637 +@@ -582,6 +583,11 @@ asmlinkage long sys_ptrace(long request,
69638 + if (ret < 0)
69639 + goto out_put_task_struct;
69640 +
69641 ++ if (gr_handle_ptrace(child, request)) {
69642 ++ ret = -EPERM;
69643 ++ goto out_put_task_struct;
69644 ++ }
69645 ++
69646 + ret = arch_ptrace(child, request, addr, data);
69647 + if (ret < 0)
69648 + goto out_put_task_struct;
69649 +diff -urNp linux-2.6.27.7/kernel/relay.c linux-2.6.27.7/kernel/relay.c
69650 +--- linux-2.6.27.7/kernel/relay.c 2008-11-07 12:55:34.000000000 -0500
69651 ++++ linux-2.6.27.7/kernel/relay.c 2008-11-18 03:38:45.000000000 -0500
69652 +@@ -1291,7 +1291,7 @@ static int subbuf_splice_actor(struct fi
69653 + return 0;
69654 +
69655 + ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
69656 +- if (ret < 0 || ret < total_len)
69657 ++ if ((int)ret < 0 || ret < total_len)
69658 + return ret;
69659 +
69660 + if (read_start + ret == nonpad_end)
69661 +diff -urNp linux-2.6.27.7/kernel/resource.c linux-2.6.27.7/kernel/resource.c
69662 +--- linux-2.6.27.7/kernel/resource.c 2008-11-07 12:55:34.000000000 -0500
69663 ++++ linux-2.6.27.7/kernel/resource.c 2008-11-18 03:38:45.000000000 -0500
69664 +@@ -131,8 +131,18 @@ static const struct file_operations proc
69665 +
69666 + static int __init ioresources_init(void)
69667 + {
69668 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
69669 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
69670 ++ proc_create("ioports", S_IRUSR, NULL, &proc_ioports_operations);
69671 ++ proc_create("iomem", S_IRUSR, NULL, &proc_iomem_operations);
69672 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
69673 ++ proc_create("ioports", S_IRUSR | S_IRGRP, NULL, &proc_ioports_operations);
69674 ++ proc_create("iomem", S_IRUSR | S_IRGRP, NULL, &proc_iomem_operations);
69675 ++#endif
69676 ++#else
69677 + proc_create("ioports", 0, NULL, &proc_ioports_operations);
69678 + proc_create("iomem", 0, NULL, &proc_iomem_operations);
69679 ++#endif
69680 + return 0;
69681 + }
69682 + __initcall(ioresources_init);
69683 +diff -urNp linux-2.6.27.7/kernel/sched.c linux-2.6.27.7/kernel/sched.c
69684 +--- linux-2.6.27.7/kernel/sched.c 2008-11-07 12:55:34.000000000 -0500
69685 ++++ linux-2.6.27.7/kernel/sched.c 2008-11-18 03:38:45.000000000 -0500
69686 +@@ -71,6 +71,7 @@
69687 + #include <linux/debugfs.h>
69688 + #include <linux/ctype.h>
69689 + #include <linux/ftrace.h>
69690 ++#include <linux/grsecurity.h>
69691 +
69692 + #include <asm/tlb.h>
69693 + #include <asm/irq_regs.h>
69694 +@@ -4962,7 +4963,8 @@ asmlinkage long sys_nice(int increment)
69695 + if (nice > 19)
69696 + nice = 19;
69697 +
69698 +- if (increment < 0 && !can_nice(current, nice))
69699 ++ if (increment < 0 && (!can_nice(current, nice) ||
69700 ++ gr_handle_chroot_nice()))
69701 + return -EPERM;
69702 +
69703 + retval = security_task_setnice(current, nice);
69704 +@@ -6225,7 +6227,7 @@ static struct ctl_table sd_ctl_dir[] = {
69705 + .procname = "sched_domain",
69706 + .mode = 0555,
69707 + },
69708 +- {0, },
69709 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
69710 + };
69711 +
69712 + static struct ctl_table sd_ctl_root[] = {
69713 +@@ -6235,7 +6237,7 @@ static struct ctl_table sd_ctl_root[] =
69714 + .mode = 0555,
69715 + .child = sd_ctl_dir,
69716 + },
69717 +- {0, },
69718 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
69719 + };
69720 +
69721 + static struct ctl_table *sd_alloc_ctl_entry(int n)
69722 +diff -urNp linux-2.6.27.7/kernel/signal.c linux-2.6.27.7/kernel/signal.c
69723 +--- linux-2.6.27.7/kernel/signal.c 2008-11-07 12:55:34.000000000 -0500
69724 ++++ linux-2.6.27.7/kernel/signal.c 2008-11-18 03:38:45.000000000 -0500
69725 +@@ -26,6 +26,7 @@
69726 + #include <linux/capability.h>
69727 + #include <linux/freezer.h>
69728 + #include <linux/pid_namespace.h>
69729 ++#include <linux/grsecurity.h>
69730 + #include <linux/nsproxy.h>
69731 +
69732 + #include <asm/param.h>
69733 +@@ -595,6 +596,9 @@ static int check_kill_permission(int sig
69734 + }
69735 + }
69736 +
69737 ++ if (gr_handle_signal(t, sig))
69738 ++ return -EPERM;
69739 ++
69740 + return security_task_kill(t, info, sig, 0);
69741 + }
69742 +
69743 +@@ -884,8 +888,8 @@ static void print_fatal_signal(struct pt
69744 + for (i = 0; i < 16; i++) {
69745 + unsigned char insn;
69746 +
69747 +- __get_user(insn, (unsigned char *)(regs->ip + i));
69748 +- printk("%02x ", insn);
69749 ++ if (!get_user(insn, (unsigned char __user *)(regs->ip + i)))
69750 ++ printk("%02x ", insn);
69751 + }
69752 + }
69753 + #endif
69754 +@@ -908,7 +912,7 @@ __group_send_sig_info(int sig, struct si
69755 + return send_signal(sig, info, p, 1);
69756 + }
69757 +
69758 +-static int
69759 ++int
69760 + specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
69761 + {
69762 + return send_signal(sig, info, t, 0);
69763 +@@ -946,8 +950,12 @@ force_sig_info(int sig, struct siginfo *
69764 + if (action->sa.sa_handler == SIG_DFL)
69765 + t->signal->flags &= ~SIGNAL_UNKILLABLE;
69766 + ret = specific_send_sig_info(sig, info, t);
69767 ++
69768 + spin_unlock_irqrestore(&t->sighand->siglock, flags);
69769 +
69770 ++ gr_log_signal(sig, t);
69771 ++ gr_handle_crash(t, sig);
69772 ++
69773 + return ret;
69774 + }
69775 +
69776 +@@ -1018,6 +1026,8 @@ int group_send_sig_info(int sig, struct
69777 + ret = __group_send_sig_info(sig, info, p);
69778 + unlock_task_sighand(p, &flags);
69779 + }
69780 ++ if (!ret)
69781 ++ gr_log_signal(sig, p);
69782 + }
69783 +
69784 + return ret;
69785 +diff -urNp linux-2.6.27.7/kernel/softirq.c linux-2.6.27.7/kernel/softirq.c
69786 +--- linux-2.6.27.7/kernel/softirq.c 2008-11-07 12:55:34.000000000 -0500
69787 ++++ linux-2.6.27.7/kernel/softirq.c 2008-11-18 03:38:45.000000000 -0500
69788 +@@ -453,9 +453,9 @@ void tasklet_kill(struct tasklet_struct
69789 + printk("Attempt to kill tasklet from interrupt\n");
69790 +
69791 + while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
69792 +- do
69793 ++ do {
69794 + yield();
69795 +- while (test_bit(TASKLET_STATE_SCHED, &t->state));
69796 ++ } while (test_bit(TASKLET_STATE_SCHED, &t->state));
69797 + }
69798 + tasklet_unlock_wait(t);
69799 + clear_bit(TASKLET_STATE_SCHED, &t->state);
69800 +diff -urNp linux-2.6.27.7/kernel/sys.c linux-2.6.27.7/kernel/sys.c
69801 +--- linux-2.6.27.7/kernel/sys.c 2008-11-07 12:55:34.000000000 -0500
69802 ++++ linux-2.6.27.7/kernel/sys.c 2008-11-18 03:38:45.000000000 -0500
69803 +@@ -33,6 +33,7 @@
69804 + #include <linux/task_io_accounting_ops.h>
69805 + #include <linux/seccomp.h>
69806 + #include <linux/cpu.h>
69807 ++#include <linux/grsecurity.h>
69808 +
69809 + #include <linux/compat.h>
69810 + #include <linux/syscalls.h>
69811 +@@ -125,6 +126,12 @@ static int set_one_prio(struct task_stru
69812 + error = -EACCES;
69813 + goto out;
69814 + }
69815 ++
69816 ++ if (gr_handle_chroot_setpriority(p, niceval)) {
69817 ++ error = -EACCES;
69818 ++ goto out;
69819 ++ }
69820 ++
69821 + no_nice = security_task_setnice(p, niceval);
69822 + if (no_nice) {
69823 + error = no_nice;
69824 +@@ -181,10 +188,10 @@ asmlinkage long sys_setpriority(int whic
69825 + if ((who != current->uid) && !(user = find_user(who)))
69826 + goto out_unlock; /* No processes for this user */
69827 +
69828 +- do_each_thread(g, p)
69829 ++ do_each_thread(g, p) {
69830 + if (p->uid == who)
69831 + error = set_one_prio(p, niceval, error);
69832 +- while_each_thread(g, p);
69833 ++ } while_each_thread(g, p);
69834 + if (who != current->uid)
69835 + free_uid(user); /* For find_user() */
69836 + break;
69837 +@@ -243,13 +250,13 @@ asmlinkage long sys_getpriority(int whic
69838 + if ((who != current->uid) && !(user = find_user(who)))
69839 + goto out_unlock; /* No processes for this user */
69840 +
69841 +- do_each_thread(g, p)
69842 ++ do_each_thread(g, p) {
69843 + if (p->uid == who) {
69844 + niceval = 20 - task_nice(p);
69845 + if (niceval > retval)
69846 + retval = niceval;
69847 + }
69848 +- while_each_thread(g, p);
69849 ++ } while_each_thread(g, p);
69850 + if (who != current->uid)
69851 + free_uid(user); /* for find_user() */
69852 + break;
69853 +@@ -499,6 +506,10 @@ asmlinkage long sys_setregid(gid_t rgid,
69854 + else
69855 + return -EPERM;
69856 + }
69857 ++
69858 ++ if (gr_check_group_change(new_rgid, new_egid, -1))
69859 ++ return -EPERM;
69860 ++
69861 + if (new_egid != old_egid) {
69862 + set_dumpable(current->mm, suid_dumpable);
69863 + smp_wmb();
69864 +@@ -506,6 +517,9 @@ asmlinkage long sys_setregid(gid_t rgid,
69865 + if (rgid != (gid_t) -1 ||
69866 + (egid != (gid_t) -1 && egid != old_rgid))
69867 + current->sgid = new_egid;
69868 ++
69869 ++ gr_set_role_label(current, current->uid, new_rgid);
69870 ++
69871 + current->fsgid = new_egid;
69872 + current->egid = new_egid;
69873 + current->gid = new_rgid;
69874 +@@ -528,11 +542,17 @@ asmlinkage long sys_setgid(gid_t gid)
69875 + if (retval)
69876 + return retval;
69877 +
69878 ++ if (gr_check_group_change(gid, gid, gid))
69879 ++ return -EPERM;
69880 ++
69881 + if (capable(CAP_SETGID)) {
69882 + if (old_egid != gid) {
69883 + set_dumpable(current->mm, suid_dumpable);
69884 + smp_wmb();
69885 + }
69886 ++
69887 ++ gr_set_role_label(current, current->uid, gid);
69888 ++
69889 + current->gid = current->egid = current->sgid = current->fsgid = gid;
69890 + } else if ((gid == current->gid) || (gid == current->sgid)) {
69891 + if (old_egid != gid) {
69892 +@@ -570,6 +590,9 @@ static int set_user(uid_t new_ruid, int
69893 + set_dumpable(current->mm, suid_dumpable);
69894 + smp_wmb();
69895 + }
69896 ++
69897 ++ gr_set_role_label(current, new_ruid, current->gid);
69898 ++
69899 + current->uid = new_ruid;
69900 + return 0;
69901 + }
69902 +@@ -619,6 +642,9 @@ asmlinkage long sys_setreuid(uid_t ruid,
69903 + return -EPERM;
69904 + }
69905 +
69906 ++ if (gr_check_user_change(new_ruid, new_euid, -1))
69907 ++ return -EPERM;
69908 ++
69909 + if (new_ruid != old_ruid && set_user(new_ruid, new_euid != old_euid) < 0)
69910 + return -EAGAIN;
69911 +
69912 +@@ -665,6 +691,12 @@ asmlinkage long sys_setuid(uid_t uid)
69913 + old_suid = current->suid;
69914 + new_suid = old_suid;
69915 +
69916 ++ if (gr_check_crash_uid(uid))
69917 ++ return -EPERM;
69918 ++
69919 ++ if (gr_check_user_change(uid, uid, uid))
69920 ++ return -EPERM;
69921 ++
69922 + if (capable(CAP_SETUID)) {
69923 + if (uid != old_ruid && set_user(uid, old_euid != uid) < 0)
69924 + return -EAGAIN;
69925 +@@ -712,6 +744,10 @@ asmlinkage long sys_setresuid(uid_t ruid
69926 + (suid != current->euid) && (suid != current->suid))
69927 + return -EPERM;
69928 + }
69929 ++
69930 ++ if (gr_check_user_change(ruid, euid, -1))
69931 ++ return -EPERM;
69932 ++
69933 + if (ruid != (uid_t) -1) {
69934 + if (ruid != current->uid && set_user(ruid, euid != current->euid) < 0)
69935 + return -EAGAIN;
69936 +@@ -766,6 +802,10 @@ asmlinkage long sys_setresgid(gid_t rgid
69937 + (sgid != current->egid) && (sgid != current->sgid))
69938 + return -EPERM;
69939 + }
69940 ++
69941 ++ if (gr_check_group_change(rgid, egid, -1))
69942 ++ return -EPERM;
69943 ++
69944 + if (egid != (gid_t) -1) {
69945 + if (egid != current->egid) {
69946 + set_dumpable(current->mm, suid_dumpable);
69947 +@@ -774,8 +814,10 @@ asmlinkage long sys_setresgid(gid_t rgid
69948 + current->egid = egid;
69949 + }
69950 + current->fsgid = current->egid;
69951 +- if (rgid != (gid_t) -1)
69952 ++ if (rgid != (gid_t) -1) {
69953 ++ gr_set_role_label(current, current->uid, rgid);
69954 + current->gid = rgid;
69955 ++ }
69956 + if (sgid != (gid_t) -1)
69957 + current->sgid = sgid;
69958 +
69959 +@@ -810,6 +852,9 @@ asmlinkage long sys_setfsuid(uid_t uid)
69960 + if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS))
69961 + return old_fsuid;
69962 +
69963 ++ if (gr_check_user_change(-1, -1, uid))
69964 ++ return old_fsuid;
69965 ++
69966 + if (uid == current->uid || uid == current->euid ||
69967 + uid == current->suid || uid == current->fsuid ||
69968 + capable(CAP_SETUID)) {
69969 +@@ -842,6 +887,9 @@ asmlinkage long sys_setfsgid(gid_t gid)
69970 + if (gid == current->gid || gid == current->egid ||
69971 + gid == current->sgid || gid == current->fsgid ||
69972 + capable(CAP_SETGID)) {
69973 ++ if (gr_check_group_change(-1, -1, gid))
69974 ++ return old_fsgid;
69975 ++
69976 + if (gid != old_fsgid) {
69977 + set_dumpable(current->mm, suid_dumpable);
69978 + smp_wmb();
69979 +@@ -923,7 +971,10 @@ asmlinkage long sys_setpgid(pid_t pid, p
69980 + write_lock_irq(&tasklist_lock);
69981 +
69982 + err = -ESRCH;
69983 +- p = find_task_by_vpid(pid);
69984 ++ /* grsec: replaced find_task_by_vpid with equivalent call which
69985 ++ lacks the chroot restriction
69986 ++ */
69987 ++ p = pid_task(find_pid_ns(pid, current->nsproxy->pid_ns), PIDTYPE_PID);
69988 + if (!p)
69989 + goto out;
69990 +
69991 +@@ -1655,7 +1706,7 @@ asmlinkage long sys_prctl(int option, un
69992 + error = get_dumpable(current->mm);
69993 + break;
69994 + case PR_SET_DUMPABLE:
69995 +- if (arg2 < 0 || arg2 > 1) {
69996 ++ if (arg2 > 1) {
69997 + error = -EINVAL;
69998 + break;
69999 + }
70000 +diff -urNp linux-2.6.27.7/kernel/sysctl.c linux-2.6.27.7/kernel/sysctl.c
70001 +--- linux-2.6.27.7/kernel/sysctl.c 2008-11-07 12:55:34.000000000 -0500
70002 ++++ linux-2.6.27.7/kernel/sysctl.c 2008-11-18 03:38:45.000000000 -0500
70003 +@@ -61,6 +61,13 @@
70004 + static int deprecated_sysctl_warning(struct __sysctl_args *args);
70005 +
70006 + #if defined(CONFIG_SYSCTL)
70007 ++#include <linux/grsecurity.h>
70008 ++#include <linux/grinternal.h>
70009 ++
70010 ++extern __u32 gr_handle_sysctl(const ctl_table *table, const int op);
70011 ++extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
70012 ++ const int op);
70013 ++extern int gr_handle_chroot_sysctl(const int op);
70014 +
70015 + /* External variables not in a header file. */
70016 + extern int C_A_D;
70017 +@@ -155,6 +162,7 @@ static int proc_do_cad_pid(struct ctl_ta
70018 + static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp,
70019 + void __user *buffer, size_t *lenp, loff_t *ppos);
70020 + #endif
70021 ++extern ctl_table grsecurity_table[];
70022 +
70023 + static struct ctl_table root_table[];
70024 + static struct ctl_table_root sysctl_table_root;
70025 +@@ -184,6 +192,21 @@ extern struct ctl_table inotify_table[];
70026 + int sysctl_legacy_va_layout;
70027 + #endif
70028 +
70029 ++#ifdef CONFIG_PAX_SOFTMODE
70030 ++static ctl_table pax_table[] = {
70031 ++ {
70032 ++ .ctl_name = CTL_UNNUMBERED,
70033 ++ .procname = "softmode",
70034 ++ .data = &pax_softmode,
70035 ++ .maxlen = sizeof(unsigned int),
70036 ++ .mode = 0600,
70037 ++ .proc_handler = &proc_dointvec,
70038 ++ },
70039 ++
70040 ++ { .ctl_name = 0 }
70041 ++};
70042 ++#endif
70043 ++
70044 + extern int prove_locking;
70045 + extern int lock_stat;
70046 +
70047 +@@ -220,6 +243,7 @@ static struct ctl_table root_table[] = {
70048 + .mode = 0555,
70049 + .child = dev_table,
70050 + },
70051 ++
70052 + /*
70053 + * NOTE: do not add new entries to this table unless you have read
70054 + * Documentation/sysctl/ctl_unnumbered.txt
70055 +@@ -847,6 +871,25 @@ static struct ctl_table kern_table[] = {
70056 + .proc_handler = &proc_dointvec,
70057 + },
70058 + #endif
70059 ++
70060 ++#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
70061 ++ {
70062 ++ .ctl_name = CTL_UNNUMBERED,
70063 ++ .procname = "grsecurity",
70064 ++ .mode = 0500,
70065 ++ .child = grsecurity_table,
70066 ++ },
70067 ++#endif
70068 ++
70069 ++#ifdef CONFIG_PAX_SOFTMODE
70070 ++ {
70071 ++ .ctl_name = CTL_UNNUMBERED,
70072 ++ .procname = "pax",
70073 ++ .mode = 0500,
70074 ++ .child = pax_table,
70075 ++ },
70076 ++#endif
70077 ++
70078 + /*
70079 + * NOTE: do not add new entries to this table unless you have read
70080 + * Documentation/sysctl/ctl_unnumbered.txt
70081 +@@ -1176,6 +1219,7 @@ static struct ctl_table vm_table[] = {
70082 + .extra2 = &one,
70083 + },
70084 + #endif
70085 ++
70086 + /*
70087 + * NOTE: do not add new entries to this table unless you have read
70088 + * Documentation/sysctl/ctl_unnumbered.txt
70089 +@@ -1543,6 +1587,8 @@ static int do_sysctl_strategy(struct ctl
70090 + return 0;
70091 + }
70092 +
70093 ++static int sysctl_perm_nochk(struct ctl_table_root *root, struct ctl_table *table, int op);
70094 ++
70095 + static int parse_table(int __user *name, int nlen,
70096 + void __user *oldval, size_t __user *oldlenp,
70097 + void __user *newval, size_t newlen,
70098 +@@ -1561,7 +1607,7 @@ repeat:
70099 + if (n == table->ctl_name) {
70100 + int error;
70101 + if (table->child) {
70102 +- if (sysctl_perm(root, table, MAY_EXEC))
70103 ++ if (sysctl_perm_nochk(root, table, MAY_EXEC))
70104 + return -EPERM;
70105 + name++;
70106 + nlen--;
70107 +@@ -1658,6 +1704,33 @@ int sysctl_perm(struct ctl_table_root *r
70108 + return test_perm(mode, op);
70109 + }
70110 +
70111 ++int sysctl_perm_nochk(struct ctl_table_root *root, struct ctl_table *table, int op)
70112 ++{
70113 ++ int error;
70114 ++ int mode;
70115 ++
70116 ++ if (table->parent != NULL && table->parent->procname != NULL &&
70117 ++ table->procname != NULL &&
70118 ++ gr_handle_sysctl_mod(table->parent->procname, table->procname, op))
70119 ++ return -EACCES;
70120 ++ if (gr_handle_chroot_sysctl(op))
70121 ++ return -EACCES;
70122 ++ error = gr_handle_sysctl(table, op);
70123 ++ if (error)
70124 ++ return error;
70125 ++
70126 ++ error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
70127 ++ if (error)
70128 ++ return error;
70129 ++
70130 ++ if (root->permissions)
70131 ++ mode = root->permissions(root, current->nsproxy, table);
70132 ++ else
70133 ++ mode = table->mode;
70134 ++
70135 ++ return test_perm(mode, op);
70136 ++}
70137 ++
70138 + static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table)
70139 + {
70140 + for (; table->ctl_name || table->procname; table++) {
70141 +diff -urNp linux-2.6.27.7/kernel/time/tick-broadcast.c linux-2.6.27.7/kernel/time/tick-broadcast.c
70142 +--- linux-2.6.27.7/kernel/time/tick-broadcast.c 2008-11-07 12:55:34.000000000 -0500
70143 ++++ linux-2.6.27.7/kernel/time/tick-broadcast.c 2008-11-18 03:38:45.000000000 -0500
70144 +@@ -114,7 +114,7 @@ int tick_device_uses_broadcast(struct cl
70145 + * then clear the broadcast bit.
70146 + */
70147 + if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) {
70148 +- int cpu = smp_processor_id();
70149 ++ cpu = smp_processor_id();
70150 +
70151 + cpu_clear(cpu, tick_broadcast_mask);
70152 + tick_broadcast_clear_oneshot(cpu);
70153 +diff -urNp linux-2.6.27.7/kernel/time.c linux-2.6.27.7/kernel/time.c
70154 +--- linux-2.6.27.7/kernel/time.c 2008-11-07 12:55:34.000000000 -0500
70155 ++++ linux-2.6.27.7/kernel/time.c 2008-11-18 03:38:45.000000000 -0500
70156 +@@ -37,6 +37,7 @@
70157 + #include <linux/fs.h>
70158 + #include <linux/slab.h>
70159 + #include <linux/math64.h>
70160 ++#include <linux/grsecurity.h>
70161 +
70162 + #include <asm/uaccess.h>
70163 + #include <asm/unistd.h>
70164 +@@ -92,6 +93,9 @@ asmlinkage long sys_stime(time_t __user
70165 + return err;
70166 +
70167 + do_settimeofday(&tv);
70168 ++
70169 ++ gr_log_timechange();
70170 ++
70171 + return 0;
70172 + }
70173 +
70174 +@@ -200,6 +204,8 @@ asmlinkage long sys_settimeofday(struct
70175 + return -EFAULT;
70176 + }
70177 +
70178 ++ gr_log_timechange();
70179 ++
70180 + return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
70181 + }
70182 +
70183 +@@ -238,7 +244,7 @@ EXPORT_SYMBOL(current_fs_time);
70184 + * Avoid unnecessary multiplications/divisions in the
70185 + * two most common HZ cases:
70186 + */
70187 +-unsigned int inline jiffies_to_msecs(const unsigned long j)
70188 ++inline unsigned int jiffies_to_msecs(const unsigned long j)
70189 + {
70190 + #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
70191 + return (MSEC_PER_SEC / HZ) * j;
70192 +@@ -254,7 +260,7 @@ unsigned int inline jiffies_to_msecs(con
70193 + }
70194 + EXPORT_SYMBOL(jiffies_to_msecs);
70195 +
70196 +-unsigned int inline jiffies_to_usecs(const unsigned long j)
70197 ++inline unsigned int jiffies_to_usecs(const unsigned long j)
70198 + {
70199 + #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
70200 + return (USEC_PER_SEC / HZ) * j;
70201 +diff -urNp linux-2.6.27.7/kernel/utsname_sysctl.c linux-2.6.27.7/kernel/utsname_sysctl.c
70202 +--- linux-2.6.27.7/kernel/utsname_sysctl.c 2008-11-07 12:55:34.000000000 -0500
70203 ++++ linux-2.6.27.7/kernel/utsname_sysctl.c 2008-11-18 03:38:45.000000000 -0500
70204 +@@ -124,7 +124,7 @@ static struct ctl_table uts_kern_table[]
70205 + .proc_handler = proc_do_uts_string,
70206 + .strategy = sysctl_uts_string,
70207 + },
70208 +- {}
70209 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
70210 + };
70211 +
70212 + static struct ctl_table uts_root_table[] = {
70213 +@@ -134,7 +134,7 @@ static struct ctl_table uts_root_table[]
70214 + .mode = 0555,
70215 + .child = uts_kern_table,
70216 + },
70217 +- {}
70218 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
70219 + };
70220 +
70221 + static int __init utsname_sysctl_init(void)
70222 +diff -urNp linux-2.6.27.7/lib/radix-tree.c linux-2.6.27.7/lib/radix-tree.c
70223 +--- linux-2.6.27.7/lib/radix-tree.c 2008-11-07 12:55:34.000000000 -0500
70224 ++++ linux-2.6.27.7/lib/radix-tree.c 2008-11-18 03:38:45.000000000 -0500
70225 +@@ -81,7 +81,7 @@ struct radix_tree_preload {
70226 + int nr;
70227 + struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
70228 + };
70229 +-DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
70230 ++DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads);
70231 +
70232 + static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
70233 + {
70234 +diff -urNp linux-2.6.27.7/localversion-grsec linux-2.6.27.7/localversion-grsec
70235 +--- linux-2.6.27.7/localversion-grsec 1969-12-31 19:00:00.000000000 -0500
70236 ++++ linux-2.6.27.7/localversion-grsec 2008-11-18 03:38:45.000000000 -0500
70237 +@@ -0,0 +1 @@
70238 ++-grsec
70239 +diff -urNp linux-2.6.27.7/Makefile linux-2.6.27.7/Makefile
70240 +--- linux-2.6.27.7/Makefile 2008-11-18 11:38:40.000000000 -0500
70241 ++++ linux-2.6.27.7/Makefile 2008-11-18 11:40:52.000000000 -0500
70242 +@@ -221,7 +221,7 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH"
70243 +
70244 + HOSTCC = gcc
70245 + HOSTCXX = g++
70246 +-HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
70247 ++HOSTCFLAGS = -Wall -W -Wno-unused -Wno-sign-compare -Wstrict-prototypes -O2 -fomit-frame-pointer
70248 + HOSTCXXFLAGS = -O2
70249 +
70250 + # Decide whether to build built-in, modular, or both.
70251 +@@ -619,7 +619,7 @@ export mod_strip_cmd
70252 +
70253 +
70254 + ifeq ($(KBUILD_EXTMOD),)
70255 +-core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
70256 ++core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
70257 +
70258 + vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
70259 + $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
70260 +diff -urNp linux-2.6.27.7/mm/filemap.c linux-2.6.27.7/mm/filemap.c
70261 +--- linux-2.6.27.7/mm/filemap.c 2008-11-07 12:55:34.000000000 -0500
70262 ++++ linux-2.6.27.7/mm/filemap.c 2008-11-18 03:38:45.000000000 -0500
70263 +@@ -33,6 +33,7 @@
70264 + #include <linux/cpuset.h>
70265 + #include <linux/hardirq.h> /* for BUG_ON(!in_atomic()) only */
70266 + #include <linux/memcontrol.h>
70267 ++#include <linux/grsecurity.h>
70268 + #include "internal.h"
70269 +
70270 + /*
70271 +@@ -1588,7 +1589,7 @@ int generic_file_mmap(struct file * file
70272 + struct address_space *mapping = file->f_mapping;
70273 +
70274 + if (!mapping->a_ops->readpage)
70275 +- return -ENOEXEC;
70276 ++ return -ENODEV;
70277 + file_accessed(file);
70278 + vma->vm_ops = &generic_file_vm_ops;
70279 + vma->vm_flags |= VM_CAN_NONLINEAR;
70280 +@@ -1949,6 +1950,7 @@ inline int generic_write_checks(struct f
70281 + *pos = i_size_read(inode);
70282 +
70283 + if (limit != RLIM_INFINITY) {
70284 ++ gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
70285 + if (*pos >= limit) {
70286 + send_sig(SIGXFSZ, current, 0);
70287 + return -EFBIG;
70288 +diff -urNp linux-2.6.27.7/mm/fremap.c linux-2.6.27.7/mm/fremap.c
70289 +--- linux-2.6.27.7/mm/fremap.c 2008-11-07 12:55:34.000000000 -0500
70290 ++++ linux-2.6.27.7/mm/fremap.c 2008-11-18 03:38:45.000000000 -0500
70291 +@@ -151,6 +151,13 @@ asmlinkage long sys_remap_file_pages(uns
70292 + retry:
70293 + vma = find_vma(mm, start);
70294 +
70295 ++#ifdef CONFIG_PAX_SEGMEXEC
70296 ++ if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC)) {
70297 ++ up_read(&mm->mmap_sem);
70298 ++ return err;
70299 ++ }
70300 ++#endif
70301 ++
70302 + /*
70303 + * Make sure the vma is shared, that it supports prefaulting,
70304 + * and that the remapped range is valid and fully within
70305 +diff -urNp linux-2.6.27.7/mm/hugetlb.c linux-2.6.27.7/mm/hugetlb.c
70306 +--- linux-2.6.27.7/mm/hugetlb.c 2008-11-18 11:38:40.000000000 -0500
70307 ++++ linux-2.6.27.7/mm/hugetlb.c 2008-11-18 11:40:53.000000000 -0500
70308 +@@ -1833,6 +1833,26 @@ int unmap_ref_private(struct mm_struct *
70309 + return 1;
70310 + }
70311 +
70312 ++#ifdef CONFIG_PAX_SEGMEXEC
70313 ++static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m)
70314 ++{
70315 ++ struct mm_struct *mm = vma->vm_mm;
70316 ++ struct vm_area_struct *vma_m;
70317 ++ unsigned long address_m;
70318 ++ pte_t *ptep_m;
70319 ++
70320 ++ vma_m = pax_find_mirror_vma(vma);
70321 ++ if (!vma_m)
70322 ++ return;
70323 ++
70324 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
70325 ++ address_m = address + SEGMEXEC_TASK_SIZE;
70326 ++ ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK);
70327 ++ get_page(page_m);
70328 ++ set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0));
70329 ++}
70330 ++#endif
70331 ++
70332 + static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
70333 + unsigned long address, pte_t *ptep, pte_t pte,
70334 + struct page *pagecache_page)
70335 +@@ -1904,6 +1924,11 @@ retry_avoidcopy:
70336 + huge_ptep_clear_flush(vma, address, ptep);
70337 + set_huge_pte_at(mm, address, ptep,
70338 + make_huge_pte(vma, new_page, 1));
70339 ++
70340 ++#ifdef CONFIG_PAX_SEGMEXEC
70341 ++ pax_mirror_huge_pte(vma, address, new_page);
70342 ++#endif
70343 ++
70344 + /* Make the old page be freed below */
70345 + new_page = old_page;
70346 + }
70347 +@@ -2013,6 +2038,10 @@ retry:
70348 + && (vma->vm_flags & VM_SHARED)));
70349 + set_huge_pte_at(mm, address, ptep, new_pte);
70350 +
70351 ++#ifdef CONFIG_PAX_SEGMEXEC
70352 ++ pax_mirror_huge_pte(vma, address, page);
70353 ++#endif
70354 ++
70355 + if (write_access && !(vma->vm_flags & VM_SHARED)) {
70356 + /* Optimization, do the COW without a second fault */
70357 + ret = hugetlb_cow(mm, vma, address, ptep, new_pte, page);
70358 +@@ -2041,6 +2070,28 @@ int hugetlb_fault(struct mm_struct *mm,
70359 + static DEFINE_MUTEX(hugetlb_instantiation_mutex);
70360 + struct hstate *h = hstate_vma(vma);
70361 +
70362 ++#ifdef CONFIG_PAX_SEGMEXEC
70363 ++ struct vm_area_struct *vma_m;
70364 ++
70365 ++ vma_m = pax_find_mirror_vma(vma);
70366 ++ if (vma_m) {
70367 ++ unsigned long address_m;
70368 ++
70369 ++ if (vma->vm_start > vma_m->vm_start) {
70370 ++ address_m = address;
70371 ++ address -= SEGMEXEC_TASK_SIZE;
70372 ++ vma = vma_m;
70373 ++ h = hstate_vma(vma);
70374 ++ } else
70375 ++ address_m = address + SEGMEXEC_TASK_SIZE;
70376 ++
70377 ++ if (!huge_pte_alloc(mm, address_m, huge_page_size(h)))
70378 ++ return VM_FAULT_OOM;
70379 ++ address_m &= HPAGE_MASK;
70380 ++ unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE, NULL);
70381 ++ }
70382 ++#endif
70383 ++
70384 + ptep = huge_pte_alloc(mm, address, huge_page_size(h));
70385 + if (!ptep)
70386 + return VM_FAULT_OOM;
70387 +diff -urNp linux-2.6.27.7/mm/madvise.c linux-2.6.27.7/mm/madvise.c
70388 +--- linux-2.6.27.7/mm/madvise.c 2008-11-07 12:55:34.000000000 -0500
70389 ++++ linux-2.6.27.7/mm/madvise.c 2008-11-18 03:38:45.000000000 -0500
70390 +@@ -43,6 +43,10 @@ static long madvise_behavior(struct vm_a
70391 + pgoff_t pgoff;
70392 + int new_flags = vma->vm_flags;
70393 +
70394 ++#ifdef CONFIG_PAX_SEGMEXEC
70395 ++ struct vm_area_struct *vma_m;
70396 ++#endif
70397 ++
70398 + switch (behavior) {
70399 + case MADV_NORMAL:
70400 + new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
70401 +@@ -92,6 +96,13 @@ success:
70402 + /*
70403 + * vm_flags is protected by the mmap_sem held in write mode.
70404 + */
70405 ++
70406 ++#ifdef CONFIG_PAX_SEGMEXEC
70407 ++ vma_m = pax_find_mirror_vma(vma);
70408 ++ if (vma_m)
70409 ++ vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT);
70410 ++#endif
70411 ++
70412 + vma->vm_flags = new_flags;
70413 +
70414 + out:
70415 +@@ -236,6 +247,17 @@ madvise_vma(struct vm_area_struct *vma,
70416 +
70417 + case MADV_DONTNEED:
70418 + error = madvise_dontneed(vma, prev, start, end);
70419 ++
70420 ++#ifdef CONFIG_PAX_SEGMEXEC
70421 ++ if (!error) {
70422 ++ struct vm_area_struct *vma_m, *prev_m;
70423 ++
70424 ++ vma_m = pax_find_mirror_vma(vma);
70425 ++ if (vma_m)
70426 ++ error = madvise_dontneed(vma_m, &prev_m, start + SEGMEXEC_TASK_SIZE, end + SEGMEXEC_TASK_SIZE);
70427 ++ }
70428 ++#endif
70429 ++
70430 + break;
70431 +
70432 + default:
70433 +@@ -308,6 +330,16 @@ asmlinkage long sys_madvise(unsigned lon
70434 + if (end < start)
70435 + goto out;
70436 +
70437 ++#ifdef CONFIG_PAX_SEGMEXEC
70438 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
70439 ++ if (end > SEGMEXEC_TASK_SIZE)
70440 ++ goto out;
70441 ++ } else
70442 ++#endif
70443 ++
70444 ++ if (end > TASK_SIZE)
70445 ++ goto out;
70446 ++
70447 + error = 0;
70448 + if (end == start)
70449 + goto out;
70450 +diff -urNp linux-2.6.27.7/mm/memory.c linux-2.6.27.7/mm/memory.c
70451 +--- linux-2.6.27.7/mm/memory.c 2008-11-07 12:55:34.000000000 -0500
70452 ++++ linux-2.6.27.7/mm/memory.c 2008-11-18 03:38:45.000000000 -0500
70453 +@@ -52,6 +52,7 @@
70454 + #include <linux/writeback.h>
70455 + #include <linux/memcontrol.h>
70456 + #include <linux/mmu_notifier.h>
70457 ++#include <linux/grsecurity.h>
70458 +
70459 + #include <asm/pgalloc.h>
70460 + #include <asm/uaccess.h>
70461 +@@ -1146,11 +1147,11 @@ int get_user_pages(struct task_struct *t
70462 + vm_flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
70463 + i = 0;
70464 +
70465 +- do {
70466 ++ while (len) {
70467 + struct vm_area_struct *vma;
70468 + unsigned int foll_flags;
70469 +
70470 +- vma = find_extend_vma(mm, start);
70471 ++ vma = find_vma(mm, start);
70472 + if (!vma && in_gate_area(tsk, start)) {
70473 + unsigned long pg = start & PAGE_MASK;
70474 + struct vm_area_struct *gate_vma = get_gate_vma(tsk);
70475 +@@ -1190,7 +1191,7 @@ int get_user_pages(struct task_struct *t
70476 + continue;
70477 + }
70478 +
70479 +- if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP))
70480 ++ if (!vma || start < vma->vm_start || (vma->vm_flags & (VM_IO | VM_PFNMAP))
70481 + || !(vm_flags & vma->vm_flags))
70482 + return i ? : -EFAULT;
70483 +
70484 +@@ -1263,7 +1264,7 @@ int get_user_pages(struct task_struct *t
70485 + start += PAGE_SIZE;
70486 + len--;
70487 + } while (len && start < vma->vm_end);
70488 +- } while (len);
70489 ++ }
70490 + return i;
70491 + }
70492 + EXPORT_SYMBOL(get_user_pages);
70493 +@@ -1741,6 +1742,186 @@ static inline void cow_user_page(struct
70494 + copy_user_highpage(dst, src, va, vma);
70495 + }
70496 +
70497 ++#ifdef CONFIG_PAX_SEGMEXEC
70498 ++static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd)
70499 ++{
70500 ++ struct mm_struct *mm = vma->vm_mm;
70501 ++ spinlock_t *ptl;
70502 ++ pte_t *pte, entry;
70503 ++
70504 ++ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
70505 ++ entry = *pte;
70506 ++ if (!pte_present(entry)) {
70507 ++ if (!pte_none(entry)) {
70508 ++ BUG_ON(pte_file(entry));
70509 ++ free_swap_and_cache(pte_to_swp_entry(entry));
70510 ++ pte_clear_not_present_full(mm, address, pte, 0);
70511 ++ }
70512 ++ } else {
70513 ++ struct page *page;
70514 ++
70515 ++ flush_cache_page(vma, address, pte_pfn(entry));
70516 ++ entry = ptep_clear_flush(vma, address, pte);
70517 ++ BUG_ON(pte_dirty(entry));
70518 ++ page = vm_normal_page(vma, address, entry);
70519 ++ if (page) {
70520 ++ update_hiwater_rss(mm);
70521 ++ if (PageAnon(page))
70522 ++ dec_mm_counter(mm, anon_rss);
70523 ++ else
70524 ++ dec_mm_counter(mm, file_rss);
70525 ++ page_remove_rmap(page, vma);
70526 ++ page_cache_release(page);
70527 ++ }
70528 ++ }
70529 ++ pte_unmap_unlock(pte, ptl);
70530 ++}
70531 ++
70532 ++/* PaX: if vma is mirrored, synchronize the mirror's PTE
70533 ++ *
70534 ++ * the ptl of the lower mapped page is held on entry and is not released on exit
70535 ++ * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
70536 ++ */
70537 ++static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
70538 ++{
70539 ++ struct mm_struct *mm = vma->vm_mm;
70540 ++ unsigned long address_m;
70541 ++ spinlock_t *ptl_m;
70542 ++ struct vm_area_struct *vma_m;
70543 ++ pmd_t *pmd_m;
70544 ++ pte_t *pte_m, entry_m;
70545 ++
70546 ++ BUG_ON(!page_m || !PageAnon(page_m));
70547 ++
70548 ++ vma_m = pax_find_mirror_vma(vma);
70549 ++ if (!vma_m)
70550 ++ return;
70551 ++
70552 ++ BUG_ON(!PageLocked(page_m));
70553 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
70554 ++ address_m = address + SEGMEXEC_TASK_SIZE;
70555 ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
70556 ++ pte_m = pte_offset_map_nested(pmd_m, address_m);
70557 ++ ptl_m = pte_lockptr(mm, pmd_m);
70558 ++ if (ptl != ptl_m) {
70559 ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
70560 ++ if (!pte_none(*pte_m))
70561 ++ goto out;
70562 ++ }
70563 ++
70564 ++ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
70565 ++ page_cache_get(page_m);
70566 ++ page_add_anon_rmap(page_m, vma_m, address_m);
70567 ++ inc_mm_counter(mm, anon_rss);
70568 ++ set_pte_at(mm, address_m, pte_m, entry_m);
70569 ++ update_mmu_cache(vma_m, address_m, entry_m);
70570 ++out:
70571 ++ if (ptl != ptl_m)
70572 ++ spin_unlock(ptl_m);
70573 ++ pte_unmap_nested(pte_m);
70574 ++ unlock_page(page_m);
70575 ++}
70576 ++
70577 ++void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
70578 ++{
70579 ++ struct mm_struct *mm = vma->vm_mm;
70580 ++ unsigned long address_m;
70581 ++ spinlock_t *ptl_m;
70582 ++ struct vm_area_struct *vma_m;
70583 ++ pmd_t *pmd_m;
70584 ++ pte_t *pte_m, entry_m;
70585 ++
70586 ++ BUG_ON(!page_m || PageAnon(page_m));
70587 ++
70588 ++ vma_m = pax_find_mirror_vma(vma);
70589 ++ if (!vma_m)
70590 ++ return;
70591 ++
70592 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
70593 ++ address_m = address + SEGMEXEC_TASK_SIZE;
70594 ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
70595 ++ pte_m = pte_offset_map_nested(pmd_m, address_m);
70596 ++ ptl_m = pte_lockptr(mm, pmd_m);
70597 ++ if (ptl != ptl_m) {
70598 ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
70599 ++ if (!pte_none(*pte_m))
70600 ++ goto out;
70601 ++ }
70602 ++
70603 ++ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
70604 ++ page_cache_get(page_m);
70605 ++ page_add_file_rmap(page_m);
70606 ++ inc_mm_counter(mm, file_rss);
70607 ++ set_pte_at(mm, address_m, pte_m, entry_m);
70608 ++ update_mmu_cache(vma_m, address_m, entry_m);
70609 ++out:
70610 ++ if (ptl != ptl_m)
70611 ++ spin_unlock(ptl_m);
70612 ++ pte_unmap_nested(pte_m);
70613 ++}
70614 ++
70615 ++static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl)
70616 ++{
70617 ++ struct mm_struct *mm = vma->vm_mm;
70618 ++ unsigned long address_m;
70619 ++ spinlock_t *ptl_m;
70620 ++ struct vm_area_struct *vma_m;
70621 ++ pmd_t *pmd_m;
70622 ++ pte_t *pte_m, entry_m;
70623 ++
70624 ++ vma_m = pax_find_mirror_vma(vma);
70625 ++ if (!vma_m)
70626 ++ return;
70627 ++
70628 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
70629 ++ address_m = address + SEGMEXEC_TASK_SIZE;
70630 ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
70631 ++ pte_m = pte_offset_map_nested(pmd_m, address_m);
70632 ++ ptl_m = pte_lockptr(mm, pmd_m);
70633 ++ if (ptl != ptl_m) {
70634 ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
70635 ++ if (!pte_none(*pte_m))
70636 ++ goto out;
70637 ++ }
70638 ++
70639 ++ entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
70640 ++ set_pte_at(mm, address_m, pte_m, entry_m);
70641 ++out:
70642 ++ if (ptl != ptl_m)
70643 ++ spin_unlock(ptl_m);
70644 ++ pte_unmap_nested(pte_m);
70645 ++}
70646 ++
70647 ++static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, pmd_t *pmd, spinlock_t *ptl)
70648 ++{
70649 ++ struct page *page_m;
70650 ++ pte_t entry;
70651 ++
70652 ++ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC))
70653 ++ goto out;
70654 ++
70655 ++ entry = *pte;
70656 ++ page_m = vm_normal_page(vma, address, entry);
70657 ++ if (!page_m)
70658 ++ pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl);
70659 ++ else if (PageAnon(page_m)) {
70660 ++ if (pax_find_mirror_vma(vma)) {
70661 ++ pte_unmap_unlock(pte, ptl);
70662 ++ lock_page(page_m);
70663 ++ pte = pte_offset_map_lock(vma->vm_mm, pmd, address, &ptl);
70664 ++ if (pte_same(entry, *pte))
70665 ++ pax_mirror_anon_pte(vma, address, page_m, ptl);
70666 ++ else
70667 ++ unlock_page(page_m);
70668 ++ }
70669 ++ } else
70670 ++ pax_mirror_file_pte(vma, address, page_m, ptl);
70671 ++
70672 ++out:
70673 ++ pte_unmap_unlock(pte, ptl);
70674 ++}
70675 ++#endif
70676 ++
70677 + /*
70678 + * This routine handles present pages, when users try to write
70679 + * to a shared page. It is done by copying the page to a new address
70680 +@@ -1869,6 +2050,12 @@ gotten:
70681 + */
70682 + page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
70683 + if (likely(pte_same(*page_table, orig_pte))) {
70684 ++
70685 ++#ifdef CONFIG_PAX_SEGMEXEC
70686 ++ if (pax_find_mirror_vma(vma))
70687 ++ BUG_ON(!trylock_page(new_page));
70688 ++#endif
70689 ++
70690 + if (old_page) {
70691 + if (!PageAnon(old_page)) {
70692 + dec_mm_counter(mm, file_rss);
70693 +@@ -1917,6 +2104,10 @@ gotten:
70694 + page_remove_rmap(old_page, vma);
70695 + }
70696 +
70697 ++#ifdef CONFIG_PAX_SEGMEXEC
70698 ++ pax_mirror_anon_pte(vma, address, new_page, ptl);
70699 ++#endif
70700 ++
70701 + /* Free the old page.. */
70702 + new_page = old_page;
70703 + ret |= VM_FAULT_WRITE;
70704 +@@ -2176,6 +2367,7 @@ int vmtruncate(struct inode * inode, lof
70705 + unsigned long limit;
70706 +
70707 + limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
70708 ++ gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
70709 + if (limit != RLIM_INFINITY && offset > limit)
70710 + goto out_sig;
70711 + if (offset > inode->i_sb->s_maxbytes)
70712 +@@ -2326,6 +2518,11 @@ static int do_swap_page(struct mm_struct
70713 + swap_free(entry);
70714 + if (vm_swap_full())
70715 + remove_exclusive_swap_page(page);
70716 ++
70717 ++#ifdef CONFIG_PAX_SEGMEXEC
70718 ++ if (write_access || !pax_find_mirror_vma(vma))
70719 ++#endif
70720 ++
70721 + unlock_page(page);
70722 +
70723 + if (write_access) {
70724 +@@ -2337,6 +2534,11 @@ static int do_swap_page(struct mm_struct
70725 +
70726 + /* No need to invalidate - it was non-present before */
70727 + update_mmu_cache(vma, address, pte);
70728 ++
70729 ++#ifdef CONFIG_PAX_SEGMEXEC
70730 ++ pax_mirror_anon_pte(vma, address, page, ptl);
70731 ++#endif
70732 ++
70733 + unlock:
70734 + pte_unmap_unlock(page_table, ptl);
70735 + out:
70736 +@@ -2381,6 +2583,12 @@ static int do_anonymous_page(struct mm_s
70737 + page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
70738 + if (!pte_none(*page_table))
70739 + goto release;
70740 ++
70741 ++#ifdef CONFIG_PAX_SEGMEXEC
70742 ++ if (pax_find_mirror_vma(vma))
70743 ++ BUG_ON(!trylock_page(page));
70744 ++#endif
70745 ++
70746 + inc_mm_counter(mm, anon_rss);
70747 + lru_cache_add_active(page);
70748 + page_add_new_anon_rmap(page, vma, address);
70749 +@@ -2388,6 +2596,11 @@ static int do_anonymous_page(struct mm_s
70750 +
70751 + /* No need to invalidate - it was non-present before */
70752 + update_mmu_cache(vma, address, entry);
70753 ++
70754 ++#ifdef CONFIG_PAX_SEGMEXEC
70755 ++ pax_mirror_anon_pte(vma, address, page, ptl);
70756 ++#endif
70757 ++
70758 + unlock:
70759 + pte_unmap_unlock(page_table, ptl);
70760 + return 0;
70761 +@@ -2516,6 +2729,12 @@ static int __do_fault(struct mm_struct *
70762 + */
70763 + /* Only go through if we didn't race with anybody else... */
70764 + if (likely(pte_same(*page_table, orig_pte))) {
70765 ++
70766 ++#ifdef CONFIG_PAX_SEGMEXEC
70767 ++ if (anon && pax_find_mirror_vma(vma))
70768 ++ BUG_ON(!trylock_page(page));
70769 ++#endif
70770 ++
70771 + flush_icache_page(vma, page);
70772 + entry = mk_pte(page, vma->vm_page_prot);
70773 + if (flags & FAULT_FLAG_WRITE)
70774 +@@ -2536,6 +2755,14 @@ static int __do_fault(struct mm_struct *
70775 +
70776 + /* no need to invalidate: a not-present page won't be cached */
70777 + update_mmu_cache(vma, address, entry);
70778 ++
70779 ++#ifdef CONFIG_PAX_SEGMEXEC
70780 ++ if (anon)
70781 ++ pax_mirror_anon_pte(vma, address, page, ptl);
70782 ++ else
70783 ++ pax_mirror_file_pte(vma, address, page, ptl);
70784 ++#endif
70785 ++
70786 + } else {
70787 + mem_cgroup_uncharge_page(page);
70788 + if (anon)
70789 +@@ -2668,6 +2895,12 @@ static inline int handle_pte_fault(struc
70790 + if (write_access)
70791 + flush_tlb_page(vma, address);
70792 + }
70793 ++
70794 ++#ifdef CONFIG_PAX_SEGMEXEC
70795 ++ pax_mirror_pte(vma, address, pte, pmd, ptl);
70796 ++ return 0;
70797 ++#endif
70798 ++
70799 + unlock:
70800 + pte_unmap_unlock(pte, ptl);
70801 + return 0;
70802 +@@ -2684,6 +2917,10 @@ int handle_mm_fault(struct mm_struct *mm
70803 + pmd_t *pmd;
70804 + pte_t *pte;
70805 +
70806 ++#ifdef CONFIG_PAX_SEGMEXEC
70807 ++ struct vm_area_struct *vma_m;
70808 ++#endif
70809 ++
70810 + __set_current_state(TASK_RUNNING);
70811 +
70812 + count_vm_event(PGFAULT);
70813 +@@ -2691,6 +2928,34 @@ int handle_mm_fault(struct mm_struct *mm
70814 + if (unlikely(is_vm_hugetlb_page(vma)))
70815 + return hugetlb_fault(mm, vma, address, write_access);
70816 +
70817 ++#ifdef CONFIG_PAX_SEGMEXEC
70818 ++ vma_m = pax_find_mirror_vma(vma);
70819 ++ if (vma_m) {
70820 ++ unsigned long address_m;
70821 ++ pgd_t *pgd_m;
70822 ++ pud_t *pud_m;
70823 ++ pmd_t *pmd_m;
70824 ++
70825 ++ if (vma->vm_start > vma_m->vm_start) {
70826 ++ address_m = address;
70827 ++ address -= SEGMEXEC_TASK_SIZE;
70828 ++ vma = vma_m;
70829 ++ } else
70830 ++ address_m = address + SEGMEXEC_TASK_SIZE;
70831 ++
70832 ++ pgd_m = pgd_offset(mm, address_m);
70833 ++ pud_m = pud_alloc(mm, pgd_m, address_m);
70834 ++ if (!pud_m)
70835 ++ return VM_FAULT_OOM;
70836 ++ pmd_m = pmd_alloc(mm, pud_m, address_m);
70837 ++ if (!pmd_m)
70838 ++ return VM_FAULT_OOM;
70839 ++ if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
70840 ++ return VM_FAULT_OOM;
70841 ++ pax_unmap_mirror_pte(vma_m, address_m, pmd_m);
70842 ++ }
70843 ++#endif
70844 ++
70845 + pgd = pgd_offset(mm, address);
70846 + pud = pud_alloc(mm, pgd, address);
70847 + if (!pud)
70848 +@@ -2798,7 +3063,7 @@ static int __init gate_vma_init(void)
70849 + gate_vma.vm_start = FIXADDR_USER_START;
70850 + gate_vma.vm_end = FIXADDR_USER_END;
70851 + gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
70852 +- gate_vma.vm_page_prot = __P101;
70853 ++ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
70854 + /*
70855 + * Make sure the vDSO gets into every core dump.
70856 + * Dumping its contents makes post-mortem fully interpretable later
70857 +diff -urNp linux-2.6.27.7/mm/mempolicy.c linux-2.6.27.7/mm/mempolicy.c
70858 +--- linux-2.6.27.7/mm/mempolicy.c 2008-11-07 12:55:34.000000000 -0500
70859 ++++ linux-2.6.27.7/mm/mempolicy.c 2008-11-18 03:38:45.000000000 -0500
70860 +@@ -555,6 +555,10 @@ static int mbind_range(struct vm_area_st
70861 + struct vm_area_struct *next;
70862 + int err;
70863 +
70864 ++#ifdef CONFIG_PAX_SEGMEXEC
70865 ++ struct vm_area_struct *vma_m;
70866 ++#endif
70867 ++
70868 + err = 0;
70869 + for (; vma && vma->vm_start < end; vma = next) {
70870 + next = vma->vm_next;
70871 +@@ -566,6 +570,16 @@ static int mbind_range(struct vm_area_st
70872 + err = policy_vma(vma, new);
70873 + if (err)
70874 + break;
70875 ++
70876 ++#ifdef CONFIG_PAX_SEGMEXEC
70877 ++ vma_m = pax_find_mirror_vma(vma);
70878 ++ if (vma_m) {
70879 ++ err = policy_vma(vma_m, new);
70880 ++ if (err)
70881 ++ break;
70882 ++ }
70883 ++#endif
70884 ++
70885 + }
70886 + return err;
70887 + }
70888 +@@ -951,6 +965,17 @@ static long do_mbind(unsigned long start
70889 +
70890 + if (end < start)
70891 + return -EINVAL;
70892 ++
70893 ++#ifdef CONFIG_PAX_SEGMEXEC
70894 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC) {
70895 ++ if (end > SEGMEXEC_TASK_SIZE)
70896 ++ return -EINVAL;
70897 ++ } else
70898 ++#endif
70899 ++
70900 ++ if (end > TASK_SIZE)
70901 ++ return -EINVAL;
70902 ++
70903 + if (end == start)
70904 + return 0;
70905 +
70906 +diff -urNp linux-2.6.27.7/mm/mlock.c linux-2.6.27.7/mm/mlock.c
70907 +--- linux-2.6.27.7/mm/mlock.c 2008-11-07 12:55:34.000000000 -0500
70908 ++++ linux-2.6.27.7/mm/mlock.c 2008-11-18 03:38:45.000000000 -0500
70909 +@@ -12,6 +12,7 @@
70910 + #include <linux/syscalls.h>
70911 + #include <linux/sched.h>
70912 + #include <linux/module.h>
70913 ++#include <linux/grsecurity.h>
70914 +
70915 + int can_do_mlock(void)
70916 + {
70917 +@@ -93,6 +94,17 @@ static int do_mlock(unsigned long start,
70918 + return -EINVAL;
70919 + if (end == start)
70920 + return 0;
70921 ++
70922 ++#ifdef CONFIG_PAX_SEGMEXEC
70923 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
70924 ++ if (end > SEGMEXEC_TASK_SIZE)
70925 ++ return -EINVAL;
70926 ++ } else
70927 ++#endif
70928 ++
70929 ++ if (end > TASK_SIZE)
70930 ++ return -EINVAL;
70931 ++
70932 + vma = find_vma_prev(current->mm, start, &prev);
70933 + if (!vma || vma->vm_start > start)
70934 + return -ENOMEM;
70935 +@@ -150,6 +162,7 @@ asmlinkage long sys_mlock(unsigned long
70936 + lock_limit >>= PAGE_SHIFT;
70937 +
70938 + /* check against resource limits */
70939 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
70940 + if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
70941 + error = do_mlock(start, len, 1);
70942 + up_write(&current->mm->mmap_sem);
70943 +@@ -171,10 +184,10 @@ asmlinkage long sys_munlock(unsigned lon
70944 + static int do_mlockall(int flags)
70945 + {
70946 + struct vm_area_struct * vma, * prev = NULL;
70947 +- unsigned int def_flags = 0;
70948 ++ unsigned int def_flags = current->mm->def_flags & ~VM_LOCKED;
70949 +
70950 + if (flags & MCL_FUTURE)
70951 +- def_flags = VM_LOCKED;
70952 ++ def_flags |= VM_LOCKED;
70953 + current->mm->def_flags = def_flags;
70954 + if (flags == MCL_FUTURE)
70955 + goto out;
70956 +@@ -182,6 +195,12 @@ static int do_mlockall(int flags)
70957 + for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
70958 + unsigned int newflags;
70959 +
70960 ++#ifdef CONFIG_PAX_SEGMEXEC
70961 ++ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
70962 ++ break;
70963 ++#endif
70964 ++
70965 ++ BUG_ON(vma->vm_end > TASK_SIZE);
70966 + newflags = vma->vm_flags | VM_LOCKED;
70967 + if (!(flags & MCL_CURRENT))
70968 + newflags &= ~VM_LOCKED;
70969 +@@ -211,6 +230,7 @@ asmlinkage long sys_mlockall(int flags)
70970 + lock_limit >>= PAGE_SHIFT;
70971 +
70972 + ret = -ENOMEM;
70973 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
70974 + if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
70975 + capable(CAP_IPC_LOCK))
70976 + ret = do_mlockall(flags);
70977 +diff -urNp linux-2.6.27.7/mm/mmap.c linux-2.6.27.7/mm/mmap.c
70978 +--- linux-2.6.27.7/mm/mmap.c 2008-11-07 12:55:34.000000000 -0500
70979 ++++ linux-2.6.27.7/mm/mmap.c 2008-11-18 03:38:45.000000000 -0500
70980 +@@ -27,6 +27,7 @@
70981 + #include <linux/mempolicy.h>
70982 + #include <linux/rmap.h>
70983 + #include <linux/mmu_notifier.h>
70984 ++#include <linux/grsecurity.h>
70985 +
70986 + #include <asm/uaccess.h>
70987 + #include <asm/cacheflush.h>
70988 +@@ -43,6 +44,16 @@
70989 + #define arch_rebalance_pgtables(addr, len) (addr)
70990 + #endif
70991 +
70992 ++static inline void verify_mm_writelocked(struct mm_struct *mm)
70993 ++{
70994 ++#if defined(CONFIG_DEBUG_VM) || defined(CONFIG_PAX)
70995 ++ if (unlikely(down_read_trylock(&mm->mmap_sem))) {
70996 ++ up_read(&mm->mmap_sem);
70997 ++ BUG();
70998 ++ }
70999 ++#endif
71000 ++}
71001 ++
71002 + static void unmap_region(struct mm_struct *mm,
71003 + struct vm_area_struct *vma, struct vm_area_struct *prev,
71004 + unsigned long start, unsigned long end);
71005 +@@ -68,16 +79,25 @@ static void unmap_region(struct mm_struc
71006 + * x: (no) no x: (no) yes x: (no) yes x: (yes) yes
71007 + *
71008 + */
71009 +-pgprot_t protection_map[16] = {
71010 ++pgprot_t protection_map[16] __read_only = {
71011 + __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
71012 + __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
71013 + };
71014 +
71015 + pgprot_t vm_get_page_prot(unsigned long vm_flags)
71016 + {
71017 +- return __pgprot(pgprot_val(protection_map[vm_flags &
71018 ++ pgprot_t prot = __pgprot(pgprot_val(protection_map[vm_flags &
71019 + (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]) |
71020 + pgprot_val(arch_vm_get_page_prot(vm_flags)));
71021 ++
71022 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
71023 ++ if (!nx_enabled &&
71024 ++ (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC &&
71025 ++ (vm_flags & (VM_READ | VM_WRITE)))
71026 ++ prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot)))));
71027 ++#endif
71028 ++
71029 ++ return prot;
71030 + }
71031 + EXPORT_SYMBOL(vm_get_page_prot);
71032 +
71033 +@@ -232,6 +252,7 @@ static struct vm_area_struct *remove_vma
71034 + struct vm_area_struct *next = vma->vm_next;
71035 +
71036 + might_sleep();
71037 ++ BUG_ON(vma->vm_mirror);
71038 + if (vma->vm_ops && vma->vm_ops->close)
71039 + vma->vm_ops->close(vma);
71040 + if (vma->vm_file) {
71041 +@@ -268,6 +289,7 @@ asmlinkage unsigned long sys_brk(unsigne
71042 + * not page aligned -Ram Gupta
71043 + */
71044 + rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
71045 ++ gr_learn_resource(current, RLIMIT_DATA, (brk - mm->start_brk) + (mm->end_data - mm->start_data), 1);
71046 + if (rlim < RLIM_INFINITY && (brk - mm->start_brk) +
71047 + (mm->end_data - mm->start_data) > rlim)
71048 + goto out;
71049 +@@ -697,6 +719,12 @@ static int
71050 + can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
71051 + struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
71052 + {
71053 ++
71054 ++#ifdef CONFIG_PAX_SEGMEXEC
71055 ++ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE)
71056 ++ return 0;
71057 ++#endif
71058 ++
71059 + if (is_mergeable_vma(vma, file, vm_flags) &&
71060 + is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
71061 + if (vma->vm_pgoff == vm_pgoff)
71062 +@@ -716,6 +744,12 @@ static int
71063 + can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
71064 + struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
71065 + {
71066 ++
71067 ++#ifdef CONFIG_PAX_SEGMEXEC
71068 ++ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE)
71069 ++ return 0;
71070 ++#endif
71071 ++
71072 + if (is_mergeable_vma(vma, file, vm_flags) &&
71073 + is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
71074 + pgoff_t vm_pglen;
71075 +@@ -758,12 +792,19 @@ can_vma_merge_after(struct vm_area_struc
71076 + struct vm_area_struct *vma_merge(struct mm_struct *mm,
71077 + struct vm_area_struct *prev, unsigned long addr,
71078 + unsigned long end, unsigned long vm_flags,
71079 +- struct anon_vma *anon_vma, struct file *file,
71080 ++ struct anon_vma *anon_vma, struct file *file,
71081 + pgoff_t pgoff, struct mempolicy *policy)
71082 + {
71083 + pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
71084 + struct vm_area_struct *area, *next;
71085 +
71086 ++#ifdef CONFIG_PAX_SEGMEXEC
71087 ++ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE;
71088 ++ struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL;
71089 ++
71090 ++ BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end);
71091 ++#endif
71092 ++
71093 + /*
71094 + * We later require that vma->vm_flags == vm_flags,
71095 + * so this tests vma->vm_flags & VM_SPECIAL, too.
71096 +@@ -779,6 +820,15 @@ struct vm_area_struct *vma_merge(struct
71097 + if (next && next->vm_end == end) /* cases 6, 7, 8 */
71098 + next = next->vm_next;
71099 +
71100 ++#ifdef CONFIG_PAX_SEGMEXEC
71101 ++ if (prev)
71102 ++ prev_m = pax_find_mirror_vma(prev);
71103 ++ if (area)
71104 ++ area_m = pax_find_mirror_vma(area);
71105 ++ if (next)
71106 ++ next_m = pax_find_mirror_vma(next);
71107 ++#endif
71108 ++
71109 + /*
71110 + * Can it merge with the predecessor?
71111 + */
71112 +@@ -798,9 +848,24 @@ struct vm_area_struct *vma_merge(struct
71113 + /* cases 1, 6 */
71114 + vma_adjust(prev, prev->vm_start,
71115 + next->vm_end, prev->vm_pgoff, NULL);
71116 +- } else /* cases 2, 5, 7 */
71117 ++
71118 ++#ifdef CONFIG_PAX_SEGMEXEC
71119 ++ if (prev_m)
71120 ++ vma_adjust(prev_m, prev_m->vm_start,
71121 ++ next_m->vm_end, prev_m->vm_pgoff, NULL);
71122 ++#endif
71123 ++
71124 ++ } else { /* cases 2, 5, 7 */
71125 + vma_adjust(prev, prev->vm_start,
71126 + end, prev->vm_pgoff, NULL);
71127 ++
71128 ++#ifdef CONFIG_PAX_SEGMEXEC
71129 ++ if (prev_m)
71130 ++ vma_adjust(prev_m, prev_m->vm_start,
71131 ++ end_m, prev_m->vm_pgoff, NULL);
71132 ++#endif
71133 ++
71134 ++ }
71135 + return prev;
71136 + }
71137 +
71138 +@@ -811,12 +876,27 @@ struct vm_area_struct *vma_merge(struct
71139 + mpol_equal(policy, vma_policy(next)) &&
71140 + can_vma_merge_before(next, vm_flags,
71141 + anon_vma, file, pgoff+pglen)) {
71142 +- if (prev && addr < prev->vm_end) /* case 4 */
71143 ++ if (prev && addr < prev->vm_end) { /* case 4 */
71144 + vma_adjust(prev, prev->vm_start,
71145 + addr, prev->vm_pgoff, NULL);
71146 +- else /* cases 3, 8 */
71147 ++
71148 ++#ifdef CONFIG_PAX_SEGMEXEC
71149 ++ if (prev_m)
71150 ++ vma_adjust(prev_m, prev_m->vm_start,
71151 ++ addr_m, prev_m->vm_pgoff, NULL);
71152 ++#endif
71153 ++
71154 ++ } else { /* cases 3, 8 */
71155 + vma_adjust(area, addr, next->vm_end,
71156 + next->vm_pgoff - pglen, NULL);
71157 ++
71158 ++#ifdef CONFIG_PAX_SEGMEXEC
71159 ++ if (area_m)
71160 ++ vma_adjust(area_m, addr_m, next_m->vm_end,
71161 ++ next_m->vm_pgoff - pglen, NULL);
71162 ++#endif
71163 ++
71164 ++ }
71165 + return area;
71166 + }
71167 +
71168 +@@ -891,14 +971,11 @@ none:
71169 + void vm_stat_account(struct mm_struct *mm, unsigned long flags,
71170 + struct file *file, long pages)
71171 + {
71172 +- const unsigned long stack_flags
71173 +- = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
71174 +-
71175 + if (file) {
71176 + mm->shared_vm += pages;
71177 + if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
71178 + mm->exec_vm += pages;
71179 +- } else if (flags & stack_flags)
71180 ++ } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
71181 + mm->stack_vm += pages;
71182 + if (flags & (VM_RESERVED|VM_IO))
71183 + mm->reserved_vm += pages;
71184 +@@ -926,7 +1003,7 @@ unsigned long do_mmap_pgoff(struct file
71185 + * (the exception is when the underlying filesystem is noexec
71186 + * mounted, in which case we dont add PROT_EXEC.)
71187 + */
71188 +- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
71189 ++ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
71190 + if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
71191 + prot |= PROT_EXEC;
71192 +
71193 +@@ -936,15 +1013,15 @@ unsigned long do_mmap_pgoff(struct file
71194 + if (!(flags & MAP_FIXED))
71195 + addr = round_hint_to_min(addr);
71196 +
71197 +- error = arch_mmap_check(addr, len, flags);
71198 +- if (error)
71199 +- return error;
71200 +-
71201 + /* Careful about overflows.. */
71202 + len = PAGE_ALIGN(len);
71203 + if (!len || len > TASK_SIZE)
71204 + return -ENOMEM;
71205 +
71206 ++ error = arch_mmap_check(addr, len, flags);
71207 ++ if (error)
71208 ++ return error;
71209 ++
71210 + /* offset overflow? */
71211 + if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
71212 + return -EOVERFLOW;
71213 +@@ -956,7 +1033,7 @@ unsigned long do_mmap_pgoff(struct file
71214 + /* Obtain the address to map to. we verify (or select) it and ensure
71215 + * that it represents a valid section of the address space.
71216 + */
71217 +- addr = get_unmapped_area(file, addr, len, pgoff, flags);
71218 ++ addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
71219 + if (addr & ~PAGE_MASK)
71220 + return addr;
71221 +
71222 +@@ -967,6 +1044,26 @@ unsigned long do_mmap_pgoff(struct file
71223 + vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
71224 + mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
71225 +
71226 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
71227 ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
71228 ++
71229 ++#ifdef CONFIG_PAX_MPROTECT
71230 ++ if (mm->pax_flags & MF_PAX_MPROTECT) {
71231 ++ if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
71232 ++ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
71233 ++ else
71234 ++ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
71235 ++ }
71236 ++#endif
71237 ++
71238 ++ }
71239 ++#endif
71240 ++
71241 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
71242 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file)
71243 ++ vm_flags &= ~VM_PAGEEXEC;
71244 ++#endif
71245 ++
71246 + if (flags & MAP_LOCKED) {
71247 + if (!can_do_mlock())
71248 + return -EPERM;
71249 +@@ -979,6 +1076,7 @@ unsigned long do_mmap_pgoff(struct file
71250 + locked += mm->locked_vm;
71251 + lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
71252 + lock_limit >>= PAGE_SHIFT;
71253 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
71254 + if (locked > lock_limit && !capable(CAP_IPC_LOCK))
71255 + return -EAGAIN;
71256 + }
71257 +@@ -1051,6 +1149,9 @@ unsigned long do_mmap_pgoff(struct file
71258 + if (error)
71259 + return error;
71260 +
71261 ++ if (!gr_acl_handle_mmap(file, prot))
71262 ++ return -EACCES;
71263 ++
71264 + return mmap_region(file, addr, len, flags, vm_flags, pgoff,
71265 + accountable);
71266 + }
71267 +@@ -1064,10 +1165,10 @@ EXPORT_SYMBOL(do_mmap_pgoff);
71268 + */
71269 + int vma_wants_writenotify(struct vm_area_struct *vma)
71270 + {
71271 +- unsigned int vm_flags = vma->vm_flags;
71272 ++ unsigned long vm_flags = vma->vm_flags;
71273 +
71274 + /* If it was private or non-writable, the write bit is already clear */
71275 +- if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED)))
71276 ++ if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED))
71277 + return 0;
71278 +
71279 + /* The backer wishes to know when pages are first written to? */
71280 +@@ -1101,14 +1202,24 @@ unsigned long mmap_region(struct file *f
71281 + unsigned long charged = 0;
71282 + struct inode *inode = file ? file->f_path.dentry->d_inode : NULL;
71283 +
71284 ++#ifdef CONFIG_PAX_SEGMEXEC
71285 ++ struct vm_area_struct *vma_m = NULL;
71286 ++#endif
71287 ++
71288 ++ /*
71289 ++ * mm->mmap_sem is required to protect against another thread
71290 ++ * changing the mappings in case we sleep.
71291 ++ */
71292 ++ verify_mm_writelocked(mm);
71293 ++
71294 + /* Clear old maps */
71295 + error = -ENOMEM;
71296 +-munmap_back:
71297 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
71298 + if (vma && vma->vm_start < addr + len) {
71299 + if (do_munmap(mm, addr, len))
71300 + return -ENOMEM;
71301 +- goto munmap_back;
71302 ++ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
71303 ++ BUG_ON(vma && vma->vm_start < addr + len);
71304 + }
71305 +
71306 + /* Check against address space limit. */
71307 +@@ -1155,6 +1266,16 @@ munmap_back:
71308 + goto unacct_error;
71309 + }
71310 +
71311 ++#ifdef CONFIG_PAX_SEGMEXEC
71312 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) {
71313 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
71314 ++ if (!vma_m) {
71315 ++ error = -ENOMEM;
71316 ++ goto free_vma;
71317 ++ }
71318 ++ }
71319 ++#endif
71320 ++
71321 + vma->vm_mm = mm;
71322 + vma->vm_start = addr;
71323 + vma->vm_end = addr + len;
71324 +@@ -1177,6 +1298,19 @@ munmap_back:
71325 + error = file->f_op->mmap(file, vma);
71326 + if (error)
71327 + goto unmap_and_free_vma;
71328 ++
71329 ++#ifdef CONFIG_PAX_SEGMEXEC
71330 ++ if (vma_m && (vm_flags & VM_EXECUTABLE))
71331 ++ added_exe_file_vma(mm);
71332 ++#endif
71333 ++
71334 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
71335 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) {
71336 ++ vma->vm_flags |= VM_PAGEEXEC;
71337 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
71338 ++ }
71339 ++#endif
71340 ++
71341 + if (vm_flags & VM_EXECUTABLE)
71342 + added_exe_file_vma(mm);
71343 + } else if (vm_flags & VM_SHARED) {
71344 +@@ -1209,12 +1343,29 @@ munmap_back:
71345 + vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) {
71346 + mpol_put(vma_policy(vma));
71347 + kmem_cache_free(vm_area_cachep, vma);
71348 ++ vma = NULL;
71349 + fput(file);
71350 ++
71351 ++#ifdef CONFIG_PAX_SEGMEXEC
71352 ++ if (vma_m) {
71353 ++ kmem_cache_free(vm_area_cachep, vma_m);
71354 ++
71355 ++ if (vm_flags & VM_EXECUTABLE)
71356 ++ removed_exe_file_vma(mm);
71357 ++ }
71358 ++#endif
71359 ++
71360 + if (vm_flags & VM_EXECUTABLE)
71361 + removed_exe_file_vma(mm);
71362 + } else {
71363 + vma_link(mm, vma, prev, rb_link, rb_parent);
71364 + file = vma->vm_file;
71365 ++
71366 ++#ifdef CONFIG_PAX_SEGMEXEC
71367 ++ if (vma_m)
71368 ++ pax_mirror_vma(vma_m, vma);
71369 ++#endif
71370 ++
71371 + }
71372 +
71373 + /* Once vma denies write, undo our temporary denial count */
71374 +@@ -1223,6 +1374,7 @@ munmap_back:
71375 + out:
71376 + mm->total_vm += len >> PAGE_SHIFT;
71377 + vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
71378 ++ track_exec_limit(mm, addr, addr + len, vm_flags);
71379 + if (vm_flags & VM_LOCKED) {
71380 + mm->locked_vm += len >> PAGE_SHIFT;
71381 + make_pages_present(addr, addr + len);
71382 +@@ -1241,6 +1393,12 @@ unmap_and_free_vma:
71383 + unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
71384 + charged = 0;
71385 + free_vma:
71386 ++
71387 ++#ifdef CONFIG_PAX_SEGMEXEC
71388 ++ if (vma_m)
71389 ++ kmem_cache_free(vm_area_cachep, vma_m);
71390 ++#endif
71391 ++
71392 + kmem_cache_free(vm_area_cachep, vma);
71393 + unacct_error:
71394 + if (charged)
71395 +@@ -1274,6 +1432,10 @@ arch_get_unmapped_area(struct file *filp
71396 + if (flags & MAP_FIXED)
71397 + return addr;
71398 +
71399 ++#ifdef CONFIG_PAX_RANDMMAP
71400 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
71401 ++#endif
71402 ++
71403 + if (addr) {
71404 + addr = PAGE_ALIGN(addr);
71405 + vma = find_vma(mm, addr);
71406 +@@ -1282,10 +1444,10 @@ arch_get_unmapped_area(struct file *filp
71407 + return addr;
71408 + }
71409 + if (len > mm->cached_hole_size) {
71410 +- start_addr = addr = mm->free_area_cache;
71411 ++ start_addr = addr = mm->free_area_cache;
71412 + } else {
71413 +- start_addr = addr = TASK_UNMAPPED_BASE;
71414 +- mm->cached_hole_size = 0;
71415 ++ start_addr = addr = mm->mmap_base;
71416 ++ mm->cached_hole_size = 0;
71417 + }
71418 +
71419 + full_search:
71420 +@@ -1296,9 +1458,8 @@ full_search:
71421 + * Start a new search - just in case we missed
71422 + * some holes.
71423 + */
71424 +- if (start_addr != TASK_UNMAPPED_BASE) {
71425 +- addr = TASK_UNMAPPED_BASE;
71426 +- start_addr = addr;
71427 ++ if (start_addr != mm->mmap_base) {
71428 ++ start_addr = addr = mm->mmap_base;
71429 + mm->cached_hole_size = 0;
71430 + goto full_search;
71431 + }
71432 +@@ -1320,10 +1481,16 @@ full_search:
71433 +
71434 + void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
71435 + {
71436 ++
71437 ++#ifdef CONFIG_PAX_SEGMEXEC
71438 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
71439 ++ return;
71440 ++#endif
71441 ++
71442 + /*
71443 + * Is this a new hole at the lowest possible address?
71444 + */
71445 +- if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
71446 ++ if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
71447 + mm->free_area_cache = addr;
71448 + mm->cached_hole_size = ~0UL;
71449 + }
71450 +@@ -1341,7 +1508,7 @@ arch_get_unmapped_area_topdown(struct fi
71451 + {
71452 + struct vm_area_struct *vma;
71453 + struct mm_struct *mm = current->mm;
71454 +- unsigned long addr = addr0;
71455 ++ unsigned long base = mm->mmap_base, addr = addr0;
71456 +
71457 + /* requested length too big for entire address space */
71458 + if (len > TASK_SIZE)
71459 +@@ -1350,6 +1517,10 @@ arch_get_unmapped_area_topdown(struct fi
71460 + if (flags & MAP_FIXED)
71461 + return addr;
71462 +
71463 ++#ifdef CONFIG_PAX_RANDMMAP
71464 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
71465 ++#endif
71466 ++
71467 + /* requesting a specific address */
71468 + if (addr) {
71469 + addr = PAGE_ALIGN(addr);
71470 +@@ -1407,13 +1578,21 @@ bottomup:
71471 + * can happen with large stack limits and large mmap()
71472 + * allocations.
71473 + */
71474 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
71475 ++
71476 ++#ifdef CONFIG_PAX_RANDMMAP
71477 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
71478 ++ mm->mmap_base += mm->delta_mmap;
71479 ++#endif
71480 ++
71481 ++ mm->free_area_cache = mm->mmap_base;
71482 + mm->cached_hole_size = ~0UL;
71483 +- mm->free_area_cache = TASK_UNMAPPED_BASE;
71484 + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
71485 + /*
71486 + * Restore the topdown base:
71487 + */
71488 +- mm->free_area_cache = mm->mmap_base;
71489 ++ mm->mmap_base = base;
71490 ++ mm->free_area_cache = base;
71491 + mm->cached_hole_size = ~0UL;
71492 +
71493 + return addr;
71494 +@@ -1422,6 +1601,12 @@ bottomup:
71495 +
71496 + void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
71497 + {
71498 ++
71499 ++#ifdef CONFIG_PAX_SEGMEXEC
71500 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
71501 ++ return;
71502 ++#endif
71503 ++
71504 + /*
71505 + * Is this a new hole at the highest possible address?
71506 + */
71507 +@@ -1429,8 +1614,10 @@ void arch_unmap_area_topdown(struct mm_s
71508 + mm->free_area_cache = addr;
71509 +
71510 + /* dont allow allocations above current base */
71511 +- if (mm->free_area_cache > mm->mmap_base)
71512 ++ if (mm->free_area_cache > mm->mmap_base) {
71513 + mm->free_area_cache = mm->mmap_base;
71514 ++ mm->cached_hole_size = ~0UL;
71515 ++ }
71516 + }
71517 +
71518 + unsigned long
71519 +@@ -1530,6 +1717,33 @@ out:
71520 + return prev ? prev->vm_next : vma;
71521 + }
71522 +
71523 ++#ifdef CONFIG_PAX_SEGMEXEC
71524 ++struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
71525 ++{
71526 ++ struct vm_area_struct *vma_m;
71527 ++
71528 ++ BUG_ON(!vma || vma->vm_start >= vma->vm_end);
71529 ++ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) {
71530 ++ BUG_ON(vma->vm_mirror);
71531 ++ return NULL;
71532 ++ }
71533 ++ BUG_ON(vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < vma->vm_start - SEGMEXEC_TASK_SIZE - 1);
71534 ++ vma_m = vma->vm_mirror;
71535 ++ BUG_ON(!vma_m || vma_m->vm_mirror != vma);
71536 ++ BUG_ON(vma->vm_file != vma_m->vm_file);
71537 ++ BUG_ON(vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start);
71538 ++ BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff || vma->anon_vma != vma_m->anon_vma);
71539 ++
71540 ++#ifdef CONFIG_PAX_MPROTECT
71541 ++ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED | VM_MAYNOTWRITE));
71542 ++#else
71543 ++ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED));
71544 ++#endif
71545 ++
71546 ++ return vma_m;
71547 ++}
71548 ++#endif
71549 ++
71550 + /*
71551 + * Verify that the stack growth is acceptable and
71552 + * update accounting. This is shared with both the
71553 +@@ -1546,6 +1760,7 @@ static int acct_stack_growth(struct vm_a
71554 + return -ENOMEM;
71555 +
71556 + /* Stack limit test */
71557 ++ gr_learn_resource(current, RLIMIT_STACK, size, 1);
71558 + if (size > rlim[RLIMIT_STACK].rlim_cur)
71559 + return -ENOMEM;
71560 +
71561 +@@ -1555,6 +1770,7 @@ static int acct_stack_growth(struct vm_a
71562 + unsigned long limit;
71563 + locked = mm->locked_vm + grow;
71564 + limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
71565 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
71566 + if (locked > limit && !capable(CAP_IPC_LOCK))
71567 + return -ENOMEM;
71568 + }
71569 +@@ -1569,7 +1785,7 @@ static int acct_stack_growth(struct vm_a
71570 + * Overcommit.. This must be the final test, as it will
71571 + * update security statistics.
71572 + */
71573 +- if (security_vm_enough_memory(grow))
71574 ++ if (security_vm_enough_memory_mm(mm, grow))
71575 + return -ENOMEM;
71576 +
71577 + /* Ok, everything looks good - let it rip */
71578 +@@ -1590,35 +1806,40 @@ static inline
71579 + #endif
71580 + int expand_upwards(struct vm_area_struct *vma, unsigned long address)
71581 + {
71582 +- int error;
71583 ++ int error, locknext;
71584 +
71585 + if (!(vma->vm_flags & VM_GROWSUP))
71586 + return -EFAULT;
71587 +
71588 ++ /* Also guard against wrapping around to address 0. */
71589 ++ if (address < PAGE_ALIGN(address+1))
71590 ++ address = PAGE_ALIGN(address+1);
71591 ++ else
71592 ++ return -ENOMEM;
71593 ++
71594 + /*
71595 + * We must make sure the anon_vma is allocated
71596 + * so that the anon_vma locking is not a noop.
71597 + */
71598 + if (unlikely(anon_vma_prepare(vma)))
71599 + return -ENOMEM;
71600 ++ locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN);
71601 ++ if (locknext && unlikely(anon_vma_prepare(vma->vm_next)))
71602 ++ return -ENOMEM;
71603 + anon_vma_lock(vma);
71604 ++ if (locknext)
71605 ++ anon_vma_lock(vma->vm_next);
71606 +
71607 + /*
71608 + * vma->vm_start/vm_end cannot change under us because the caller
71609 + * is required to hold the mmap_sem in read mode. We need the
71610 +- * anon_vma lock to serialize against concurrent expand_stacks.
71611 +- * Also guard against wrapping around to address 0.
71612 ++ * anon_vma locks to serialize against concurrent expand_stacks
71613 ++ * and expand_upwards.
71614 + */
71615 +- if (address < PAGE_ALIGN(address+4))
71616 +- address = PAGE_ALIGN(address+4);
71617 +- else {
71618 +- anon_vma_unlock(vma);
71619 +- return -ENOMEM;
71620 +- }
71621 + error = 0;
71622 +
71623 + /* Somebody else might have raced and expanded it already */
71624 +- if (address > vma->vm_end) {
71625 ++ if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) {
71626 + unsigned long size, grow;
71627 +
71628 + size = address - vma->vm_start;
71629 +@@ -1628,6 +1849,8 @@ int expand_upwards(struct vm_area_struct
71630 + if (!error)
71631 + vma->vm_end = address;
71632 + }
71633 ++ if (locknext)
71634 ++ anon_vma_unlock(vma->vm_next);
71635 + anon_vma_unlock(vma);
71636 + return error;
71637 + }
71638 +@@ -1639,7 +1862,8 @@ int expand_upwards(struct vm_area_struct
71639 + static inline int expand_downwards(struct vm_area_struct *vma,
71640 + unsigned long address)
71641 + {
71642 +- int error;
71643 ++ int error, lockprev = 0;
71644 ++ struct vm_area_struct *prev = NULL;
71645 +
71646 + /*
71647 + * We must make sure the anon_vma is allocated
71648 +@@ -1653,6 +1877,15 @@ static inline int expand_downwards(struc
71649 + if (error)
71650 + return error;
71651 +
71652 ++#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
71653 ++ find_vma_prev(vma->vm_mm, address, &prev);
71654 ++ lockprev = prev && (prev->vm_flags & VM_GROWSUP);
71655 ++#endif
71656 ++ if (lockprev && unlikely(anon_vma_prepare(prev)))
71657 ++ return -ENOMEM;
71658 ++ if (lockprev)
71659 ++ anon_vma_lock(prev);
71660 ++
71661 + anon_vma_lock(vma);
71662 +
71663 + /*
71664 +@@ -1662,9 +1895,15 @@ static inline int expand_downwards(struc
71665 + */
71666 +
71667 + /* Somebody else might have raced and expanded it already */
71668 +- if (address < vma->vm_start) {
71669 ++ if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) {
71670 + unsigned long size, grow;
71671 +
71672 ++#ifdef CONFIG_PAX_SEGMEXEC
71673 ++ struct vm_area_struct *vma_m;
71674 ++
71675 ++ vma_m = pax_find_mirror_vma(vma);
71676 ++#endif
71677 ++
71678 + size = vma->vm_end - address;
71679 + grow = (vma->vm_start - address) >> PAGE_SHIFT;
71680 +
71681 +@@ -1672,9 +1911,20 @@ static inline int expand_downwards(struc
71682 + if (!error) {
71683 + vma->vm_start = address;
71684 + vma->vm_pgoff -= grow;
71685 ++ track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
71686 ++
71687 ++#ifdef CONFIG_PAX_SEGMEXEC
71688 ++ if (vma_m) {
71689 ++ vma_m->vm_start -= grow << PAGE_SHIFT;
71690 ++ vma_m->vm_pgoff -= grow;
71691 ++ }
71692 ++#endif
71693 ++
71694 + }
71695 + }
71696 + anon_vma_unlock(vma);
71697 ++ if (lockprev)
71698 ++ anon_vma_unlock(prev);
71699 + return error;
71700 + }
71701 +
71702 +@@ -1746,6 +1996,13 @@ static void remove_vma_list(struct mm_st
71703 + do {
71704 + long nrpages = vma_pages(vma);
71705 +
71706 ++#ifdef CONFIG_PAX_SEGMEXEC
71707 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) {
71708 ++ vma = remove_vma(vma);
71709 ++ continue;
71710 ++ }
71711 ++#endif
71712 ++
71713 + mm->total_vm -= nrpages;
71714 + if (vma->vm_flags & VM_LOCKED)
71715 + mm->locked_vm -= nrpages;
71716 +@@ -1792,6 +2049,16 @@ detach_vmas_to_be_unmapped(struct mm_str
71717 +
71718 + insertion_point = (prev ? &prev->vm_next : &mm->mmap);
71719 + do {
71720 ++
71721 ++#ifdef CONFIG_PAX_SEGMEXEC
71722 ++ if (vma->vm_mirror) {
71723 ++ BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma);
71724 ++ vma->vm_mirror->vm_mirror = NULL;
71725 ++ vma->vm_mirror->vm_flags &= ~VM_EXEC;
71726 ++ vma->vm_mirror = NULL;
71727 ++ }
71728 ++#endif
71729 ++
71730 + rb_erase(&vma->vm_rb, &mm->mm_rb);
71731 + mm->map_count--;
71732 + tail_vma = vma;
71733 +@@ -1811,6 +2078,108 @@ detach_vmas_to_be_unmapped(struct mm_str
71734 + * Split a vma into two pieces at address 'addr', a new vma is allocated
71735 + * either for the first part or the tail.
71736 + */
71737 ++
71738 ++#ifdef CONFIG_PAX_SEGMEXEC
71739 ++int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
71740 ++ unsigned long addr, int new_below)
71741 ++{
71742 ++ struct mempolicy *pol;
71743 ++ struct vm_area_struct *new, *vma_m, *new_m = NULL;
71744 ++ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE;
71745 ++
71746 ++ if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK))
71747 ++ return -EINVAL;
71748 ++
71749 ++ vma_m = pax_find_mirror_vma(vma);
71750 ++ if (vma_m) {
71751 ++ BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE);
71752 ++ if (mm->map_count >= sysctl_max_map_count-1)
71753 ++ return -ENOMEM;
71754 ++ } else if (mm->map_count >= sysctl_max_map_count)
71755 ++ return -ENOMEM;
71756 ++
71757 ++ new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
71758 ++ if (!new)
71759 ++ return -ENOMEM;
71760 ++
71761 ++ if (vma_m) {
71762 ++ new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
71763 ++ if (!new_m) {
71764 ++ kmem_cache_free(vm_area_cachep, new);
71765 ++ return -ENOMEM;
71766 ++ }
71767 ++ }
71768 ++
71769 ++ /* most fields are the same, copy all, and then fixup */
71770 ++ *new = *vma;
71771 ++
71772 ++ if (new_below)
71773 ++ new->vm_end = addr;
71774 ++ else {
71775 ++ new->vm_start = addr;
71776 ++ new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
71777 ++ }
71778 ++
71779 ++ if (vma_m) {
71780 ++ *new_m = *vma_m;
71781 ++ new_m->vm_mirror = new;
71782 ++ new->vm_mirror = new_m;
71783 ++
71784 ++ if (new_below)
71785 ++ new_m->vm_end = addr_m;
71786 ++ else {
71787 ++ new_m->vm_start = addr_m;
71788 ++ new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT);
71789 ++ }
71790 ++ }
71791 ++
71792 ++ pol = mpol_dup(vma_policy(vma));
71793 ++ if (IS_ERR(pol)) {
71794 ++ if (new_m)
71795 ++ kmem_cache_free(vm_area_cachep, new_m);
71796 ++ kmem_cache_free(vm_area_cachep, new);
71797 ++ return PTR_ERR(pol);
71798 ++ }
71799 ++ vma_set_policy(new, pol);
71800 ++
71801 ++ if (new->vm_file) {
71802 ++ get_file(new->vm_file);
71803 ++ if (vma->vm_flags & VM_EXECUTABLE)
71804 ++ added_exe_file_vma(mm);
71805 ++ }
71806 ++
71807 ++ if (new->vm_ops && new->vm_ops->open)
71808 ++ new->vm_ops->open(new);
71809 ++
71810 ++ if (new_below)
71811 ++ vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
71812 ++ ((addr - new->vm_start) >> PAGE_SHIFT), new);
71813 ++ else
71814 ++ vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
71815 ++
71816 ++ if (vma_m) {
71817 ++ mpol_get(pol);
71818 ++ vma_set_policy(new_m, pol);
71819 ++
71820 ++ if (new_m->vm_file) {
71821 ++ get_file(new_m->vm_file);
71822 ++ if (vma_m->vm_flags & VM_EXECUTABLE)
71823 ++ added_exe_file_vma(mm);
71824 ++ }
71825 ++
71826 ++ if (new_m->vm_ops && new_m->vm_ops->open)
71827 ++ new_m->vm_ops->open(new_m);
71828 ++
71829 ++ if (new_below)
71830 ++ vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff +
71831 ++ ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m);
71832 ++ else
71833 ++ vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m);
71834 ++ }
71835 ++
71836 ++ return 0;
71837 ++}
71838 ++#else
71839 + int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
71840 + unsigned long addr, int new_below)
71841 + {
71842 +@@ -1862,17 +2231,37 @@ int split_vma(struct mm_struct * mm, str
71843 +
71844 + return 0;
71845 + }
71846 ++#endif
71847 +
71848 + /* Munmap is split into 2 main parts -- this part which finds
71849 + * what needs doing, and the areas themselves, which do the
71850 + * work. This now handles partial unmappings.
71851 + * Jeremy Fitzhardinge <jeremy@××××.org>
71852 + */
71853 ++#ifdef CONFIG_PAX_SEGMEXEC
71854 + int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
71855 + {
71856 ++ int ret = __do_munmap(mm, start, len);
71857 ++ if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC))
71858 ++ return ret;
71859 ++
71860 ++ return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
71861 ++}
71862 ++
71863 ++int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
71864 ++#else
71865 ++int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
71866 ++#endif
71867 ++{
71868 + unsigned long end;
71869 + struct vm_area_struct *vma, *prev, *last;
71870 +
71871 ++ /*
71872 ++ * mm->mmap_sem is required to protect against another thread
71873 ++ * changing the mappings in case we sleep.
71874 ++ */
71875 ++ verify_mm_writelocked(mm);
71876 ++
71877 + if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
71878 + return -EINVAL;
71879 +
71880 +@@ -1922,6 +2311,8 @@ int do_munmap(struct mm_struct *mm, unsi
71881 + /* Fix up all other VM information */
71882 + remove_vma_list(mm, vma);
71883 +
71884 ++ track_exec_limit(mm, start, end, 0UL);
71885 ++
71886 + return 0;
71887 + }
71888 +
71889 +@@ -1934,22 +2325,18 @@ asmlinkage long sys_munmap(unsigned long
71890 +
71891 + profile_munmap(addr);
71892 +
71893 ++#ifdef CONFIG_PAX_SEGMEXEC
71894 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
71895 ++ (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
71896 ++ return -EINVAL;
71897 ++#endif
71898 ++
71899 + down_write(&mm->mmap_sem);
71900 + ret = do_munmap(mm, addr, len);
71901 + up_write(&mm->mmap_sem);
71902 + return ret;
71903 + }
71904 +
71905 +-static inline void verify_mm_writelocked(struct mm_struct *mm)
71906 +-{
71907 +-#ifdef CONFIG_DEBUG_VM
71908 +- if (unlikely(down_read_trylock(&mm->mmap_sem))) {
71909 +- WARN_ON(1);
71910 +- up_read(&mm->mmap_sem);
71911 +- }
71912 +-#endif
71913 +-}
71914 +-
71915 + /*
71916 + * this is really a simplified "do_mmap". it only handles
71917 + * anonymous maps. eventually we may be able to do some
71918 +@@ -1963,6 +2350,11 @@ unsigned long do_brk(unsigned long addr,
71919 + struct rb_node ** rb_link, * rb_parent;
71920 + pgoff_t pgoff = addr >> PAGE_SHIFT;
71921 + int error;
71922 ++ unsigned long charged;
71923 ++
71924 ++#ifdef CONFIG_PAX_SEGMEXEC
71925 ++ struct vm_area_struct *vma_m = NULL;
71926 ++#endif
71927 +
71928 + len = PAGE_ALIGN(len);
71929 + if (!len)
71930 +@@ -1980,19 +2372,34 @@ unsigned long do_brk(unsigned long addr,
71931 +
71932 + flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
71933 +
71934 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
71935 ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
71936 ++ flags &= ~VM_EXEC;
71937 ++
71938 ++#ifdef CONFIG_PAX_MPROTECT
71939 ++ if (mm->pax_flags & MF_PAX_MPROTECT)
71940 ++ flags &= ~VM_MAYEXEC;
71941 ++#endif
71942 ++
71943 ++ }
71944 ++#endif
71945 ++
71946 + error = arch_mmap_check(addr, len, flags);
71947 + if (error)
71948 + return error;
71949 +
71950 ++ charged = len >> PAGE_SHIFT;
71951 ++
71952 + /*
71953 + * mlock MCL_FUTURE?
71954 + */
71955 + if (mm->def_flags & VM_LOCKED) {
71956 + unsigned long locked, lock_limit;
71957 +- locked = len >> PAGE_SHIFT;
71958 ++ locked = charged;
71959 + locked += mm->locked_vm;
71960 + lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
71961 + lock_limit >>= PAGE_SHIFT;
71962 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
71963 + if (locked > lock_limit && !capable(CAP_IPC_LOCK))
71964 + return -EAGAIN;
71965 + }
71966 +@@ -2006,22 +2413,22 @@ unsigned long do_brk(unsigned long addr,
71967 + /*
71968 + * Clear old maps. this also does some error checking for us
71969 + */
71970 +- munmap_back:
71971 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
71972 + if (vma && vma->vm_start < addr + len) {
71973 + if (do_munmap(mm, addr, len))
71974 + return -ENOMEM;
71975 +- goto munmap_back;
71976 ++ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
71977 ++ BUG_ON(vma && vma->vm_start < addr + len);
71978 + }
71979 +
71980 + /* Check against address space limits *after* clearing old maps... */
71981 +- if (!may_expand_vm(mm, len >> PAGE_SHIFT))
71982 ++ if (!may_expand_vm(mm, charged))
71983 + return -ENOMEM;
71984 +
71985 + if (mm->map_count > sysctl_max_map_count)
71986 + return -ENOMEM;
71987 +
71988 +- if (security_vm_enough_memory(len >> PAGE_SHIFT))
71989 ++ if (security_vm_enough_memory(charged))
71990 + return -ENOMEM;
71991 +
71992 + /* Can we just expand an old private anonymous mapping? */
71993 +@@ -2034,10 +2441,21 @@ unsigned long do_brk(unsigned long addr,
71994 + */
71995 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
71996 + if (!vma) {
71997 +- vm_unacct_memory(len >> PAGE_SHIFT);
71998 ++ vm_unacct_memory(charged);
71999 + return -ENOMEM;
72000 + }
72001 +
72002 ++#ifdef CONFIG_PAX_SEGMEXEC
72003 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (flags & VM_EXEC)) {
72004 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
72005 ++ if (!vma_m) {
72006 ++ kmem_cache_free(vm_area_cachep, vma);
72007 ++ vm_unacct_memory(charged);
72008 ++ return -ENOMEM;
72009 ++ }
72010 ++ }
72011 ++#endif
72012 ++
72013 + vma->vm_mm = mm;
72014 + vma->vm_start = addr;
72015 + vma->vm_end = addr + len;
72016 +@@ -2045,12 +2463,19 @@ unsigned long do_brk(unsigned long addr,
72017 + vma->vm_flags = flags;
72018 + vma->vm_page_prot = vm_get_page_prot(flags);
72019 + vma_link(mm, vma, prev, rb_link, rb_parent);
72020 ++
72021 ++#ifdef CONFIG_PAX_SEGMEXEC
72022 ++ if (vma_m)
72023 ++ pax_mirror_vma(vma_m, vma);
72024 ++#endif
72025 ++
72026 + out:
72027 +- mm->total_vm += len >> PAGE_SHIFT;
72028 ++ mm->total_vm += charged;
72029 + if (flags & VM_LOCKED) {
72030 +- mm->locked_vm += len >> PAGE_SHIFT;
72031 ++ mm->locked_vm += charged;
72032 + make_pages_present(addr, addr + len);
72033 + }
72034 ++ track_exec_limit(mm, addr, addr + len, flags);
72035 + return addr;
72036 + }
72037 +
72038 +@@ -2082,8 +2507,10 @@ void exit_mmap(struct mm_struct *mm)
72039 + * Walk the list again, actually closing and freeing it,
72040 + * with preemption enabled, without holding any MM locks.
72041 + */
72042 +- while (vma)
72043 ++ while (vma) {
72044 ++ vma->vm_mirror = NULL;
72045 + vma = remove_vma(vma);
72046 ++ }
72047 +
72048 + BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
72049 + }
72050 +@@ -2097,6 +2524,10 @@ int insert_vm_struct(struct mm_struct *
72051 + struct vm_area_struct * __vma, * prev;
72052 + struct rb_node ** rb_link, * rb_parent;
72053 +
72054 ++#ifdef CONFIG_PAX_SEGMEXEC
72055 ++ struct vm_area_struct *vma_m = NULL;
72056 ++#endif
72057 ++
72058 + /*
72059 + * The vm_pgoff of a purely anonymous vma should be irrelevant
72060 + * until its first write fault, when page's anon_vma and index
72061 +@@ -2119,7 +2550,22 @@ int insert_vm_struct(struct mm_struct *
72062 + if ((vma->vm_flags & VM_ACCOUNT) &&
72063 + security_vm_enough_memory_mm(mm, vma_pages(vma)))
72064 + return -ENOMEM;
72065 ++
72066 ++#ifdef CONFIG_PAX_SEGMEXEC
72067 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) {
72068 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
72069 ++ if (!vma_m)
72070 ++ return -ENOMEM;
72071 ++ }
72072 ++#endif
72073 ++
72074 + vma_link(mm, vma, prev, rb_link, rb_parent);
72075 ++
72076 ++#ifdef CONFIG_PAX_SEGMEXEC
72077 ++ if (vma_m)
72078 ++ pax_mirror_vma(vma_m, vma);
72079 ++#endif
72080 ++
72081 + return 0;
72082 + }
72083 +
72084 +@@ -2137,6 +2583,8 @@ struct vm_area_struct *copy_vma(struct v
72085 + struct rb_node **rb_link, *rb_parent;
72086 + struct mempolicy *pol;
72087 +
72088 ++ BUG_ON(vma->vm_mirror);
72089 ++
72090 + /*
72091 + * If anonymous vma has not yet been faulted, update new pgoff
72092 + * to match new location, to increase its chance of merging.
72093 +@@ -2180,6 +2628,35 @@ struct vm_area_struct *copy_vma(struct v
72094 + return new_vma;
72095 + }
72096 +
72097 ++#ifdef CONFIG_PAX_SEGMEXEC
72098 ++void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma)
72099 ++{
72100 ++ struct vm_area_struct *prev_m;
72101 ++ struct rb_node **rb_link_m, *rb_parent_m;
72102 ++ struct mempolicy *pol_m;
72103 ++
72104 ++ BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC));
72105 ++ BUG_ON(vma->vm_mirror || vma_m->vm_mirror);
72106 ++ BUG_ON(!mpol_equal(vma_policy(vma), vma_policy(vma_m)));
72107 ++ *vma_m = *vma;
72108 ++ pol_m = vma_policy(vma_m);
72109 ++ mpol_get(pol_m);
72110 ++ vma_set_policy(vma_m, pol_m);
72111 ++ vma_m->vm_start += SEGMEXEC_TASK_SIZE;
72112 ++ vma_m->vm_end += SEGMEXEC_TASK_SIZE;
72113 ++ vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED);
72114 ++ vma_m->vm_page_prot = vm_get_page_prot(vma_m->vm_flags);
72115 ++ if (vma_m->vm_file)
72116 ++ get_file(vma_m->vm_file);
72117 ++ if (vma_m->vm_ops && vma_m->vm_ops->open)
72118 ++ vma_m->vm_ops->open(vma_m);
72119 ++ find_vma_prepare(vma->vm_mm, vma_m->vm_start, &prev_m, &rb_link_m, &rb_parent_m);
72120 ++ vma_link(vma->vm_mm, vma_m, prev_m, rb_link_m, rb_parent_m);
72121 ++ vma_m->vm_mirror = vma;
72122 ++ vma->vm_mirror = vma_m;
72123 ++}
72124 ++#endif
72125 ++
72126 + /*
72127 + * Return true if the calling process may expand its vm space by the passed
72128 + * number of pages
72129 +@@ -2190,7 +2667,7 @@ int may_expand_vm(struct mm_struct *mm,
72130 + unsigned long lim;
72131 +
72132 + lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
72133 +-
72134 ++ gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
72135 + if (cur + npages > lim)
72136 + return 0;
72137 + return 1;
72138 +@@ -2259,6 +2736,15 @@ int install_special_mapping(struct mm_st
72139 + vma->vm_start = addr;
72140 + vma->vm_end = addr + len;
72141 +
72142 ++#ifdef CONFIG_PAX_MPROTECT
72143 ++ if (mm->pax_flags & MF_PAX_MPROTECT) {
72144 ++ if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC)
72145 ++ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
72146 ++ else
72147 ++ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
72148 ++ }
72149 ++#endif
72150 ++
72151 + vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
72152 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
72153 +
72154 +diff -urNp linux-2.6.27.7/mm/mprotect.c linux-2.6.27.7/mm/mprotect.c
72155 +--- linux-2.6.27.7/mm/mprotect.c 2008-11-07 12:55:34.000000000 -0500
72156 ++++ linux-2.6.27.7/mm/mprotect.c 2008-11-18 03:38:45.000000000 -0500
72157 +@@ -22,10 +22,17 @@
72158 + #include <linux/swap.h>
72159 + #include <linux/swapops.h>
72160 + #include <linux/mmu_notifier.h>
72161 ++#include <linux/grsecurity.h>
72162 ++
72163 ++#ifdef CONFIG_PAX_MPROTECT
72164 ++#include <linux/elf.h>
72165 ++#endif
72166 ++
72167 + #include <asm/uaccess.h>
72168 + #include <asm/pgtable.h>
72169 + #include <asm/cacheflush.h>
72170 + #include <asm/tlbflush.h>
72171 ++#include <asm/mmu_context.h>
72172 +
72173 + #ifndef pgprot_modify
72174 + static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
72175 +@@ -133,6 +140,48 @@ static void change_protection(struct vm_
72176 + flush_tlb_range(vma, start, end);
72177 + }
72178 +
72179 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
72180 ++/* called while holding the mmap semaphor for writing except stack expansion */
72181 ++void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
72182 ++{
72183 ++ unsigned long oldlimit, newlimit = 0UL;
72184 ++
72185 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || nx_enabled)
72186 ++ return;
72187 ++
72188 ++ spin_lock(&mm->page_table_lock);
72189 ++ oldlimit = mm->context.user_cs_limit;
72190 ++ if ((prot & VM_EXEC) && oldlimit < end)
72191 ++ /* USER_CS limit moved up */
72192 ++ newlimit = end;
72193 ++ else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
72194 ++ /* USER_CS limit moved down */
72195 ++ newlimit = start;
72196 ++
72197 ++ if (newlimit) {
72198 ++ mm->context.user_cs_limit = newlimit;
72199 ++
72200 ++#ifdef CONFIG_SMP
72201 ++ wmb();
72202 ++ cpus_clear(mm->context.cpu_user_cs_mask);
72203 ++ cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
72204 ++#endif
72205 ++
72206 ++ set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
72207 ++ }
72208 ++ spin_unlock(&mm->page_table_lock);
72209 ++ if (newlimit == end) {
72210 ++ struct vm_area_struct *vma = find_vma(mm, oldlimit);
72211 ++
72212 ++ for (; vma && vma->vm_start < end; vma = vma->vm_next)
72213 ++ if (is_vm_hugetlb_page(vma))
72214 ++ hugetlb_change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
72215 ++ else
72216 ++ change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
72217 ++ }
72218 ++}
72219 ++#endif
72220 ++
72221 + int
72222 + mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
72223 + unsigned long start, unsigned long end, unsigned long newflags)
72224 +@@ -145,6 +194,14 @@ mprotect_fixup(struct vm_area_struct *vm
72225 + int error;
72226 + int dirty_accountable = 0;
72227 +
72228 ++#ifdef CONFIG_PAX_SEGMEXEC
72229 ++ struct vm_area_struct *vma_m = NULL;
72230 ++ unsigned long start_m, end_m;
72231 ++
72232 ++ start_m = start + SEGMEXEC_TASK_SIZE;
72233 ++ end_m = end + SEGMEXEC_TASK_SIZE;
72234 ++#endif
72235 ++
72236 + if (newflags == oldflags) {
72237 + *pprev = vma;
72238 + return 0;
72239 +@@ -165,6 +222,38 @@ mprotect_fixup(struct vm_area_struct *vm
72240 + }
72241 + }
72242 +
72243 ++#ifdef CONFIG_PAX_SEGMEXEC
72244 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && ((oldflags ^ newflags) & VM_EXEC)) {
72245 ++ if (start != vma->vm_start) {
72246 ++ error = split_vma(mm, vma, start, 1);
72247 ++ if (error)
72248 ++ goto fail;
72249 ++ BUG_ON(!*pprev || (*pprev)->vm_next == vma);
72250 ++ *pprev = (*pprev)->vm_next;
72251 ++ }
72252 ++
72253 ++ if (end != vma->vm_end) {
72254 ++ error = split_vma(mm, vma, end, 0);
72255 ++ if (error)
72256 ++ goto fail;
72257 ++ }
72258 ++
72259 ++ if (pax_find_mirror_vma(vma)) {
72260 ++ error = __do_munmap(mm, start_m, end_m - start_m);
72261 ++ if (error)
72262 ++ goto fail;
72263 ++ } else {
72264 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
72265 ++ if (!vma_m) {
72266 ++ error = -ENOMEM;
72267 ++ goto fail;
72268 ++ }
72269 ++ vma->vm_flags = newflags;
72270 ++ pax_mirror_vma(vma_m, vma);
72271 ++ }
72272 ++ }
72273 ++#endif
72274 ++
72275 + /*
72276 + * First try to merge with previous and/or next vma.
72277 + */
72278 +@@ -219,6 +308,70 @@ fail:
72279 + return error;
72280 + }
72281 +
72282 ++#ifdef CONFIG_PAX_MPROTECT
72283 ++/* PaX: non-PIC ELF libraries need relocations on their executable segments
72284 ++ * therefore we'll grant them VM_MAYWRITE once during their life.
72285 ++ *
72286 ++ * The checks favour ld-linux.so behaviour which operates on a per ELF segment
72287 ++ * basis because we want to allow the common case and not the special ones.
72288 ++ */
72289 ++static inline void pax_handle_maywrite(struct vm_area_struct *vma, unsigned long start)
72290 ++{
72291 ++ struct elfhdr elf_h;
72292 ++ struct elf_phdr elf_p;
72293 ++ elf_addr_t dyn_offset = 0UL;
72294 ++ elf_dyn dyn;
72295 ++ unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
72296 ++
72297 ++#ifndef CONFIG_PAX_NOELFRELOCS
72298 ++ if ((vma->vm_start != start) ||
72299 ++ !vma->vm_file ||
72300 ++ !(vma->vm_flags & VM_MAYEXEC) ||
72301 ++ (vma->vm_flags & VM_MAYNOTWRITE))
72302 ++#endif
72303 ++
72304 ++ return;
72305 ++
72306 ++ if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) ||
72307 ++ memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
72308 ++
72309 ++#ifdef CONFIG_PAX_ETEXECRELOCS
72310 ++ (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
72311 ++#else
72312 ++ elf_h.e_type != ET_DYN ||
72313 ++#endif
72314 ++
72315 ++ !elf_check_arch(&elf_h) ||
72316 ++ elf_h.e_phentsize != sizeof(struct elf_phdr) ||
72317 ++ elf_h.e_phnum > j)
72318 ++ return;
72319 ++
72320 ++ for (i = 0UL; i < elf_h.e_phnum; i++) {
72321 ++ if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p)))
72322 ++ return;
72323 ++ if (elf_p.p_type == PT_DYNAMIC) {
72324 ++ dyn_offset = elf_p.p_offset;
72325 ++ j = i;
72326 ++ }
72327 ++ }
72328 ++ if (elf_h.e_phnum <= j)
72329 ++ return;
72330 ++
72331 ++ i = 0UL;
72332 ++ do {
72333 ++ if (sizeof(dyn) != kernel_read(vma->vm_file, dyn_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn)))
72334 ++ return;
72335 ++ if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
72336 ++ vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
72337 ++ gr_log_textrel(vma);
72338 ++ return;
72339 ++ }
72340 ++ i++;
72341 ++ } while (dyn.d_tag != DT_NULL);
72342 ++ return;
72343 ++}
72344 ++#endif
72345 ++
72346 + asmlinkage long
72347 + sys_mprotect(unsigned long start, size_t len, unsigned long prot)
72348 + {
72349 +@@ -238,6 +391,17 @@ sys_mprotect(unsigned long start, size_t
72350 + end = start + len;
72351 + if (end <= start)
72352 + return -ENOMEM;
72353 ++
72354 ++#ifdef CONFIG_PAX_SEGMEXEC
72355 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
72356 ++ if (end > SEGMEXEC_TASK_SIZE)
72357 ++ return -EINVAL;
72358 ++ } else
72359 ++#endif
72360 ++
72361 ++ if (end > TASK_SIZE)
72362 ++ return -EINVAL;
72363 ++
72364 + if (!arch_validate_prot(prot))
72365 + return -EINVAL;
72366 +
72367 +@@ -245,7 +409,7 @@ sys_mprotect(unsigned long start, size_t
72368 + /*
72369 + * Does the application expect PROT_READ to imply PROT_EXEC:
72370 + */
72371 +- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
72372 ++ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
72373 + prot |= PROT_EXEC;
72374 +
72375 + vm_flags = calc_vm_prot_bits(prot);
72376 +@@ -277,6 +441,16 @@ sys_mprotect(unsigned long start, size_t
72377 + if (start > vma->vm_start)
72378 + prev = vma;
72379 +
72380 ++ if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
72381 ++ error = -EACCES;
72382 ++ goto out;
72383 ++ }
72384 ++
72385 ++#ifdef CONFIG_PAX_MPROTECT
72386 ++ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
72387 ++ pax_handle_maywrite(vma, start);
72388 ++#endif
72389 ++
72390 + for (nstart = start ; ; ) {
72391 + unsigned long newflags;
72392 +
72393 +@@ -290,6 +464,12 @@ sys_mprotect(unsigned long start, size_t
72394 + goto out;
72395 + }
72396 +
72397 ++#ifdef CONFIG_PAX_MPROTECT
72398 ++ /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
72399 ++ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
72400 ++ newflags &= ~VM_MAYWRITE;
72401 ++#endif
72402 ++
72403 + error = security_file_mprotect(vma, reqprot, prot);
72404 + if (error)
72405 + goto out;
72406 +@@ -300,6 +480,9 @@ sys_mprotect(unsigned long start, size_t
72407 + error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
72408 + if (error)
72409 + goto out;
72410 ++
72411 ++ track_exec_limit(current->mm, nstart, tmp, vm_flags);
72412 ++
72413 + nstart = tmp;
72414 +
72415 + if (nstart < prev->vm_end)
72416 +diff -urNp linux-2.6.27.7/mm/mremap.c linux-2.6.27.7/mm/mremap.c
72417 +--- linux-2.6.27.7/mm/mremap.c 2008-11-07 12:55:34.000000000 -0500
72418 ++++ linux-2.6.27.7/mm/mremap.c 2008-11-18 03:38:45.000000000 -0500
72419 +@@ -111,6 +111,12 @@ static void move_ptes(struct vm_area_str
72420 + continue;
72421 + pte = ptep_clear_flush(vma, old_addr, old_pte);
72422 + pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
72423 ++
72424 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
72425 ++ if (!nx_enabled && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC)
72426 ++ pte = pte_exprotect(pte);
72427 ++#endif
72428 ++
72429 + set_pte_at(mm, new_addr, new_pte, pte);
72430 + }
72431 +
72432 +@@ -260,6 +266,7 @@ unsigned long do_mremap(unsigned long ad
72433 + struct vm_area_struct *vma;
72434 + unsigned long ret = -EINVAL;
72435 + unsigned long charged = 0;
72436 ++ unsigned long pax_task_size = TASK_SIZE;
72437 +
72438 + if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
72439 + goto out;
72440 +@@ -278,6 +285,15 @@ unsigned long do_mremap(unsigned long ad
72441 + if (!new_len)
72442 + goto out;
72443 +
72444 ++#ifdef CONFIG_PAX_SEGMEXEC
72445 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
72446 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
72447 ++#endif
72448 ++
72449 ++ if (new_len > pax_task_size || addr > pax_task_size-new_len ||
72450 ++ old_len > pax_task_size || addr > pax_task_size-old_len)
72451 ++ goto out;
72452 ++
72453 + /* new_addr is only valid if MREMAP_FIXED is specified */
72454 + if (flags & MREMAP_FIXED) {
72455 + if (new_addr & ~PAGE_MASK)
72456 +@@ -285,16 +301,13 @@ unsigned long do_mremap(unsigned long ad
72457 + if (!(flags & MREMAP_MAYMOVE))
72458 + goto out;
72459 +
72460 +- if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
72461 ++ if (new_addr > pax_task_size - new_len)
72462 + goto out;
72463 +
72464 + /* Check if the location we're moving into overlaps the
72465 + * old location at all, and fail if it does.
72466 + */
72467 +- if ((new_addr <= addr) && (new_addr+new_len) > addr)
72468 +- goto out;
72469 +-
72470 +- if ((addr <= new_addr) && (addr+old_len) > new_addr)
72471 ++ if (addr + old_len > new_addr && new_addr + new_len > addr)
72472 + goto out;
72473 +
72474 + ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
72475 +@@ -332,6 +345,14 @@ unsigned long do_mremap(unsigned long ad
72476 + ret = -EINVAL;
72477 + goto out;
72478 + }
72479 ++
72480 ++#ifdef CONFIG_PAX_SEGMEXEC
72481 ++ if (pax_find_mirror_vma(vma)) {
72482 ++ ret = -EINVAL;
72483 ++ goto out;
72484 ++ }
72485 ++#endif
72486 ++
72487 + /* We can't remap across vm area boundaries */
72488 + if (old_len > vma->vm_end - addr)
72489 + goto out;
72490 +@@ -365,7 +386,7 @@ unsigned long do_mremap(unsigned long ad
72491 + if (old_len == vma->vm_end - addr &&
72492 + !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
72493 + (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
72494 +- unsigned long max_addr = TASK_SIZE;
72495 ++ unsigned long max_addr = pax_task_size;
72496 + if (vma->vm_next)
72497 + max_addr = vma->vm_next->vm_start;
72498 + /* can we just expand the current mapping? */
72499 +@@ -383,6 +404,7 @@ unsigned long do_mremap(unsigned long ad
72500 + addr + new_len);
72501 + }
72502 + ret = addr;
72503 ++ track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
72504 + goto out;
72505 + }
72506 + }
72507 +@@ -393,8 +415,8 @@ unsigned long do_mremap(unsigned long ad
72508 + */
72509 + ret = -ENOMEM;
72510 + if (flags & MREMAP_MAYMOVE) {
72511 ++ unsigned long map_flags = 0;
72512 + if (!(flags & MREMAP_FIXED)) {
72513 +- unsigned long map_flags = 0;
72514 + if (vma->vm_flags & VM_MAYSHARE)
72515 + map_flags |= MAP_SHARED;
72516 +
72517 +@@ -409,7 +431,12 @@ unsigned long do_mremap(unsigned long ad
72518 + if (ret)
72519 + goto out;
72520 + }
72521 ++ map_flags = vma->vm_flags;
72522 + ret = move_vma(vma, addr, old_len, new_len, new_addr);
72523 ++ if (!(ret & ~PAGE_MASK)) {
72524 ++ track_exec_limit(current->mm, addr, addr + old_len, 0UL);
72525 ++ track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
72526 ++ }
72527 + }
72528 + out:
72529 + if (ret & ~PAGE_MASK)
72530 +diff -urNp linux-2.6.27.7/mm/nommu.c linux-2.6.27.7/mm/nommu.c
72531 +--- linux-2.6.27.7/mm/nommu.c 2008-11-07 12:55:34.000000000 -0500
72532 ++++ linux-2.6.27.7/mm/nommu.c 2008-11-18 03:38:45.000000000 -0500
72533 +@@ -437,15 +437,6 @@ struct vm_area_struct *find_vma(struct m
72534 + }
72535 + EXPORT_SYMBOL(find_vma);
72536 +
72537 +-/*
72538 +- * find a VMA
72539 +- * - we don't extend stack VMAs under NOMMU conditions
72540 +- */
72541 +-struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
72542 +-{
72543 +- return find_vma(mm, addr);
72544 +-}
72545 +-
72546 + int expand_stack(struct vm_area_struct *vma, unsigned long address)
72547 + {
72548 + return -ENOMEM;
72549 +diff -urNp linux-2.6.27.7/mm/page_alloc.c linux-2.6.27.7/mm/page_alloc.c
72550 +--- linux-2.6.27.7/mm/page_alloc.c 2008-11-17 20:03:30.000000000 -0500
72551 ++++ linux-2.6.27.7/mm/page_alloc.c 2008-11-18 03:38:45.000000000 -0500
72552 +@@ -515,9 +515,20 @@ static void free_pages_bulk(struct zone
72553 +
72554 + static void free_one_page(struct zone *zone, struct page *page, int order)
72555 + {
72556 ++
72557 ++#ifdef CONFIG_PAX_MEMORY_SANITIZE
72558 ++ unsigned long index = 1UL << order;
72559 ++#endif
72560 ++
72561 + spin_lock(&zone->lock);
72562 + zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE);
72563 + zone->pages_scanned = 0;
72564 ++
72565 ++#ifdef CONFIG_PAX_MEMORY_SANITIZE
72566 ++ for (; index; --index)
72567 ++ sanitize_highpage(page + index - 1);
72568 ++#endif
72569 ++
72570 + __free_one_page(page, zone, order);
72571 + spin_unlock(&zone->lock);
72572 + }
72573 +@@ -635,8 +646,10 @@ static int prep_new_page(struct page *pa
72574 + arch_alloc_page(page, order);
72575 + kernel_map_pages(page, 1 << order, 1);
72576 +
72577 ++#ifndef CONFIG_PAX_MEMORY_SANITIZE
72578 + if (gfp_flags & __GFP_ZERO)
72579 + prep_zero_page(page, order, gfp_flags);
72580 ++#endif
72581 +
72582 + if (order && (gfp_flags & __GFP_COMP))
72583 + prep_compound_page(page, order);
72584 +@@ -1009,6 +1022,11 @@ static void free_hot_cold_page(struct pa
72585 + list_add(&page->lru, &pcp->list);
72586 + set_page_private(page, get_pageblock_migratetype(page));
72587 + pcp->count++;
72588 ++
72589 ++#ifdef CONFIG_PAX_MEMORY_SANITIZE
72590 ++ sanitize_highpage(page);
72591 ++#endif
72592 ++
72593 + if (pcp->count >= pcp->high) {
72594 + free_pages_bulk(zone, pcp->batch, &pcp->list, 0);
72595 + pcp->count -= pcp->batch;
72596 +diff -urNp linux-2.6.27.7/mm/rmap.c linux-2.6.27.7/mm/rmap.c
72597 +--- linux-2.6.27.7/mm/rmap.c 2008-11-07 12:55:34.000000000 -0500
72598 ++++ linux-2.6.27.7/mm/rmap.c 2008-11-18 03:38:45.000000000 -0500
72599 +@@ -91,6 +91,10 @@ int anon_vma_prepare(struct vm_area_stru
72600 + struct mm_struct *mm = vma->vm_mm;
72601 + struct anon_vma *allocated;
72602 +
72603 ++#ifdef CONFIG_PAX_SEGMEXEC
72604 ++ struct vm_area_struct *vma_m;
72605 ++#endif
72606 ++
72607 + anon_vma = find_mergeable_anon_vma(vma);
72608 + allocated = NULL;
72609 + if (!anon_vma) {
72610 +@@ -104,6 +108,15 @@ int anon_vma_prepare(struct vm_area_stru
72611 + /* page_table_lock to protect against threads */
72612 + spin_lock(&mm->page_table_lock);
72613 + if (likely(!vma->anon_vma)) {
72614 ++
72615 ++#ifdef CONFIG_PAX_SEGMEXEC
72616 ++ vma_m = pax_find_mirror_vma(vma);
72617 ++ if (vma_m) {
72618 ++ vma_m->anon_vma = anon_vma;
72619 ++ __anon_vma_link(vma_m);
72620 ++ }
72621 ++#endif
72622 ++
72623 + vma->anon_vma = anon_vma;
72624 + list_add_tail(&vma->anon_vma_node, &anon_vma->head);
72625 + allocated = NULL;
72626 +diff -urNp linux-2.6.27.7/mm/shmem.c linux-2.6.27.7/mm/shmem.c
72627 +--- linux-2.6.27.7/mm/shmem.c 2008-11-07 12:55:34.000000000 -0500
72628 ++++ linux-2.6.27.7/mm/shmem.c 2008-11-18 03:38:45.000000000 -0500
72629 +@@ -2483,7 +2483,7 @@ static struct file_system_type tmpfs_fs_
72630 + .get_sb = shmem_get_sb,
72631 + .kill_sb = kill_litter_super,
72632 + };
72633 +-static struct vfsmount *shm_mnt;
72634 ++struct vfsmount *shm_mnt;
72635 +
72636 + static int __init init_tmpfs(void)
72637 + {
72638 +diff -urNp linux-2.6.27.7/mm/slab.c linux-2.6.27.7/mm/slab.c
72639 +--- linux-2.6.27.7/mm/slab.c 2008-11-07 12:55:34.000000000 -0500
72640 ++++ linux-2.6.27.7/mm/slab.c 2008-11-18 03:38:45.000000000 -0500
72641 +@@ -304,7 +304,7 @@ struct kmem_list3 {
72642 + * Need this for bootstrapping a per node allocator.
72643 + */
72644 + #define NUM_INIT_LISTS (3 * MAX_NUMNODES)
72645 +-struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
72646 ++struct kmem_list3 initkmem_list3[NUM_INIT_LISTS];
72647 + #define CACHE_CACHE 0
72648 + #define SIZE_AC MAX_NUMNODES
72649 + #define SIZE_L3 (2 * MAX_NUMNODES)
72650 +@@ -653,14 +653,14 @@ struct cache_names {
72651 + static struct cache_names __initdata cache_names[] = {
72652 + #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
72653 + #include <linux/kmalloc_sizes.h>
72654 +- {NULL,}
72655 ++ {NULL, NULL}
72656 + #undef CACHE
72657 + };
72658 +
72659 + static struct arraycache_init initarray_cache __initdata =
72660 +- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
72661 ++ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
72662 + static struct arraycache_init initarray_generic =
72663 +- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
72664 ++ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
72665 +
72666 + /* internal cache of cache description objs */
72667 + static struct kmem_cache cache_cache = {
72668 +@@ -2996,7 +2996,7 @@ retry:
72669 + * there must be at least one object available for
72670 + * allocation.
72671 + */
72672 +- BUG_ON(slabp->inuse < 0 || slabp->inuse >= cachep->num);
72673 ++ BUG_ON(slabp->inuse >= cachep->num);
72674 +
72675 + while (slabp->inuse < cachep->num && batchcount--) {
72676 + STATS_INC_ALLOCED(cachep);
72677 +diff -urNp linux-2.6.27.7/mm/tiny-shmem.c linux-2.6.27.7/mm/tiny-shmem.c
72678 +--- linux-2.6.27.7/mm/tiny-shmem.c 2008-11-07 12:55:34.000000000 -0500
72679 ++++ linux-2.6.27.7/mm/tiny-shmem.c 2008-11-18 03:38:45.000000000 -0500
72680 +@@ -26,7 +26,7 @@ static struct file_system_type tmpfs_fs_
72681 + .kill_sb = kill_litter_super,
72682 + };
72683 +
72684 +-static struct vfsmount *shm_mnt;
72685 ++struct vfsmount *shm_mnt;
72686 +
72687 + static int __init init_tmpfs(void)
72688 + {
72689 +diff -urNp linux-2.6.27.7/mm/util.c linux-2.6.27.7/mm/util.c
72690 +--- linux-2.6.27.7/mm/util.c 2008-11-07 12:55:34.000000000 -0500
72691 ++++ linux-2.6.27.7/mm/util.c 2008-11-18 03:38:45.000000000 -0500
72692 +@@ -167,6 +167,12 @@ EXPORT_SYMBOL(strndup_user);
72693 + void arch_pick_mmap_layout(struct mm_struct *mm)
72694 + {
72695 + mm->mmap_base = TASK_UNMAPPED_BASE;
72696 ++
72697 ++#ifdef CONFIG_PAX_RANDMMAP
72698 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
72699 ++ mm->mmap_base += mm->delta_mmap;
72700 ++#endif
72701 ++
72702 + mm->get_unmapped_area = arch_get_unmapped_area;
72703 + mm->unmap_area = arch_unmap_area;
72704 + }
72705 +diff -urNp linux-2.6.27.7/mm/vmalloc.c linux-2.6.27.7/mm/vmalloc.c
72706 +--- linux-2.6.27.7/mm/vmalloc.c 2008-11-07 12:55:34.000000000 -0500
72707 ++++ linux-2.6.27.7/mm/vmalloc.c 2008-11-18 03:38:45.000000000 -0500
72708 +@@ -98,19 +98,36 @@ static int vmap_pte_range(pmd_t *pmd, un
72709 + unsigned long end, pgprot_t prot, struct page ***pages)
72710 + {
72711 + pte_t *pte;
72712 ++ int ret = -ENOMEM;
72713 ++
72714 ++#ifdef CONFIG_PAX_KERNEXEC
72715 ++ unsigned long cr0;
72716 ++#endif
72717 +
72718 + pte = pte_alloc_kernel(pmd, addr);
72719 + if (!pte)
72720 + return -ENOMEM;
72721 ++
72722 ++#ifdef CONFIG_PAX_KERNEXEC
72723 ++ pax_open_kernel(cr0);
72724 ++#endif
72725 ++
72726 + do {
72727 + struct page *page = **pages;
72728 + WARN_ON(!pte_none(*pte));
72729 + if (!page)
72730 +- return -ENOMEM;
72731 ++ goto out;
72732 + set_pte_at(&init_mm, addr, pte, mk_pte(page, prot));
72733 + (*pages)++;
72734 + } while (pte++, addr += PAGE_SIZE, addr != end);
72735 +- return 0;
72736 ++ ret = 0;
72737 ++out:
72738 ++
72739 ++#ifdef CONFIG_PAX_KERNEXEC
72740 ++ pax_close_kernel(cr0);
72741 ++#endif
72742 ++
72743 ++ return ret;
72744 + }
72745 +
72746 + static inline int vmap_pmd_range(pud_t *pud, unsigned long addr,
72747 +@@ -215,6 +232,16 @@ __get_vm_area_node(unsigned long size, u
72748 + unsigned long addr;
72749 +
72750 + BUG_ON(in_interrupt());
72751 ++
72752 ++#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
72753 ++ if (flags & VM_KERNEXEC) {
72754 ++ if (start != VMALLOC_START || end != VMALLOC_END)
72755 ++ return NULL;
72756 ++ start = (unsigned long)MODULES_VADDR;
72757 ++ end = (unsigned long)MODULES_END;
72758 ++ }
72759 ++#endif
72760 ++
72761 + if (flags & VM_IOREMAP) {
72762 + int bit = fls(size);
72763 +
72764 +@@ -248,20 +275,15 @@ __get_vm_area_node(unsigned long size, u
72765 + (unsigned long)tmp->addr, align);
72766 + continue;
72767 + }
72768 +- if ((size + addr) < addr)
72769 +- goto out;
72770 + if (size + addr <= (unsigned long)tmp->addr)
72771 +- goto found;
72772 ++ break;
72773 + addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
72774 +- if (addr > end - size)
72775 +- goto out;
72776 + }
72777 + if ((size + addr) < addr)
72778 + goto out;
72779 + if (addr > end - size)
72780 + goto out;
72781 +
72782 +-found:
72783 + area->next = *p;
72784 + *p = area;
72785 +
72786 +@@ -466,6 +488,11 @@ void *vmap(struct page **pages, unsigned
72787 + if (count > num_physpages)
72788 + return NULL;
72789 +
72790 ++#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
72791 ++ if (!(pgprot_val(prot) & _PAGE_NX))
72792 ++ flags |= VM_KERNEXEC;
72793 ++#endif
72794 ++
72795 + area = get_vm_area_caller((count << PAGE_SHIFT), flags,
72796 + __builtin_return_address(0));
72797 + if (!area)
72798 +@@ -560,6 +587,13 @@ static void *__vmalloc_node(unsigned lon
72799 + if (!size || (size >> PAGE_SHIFT) > num_physpages)
72800 + return NULL;
72801 +
72802 ++#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
72803 ++ if (!(pgprot_val(prot) & _PAGE_NX))
72804 ++ area = __get_vm_area_node(size, VM_ALLOC | VM_KERNEXEC, VMALLOC_START, VMALLOC_END,
72805 ++ node, gfp_mask, caller);
72806 ++ else
72807 ++#endif
72808 ++
72809 + area = __get_vm_area_node(size, VM_ALLOC, VMALLOC_START, VMALLOC_END,
72810 + node, gfp_mask, caller);
72811 +
72812 +@@ -651,7 +685,7 @@ EXPORT_SYMBOL(vmalloc_node);
72813 +
72814 + void *vmalloc_exec(unsigned long size)
72815 + {
72816 +- return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC);
72817 ++ return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL_EXEC);
72818 + }
72819 +
72820 + #if defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA32)
72821 +diff -urNp linux-2.6.27.7/net/bridge/br_stp_if.c linux-2.6.27.7/net/bridge/br_stp_if.c
72822 +--- linux-2.6.27.7/net/bridge/br_stp_if.c 2008-11-07 12:55:34.000000000 -0500
72823 ++++ linux-2.6.27.7/net/bridge/br_stp_if.c 2008-11-18 03:38:45.000000000 -0500
72824 +@@ -146,7 +146,7 @@ static void br_stp_stop(struct net_bridg
72825 + char *envp[] = { NULL };
72826 +
72827 + if (br->stp_enabled == BR_USER_STP) {
72828 +- r = call_usermodehelper(BR_STP_PROG, argv, envp, 1);
72829 ++ r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
72830 + printk(KERN_INFO "%s: userspace STP stopped, return code %d\n",
72831 + br->dev->name, r);
72832 +
72833 +diff -urNp linux-2.6.27.7/net/core/flow.c linux-2.6.27.7/net/core/flow.c
72834 +--- linux-2.6.27.7/net/core/flow.c 2008-11-07 12:55:34.000000000 -0500
72835 ++++ linux-2.6.27.7/net/core/flow.c 2008-11-18 03:38:45.000000000 -0500
72836 +@@ -39,7 +39,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT(
72837 +
72838 + static u32 flow_hash_shift;
72839 + #define flow_hash_size (1 << flow_hash_shift)
72840 +-static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL };
72841 ++static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables);
72842 +
72843 + #define flow_table(cpu) (per_cpu(flow_tables, cpu))
72844 +
72845 +@@ -52,7 +52,7 @@ struct flow_percpu_info {
72846 + u32 hash_rnd;
72847 + int count;
72848 + };
72849 +-static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 };
72850 ++static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info);
72851 +
72852 + #define flow_hash_rnd_recalc(cpu) \
72853 + (per_cpu(flow_hash_info, cpu).hash_rnd_recalc)
72854 +@@ -69,7 +69,7 @@ struct flow_flush_info {
72855 + atomic_t cpuleft;
72856 + struct completion completion;
72857 + };
72858 +-static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL };
72859 ++static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets);
72860 +
72861 + #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu))
72862 +
72863 +diff -urNp linux-2.6.27.7/net/dccp/ccids/ccid3.c linux-2.6.27.7/net/dccp/ccids/ccid3.c
72864 +--- linux-2.6.27.7/net/dccp/ccids/ccid3.c 2008-11-07 12:55:34.000000000 -0500
72865 ++++ linux-2.6.27.7/net/dccp/ccids/ccid3.c 2008-11-18 03:38:45.000000000 -0500
72866 +@@ -43,7 +43,7 @@
72867 + static int ccid3_debug;
72868 + #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
72869 + #else
72870 +-#define ccid3_pr_debug(format, a...)
72871 ++#define ccid3_pr_debug(format, a...) do {} while (0)
72872 + #endif
72873 +
72874 + /*
72875 +diff -urNp linux-2.6.27.7/net/dccp/dccp.h linux-2.6.27.7/net/dccp/dccp.h
72876 +--- linux-2.6.27.7/net/dccp/dccp.h 2008-11-07 12:55:34.000000000 -0500
72877 ++++ linux-2.6.27.7/net/dccp/dccp.h 2008-11-18 03:38:45.000000000 -0500
72878 +@@ -43,8 +43,8 @@ extern int dccp_debug;
72879 + #define dccp_pr_debug(format, a...) DCCP_PR_DEBUG(dccp_debug, format, ##a)
72880 + #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a)
72881 + #else
72882 +-#define dccp_pr_debug(format, a...)
72883 +-#define dccp_pr_debug_cat(format, a...)
72884 ++#define dccp_pr_debug(format, a...) do {} while (0)
72885 ++#define dccp_pr_debug_cat(format, a...) do {} while (0)
72886 + #endif
72887 +
72888 + extern struct inet_hashinfo dccp_hashinfo;
72889 +diff -urNp linux-2.6.27.7/net/ipv4/inet_connection_sock.c linux-2.6.27.7/net/ipv4/inet_connection_sock.c
72890 +--- linux-2.6.27.7/net/ipv4/inet_connection_sock.c 2008-11-07 12:55:34.000000000 -0500
72891 ++++ linux-2.6.27.7/net/ipv4/inet_connection_sock.c 2008-11-18 03:38:45.000000000 -0500
72892 +@@ -15,6 +15,7 @@
72893 +
72894 + #include <linux/module.h>
72895 + #include <linux/jhash.h>
72896 ++#include <linux/grsecurity.h>
72897 +
72898 + #include <net/inet_connection_sock.h>
72899 + #include <net/inet_hashtables.h>
72900 +diff -urNp linux-2.6.27.7/net/ipv4/inet_hashtables.c linux-2.6.27.7/net/ipv4/inet_hashtables.c
72901 +--- linux-2.6.27.7/net/ipv4/inet_hashtables.c 2008-11-07 12:55:34.000000000 -0500
72902 ++++ linux-2.6.27.7/net/ipv4/inet_hashtables.c 2008-11-18 03:38:45.000000000 -0500
72903 +@@ -18,11 +18,14 @@
72904 + #include <linux/sched.h>
72905 + #include <linux/slab.h>
72906 + #include <linux/wait.h>
72907 ++#include <linux/grsecurity.h>
72908 +
72909 + #include <net/inet_connection_sock.h>
72910 + #include <net/inet_hashtables.h>
72911 + #include <net/ip.h>
72912 +
72913 ++extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
72914 ++
72915 + /*
72916 + * Allocate and initialize a new local port bind bucket.
72917 + * The bindhash mutex for snum's hash chain must be held here.
72918 +@@ -487,6 +490,8 @@ ok:
72919 + }
72920 + spin_unlock(&head->lock);
72921 +
72922 ++ gr_update_task_in_ip_table(current, inet_sk(sk));
72923 ++
72924 + if (tw) {
72925 + inet_twsk_deschedule(tw, death_row);
72926 + inet_twsk_put(tw);
72927 +diff -urNp linux-2.6.27.7/net/ipv4/netfilter/ipt_stealth.c linux-2.6.27.7/net/ipv4/netfilter/ipt_stealth.c
72928 +--- linux-2.6.27.7/net/ipv4/netfilter/ipt_stealth.c 1969-12-31 19:00:00.000000000 -0500
72929 ++++ linux-2.6.27.7/net/ipv4/netfilter/ipt_stealth.c 2008-11-18 03:38:45.000000000 -0500
72930 +@@ -0,0 +1,114 @@
72931 ++/* Kernel module to add stealth support.
72932 ++ *
72933 ++ * Copyright (C) 2002-2006 Brad Spengler <spender@××××××××××.net>
72934 ++ *
72935 ++ */
72936 ++
72937 ++#include <linux/kernel.h>
72938 ++#include <linux/module.h>
72939 ++#include <linux/skbuff.h>
72940 ++#include <linux/net.h>
72941 ++#include <linux/sched.h>
72942 ++#include <linux/inet.h>
72943 ++#include <linux/stddef.h>
72944 ++
72945 ++#include <net/ip.h>
72946 ++#include <net/sock.h>
72947 ++#include <net/tcp.h>
72948 ++#include <net/udp.h>
72949 ++#include <net/route.h>
72950 ++#include <net/inet_common.h>
72951 ++
72952 ++#include <linux/netfilter_ipv4/ip_tables.h>
72953 ++
72954 ++MODULE_LICENSE("GPL");
72955 ++
72956 ++extern struct sock *udp_v4_lookup(struct net *net, u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
72957 ++
72958 ++static bool
72959 ++match(const struct sk_buff *skb,
72960 ++ const struct net_device *in,
72961 ++ const struct net_device *out,
72962 ++ const struct xt_match *match,
72963 ++ const void *matchinfo,
72964 ++ int offset,
72965 ++ unsigned int protoff,
72966 ++ bool *hotdrop)
72967 ++{
72968 ++ struct iphdr *ip = ip_hdr(skb);
72969 ++ struct tcphdr th;
72970 ++ struct udphdr uh;
72971 ++ struct sock *sk = NULL;
72972 ++
72973 ++ if (!ip || offset) return false;
72974 ++
72975 ++ switch(ip->protocol) {
72976 ++ case IPPROTO_TCP:
72977 ++ if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &th, sizeof(th)) < 0) {
72978 ++ *hotdrop = true;
72979 ++ return false;
72980 ++ }
72981 ++ if (!(th.syn && !th.ack)) return false;
72982 ++ sk = inet_lookup_listener(dev_net(skb->dev), &tcp_hashinfo, ip->daddr, th.dest, inet_iif(skb));
72983 ++ break;
72984 ++ case IPPROTO_UDP:
72985 ++ if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &uh, sizeof(uh)) < 0) {
72986 ++ *hotdrop = true;
72987 ++ return false;
72988 ++ }
72989 ++ sk = udp_v4_lookup(dev_net(skb->dev), ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
72990 ++ break;
72991 ++ default:
72992 ++ return false;
72993 ++ }
72994 ++
72995 ++ if(!sk) // port is being listened on, match this
72996 ++ return true;
72997 ++ else {
72998 ++ sock_put(sk);
72999 ++ return false;
73000 ++ }
73001 ++}
73002 ++
73003 ++/* Called when user tries to insert an entry of this type. */
73004 ++static bool
73005 ++checkentry(const char *tablename,
73006 ++ const void *nip,
73007 ++ const struct xt_match *match,
73008 ++ void *matchinfo,
73009 ++ unsigned int hook_mask)
73010 ++{
73011 ++ const struct ipt_ip *ip = (const struct ipt_ip *)nip;
73012 ++
73013 ++ if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
73014 ++ ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
73015 ++ && (hook_mask & (1 << NF_INET_LOCAL_IN)))
73016 ++ return true;
73017 ++
73018 ++ printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
73019 ++
73020 ++ return false;
73021 ++}
73022 ++
73023 ++
73024 ++static struct xt_match stealth_match __read_mostly = {
73025 ++ .name = "stealth",
73026 ++ .family = AF_INET,
73027 ++ .match = match,
73028 ++ .checkentry = checkentry,
73029 ++ .destroy = NULL,
73030 ++ .me = THIS_MODULE
73031 ++};
73032 ++
73033 ++static int __init init(void)
73034 ++{
73035 ++ return xt_register_match(&stealth_match);
73036 ++}
73037 ++
73038 ++static void __exit fini(void)
73039 ++{
73040 ++ xt_unregister_match(&stealth_match);
73041 ++}
73042 ++
73043 ++module_init(init);
73044 ++module_exit(fini);
73045 +diff -urNp linux-2.6.27.7/net/ipv4/netfilter/Kconfig linux-2.6.27.7/net/ipv4/netfilter/Kconfig
73046 +--- linux-2.6.27.7/net/ipv4/netfilter/Kconfig 2008-11-07 12:55:34.000000000 -0500
73047 ++++ linux-2.6.27.7/net/ipv4/netfilter/Kconfig 2008-11-18 03:38:45.000000000 -0500
73048 +@@ -111,6 +111,21 @@ config IP_NF_MATCH_ADDRTYPE
73049 + If you want to compile it as a module, say M here and read
73050 + <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
73051 +
73052 ++config IP_NF_MATCH_STEALTH
73053 ++ tristate "stealth match support"
73054 ++ depends on IP_NF_IPTABLES
73055 ++ help
73056 ++ Enabling this option will drop all syn packets coming to unserved tcp
73057 ++ ports as well as all packets coming to unserved udp ports. If you
73058 ++ are using your system to route any type of packets (ie. via NAT)
73059 ++ you should put this module at the end of your ruleset, since it will
73060 ++ drop packets that aren't going to ports that are listening on your
73061 ++ machine itself, it doesn't take into account that the packet might be
73062 ++ destined for someone on your internal network if you're using NAT for
73063 ++ instance.
73064 ++
73065 ++ To compile it as a module, choose M here. If unsure, say N.
73066 ++
73067 + # `filter', generic and specific targets
73068 + config IP_NF_FILTER
73069 + tristate "Packet filtering"
73070 +@@ -407,4 +422,3 @@ config IP_NF_ARP_MANGLE
73071 + hardware and network addresses.
73072 +
73073 + endmenu
73074 +-
73075 +diff -urNp linux-2.6.27.7/net/ipv4/netfilter/Makefile linux-2.6.27.7/net/ipv4/netfilter/Makefile
73076 +--- linux-2.6.27.7/net/ipv4/netfilter/Makefile 2008-11-07 12:55:34.000000000 -0500
73077 ++++ linux-2.6.27.7/net/ipv4/netfilter/Makefile 2008-11-18 03:38:45.000000000 -0500
73078 +@@ -59,6 +59,7 @@ obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) +=
73079 + obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
73080 + obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
73081 + obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
73082 ++obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
73083 + obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
73084 + obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
73085 +
73086 +diff -urNp linux-2.6.27.7/net/ipv4/tcp_ipv4.c linux-2.6.27.7/net/ipv4/tcp_ipv4.c
73087 +--- linux-2.6.27.7/net/ipv4/tcp_ipv4.c 2008-11-07 12:55:34.000000000 -0500
73088 ++++ linux-2.6.27.7/net/ipv4/tcp_ipv4.c 2008-11-18 03:38:45.000000000 -0500
73089 +@@ -59,6 +59,7 @@
73090 + #include <linux/jhash.h>
73091 + #include <linux/init.h>
73092 + #include <linux/times.h>
73093 ++#include <linux/grsecurity.h>
73094 +
73095 + #include <net/net_namespace.h>
73096 + #include <net/icmp.h>
73097 +diff -urNp linux-2.6.27.7/net/ipv4/udp.c linux-2.6.27.7/net/ipv4/udp.c
73098 +--- linux-2.6.27.7/net/ipv4/udp.c 2008-11-07 12:55:34.000000000 -0500
73099 ++++ linux-2.6.27.7/net/ipv4/udp.c 2008-11-18 03:38:45.000000000 -0500
73100 +@@ -97,6 +97,7 @@
73101 + #include <linux/skbuff.h>
73102 + #include <linux/proc_fs.h>
73103 + #include <linux/seq_file.h>
73104 ++#include <linux/grsecurity.h>
73105 + #include <net/net_namespace.h>
73106 + #include <net/icmp.h>
73107 + #include <net/route.h>
73108 +@@ -104,6 +105,11 @@
73109 + #include <net/xfrm.h>
73110 + #include "udp_impl.h"
73111 +
73112 ++extern int gr_search_udp_recvmsg(const struct sock *sk,
73113 ++ const struct sk_buff *skb);
73114 ++extern int gr_search_udp_sendmsg(const struct sock *sk,
73115 ++ const struct sockaddr_in *addr);
73116 ++
73117 + /*
73118 + * Snmp MIB for the UDP layer
73119 + */
73120 +@@ -302,6 +308,13 @@ static struct sock *__udp4_lib_lookup(st
73121 + return result;
73122 + }
73123 +
73124 ++struct sock *udp_v4_lookup(struct net *net, __be32 saddr, __be16 sport,
73125 ++ __be32 daddr, __be16 dport, int dif)
73126 ++{
73127 ++ return __udp4_lib_lookup(net, saddr, sport, daddr, dport, dif, udp_hash);
73128 ++}
73129 ++
73130 ++
73131 + static inline struct sock *udp_v4_mcast_next(struct sock *sk,
73132 + __be16 loc_port, __be32 loc_addr,
73133 + __be16 rmt_port, __be32 rmt_addr,
73134 +@@ -591,9 +604,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
73135 + dport = usin->sin_port;
73136 + if (dport == 0)
73137 + return -EINVAL;
73138 ++
73139 ++ if (!gr_search_udp_sendmsg(sk, usin))
73140 ++ return -EPERM;
73141 + } else {
73142 + if (sk->sk_state != TCP_ESTABLISHED)
73143 + return -EDESTADDRREQ;
73144 ++
73145 ++ if (!gr_search_udp_sendmsg(sk, NULL))
73146 ++ return -EPERM;
73147 ++
73148 + daddr = inet->daddr;
73149 + dport = inet->dport;
73150 + /* Open fast path for connected socket.
73151 +@@ -858,6 +878,11 @@ try_again:
73152 + if (!skb)
73153 + goto out;
73154 +
73155 ++ if (!gr_search_udp_recvmsg(sk, skb)) {
73156 ++ err = -EPERM;
73157 ++ goto out_free;
73158 ++ }
73159 ++
73160 + ulen = skb->len - sizeof(struct udphdr);
73161 + copied = len;
73162 + if (copied > ulen)
73163 +diff -urNp linux-2.6.27.7/net/ipv6/exthdrs.c linux-2.6.27.7/net/ipv6/exthdrs.c
73164 +--- linux-2.6.27.7/net/ipv6/exthdrs.c 2008-11-07 12:55:34.000000000 -0500
73165 ++++ linux-2.6.27.7/net/ipv6/exthdrs.c 2008-11-18 03:38:45.000000000 -0500
73166 +@@ -624,7 +624,7 @@ static struct tlvtype_proc tlvprochopopt
73167 + .type = IPV6_TLV_JUMBO,
73168 + .func = ipv6_hop_jumbo,
73169 + },
73170 +- { -1, }
73171 ++ { -1, NULL }
73172 + };
73173 +
73174 + int ipv6_parse_hopopts(struct sk_buff *skb)
73175 +diff -urNp linux-2.6.27.7/net/ipv6/raw.c linux-2.6.27.7/net/ipv6/raw.c
73176 +--- linux-2.6.27.7/net/ipv6/raw.c 2008-11-07 12:55:34.000000000 -0500
73177 ++++ linux-2.6.27.7/net/ipv6/raw.c 2008-11-18 03:38:45.000000000 -0500
73178 +@@ -600,7 +600,7 @@ out:
73179 + return err;
73180 + }
73181 +
73182 +-static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
73183 ++static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
73184 + struct flowi *fl, struct rt6_info *rt,
73185 + unsigned int flags)
73186 + {
73187 +diff -urNp linux-2.6.27.7/net/irda/ircomm/ircomm_tty.c linux-2.6.27.7/net/irda/ircomm/ircomm_tty.c
73188 +--- linux-2.6.27.7/net/irda/ircomm/ircomm_tty.c 2008-11-07 12:55:34.000000000 -0500
73189 ++++ linux-2.6.27.7/net/irda/ircomm/ircomm_tty.c 2008-11-18 03:38:45.000000000 -0500
73190 +@@ -371,7 +371,7 @@ static int ircomm_tty_open(struct tty_st
73191 + IRDA_DEBUG(2, "%s()\n", __func__ );
73192 +
73193 + line = tty->index;
73194 +- if ((line < 0) || (line >= IRCOMM_TTY_PORTS)) {
73195 ++ if (line >= IRCOMM_TTY_PORTS) {
73196 + return -ENODEV;
73197 + }
73198 +
73199 +diff -urNp linux-2.6.27.7/net/sctp/socket.c linux-2.6.27.7/net/sctp/socket.c
73200 +--- linux-2.6.27.7/net/sctp/socket.c 2008-11-07 12:55:34.000000000 -0500
73201 ++++ linux-2.6.27.7/net/sctp/socket.c 2008-11-18 03:38:45.000000000 -0500
73202 +@@ -1434,7 +1434,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
73203 + struct sctp_sndrcvinfo *sinfo;
73204 + struct sctp_initmsg *sinit;
73205 + sctp_assoc_t associd = 0;
73206 +- sctp_cmsgs_t cmsgs = { NULL };
73207 ++ sctp_cmsgs_t cmsgs = { NULL, NULL };
73208 + int err;
73209 + sctp_scope_t scope;
73210 + long timeo;
73211 +@@ -5616,7 +5616,6 @@ pp_found:
73212 + */
73213 + int reuse = sk->sk_reuse;
73214 + struct sock *sk2;
73215 +- struct hlist_node *node;
73216 +
73217 + SCTP_DEBUG_PRINTK("sctp_get_port() found a possible match\n");
73218 + if (pp->fastreuse && sk->sk_reuse &&
73219 +diff -urNp linux-2.6.27.7/net/socket.c linux-2.6.27.7/net/socket.c
73220 +--- linux-2.6.27.7/net/socket.c 2008-11-07 12:55:34.000000000 -0500
73221 ++++ linux-2.6.27.7/net/socket.c 2008-11-18 03:38:45.000000000 -0500
73222 +@@ -87,6 +87,7 @@
73223 + #include <linux/audit.h>
73224 + #include <linux/wireless.h>
73225 + #include <linux/nsproxy.h>
73226 ++#include <linux/in.h>
73227 +
73228 + #include <asm/uaccess.h>
73229 + #include <asm/unistd.h>
73230 +@@ -97,6 +98,21 @@
73231 + #include <net/sock.h>
73232 + #include <linux/netfilter.h>
73233 +
73234 ++extern void gr_attach_curr_ip(const struct sock *sk);
73235 ++extern int gr_handle_sock_all(const int family, const int type,
73236 ++ const int protocol);
73237 ++extern int gr_handle_sock_server(const struct sockaddr *sck);
73238 ++extern int gr_handle_sock_server_other(const struct socket *sck);
73239 ++extern int gr_handle_sock_client(const struct sockaddr *sck);
73240 ++extern int gr_search_connect(const struct socket * sock,
73241 ++ const struct sockaddr_in * addr);
73242 ++extern int gr_search_bind(const struct socket * sock,
73243 ++ const struct sockaddr_in * addr);
73244 ++extern int gr_search_listen(const struct socket * sock);
73245 ++extern int gr_search_accept(const struct socket * sock);
73246 ++extern int gr_search_socket(const int domain, const int type,
73247 ++ const int protocol);
73248 ++
73249 + static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
73250 + static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
73251 + unsigned long nr_segs, loff_t pos);
73252 +@@ -300,7 +316,7 @@ static int sockfs_get_sb(struct file_sys
73253 + mnt);
73254 + }
73255 +
73256 +-static struct vfsmount *sock_mnt __read_mostly;
73257 ++struct vfsmount *sock_mnt __read_mostly;
73258 +
73259 + static struct file_system_type sock_fs_type = {
73260 + .name = "sockfs",
73261 +@@ -1236,6 +1252,16 @@ asmlinkage long sys_socket(int family, i
73262 + if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
73263 + flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
73264 +
73265 ++ if(!gr_search_socket(family, type, protocol)) {
73266 ++ retval = -EACCES;
73267 ++ goto out;
73268 ++ }
73269 ++
73270 ++ if (gr_handle_sock_all(family, type, protocol)) {
73271 ++ retval = -EACCES;
73272 ++ goto out;
73273 ++ }
73274 ++
73275 + retval = sock_create(family, type, protocol, &sock);
73276 + if (retval < 0)
73277 + goto out;
73278 +@@ -1375,6 +1401,12 @@ asmlinkage long sys_bind(int fd, struct
73279 + if (sock) {
73280 + err = move_addr_to_kernel(umyaddr, addrlen, (struct sockaddr *)&address);
73281 + if (err >= 0) {
73282 ++ if (!gr_search_bind(sock, (struct sockaddr_in *)&address) ||
73283 ++ gr_handle_sock_server((struct sockaddr *)&address)) {
73284 ++ err = -EACCES;
73285 ++ goto error;
73286 ++ }
73287 ++
73288 + err = security_socket_bind(sock,
73289 + (struct sockaddr *)&address,
73290 + addrlen);
73291 +@@ -1383,6 +1415,7 @@ asmlinkage long sys_bind(int fd, struct
73292 + (struct sockaddr *)
73293 + &address, addrlen);
73294 + }
73295 ++error:
73296 + fput_light(sock->file, fput_needed);
73297 + }
73298 + return err;
73299 +@@ -1406,10 +1439,17 @@ asmlinkage long sys_listen(int fd, int b
73300 + if ((unsigned)backlog > somaxconn)
73301 + backlog = somaxconn;
73302 +
73303 ++ if (gr_handle_sock_server_other(sock) ||
73304 ++ !gr_search_listen(sock)) {
73305 ++ err = -EPERM;
73306 ++ goto error;
73307 ++ }
73308 ++
73309 + err = security_socket_listen(sock, backlog);
73310 + if (!err)
73311 + err = sock->ops->listen(sock, backlog);
73312 +
73313 ++error:
73314 + fput_light(sock->file, fput_needed);
73315 + }
73316 + return err;
73317 +@@ -1452,6 +1492,13 @@ long do_accept(int fd, struct sockaddr _
73318 + newsock->type = sock->type;
73319 + newsock->ops = sock->ops;
73320 +
73321 ++ if (gr_handle_sock_server_other(sock) ||
73322 ++ !gr_search_accept(sock)) {
73323 ++ err = -EPERM;
73324 ++ sock_release(newsock);
73325 ++ goto out_put;
73326 ++ }
73327 ++
73328 + /*
73329 + * We don't need try_module_get here, as the listening socket (sock)
73330 + * has the protocol module (sock->ops->owner) held.
73331 +@@ -1495,6 +1542,7 @@ long do_accept(int fd, struct sockaddr _
73332 + err = newfd;
73333 +
73334 + security_socket_post_accept(sock, newsock);
73335 ++ gr_attach_curr_ip(newsock->sk);
73336 +
73337 + out_put:
73338 + fput_light(sock->file, fput_needed);
73339 +@@ -1589,6 +1637,7 @@ asmlinkage long sys_connect(int fd, stru
73340 + int addrlen)
73341 + {
73342 + struct socket *sock;
73343 ++ struct sockaddr *sck;
73344 + struct sockaddr_storage address;
73345 + int err, fput_needed;
73346 +
73347 +@@ -1599,6 +1648,13 @@ asmlinkage long sys_connect(int fd, stru
73348 + if (err < 0)
73349 + goto out_put;
73350 +
73351 ++ sck = (struct sockaddr *)&address;
73352 ++ if (!gr_search_connect(sock, (struct sockaddr_in *)sck) ||
73353 ++ gr_handle_sock_client(sck)) {
73354 ++ err = -EACCES;
73355 ++ goto out_put;
73356 ++ }
73357 ++
73358 + err =
73359 + security_socket_connect(sock, (struct sockaddr *)&address, addrlen);
73360 + if (err)
73361 +@@ -1866,6 +1922,7 @@ asmlinkage long sys_shutdown(int fd, int
73362 + err = sock->ops->shutdown(sock, how);
73363 + fput_light(sock->file, fput_needed);
73364 + }
73365 ++
73366 + return err;
73367 + }
73368 +
73369 +diff -urNp linux-2.6.27.7/net/unix/af_unix.c linux-2.6.27.7/net/unix/af_unix.c
73370 +--- linux-2.6.27.7/net/unix/af_unix.c 2008-11-17 20:03:30.000000000 -0500
73371 ++++ linux-2.6.27.7/net/unix/af_unix.c 2008-11-18 03:38:45.000000000 -0500
73372 +@@ -114,6 +114,7 @@
73373 + #include <linux/mount.h>
73374 + #include <net/checksum.h>
73375 + #include <linux/security.h>
73376 ++#include <linux/grsecurity.h>
73377 +
73378 + static struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
73379 + static DEFINE_SPINLOCK(unix_table_lock);
73380 +@@ -725,6 +726,12 @@ static struct sock *unix_find_other(stru
73381 + err = -ECONNREFUSED;
73382 + if (!S_ISSOCK(nd.path.dentry->d_inode->i_mode))
73383 + goto put_fail;
73384 ++
73385 ++ if (!gr_acl_handle_unix(nd.path.dentry, nd.path.mnt)) {
73386 ++ err = -EACCES;
73387 ++ goto put_fail;
73388 ++ }
73389 ++
73390 + u = unix_find_socket_byinode(net, nd.path.dentry->d_inode);
73391 + if (!u)
73392 + goto put_fail;
73393 +@@ -745,6 +752,13 @@ static struct sock *unix_find_other(stru
73394 + if (u) {
73395 + struct dentry *dentry;
73396 + dentry = unix_sk(u)->dentry;
73397 ++
73398 ++ if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
73399 ++ err = -EPERM;
73400 ++ sock_put(u);
73401 ++ goto fail;
73402 ++ }
73403 ++
73404 + if (dentry)
73405 + touch_atime(unix_sk(u)->mnt, dentry);
73406 + } else
73407 +@@ -827,10 +841,20 @@ static int unix_bind(struct socket *sock
73408 + err = mnt_want_write(nd.path.mnt);
73409 + if (err)
73410 + goto out_mknod_dput;
73411 ++
73412 ++ if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
73413 ++ err = -EACCES;
73414 ++ mnt_drop_write(nd.path.mnt);
73415 ++ goto out_mknod_dput;
73416 ++ }
73417 ++
73418 + err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0);
73419 + mnt_drop_write(nd.path.mnt);
73420 + if (err)
73421 + goto out_mknod_dput;
73422 ++
73423 ++ gr_handle_create(dentry, nd.path.mnt);
73424 ++
73425 + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
73426 + dput(nd.path.dentry);
73427 + nd.path.dentry = dentry;
73428 +@@ -848,6 +872,10 @@ static int unix_bind(struct socket *sock
73429 + goto out_unlock;
73430 + }
73431 +
73432 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
73433 ++ sk->sk_peercred.pid = current->pid;
73434 ++#endif
73435 ++
73436 + list = &unix_socket_table[addr->hash];
73437 + } else {
73438 + list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
73439 +diff -urNp linux-2.6.27.7/scripts/pnmtologo.c linux-2.6.27.7/scripts/pnmtologo.c
73440 +--- linux-2.6.27.7/scripts/pnmtologo.c 2008-11-07 12:55:34.000000000 -0500
73441 ++++ linux-2.6.27.7/scripts/pnmtologo.c 2008-11-18 03:38:45.000000000 -0500
73442 +@@ -237,14 +237,14 @@ static void write_header(void)
73443 + fprintf(out, " * Linux logo %s\n", logoname);
73444 + fputs(" */\n\n", out);
73445 + fputs("#include <linux/linux_logo.h>\n\n", out);
73446 +- fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
73447 ++ fprintf(out, "static unsigned char %s_data[] = {\n",
73448 + logoname);
73449 + }
73450 +
73451 + static void write_footer(void)
73452 + {
73453 + fputs("\n};\n\n", out);
73454 +- fprintf(out, "struct linux_logo %s __initdata = {\n", logoname);
73455 ++ fprintf(out, "struct linux_logo %s = {\n", logoname);
73456 + fprintf(out, " .type\t= %s,\n", logo_types[logo_type]);
73457 + fprintf(out, " .width\t= %d,\n", logo_width);
73458 + fprintf(out, " .height\t= %d,\n", logo_height);
73459 +@@ -374,7 +374,7 @@ static void write_logo_clut224(void)
73460 + fputs("\n};\n\n", out);
73461 +
73462 + /* write logo clut */
73463 +- fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
73464 ++ fprintf(out, "static unsigned char %s_clut[] = {\n",
73465 + logoname);
73466 + write_hex_cnt = 0;
73467 + for (i = 0; i < logo_clutsize; i++) {
73468 +diff -urNp linux-2.6.27.7/security/commoncap.c linux-2.6.27.7/security/commoncap.c
73469 +--- linux-2.6.27.7/security/commoncap.c 2008-11-07 12:55:34.000000000 -0500
73470 ++++ linux-2.6.27.7/security/commoncap.c 2008-11-18 03:38:45.000000000 -0500
73471 +@@ -26,10 +26,13 @@
73472 + #include <linux/sched.h>
73473 + #include <linux/prctl.h>
73474 + #include <linux/securebits.h>
73475 ++#include <linux/grsecurity.h>
73476 ++
73477 ++extern kernel_cap_t gr_cap_rtnetlink(struct sock *sk);
73478 +
73479 + int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
73480 + {
73481 +- NETLINK_CB(skb).eff_cap = current->cap_effective;
73482 ++ NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink(sk);
73483 + return 0;
73484 + }
73485 +
73486 +@@ -51,7 +54,15 @@ EXPORT_SYMBOL(cap_netlink_recv);
73487 + int cap_capable (struct task_struct *tsk, int cap)
73488 + {
73489 + /* Derived from include/linux/sched.h:capable. */
73490 +- if (cap_raised(tsk->cap_effective, cap))
73491 ++ if (cap_raised (tsk->cap_effective, cap))
73492 ++ return 0;
73493 ++ return -EPERM;
73494 ++}
73495 ++
73496 ++int cap_capable_nolog (struct task_struct *tsk, int cap)
73497 ++{
73498 ++ /* tsk = current for all callers */
73499 ++ if (cap_raised(tsk->cap_effective, cap) && gr_is_capable_nolog(cap))
73500 + return 0;
73501 + return -EPERM;
73502 + }
73503 +@@ -379,8 +390,11 @@ void cap_bprm_apply_creds (struct linux_
73504 + }
73505 + }
73506 +
73507 +- current->suid = current->euid = current->fsuid = bprm->e_uid;
73508 +- current->sgid = current->egid = current->fsgid = bprm->e_gid;
73509 ++ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
73510 ++ current->suid = current->euid = current->fsuid = bprm->e_uid;
73511 ++
73512 ++ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
73513 ++ current->sgid = current->egid = current->fsgid = bprm->e_gid;
73514 +
73515 + /* For init, we want to retain the capabilities set
73516 + * in the init_task struct. Thus we skip the usual
73517 +@@ -393,6 +407,8 @@ void cap_bprm_apply_creds (struct linux_
73518 + cap_clear(current->cap_effective);
73519 + }
73520 +
73521 ++ gr_handle_chroot_caps(current);
73522 ++
73523 + /* AUD: Audit candidate if current->cap_effective is set */
73524 +
73525 + current->securebits &= ~issecure_mask(SECURE_KEEP_CAPS);
73526 +@@ -705,7 +721,7 @@ int cap_vm_enough_memory(struct mm_struc
73527 + {
73528 + int cap_sys_admin = 0;
73529 +
73530 +- if (cap_capable(current, CAP_SYS_ADMIN) == 0)
73531 ++ if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
73532 + cap_sys_admin = 1;
73533 + return __vm_enough_memory(mm, pages, cap_sys_admin);
73534 + }
73535 +diff -urNp linux-2.6.27.7/security/Kconfig linux-2.6.27.7/security/Kconfig
73536 +--- linux-2.6.27.7/security/Kconfig 2008-11-07 12:55:34.000000000 -0500
73537 ++++ linux-2.6.27.7/security/Kconfig 2008-11-18 03:38:45.000000000 -0500
73538 +@@ -4,6 +4,447 @@
73539 +
73540 + menu "Security options"
73541 +
73542 ++source grsecurity/Kconfig
73543 ++
73544 ++menu "PaX"
73545 ++
73546 ++config PAX
73547 ++ bool "Enable various PaX features"
73548 ++ depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86)
73549 ++ help
73550 ++ This allows you to enable various PaX features. PaX adds
73551 ++ intrusion prevention mechanisms to the kernel that reduce
73552 ++ the risks posed by exploitable memory corruption bugs.
73553 ++
73554 ++menu "PaX Control"
73555 ++ depends on PAX
73556 ++
73557 ++config PAX_SOFTMODE
73558 ++ bool 'Support soft mode'
73559 ++ help
73560 ++ Enabling this option will allow you to run PaX in soft mode, that
73561 ++ is, PaX features will not be enforced by default, only on executables
73562 ++ marked explicitly. You must also enable PT_PAX_FLAGS support as it
73563 ++ is the only way to mark executables for soft mode use.
73564 ++
73565 ++ Soft mode can be activated by using the "pax_softmode=1" kernel command
73566 ++ line option on boot. Furthermore you can control various PaX features
73567 ++ at runtime via the entries in /proc/sys/kernel/pax.
73568 ++
73569 ++config PAX_EI_PAX
73570 ++ bool 'Use legacy ELF header marking'
73571 ++ help
73572 ++ Enabling this option will allow you to control PaX features on
73573 ++ a per executable basis via the 'chpax' utility available at
73574 ++ http://pax.grsecurity.net/. The control flags will be read from
73575 ++ an otherwise reserved part of the ELF header. This marking has
73576 ++ numerous drawbacks (no support for soft-mode, toolchain does not
73577 ++ know about the non-standard use of the ELF header) therefore it
73578 ++ has been deprecated in favour of PT_PAX_FLAGS support.
73579 ++
73580 ++ If you have applications not marked by the PT_PAX_FLAGS ELF
73581 ++ program header then you MUST enable this option otherwise they
73582 ++ will not get any protection.
73583 ++
73584 ++ Note that if you enable PT_PAX_FLAGS marking support as well,
73585 ++ the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
73586 ++
73587 ++config PAX_PT_PAX_FLAGS
73588 ++ bool 'Use ELF program header marking'
73589 ++ help
73590 ++ Enabling this option will allow you to control PaX features on
73591 ++ a per executable basis via the 'paxctl' utility available at
73592 ++ http://pax.grsecurity.net/. The control flags will be read from
73593 ++ a PaX specific ELF program header (PT_PAX_FLAGS). This marking
73594 ++ has the benefits of supporting both soft mode and being fully
73595 ++ integrated into the toolchain (the binutils patch is available
73596 ++ from http://pax.grsecurity.net).
73597 ++
73598 ++ If you have applications not marked by the PT_PAX_FLAGS ELF
73599 ++ program header then you MUST enable the EI_PAX marking support
73600 ++ otherwise they will not get any protection.
73601 ++
73602 ++ Note that if you enable the legacy EI_PAX marking support as well,
73603 ++ the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
73604 ++
73605 ++choice
73606 ++ prompt 'MAC system integration'
73607 ++ default PAX_HAVE_ACL_FLAGS
73608 ++ help
73609 ++ Mandatory Access Control systems have the option of controlling
73610 ++ PaX flags on a per executable basis, choose the method supported
73611 ++ by your particular system.
73612 ++
73613 ++ - "none": if your MAC system does not interact with PaX,
73614 ++ - "direct": if your MAC system defines pax_set_initial_flags() itself,
73615 ++ - "hook": if your MAC system uses the pax_set_initial_flags_func callback.
73616 ++
73617 ++ NOTE: this option is for developers/integrators only.
73618 ++
73619 ++ config PAX_NO_ACL_FLAGS
73620 ++ bool 'none'
73621 ++
73622 ++ config PAX_HAVE_ACL_FLAGS
73623 ++ bool 'direct'
73624 ++
73625 ++ config PAX_HOOK_ACL_FLAGS
73626 ++ bool 'hook'
73627 ++endchoice
73628 ++
73629 ++endmenu
73630 ++
73631 ++menu "Non-executable pages"
73632 ++ depends on PAX
73633 ++
73634 ++config PAX_NOEXEC
73635 ++ bool "Enforce non-executable pages"
73636 ++ 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)
73637 ++ help
73638 ++ By design some architectures do not allow for protecting memory
73639 ++ pages against execution or even if they do, Linux does not make
73640 ++ use of this feature. In practice this means that if a page is
73641 ++ readable (such as the stack or heap) it is also executable.
73642 ++
73643 ++ There is a well known exploit technique that makes use of this
73644 ++ fact and a common programming mistake where an attacker can
73645 ++ introduce code of his choice somewhere in the attacked program's
73646 ++ memory (typically the stack or the heap) and then execute it.
73647 ++
73648 ++ If the attacked program was running with different (typically
73649 ++ higher) privileges than that of the attacker, then he can elevate
73650 ++ his own privilege level (e.g. get a root shell, write to files for
73651 ++ which he does not have write access to, etc).
73652 ++
73653 ++ Enabling this option will let you choose from various features
73654 ++ that prevent the injection and execution of 'foreign' code in
73655 ++ a program.
73656 ++
73657 ++ This will also break programs that rely on the old behaviour and
73658 ++ expect that dynamically allocated memory via the malloc() family
73659 ++ of functions is executable (which it is not). Notable examples
73660 ++ are the XFree86 4.x server, the java runtime and wine.
73661 ++
73662 ++config PAX_PAGEEXEC
73663 ++ bool "Paging based non-executable pages"
73664 ++ 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)
73665 ++ help
73666 ++ This implementation is based on the paging feature of the CPU.
73667 ++ On i386 without hardware non-executable bit support there is a
73668 ++ variable but usually low performance impact, however on Intel's
73669 ++ P4 core based CPUs it is very high so you should not enable this
73670 ++ for kernels meant to be used on such CPUs.
73671 ++
73672 ++ On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386
73673 ++ with hardware non-executable bit support there is no performance
73674 ++ impact, on ppc the impact is negligible.
73675 ++
73676 ++ Note that several architectures require various emulations due to
73677 ++ badly designed userland ABIs, this will cause a performance impact
73678 ++ but will disappear as soon as userland is fixed (e.g., ppc users
73679 ++ can make use of the secure-plt feature found in binutils).
73680 ++
73681 ++config PAX_SEGMEXEC
73682 ++ bool "Segmentation based non-executable pages"
73683 ++ depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32
73684 ++ help
73685 ++ This implementation is based on the segmentation feature of the
73686 ++ CPU and has a very small performance impact, however applications
73687 ++ will be limited to a 1.5 GB address space instead of the normal
73688 ++ 3 GB.
73689 ++
73690 ++config PAX_EMUTRAMP
73691 ++ bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86)
73692 ++ default y if PARISC || PPC32
73693 ++ help
73694 ++ There are some programs and libraries that for one reason or
73695 ++ another attempt to execute special small code snippets from
73696 ++ non-executable memory pages. Most notable examples are the
73697 ++ signal handler return code generated by the kernel itself and
73698 ++ the GCC trampolines.
73699 ++
73700 ++ If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
73701 ++ such programs will no longer work under your kernel.
73702 ++
73703 ++ As a remedy you can say Y here and use the 'chpax' or 'paxctl'
73704 ++ utilities to enable trampoline emulation for the affected programs
73705 ++ yet still have the protection provided by the non-executable pages.
73706 ++
73707 ++ On parisc and ppc you MUST enable this option and EMUSIGRT as
73708 ++ well, otherwise your system will not even boot.
73709 ++
73710 ++ Alternatively you can say N here and use the 'chpax' or 'paxctl'
73711 ++ utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
73712 ++ for the affected files.
73713 ++
73714 ++ NOTE: enabling this feature *may* open up a loophole in the
73715 ++ protection provided by non-executable pages that an attacker
73716 ++ could abuse. Therefore the best solution is to not have any
73717 ++ files on your system that would require this option. This can
73718 ++ be achieved by not using libc5 (which relies on the kernel
73719 ++ signal handler return code) and not using or rewriting programs
73720 ++ that make use of the nested function implementation of GCC.
73721 ++ Skilled users can just fix GCC itself so that it implements
73722 ++ nested function calls in a way that does not interfere with PaX.
73723 ++
73724 ++config PAX_EMUSIGRT
73725 ++ bool "Automatically emulate sigreturn trampolines"
73726 ++ depends on PAX_EMUTRAMP && (PARISC || PPC32)
73727 ++ default y
73728 ++ help
73729 ++ Enabling this option will have the kernel automatically detect
73730 ++ and emulate signal return trampolines executing on the stack
73731 ++ that would otherwise lead to task termination.
73732 ++
73733 ++ This solution is intended as a temporary one for users with
73734 ++ legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
73735 ++ Modula-3 runtime, etc) or executables linked to such, basically
73736 ++ everything that does not specify its own SA_RESTORER function in
73737 ++ normal executable memory like glibc 2.1+ does.
73738 ++
73739 ++ On parisc and ppc you MUST enable this option, otherwise your
73740 ++ system will not even boot.
73741 ++
73742 ++ NOTE: this feature cannot be disabled on a per executable basis
73743 ++ and since it *does* open up a loophole in the protection provided
73744 ++ by non-executable pages, the best solution is to not have any
73745 ++ files on your system that would require this option.
73746 ++
73747 ++config PAX_MPROTECT
73748 ++ bool "Restrict mprotect()"
73749 ++ depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
73750 ++ help
73751 ++ Enabling this option will prevent programs from
73752 ++ - changing the executable status of memory pages that were
73753 ++ not originally created as executable,
73754 ++ - making read-only executable pages writable again,
73755 ++ - creating executable pages from anonymous memory.
73756 ++
73757 ++ You should say Y here to complete the protection provided by
73758 ++ the enforcement of non-executable pages.
73759 ++
73760 ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
73761 ++ this feature on a per file basis.
73762 ++
73763 ++config PAX_NOELFRELOCS
73764 ++ bool "Disallow ELF text relocations"
73765 ++ depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86)
73766 ++ help
73767 ++ Non-executable pages and mprotect() restrictions are effective
73768 ++ in preventing the introduction of new executable code into an
73769 ++ attacked task's address space. There remain only two venues
73770 ++ for this kind of attack: if the attacker can execute already
73771 ++ existing code in the attacked task then he can either have it
73772 ++ create and mmap() a file containing his code or have it mmap()
73773 ++ an already existing ELF library that does not have position
73774 ++ independent code in it and use mprotect() on it to make it
73775 ++ writable and copy his code there. While protecting against
73776 ++ the former approach is beyond PaX, the latter can be prevented
73777 ++ by having only PIC ELF libraries on one's system (which do not
73778 ++ need to relocate their code). If you are sure this is your case,
73779 ++ then enable this option otherwise be careful as you may not even
73780 ++ be able to boot or log on your system (for example, some PAM
73781 ++ modules are erroneously compiled as non-PIC by default).
73782 ++
73783 ++ NOTE: if you are using dynamic ELF executables (as suggested
73784 ++ when using ASLR) then you must have made sure that you linked
73785 ++ your files using the PIC version of crt1 (the et_dyn.tar.gz package
73786 ++ referenced there has already been updated to support this).
73787 ++
73788 ++config PAX_ETEXECRELOCS
73789 ++ bool "Allow ELF ET_EXEC text relocations"
73790 ++ depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
73791 ++ default y
73792 ++ help
73793 ++ On some architectures there are incorrectly created applications
73794 ++ that require text relocations and would not work without enabling
73795 ++ this option. If you are an alpha, ia64 or parisc user, you should
73796 ++ enable this option and disable it once you have made sure that
73797 ++ none of your applications need it.
73798 ++
73799 ++config PAX_EMUPLT
73800 ++ bool "Automatically emulate ELF PLT"
73801 ++ depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
73802 ++ default y
73803 ++ help
73804 ++ Enabling this option will have the kernel automatically detect
73805 ++ and emulate the Procedure Linkage Table entries in ELF files.
73806 ++ On some architectures such entries are in writable memory, and
73807 ++ become non-executable leading to task termination. Therefore
73808 ++ it is mandatory that you enable this option on alpha, parisc,
73809 ++ ppc (if secure-plt is not used throughout in userland), sparc
73810 ++ and sparc64, otherwise your system would not even boot.
73811 ++
73812 ++ NOTE: this feature *does* open up a loophole in the protection
73813 ++ provided by the non-executable pages, therefore the proper
73814 ++ solution is to modify the toolchain to produce a PLT that does
73815 ++ not need to be writable.
73816 ++
73817 ++config PAX_DLRESOLVE
73818 ++ bool
73819 ++ depends on PAX_EMUPLT && (SPARC32 || SPARC64)
73820 ++ default y
73821 ++
73822 ++config PAX_SYSCALL
73823 ++ bool
73824 ++ depends on PAX_PAGEEXEC && PPC32
73825 ++ default y
73826 ++
73827 ++config PAX_KERNEXEC
73828 ++ bool "Enforce non-executable kernel pages"
73829 ++ depends on PAX_NOEXEC && X86 && !EFI && !COMPAT_VDSO && (!X86_32 || X86_WP_WORKS_OK) && !PARAVIRT
73830 ++ help
73831 ++ This is the kernel land equivalent of PAGEEXEC and MPROTECT,
73832 ++ that is, enabling this option will make it harder to inject
73833 ++ and execute 'foreign' code in kernel memory itself.
73834 ++
73835 ++endmenu
73836 ++
73837 ++menu "Address Space Layout Randomization"
73838 ++ depends on PAX
73839 ++
73840 ++config PAX_ASLR
73841 ++ bool "Address Space Layout Randomization"
73842 ++ depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
73843 ++ help
73844 ++ Many if not most exploit techniques rely on the knowledge of
73845 ++ certain addresses in the attacked program. The following options
73846 ++ will allow the kernel to apply a certain amount of randomization
73847 ++ to specific parts of the program thereby forcing an attacker to
73848 ++ guess them in most cases. Any failed guess will most likely crash
73849 ++ the attacked program which allows the kernel to detect such attempts
73850 ++ and react on them. PaX itself provides no reaction mechanisms,
73851 ++ instead it is strongly encouraged that you make use of Nergal's
73852 ++ segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
73853 ++ (http://www.grsecurity.net/) built-in crash detection features or
73854 ++ develop one yourself.
73855 ++
73856 ++ By saying Y here you can choose to randomize the following areas:
73857 ++ - top of the task's kernel stack
73858 ++ - top of the task's userland stack
73859 ++ - base address for mmap() requests that do not specify one
73860 ++ (this includes all libraries)
73861 ++ - base address of the main executable
73862 ++
73863 ++ It is strongly recommended to say Y here as address space layout
73864 ++ randomization has negligible impact on performance yet it provides
73865 ++ a very effective protection.
73866 ++
73867 ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
73868 ++ this feature on a per file basis.
73869 ++
73870 ++config PAX_RANDKSTACK
73871 ++ bool "Randomize kernel stack base"
73872 ++ depends on PAX_ASLR && X86_TSC && X86_32
73873 ++ help
73874 ++ By saying Y here the kernel will randomize every task's kernel
73875 ++ stack on every system call. This will not only force an attacker
73876 ++ to guess it but also prevent him from making use of possible
73877 ++ leaked information about it.
73878 ++
73879 ++ Since the kernel stack is a rather scarce resource, randomization
73880 ++ may cause unexpected stack overflows, therefore you should very
73881 ++ carefully test your system. Note that once enabled in the kernel
73882 ++ configuration, this feature cannot be disabled on a per file basis.
73883 ++
73884 ++config PAX_RANDUSTACK
73885 ++ bool "Randomize user stack base"
73886 ++ depends on PAX_ASLR
73887 ++ help
73888 ++ By saying Y here the kernel will randomize every task's userland
73889 ++ stack. The randomization is done in two steps where the second
73890 ++ one may apply a big amount of shift to the top of the stack and
73891 ++ cause problems for programs that want to use lots of memory (more
73892 ++ than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
73893 ++ For this reason the second step can be controlled by 'chpax' or
73894 ++ 'paxctl' on a per file basis.
73895 ++
73896 ++config PAX_RANDMMAP
73897 ++ bool "Randomize mmap() base"
73898 ++ depends on PAX_ASLR
73899 ++ help
73900 ++ By saying Y here the kernel will use a randomized base address for
73901 ++ mmap() requests that do not specify one themselves. As a result
73902 ++ all dynamically loaded libraries will appear at random addresses
73903 ++ and therefore be harder to exploit by a technique where an attacker
73904 ++ attempts to execute library code for his purposes (e.g. spawn a
73905 ++ shell from an exploited program that is running at an elevated
73906 ++ privilege level).
73907 ++
73908 ++ Furthermore, if a program is relinked as a dynamic ELF file, its
73909 ++ base address will be randomized as well, completing the full
73910 ++ randomization of the address space layout. Attacking such programs
73911 ++ becomes a guess game. You can find an example of doing this at
73912 ++ http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
73913 ++ http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
73914 ++
73915 ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
73916 ++ feature on a per file basis.
73917 ++
73918 ++endmenu
73919 ++
73920 ++menu "Miscellaneous hardening features"
73921 ++
73922 ++config PAX_MEMORY_SANITIZE
73923 ++ bool "Sanitize all freed memory"
73924 ++ help
73925 ++ By saying Y here the kernel will erase memory pages as soon as they
73926 ++ are freed. This in turn reduces the lifetime of data stored in the
73927 ++ pages, making it less likely that sensitive information such as
73928 ++ passwords, cryptographic secrets, etc stay in memory for too long.
73929 ++
73930 ++ This is especially useful for programs whose runtime is short, long
73931 ++ lived processes and the kernel itself benefit from this as long as
73932 ++ they operate on whole memory pages and ensure timely freeing of pages
73933 ++ that may hold sensitive information.
73934 ++
73935 ++ The tradeoff is performance impact, on a single CPU system kernel
73936 ++ compilation sees a 3% slowdown, other systems and workloads may vary
73937 ++ and you are advised to test this feature on your expected workload
73938 ++ before deploying it.
73939 ++
73940 ++ Note that this feature does not protect data stored in live pages,
73941 ++ e.g., process memory swapped to disk may stay there for a long time.
73942 ++
73943 ++config PAX_MEMORY_UDEREF
73944 ++ bool "Prevent invalid userland pointer dereference"
73945 ++ depends on X86_32 && !COMPAT_VDSO && !UML_X86
73946 ++ help
73947 ++ By saying Y here the kernel will be prevented from dereferencing
73948 ++ userland pointers in contexts where the kernel expects only kernel
73949 ++ pointers. This is both a useful runtime debugging feature and a
73950 ++ security measure that prevents exploiting a class of kernel bugs.
73951 ++
73952 ++ The tradeoff is that some virtualization solutions may experience
73953 ++ a huge slowdown and therefore you should not enable this feature
73954 ++ for kernels meant to run in such environments. Whether a given VM
73955 ++ solution is affected or not is best determined by simply trying it
73956 ++ out, the performance impact will be obvious right on boot as this
73957 ++ mechanism engages from very early on. A good rule of thumb is that
73958 ++ VMs running on CPUs without hardware virtualization support (i.e.,
73959 ++ the majority of IA-32 CPUs) will likely experience the slowdown.
73960 ++
73961 ++config PAX_REFCOUNT
73962 ++ bool "Prevent various kernel object reference counter overflows"
73963 ++ depends on X86
73964 ++ help
73965 ++ By saying Y here the kernel will detect and prevent overflowing
73966 ++ various (but not all) kinds of object reference counters. Such
73967 ++ overflows can normally occur due to bugs only and are often, if
73968 ++ not always, exploitable.
73969 ++
73970 ++ The tradeoff is that data structures protected by an oveflowed
73971 ++ refcount will never be freed and therefore will leak memory. Note
73972 ++ that this leak also happens even without this protection but in
73973 ++ that case the overflow can eventually trigger the freeing of the
73974 ++ data structure while it is still being used elsewhere, resulting
73975 ++ in the exploitable situation that this feature prevents.
73976 ++
73977 ++ Since this has a negligible performance impact, you should enable
73978 ++ this feature.
73979 ++endmenu
73980 ++
73981 ++endmenu
73982 ++
73983 + config KEYS
73984 + bool "Enable access key retention support"
73985 + help
73986 +diff -urNp linux-2.6.27.7/sound/core/oss/pcm_oss.c linux-2.6.27.7/sound/core/oss/pcm_oss.c
73987 +--- linux-2.6.27.7/sound/core/oss/pcm_oss.c 2008-11-07 12:55:34.000000000 -0500
73988 ++++ linux-2.6.27.7/sound/core/oss/pcm_oss.c 2008-11-18 03:38:45.000000000 -0500
73989 +@@ -2911,8 +2911,8 @@ static void snd_pcm_oss_proc_done(struct
73990 + }
73991 + }
73992 + #else /* !CONFIG_SND_VERBOSE_PROCFS */
73993 +-#define snd_pcm_oss_proc_init(pcm)
73994 +-#define snd_pcm_oss_proc_done(pcm)
73995 ++#define snd_pcm_oss_proc_init(pcm) do {} while (0)
73996 ++#define snd_pcm_oss_proc_done(pcm) do {} while (0)
73997 + #endif /* CONFIG_SND_VERBOSE_PROCFS */
73998 +
73999 + /*
74000 +diff -urNp linux-2.6.27.7/sound/core/seq/seq_lock.h linux-2.6.27.7/sound/core/seq/seq_lock.h
74001 +--- linux-2.6.27.7/sound/core/seq/seq_lock.h 2008-11-07 12:55:34.000000000 -0500
74002 ++++ linux-2.6.27.7/sound/core/seq/seq_lock.h 2008-11-18 03:38:45.000000000 -0500
74003 +@@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo
74004 + #else /* SMP || CONFIG_SND_DEBUG */
74005 +
74006 + typedef spinlock_t snd_use_lock_t; /* dummy */
74007 +-#define snd_use_lock_init(lockp) /**/
74008 +-#define snd_use_lock_use(lockp) /**/
74009 +-#define snd_use_lock_free(lockp) /**/
74010 +-#define snd_use_lock_sync(lockp) /**/
74011 ++#define snd_use_lock_init(lockp) do {} while (0)
74012 ++#define snd_use_lock_use(lockp) do {} while (0)
74013 ++#define snd_use_lock_free(lockp) do {} while (0)
74014 ++#define snd_use_lock_sync(lockp) do {} while (0)
74015 +
74016 + #endif /* SMP || CONFIG_SND_DEBUG */
74017 +
74018 +diff -urNp linux-2.6.27.7/sound/pci/ac97/ac97_patch.c linux-2.6.27.7/sound/pci/ac97/ac97_patch.c
74019 +--- linux-2.6.27.7/sound/pci/ac97/ac97_patch.c 2008-11-07 12:55:34.000000000 -0500
74020 ++++ linux-2.6.27.7/sound/pci/ac97/ac97_patch.c 2008-11-18 03:38:45.000000000 -0500
74021 +@@ -1498,7 +1498,7 @@ static const struct snd_ac97_res_table a
74022 + { AC97_VIDEO, 0x9f1f },
74023 + { AC97_AUX, 0x9f1f },
74024 + { AC97_PCM, 0x9f1f },
74025 +- { } /* terminator */
74026 ++ { 0, 0 } /* terminator */
74027 + };
74028 +
74029 + static int patch_ad1819(struct snd_ac97 * ac97)
74030 +@@ -3668,7 +3668,7 @@ static struct snd_ac97_res_table lm4550_
74031 + { AC97_AUX, 0x1f1f },
74032 + { AC97_PCM, 0x1f1f },
74033 + { AC97_REC_GAIN, 0x0f0f },
74034 +- { } /* terminator */
74035 ++ { 0, 0 } /* terminator */
74036 + };
74037 +
74038 + static int patch_lm4550(struct snd_ac97 *ac97)
74039 +diff -urNp linux-2.6.27.7/sound/pci/ens1370.c linux-2.6.27.7/sound/pci/ens1370.c
74040 +--- linux-2.6.27.7/sound/pci/ens1370.c 2008-11-07 12:55:34.000000000 -0500
74041 ++++ linux-2.6.27.7/sound/pci/ens1370.c 2008-11-18 03:38:45.000000000 -0500
74042 +@@ -452,7 +452,7 @@ static struct pci_device_id snd_audiopci
74043 + { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1373 - CT5880 */
74044 + { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ectiva EV1938 */
74045 + #endif
74046 +- { 0, }
74047 ++ { 0, 0, 0, 0, 0, 0, 0 }
74048 + };
74049 +
74050 + MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
74051 +diff -urNp linux-2.6.27.7/sound/pci/intel8x0.c linux-2.6.27.7/sound/pci/intel8x0.c
74052 +--- linux-2.6.27.7/sound/pci/intel8x0.c 2008-11-07 12:55:34.000000000 -0500
74053 ++++ linux-2.6.27.7/sound/pci/intel8x0.c 2008-11-18 03:38:45.000000000 -0500
74054 +@@ -437,7 +437,7 @@ static struct pci_device_id snd_intel8x0
74055 + { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
74056 + { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
74057 + { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
74058 +- { 0, }
74059 ++ { 0, 0, 0, 0, 0, 0, 0 }
74060 + };
74061 +
74062 + MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
74063 +@@ -2076,7 +2076,7 @@ static struct ac97_quirk ac97_quirks[] _
74064 + .type = AC97_TUNE_HP_ONLY
74065 + },
74066 + #endif
74067 +- { } /* terminator */
74068 ++ { 0, 0, 0, 0, NULL, 0 } /* terminator */
74069 + };
74070 +
74071 + static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
74072 +diff -urNp linux-2.6.27.7/sound/pci/intel8x0m.c linux-2.6.27.7/sound/pci/intel8x0m.c
74073 +--- linux-2.6.27.7/sound/pci/intel8x0m.c 2008-11-07 12:55:34.000000000 -0500
74074 ++++ linux-2.6.27.7/sound/pci/intel8x0m.c 2008-11-18 03:38:45.000000000 -0500
74075 +@@ -239,7 +239,7 @@ static struct pci_device_id snd_intel8x0
74076 + { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
74077 + { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
74078 + #endif
74079 +- { 0, }
74080 ++ { 0, 0, 0, 0, 0, 0, 0 }
74081 + };
74082 +
74083 + MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
74084 +@@ -1257,7 +1257,7 @@ static struct shortname_table {
74085 + { 0x5455, "ALi M5455" },
74086 + { 0x746d, "AMD AMD8111" },
74087 + #endif
74088 +- { 0 },
74089 ++ { 0, NULL },
74090 + };
74091 +
74092 + static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
74093 +diff -urNp linux-2.6.27.7/virt/kvm/kvm_main.c linux-2.6.27.7/virt/kvm/kvm_main.c
74094 +--- linux-2.6.27.7/virt/kvm/kvm_main.c 2008-11-07 12:55:34.000000000 -0500
74095 ++++ linux-2.6.27.7/virt/kvm/kvm_main.c 2008-11-18 03:38:45.000000000 -0500
74096 +@@ -1469,6 +1469,9 @@ static struct miscdevice kvm_dev = {
74097 + KVM_MINOR,
74098 + "kvm",
74099 + &kvm_chardev_ops,
74100 ++ {NULL, NULL},
74101 ++ NULL,
74102 ++ NULL
74103 + };
74104 +
74105 + static void hardware_enable(void *junk)