Gentoo Archives: gentoo-commits

From: "Gordon Malm (gengor)" <gengor@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] linux-patches r1529 - in hardened/2.6/tags: . 2.6.28-7
Date: Sat, 21 Mar 2009 10:59:32
Message-Id: E1Lkyu7-0005Hy-8J@stork.gentoo.org
1 Author: gengor
2 Date: 2009-03-21 10:58:14 +0000 (Sat, 21 Mar 2009)
3 New Revision: 1529
4
5 Added:
6 hardened/2.6/tags/2.6.28-7/
7 hardened/2.6/tags/2.6.28-7/0000_README
8 hardened/2.6/tags/2.6.28-7/4420_grsec-2.1.13-2.6.28.8-200903191958.patch
9 hardened/2.6/tags/2.6.28-7/4421_grsec-remove-localversion-grsec.patch
10 hardened/2.6/tags/2.6.28-7/4422_grsec-mute-warnings.patch
11 hardened/2.6/tags/2.6.28-7/4425_grsec-pax-without-grsec.patch
12 hardened/2.6/tags/2.6.28-7/4430_grsec-kconfig-default-gids.patch
13 hardened/2.6/tags/2.6.28-7/4435_grsec-kconfig-gentoo.patch
14 hardened/2.6/tags/2.6.28-7/4440_selinux-avc_audit-log-curr_ip.patch
15 hardened/2.6/tags/2.6.28-7/4445_disable-compat_vdso.patch
16 hardened/2.6/tags/2.6.28-7/4450_grsec-grkernsec_io-select-rtc-cmos.patch
17 Log:
18 Tag hardened-extras 2.6.28-7 patchset
19
20 Added: hardened/2.6/tags/2.6.28-7/0000_README
21 ===================================================================
22 --- hardened/2.6/tags/2.6.28-7/0000_README (rev 0)
23 +++ hardened/2.6/tags/2.6.28-7/0000_README 2009-03-21 10:58:14 UTC (rev 1529)
24 @@ -0,0 +1,46 @@
25 +README
26 +-----------------------------------------------------------------------------
27 +
28 +Individual Patch Descriptions:
29 +-----------------------------------------------------------------------------
30 +Patch: 4420_grsec-2.1.13-2.6.28.8-200903191958.patch
31 +From: http://www.grsecurity.net
32 +Desc: hardened-sources base patch from upstream grsecurity
33 +
34 +Patch: 4421_grsec-remove-localversion-grsec.patch
35 +From: Kerin Millar <kerframil@×××××.com>
36 +Desc: Removes grsecurity's localversion-grsec file
37 +
38 +Patch: 4422_grsec-mute-warnings.patch
39 +From: Alexander Gabert <gaberta@××××××××.de>
40 + Gordon Malm <gengor@g.o>
41 +Desc: Removes verbose compile warning settings from grsecurity, restores
42 + mainline Linux kernel behavior
43 +
44 +Patch: 4425_grsec-pax-without-grsec.patch
45 +From: Gordon Malm <gengor@g.o>
46 +Desc: Allows PaX features to be selected without enabling GRKERNSEC
47 +
48 +Patch: 4430_grsec-kconfig-default-gids.patch
49 +From: Kerin Millar <kerframil@×××××.com>
50 +Desc: Sets sane(r) default GIDs on various grsecurity group-dependent
51 + features
52 +
53 +Patch: 4435_grsec-kconfig-gentoo.patch
54 +From: Gordon Malm <gengor@g.o>
55 + Kerin Millar <kerframil@×××××.com>
56 +Desc: Adds Hardened Gentoo [server/workstation] security levels, sets
57 + Hardened Gentoo [workstation] as default
58 +
59 +Patch: 4440_selinux-avc_audit-log-curr_ip.patch
60 +From: Gordon Malm <gengor@g.o>
61 +Desc: Configurable option to add src IP address to SELinux log messages
62 +
63 +Patch: 4445_disable-compat_vdso.patch
64 +From: Gordon Malm <gengor@g.o>
65 + Kerin Millar <kerframil@×××××.com>
66 +Desc: Disables VDSO_COMPAT operation completely
67 +
68 +Patch: 4450_grsec-grkernsec_io-select-rtc-cmos.patch
69 +From: Gordon Malm <gengor@g.o>
70 +Desc: Build rtc-cmos driver into the kernel when GRKERNSEC_IO is enabled
71
72 Added: hardened/2.6/tags/2.6.28-7/4420_grsec-2.1.13-2.6.28.8-200903191958.patch
73 ===================================================================
74 --- hardened/2.6/tags/2.6.28-7/4420_grsec-2.1.13-2.6.28.8-200903191958.patch (rev 0)
75 +++ hardened/2.6/tags/2.6.28-7/4420_grsec-2.1.13-2.6.28.8-200903191958.patch 2009-03-21 10:58:14 UTC (rev 1529)
76 @@ -0,0 +1,37186 @@
77 +diff -urNp linux-2.6.28.8/arch/alpha/include/asm/elf.h linux-2.6.28.8/arch/alpha/include/asm/elf.h
78 +--- linux-2.6.28.8/arch/alpha/include/asm/elf.h 2009-02-06 16:47:45.000000000 -0500
79 ++++ linux-2.6.28.8/arch/alpha/include/asm/elf.h 2009-02-21 09:37:48.000000000 -0500
80 +@@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
81 +
82 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
83 +
84 ++#ifdef CONFIG_PAX_ASLR
85 ++#define PAX_ELF_ET_DYN_BASE (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
86 ++
87 ++#define PAX_DELTA_MMAP_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 28)
88 ++#define PAX_DELTA_STACK_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 19)
89 ++#endif
90 ++
91 + /* $0 is set by ld.so to a pointer to a function which might be
92 + registered using atexit. This provides a mean for the dynamic
93 + linker to call DT_FINI functions for shared libraries that have
94 +diff -urNp linux-2.6.28.8/arch/alpha/include/asm/kmap_types.h linux-2.6.28.8/arch/alpha/include/asm/kmap_types.h
95 +--- linux-2.6.28.8/arch/alpha/include/asm/kmap_types.h 2009-02-06 16:47:45.000000000 -0500
96 ++++ linux-2.6.28.8/arch/alpha/include/asm/kmap_types.h 2009-02-21 09:37:48.000000000 -0500
97 +@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
98 + D(10) KM_IRQ1,
99 + D(11) KM_SOFTIRQ0,
100 + D(12) KM_SOFTIRQ1,
101 +-D(13) KM_TYPE_NR
102 ++D(13) KM_CLEARPAGE,
103 ++D(14) KM_TYPE_NR
104 + };
105 +
106 + #undef D
107 +diff -urNp linux-2.6.28.8/arch/alpha/include/asm/pgtable.h linux-2.6.28.8/arch/alpha/include/asm/pgtable.h
108 +--- linux-2.6.28.8/arch/alpha/include/asm/pgtable.h 2009-02-06 16:47:45.000000000 -0500
109 ++++ linux-2.6.28.8/arch/alpha/include/asm/pgtable.h 2009-02-21 09:37:48.000000000 -0500
110 +@@ -101,6 +101,17 @@ struct vm_area_struct;
111 + #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
112 + #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
113 + #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
114 ++
115 ++#ifdef CONFIG_PAX_PAGEEXEC
116 ++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
117 ++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
118 ++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
119 ++#else
120 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
121 ++# define PAGE_COPY_NOEXEC PAGE_COPY
122 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
123 ++#endif
124 ++
125 + #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
126 +
127 + #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
128 +diff -urNp linux-2.6.28.8/arch/alpha/kernel/module.c linux-2.6.28.8/arch/alpha/kernel/module.c
129 +--- linux-2.6.28.8/arch/alpha/kernel/module.c 2009-02-06 16:47:45.000000000 -0500
130 ++++ linux-2.6.28.8/arch/alpha/kernel/module.c 2009-02-21 09:37:48.000000000 -0500
131 +@@ -182,7 +182,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
132 +
133 + /* The small sections were sorted to the end of the segment.
134 + The following should definitely cover them. */
135 +- gp = (u64)me->module_core + me->core_size - 0x8000;
136 ++ gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
137 + got = sechdrs[me->arch.gotsecindex].sh_addr;
138 +
139 + for (i = 0; i < n; i++) {
140 +diff -urNp linux-2.6.28.8/arch/alpha/kernel/osf_sys.c linux-2.6.28.8/arch/alpha/kernel/osf_sys.c
141 +--- linux-2.6.28.8/arch/alpha/kernel/osf_sys.c 2009-02-06 16:47:45.000000000 -0500
142 ++++ linux-2.6.28.8/arch/alpha/kernel/osf_sys.c 2009-02-21 09:37:48.000000000 -0500
143 +@@ -1230,6 +1230,10 @@ arch_get_unmapped_area(struct file *filp
144 + merely specific addresses, but regions of memory -- perhaps
145 + this feature should be incorporated into all ports? */
146 +
147 ++#ifdef CONFIG_PAX_RANDMMAP
148 ++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
149 ++#endif
150 ++
151 + if (addr) {
152 + addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
153 + if (addr != (unsigned long) -ENOMEM)
154 +@@ -1237,8 +1241,8 @@ arch_get_unmapped_area(struct file *filp
155 + }
156 +
157 + /* Next, try allocating at TASK_UNMAPPED_BASE. */
158 +- addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
159 +- len, limit);
160 ++ addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
161 ++
162 + if (addr != (unsigned long) -ENOMEM)
163 + return addr;
164 +
165 +diff -urNp linux-2.6.28.8/arch/alpha/kernel/ptrace.c linux-2.6.28.8/arch/alpha/kernel/ptrace.c
166 +--- linux-2.6.28.8/arch/alpha/kernel/ptrace.c 2009-02-06 16:47:45.000000000 -0500
167 ++++ linux-2.6.28.8/arch/alpha/kernel/ptrace.c 2009-02-21 09:37:48.000000000 -0500
168 +@@ -266,6 +266,9 @@ long arch_ptrace(struct task_struct *chi
169 + size_t copied;
170 + long ret;
171 +
172 ++ if (gr_handle_ptrace(child, request))
173 ++ return -EPERM;
174 ++
175 + switch (request) {
176 + /* When I and D space are separate, these will need to be fixed. */
177 + case PTRACE_PEEKTEXT: /* read word at location addr. */
178 +diff -urNp linux-2.6.28.8/arch/alpha/mm/fault.c linux-2.6.28.8/arch/alpha/mm/fault.c
179 +--- linux-2.6.28.8/arch/alpha/mm/fault.c 2009-02-06 16:47:45.000000000 -0500
180 ++++ linux-2.6.28.8/arch/alpha/mm/fault.c 2009-02-21 09:37:48.000000000 -0500
181 +@@ -54,6 +54,124 @@ __load_new_mm_context(struct mm_struct *
182 + __reload_thread(pcb);
183 + }
184 +
185 ++#ifdef CONFIG_PAX_PAGEEXEC
186 ++/*
187 ++ * PaX: decide what to do with offenders (regs->pc = fault address)
188 ++ *
189 ++ * returns 1 when task should be killed
190 ++ * 2 when patched PLT trampoline was detected
191 ++ * 3 when unpatched PLT trampoline was detected
192 ++ */
193 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
194 ++{
195 ++
196 ++#ifdef CONFIG_PAX_EMUPLT
197 ++ int err;
198 ++
199 ++ do { /* PaX: patched PLT emulation #1 */
200 ++ unsigned int ldah, ldq, jmp;
201 ++
202 ++ err = get_user(ldah, (unsigned int *)regs->pc);
203 ++ err |= get_user(ldq, (unsigned int *)(regs->pc+4));
204 ++ err |= get_user(jmp, (unsigned int *)(regs->pc+8));
205 ++
206 ++ if (err)
207 ++ break;
208 ++
209 ++ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
210 ++ (ldq & 0xFFFF0000U) == 0xA77B0000U &&
211 ++ jmp == 0x6BFB0000U)
212 ++ {
213 ++ unsigned long r27, addr;
214 ++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
215 ++ unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
216 ++
217 ++ addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
218 ++ err = get_user(r27, (unsigned long *)addr);
219 ++ if (err)
220 ++ break;
221 ++
222 ++ regs->r27 = r27;
223 ++ regs->pc = r27;
224 ++ return 2;
225 ++ }
226 ++ } while (0);
227 ++
228 ++ do { /* PaX: patched PLT emulation #2 */
229 ++ unsigned int ldah, lda, br;
230 ++
231 ++ err = get_user(ldah, (unsigned int *)regs->pc);
232 ++ err |= get_user(lda, (unsigned int *)(regs->pc+4));
233 ++ err |= get_user(br, (unsigned int *)(regs->pc+8));
234 ++
235 ++ if (err)
236 ++ break;
237 ++
238 ++ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
239 ++ (lda & 0xFFFF0000U) == 0xA77B0000U &&
240 ++ (br & 0xFFE00000U) == 0xC3E00000U)
241 ++ {
242 ++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
243 ++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
244 ++ unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
245 ++
246 ++ regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
247 ++ regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
248 ++ return 2;
249 ++ }
250 ++ } while (0);
251 ++
252 ++ do { /* PaX: unpatched PLT emulation */
253 ++ unsigned int br;
254 ++
255 ++ err = get_user(br, (unsigned int *)regs->pc);
256 ++
257 ++ if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
258 ++ unsigned int br2, ldq, nop, jmp;
259 ++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
260 ++
261 ++ addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
262 ++ err = get_user(br2, (unsigned int *)addr);
263 ++ err |= get_user(ldq, (unsigned int *)(addr+4));
264 ++ err |= get_user(nop, (unsigned int *)(addr+8));
265 ++ err |= get_user(jmp, (unsigned int *)(addr+12));
266 ++ err |= get_user(resolver, (unsigned long *)(addr+16));
267 ++
268 ++ if (err)
269 ++ break;
270 ++
271 ++ if (br2 == 0xC3600000U &&
272 ++ ldq == 0xA77B000CU &&
273 ++ nop == 0x47FF041FU &&
274 ++ jmp == 0x6B7B0000U)
275 ++ {
276 ++ regs->r28 = regs->pc+4;
277 ++ regs->r27 = addr+16;
278 ++ regs->pc = resolver;
279 ++ return 3;
280 ++ }
281 ++ }
282 ++ } while (0);
283 ++#endif
284 ++
285 ++ return 1;
286 ++}
287 ++
288 ++void pax_report_insns(void *pc, void *sp)
289 ++{
290 ++ unsigned long i;
291 ++
292 ++ printk(KERN_ERR "PAX: bytes at PC: ");
293 ++ for (i = 0; i < 5; i++) {
294 ++ unsigned int c;
295 ++ if (get_user(c, (unsigned int *)pc+i))
296 ++ printk(KERN_CONT "???????? ");
297 ++ else
298 ++ printk(KERN_CONT "%08x ", c);
299 ++ }
300 ++ printk("\n");
301 ++}
302 ++#endif
303 +
304 + /*
305 + * This routine handles page faults. It determines the address,
306 +@@ -131,8 +249,29 @@ do_page_fault(unsigned long address, uns
307 + good_area:
308 + si_code = SEGV_ACCERR;
309 + if (cause < 0) {
310 +- if (!(vma->vm_flags & VM_EXEC))
311 ++ if (!(vma->vm_flags & VM_EXEC)) {
312 ++
313 ++#ifdef CONFIG_PAX_PAGEEXEC
314 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
315 ++ goto bad_area;
316 ++
317 ++ up_read(&mm->mmap_sem);
318 ++ switch (pax_handle_fetch_fault(regs)) {
319 ++
320 ++#ifdef CONFIG_PAX_EMUPLT
321 ++ case 2:
322 ++ case 3:
323 ++ return;
324 ++#endif
325 ++
326 ++ }
327 ++ pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
328 ++ do_group_exit(SIGKILL);
329 ++#else
330 + goto bad_area;
331 ++#endif
332 ++
333 ++ }
334 + } else if (!cause) {
335 + /* Allow reads even for write-only mappings */
336 + if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
337 +diff -urNp linux-2.6.28.8/arch/arm/include/asm/elf.h linux-2.6.28.8/arch/arm/include/asm/elf.h
338 +--- linux-2.6.28.8/arch/arm/include/asm/elf.h 2009-02-06 16:47:45.000000000 -0500
339 ++++ linux-2.6.28.8/arch/arm/include/asm/elf.h 2009-02-21 09:37:48.000000000 -0500
340 +@@ -99,7 +99,14 @@ extern int arm_elf_read_implies_exec(con
341 + the loader. We need to make sure that it is out of the way of the program
342 + that it will "exec", and that there is sufficient room for the brk. */
343 +
344 +-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
345 ++#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
346 ++
347 ++#ifdef CONFIG_PAX_ASLR
348 ++#define PAX_ELF_ET_DYN_BASE 0x00008000UL
349 ++
350 ++#define PAX_DELTA_MMAP_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
351 ++#define PAX_DELTA_STACK_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
352 ++#endif
353 +
354 + /* When the program starts, a1 contains a pointer to a function to be
355 + registered with atexit, as per the SVR4 ABI. A value of 0 means we
356 +diff -urNp linux-2.6.28.8/arch/arm/include/asm/kmap_types.h linux-2.6.28.8/arch/arm/include/asm/kmap_types.h
357 +--- linux-2.6.28.8/arch/arm/include/asm/kmap_types.h 2009-02-06 16:47:45.000000000 -0500
358 ++++ linux-2.6.28.8/arch/arm/include/asm/kmap_types.h 2009-02-21 09:37:48.000000000 -0500
359 +@@ -18,6 +18,7 @@ enum km_type {
360 + KM_IRQ1,
361 + KM_SOFTIRQ0,
362 + KM_SOFTIRQ1,
363 ++ KM_CLEARPAGE,
364 + KM_TYPE_NR
365 + };
366 +
367 +diff -urNp linux-2.6.28.8/arch/arm/mm/mmap.c linux-2.6.28.8/arch/arm/mm/mmap.c
368 +--- linux-2.6.28.8/arch/arm/mm/mmap.c 2009-02-06 16:47:45.000000000 -0500
369 ++++ linux-2.6.28.8/arch/arm/mm/mmap.c 2009-02-21 09:37:48.000000000 -0500
370 +@@ -62,6 +62,10 @@ arch_get_unmapped_area(struct file *filp
371 + if (len > TASK_SIZE)
372 + return -ENOMEM;
373 +
374 ++#ifdef CONFIG_PAX_RANDMMAP
375 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
376 ++#endif
377 ++
378 + if (addr) {
379 + if (do_align)
380 + addr = COLOUR_ALIGN(addr, pgoff);
381 +@@ -74,10 +78,10 @@ arch_get_unmapped_area(struct file *filp
382 + return addr;
383 + }
384 + if (len > mm->cached_hole_size) {
385 +- start_addr = addr = mm->free_area_cache;
386 ++ start_addr = addr = mm->free_area_cache;
387 + } else {
388 +- start_addr = addr = TASK_UNMAPPED_BASE;
389 +- mm->cached_hole_size = 0;
390 ++ start_addr = addr = mm->mmap_base;
391 ++ mm->cached_hole_size = 0;
392 + }
393 +
394 + full_search:
395 +@@ -93,8 +97,8 @@ full_search:
396 + * Start a new search - just in case we missed
397 + * some holes.
398 + */
399 +- if (start_addr != TASK_UNMAPPED_BASE) {
400 +- start_addr = addr = TASK_UNMAPPED_BASE;
401 ++ if (start_addr != mm->mmap_base) {
402 ++ start_addr = addr = mm->mmap_base;
403 + mm->cached_hole_size = 0;
404 + goto full_search;
405 + }
406 +diff -urNp linux-2.6.28.8/arch/avr32/include/asm/elf.h linux-2.6.28.8/arch/avr32/include/asm/elf.h
407 +--- linux-2.6.28.8/arch/avr32/include/asm/elf.h 2009-02-06 16:47:45.000000000 -0500
408 ++++ linux-2.6.28.8/arch/avr32/include/asm/elf.h 2009-02-21 09:37:48.000000000 -0500
409 +@@ -85,8 +85,14 @@ typedef struct user_fpu_struct elf_fpreg
410 + the loader. We need to make sure that it is out of the way of the program
411 + that it will "exec", and that there is sufficient room for the brk. */
412 +
413 +-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
414 ++#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
415 +
416 ++#ifdef CONFIG_PAX_ASLR
417 ++#define PAX_ELF_ET_DYN_BASE 0x00001000UL
418 ++
419 ++#define PAX_DELTA_MMAP_LEN 15
420 ++#define PAX_DELTA_STACK_LEN 15
421 ++#endif
422 +
423 + /* This yields a mask that user programs can use to figure out what
424 + instruction set this CPU supports. This could be done in user space,
425 +diff -urNp linux-2.6.28.8/arch/avr32/include/asm/kmap_types.h linux-2.6.28.8/arch/avr32/include/asm/kmap_types.h
426 +--- linux-2.6.28.8/arch/avr32/include/asm/kmap_types.h 2009-02-06 16:47:45.000000000 -0500
427 ++++ linux-2.6.28.8/arch/avr32/include/asm/kmap_types.h 2009-02-21 09:37:48.000000000 -0500
428 +@@ -22,7 +22,8 @@ D(10) KM_IRQ0,
429 + D(11) KM_IRQ1,
430 + D(12) KM_SOFTIRQ0,
431 + D(13) KM_SOFTIRQ1,
432 +-D(14) KM_TYPE_NR
433 ++D(14) KM_CLEARPAGE,
434 ++D(15) KM_TYPE_NR
435 + };
436 +
437 + #undef D
438 +diff -urNp linux-2.6.28.8/arch/avr32/mm/fault.c linux-2.6.28.8/arch/avr32/mm/fault.c
439 +--- linux-2.6.28.8/arch/avr32/mm/fault.c 2009-02-06 16:47:45.000000000 -0500
440 ++++ linux-2.6.28.8/arch/avr32/mm/fault.c 2009-02-21 09:37:48.000000000 -0500
441 +@@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
442 +
443 + int exception_trace = 1;
444 +
445 ++#ifdef CONFIG_PAX_PAGEEXEC
446 ++void pax_report_insns(void *pc, void *sp)
447 ++{
448 ++ unsigned long i;
449 ++
450 ++ printk(KERN_ERR "PAX: bytes at PC: ");
451 ++ for (i = 0; i < 20; i++) {
452 ++ unsigned char c;
453 ++ if (get_user(c, (unsigned char *)pc+i))
454 ++ printk(KERN_CONT "???????? ");
455 ++ else
456 ++ printk(KERN_CONT "%02x ", c);
457 ++ }
458 ++ printk("\n");
459 ++}
460 ++#endif
461 ++
462 + /*
463 + * This routine handles page faults. It determines the address and the
464 + * problem, and then passes it off to one of the appropriate routines.
465 +@@ -157,6 +174,16 @@ bad_area:
466 + up_read(&mm->mmap_sem);
467 +
468 + if (user_mode(regs)) {
469 ++
470 ++#ifdef CONFIG_PAX_PAGEEXEC
471 ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
472 ++ if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
473 ++ pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
474 ++ do_group_exit(SIGKILL);
475 ++ }
476 ++ }
477 ++#endif
478 ++
479 + if (exception_trace && printk_ratelimit())
480 + printk("%s%s[%d]: segfault at %08lx pc %08lx "
481 + "sp %08lx ecr %lu\n",
482 +diff -urNp linux-2.6.28.8/arch/blackfin/include/asm/kmap_types.h linux-2.6.28.8/arch/blackfin/include/asm/kmap_types.h
483 +--- linux-2.6.28.8/arch/blackfin/include/asm/kmap_types.h 2009-02-06 16:47:45.000000000 -0500
484 ++++ linux-2.6.28.8/arch/blackfin/include/asm/kmap_types.h 2009-02-21 09:37:48.000000000 -0500
485 +@@ -15,6 +15,7 @@ enum km_type {
486 + KM_IRQ1,
487 + KM_SOFTIRQ0,
488 + KM_SOFTIRQ1,
489 ++ KM_CLEARPAGE,
490 + KM_TYPE_NR
491 + };
492 +
493 +diff -urNp linux-2.6.28.8/arch/cris/include/asm/kmap_types.h linux-2.6.28.8/arch/cris/include/asm/kmap_types.h
494 +--- linux-2.6.28.8/arch/cris/include/asm/kmap_types.h 2009-02-06 16:47:45.000000000 -0500
495 ++++ linux-2.6.28.8/arch/cris/include/asm/kmap_types.h 2009-02-21 09:37:48.000000000 -0500
496 +@@ -19,6 +19,7 @@ enum km_type {
497 + KM_IRQ1,
498 + KM_SOFTIRQ0,
499 + KM_SOFTIRQ1,
500 ++ KM_CLEARPAGE,
501 + KM_TYPE_NR
502 + };
503 +
504 +diff -urNp linux-2.6.28.8/arch/h8300/include/asm/kmap_types.h linux-2.6.28.8/arch/h8300/include/asm/kmap_types.h
505 +--- linux-2.6.28.8/arch/h8300/include/asm/kmap_types.h 2009-02-06 16:47:45.000000000 -0500
506 ++++ linux-2.6.28.8/arch/h8300/include/asm/kmap_types.h 2009-02-21 09:37:48.000000000 -0500
507 +@@ -15,6 +15,7 @@ enum km_type {
508 + KM_IRQ1,
509 + KM_SOFTIRQ0,
510 + KM_SOFTIRQ1,
511 ++ KM_CLEARPAGE,
512 + KM_TYPE_NR
513 + };
514 +
515 +diff -urNp linux-2.6.28.8/arch/ia64/ia32/binfmt_elf32.c linux-2.6.28.8/arch/ia64/ia32/binfmt_elf32.c
516 +--- linux-2.6.28.8/arch/ia64/ia32/binfmt_elf32.c 2009-02-06 16:47:45.000000000 -0500
517 ++++ linux-2.6.28.8/arch/ia64/ia32/binfmt_elf32.c 2009-02-21 09:37:48.000000000 -0500
518 +@@ -45,6 +45,13 @@ randomize_stack_top(unsigned long stack_
519 +
520 + #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
521 +
522 ++#ifdef CONFIG_PAX_ASLR
523 ++#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
524 ++
525 ++#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
526 ++#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
527 ++#endif
528 ++
529 + /* Ugly but avoids duplication */
530 + #include "../../../fs/binfmt_elf.c"
531 +
532 +diff -urNp linux-2.6.28.8/arch/ia64/ia32/ia32priv.h linux-2.6.28.8/arch/ia64/ia32/ia32priv.h
533 +--- linux-2.6.28.8/arch/ia64/ia32/ia32priv.h 2009-02-06 16:47:45.000000000 -0500
534 ++++ linux-2.6.28.8/arch/ia64/ia32/ia32priv.h 2009-02-21 09:37:48.000000000 -0500
535 +@@ -296,7 +296,14 @@ typedef struct compat_siginfo {
536 + #define ELF_DATA ELFDATA2LSB
537 + #define ELF_ARCH EM_386
538 +
539 +-#define IA32_STACK_TOP IA32_PAGE_OFFSET
540 ++#ifdef CONFIG_PAX_RANDUSTACK
541 ++#define __IA32_DELTA_STACK (current->mm->delta_stack)
542 ++#else
543 ++#define __IA32_DELTA_STACK 0UL
544 ++#endif
545 ++
546 ++#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
547 ++
548 + #define IA32_GATE_OFFSET IA32_PAGE_OFFSET
549 + #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
550 +
551 +diff -urNp linux-2.6.28.8/arch/ia64/include/asm/elf.h linux-2.6.28.8/arch/ia64/include/asm/elf.h
552 +--- linux-2.6.28.8/arch/ia64/include/asm/elf.h 2009-02-06 16:47:45.000000000 -0500
553 ++++ linux-2.6.28.8/arch/ia64/include/asm/elf.h 2009-02-21 09:37:48.000000000 -0500
554 +@@ -43,6 +43,13 @@
555 + */
556 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x800000000UL)
557 +
558 ++#ifdef CONFIG_PAX_ASLR
559 ++#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
560 ++
561 ++#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
562 ++#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
563 ++#endif
564 ++
565 + #define PT_IA_64_UNWIND 0x70000001
566 +
567 + /* IA-64 relocations: */
568 +diff -urNp linux-2.6.28.8/arch/ia64/include/asm/kmap_types.h linux-2.6.28.8/arch/ia64/include/asm/kmap_types.h
569 +--- linux-2.6.28.8/arch/ia64/include/asm/kmap_types.h 2009-02-06 16:47:45.000000000 -0500
570 ++++ linux-2.6.28.8/arch/ia64/include/asm/kmap_types.h 2009-02-21 09:37:48.000000000 -0500
571 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
572 + D(10) KM_IRQ1,
573 + D(11) KM_SOFTIRQ0,
574 + D(12) KM_SOFTIRQ1,
575 +-D(13) KM_TYPE_NR
576 ++D(13) KM_CLEARPAGE,
577 ++D(14) KM_TYPE_NR
578 + };
579 +
580 + #undef D
581 +diff -urNp linux-2.6.28.8/arch/ia64/include/asm/pgtable.h linux-2.6.28.8/arch/ia64/include/asm/pgtable.h
582 +--- linux-2.6.28.8/arch/ia64/include/asm/pgtable.h 2009-02-06 16:47:45.000000000 -0500
583 ++++ linux-2.6.28.8/arch/ia64/include/asm/pgtable.h 2009-02-21 09:37:48.000000000 -0500
584 +@@ -143,6 +143,17 @@
585 + #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
586 + #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
587 + #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
588 ++
589 ++#ifdef CONFIG_PAX_PAGEEXEC
590 ++# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
591 ++# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
592 ++# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
593 ++#else
594 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
595 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
596 ++# define PAGE_COPY_NOEXEC PAGE_COPY
597 ++#endif
598 ++
599 + #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
600 + #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
601 + #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
602 +diff -urNp linux-2.6.28.8/arch/ia64/kernel/module.c linux-2.6.28.8/arch/ia64/kernel/module.c
603 +--- linux-2.6.28.8/arch/ia64/kernel/module.c 2009-02-06 16:47:45.000000000 -0500
604 ++++ linux-2.6.28.8/arch/ia64/kernel/module.c 2009-02-21 09:37:48.000000000 -0500
605 +@@ -312,8 +312,7 @@ module_alloc (unsigned long size)
606 + void
607 + module_free (struct module *mod, void *module_region)
608 + {
609 +- if (mod && mod->arch.init_unw_table &&
610 +- module_region == mod->module_init) {
611 ++ if (mod && mod->arch.init_unw_table && module_region == mod->module_init_rx) {
612 + unw_remove_unwind_table(mod->arch.init_unw_table);
613 + mod->arch.init_unw_table = NULL;
614 + }
615 +@@ -491,15 +490,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
616 + }
617 +
618 + static inline int
619 ++in_init_rx (const struct module *mod, uint64_t addr)
620 ++{
621 ++ return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
622 ++}
623 ++
624 ++static inline int
625 ++in_init_rw (const struct module *mod, uint64_t addr)
626 ++{
627 ++ return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
628 ++}
629 ++
630 ++static inline int
631 + in_init (const struct module *mod, uint64_t addr)
632 + {
633 +- return addr - (uint64_t) mod->module_init < mod->init_size;
634 ++ return in_init_rx(mod, addr) || in_init_rw(mod, addr);
635 ++}
636 ++
637 ++static inline int
638 ++in_core_rx (const struct module *mod, uint64_t addr)
639 ++{
640 ++ return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
641 ++}
642 ++
643 ++static inline int
644 ++in_core_rw (const struct module *mod, uint64_t addr)
645 ++{
646 ++ return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
647 + }
648 +
649 + static inline int
650 + in_core (const struct module *mod, uint64_t addr)
651 + {
652 +- return addr - (uint64_t) mod->module_core < mod->core_size;
653 ++ return in_core_rx(mod, addr) || in_core_rw(mod, addr);
654 + }
655 +
656 + static inline int
657 +@@ -683,7 +706,14 @@ do_reloc (struct module *mod, uint8_t r_
658 + break;
659 +
660 + case RV_BDREL:
661 +- val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
662 ++ if (in_init_rx(mod, val))
663 ++ val -= (uint64_t) mod->module_init_rx;
664 ++ else if (in_init_rw(mod, val))
665 ++ val -= (uint64_t) mod->module_init_rw;
666 ++ else if (in_core_rx(mod, val))
667 ++ val -= (uint64_t) mod->module_core_rx;
668 ++ else if (in_core_rw(mod, val))
669 ++ val -= (uint64_t) mod->module_core_rw;
670 + break;
671 +
672 + case RV_LTV:
673 +@@ -817,15 +847,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
674 + * addresses have been selected...
675 + */
676 + uint64_t gp;
677 +- if (mod->core_size > MAX_LTOFF)
678 ++ if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
679 + /*
680 + * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
681 + * at the end of the module.
682 + */
683 +- gp = mod->core_size - MAX_LTOFF / 2;
684 ++ gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
685 + else
686 +- gp = mod->core_size / 2;
687 +- gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
688 ++ gp = (mod->core_size_rx + mod->core_size_rw) / 2;
689 ++ gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
690 + mod->arch.gp = gp;
691 + DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
692 + }
693 +diff -urNp linux-2.6.28.8/arch/ia64/kernel/sys_ia64.c linux-2.6.28.8/arch/ia64/kernel/sys_ia64.c
694 +--- linux-2.6.28.8/arch/ia64/kernel/sys_ia64.c 2009-02-06 16:47:45.000000000 -0500
695 ++++ linux-2.6.28.8/arch/ia64/kernel/sys_ia64.c 2009-02-21 09:37:48.000000000 -0500
696 +@@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
697 + if (REGION_NUMBER(addr) == RGN_HPAGE)
698 + addr = 0;
699 + #endif
700 ++
701 ++#ifdef CONFIG_PAX_RANDMMAP
702 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
703 ++ addr = mm->free_area_cache;
704 ++ else
705 ++#endif
706 ++
707 + if (!addr)
708 + addr = mm->free_area_cache;
709 +
710 +@@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil
711 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
712 + /* At this point: (!vma || addr < vma->vm_end). */
713 + if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
714 +- if (start_addr != TASK_UNMAPPED_BASE) {
715 ++ if (start_addr != mm->mmap_base) {
716 + /* Start a new search --- just in case we missed some holes. */
717 +- addr = TASK_UNMAPPED_BASE;
718 ++ addr = mm->mmap_base;
719 + goto full_search;
720 + }
721 + return -ENOMEM;
722 +diff -urNp linux-2.6.28.8/arch/ia64/mm/fault.c linux-2.6.28.8/arch/ia64/mm/fault.c
723 +--- linux-2.6.28.8/arch/ia64/mm/fault.c 2009-02-06 16:47:45.000000000 -0500
724 ++++ linux-2.6.28.8/arch/ia64/mm/fault.c 2009-02-21 09:37:48.000000000 -0500
725 +@@ -72,6 +72,23 @@ mapped_kernel_page_is_present (unsigned
726 + return pte_present(pte);
727 + }
728 +
729 ++#ifdef CONFIG_PAX_PAGEEXEC
730 ++void pax_report_insns(void *pc, void *sp)
731 ++{
732 ++ unsigned long i;
733 ++
734 ++ printk(KERN_ERR "PAX: bytes at PC: ");
735 ++ for (i = 0; i < 8; i++) {
736 ++ unsigned int c;
737 ++ if (get_user(c, (unsigned int *)pc+i))
738 ++ printk(KERN_CONT "???????? ");
739 ++ else
740 ++ printk(KERN_CONT "%08x ", c);
741 ++ }
742 ++ printk("\n");
743 ++}
744 ++#endif
745 ++
746 + void __kprobes
747 + ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
748 + {
749 +@@ -145,9 +162,23 @@ ia64_do_page_fault (unsigned long addres
750 + mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
751 + | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
752 +
753 +- if ((vma->vm_flags & mask) != mask)
754 ++ if ((vma->vm_flags & mask) != mask) {
755 ++
756 ++#ifdef CONFIG_PAX_PAGEEXEC
757 ++ if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
758 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
759 ++ goto bad_area;
760 ++
761 ++ up_read(&mm->mmap_sem);
762 ++ pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
763 ++ do_group_exit(SIGKILL);
764 ++ }
765 ++#endif
766 ++
767 + goto bad_area;
768 +
769 ++ }
770 ++
771 + survive:
772 + /*
773 + * If for any reason at all we couldn't handle the fault, make
774 +diff -urNp linux-2.6.28.8/arch/ia64/mm/init.c linux-2.6.28.8/arch/ia64/mm/init.c
775 +--- linux-2.6.28.8/arch/ia64/mm/init.c 2009-02-06 16:47:45.000000000 -0500
776 ++++ linux-2.6.28.8/arch/ia64/mm/init.c 2009-02-21 09:37:48.000000000 -0500
777 +@@ -121,6 +121,19 @@ ia64_init_addr_space (void)
778 + vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
779 + vma->vm_end = vma->vm_start + PAGE_SIZE;
780 + vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
781 ++
782 ++#ifdef CONFIG_PAX_PAGEEXEC
783 ++ if (current->mm->pax_flags & MF_PAX_PAGEEXEC) {
784 ++ vma->vm_flags &= ~VM_EXEC;
785 ++
786 ++#ifdef CONFIG_PAX_MPROTECT
787 ++ if (current->mm->pax_flags & MF_PAX_MPROTECT)
788 ++ vma->vm_flags &= ~VM_MAYEXEC;
789 ++#endif
790 ++
791 ++ }
792 ++#endif
793 ++
794 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
795 + down_write(&current->mm->mmap_sem);
796 + if (insert_vm_struct(current->mm, vma)) {
797 +diff -urNp linux-2.6.28.8/arch/m68knommu/include/asm/kmap_types.h linux-2.6.28.8/arch/m68knommu/include/asm/kmap_types.h
798 +--- linux-2.6.28.8/arch/m68knommu/include/asm/kmap_types.h 2009-02-06 16:47:45.000000000 -0500
799 ++++ linux-2.6.28.8/arch/m68knommu/include/asm/kmap_types.h 2009-02-21 09:37:48.000000000 -0500
800 +@@ -15,6 +15,7 @@ enum km_type {
801 + KM_IRQ1,
802 + KM_SOFTIRQ0,
803 + KM_SOFTIRQ1,
804 ++ KM_CLEARPAGE,
805 + KM_TYPE_NR
806 + };
807 +
808 +diff -urNp linux-2.6.28.8/arch/mips/include/asm/elf.h linux-2.6.28.8/arch/mips/include/asm/elf.h
809 +--- linux-2.6.28.8/arch/mips/include/asm/elf.h 2009-02-06 16:47:45.000000000 -0500
810 ++++ linux-2.6.28.8/arch/mips/include/asm/elf.h 2009-02-21 09:37:48.000000000 -0500
811 +@@ -364,4 +364,11 @@ extern int dump_task_fpu(struct task_str
812 + #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
813 + #endif
814 +
815 ++#ifdef CONFIG_PAX_ASLR
816 ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
817 ++
818 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
819 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
820 ++#endif
821 ++
822 + #endif /* _ASM_ELF_H */
823 +diff -urNp linux-2.6.28.8/arch/mips/include/asm/kmap_types.h linux-2.6.28.8/arch/mips/include/asm/kmap_types.h
824 +--- linux-2.6.28.8/arch/mips/include/asm/kmap_types.h 2009-02-06 16:47:45.000000000 -0500
825 ++++ linux-2.6.28.8/arch/mips/include/asm/kmap_types.h 2009-02-21 09:37:48.000000000 -0500
826 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
827 + D(10) KM_IRQ1,
828 + D(11) KM_SOFTIRQ0,
829 + D(12) KM_SOFTIRQ1,
830 +-D(13) KM_TYPE_NR
831 ++D(13) KM_CLEARPAGE,
832 ++D(14) KM_TYPE_NR
833 + };
834 +
835 + #undef D
836 +diff -urNp linux-2.6.28.8/arch/mips/include/asm/page.h linux-2.6.28.8/arch/mips/include/asm/page.h
837 +--- linux-2.6.28.8/arch/mips/include/asm/page.h 2009-02-06 16:47:45.000000000 -0500
838 ++++ linux-2.6.28.8/arch/mips/include/asm/page.h 2009-02-21 09:37:48.000000000 -0500
839 +@@ -82,7 +82,7 @@ extern void copy_user_highpage(struct pa
840 + #ifdef CONFIG_CPU_MIPS32
841 + typedef struct { unsigned long pte_low, pte_high; } pte_t;
842 + #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
843 +- #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
844 ++ #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
845 + #else
846 + typedef struct { unsigned long long pte; } pte_t;
847 + #define pte_val(x) ((x).pte)
848 +diff -urNp linux-2.6.28.8/arch/mips/include/asm/system.h linux-2.6.28.8/arch/mips/include/asm/system.h
849 +--- linux-2.6.28.8/arch/mips/include/asm/system.h 2009-02-06 16:47:45.000000000 -0500
850 ++++ linux-2.6.28.8/arch/mips/include/asm/system.h 2009-02-21 09:37:48.000000000 -0500
851 +@@ -217,6 +217,6 @@ extern void per_cpu_trap_init(void);
852 + */
853 + #define __ARCH_WANT_UNLOCKED_CTXSW
854 +
855 +-extern unsigned long arch_align_stack(unsigned long sp);
856 ++#define arch_align_stack(x) ((x) & ALMASK)
857 +
858 + #endif /* _ASM_SYSTEM_H */
859 +diff -urNp linux-2.6.28.8/arch/mips/kernel/binfmt_elfn32.c linux-2.6.28.8/arch/mips/kernel/binfmt_elfn32.c
860 +--- linux-2.6.28.8/arch/mips/kernel/binfmt_elfn32.c 2009-02-06 16:47:45.000000000 -0500
861 ++++ linux-2.6.28.8/arch/mips/kernel/binfmt_elfn32.c 2009-02-21 09:37:48.000000000 -0500
862 +@@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
863 + #undef ELF_ET_DYN_BASE
864 + #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
865 +
866 ++#ifdef CONFIG_PAX_ASLR
867 ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
868 ++
869 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
870 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
871 ++#endif
872 ++
873 + #include <asm/processor.h>
874 + #include <linux/module.h>
875 + #include <linux/elfcore.h>
876 +diff -urNp linux-2.6.28.8/arch/mips/kernel/binfmt_elfo32.c linux-2.6.28.8/arch/mips/kernel/binfmt_elfo32.c
877 +--- linux-2.6.28.8/arch/mips/kernel/binfmt_elfo32.c 2009-02-06 16:47:45.000000000 -0500
878 ++++ linux-2.6.28.8/arch/mips/kernel/binfmt_elfo32.c 2009-02-21 09:37:48.000000000 -0500
879 +@@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
880 + #undef ELF_ET_DYN_BASE
881 + #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
882 +
883 ++#ifdef CONFIG_PAX_ASLR
884 ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
885 ++
886 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
887 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
888 ++#endif
889 ++
890 + #include <asm/processor.h>
891 + #include <linux/module.h>
892 + #include <linux/elfcore.h>
893 +diff -urNp linux-2.6.28.8/arch/mips/kernel/process.c linux-2.6.28.8/arch/mips/kernel/process.c
894 +--- linux-2.6.28.8/arch/mips/kernel/process.c 2009-02-06 16:47:45.000000000 -0500
895 ++++ linux-2.6.28.8/arch/mips/kernel/process.c 2009-02-21 09:37:48.000000000 -0500
896 +@@ -457,15 +457,3 @@ unsigned long get_wchan(struct task_stru
897 + out:
898 + return pc;
899 + }
900 +-
901 +-/*
902 +- * Don't forget that the stack pointer must be aligned on a 8 bytes
903 +- * boundary for 32-bits ABI and 16 bytes for 64-bits ABI.
904 +- */
905 +-unsigned long arch_align_stack(unsigned long sp)
906 +-{
907 +- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
908 +- sp -= get_random_int() & ~PAGE_MASK;
909 +-
910 +- return sp & ALMASK;
911 +-}
912 +diff -urNp linux-2.6.28.8/arch/mips/kernel/syscall.c linux-2.6.28.8/arch/mips/kernel/syscall.c
913 +--- linux-2.6.28.8/arch/mips/kernel/syscall.c 2009-02-06 16:47:45.000000000 -0500
914 ++++ linux-2.6.28.8/arch/mips/kernel/syscall.c 2009-02-21 09:37:48.000000000 -0500
915 +@@ -99,6 +99,11 @@ unsigned long arch_get_unmapped_area(str
916 + do_color_align = 0;
917 + if (filp || (flags & MAP_SHARED))
918 + do_color_align = 1;
919 ++
920 ++#ifdef CONFIG_PAX_RANDMMAP
921 ++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
922 ++#endif
923 ++
924 + if (addr) {
925 + if (do_color_align)
926 + addr = COLOUR_ALIGN(addr, pgoff);
927 +@@ -109,7 +114,7 @@ unsigned long arch_get_unmapped_area(str
928 + (!vmm || addr + len <= vmm->vm_start))
929 + return addr;
930 + }
931 +- addr = TASK_UNMAPPED_BASE;
932 ++ addr = current->mm->mmap_base;
933 + if (do_color_align)
934 + addr = COLOUR_ALIGN(addr, pgoff);
935 + else
936 +diff -urNp linux-2.6.28.8/arch/mips/mm/fault.c linux-2.6.28.8/arch/mips/mm/fault.c
937 +--- linux-2.6.28.8/arch/mips/mm/fault.c 2009-02-06 16:47:45.000000000 -0500
938 ++++ linux-2.6.28.8/arch/mips/mm/fault.c 2009-02-21 09:37:48.000000000 -0500
939 +@@ -26,6 +26,23 @@
940 + #include <asm/ptrace.h>
941 + #include <asm/highmem.h> /* For VMALLOC_END */
942 +
943 ++#ifdef CONFIG_PAX_PAGEEXEC
944 ++void pax_report_insns(void *pc)
945 ++{
946 ++ unsigned long i;
947 ++
948 ++ printk(KERN_ERR "PAX: bytes at PC: ");
949 ++ for (i = 0; i < 5; i++) {
950 ++ unsigned int c;
951 ++ if (get_user(c, (unsigned int *)pc+i))
952 ++ printk(KERN_CONT "???????? ");
953 ++ else
954 ++ printk(KERN_CONT "%08x ", c);
955 ++ }
956 ++ printk("\n");
957 ++}
958 ++#endif
959 ++
960 + /*
961 + * This routine handles page faults. It determines the address,
962 + * and the problem, and then passes it off to one of the appropriate
963 +diff -urNp linux-2.6.28.8/arch/parisc/include/asm/elf.h linux-2.6.28.8/arch/parisc/include/asm/elf.h
964 +--- linux-2.6.28.8/arch/parisc/include/asm/elf.h 2009-02-06 16:47:45.000000000 -0500
965 ++++ linux-2.6.28.8/arch/parisc/include/asm/elf.h 2009-02-21 09:37:48.000000000 -0500
966 +@@ -333,6 +333,13 @@ struct pt_regs; /* forward declaration..
967 +
968 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
969 +
970 ++#ifdef CONFIG_PAX_ASLR
971 ++#define PAX_ELF_ET_DYN_BASE 0x10000UL
972 ++
973 ++#define PAX_DELTA_MMAP_LEN 16
974 ++#define PAX_DELTA_STACK_LEN 16
975 ++#endif
976 ++
977 + /* This yields a mask that user programs can use to figure out what
978 + instruction set this CPU supports. This could be done in user space,
979 + but it's not easy, and we've already done it here. */
980 +diff -urNp linux-2.6.28.8/arch/parisc/include/asm/kmap_types.h linux-2.6.28.8/arch/parisc/include/asm/kmap_types.h
981 +--- linux-2.6.28.8/arch/parisc/include/asm/kmap_types.h 2009-02-06 16:47:45.000000000 -0500
982 ++++ linux-2.6.28.8/arch/parisc/include/asm/kmap_types.h 2009-02-21 09:37:48.000000000 -0500
983 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
984 + D(10) KM_IRQ1,
985 + D(11) KM_SOFTIRQ0,
986 + D(12) KM_SOFTIRQ1,
987 +-D(13) KM_TYPE_NR
988 ++D(13) KM_CLEARPAGE,
989 ++D(14) KM_TYPE_NR
990 + };
991 +
992 + #undef D
993 +diff -urNp linux-2.6.28.8/arch/parisc/include/asm/pgtable.h linux-2.6.28.8/arch/parisc/include/asm/pgtable.h
994 +--- linux-2.6.28.8/arch/parisc/include/asm/pgtable.h 2009-02-06 16:47:45.000000000 -0500
995 ++++ linux-2.6.28.8/arch/parisc/include/asm/pgtable.h 2009-02-21 09:37:48.000000000 -0500
996 +@@ -202,6 +202,17 @@
997 + #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
998 + #define PAGE_COPY PAGE_EXECREAD
999 + #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
1000 ++
1001 ++#ifdef CONFIG_PAX_PAGEEXEC
1002 ++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
1003 ++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
1004 ++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
1005 ++#else
1006 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
1007 ++# define PAGE_COPY_NOEXEC PAGE_COPY
1008 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
1009 ++#endif
1010 ++
1011 + #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
1012 + #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
1013 + #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
1014 +diff -urNp linux-2.6.28.8/arch/parisc/kernel/module.c linux-2.6.28.8/arch/parisc/kernel/module.c
1015 +--- linux-2.6.28.8/arch/parisc/kernel/module.c 2009-02-06 16:47:45.000000000 -0500
1016 ++++ linux-2.6.28.8/arch/parisc/kernel/module.c 2009-02-21 09:37:48.000000000 -0500
1017 +@@ -75,16 +75,38 @@
1018 +
1019 + /* three functions to determine where in the module core
1020 + * or init pieces the location is */
1021 ++static inline int in_init_rx(struct module *me, void *loc)
1022 ++{
1023 ++ return (loc >= me->module_init_rx &&
1024 ++ loc < (me->module_init_rx + me->init_size_rx));
1025 ++}
1026 ++
1027 ++static inline int in_init_rw(struct module *me, void *loc)
1028 ++{
1029 ++ return (loc >= me->module_init_rw &&
1030 ++ loc < (me->module_init_rw + me->init_size_rw));
1031 ++}
1032 ++
1033 + static inline int in_init(struct module *me, void *loc)
1034 + {
1035 +- return (loc >= me->module_init &&
1036 +- loc <= (me->module_init + me->init_size));
1037 ++ return in_init_rx(me, loc) || in_init_rw(me, loc);
1038 ++}
1039 ++
1040 ++static inline int in_core_rx(struct module *me, void *loc)
1041 ++{
1042 ++ return (loc >= me->module_core_rx &&
1043 ++ loc < (me->module_core_rx + me->core_size_rx));
1044 ++}
1045 ++
1046 ++static inline int in_core_rw(struct module *me, void *loc)
1047 ++{
1048 ++ return (loc >= me->module_core_rw &&
1049 ++ loc < (me->module_core_rw + me->core_size_rw));
1050 + }
1051 +
1052 + static inline int in_core(struct module *me, void *loc)
1053 + {
1054 +- return (loc >= me->module_core &&
1055 +- loc <= (me->module_core + me->core_size));
1056 ++ return in_core_rx(me, loc) || in_core_rw(me, loc);
1057 + }
1058 +
1059 + static inline int in_local(struct module *me, void *loc)
1060 +@@ -298,21 +320,21 @@ int module_frob_arch_sections(CONST Elf_
1061 + }
1062 +
1063 + /* align things a bit */
1064 +- me->core_size = ALIGN(me->core_size, 16);
1065 +- me->arch.got_offset = me->core_size;
1066 +- me->core_size += gots * sizeof(struct got_entry);
1067 +-
1068 +- me->core_size = ALIGN(me->core_size, 16);
1069 +- me->arch.fdesc_offset = me->core_size;
1070 +- me->core_size += fdescs * sizeof(Elf_Fdesc);
1071 +-
1072 +- me->core_size = ALIGN(me->core_size, 16);
1073 +- me->arch.stub_offset = me->core_size;
1074 +- me->core_size += stubs * sizeof(struct stub_entry);
1075 +-
1076 +- me->init_size = ALIGN(me->init_size, 16);
1077 +- me->arch.init_stub_offset = me->init_size;
1078 +- me->init_size += init_stubs * sizeof(struct stub_entry);
1079 ++ me->core_size_rw = ALIGN(me->core_size_rw, 16);
1080 ++ me->arch.got_offset = me->core_size_rw;
1081 ++ me->core_size_rw += gots * sizeof(struct got_entry);
1082 ++
1083 ++ me->core_size_rw = ALIGN(me->core_size_rw, 16);
1084 ++ me->arch.fdesc_offset = me->core_size_rw;
1085 ++ me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
1086 ++
1087 ++ me->core_size_rx = ALIGN(me->core_size_rx, 16);
1088 ++ me->arch.stub_offset = me->core_size_rx;
1089 ++ me->core_size_rx += stubs * sizeof(struct stub_entry);
1090 ++
1091 ++ me->init_size_rx = ALIGN(me->init_size_rx, 16);
1092 ++ me->arch.init_stub_offset = me->init_size_rx;
1093 ++ me->init_size_rx += init_stubs * sizeof(struct stub_entry);
1094 +
1095 + me->arch.got_max = gots;
1096 + me->arch.fdesc_max = fdescs;
1097 +@@ -332,7 +354,7 @@ static Elf64_Word get_got(struct module
1098 +
1099 + BUG_ON(value == 0);
1100 +
1101 +- got = me->module_core + me->arch.got_offset;
1102 ++ got = me->module_core_rw + me->arch.got_offset;
1103 + for (i = 0; got[i].addr; i++)
1104 + if (got[i].addr == value)
1105 + goto out;
1106 +@@ -350,7 +372,7 @@ static Elf64_Word get_got(struct module
1107 + #ifdef CONFIG_64BIT
1108 + static Elf_Addr get_fdesc(struct module *me, unsigned long value)
1109 + {
1110 +- Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
1111 ++ Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
1112 +
1113 + if (!value) {
1114 + printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
1115 +@@ -368,7 +390,7 @@ static Elf_Addr get_fdesc(struct module
1116 +
1117 + /* Create new one */
1118 + fdesc->addr = value;
1119 +- fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
1120 ++ fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
1121 + return (Elf_Addr)fdesc;
1122 + }
1123 + #endif /* CONFIG_64BIT */
1124 +@@ -388,12 +410,12 @@ static Elf_Addr get_stub(struct module *
1125 + if(init_section) {
1126 + i = me->arch.init_stub_count++;
1127 + BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
1128 +- stub = me->module_init + me->arch.init_stub_offset +
1129 ++ stub = me->module_init_rx + me->arch.init_stub_offset +
1130 + i * sizeof(struct stub_entry);
1131 + } else {
1132 + i = me->arch.stub_count++;
1133 + BUG_ON(me->arch.stub_count > me->arch.stub_max);
1134 +- stub = me->module_core + me->arch.stub_offset +
1135 ++ stub = me->module_core_rx + me->arch.stub_offset +
1136 + i * sizeof(struct stub_entry);
1137 + }
1138 +
1139 +@@ -761,7 +783,7 @@ register_unwind_table(struct module *me,
1140 +
1141 + table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
1142 + end = table + sechdrs[me->arch.unwind_section].sh_size;
1143 +- gp = (Elf_Addr)me->module_core + me->arch.got_offset;
1144 ++ gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
1145 +
1146 + DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
1147 + me->arch.unwind_section, table, end, gp);
1148 +diff -urNp linux-2.6.28.8/arch/parisc/kernel/sys_parisc.c linux-2.6.28.8/arch/parisc/kernel/sys_parisc.c
1149 +--- linux-2.6.28.8/arch/parisc/kernel/sys_parisc.c 2009-02-06 16:47:45.000000000 -0500
1150 ++++ linux-2.6.28.8/arch/parisc/kernel/sys_parisc.c 2009-02-21 09:37:48.000000000 -0500
1151 +@@ -98,7 +98,7 @@ unsigned long arch_get_unmapped_area(str
1152 + if (flags & MAP_FIXED)
1153 + return addr;
1154 + if (!addr)
1155 +- addr = TASK_UNMAPPED_BASE;
1156 ++ addr = current->mm->mmap_base;
1157 +
1158 + if (filp) {
1159 + addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
1160 +diff -urNp linux-2.6.28.8/arch/parisc/kernel/traps.c linux-2.6.28.8/arch/parisc/kernel/traps.c
1161 +--- linux-2.6.28.8/arch/parisc/kernel/traps.c 2009-02-06 16:47:45.000000000 -0500
1162 ++++ linux-2.6.28.8/arch/parisc/kernel/traps.c 2009-02-21 09:37:48.000000000 -0500
1163 +@@ -731,9 +731,7 @@ void handle_interruption(int code, struc
1164 +
1165 + down_read(&current->mm->mmap_sem);
1166 + vma = find_vma(current->mm,regs->iaoq[0]);
1167 +- if (vma && (regs->iaoq[0] >= vma->vm_start)
1168 +- && (vma->vm_flags & VM_EXEC)) {
1169 +-
1170 ++ if (vma && (regs->iaoq[0] >= vma->vm_start)) {
1171 + fault_address = regs->iaoq[0];
1172 + fault_space = regs->iasq[0];
1173 +
1174 +diff -urNp linux-2.6.28.8/arch/parisc/mm/fault.c linux-2.6.28.8/arch/parisc/mm/fault.c
1175 +--- linux-2.6.28.8/arch/parisc/mm/fault.c 2009-02-06 16:47:45.000000000 -0500
1176 ++++ linux-2.6.28.8/arch/parisc/mm/fault.c 2009-02-21 09:37:48.000000000 -0500
1177 +@@ -16,6 +16,7 @@
1178 + #include <linux/sched.h>
1179 + #include <linux/interrupt.h>
1180 + #include <linux/module.h>
1181 ++#include <linux/unistd.h>
1182 +
1183 + #include <asm/uaccess.h>
1184 + #include <asm/traps.h>
1185 +@@ -53,7 +54,7 @@ DEFINE_PER_CPU(struct exception_data, ex
1186 + static unsigned long
1187 + parisc_acctyp(unsigned long code, unsigned int inst)
1188 + {
1189 +- if (code == 6 || code == 16)
1190 ++ if (code == 6 || code == 7 || code == 16)
1191 + return VM_EXEC;
1192 +
1193 + switch (inst & 0xf0000000) {
1194 +@@ -139,6 +140,116 @@ parisc_acctyp(unsigned long code, unsign
1195 + }
1196 + #endif
1197 +
1198 ++#ifdef CONFIG_PAX_PAGEEXEC
1199 ++/*
1200 ++ * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
1201 ++ *
1202 ++ * returns 1 when task should be killed
1203 ++ * 2 when rt_sigreturn trampoline was detected
1204 ++ * 3 when unpatched PLT trampoline was detected
1205 ++ */
1206 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
1207 ++{
1208 ++
1209 ++#ifdef CONFIG_PAX_EMUPLT
1210 ++ int err;
1211 ++
1212 ++ do { /* PaX: unpatched PLT emulation */
1213 ++ unsigned int bl, depwi;
1214 ++
1215 ++ err = get_user(bl, (unsigned int *)instruction_pointer(regs));
1216 ++ err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
1217 ++
1218 ++ if (err)
1219 ++ break;
1220 ++
1221 ++ if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
1222 ++ unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
1223 ++
1224 ++ err = get_user(ldw, (unsigned int *)addr);
1225 ++ err |= get_user(bv, (unsigned int *)(addr+4));
1226 ++ err |= get_user(ldw2, (unsigned int *)(addr+8));
1227 ++
1228 ++ if (err)
1229 ++ break;
1230 ++
1231 ++ if (ldw == 0x0E801096U &&
1232 ++ bv == 0xEAC0C000U &&
1233 ++ ldw2 == 0x0E881095U)
1234 ++ {
1235 ++ unsigned int resolver, map;
1236 ++
1237 ++ err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
1238 ++ err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
1239 ++ if (err)
1240 ++ break;
1241 ++
1242 ++ regs->gr[20] = instruction_pointer(regs)+8;
1243 ++ regs->gr[21] = map;
1244 ++ regs->gr[22] = resolver;
1245 ++ regs->iaoq[0] = resolver | 3UL;
1246 ++ regs->iaoq[1] = regs->iaoq[0] + 4;
1247 ++ return 3;
1248 ++ }
1249 ++ }
1250 ++ } while (0);
1251 ++#endif
1252 ++
1253 ++#ifdef CONFIG_PAX_EMUTRAMP
1254 ++
1255 ++#ifndef CONFIG_PAX_EMUSIGRT
1256 ++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
1257 ++ return 1;
1258 ++#endif
1259 ++
1260 ++ do { /* PaX: rt_sigreturn emulation */
1261 ++ unsigned int ldi1, ldi2, bel, nop;
1262 ++
1263 ++ err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
1264 ++ err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
1265 ++ err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
1266 ++ err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
1267 ++
1268 ++ if (err)
1269 ++ break;
1270 ++
1271 ++ if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
1272 ++ ldi2 == 0x3414015AU &&
1273 ++ bel == 0xE4008200U &&
1274 ++ nop == 0x08000240U)
1275 ++ {
1276 ++ regs->gr[25] = (ldi1 & 2) >> 1;
1277 ++ regs->gr[20] = __NR_rt_sigreturn;
1278 ++ regs->gr[31] = regs->iaoq[1] + 16;
1279 ++ regs->sr[0] = regs->iasq[1];
1280 ++ regs->iaoq[0] = 0x100UL;
1281 ++ regs->iaoq[1] = regs->iaoq[0] + 4;
1282 ++ regs->iasq[0] = regs->sr[2];
1283 ++ regs->iasq[1] = regs->sr[2];
1284 ++ return 2;
1285 ++ }
1286 ++ } while (0);
1287 ++#endif
1288 ++
1289 ++ return 1;
1290 ++}
1291 ++
1292 ++void pax_report_insns(void *pc, void *sp)
1293 ++{
1294 ++ unsigned long i;
1295 ++
1296 ++ printk(KERN_ERR "PAX: bytes at PC: ");
1297 ++ for (i = 0; i < 5; i++) {
1298 ++ unsigned int c;
1299 ++ if (get_user(c, (unsigned int *)pc+i))
1300 ++ printk(KERN_CONT "???????? ");
1301 ++ else
1302 ++ printk(KERN_CONT "%08x ", c);
1303 ++ }
1304 ++ printk("\n");
1305 ++}
1306 ++#endif
1307 ++
1308 + void do_page_fault(struct pt_regs *regs, unsigned long code,
1309 + unsigned long address)
1310 + {
1311 +@@ -165,8 +276,33 @@ good_area:
1312 +
1313 + acc_type = parisc_acctyp(code,regs->iir);
1314 +
1315 +- if ((vma->vm_flags & acc_type) != acc_type)
1316 ++ if ((vma->vm_flags & acc_type) != acc_type) {
1317 ++
1318 ++#ifdef CONFIG_PAX_PAGEEXEC
1319 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
1320 ++ (address & ~3UL) == instruction_pointer(regs))
1321 ++ {
1322 ++ up_read(&mm->mmap_sem);
1323 ++ switch (pax_handle_fetch_fault(regs)) {
1324 ++
1325 ++#ifdef CONFIG_PAX_EMUPLT
1326 ++ case 3:
1327 ++ return;
1328 ++#endif
1329 ++
1330 ++#ifdef CONFIG_PAX_EMUTRAMP
1331 ++ case 2:
1332 ++ return;
1333 ++#endif
1334 ++
1335 ++ }
1336 ++ pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
1337 ++ do_group_exit(SIGKILL);
1338 ++ }
1339 ++#endif
1340 ++
1341 + goto bad_area;
1342 ++ }
1343 +
1344 + /*
1345 + * If for any reason at all we couldn't handle the fault, make
1346 +diff -urNp linux-2.6.28.8/arch/powerpc/include/asm/elf.h linux-2.6.28.8/arch/powerpc/include/asm/elf.h
1347 +--- linux-2.6.28.8/arch/powerpc/include/asm/elf.h 2009-02-06 16:47:45.000000000 -0500
1348 ++++ linux-2.6.28.8/arch/powerpc/include/asm/elf.h 2009-02-21 09:37:48.000000000 -0500
1349 +@@ -180,6 +180,18 @@ typedef elf_fpreg_t elf_vsrreghalf_t32[E
1350 +
1351 + #define ELF_ET_DYN_BASE (0x20000000)
1352 +
1353 ++#ifdef CONFIG_PAX_ASLR
1354 ++#define PAX_ELF_ET_DYN_BASE (0x10000000UL)
1355 ++
1356 ++#ifdef __powerpc64__
1357 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
1358 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
1359 ++#else
1360 ++#define PAX_DELTA_MMAP_LEN 15
1361 ++#define PAX_DELTA_STACK_LEN 15
1362 ++#endif
1363 ++#endif
1364 ++
1365 + /*
1366 + * Our registers are always unsigned longs, whether we're a 32 bit
1367 + * process or 64 bit, on either a 64 bit or 32 bit kernel.
1368 +diff -urNp linux-2.6.28.8/arch/powerpc/include/asm/kmap_types.h linux-2.6.28.8/arch/powerpc/include/asm/kmap_types.h
1369 +--- linux-2.6.28.8/arch/powerpc/include/asm/kmap_types.h 2009-02-06 16:47:45.000000000 -0500
1370 ++++ linux-2.6.28.8/arch/powerpc/include/asm/kmap_types.h 2009-02-21 09:37:48.000000000 -0500
1371 +@@ -26,6 +26,7 @@ enum km_type {
1372 + KM_SOFTIRQ1,
1373 + KM_PPC_SYNC_PAGE,
1374 + KM_PPC_SYNC_ICACHE,
1375 ++ KM_CLEARPAGE,
1376 + KM_TYPE_NR
1377 + };
1378 +
1379 +diff -urNp linux-2.6.28.8/arch/powerpc/include/asm/page_64.h linux-2.6.28.8/arch/powerpc/include/asm/page_64.h
1380 +--- linux-2.6.28.8/arch/powerpc/include/asm/page_64.h 2009-02-06 16:47:45.000000000 -0500
1381 ++++ linux-2.6.28.8/arch/powerpc/include/asm/page_64.h 2009-02-21 09:37:48.000000000 -0500
1382 +@@ -170,15 +170,18 @@ do { \
1383 + * stack by default, so in the absense of a PT_GNU_STACK program header
1384 + * we turn execute permission off.
1385 + */
1386 +-#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
1387 +- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1388 ++#define VM_STACK_DEFAULT_FLAGS32 \
1389 ++ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
1390 ++ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1391 +
1392 + #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
1393 + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1394 +
1395 ++#ifndef CONFIG_PAX_PAGEEXEC
1396 + #define VM_STACK_DEFAULT_FLAGS \
1397 + (test_thread_flag(TIF_32BIT) ? \
1398 + VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
1399 ++#endif
1400 +
1401 + #include <asm-generic/page.h>
1402 +
1403 +diff -urNp linux-2.6.28.8/arch/powerpc/include/asm/page.h linux-2.6.28.8/arch/powerpc/include/asm/page.h
1404 +--- linux-2.6.28.8/arch/powerpc/include/asm/page.h 2009-02-06 16:47:45.000000000 -0500
1405 ++++ linux-2.6.28.8/arch/powerpc/include/asm/page.h 2009-02-21 09:37:48.000000000 -0500
1406 +@@ -111,8 +111,9 @@ extern phys_addr_t kernstart_addr;
1407 + * and needs to be executable. This means the whole heap ends
1408 + * up being executable.
1409 + */
1410 +-#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
1411 +- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1412 ++#define VM_DATA_DEFAULT_FLAGS32 \
1413 ++ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
1414 ++ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1415 +
1416 + #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
1417 + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1418 +diff -urNp linux-2.6.28.8/arch/powerpc/kernel/module_32.c linux-2.6.28.8/arch/powerpc/kernel/module_32.c
1419 +--- linux-2.6.28.8/arch/powerpc/kernel/module_32.c 2009-02-06 16:47:45.000000000 -0500
1420 ++++ linux-2.6.28.8/arch/powerpc/kernel/module_32.c 2009-02-21 09:37:48.000000000 -0500
1421 +@@ -158,7 +158,7 @@ int module_frob_arch_sections(Elf32_Ehdr
1422 + me->arch.core_plt_section = i;
1423 + }
1424 + if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
1425 +- printk("Module doesn't contain .plt or .init.plt sections.\n");
1426 ++ printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
1427 + return -ENOEXEC;
1428 + }
1429 +
1430 +@@ -199,11 +199,16 @@ static uint32_t do_plt_call(void *locati
1431 +
1432 + DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
1433 + /* Init, or core PLT? */
1434 +- if (location >= mod->module_core
1435 +- && location < mod->module_core + mod->core_size)
1436 ++ if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
1437 ++ (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
1438 + entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
1439 +- else
1440 ++ else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
1441 ++ (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
1442 + entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
1443 ++ else {
1444 ++ printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
1445 ++ return ~0UL;
1446 ++ }
1447 +
1448 + /* Find this entry, or if that fails, the next avail. entry */
1449 + while (entry->jump[0]) {
1450 +diff -urNp linux-2.6.28.8/arch/powerpc/kernel/signal_32.c linux-2.6.28.8/arch/powerpc/kernel/signal_32.c
1451 +--- linux-2.6.28.8/arch/powerpc/kernel/signal_32.c 2009-02-06 16:47:45.000000000 -0500
1452 ++++ linux-2.6.28.8/arch/powerpc/kernel/signal_32.c 2009-02-21 09:37:48.000000000 -0500
1453 +@@ -857,7 +857,7 @@ int handle_rt_signal32(unsigned long sig
1454 + /* Save user registers on the stack */
1455 + frame = &rt_sf->uc.uc_mcontext;
1456 + addr = frame;
1457 +- if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
1458 ++ if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
1459 + if (save_user_regs(regs, frame, 0, 1))
1460 + goto badframe;
1461 + regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
1462 +diff -urNp linux-2.6.28.8/arch/powerpc/kernel/signal_64.c linux-2.6.28.8/arch/powerpc/kernel/signal_64.c
1463 +--- linux-2.6.28.8/arch/powerpc/kernel/signal_64.c 2009-02-06 16:47:45.000000000 -0500
1464 ++++ linux-2.6.28.8/arch/powerpc/kernel/signal_64.c 2009-02-21 09:37:48.000000000 -0500
1465 +@@ -429,7 +429,7 @@ int handle_rt_signal64(int signr, struct
1466 + current->thread.fpscr.val = 0;
1467 +
1468 + /* Set up to return from userspace. */
1469 +- if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
1470 ++ if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
1471 + regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
1472 + } else {
1473 + err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
1474 +diff -urNp linux-2.6.28.8/arch/powerpc/kernel/vdso.c linux-2.6.28.8/arch/powerpc/kernel/vdso.c
1475 +--- linux-2.6.28.8/arch/powerpc/kernel/vdso.c 2009-02-06 16:47:45.000000000 -0500
1476 ++++ linux-2.6.28.8/arch/powerpc/kernel/vdso.c 2009-02-21 09:37:48.000000000 -0500
1477 +@@ -212,7 +212,7 @@ int arch_setup_additional_pages(struct l
1478 + vdso_base = VDSO32_MBASE;
1479 + #endif
1480 +
1481 +- current->mm->context.vdso_base = 0;
1482 ++ current->mm->context.vdso_base = ~0UL;
1483 +
1484 + /* vDSO has a problem and was disabled, just don't "enable" it for the
1485 + * process
1486 +@@ -229,7 +229,7 @@ int arch_setup_additional_pages(struct l
1487 + */
1488 + down_write(&mm->mmap_sem);
1489 + vdso_base = get_unmapped_area(NULL, vdso_base,
1490 +- vdso_pages << PAGE_SHIFT, 0, 0);
1491 ++ vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
1492 + if (IS_ERR_VALUE(vdso_base)) {
1493 + rc = vdso_base;
1494 + goto fail_mmapsem;
1495 +diff -urNp linux-2.6.28.8/arch/powerpc/mm/fault.c linux-2.6.28.8/arch/powerpc/mm/fault.c
1496 +--- linux-2.6.28.8/arch/powerpc/mm/fault.c 2009-02-06 16:47:45.000000000 -0500
1497 ++++ linux-2.6.28.8/arch/powerpc/mm/fault.c 2009-02-21 09:37:48.000000000 -0500
1498 +@@ -29,6 +29,10 @@
1499 + #include <linux/module.h>
1500 + #include <linux/kprobes.h>
1501 + #include <linux/kdebug.h>
1502 ++#include <linux/slab.h>
1503 ++#include <linux/pagemap.h>
1504 ++#include <linux/compiler.h>
1505 ++#include <linux/unistd.h>
1506 +
1507 + #include <asm/page.h>
1508 + #include <asm/pgtable.h>
1509 +@@ -62,6 +66,363 @@ static inline int notify_page_fault(stru
1510 + }
1511 + #endif
1512 +
1513 ++#ifdef CONFIG_PAX_EMUSIGRT
1514 ++void pax_syscall_close(struct vm_area_struct *vma)
1515 ++{
1516 ++ vma->vm_mm->call_syscall = 0UL;
1517 ++}
1518 ++
1519 ++static int pax_syscall_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1520 ++{
1521 ++ unsigned int *kaddr;
1522 ++
1523 ++ vmf->page = alloc_page(GFP_HIGHUSER);
1524 ++ if (!vmf->page)
1525 ++ return VM_FAULT_OOM;
1526 ++
1527 ++ kaddr = kmap(vmf->page);
1528 ++ memset(kaddr, 0, PAGE_SIZE);
1529 ++ kaddr[0] = 0x44000002U; /* sc */
1530 ++ __flush_dcache_icache(kaddr);
1531 ++ kunmap(vmf->page);
1532 ++ return VM_FAULT_MAJOR;
1533 ++}
1534 ++
1535 ++static struct vm_operations_struct pax_vm_ops = {
1536 ++ .close = pax_syscall_close,
1537 ++ .fault = pax_syscall_fault
1538 ++};
1539 ++
1540 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
1541 ++{
1542 ++ int ret;
1543 ++
1544 ++ vma->vm_mm = current->mm;
1545 ++ vma->vm_start = addr;
1546 ++ vma->vm_end = addr + PAGE_SIZE;
1547 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
1548 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
1549 ++ vma->vm_ops = &pax_vm_ops;
1550 ++
1551 ++ ret = insert_vm_struct(current->mm, vma);
1552 ++ if (ret)
1553 ++ return ret;
1554 ++
1555 ++ ++current->mm->total_vm;
1556 ++ return 0;
1557 ++}
1558 ++#endif
1559 ++
1560 ++#ifdef CONFIG_PAX_PAGEEXEC
1561 ++/*
1562 ++ * PaX: decide what to do with offenders (regs->nip = fault address)
1563 ++ *
1564 ++ * returns 1 when task should be killed
1565 ++ * 2 when patched GOT trampoline was detected
1566 ++ * 3 when patched PLT trampoline was detected
1567 ++ * 4 when unpatched PLT trampoline was detected
1568 ++ * 5 when sigreturn trampoline was detected
1569 ++ * 6 when rt_sigreturn trampoline was detected
1570 ++ */
1571 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
1572 ++{
1573 ++
1574 ++#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
1575 ++ int err;
1576 ++#endif
1577 ++
1578 ++#ifdef CONFIG_PAX_EMUPLT
1579 ++ do { /* PaX: patched GOT emulation */
1580 ++ unsigned int blrl;
1581 ++
1582 ++ err = get_user(blrl, (unsigned int *)regs->nip);
1583 ++
1584 ++ if (!err && blrl == 0x4E800021U) {
1585 ++ unsigned long temp = regs->nip;
1586 ++
1587 ++ regs->nip = regs->link & 0xFFFFFFFCUL;
1588 ++ regs->link = temp + 4UL;
1589 ++ return 2;
1590 ++ }
1591 ++ } while (0);
1592 ++
1593 ++ do { /* PaX: patched PLT emulation #1 */
1594 ++ unsigned int b;
1595 ++
1596 ++ err = get_user(b, (unsigned int *)regs->nip);
1597 ++
1598 ++ if (!err && (b & 0xFC000003U) == 0x48000000U) {
1599 ++ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
1600 ++ return 3;
1601 ++ }
1602 ++ } while (0);
1603 ++
1604 ++ do { /* PaX: unpatched PLT emulation #1 */
1605 ++ unsigned int li, b;
1606 ++
1607 ++ err = get_user(li, (unsigned int *)regs->nip);
1608 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
1609 ++
1610 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1611 ++ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1612 ++ unsigned long addr = b | 0xFC000000UL;
1613 ++
1614 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1615 ++ err = get_user(rlwinm, (unsigned int *)addr);
1616 ++ err |= get_user(add, (unsigned int *)(addr+4));
1617 ++ err |= get_user(li2, (unsigned int *)(addr+8));
1618 ++ err |= get_user(addis2, (unsigned int *)(addr+12));
1619 ++ err |= get_user(mtctr, (unsigned int *)(addr+16));
1620 ++ err |= get_user(li3, (unsigned int *)(addr+20));
1621 ++ err |= get_user(addis3, (unsigned int *)(addr+24));
1622 ++ err |= get_user(bctr, (unsigned int *)(addr+28));
1623 ++
1624 ++ if (err)
1625 ++ break;
1626 ++
1627 ++ if (rlwinm == 0x556C083CU &&
1628 ++ add == 0x7D6C5A14U &&
1629 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
1630 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1631 ++ mtctr == 0x7D8903A6U &&
1632 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
1633 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1634 ++ bctr == 0x4E800420U)
1635 ++ {
1636 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1637 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1638 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1639 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1640 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
1641 ++ regs->nip = regs->ctr;
1642 ++ return 4;
1643 ++ }
1644 ++ }
1645 ++ } while (0);
1646 ++
1647 ++#if 0
1648 ++ do { /* PaX: unpatched PLT emulation #2 */
1649 ++ unsigned int lis, lwzu, b, bctr;
1650 ++
1651 ++ err = get_user(lis, (unsigned int *)regs->nip);
1652 ++ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
1653 ++ err |= get_user(b, (unsigned int *)(regs->nip+8));
1654 ++ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
1655 ++
1656 ++ if (err)
1657 ++ break;
1658 ++
1659 ++ if ((lis & 0xFFFF0000U) == 0x39600000U &&
1660 ++ (lwzu & 0xU) == 0xU &&
1661 ++ (b & 0xFC000003U) == 0x48000000U &&
1662 ++ bctr == 0x4E800420U)
1663 ++ {
1664 ++ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1665 ++ unsigned long addr = b | 0xFC000000UL;
1666 ++
1667 ++ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1668 ++ err = get_user(addis, (unsigned int *)addr);
1669 ++ err |= get_user(addi, (unsigned int *)(addr+4));
1670 ++ err |= get_user(rlwinm, (unsigned int *)(addr+8));
1671 ++ err |= get_user(add, (unsigned int *)(addr+12));
1672 ++ err |= get_user(li2, (unsigned int *)(addr+16));
1673 ++ err |= get_user(addis2, (unsigned int *)(addr+20));
1674 ++ err |= get_user(mtctr, (unsigned int *)(addr+24));
1675 ++ err |= get_user(li3, (unsigned int *)(addr+28));
1676 ++ err |= get_user(addis3, (unsigned int *)(addr+32));
1677 ++ err |= get_user(bctr, (unsigned int *)(addr+36));
1678 ++
1679 ++ if (err)
1680 ++ break;
1681 ++
1682 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1683 ++ (addi & 0xFFFF0000U) == 0x396B0000U &&
1684 ++ rlwinm == 0x556C083CU &&
1685 ++ add == 0x7D6C5A14U &&
1686 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
1687 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1688 ++ mtctr == 0x7D8903A6U &&
1689 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
1690 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1691 ++ bctr == 0x4E800420U)
1692 ++ {
1693 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1694 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1695 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1696 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1697 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
1698 ++ regs->nip = regs->ctr;
1699 ++ return 4;
1700 ++ }
1701 ++ }
1702 ++ } while (0);
1703 ++#endif
1704 ++
1705 ++ do { /* PaX: unpatched PLT emulation #3 */
1706 ++ unsigned int li, b;
1707 ++
1708 ++ err = get_user(li, (unsigned int *)regs->nip);
1709 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
1710 ++
1711 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1712 ++ unsigned int addis, lwz, mtctr, bctr;
1713 ++ unsigned long addr = b | 0xFC000000UL;
1714 ++
1715 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1716 ++ err = get_user(addis, (unsigned int *)addr);
1717 ++ err |= get_user(lwz, (unsigned int *)(addr+4));
1718 ++ err |= get_user(mtctr, (unsigned int *)(addr+8));
1719 ++ err |= get_user(bctr, (unsigned int *)(addr+12));
1720 ++
1721 ++ if (err)
1722 ++ break;
1723 ++
1724 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1725 ++ (lwz & 0xFFFF0000U) == 0x816B0000U &&
1726 ++ mtctr == 0x7D6903A6U &&
1727 ++ bctr == 0x4E800420U)
1728 ++ {
1729 ++ unsigned int r11;
1730 ++
1731 ++ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1732 ++ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1733 ++
1734 ++ err = get_user(r11, (unsigned int *)addr);
1735 ++ if (err)
1736 ++ break;
1737 ++
1738 ++ regs->gpr[PT_R11] = r11;
1739 ++ regs->ctr = r11;
1740 ++ regs->nip = r11;
1741 ++ return 4;
1742 ++ }
1743 ++ }
1744 ++ } while (0);
1745 ++#endif
1746 ++
1747 ++#ifdef CONFIG_PAX_EMUSIGRT
1748 ++ do { /* PaX: sigreturn emulation */
1749 ++ unsigned int li, sc;
1750 ++
1751 ++ err = get_user(li, (unsigned int *)regs->nip);
1752 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
1753 ++
1754 ++ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
1755 ++ struct vm_area_struct *vma;
1756 ++ unsigned long call_syscall;
1757 ++
1758 ++ down_read(&current->mm->mmap_sem);
1759 ++ call_syscall = current->mm->call_syscall;
1760 ++ up_read(&current->mm->mmap_sem);
1761 ++ if (likely(call_syscall))
1762 ++ goto emulate;
1763 ++
1764 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1765 ++
1766 ++ down_write(&current->mm->mmap_sem);
1767 ++ if (current->mm->call_syscall) {
1768 ++ call_syscall = current->mm->call_syscall;
1769 ++ up_write(&current->mm->mmap_sem);
1770 ++ if (vma)
1771 ++ kmem_cache_free(vm_area_cachep, vma);
1772 ++ goto emulate;
1773 ++ }
1774 ++
1775 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1776 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
1777 ++ up_write(&current->mm->mmap_sem);
1778 ++ if (vma)
1779 ++ kmem_cache_free(vm_area_cachep, vma);
1780 ++ return 1;
1781 ++ }
1782 ++
1783 ++ if (pax_insert_vma(vma, call_syscall)) {
1784 ++ up_write(&current->mm->mmap_sem);
1785 ++ kmem_cache_free(vm_area_cachep, vma);
1786 ++ return 1;
1787 ++ }
1788 ++
1789 ++ current->mm->call_syscall = call_syscall;
1790 ++ up_write(&current->mm->mmap_sem);
1791 ++
1792 ++emulate:
1793 ++ regs->gpr[PT_R0] = __NR_sigreturn;
1794 ++ regs->nip = call_syscall;
1795 ++ return 5;
1796 ++ }
1797 ++ } while (0);
1798 ++
1799 ++ do { /* PaX: rt_sigreturn emulation */
1800 ++ unsigned int li, sc;
1801 ++
1802 ++ err = get_user(li, (unsigned int *)regs->nip);
1803 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
1804 ++
1805 ++ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
1806 ++ struct vm_area_struct *vma;
1807 ++ unsigned int call_syscall;
1808 ++
1809 ++ down_read(&current->mm->mmap_sem);
1810 ++ call_syscall = current->mm->call_syscall;
1811 ++ up_read(&current->mm->mmap_sem);
1812 ++ if (likely(call_syscall))
1813 ++ goto rt_emulate;
1814 ++
1815 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1816 ++
1817 ++ down_write(&current->mm->mmap_sem);
1818 ++ if (current->mm->call_syscall) {
1819 ++ call_syscall = current->mm->call_syscall;
1820 ++ up_write(&current->mm->mmap_sem);
1821 ++ if (vma)
1822 ++ kmem_cache_free(vm_area_cachep, vma);
1823 ++ goto rt_emulate;
1824 ++ }
1825 ++
1826 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1827 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
1828 ++ up_write(&current->mm->mmap_sem);
1829 ++ if (vma)
1830 ++ kmem_cache_free(vm_area_cachep, vma);
1831 ++ return 1;
1832 ++ }
1833 ++
1834 ++ if (pax_insert_vma(vma, call_syscall)) {
1835 ++ up_write(&current->mm->mmap_sem);
1836 ++ kmem_cache_free(vm_area_cachep, vma);
1837 ++ return 1;
1838 ++ }
1839 ++
1840 ++ current->mm->call_syscall = call_syscall;
1841 ++ up_write(&current->mm->mmap_sem);
1842 ++
1843 ++rt_emulate:
1844 ++ regs->gpr[PT_R0] = __NR_rt_sigreturn;
1845 ++ regs->nip = call_syscall;
1846 ++ return 6;
1847 ++ }
1848 ++ } while (0);
1849 ++#endif
1850 ++
1851 ++ return 1;
1852 ++}
1853 ++
1854 ++void pax_report_insns(void *pc, void *sp)
1855 ++{
1856 ++ unsigned long i;
1857 ++
1858 ++ printk(KERN_ERR "PAX: bytes at PC: ");
1859 ++ for (i = 0; i < 5; i++) {
1860 ++ unsigned int c;
1861 ++ if (get_user(c, (unsigned int *)pc+i))
1862 ++ printk(KERN_CONT "???????? ");
1863 ++ else
1864 ++ printk(KERN_CONT "%08x ", c);
1865 ++ }
1866 ++ printk("\n");
1867 ++}
1868 ++#endif
1869 ++
1870 + /*
1871 + * Check whether the instruction at regs->nip is a store using
1872 + * an update addressing form which will update r1.
1873 +@@ -132,7 +493,7 @@ int __kprobes do_page_fault(struct pt_re
1874 + * indicate errors in DSISR but can validly be set in SRR1.
1875 + */
1876 + if (trap == 0x400)
1877 +- error_code &= 0x48200000;
1878 ++ error_code &= 0x58200000;
1879 + else
1880 + is_write = error_code & DSISR_ISSTORE;
1881 + #else
1882 +@@ -331,6 +692,37 @@ bad_area:
1883 + bad_area_nosemaphore:
1884 + /* User mode accesses cause a SIGSEGV */
1885 + if (user_mode(regs)) {
1886 ++
1887 ++#ifdef CONFIG_PAX_PAGEEXEC
1888 ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
1889 ++#ifdef CONFIG_PPC64
1890 ++ if (is_exec && (error_code & DSISR_PROTFAULT)) {
1891 ++#else
1892 ++ if (is_exec && regs->nip == address) {
1893 ++#endif
1894 ++ switch (pax_handle_fetch_fault(regs)) {
1895 ++
1896 ++#ifdef CONFIG_PAX_EMUPLT
1897 ++ case 2:
1898 ++ case 3:
1899 ++ case 4:
1900 ++ return 0;
1901 ++#endif
1902 ++
1903 ++#ifdef CONFIG_PAX_EMUSIGRT
1904 ++ case 5:
1905 ++ case 6:
1906 ++ return 0;
1907 ++#endif
1908 ++
1909 ++ }
1910 ++
1911 ++ pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[PT_R1]);
1912 ++ do_group_exit(SIGKILL);
1913 ++ }
1914 ++ }
1915 ++#endif
1916 ++
1917 + _exception(SIGSEGV, regs, code, address);
1918 + return 0;
1919 + }
1920 +diff -urNp linux-2.6.28.8/arch/powerpc/mm/mmap.c linux-2.6.28.8/arch/powerpc/mm/mmap.c
1921 +--- linux-2.6.28.8/arch/powerpc/mm/mmap.c 2009-02-06 16:47:45.000000000 -0500
1922 ++++ linux-2.6.28.8/arch/powerpc/mm/mmap.c 2009-02-21 09:37:48.000000000 -0500
1923 +@@ -75,10 +75,22 @@ void arch_pick_mmap_layout(struct mm_str
1924 + */
1925 + if (mmap_is_legacy()) {
1926 + mm->mmap_base = TASK_UNMAPPED_BASE;
1927 ++
1928 ++#ifdef CONFIG_PAX_RANDMMAP
1929 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
1930 ++ mm->mmap_base += mm->delta_mmap;
1931 ++#endif
1932 ++
1933 + mm->get_unmapped_area = arch_get_unmapped_area;
1934 + mm->unmap_area = arch_unmap_area;
1935 + } else {
1936 + mm->mmap_base = mmap_base();
1937 ++
1938 ++#ifdef CONFIG_PAX_RANDMMAP
1939 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
1940 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
1941 ++#endif
1942 ++
1943 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
1944 + mm->unmap_area = arch_unmap_area_topdown;
1945 + }
1946 +diff -urNp linux-2.6.28.8/arch/s390/include/asm/kmap_types.h linux-2.6.28.8/arch/s390/include/asm/kmap_types.h
1947 +--- linux-2.6.28.8/arch/s390/include/asm/kmap_types.h 2009-02-06 16:47:45.000000000 -0500
1948 ++++ linux-2.6.28.8/arch/s390/include/asm/kmap_types.h 2009-02-21 09:37:48.000000000 -0500
1949 +@@ -16,6 +16,7 @@ enum km_type {
1950 + KM_IRQ1,
1951 + KM_SOFTIRQ0,
1952 + KM_SOFTIRQ1,
1953 ++ KM_CLEARPAGE,
1954 + KM_TYPE_NR
1955 + };
1956 +
1957 +diff -urNp linux-2.6.28.8/arch/s390/kernel/module.c linux-2.6.28.8/arch/s390/kernel/module.c
1958 +--- linux-2.6.28.8/arch/s390/kernel/module.c 2009-02-06 16:47:45.000000000 -0500
1959 ++++ linux-2.6.28.8/arch/s390/kernel/module.c 2009-02-21 09:37:48.000000000 -0500
1960 +@@ -166,11 +166,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
1961 +
1962 + /* Increase core size by size of got & plt and set start
1963 + offsets for got and plt. */
1964 +- me->core_size = ALIGN(me->core_size, 4);
1965 +- me->arch.got_offset = me->core_size;
1966 +- me->core_size += me->arch.got_size;
1967 +- me->arch.plt_offset = me->core_size;
1968 +- me->core_size += me->arch.plt_size;
1969 ++ me->core_size_rw = ALIGN(me->core_size_rw, 4);
1970 ++ me->arch.got_offset = me->core_size_rw;
1971 ++ me->core_size_rw += me->arch.got_size;
1972 ++ me->arch.plt_offset = me->core_size_rx;
1973 ++ me->core_size_rx += me->arch.plt_size;
1974 + return 0;
1975 + }
1976 +
1977 +@@ -256,7 +256,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1978 + if (info->got_initialized == 0) {
1979 + Elf_Addr *gotent;
1980 +
1981 +- gotent = me->module_core + me->arch.got_offset +
1982 ++ gotent = me->module_core_rw + me->arch.got_offset +
1983 + info->got_offset;
1984 + *gotent = val;
1985 + info->got_initialized = 1;
1986 +@@ -280,7 +280,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1987 + else if (r_type == R_390_GOTENT ||
1988 + r_type == R_390_GOTPLTENT)
1989 + *(unsigned int *) loc =
1990 +- (val + (Elf_Addr) me->module_core - loc) >> 1;
1991 ++ (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
1992 + else if (r_type == R_390_GOT64 ||
1993 + r_type == R_390_GOTPLT64)
1994 + *(unsigned long *) loc = val;
1995 +@@ -294,7 +294,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1996 + case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
1997 + if (info->plt_initialized == 0) {
1998 + unsigned int *ip;
1999 +- ip = me->module_core + me->arch.plt_offset +
2000 ++ ip = me->module_core_rx + me->arch.plt_offset +
2001 + info->plt_offset;
2002 + #ifndef CONFIG_64BIT
2003 + ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
2004 +@@ -316,7 +316,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2005 + val = me->arch.plt_offset - me->arch.got_offset +
2006 + info->plt_offset + rela->r_addend;
2007 + else
2008 +- val = (Elf_Addr) me->module_core +
2009 ++ val = (Elf_Addr) me->module_core_rx +
2010 + me->arch.plt_offset + info->plt_offset +
2011 + rela->r_addend - loc;
2012 + if (r_type == R_390_PLT16DBL)
2013 +@@ -336,7 +336,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2014 + case R_390_GOTOFF32: /* 32 bit offset to GOT. */
2015 + case R_390_GOTOFF64: /* 64 bit offset to GOT. */
2016 + val = val + rela->r_addend -
2017 +- ((Elf_Addr) me->module_core + me->arch.got_offset);
2018 ++ ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
2019 + if (r_type == R_390_GOTOFF16)
2020 + *(unsigned short *) loc = val;
2021 + else if (r_type == R_390_GOTOFF32)
2022 +@@ -346,7 +346,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2023 + break;
2024 + case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
2025 + case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
2026 +- val = (Elf_Addr) me->module_core + me->arch.got_offset +
2027 ++ val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
2028 + rela->r_addend - loc;
2029 + if (r_type == R_390_GOTPC)
2030 + *(unsigned int *) loc = val;
2031 +diff -urNp linux-2.6.28.8/arch/sh/include/asm/kmap_types.h linux-2.6.28.8/arch/sh/include/asm/kmap_types.h
2032 +--- linux-2.6.28.8/arch/sh/include/asm/kmap_types.h 2009-02-06 16:47:45.000000000 -0500
2033 ++++ linux-2.6.28.8/arch/sh/include/asm/kmap_types.h 2009-02-21 09:37:48.000000000 -0500
2034 +@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
2035 + D(10) KM_IRQ1,
2036 + D(11) KM_SOFTIRQ0,
2037 + D(12) KM_SOFTIRQ1,
2038 +-D(13) KM_TYPE_NR
2039 ++D(13) KM_CLEARPAGE,
2040 ++D(14) KM_TYPE_NR
2041 + };
2042 +
2043 + #undef D
2044 +diff -urNp linux-2.6.28.8/arch/sparc/include/asm/elf_32.h linux-2.6.28.8/arch/sparc/include/asm/elf_32.h
2045 +--- linux-2.6.28.8/arch/sparc/include/asm/elf_32.h 2009-02-06 16:47:45.000000000 -0500
2046 ++++ linux-2.6.28.8/arch/sparc/include/asm/elf_32.h 2009-02-21 09:37:48.000000000 -0500
2047 +@@ -116,6 +116,13 @@ typedef struct {
2048 +
2049 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
2050 +
2051 ++#ifdef CONFIG_PAX_ASLR
2052 ++#define PAX_ELF_ET_DYN_BASE 0x10000UL
2053 ++
2054 ++#define PAX_DELTA_MMAP_LEN 16
2055 ++#define PAX_DELTA_STACK_LEN 16
2056 ++#endif
2057 ++
2058 + /* This yields a mask that user programs can use to figure out what
2059 + instruction set this cpu supports. This can NOT be done in userspace
2060 + on Sparc. */
2061 +diff -urNp linux-2.6.28.8/arch/sparc/include/asm/elf_64.h linux-2.6.28.8/arch/sparc/include/asm/elf_64.h
2062 +--- linux-2.6.28.8/arch/sparc/include/asm/elf_64.h 2009-02-06 16:47:45.000000000 -0500
2063 ++++ linux-2.6.28.8/arch/sparc/include/asm/elf_64.h 2009-02-21 09:37:48.000000000 -0500
2064 +@@ -163,6 +163,12 @@ typedef struct {
2065 + #define ELF_ET_DYN_BASE 0x0000010000000000UL
2066 + #define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL
2067 +
2068 ++#ifdef CONFIG_PAX_ASLR
2069 ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
2070 ++
2071 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 14 : 28 )
2072 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 15 : 29 )
2073 ++#endif
2074 +
2075 + /* This yields a mask that user programs can use to figure out what
2076 + instruction set this cpu supports. */
2077 +diff -urNp linux-2.6.28.8/arch/sparc/include/asm/kmap_types.h linux-2.6.28.8/arch/sparc/include/asm/kmap_types.h
2078 +--- linux-2.6.28.8/arch/sparc/include/asm/kmap_types.h 2009-02-06 16:47:45.000000000 -0500
2079 ++++ linux-2.6.28.8/arch/sparc/include/asm/kmap_types.h 2009-02-21 09:37:48.000000000 -0500
2080 +@@ -19,6 +19,7 @@ enum km_type {
2081 + KM_IRQ1,
2082 + KM_SOFTIRQ0,
2083 + KM_SOFTIRQ1,
2084 ++ KM_CLEARPAGE,
2085 + KM_TYPE_NR
2086 + };
2087 +
2088 +diff -urNp linux-2.6.28.8/arch/sparc/include/asm/pgtable_32.h linux-2.6.28.8/arch/sparc/include/asm/pgtable_32.h
2089 +--- linux-2.6.28.8/arch/sparc/include/asm/pgtable_32.h 2009-02-06 16:47:45.000000000 -0500
2090 ++++ linux-2.6.28.8/arch/sparc/include/asm/pgtable_32.h 2009-02-21 09:37:48.000000000 -0500
2091 +@@ -43,6 +43,13 @@ BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
2092 + BTFIXUPDEF_INT(page_none)
2093 + BTFIXUPDEF_INT(page_copy)
2094 + BTFIXUPDEF_INT(page_readonly)
2095 ++
2096 ++#ifdef CONFIG_PAX_PAGEEXEC
2097 ++BTFIXUPDEF_INT(page_shared_noexec)
2098 ++BTFIXUPDEF_INT(page_copy_noexec)
2099 ++BTFIXUPDEF_INT(page_readonly_noexec)
2100 ++#endif
2101 ++
2102 + BTFIXUPDEF_INT(page_kernel)
2103 +
2104 + #define PMD_SHIFT SUN4C_PMD_SHIFT
2105 +@@ -64,6 +71,16 @@ extern pgprot_t PAGE_SHARED;
2106 + #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
2107 + #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
2108 +
2109 ++#ifdef CONFIG_PAX_PAGEEXEC
2110 ++extern pgprot_t PAGE_SHARED_NOEXEC;
2111 ++# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec))
2112 ++# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec))
2113 ++#else
2114 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
2115 ++# define PAGE_COPY_NOEXEC PAGE_COPY
2116 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
2117 ++#endif
2118 ++
2119 + extern unsigned long page_kernel;
2120 +
2121 + #ifdef MODULE
2122 +diff -urNp linux-2.6.28.8/arch/sparc/include/asm/pgtsrmmu.h linux-2.6.28.8/arch/sparc/include/asm/pgtsrmmu.h
2123 +--- linux-2.6.28.8/arch/sparc/include/asm/pgtsrmmu.h 2009-02-06 16:47:45.000000000 -0500
2124 ++++ linux-2.6.28.8/arch/sparc/include/asm/pgtsrmmu.h 2009-02-21 09:37:48.000000000 -0500
2125 +@@ -115,6 +115,13 @@
2126 + SRMMU_EXEC | SRMMU_REF)
2127 + #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
2128 + SRMMU_EXEC | SRMMU_REF)
2129 ++
2130 ++#ifdef CONFIG_PAX_PAGEEXEC
2131 ++#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_WRITE | SRMMU_REF)
2132 ++#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_REF)
2133 ++#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_REF)
2134 ++#endif
2135 ++
2136 + #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
2137 + SRMMU_DIRTY | SRMMU_REF)
2138 +
2139 +diff -urNp linux-2.6.28.8/arch/sparc/kernel/sys_sparc.c linux-2.6.28.8/arch/sparc/kernel/sys_sparc.c
2140 +--- linux-2.6.28.8/arch/sparc/kernel/sys_sparc.c 2009-02-06 16:47:45.000000000 -0500
2141 ++++ linux-2.6.28.8/arch/sparc/kernel/sys_sparc.c 2009-02-21 09:37:48.000000000 -0500
2142 +@@ -56,7 +56,7 @@ unsigned long arch_get_unmapped_area(str
2143 + if (ARCH_SUN4C && len > 0x20000000)
2144 + return -ENOMEM;
2145 + if (!addr)
2146 +- addr = TASK_UNMAPPED_BASE;
2147 ++ addr = current->mm->mmap_base;
2148 +
2149 + if (flags & MAP_SHARED)
2150 + addr = COLOUR_ALIGN(addr);
2151 +diff -urNp linux-2.6.28.8/arch/sparc/Makefile linux-2.6.28.8/arch/sparc/Makefile
2152 +--- linux-2.6.28.8/arch/sparc/Makefile 2009-02-06 16:47:45.000000000 -0500
2153 ++++ linux-2.6.28.8/arch/sparc/Makefile 2009-02-21 09:37:48.000000000 -0500
2154 +@@ -37,7 +37,7 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc
2155 + # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
2156 + INIT_Y := $(patsubst %/, %/built-in.o, $(init-y))
2157 + CORE_Y := $(core-y)
2158 +-CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
2159 ++CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
2160 + CORE_Y := $(patsubst %/, %/built-in.o, $(CORE_Y))
2161 + DRIVERS_Y := $(patsubst %/, %/built-in.o, $(drivers-y))
2162 + NET_Y := $(patsubst %/, %/built-in.o, $(net-y))
2163 +diff -urNp linux-2.6.28.8/arch/sparc/mm/fault.c linux-2.6.28.8/arch/sparc/mm/fault.c
2164 +--- linux-2.6.28.8/arch/sparc/mm/fault.c 2009-02-06 16:47:45.000000000 -0500
2165 ++++ linux-2.6.28.8/arch/sparc/mm/fault.c 2009-02-21 09:37:48.000000000 -0500
2166 +@@ -21,6 +21,9 @@
2167 + #include <linux/interrupt.h>
2168 + #include <linux/module.h>
2169 + #include <linux/kdebug.h>
2170 ++#include <linux/slab.h>
2171 ++#include <linux/pagemap.h>
2172 ++#include <linux/compiler.h>
2173 +
2174 + #include <asm/system.h>
2175 + #include <asm/page.h>
2176 +@@ -167,6 +170,249 @@ static unsigned long compute_si_addr(str
2177 + return safe_compute_effective_address(regs, insn);
2178 + }
2179 +
2180 ++#ifdef CONFIG_PAX_PAGEEXEC
2181 ++void pax_emuplt_close(struct vm_area_struct *vma)
2182 ++{
2183 ++ vma->vm_mm->call_dl_resolve = 0UL;
2184 ++}
2185 ++
2186 ++static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
2187 ++{
2188 ++ unsigned int *kaddr;
2189 ++
2190 ++ vmf->page = alloc_page(GFP_HIGHUSER);
2191 ++ if (!vmf->page)
2192 ++ return VM_FAULT_OOM;
2193 ++
2194 ++ kaddr = kmap(vmf->page);
2195 ++ memset(kaddr, 0, PAGE_SIZE);
2196 ++ kaddr[0] = 0x9DE3BFA8U; /* save */
2197 ++ flush_dcache_page(vmf->page);
2198 ++ kunmap(vmf->page);
2199 ++ return VM_FAULT_MAJOR;
2200 ++}
2201 ++
2202 ++static struct vm_operations_struct pax_vm_ops = {
2203 ++ .close = pax_emuplt_close,
2204 ++ .fault = pax_emuplt_fault
2205 ++};
2206 ++
2207 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2208 ++{
2209 ++ int ret;
2210 ++
2211 ++ vma->vm_mm = current->mm;
2212 ++ vma->vm_start = addr;
2213 ++ vma->vm_end = addr + PAGE_SIZE;
2214 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2215 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
2216 ++ vma->vm_ops = &pax_vm_ops;
2217 ++
2218 ++ ret = insert_vm_struct(current->mm, vma);
2219 ++ if (ret)
2220 ++ return ret;
2221 ++
2222 ++ ++current->mm->total_vm;
2223 ++ return 0;
2224 ++}
2225 ++
2226 ++/*
2227 ++ * PaX: decide what to do with offenders (regs->pc = fault address)
2228 ++ *
2229 ++ * returns 1 when task should be killed
2230 ++ * 2 when patched PLT trampoline was detected
2231 ++ * 3 when unpatched PLT trampoline was detected
2232 ++ */
2233 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
2234 ++{
2235 ++
2236 ++#ifdef CONFIG_PAX_EMUPLT
2237 ++ int err;
2238 ++
2239 ++ do { /* PaX: patched PLT emulation #1 */
2240 ++ unsigned int sethi1, sethi2, jmpl;
2241 ++
2242 ++ err = get_user(sethi1, (unsigned int *)regs->pc);
2243 ++ err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
2244 ++ err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
2245 ++
2246 ++ if (err)
2247 ++ break;
2248 ++
2249 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2250 ++ (sethi2 & 0xFFC00000U) == 0x03000000U &&
2251 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U)
2252 ++ {
2253 ++ unsigned int addr;
2254 ++
2255 ++ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
2256 ++ addr = regs->u_regs[UREG_G1];
2257 ++ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
2258 ++ regs->pc = addr;
2259 ++ regs->npc = addr+4;
2260 ++ return 2;
2261 ++ }
2262 ++ } while (0);
2263 ++
2264 ++ { /* PaX: patched PLT emulation #2 */
2265 ++ unsigned int ba;
2266 ++
2267 ++ err = get_user(ba, (unsigned int *)regs->pc);
2268 ++
2269 ++ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
2270 ++ unsigned int addr;
2271 ++
2272 ++ addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
2273 ++ regs->pc = addr;
2274 ++ regs->npc = addr+4;
2275 ++ return 2;
2276 ++ }
2277 ++ }
2278 ++
2279 ++ do { /* PaX: patched PLT emulation #3 */
2280 ++ unsigned int sethi, jmpl, nop;
2281 ++
2282 ++ err = get_user(sethi, (unsigned int *)regs->pc);
2283 ++ err |= get_user(jmpl, (unsigned int *)(regs->pc+4));
2284 ++ err |= get_user(nop, (unsigned int *)(regs->pc+8));
2285 ++
2286 ++ if (err)
2287 ++ break;
2288 ++
2289 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
2290 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
2291 ++ nop == 0x01000000U)
2292 ++ {
2293 ++ unsigned int addr;
2294 ++
2295 ++ addr = (sethi & 0x003FFFFFU) << 10;
2296 ++ regs->u_regs[UREG_G1] = addr;
2297 ++ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
2298 ++ regs->pc = addr;
2299 ++ regs->npc = addr+4;
2300 ++ return 2;
2301 ++ }
2302 ++ } while (0);
2303 ++
2304 ++ do { /* PaX: unpatched PLT emulation step 1 */
2305 ++ unsigned int sethi, ba, nop;
2306 ++
2307 ++ err = get_user(sethi, (unsigned int *)regs->pc);
2308 ++ err |= get_user(ba, (unsigned int *)(regs->pc+4));
2309 ++ err |= get_user(nop, (unsigned int *)(regs->pc+8));
2310 ++
2311 ++ if (err)
2312 ++ break;
2313 ++
2314 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
2315 ++ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
2316 ++ nop == 0x01000000U)
2317 ++ {
2318 ++ unsigned int addr, save, call;
2319 ++
2320 ++ if ((ba & 0xFFC00000U) == 0x30800000U)
2321 ++ addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
2322 ++ else
2323 ++ addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
2324 ++
2325 ++ err = get_user(save, (unsigned int *)addr);
2326 ++ err |= get_user(call, (unsigned int *)(addr+4));
2327 ++ err |= get_user(nop, (unsigned int *)(addr+8));
2328 ++ if (err)
2329 ++ break;
2330 ++
2331 ++ if (save == 0x9DE3BFA8U &&
2332 ++ (call & 0xC0000000U) == 0x40000000U &&
2333 ++ nop == 0x01000000U)
2334 ++ {
2335 ++ struct vm_area_struct *vma;
2336 ++ unsigned long call_dl_resolve;
2337 ++
2338 ++ down_read(&current->mm->mmap_sem);
2339 ++ call_dl_resolve = current->mm->call_dl_resolve;
2340 ++ up_read(&current->mm->mmap_sem);
2341 ++ if (likely(call_dl_resolve))
2342 ++ goto emulate;
2343 ++
2344 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
2345 ++
2346 ++ down_write(&current->mm->mmap_sem);
2347 ++ if (current->mm->call_dl_resolve) {
2348 ++ call_dl_resolve = current->mm->call_dl_resolve;
2349 ++ up_write(&current->mm->mmap_sem);
2350 ++ if (vma)
2351 ++ kmem_cache_free(vm_area_cachep, vma);
2352 ++ goto emulate;
2353 ++ }
2354 ++
2355 ++ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2356 ++ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
2357 ++ up_write(&current->mm->mmap_sem);
2358 ++ if (vma)
2359 ++ kmem_cache_free(vm_area_cachep, vma);
2360 ++ return 1;
2361 ++ }
2362 ++
2363 ++ if (pax_insert_vma(vma, call_dl_resolve)) {
2364 ++ up_write(&current->mm->mmap_sem);
2365 ++ kmem_cache_free(vm_area_cachep, vma);
2366 ++ return 1;
2367 ++ }
2368 ++
2369 ++ current->mm->call_dl_resolve = call_dl_resolve;
2370 ++ up_write(&current->mm->mmap_sem);
2371 ++
2372 ++emulate:
2373 ++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
2374 ++ regs->pc = call_dl_resolve;
2375 ++ regs->npc = addr+4;
2376 ++ return 3;
2377 ++ }
2378 ++ }
2379 ++ } while (0);
2380 ++
2381 ++ do { /* PaX: unpatched PLT emulation step 2 */
2382 ++ unsigned int save, call, nop;
2383 ++
2384 ++ err = get_user(save, (unsigned int *)(regs->pc-4));
2385 ++ err |= get_user(call, (unsigned int *)regs->pc);
2386 ++ err |= get_user(nop, (unsigned int *)(regs->pc+4));
2387 ++ if (err)
2388 ++ break;
2389 ++
2390 ++ if (save == 0x9DE3BFA8U &&
2391 ++ (call & 0xC0000000U) == 0x40000000U &&
2392 ++ nop == 0x01000000U)
2393 ++ {
2394 ++ unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
2395 ++
2396 ++ regs->u_regs[UREG_RETPC] = regs->pc;
2397 ++ regs->pc = dl_resolve;
2398 ++ regs->npc = dl_resolve+4;
2399 ++ return 3;
2400 ++ }
2401 ++ } while (0);
2402 ++#endif
2403 ++
2404 ++ return 1;
2405 ++}
2406 ++
2407 ++void pax_report_insns(void *pc, void *sp)
2408 ++{
2409 ++ unsigned long i;
2410 ++
2411 ++ printk(KERN_ERR "PAX: bytes at PC: ");
2412 ++ for (i = 0; i < 5; i++) {
2413 ++ unsigned int c;
2414 ++ if (get_user(c, (unsigned int *)pc+i))
2415 ++ printk(KERN_CONT "???????? ");
2416 ++ else
2417 ++ printk(KERN_CONT "%08x ", c);
2418 ++ }
2419 ++ printk("\n");
2420 ++}
2421 ++#endif
2422 ++
2423 + asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
2424 + unsigned long address)
2425 + {
2426 +@@ -231,6 +477,24 @@ good_area:
2427 + if(!(vma->vm_flags & VM_WRITE))
2428 + goto bad_area;
2429 + } else {
2430 ++
2431 ++#ifdef CONFIG_PAX_PAGEEXEC
2432 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
2433 ++ up_read(&mm->mmap_sem);
2434 ++ switch (pax_handle_fetch_fault(regs)) {
2435 ++
2436 ++#ifdef CONFIG_PAX_EMUPLT
2437 ++ case 2:
2438 ++ case 3:
2439 ++ return;
2440 ++#endif
2441 ++
2442 ++ }
2443 ++ pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]);
2444 ++ do_group_exit(SIGKILL);
2445 ++ }
2446 ++#endif
2447 ++
2448 + /* Allow reads even for write-only mappings */
2449 + if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
2450 + goto bad_area;
2451 +diff -urNp linux-2.6.28.8/arch/sparc/mm/init.c linux-2.6.28.8/arch/sparc/mm/init.c
2452 +--- linux-2.6.28.8/arch/sparc/mm/init.c 2009-02-06 16:47:45.000000000 -0500
2453 ++++ linux-2.6.28.8/arch/sparc/mm/init.c 2009-02-21 09:37:48.000000000 -0500
2454 +@@ -313,6 +313,9 @@ extern void device_scan(void);
2455 + pgprot_t PAGE_SHARED __read_mostly;
2456 + EXPORT_SYMBOL(PAGE_SHARED);
2457 +
2458 ++pgprot_t PAGE_SHARED_NOEXEC __read_mostly;
2459 ++EXPORT_SYMBOL(PAGE_SHARED_NOEXEC);
2460 ++
2461 + void __init paging_init(void)
2462 + {
2463 + switch(sparc_cpu_model) {
2464 +@@ -338,17 +341,17 @@ void __init paging_init(void)
2465 +
2466 + /* Initialize the protection map with non-constant, MMU dependent values. */
2467 + protection_map[0] = PAGE_NONE;
2468 +- protection_map[1] = PAGE_READONLY;
2469 +- protection_map[2] = PAGE_COPY;
2470 +- protection_map[3] = PAGE_COPY;
2471 ++ protection_map[1] = PAGE_READONLY_NOEXEC;
2472 ++ protection_map[2] = PAGE_COPY_NOEXEC;
2473 ++ protection_map[3] = PAGE_COPY_NOEXEC;
2474 + protection_map[4] = PAGE_READONLY;
2475 + protection_map[5] = PAGE_READONLY;
2476 + protection_map[6] = PAGE_COPY;
2477 + protection_map[7] = PAGE_COPY;
2478 + protection_map[8] = PAGE_NONE;
2479 +- protection_map[9] = PAGE_READONLY;
2480 +- protection_map[10] = PAGE_SHARED;
2481 +- protection_map[11] = PAGE_SHARED;
2482 ++ protection_map[9] = PAGE_READONLY_NOEXEC;
2483 ++ protection_map[10] = PAGE_SHARED_NOEXEC;
2484 ++ protection_map[11] = PAGE_SHARED_NOEXEC;
2485 + protection_map[12] = PAGE_READONLY;
2486 + protection_map[13] = PAGE_READONLY;
2487 + protection_map[14] = PAGE_SHARED;
2488 +diff -urNp linux-2.6.28.8/arch/sparc/mm/srmmu.c linux-2.6.28.8/arch/sparc/mm/srmmu.c
2489 +--- linux-2.6.28.8/arch/sparc/mm/srmmu.c 2009-02-06 16:47:45.000000000 -0500
2490 ++++ linux-2.6.28.8/arch/sparc/mm/srmmu.c 2009-02-21 09:37:48.000000000 -0500
2491 +@@ -2162,6 +2162,13 @@ void __init ld_mmu_srmmu(void)
2492 + PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED);
2493 + BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
2494 + BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
2495 ++
2496 ++#ifdef CONFIG_PAX_PAGEEXEC
2497 ++ PAGE_SHARED_NOEXEC = pgprot_val(SRMMU_PAGE_SHARED_NOEXEC);
2498 ++ BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
2499 ++ BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
2500 ++#endif
2501 ++
2502 + BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
2503 + page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
2504 +
2505 +diff -urNp linux-2.6.28.8/arch/sparc64/kernel/Makefile linux-2.6.28.8/arch/sparc64/kernel/Makefile
2506 +--- linux-2.6.28.8/arch/sparc64/kernel/Makefile 2009-02-06 16:47:45.000000000 -0500
2507 ++++ linux-2.6.28.8/arch/sparc64/kernel/Makefile 2009-02-21 09:37:48.000000000 -0500
2508 +@@ -3,7 +3,7 @@
2509 + #
2510 +
2511 + EXTRA_AFLAGS := -ansi
2512 +-EXTRA_CFLAGS := -Werror
2513 ++#EXTRA_CFLAGS := -Werror
2514 +
2515 + CFLAGS_REMOVE_ftrace.o = -pg
2516 +
2517 +diff -urNp linux-2.6.28.8/arch/sparc64/kernel/sys_sparc.c linux-2.6.28.8/arch/sparc64/kernel/sys_sparc.c
2518 +--- linux-2.6.28.8/arch/sparc64/kernel/sys_sparc.c 2009-02-08 00:54:27.000000000 -0500
2519 ++++ linux-2.6.28.8/arch/sparc64/kernel/sys_sparc.c 2009-02-21 09:37:48.000000000 -0500
2520 +@@ -124,7 +124,7 @@ unsigned long arch_get_unmapped_area(str
2521 + /* We do not accept a shared mapping if it would violate
2522 + * cache aliasing constraints.
2523 + */
2524 +- if ((flags & MAP_SHARED) &&
2525 ++ if ((filp || (flags & MAP_SHARED)) &&
2526 + ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
2527 + return -EINVAL;
2528 + return addr;
2529 +@@ -139,6 +139,10 @@ unsigned long arch_get_unmapped_area(str
2530 + if (filp || (flags & MAP_SHARED))
2531 + do_color_align = 1;
2532 +
2533 ++#ifdef CONFIG_PAX_RANDMMAP
2534 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
2535 ++#endif
2536 ++
2537 + if (addr) {
2538 + if (do_color_align)
2539 + addr = COLOUR_ALIGN(addr, pgoff);
2540 +@@ -152,9 +156,9 @@ unsigned long arch_get_unmapped_area(str
2541 + }
2542 +
2543 + if (len > mm->cached_hole_size) {
2544 +- start_addr = addr = mm->free_area_cache;
2545 ++ start_addr = addr = mm->free_area_cache;
2546 + } else {
2547 +- start_addr = addr = TASK_UNMAPPED_BASE;
2548 ++ start_addr = addr = mm->mmap_base;
2549 + mm->cached_hole_size = 0;
2550 + }
2551 +
2552 +@@ -174,8 +178,8 @@ full_search:
2553 + vma = find_vma(mm, VA_EXCLUDE_END);
2554 + }
2555 + if (unlikely(task_size < addr)) {
2556 +- if (start_addr != TASK_UNMAPPED_BASE) {
2557 +- start_addr = addr = TASK_UNMAPPED_BASE;
2558 ++ if (start_addr != mm->mmap_base) {
2559 ++ start_addr = addr = mm->mmap_base;
2560 + mm->cached_hole_size = 0;
2561 + goto full_search;
2562 + }
2563 +@@ -215,7 +219,7 @@ arch_get_unmapped_area_topdown(struct fi
2564 + /* We do not accept a shared mapping if it would violate
2565 + * cache aliasing constraints.
2566 + */
2567 +- if ((flags & MAP_SHARED) &&
2568 ++ if ((filp || (flags & MAP_SHARED)) &&
2569 + ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
2570 + return -EINVAL;
2571 + return addr;
2572 +@@ -378,6 +382,12 @@ void arch_pick_mmap_layout(struct mm_str
2573 + current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
2574 + sysctl_legacy_va_layout) {
2575 + mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
2576 ++
2577 ++#ifdef CONFIG_PAX_RANDMMAP
2578 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
2579 ++ mm->mmap_base += mm->delta_mmap;
2580 ++#endif
2581 ++
2582 + mm->get_unmapped_area = arch_get_unmapped_area;
2583 + mm->unmap_area = arch_unmap_area;
2584 + } else {
2585 +@@ -392,6 +402,12 @@ void arch_pick_mmap_layout(struct mm_str
2586 + gap = (task_size / 6 * 5);
2587 +
2588 + mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
2589 ++
2590 ++#ifdef CONFIG_PAX_RANDMMAP
2591 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
2592 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
2593 ++#endif
2594 ++
2595 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
2596 + mm->unmap_area = arch_unmap_area_topdown;
2597 + }
2598 +diff -urNp linux-2.6.28.8/arch/sparc64/mm/fault.c linux-2.6.28.8/arch/sparc64/mm/fault.c
2599 +--- linux-2.6.28.8/arch/sparc64/mm/fault.c 2009-02-06 16:47:45.000000000 -0500
2600 ++++ linux-2.6.28.8/arch/sparc64/mm/fault.c 2009-02-21 09:37:48.000000000 -0500
2601 +@@ -19,6 +19,9 @@
2602 + #include <linux/interrupt.h>
2603 + #include <linux/kprobes.h>
2604 + #include <linux/kdebug.h>
2605 ++#include <linux/slab.h>
2606 ++#include <linux/pagemap.h>
2607 ++#include <linux/compiler.h>
2608 +
2609 + #include <asm/page.h>
2610 + #include <asm/pgtable.h>
2611 +@@ -224,6 +227,367 @@ cannot_handle:
2612 + unhandled_fault (address, current, regs);
2613 + }
2614 +
2615 ++#ifdef CONFIG_PAX_PAGEEXEC
2616 ++#ifdef CONFIG_PAX_EMUPLT
2617 ++static void pax_emuplt_close(struct vm_area_struct *vma)
2618 ++{
2619 ++ vma->vm_mm->call_dl_resolve = 0UL;
2620 ++}
2621 ++
2622 ++static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
2623 ++{
2624 ++ unsigned int *kaddr;
2625 ++
2626 ++ vmf->page = alloc_page(GFP_HIGHUSER);
2627 ++ if (!vmf->page)
2628 ++ return VM_FAULT_OOM;
2629 ++
2630 ++ kaddr = kmap(vmf->page);
2631 ++ memset(kaddr, 0, PAGE_SIZE);
2632 ++ kaddr[0] = 0x9DE3BFA8U; /* save */
2633 ++ flush_dcache_page(vmf->page);
2634 ++ kunmap(vmf->page);
2635 ++ return VM_FAULT_MAJOR;
2636 ++}
2637 ++
2638 ++static struct vm_operations_struct pax_vm_ops = {
2639 ++ .close = pax_emuplt_close,
2640 ++ .fault = pax_emuplt_fault
2641 ++};
2642 ++
2643 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2644 ++{
2645 ++ int ret;
2646 ++
2647 ++ vma->vm_mm = current->mm;
2648 ++ vma->vm_start = addr;
2649 ++ vma->vm_end = addr + PAGE_SIZE;
2650 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2651 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
2652 ++ vma->vm_ops = &pax_vm_ops;
2653 ++
2654 ++ ret = insert_vm_struct(current->mm, vma);
2655 ++ if (ret)
2656 ++ return ret;
2657 ++
2658 ++ ++current->mm->total_vm;
2659 ++ return 0;
2660 ++}
2661 ++#endif
2662 ++
2663 ++/*
2664 ++ * PaX: decide what to do with offenders (regs->tpc = fault address)
2665 ++ *
2666 ++ * returns 1 when task should be killed
2667 ++ * 2 when patched PLT trampoline was detected
2668 ++ * 3 when unpatched PLT trampoline was detected
2669 ++ */
2670 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
2671 ++{
2672 ++
2673 ++#ifdef CONFIG_PAX_EMUPLT
2674 ++ int err;
2675 ++
2676 ++ do { /* PaX: patched PLT emulation #1 */
2677 ++ unsigned int sethi1, sethi2, jmpl;
2678 ++
2679 ++ err = get_user(sethi1, (unsigned int *)regs->tpc);
2680 ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2681 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+8));
2682 ++
2683 ++ if (err)
2684 ++ break;
2685 ++
2686 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2687 ++ (sethi2 & 0xFFC00000U) == 0x03000000U &&
2688 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U)
2689 ++ {
2690 ++ unsigned long addr;
2691 ++
2692 ++ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
2693 ++ addr = regs->u_regs[UREG_G1];
2694 ++ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
2695 ++ regs->tpc = addr;
2696 ++ regs->tnpc = addr+4;
2697 ++ return 2;
2698 ++ }
2699 ++ } while (0);
2700 ++
2701 ++ { /* PaX: patched PLT emulation #2 */
2702 ++ unsigned int ba;
2703 ++
2704 ++ err = get_user(ba, (unsigned int *)regs->tpc);
2705 ++
2706 ++ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
2707 ++ unsigned long addr;
2708 ++
2709 ++ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
2710 ++ regs->tpc = addr;
2711 ++ regs->tnpc = addr+4;
2712 ++ return 2;
2713 ++ }
2714 ++ }
2715 ++
2716 ++ do { /* PaX: patched PLT emulation #3 */
2717 ++ unsigned int sethi, jmpl, nop;
2718 ++
2719 ++ err = get_user(sethi, (unsigned int *)regs->tpc);
2720 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+4));
2721 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2722 ++
2723 ++ if (err)
2724 ++ break;
2725 ++
2726 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
2727 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
2728 ++ nop == 0x01000000U)
2729 ++ {
2730 ++ unsigned long addr;
2731 ++
2732 ++ addr = (sethi & 0x003FFFFFU) << 10;
2733 ++ regs->u_regs[UREG_G1] = addr;
2734 ++ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
2735 ++ regs->tpc = addr;
2736 ++ regs->tnpc = addr+4;
2737 ++ return 2;
2738 ++ }
2739 ++ } while (0);
2740 ++
2741 ++ do { /* PaX: patched PLT emulation #4 */
2742 ++ unsigned int mov1, call, mov2;
2743 ++
2744 ++ err = get_user(mov1, (unsigned int *)regs->tpc);
2745 ++ err |= get_user(call, (unsigned int *)(regs->tpc+4));
2746 ++ err |= get_user(mov2, (unsigned int *)(regs->tpc+8));
2747 ++
2748 ++ if (err)
2749 ++ break;
2750 ++
2751 ++ if (mov1 == 0x8210000FU &&
2752 ++ (call & 0xC0000000U) == 0x40000000U &&
2753 ++ mov2 == 0x9E100001U)
2754 ++ {
2755 ++ unsigned long addr;
2756 ++
2757 ++ regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
2758 ++ addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
2759 ++ regs->tpc = addr;
2760 ++ regs->tnpc = addr+4;
2761 ++ return 2;
2762 ++ }
2763 ++ } while (0);
2764 ++
2765 ++ do { /* PaX: patched PLT emulation #5 */
2766 ++ unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
2767 ++
2768 ++ err = get_user(sethi1, (unsigned int *)regs->tpc);
2769 ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2770 ++ err |= get_user(or1, (unsigned int *)(regs->tpc+8));
2771 ++ err |= get_user(or2, (unsigned int *)(regs->tpc+12));
2772 ++ err |= get_user(sllx, (unsigned int *)(regs->tpc+16));
2773 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+20));
2774 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+24));
2775 ++
2776 ++ if (err)
2777 ++ break;
2778 ++
2779 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2780 ++ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
2781 ++ (or1 & 0xFFFFE000U) == 0x82106000U &&
2782 ++ (or2 & 0xFFFFE000U) == 0x8A116000U &&
2783 ++ sllx == 0x83287020 &&
2784 ++ jmpl == 0x81C04005U &&
2785 ++ nop == 0x01000000U)
2786 ++ {
2787 ++ unsigned long addr;
2788 ++
2789 ++ regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
2790 ++ regs->u_regs[UREG_G1] <<= 32;
2791 ++ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
2792 ++ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
2793 ++ regs->tpc = addr;
2794 ++ regs->tnpc = addr+4;
2795 ++ return 2;
2796 ++ }
2797 ++ } while (0);
2798 ++
2799 ++ do { /* PaX: patched PLT emulation #6 */
2800 ++ unsigned int sethi1, sethi2, sllx, or, jmpl, nop;
2801 ++
2802 ++ err = get_user(sethi1, (unsigned int *)regs->tpc);
2803 ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2804 ++ err |= get_user(sllx, (unsigned int *)(regs->tpc+8));
2805 ++ err |= get_user(or, (unsigned int *)(regs->tpc+12));
2806 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+16));
2807 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+20));
2808 ++
2809 ++ if (err)
2810 ++ break;
2811 ++
2812 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2813 ++ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
2814 ++ sllx == 0x83287020 &&
2815 ++ (or & 0xFFFFE000U) == 0x8A116000U &&
2816 ++ jmpl == 0x81C04005U &&
2817 ++ nop == 0x01000000U)
2818 ++ {
2819 ++ unsigned long addr;
2820 ++
2821 ++ regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
2822 ++ regs->u_regs[UREG_G1] <<= 32;
2823 ++ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
2824 ++ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
2825 ++ regs->tpc = addr;
2826 ++ regs->tnpc = addr+4;
2827 ++ return 2;
2828 ++ }
2829 ++ } while (0);
2830 ++
2831 ++ do { /* PaX: patched PLT emulation #7 */
2832 ++ unsigned int sethi, ba, nop;
2833 ++
2834 ++ err = get_user(sethi, (unsigned int *)regs->tpc);
2835 ++ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
2836 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2837 ++
2838 ++ if (err)
2839 ++ break;
2840 ++
2841 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
2842 ++ (ba & 0xFFF00000U) == 0x30600000U &&
2843 ++ nop == 0x01000000U)
2844 ++ {
2845 ++ unsigned long addr;
2846 ++
2847 ++ addr = (sethi & 0x003FFFFFU) << 10;
2848 ++ regs->u_regs[UREG_G1] = addr;
2849 ++ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
2850 ++ regs->tpc = addr;
2851 ++ regs->tnpc = addr+4;
2852 ++ return 2;
2853 ++ }
2854 ++ } while (0);
2855 ++
2856 ++ do { /* PaX: unpatched PLT emulation step 1 */
2857 ++ unsigned int sethi, ba, nop;
2858 ++
2859 ++ err = get_user(sethi, (unsigned int *)regs->tpc);
2860 ++ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
2861 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2862 ++
2863 ++ if (err)
2864 ++ break;
2865 ++
2866 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
2867 ++ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
2868 ++ nop == 0x01000000U)
2869 ++ {
2870 ++ unsigned long addr;
2871 ++ unsigned int save, call;
2872 ++
2873 ++ if ((ba & 0xFFC00000U) == 0x30800000U)
2874 ++ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
2875 ++ else
2876 ++ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
2877 ++
2878 ++ err = get_user(save, (unsigned int *)addr);
2879 ++ err |= get_user(call, (unsigned int *)(addr+4));
2880 ++ err |= get_user(nop, (unsigned int *)(addr+8));
2881 ++ if (err)
2882 ++ break;
2883 ++
2884 ++ if (save == 0x9DE3BFA8U &&
2885 ++ (call & 0xC0000000U) == 0x40000000U &&
2886 ++ nop == 0x01000000U)
2887 ++ {
2888 ++ struct vm_area_struct *vma;
2889 ++ unsigned long call_dl_resolve;
2890 ++
2891 ++ down_read(&current->mm->mmap_sem);
2892 ++ call_dl_resolve = current->mm->call_dl_resolve;
2893 ++ up_read(&current->mm->mmap_sem);
2894 ++ if (likely(call_dl_resolve))
2895 ++ goto emulate;
2896 ++
2897 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
2898 ++
2899 ++ down_write(&current->mm->mmap_sem);
2900 ++ if (current->mm->call_dl_resolve) {
2901 ++ call_dl_resolve = current->mm->call_dl_resolve;
2902 ++ up_write(&current->mm->mmap_sem);
2903 ++ if (vma)
2904 ++ kmem_cache_free(vm_area_cachep, vma);
2905 ++ goto emulate;
2906 ++ }
2907 ++
2908 ++ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2909 ++ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
2910 ++ up_write(&current->mm->mmap_sem);
2911 ++ if (vma)
2912 ++ kmem_cache_free(vm_area_cachep, vma);
2913 ++ return 1;
2914 ++ }
2915 ++
2916 ++ if (pax_insert_vma(vma, call_dl_resolve)) {
2917 ++ up_write(&current->mm->mmap_sem);
2918 ++ kmem_cache_free(vm_area_cachep, vma);
2919 ++ return 1;
2920 ++ }
2921 ++
2922 ++ current->mm->call_dl_resolve = call_dl_resolve;
2923 ++ up_write(&current->mm->mmap_sem);
2924 ++
2925 ++emulate:
2926 ++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
2927 ++ regs->tpc = call_dl_resolve;
2928 ++ regs->tnpc = addr+4;
2929 ++ return 3;
2930 ++ }
2931 ++ }
2932 ++ } while (0);
2933 ++
2934 ++ do { /* PaX: unpatched PLT emulation step 2 */
2935 ++ unsigned int save, call, nop;
2936 ++
2937 ++ err = get_user(save, (unsigned int *)(regs->tpc-4));
2938 ++ err |= get_user(call, (unsigned int *)regs->tpc);
2939 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+4));
2940 ++ if (err)
2941 ++ break;
2942 ++
2943 ++ if (save == 0x9DE3BFA8U &&
2944 ++ (call & 0xC0000000U) == 0x40000000U &&
2945 ++ nop == 0x01000000U)
2946 ++ {
2947 ++ unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
2948 ++
2949 ++ regs->u_regs[UREG_RETPC] = regs->tpc;
2950 ++ regs->tpc = dl_resolve;
2951 ++ regs->tnpc = dl_resolve+4;
2952 ++ return 3;
2953 ++ }
2954 ++ } while (0);
2955 ++#endif
2956 ++
2957 ++ return 1;
2958 ++}
2959 ++
2960 ++void pax_report_insns(void *pc, void *sp)
2961 ++{
2962 ++ unsigned long i;
2963 ++
2964 ++ printk(KERN_ERR "PAX: bytes at PC: ");
2965 ++ for (i = 0; i < 5; i++) {
2966 ++ unsigned int c;
2967 ++ if (get_user(c, (unsigned int *)pc+i))
2968 ++ printk(KERN_CONT "???????? ");
2969 ++ else
2970 ++ printk(KERN_CONT "%08x ", c);
2971 ++ }
2972 ++ printk("\n");
2973 ++}
2974 ++#endif
2975 ++
2976 + asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
2977 + {
2978 + struct mm_struct *mm = current->mm;
2979 +@@ -265,8 +629,10 @@ asmlinkage void __kprobes do_sparc64_fau
2980 + goto intr_or_no_mm;
2981 +
2982 + if (test_thread_flag(TIF_32BIT)) {
2983 +- if (!(regs->tstate & TSTATE_PRIV))
2984 ++ if (!(regs->tstate & TSTATE_PRIV)) {
2985 + regs->tpc &= 0xffffffff;
2986 ++ regs->tnpc &= 0xffffffff;
2987 ++ }
2988 + address &= 0xffffffff;
2989 + }
2990 +
2991 +@@ -283,6 +649,29 @@ asmlinkage void __kprobes do_sparc64_fau
2992 + if (!vma)
2993 + goto bad_area;
2994 +
2995 ++#ifdef CONFIG_PAX_PAGEEXEC
2996 ++ /* PaX: detect ITLB misses on non-exec pages */
2997 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
2998 ++ !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
2999 ++ {
3000 ++ if (address != regs->tpc)
3001 ++ goto good_area;
3002 ++
3003 ++ up_read(&mm->mmap_sem);
3004 ++ switch (pax_handle_fetch_fault(regs)) {
3005 ++
3006 ++#ifdef CONFIG_PAX_EMUPLT
3007 ++ case 2:
3008 ++ case 3:
3009 ++ return;
3010 ++#endif
3011 ++
3012 ++ }
3013 ++ pax_report_fault(regs, (void *)regs->tpc, (void *)(regs->u_regs[UREG_FP] + STACK_BIAS));
3014 ++ do_group_exit(SIGKILL);
3015 ++ }
3016 ++#endif
3017 ++
3018 + /* Pure DTLB misses do not tell us whether the fault causing
3019 + * load/store/atomic was a write or not, it only says that there
3020 + * was no match. So in such a case we (carefully) read the
3021 +diff -urNp linux-2.6.28.8/arch/sparc64/mm/Makefile linux-2.6.28.8/arch/sparc64/mm/Makefile
3022 +--- linux-2.6.28.8/arch/sparc64/mm/Makefile 2009-02-06 16:47:45.000000000 -0500
3023 ++++ linux-2.6.28.8/arch/sparc64/mm/Makefile 2009-02-21 09:37:48.000000000 -0500
3024 +@@ -2,7 +2,7 @@
3025 + #
3026 +
3027 + EXTRA_AFLAGS := -ansi
3028 +-EXTRA_CFLAGS := -Werror
3029 ++#EXTRA_CFLAGS := -Werror
3030 +
3031 + obj-y := ultra.o tlb.o tsb.o fault.o init.o generic.o
3032 +
3033 +diff -urNp linux-2.6.28.8/arch/um/include/asm/kmap_types.h linux-2.6.28.8/arch/um/include/asm/kmap_types.h
3034 +--- linux-2.6.28.8/arch/um/include/asm/kmap_types.h 2009-02-06 16:47:45.000000000 -0500
3035 ++++ linux-2.6.28.8/arch/um/include/asm/kmap_types.h 2009-02-21 09:37:48.000000000 -0500
3036 +@@ -23,6 +23,7 @@ enum km_type {
3037 + KM_IRQ1,
3038 + KM_SOFTIRQ0,
3039 + KM_SOFTIRQ1,
3040 ++ KM_CLEARPAGE,
3041 + KM_TYPE_NR
3042 + };
3043 +
3044 +diff -urNp linux-2.6.28.8/arch/um/include/asm/page.h linux-2.6.28.8/arch/um/include/asm/page.h
3045 +--- linux-2.6.28.8/arch/um/include/asm/page.h 2009-02-06 16:47:45.000000000 -0500
3046 ++++ linux-2.6.28.8/arch/um/include/asm/page.h 2009-02-21 09:37:48.000000000 -0500
3047 +@@ -14,6 +14,9 @@
3048 + #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
3049 + #define PAGE_MASK (~(PAGE_SIZE-1))
3050 +
3051 ++#define ktla_ktva(addr) (addr)
3052 ++#define ktva_ktla(addr) (addr)
3053 ++
3054 + #ifndef __ASSEMBLY__
3055 +
3056 + struct page;
3057 +diff -urNp linux-2.6.28.8/arch/um/sys-i386/syscalls.c linux-2.6.28.8/arch/um/sys-i386/syscalls.c
3058 +--- linux-2.6.28.8/arch/um/sys-i386/syscalls.c 2009-02-06 16:47:45.000000000 -0500
3059 ++++ linux-2.6.28.8/arch/um/sys-i386/syscalls.c 2009-02-21 09:37:48.000000000 -0500
3060 +@@ -11,6 +11,21 @@
3061 + #include "asm/uaccess.h"
3062 + #include "asm/unistd.h"
3063 +
3064 ++int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
3065 ++{
3066 ++ unsigned long pax_task_size = TASK_SIZE;
3067 ++
3068 ++#ifdef CONFIG_PAX_SEGMEXEC
3069 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
3070 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
3071 ++#endif
3072 ++
3073 ++ if (len > pax_task_size || addr > pax_task_size - len)
3074 ++ return -EINVAL;
3075 ++
3076 ++ return 0;
3077 ++}
3078 ++
3079 + /*
3080 + * Perform the select(nd, in, out, ex, tv) and mmap() system
3081 + * calls. Linux/i386 didn't use to be able to handle more than
3082 +diff -urNp linux-2.6.28.8/arch/x86/boot/bitops.h linux-2.6.28.8/arch/x86/boot/bitops.h
3083 +--- linux-2.6.28.8/arch/x86/boot/bitops.h 2009-02-06 16:47:45.000000000 -0500
3084 ++++ linux-2.6.28.8/arch/x86/boot/bitops.h 2009-02-21 09:37:48.000000000 -0500
3085 +@@ -26,7 +26,7 @@ static inline int variable_test_bit(int
3086 + u8 v;
3087 + const u32 *p = (const u32 *)addr;
3088 +
3089 +- asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
3090 ++ asm volatile("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
3091 + return v;
3092 + }
3093 +
3094 +@@ -37,7 +37,7 @@ static inline int variable_test_bit(int
3095 +
3096 + static inline void set_bit(int nr, void *addr)
3097 + {
3098 +- asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
3099 ++ asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
3100 + }
3101 +
3102 + #endif /* BOOT_BITOPS_H */
3103 +diff -urNp linux-2.6.28.8/arch/x86/boot/boot.h linux-2.6.28.8/arch/x86/boot/boot.h
3104 +--- linux-2.6.28.8/arch/x86/boot/boot.h 2009-02-06 16:47:45.000000000 -0500
3105 ++++ linux-2.6.28.8/arch/x86/boot/boot.h 2009-02-21 09:37:48.000000000 -0500
3106 +@@ -80,7 +80,7 @@ static inline void io_delay(void)
3107 + static inline u16 ds(void)
3108 + {
3109 + u16 seg;
3110 +- asm("movw %%ds,%0" : "=rm" (seg));
3111 ++ asm volatile("movw %%ds,%0" : "=rm" (seg));
3112 + return seg;
3113 + }
3114 +
3115 +@@ -176,7 +176,7 @@ static inline void wrgs32(u32 v, addr_t
3116 + static inline int memcmp(const void *s1, const void *s2, size_t len)
3117 + {
3118 + u8 diff;
3119 +- asm("repe; cmpsb; setnz %0"
3120 ++ asm volatile("repe; cmpsb; setnz %0"
3121 + : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
3122 + return diff;
3123 + }
3124 +diff -urNp linux-2.6.28.8/arch/x86/boot/compressed/head_32.S linux-2.6.28.8/arch/x86/boot/compressed/head_32.S
3125 +--- linux-2.6.28.8/arch/x86/boot/compressed/head_32.S 2009-02-06 16:47:45.000000000 -0500
3126 ++++ linux-2.6.28.8/arch/x86/boot/compressed/head_32.S 2009-03-07 10:28:24.000000000 -0500
3127 +@@ -70,7 +70,7 @@ startup_32:
3128 + addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebx
3129 + andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebx
3130 + #else
3131 +- movl $LOAD_PHYSICAL_ADDR, %ebx
3132 ++ movl $____LOAD_PHYSICAL_ADDR, %ebx
3133 + #endif
3134 +
3135 + /* Replace the compressed data size with the uncompressed size */
3136 +@@ -80,8 +80,8 @@ startup_32:
3137 + /* Add 8 bytes for every 32K input block */
3138 + shrl $12, %eax
3139 + addl %eax, %ebx
3140 +- /* Add 32K + 18 bytes of extra slack */
3141 +- addl $(32768 + 18), %ebx
3142 ++ /* Add 64K of extra slack */
3143 ++ addl $65536, %ebx
3144 + /* Align on a 4K boundary */
3145 + addl $4095, %ebx
3146 + andl $~4095, %ebx
3147 +@@ -105,7 +105,7 @@ startup_32:
3148 + addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebp
3149 + andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebp
3150 + #else
3151 +- movl $LOAD_PHYSICAL_ADDR, %ebp
3152 ++ movl $____LOAD_PHYSICAL_ADDR, %ebp
3153 + #endif
3154 +
3155 + /*
3156 +@@ -160,16 +160,15 @@ relocated:
3157 + * and where it was actually loaded.
3158 + */
3159 + movl %ebp, %ebx
3160 +- subl $LOAD_PHYSICAL_ADDR, %ebx
3161 ++ subl $____LOAD_PHYSICAL_ADDR, %ebx
3162 + jz 2f /* Nothing to be done if loaded at compiled addr. */
3163 + /*
3164 + * Process relocations.
3165 + */
3166 +
3167 + 1: subl $4, %edi
3168 +- movl 0(%edi), %ecx
3169 +- testl %ecx, %ecx
3170 +- jz 2f
3171 ++ movl (%edi), %ecx
3172 ++ jecxz 2f
3173 + addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
3174 + jmp 1b
3175 + 2:
3176 +diff -urNp linux-2.6.28.8/arch/x86/boot/compressed/misc.c linux-2.6.28.8/arch/x86/boot/compressed/misc.c
3177 +--- linux-2.6.28.8/arch/x86/boot/compressed/misc.c 2009-02-06 16:47:45.000000000 -0500
3178 ++++ linux-2.6.28.8/arch/x86/boot/compressed/misc.c 2009-02-21 09:37:48.000000000 -0500
3179 +@@ -373,7 +373,7 @@ static void parse_elf(void *output)
3180 + case PT_LOAD:
3181 + #ifdef CONFIG_RELOCATABLE
3182 + dest = output;
3183 +- dest += (phdr->p_paddr - LOAD_PHYSICAL_ADDR);
3184 ++ dest += (phdr->p_paddr - ____LOAD_PHYSICAL_ADDR);
3185 + #else
3186 + dest = (void *)(phdr->p_paddr);
3187 + #endif
3188 +@@ -425,7 +425,7 @@ asmlinkage void decompress_kernel(void *
3189 + if (heap > ((-__PAGE_OFFSET-(512<<20)-1) & 0x7fffffff))
3190 + error("Destination address too large");
3191 + #ifndef CONFIG_RELOCATABLE
3192 +- if ((u32)output != LOAD_PHYSICAL_ADDR)
3193 ++ if ((u32)output != ____LOAD_PHYSICAL_ADDR)
3194 + error("Wrong destination address");
3195 + #endif
3196 + #endif
3197 +diff -urNp linux-2.6.28.8/arch/x86/boot/compressed/relocs.c linux-2.6.28.8/arch/x86/boot/compressed/relocs.c
3198 +--- linux-2.6.28.8/arch/x86/boot/compressed/relocs.c 2009-02-06 16:47:45.000000000 -0500
3199 ++++ linux-2.6.28.8/arch/x86/boot/compressed/relocs.c 2009-02-21 09:37:48.000000000 -0500
3200 +@@ -10,8 +10,11 @@
3201 + #define USE_BSD
3202 + #include <endian.h>
3203 +
3204 ++#include "../../../../include/linux/autoconf.h"
3205 ++
3206 + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
3207 + static Elf32_Ehdr ehdr;
3208 ++static Elf32_Phdr *phdr;
3209 + static unsigned long reloc_count, reloc_idx;
3210 + static unsigned long *relocs;
3211 +
3212 +@@ -245,6 +248,36 @@ static void read_ehdr(FILE *fp)
3213 + }
3214 + }
3215 +
3216 ++static void read_phdrs(FILE *fp)
3217 ++{
3218 ++ int i;
3219 ++
3220 ++ phdr = calloc(ehdr.e_phnum, sizeof(Elf32_Phdr));
3221 ++ if (!phdr) {
3222 ++ die("Unable to allocate %d program headers\n",
3223 ++ ehdr.e_phnum);
3224 ++ }
3225 ++ if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) {
3226 ++ die("Seek to %d failed: %s\n",
3227 ++ ehdr.e_phoff, strerror(errno));
3228 ++ }
3229 ++ if (fread(phdr, sizeof(*phdr), ehdr.e_phnum, fp) != ehdr.e_phnum) {
3230 ++ die("Cannot read ELF program headers: %s\n",
3231 ++ strerror(errno));
3232 ++ }
3233 ++ for(i = 0; i < ehdr.e_phnum; i++) {
3234 ++ phdr[i].p_type = elf32_to_cpu(phdr[i].p_type);
3235 ++ phdr[i].p_offset = elf32_to_cpu(phdr[i].p_offset);
3236 ++ phdr[i].p_vaddr = elf32_to_cpu(phdr[i].p_vaddr);
3237 ++ phdr[i].p_paddr = elf32_to_cpu(phdr[i].p_paddr);
3238 ++ phdr[i].p_filesz = elf32_to_cpu(phdr[i].p_filesz);
3239 ++ phdr[i].p_memsz = elf32_to_cpu(phdr[i].p_memsz);
3240 ++ phdr[i].p_flags = elf32_to_cpu(phdr[i].p_flags);
3241 ++ phdr[i].p_align = elf32_to_cpu(phdr[i].p_align);
3242 ++ }
3243 ++
3244 ++}
3245 ++
3246 + static void read_shdrs(FILE *fp)
3247 + {
3248 + int i;
3249 +@@ -341,6 +374,8 @@ static void read_symtabs(FILE *fp)
3250 + static void read_relocs(FILE *fp)
3251 + {
3252 + int i,j;
3253 ++ uint32_t base;
3254 ++
3255 + for (i = 0; i < ehdr.e_shnum; i++) {
3256 + struct section *sec = &secs[i];
3257 + if (sec->shdr.sh_type != SHT_REL) {
3258 +@@ -360,9 +395,18 @@ static void read_relocs(FILE *fp)
3259 + die("Cannot read symbol table: %s\n",
3260 + strerror(errno));
3261 + }
3262 ++ base = 0;
3263 ++ for (j = 0; j < ehdr.e_phnum; j++) {
3264 ++ if (phdr[j].p_type != PT_LOAD )
3265 ++ continue;
3266 ++ if (secs[sec->shdr.sh_info].shdr.sh_offset < phdr[j].p_offset || secs[sec->shdr.sh_info].shdr.sh_offset >= phdr[j].p_offset + phdr[j].p_filesz)
3267 ++ continue;
3268 ++ base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr;
3269 ++ break;
3270 ++ }
3271 + for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) {
3272 + Elf32_Rel *rel = &sec->reltab[j];
3273 +- rel->r_offset = elf32_to_cpu(rel->r_offset);
3274 ++ rel->r_offset = elf32_to_cpu(rel->r_offset) + base;
3275 + rel->r_info = elf32_to_cpu(rel->r_info);
3276 + }
3277 + }
3278 +@@ -504,6 +548,23 @@ static void walk_relocs(void (*visit)(El
3279 + if (sym->st_shndx == SHN_ABS) {
3280 + continue;
3281 + }
3282 ++ /* Don't relocate actual per-cpu variables, they are absolute indices, not addresses */
3283 ++ if (!strcmp(sec_name(sym->st_shndx), ".data.percpu") && strncmp(sym_name(sym_strtab, sym), "__per_cpu_", 10))
3284 ++ continue;
3285 ++#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32)
3286 ++ /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */
3287 ++ if (!strcmp(sec_name(sym->st_shndx), ".init.text"))
3288 ++ continue;
3289 ++ if (!strcmp(sec_name(sym->st_shndx), ".exit.text"))
3290 ++ continue;
3291 ++ if (!strcmp(sec_name(sym->st_shndx), ".text.head")) {
3292 ++ if (strcmp(sym_name(sym_strtab, sym), "__init_end") &&
3293 ++ strcmp(sym_name(sym_strtab, sym), "KERNEL_TEXT_OFFSET"))
3294 ++ continue;
3295 ++ }
3296 ++ if (!strcmp(sec_name(sym->st_shndx), ".text"))
3297 ++ continue;
3298 ++#endif
3299 + if (r_type == R_386_PC32) {
3300 + /* PC relative relocations don't need to be adjusted */
3301 + }
3302 +@@ -631,6 +692,7 @@ int main(int argc, char **argv)
3303 + fname, strerror(errno));
3304 + }
3305 + read_ehdr(fp);
3306 ++ read_phdrs(fp);
3307 + read_shdrs(fp);
3308 + read_strtabs(fp);
3309 + read_symtabs(fp);
3310 +diff -urNp linux-2.6.28.8/arch/x86/boot/cpucheck.c linux-2.6.28.8/arch/x86/boot/cpucheck.c
3311 +--- linux-2.6.28.8/arch/x86/boot/cpucheck.c 2009-02-06 16:47:45.000000000 -0500
3312 ++++ linux-2.6.28.8/arch/x86/boot/cpucheck.c 2009-02-21 09:37:48.000000000 -0500
3313 +@@ -74,7 +74,7 @@ static int has_fpu(void)
3314 + u16 fcw = -1, fsw = -1;
3315 + u32 cr0;
3316 +
3317 +- asm("movl %%cr0,%0" : "=r" (cr0));
3318 ++ asm volatile("movl %%cr0,%0" : "=r" (cr0));
3319 + if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
3320 + cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
3321 + asm volatile("movl %0,%%cr0" : : "r" (cr0));
3322 +@@ -90,7 +90,7 @@ static int has_eflag(u32 mask)
3323 + {
3324 + u32 f0, f1;
3325 +
3326 +- asm("pushfl ; "
3327 ++ asm volatile("pushfl ; "
3328 + "pushfl ; "
3329 + "popl %0 ; "
3330 + "movl %0,%1 ; "
3331 +@@ -115,7 +115,7 @@ static void get_flags(void)
3332 + set_bit(X86_FEATURE_FPU, cpu.flags);
3333 +
3334 + if (has_eflag(X86_EFLAGS_ID)) {
3335 +- asm("cpuid"
3336 ++ asm volatile("cpuid"
3337 + : "=a" (max_intel_level),
3338 + "=b" (cpu_vendor[0]),
3339 + "=d" (cpu_vendor[1]),
3340 +@@ -124,7 +124,7 @@ static void get_flags(void)
3341 +
3342 + if (max_intel_level >= 0x00000001 &&
3343 + max_intel_level <= 0x0000ffff) {
3344 +- asm("cpuid"
3345 ++ asm volatile("cpuid"
3346 + : "=a" (tfms),
3347 + "=c" (cpu.flags[4]),
3348 + "=d" (cpu.flags[0])
3349 +@@ -136,7 +136,7 @@ static void get_flags(void)
3350 + cpu.model += ((tfms >> 16) & 0xf) << 4;
3351 + }
3352 +
3353 +- asm("cpuid"
3354 ++ asm volatile("cpuid"
3355 + : "=a" (max_amd_level)
3356 + : "a" (0x80000000)
3357 + : "ebx", "ecx", "edx");
3358 +@@ -144,7 +144,7 @@ static void get_flags(void)
3359 + if (max_amd_level >= 0x80000001 &&
3360 + max_amd_level <= 0x8000ffff) {
3361 + u32 eax = 0x80000001;
3362 +- asm("cpuid"
3363 ++ asm volatile("cpuid"
3364 + : "+a" (eax),
3365 + "=c" (cpu.flags[6]),
3366 + "=d" (cpu.flags[1])
3367 +@@ -203,9 +203,9 @@ int check_cpu(int *cpu_level_ptr, int *r
3368 + u32 ecx = MSR_K7_HWCR;
3369 + u32 eax, edx;
3370 +
3371 +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3372 ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3373 + eax &= ~(1 << 15);
3374 +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3375 ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3376 +
3377 + get_flags(); /* Make sure it really did something */
3378 + err = check_flags();
3379 +@@ -218,9 +218,9 @@ int check_cpu(int *cpu_level_ptr, int *r
3380 + u32 ecx = MSR_VIA_FCR;
3381 + u32 eax, edx;
3382 +
3383 +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3384 ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3385 + eax |= (1<<1)|(1<<7);
3386 +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3387 ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3388 +
3389 + set_bit(X86_FEATURE_CX8, cpu.flags);
3390 + err = check_flags();
3391 +@@ -231,12 +231,12 @@ int check_cpu(int *cpu_level_ptr, int *r
3392 + u32 eax, edx;
3393 + u32 level = 1;
3394 +
3395 +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3396 +- asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
3397 +- asm("cpuid"
3398 ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3399 ++ asm volatile("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
3400 ++ asm volatile("cpuid"
3401 + : "+a" (level), "=d" (cpu.flags[0])
3402 + : : "ecx", "ebx");
3403 +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3404 ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3405 +
3406 + err = check_flags();
3407 + }
3408 +diff -urNp linux-2.6.28.8/arch/x86/boot/edd.c linux-2.6.28.8/arch/x86/boot/edd.c
3409 +--- linux-2.6.28.8/arch/x86/boot/edd.c 2009-02-06 16:47:45.000000000 -0500
3410 ++++ linux-2.6.28.8/arch/x86/boot/edd.c 2009-02-21 09:37:48.000000000 -0500
3411 +@@ -81,7 +81,7 @@ static int get_edd_info(u8 devno, struct
3412 + ax = 0x4100;
3413 + bx = EDDMAGIC1;
3414 + dx = devno;
3415 +- asm("pushfl; stc; int $0x13; setc %%al; popfl"
3416 ++ asm volatile("pushfl; stc; int $0x13; setc %%al; popfl"
3417 + : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
3418 + : : "esi", "edi");
3419 +
3420 +@@ -100,7 +100,7 @@ static int get_edd_info(u8 devno, struct
3421 + ei->params.length = sizeof(ei->params);
3422 + ax = 0x4800;
3423 + dx = devno;
3424 +- asm("pushfl; int $0x13; popfl"
3425 ++ asm volatile("pushfl; int $0x13; popfl"
3426 + : "+a" (ax), "+d" (dx), "=m" (ei->params)
3427 + : "S" (&ei->params)
3428 + : "ebx", "ecx", "edi");
3429 +@@ -111,7 +111,7 @@ static int get_edd_info(u8 devno, struct
3430 + ax = 0x0800;
3431 + dx = devno;
3432 + di = 0;
3433 +- asm("pushw %%es; "
3434 ++ asm volatile("pushw %%es; "
3435 + "movw %%di,%%es; "
3436 + "pushfl; stc; int $0x13; setc %%al; popfl; "
3437 + "popw %%es"
3438 +diff -urNp linux-2.6.28.8/arch/x86/boot/main.c linux-2.6.28.8/arch/x86/boot/main.c
3439 +--- linux-2.6.28.8/arch/x86/boot/main.c 2009-02-06 16:47:45.000000000 -0500
3440 ++++ linux-2.6.28.8/arch/x86/boot/main.c 2009-02-21 09:37:48.000000000 -0500
3441 +@@ -78,7 +78,7 @@ static void query_ist(void)
3442 + if (cpu.level < 6)
3443 + return;
3444 +
3445 +- asm("int $0x15"
3446 ++ asm volatile("int $0x15"
3447 + : "=a" (boot_params.ist_info.signature),
3448 + "=b" (boot_params.ist_info.command),
3449 + "=c" (boot_params.ist_info.event),
3450 +diff -urNp linux-2.6.28.8/arch/x86/boot/mca.c linux-2.6.28.8/arch/x86/boot/mca.c
3451 +--- linux-2.6.28.8/arch/x86/boot/mca.c 2009-02-06 16:47:45.000000000 -0500
3452 ++++ linux-2.6.28.8/arch/x86/boot/mca.c 2009-02-21 09:37:48.000000000 -0500
3453 +@@ -19,7 +19,7 @@ int query_mca(void)
3454 + u8 err;
3455 + u16 es, bx, len;
3456 +
3457 +- asm("pushw %%es ; "
3458 ++ asm volatile("pushw %%es ; "
3459 + "int $0x15 ; "
3460 + "setc %0 ; "
3461 + "movw %%es, %1 ; "
3462 +diff -urNp linux-2.6.28.8/arch/x86/boot/memory.c linux-2.6.28.8/arch/x86/boot/memory.c
3463 +--- linux-2.6.28.8/arch/x86/boot/memory.c 2009-02-06 16:47:45.000000000 -0500
3464 ++++ linux-2.6.28.8/arch/x86/boot/memory.c 2009-02-21 09:37:48.000000000 -0500
3465 +@@ -30,7 +30,7 @@ static int detect_memory_e820(void)
3466 + /* Important: %edx is clobbered by some BIOSes,
3467 + so it must be either used for the error output
3468 + or explicitly marked clobbered. */
3469 +- asm("int $0x15; setc %0"
3470 ++ asm volatile("int $0x15; setc %0"
3471 + : "=d" (err), "+b" (next), "=a" (id), "+c" (size),
3472 + "=m" (*desc)
3473 + : "D" (desc), "d" (SMAP), "a" (0xe820));
3474 +@@ -65,7 +65,7 @@ static int detect_memory_e801(void)
3475 +
3476 + bx = cx = dx = 0;
3477 + ax = 0xe801;
3478 +- asm("stc; int $0x15; setc %0"
3479 ++ asm volatile("stc; int $0x15; setc %0"
3480 + : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
3481 +
3482 + if (err)
3483 +@@ -95,7 +95,7 @@ static int detect_memory_88(void)
3484 + u8 err;
3485 +
3486 + ax = 0x8800;
3487 +- asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
3488 ++ asm volatile("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
3489 +
3490 + boot_params.screen_info.ext_mem_k = ax;
3491 +
3492 +diff -urNp linux-2.6.28.8/arch/x86/boot/video.c linux-2.6.28.8/arch/x86/boot/video.c
3493 +--- linux-2.6.28.8/arch/x86/boot/video.c 2009-02-06 16:47:45.000000000 -0500
3494 ++++ linux-2.6.28.8/arch/x86/boot/video.c 2009-02-21 09:37:48.000000000 -0500
3495 +@@ -23,7 +23,7 @@ static void store_cursor_position(void)
3496 +
3497 + ax = 0x0300;
3498 + bx = 0;
3499 +- asm(INT10
3500 ++ asm volatile(INT10
3501 + : "=d" (curpos), "+a" (ax), "+b" (bx)
3502 + : : "ecx", "esi", "edi");
3503 +
3504 +@@ -38,7 +38,7 @@ static void store_video_mode(void)
3505 + /* N.B.: the saving of the video page here is a bit silly,
3506 + since we pretty much assume page 0 everywhere. */
3507 + ax = 0x0f00;
3508 +- asm(INT10
3509 ++ asm volatile(INT10
3510 + : "+a" (ax), "=b" (page)
3511 + : : "ecx", "edx", "esi", "edi");
3512 +
3513 +diff -urNp linux-2.6.28.8/arch/x86/boot/video-vesa.c linux-2.6.28.8/arch/x86/boot/video-vesa.c
3514 +--- linux-2.6.28.8/arch/x86/boot/video-vesa.c 2009-02-06 16:47:45.000000000 -0500
3515 ++++ linux-2.6.28.8/arch/x86/boot/video-vesa.c 2009-02-21 09:37:48.000000000 -0500
3516 +@@ -41,7 +41,7 @@ static int vesa_probe(void)
3517 +
3518 + ax = 0x4f00;
3519 + di = (size_t)&vginfo;
3520 +- asm(INT10
3521 ++ asm volatile(INT10
3522 + : "+a" (ax), "+D" (di), "=m" (vginfo)
3523 + : : "ebx", "ecx", "edx", "esi");
3524 +
3525 +@@ -68,7 +68,7 @@ static int vesa_probe(void)
3526 + ax = 0x4f01;
3527 + cx = mode;
3528 + di = (size_t)&vminfo;
3529 +- asm(INT10
3530 ++ asm volatile(INT10
3531 + : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
3532 + : : "ebx", "edx", "esi");
3533 +
3534 +@@ -120,7 +120,7 @@ static int vesa_set_mode(struct mode_inf
3535 + ax = 0x4f01;
3536 + cx = vesa_mode;
3537 + di = (size_t)&vminfo;
3538 +- asm(INT10
3539 ++ asm volatile(INT10
3540 + : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
3541 + : : "ebx", "edx", "esi");
3542 +
3543 +@@ -202,19 +202,20 @@ static void vesa_dac_set_8bits(void)
3544 + /* Save the VESA protected mode info */
3545 + static void vesa_store_pm_info(void)
3546 + {
3547 +- u16 ax, bx, di, es;
3548 ++ u16 ax, bx, cx, di, es;
3549 +
3550 + ax = 0x4f0a;
3551 +- bx = di = 0;
3552 +- asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
3553 +- : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
3554 +- : : "ecx", "esi");
3555 ++ bx = cx = di = 0;
3556 ++ asm volatile("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
3557 ++ : "=d" (es), "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di)
3558 ++ : : "esi");
3559 +
3560 + if (ax != 0x004f)
3561 + return;
3562 +
3563 + boot_params.screen_info.vesapm_seg = es;
3564 + boot_params.screen_info.vesapm_off = di;
3565 ++ boot_params.screen_info.vesapm_size = cx;
3566 + }
3567 +
3568 + /*
3569 +@@ -268,7 +269,7 @@ void vesa_store_edid(void)
3570 + /* Note: The VBE DDC spec is different from the main VESA spec;
3571 + we genuinely have to assume all registers are destroyed here. */
3572 +
3573 +- asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
3574 ++ asm volatile("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
3575 + : "+a" (ax), "+b" (bx)
3576 + : "c" (cx), "D" (di)
3577 + : "esi");
3578 +@@ -284,7 +285,7 @@ void vesa_store_edid(void)
3579 + cx = 0; /* Controller 0 */
3580 + dx = 0; /* EDID block number */
3581 + di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
3582 +- asm(INT10
3583 ++ asm volatile(INT10
3584 + : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info)
3585 + : "c" (cx), "D" (di)
3586 + : "esi");
3587 +diff -urNp linux-2.6.28.8/arch/x86/boot/video-vga.c linux-2.6.28.8/arch/x86/boot/video-vga.c
3588 +--- linux-2.6.28.8/arch/x86/boot/video-vga.c 2009-02-06 16:47:45.000000000 -0500
3589 ++++ linux-2.6.28.8/arch/x86/boot/video-vga.c 2009-02-21 09:37:48.000000000 -0500
3590 +@@ -225,7 +225,7 @@ static int vga_probe(void)
3591 + };
3592 + u8 vga_flag;
3593 +
3594 +- asm(INT10
3595 ++ asm volatile(INT10
3596 + : "=b" (ega_bx)
3597 + : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
3598 + : "ecx", "edx", "esi", "edi");
3599 +@@ -237,7 +237,7 @@ static int vga_probe(void)
3600 + /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
3601 + if ((u8)ega_bx != 0x10) {
3602 + /* EGA/VGA */
3603 +- asm(INT10
3604 ++ asm volatile(INT10
3605 + : "=a" (vga_flag)
3606 + : "a" (0x1a00)
3607 + : "ebx", "ecx", "edx", "esi", "edi");
3608 +diff -urNp linux-2.6.28.8/arch/x86/boot/voyager.c linux-2.6.28.8/arch/x86/boot/voyager.c
3609 +--- linux-2.6.28.8/arch/x86/boot/voyager.c 2009-02-06 16:47:45.000000000 -0500
3610 ++++ linux-2.6.28.8/arch/x86/boot/voyager.c 2009-02-21 09:37:48.000000000 -0500
3611 +@@ -23,7 +23,7 @@ int query_voyager(void)
3612 +
3613 + data_ptr[0] = 0xff; /* Flag on config not found(?) */
3614 +
3615 +- asm("pushw %%es ; "
3616 ++ asm volatile("pushw %%es ; "
3617 + "int $0x15 ; "
3618 + "setc %0 ; "
3619 + "movw %%es, %1 ; "
3620 +diff -urNp linux-2.6.28.8/arch/x86/ia32/ia32_signal.c linux-2.6.28.8/arch/x86/ia32/ia32_signal.c
3621 +--- linux-2.6.28.8/arch/x86/ia32/ia32_signal.c 2009-02-06 16:47:45.000000000 -0500
3622 ++++ linux-2.6.28.8/arch/x86/ia32/ia32_signal.c 2009-02-21 09:37:48.000000000 -0500
3623 +@@ -518,6 +518,7 @@ int ia32_setup_rt_frame(int sig, struct
3624 + __NR_ia32_rt_sigreturn,
3625 + 0x80cd,
3626 + 0,
3627 ++ 0
3628 + };
3629 +
3630 + frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
3631 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/alternative.h linux-2.6.28.8/arch/x86/include/asm/alternative.h
3632 +--- linux-2.6.28.8/arch/x86/include/asm/alternative.h 2009-02-06 16:47:45.000000000 -0500
3633 ++++ linux-2.6.28.8/arch/x86/include/asm/alternative.h 2009-02-21 09:37:48.000000000 -0500
3634 +@@ -96,7 +96,7 @@ const unsigned char *const *find_nop_tab
3635 + " .byte 662b-661b\n" /* sourcelen */ \
3636 + " .byte 664f-663f\n" /* replacementlen */ \
3637 + ".previous\n" \
3638 +- ".section .altinstr_replacement,\"ax\"\n" \
3639 ++ ".section .altinstr_replacement,\"a\"\n" \
3640 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
3641 + ".previous" :: "i" (feature) : "memory")
3642 +
3643 +@@ -120,7 +120,7 @@ const unsigned char *const *find_nop_tab
3644 + " .byte 662b-661b\n" /* sourcelen */ \
3645 + " .byte 664f-663f\n" /* replacementlen */ \
3646 + ".previous\n" \
3647 +- ".section .altinstr_replacement,\"ax\"\n" \
3648 ++ ".section .altinstr_replacement,\"a\"\n" \
3649 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
3650 + ".previous" :: "i" (feature), ##input)
3651 +
3652 +@@ -135,7 +135,7 @@ const unsigned char *const *find_nop_tab
3653 + " .byte 662b-661b\n" /* sourcelen */ \
3654 + " .byte 664f-663f\n" /* replacementlen */ \
3655 + ".previous\n" \
3656 +- ".section .altinstr_replacement,\"ax\"\n" \
3657 ++ ".section .altinstr_replacement,\"a\"\n" \
3658 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
3659 + ".previous" : output : [feat] "i" (feature), ##input)
3660 +
3661 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/atomic_32.h linux-2.6.28.8/arch/x86/include/asm/atomic_32.h
3662 +--- linux-2.6.28.8/arch/x86/include/asm/atomic_32.h 2009-02-06 16:47:45.000000000 -0500
3663 ++++ linux-2.6.28.8/arch/x86/include/asm/atomic_32.h 2009-02-21 09:37:48.000000000 -0500
3664 +@@ -47,7 +47,29 @@ typedef struct {
3665 + */
3666 + static inline void atomic_add(int i, atomic_t *v)
3667 + {
3668 +- asm volatile(LOCK_PREFIX "addl %1,%0"
3669 ++ asm volatile(LOCK_PREFIX "addl %1,%0\n"
3670 ++
3671 ++#ifdef CONFIG_PAX_REFCOUNT
3672 ++ "jno 0f\n"
3673 ++ LOCK_PREFIX "subl %1,%0\n"
3674 ++ "into\n0:\n"
3675 ++ _ASM_EXTABLE(0b, 0b)
3676 ++#endif
3677 ++
3678 ++ : "+m" (v->counter)
3679 ++ : "ir" (i));
3680 ++}
3681 ++
3682 ++/**
3683 ++ * atomic_add_unchecked - add integer to atomic variable
3684 ++ * @i: integer value to add
3685 ++ * @v: pointer of type atomic_t
3686 ++ *
3687 ++ * Atomically adds @i to @v.
3688 ++ */
3689 ++static inline void atomic_add_unchecked(int i, atomic_t *v)
3690 ++{
3691 ++ asm volatile(LOCK_PREFIX "addl %1,%0\n"
3692 + : "+m" (v->counter)
3693 + : "ir" (i));
3694 + }
3695 +@@ -61,7 +83,15 @@ static inline void atomic_add(int i, ato
3696 + */
3697 + static inline void atomic_sub(int i, atomic_t *v)
3698 + {
3699 +- asm volatile(LOCK_PREFIX "subl %1,%0"
3700 ++ asm volatile(LOCK_PREFIX "subl %1,%0\n"
3701 ++
3702 ++#ifdef CONFIG_PAX_REFCOUNT
3703 ++ "jno 0f\n"
3704 ++ LOCK_PREFIX "addl %1,%0\n"
3705 ++ "into\n0:\n"
3706 ++ _ASM_EXTABLE(0b, 0b)
3707 ++#endif
3708 ++
3709 + : "+m" (v->counter)
3710 + : "ir" (i));
3711 + }
3712 +@@ -79,7 +109,16 @@ static inline int atomic_sub_and_test(in
3713 + {
3714 + unsigned char c;
3715 +
3716 +- asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
3717 ++ asm volatile(LOCK_PREFIX "subl %2,%0\n"
3718 ++
3719 ++#ifdef CONFIG_PAX_REFCOUNT
3720 ++ "jno 0f\n"
3721 ++ LOCK_PREFIX "addl %2,%0\n"
3722 ++ "into\n0:\n"
3723 ++ _ASM_EXTABLE(0b, 0b)
3724 ++#endif
3725 ++
3726 ++ "sete %1\n"
3727 + : "+m" (v->counter), "=qm" (c)
3728 + : "ir" (i) : "memory");
3729 + return c;
3730 +@@ -93,7 +132,18 @@ static inline int atomic_sub_and_test(in
3731 + */
3732 + static inline void atomic_inc(atomic_t *v)
3733 + {
3734 +- asm volatile(LOCK_PREFIX "incl %0"
3735 ++ asm volatile(LOCK_PREFIX "incl %0\n"
3736 ++
3737 ++#ifdef CONFIG_PAX_REFCOUNT
3738 ++ "into\n0:\n"
3739 ++ ".pushsection .fixup,\"ax\"\n"
3740 ++ "1:\n"
3741 ++ LOCK_PREFIX "decl %0\n"
3742 ++ "jmp 0b\n"
3743 ++ ".popsection\n"
3744 ++ _ASM_EXTABLE(0b, 1b)
3745 ++#endif
3746 ++
3747 + : "+m" (v->counter));
3748 + }
3749 +
3750 +@@ -105,7 +155,18 @@ static inline void atomic_inc(atomic_t *
3751 + */
3752 + static inline void atomic_dec(atomic_t *v)
3753 + {
3754 +- asm volatile(LOCK_PREFIX "decl %0"
3755 ++ asm volatile(LOCK_PREFIX "decl %0\n"
3756 ++
3757 ++#ifdef CONFIG_PAX_REFCOUNT
3758 ++ "into\n0:\n"
3759 ++ ".pushsection .fixup,\"ax\"\n"
3760 ++ "1: \n"
3761 ++ LOCK_PREFIX "incl %0\n"
3762 ++ "jmp 0b\n"
3763 ++ ".popsection\n"
3764 ++ _ASM_EXTABLE(0b, 1b)
3765 ++#endif
3766 ++
3767 + : "+m" (v->counter));
3768 + }
3769 +
3770 +@@ -121,7 +182,19 @@ static inline int atomic_dec_and_test(at
3771 + {
3772 + unsigned char c;
3773 +
3774 +- asm volatile(LOCK_PREFIX "decl %0; sete %1"
3775 ++ asm volatile(LOCK_PREFIX "decl %0\n"
3776 ++
3777 ++#ifdef CONFIG_PAX_REFCOUNT
3778 ++ "into\n0:\n"
3779 ++ ".pushsection .fixup,\"ax\"\n"
3780 ++ "1: \n"
3781 ++ LOCK_PREFIX "incl %0\n"
3782 ++ "jmp 0b\n"
3783 ++ ".popsection\n"
3784 ++ _ASM_EXTABLE(0b, 1b)
3785 ++#endif
3786 ++
3787 ++ "sete %1\n"
3788 + : "+m" (v->counter), "=qm" (c)
3789 + : : "memory");
3790 + return c != 0;
3791 +@@ -139,7 +212,19 @@ static inline int atomic_inc_and_test(at
3792 + {
3793 + unsigned char c;
3794 +
3795 +- asm volatile(LOCK_PREFIX "incl %0; sete %1"
3796 ++ asm volatile(LOCK_PREFIX "incl %0\n"
3797 ++
3798 ++#ifdef CONFIG_PAX_REFCOUNT
3799 ++ "into\n0:\n"
3800 ++ ".pushsection .fixup,\"ax\"\n"
3801 ++ "1: \n"
3802 ++ LOCK_PREFIX "decl %0\n"
3803 ++ "jmp 0b\n"
3804 ++ ".popsection\n"
3805 ++ _ASM_EXTABLE(0b, 1b)
3806 ++#endif
3807 ++
3808 ++ "sete %1\n"
3809 + : "+m" (v->counter), "=qm" (c)
3810 + : : "memory");
3811 + return c != 0;
3812 +@@ -158,7 +243,16 @@ static inline int atomic_add_negative(in
3813 + {
3814 + unsigned char c;
3815 +
3816 +- asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
3817 ++ asm volatile(LOCK_PREFIX "addl %2,%0\n"
3818 ++
3819 ++#ifdef CONFIG_PAX_REFCOUNT
3820 ++ "jno 0f\n"
3821 ++ LOCK_PREFIX "subl %2,%0\n"
3822 ++ "into\n0:\n"
3823 ++ _ASM_EXTABLE(0b, 0b)
3824 ++#endif
3825 ++
3826 ++ "sets %1\n"
3827 + : "+m" (v->counter), "=qm" (c)
3828 + : "ir" (i) : "memory");
3829 + return c;
3830 +@@ -181,7 +275,15 @@ static inline int atomic_add_return(int
3831 + #endif
3832 + /* Modern 486+ processor */
3833 + __i = i;
3834 +- asm volatile(LOCK_PREFIX "xaddl %0, %1"
3835 ++ asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
3836 ++
3837 ++#ifdef CONFIG_PAX_REFCOUNT
3838 ++ "jno 0f\n"
3839 ++ "movl %0, %1\n"
3840 ++ "into\n0:\n"
3841 ++ _ASM_EXTABLE(0b, 0b)
3842 ++#endif
3843 ++
3844 + : "+r" (i), "+m" (v->counter)
3845 + : : "memory");
3846 + return i + __i;
3847 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/atomic_64.h linux-2.6.28.8/arch/x86/include/asm/atomic_64.h
3848 +--- linux-2.6.28.8/arch/x86/include/asm/atomic_64.h 2009-02-06 16:47:45.000000000 -0500
3849 ++++ linux-2.6.28.8/arch/x86/include/asm/atomic_64.h 2009-02-21 09:37:48.000000000 -0500
3850 +@@ -48,7 +48,29 @@ typedef struct {
3851 + */
3852 + static inline void atomic_add(int i, atomic_t *v)
3853 + {
3854 +- asm volatile(LOCK_PREFIX "addl %1,%0"
3855 ++ asm volatile(LOCK_PREFIX "addl %1,%0\n"
3856 ++
3857 ++#ifdef CONFIG_PAX_REFCOUNT
3858 ++ "jno 0f\n"
3859 ++ LOCK_PREFIX "subl %1,%0\n"
3860 ++ "int $4\n0:\n"
3861 ++ _ASM_EXTABLE(0b, 0b)
3862 ++#endif
3863 ++
3864 ++ : "=m" (v->counter)
3865 ++ : "ir" (i), "m" (v->counter));
3866 ++}
3867 ++
3868 ++/**
3869 ++ * atomic_add_unchecked - add integer to atomic variable
3870 ++ * @i: integer value to add
3871 ++ * @v: pointer of type atomic_t
3872 ++ *
3873 ++ * Atomically adds @i to @v.
3874 ++ */
3875 ++static inline void atomic_add_unchecked(int i, atomic_t *v)
3876 ++{
3877 ++ asm volatile(LOCK_PREFIX "addl %1,%0\n"
3878 + : "=m" (v->counter)
3879 + : "ir" (i), "m" (v->counter));
3880 + }
3881 +@@ -62,7 +84,15 @@ static inline void atomic_add(int i, ato
3882 + */
3883 + static inline void atomic_sub(int i, atomic_t *v)
3884 + {
3885 +- asm volatile(LOCK_PREFIX "subl %1,%0"
3886 ++ asm volatile(LOCK_PREFIX "subl %1,%0\n"
3887 ++
3888 ++#ifdef CONFIG_PAX_REFCOUNT
3889 ++ "jno 0f\n"
3890 ++ LOCK_PREFIX "addl %1,%0\n"
3891 ++ "int $4\n0:\n"
3892 ++ _ASM_EXTABLE(0b, 0b)
3893 ++#endif
3894 ++
3895 + : "=m" (v->counter)
3896 + : "ir" (i), "m" (v->counter));
3897 + }
3898 +@@ -80,7 +110,16 @@ static inline int atomic_sub_and_test(in
3899 + {
3900 + unsigned char c;
3901 +
3902 +- asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
3903 ++ asm volatile(LOCK_PREFIX "subl %2,%0\n"
3904 ++
3905 ++#ifdef CONFIG_PAX_REFCOUNT
3906 ++ "jno 0f\n"
3907 ++ LOCK_PREFIX "addl %2,%0\n"
3908 ++ "int $4\n0:\n"
3909 ++ _ASM_EXTABLE(0b, 0b)
3910 ++#endif
3911 ++
3912 ++ "sete %1\n"
3913 + : "=m" (v->counter), "=qm" (c)
3914 + : "ir" (i), "m" (v->counter) : "memory");
3915 + return c;
3916 +@@ -94,7 +133,19 @@ static inline int atomic_sub_and_test(in
3917 + */
3918 + static inline void atomic_inc(atomic_t *v)
3919 + {
3920 +- asm volatile(LOCK_PREFIX "incl %0"
3921 ++ asm volatile(LOCK_PREFIX "incl %0\n"
3922 ++
3923 ++#ifdef CONFIG_PAX_REFCOUNT
3924 ++ "jno 0f\n"
3925 ++ "int $4\n0:\n"
3926 ++ ".pushsection .fixup,\"ax\"\n"
3927 ++ "1:\n"
3928 ++ LOCK_PREFIX "decl %0\n"
3929 ++ "jmp 0b\n"
3930 ++ ".popsection\n"
3931 ++ _ASM_EXTABLE(0b, 1b)
3932 ++#endif
3933 ++
3934 + : "=m" (v->counter)
3935 + : "m" (v->counter));
3936 + }
3937 +@@ -107,7 +158,19 @@ static inline void atomic_inc(atomic_t *
3938 + */
3939 + static inline void atomic_dec(atomic_t *v)
3940 + {
3941 +- asm volatile(LOCK_PREFIX "decl %0"
3942 ++ asm volatile(LOCK_PREFIX "decl %0\n"
3943 ++
3944 ++#ifdef CONFIG_PAX_REFCOUNT
3945 ++ "jno 0f\n"
3946 ++ "int $4\n0:\n"
3947 ++ ".pushsection .fixup,\"ax\"\n"
3948 ++ "1: \n"
3949 ++ LOCK_PREFIX "incl %0\n"
3950 ++ "jmp 0b\n"
3951 ++ ".popsection\n"
3952 ++ _ASM_EXTABLE(0b, 1b)
3953 ++#endif
3954 ++
3955 + : "=m" (v->counter)
3956 + : "m" (v->counter));
3957 + }
3958 +@@ -124,7 +187,20 @@ static inline int atomic_dec_and_test(at
3959 + {
3960 + unsigned char c;
3961 +
3962 +- asm volatile(LOCK_PREFIX "decl %0; sete %1"
3963 ++ asm volatile(LOCK_PREFIX "decl %0\n"
3964 ++
3965 ++#ifdef CONFIG_PAX_REFCOUNT
3966 ++ "jno 0f\n"
3967 ++ "int $4\n0:\n"
3968 ++ ".pushsection .fixup,\"ax\"\n"
3969 ++ "1: \n"
3970 ++ LOCK_PREFIX "incl %0\n"
3971 ++ "jmp 0b\n"
3972 ++ ".popsection\n"
3973 ++ _ASM_EXTABLE(0b, 1b)
3974 ++#endif
3975 ++
3976 ++ "sete %1\n"
3977 + : "=m" (v->counter), "=qm" (c)
3978 + : "m" (v->counter) : "memory");
3979 + return c != 0;
3980 +@@ -142,7 +218,20 @@ static inline int atomic_inc_and_test(at
3981 + {
3982 + unsigned char c;
3983 +
3984 +- asm volatile(LOCK_PREFIX "incl %0; sete %1"
3985 ++ asm volatile(LOCK_PREFIX "incl %0\n"
3986 ++
3987 ++#ifdef CONFIG_PAX_REFCOUNT
3988 ++ "jno 0f\n"
3989 ++ "int $4\n0:\n"
3990 ++ ".pushsection .fixup,\"ax\"\n"
3991 ++ "1: \n"
3992 ++ LOCK_PREFIX "decl %0\n"
3993 ++ "jmp 0b\n"
3994 ++ ".popsection\n"
3995 ++ _ASM_EXTABLE(0b, 1b)
3996 ++#endif
3997 ++
3998 ++ "sete %1\n"
3999 + : "=m" (v->counter), "=qm" (c)
4000 + : "m" (v->counter) : "memory");
4001 + return c != 0;
4002 +@@ -161,7 +250,16 @@ static inline int atomic_add_negative(in
4003 + {
4004 + unsigned char c;
4005 +
4006 +- asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
4007 ++ asm volatile(LOCK_PREFIX "addl %2,%0\n"
4008 ++
4009 ++#ifdef CONFIG_PAX_REFCOUNT
4010 ++ "jno 0f\n"
4011 ++ LOCK_PREFIX "subl %2,%0\n"
4012 ++ "int $4\n0:\n"
4013 ++ _ASM_EXTABLE(0b, 0b)
4014 ++#endif
4015 ++
4016 ++ "sets %1\n"
4017 + : "=m" (v->counter), "=qm" (c)
4018 + : "ir" (i), "m" (v->counter) : "memory");
4019 + return c;
4020 +@@ -177,7 +275,15 @@ static inline int atomic_add_negative(in
4021 + static inline int atomic_add_return(int i, atomic_t *v)
4022 + {
4023 + int __i = i;
4024 +- asm volatile(LOCK_PREFIX "xaddl %0, %1"
4025 ++ asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
4026 ++
4027 ++#ifdef CONFIG_PAX_REFCOUNT
4028 ++ "jno 0f\n"
4029 ++ "movl %0, %1\n"
4030 ++ "int $4\n0:\n"
4031 ++ _ASM_EXTABLE(0b, 0b)
4032 ++#endif
4033 ++
4034 + : "+r" (i), "+m" (v->counter)
4035 + : : "memory");
4036 + return i + __i;
4037 +@@ -226,7 +332,15 @@ typedef struct {
4038 + */
4039 + static inline void atomic64_add(long i, atomic64_t *v)
4040 + {
4041 +- asm volatile(LOCK_PREFIX "addq %1,%0"
4042 ++ asm volatile(LOCK_PREFIX "addq %1,%0\n"
4043 ++
4044 ++#ifdef CONFIG_PAX_REFCOUNT
4045 ++ "jno 0f\n"
4046 ++ LOCK_PREFIX "subq %1,%0\n"
4047 ++ "int $4\n0:\n"
4048 ++ _ASM_EXTABLE(0b, 0b)
4049 ++#endif
4050 ++
4051 + : "=m" (v->counter)
4052 + : "er" (i), "m" (v->counter));
4053 + }
4054 +@@ -240,7 +354,15 @@ static inline void atomic64_add(long i,
4055 + */
4056 + static inline void atomic64_sub(long i, atomic64_t *v)
4057 + {
4058 +- asm volatile(LOCK_PREFIX "subq %1,%0"
4059 ++ asm volatile(LOCK_PREFIX "subq %1,%0\n"
4060 ++
4061 ++#ifdef CONFIG_PAX_REFCOUNT
4062 ++ "jno 0f\n"
4063 ++ LOCK_PREFIX "addq %1,%0\n"
4064 ++ "int $4\n0:\n"
4065 ++ _ASM_EXTABLE(0b, 0b)
4066 ++#endif
4067 ++
4068 + : "=m" (v->counter)
4069 + : "er" (i), "m" (v->counter));
4070 + }
4071 +@@ -258,7 +380,16 @@ static inline int atomic64_sub_and_test(
4072 + {
4073 + unsigned char c;
4074 +
4075 +- asm volatile(LOCK_PREFIX "subq %2,%0; sete %1"
4076 ++ asm volatile(LOCK_PREFIX "subq %2,%0\n"
4077 ++
4078 ++#ifdef CONFIG_PAX_REFCOUNT
4079 ++ "jno 0f\n"
4080 ++ LOCK_PREFIX "addq %2,%0\n"
4081 ++ "int $4\n0:\n"
4082 ++ _ASM_EXTABLE(0b, 0b)
4083 ++#endif
4084 ++
4085 ++ "sete %1\n"
4086 + : "=m" (v->counter), "=qm" (c)
4087 + : "er" (i), "m" (v->counter) : "memory");
4088 + return c;
4089 +@@ -272,7 +403,19 @@ static inline int atomic64_sub_and_test(
4090 + */
4091 + static inline void atomic64_inc(atomic64_t *v)
4092 + {
4093 +- asm volatile(LOCK_PREFIX "incq %0"
4094 ++ asm volatile(LOCK_PREFIX "incq %0\n"
4095 ++
4096 ++#ifdef CONFIG_PAX_REFCOUNT
4097 ++ "jno 0f\n"
4098 ++ "int $4\n0:\n"
4099 ++ ".pushsection .fixup,\"ax\"\n"
4100 ++ "1:\n"
4101 ++ LOCK_PREFIX "decq %0\n"
4102 ++ "jmp 0b\n"
4103 ++ ".popsection\n"
4104 ++ _ASM_EXTABLE(0b, 1b)
4105 ++#endif
4106 ++
4107 + : "=m" (v->counter)
4108 + : "m" (v->counter));
4109 + }
4110 +@@ -285,7 +428,19 @@ static inline void atomic64_inc(atomic64
4111 + */
4112 + static inline void atomic64_dec(atomic64_t *v)
4113 + {
4114 +- asm volatile(LOCK_PREFIX "decq %0"
4115 ++ asm volatile(LOCK_PREFIX "decq %0\n"
4116 ++
4117 ++#ifdef CONFIG_PAX_REFCOUNT
4118 ++ "jno 0f\n"
4119 ++ "int $4\n0:\n"
4120 ++ ".pushsection .fixup,\"ax\"\n"
4121 ++ "1: \n"
4122 ++ LOCK_PREFIX "incq %0\n"
4123 ++ "jmp 0b\n"
4124 ++ ".popsection\n"
4125 ++ _ASM_EXTABLE(0b, 1b)
4126 ++#endif
4127 ++
4128 + : "=m" (v->counter)
4129 + : "m" (v->counter));
4130 + }
4131 +@@ -302,7 +457,20 @@ static inline int atomic64_dec_and_test(
4132 + {
4133 + unsigned char c;
4134 +
4135 +- asm volatile(LOCK_PREFIX "decq %0; sete %1"
4136 ++ asm volatile(LOCK_PREFIX "decq %0\n"
4137 ++
4138 ++#ifdef CONFIG_PAX_REFCOUNT
4139 ++ "jno 0f\n"
4140 ++ "int $4\n0:\n"
4141 ++ ".pushsection .fixup,\"ax\"\n"
4142 ++ "1: \n"
4143 ++ LOCK_PREFIX "incq %0\n"
4144 ++ "jmp 0b\n"
4145 ++ ".popsection\n"
4146 ++ _ASM_EXTABLE(0b, 1b)
4147 ++#endif
4148 ++
4149 ++ "sete %1\n"
4150 + : "=m" (v->counter), "=qm" (c)
4151 + : "m" (v->counter) : "memory");
4152 + return c != 0;
4153 +@@ -320,7 +488,20 @@ static inline int atomic64_inc_and_test(
4154 + {
4155 + unsigned char c;
4156 +
4157 +- asm volatile(LOCK_PREFIX "incq %0; sete %1"
4158 ++ asm volatile(LOCK_PREFIX "incq %0\n"
4159 ++
4160 ++#ifdef CONFIG_PAX_REFCOUNT
4161 ++ "jno 0f\n"
4162 ++ "int $4\n0:\n"
4163 ++ ".pushsection .fixup,\"ax\"\n"
4164 ++ "1: \n"
4165 ++ LOCK_PREFIX "decq %0\n"
4166 ++ "jmp 0b\n"
4167 ++ ".popsection\n"
4168 ++ _ASM_EXTABLE(0b, 1b)
4169 ++#endif
4170 ++
4171 ++ "sete %1\n"
4172 + : "=m" (v->counter), "=qm" (c)
4173 + : "m" (v->counter) : "memory");
4174 + return c != 0;
4175 +@@ -339,7 +520,16 @@ static inline int atomic64_add_negative(
4176 + {
4177 + unsigned char c;
4178 +
4179 +- asm volatile(LOCK_PREFIX "addq %2,%0; sets %1"
4180 ++ asm volatile(LOCK_PREFIX "addq %2,%0\n"
4181 ++
4182 ++#ifdef CONFIG_PAX_REFCOUNT
4183 ++ "jno 0f\n"
4184 ++ LOCK_PREFIX "subq %2,%0\n"
4185 ++ "int $4\n0:\n"
4186 ++ _ASM_EXTABLE(0b, 0b)
4187 ++#endif
4188 ++
4189 ++ "sets %1\n"
4190 + : "=m" (v->counter), "=qm" (c)
4191 + : "er" (i), "m" (v->counter) : "memory");
4192 + return c;
4193 +@@ -355,7 +545,15 @@ static inline int atomic64_add_negative(
4194 + static inline long atomic64_add_return(long i, atomic64_t *v)
4195 + {
4196 + long __i = i;
4197 +- asm volatile(LOCK_PREFIX "xaddq %0, %1;"
4198 ++ asm volatile(LOCK_PREFIX "xaddq %0, %1\n"
4199 ++
4200 ++#ifdef CONFIG_PAX_REFCOUNT
4201 ++ "jno 0f\n"
4202 ++ "movq %0, %1\n"
4203 ++ "int $4\n0:\n"
4204 ++ _ASM_EXTABLE(0b, 0b)
4205 ++#endif
4206 ++
4207 + : "+r" (i), "+m" (v->counter)
4208 + : : "memory");
4209 + return i + __i;
4210 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/boot.h linux-2.6.28.8/arch/x86/include/asm/boot.h
4211 +--- linux-2.6.28.8/arch/x86/include/asm/boot.h 2009-02-06 16:47:45.000000000 -0500
4212 ++++ linux-2.6.28.8/arch/x86/include/asm/boot.h 2009-02-21 09:37:48.000000000 -0500
4213 +@@ -11,10 +11,15 @@
4214 + #define ASK_VGA 0xfffd /* ask for it at bootup */
4215 +
4216 + /* Physical address where kernel should be loaded. */
4217 +-#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
4218 ++#define ____LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
4219 + + (CONFIG_PHYSICAL_ALIGN - 1)) \
4220 + & ~(CONFIG_PHYSICAL_ALIGN - 1))
4221 +
4222 ++#ifndef __ASSEMBLY__
4223 ++extern unsigned char __LOAD_PHYSICAL_ADDR[];
4224 ++#define LOAD_PHYSICAL_ADDR ((unsigned long)__LOAD_PHYSICAL_ADDR)
4225 ++#endif
4226 ++
4227 + #ifdef CONFIG_X86_64
4228 + #define BOOT_HEAP_SIZE 0x7000
4229 + #define BOOT_STACK_SIZE 0x4000
4230 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/cache.h linux-2.6.28.8/arch/x86/include/asm/cache.h
4231 +--- linux-2.6.28.8/arch/x86/include/asm/cache.h 2009-02-06 16:47:45.000000000 -0500
4232 ++++ linux-2.6.28.8/arch/x86/include/asm/cache.h 2009-02-21 09:37:48.000000000 -0500
4233 +@@ -6,6 +6,7 @@
4234 + #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
4235 +
4236 + #define __read_mostly __attribute__((__section__(".data.read_mostly")))
4237 ++#define __read_only __attribute__((__section__(".data.read_only")))
4238 +
4239 + #ifdef CONFIG_X86_VSMP
4240 + /* vSMP Internode cacheline shift */
4241 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/checksum_32.h linux-2.6.28.8/arch/x86/include/asm/checksum_32.h
4242 +--- linux-2.6.28.8/arch/x86/include/asm/checksum_32.h 2009-02-06 16:47:45.000000000 -0500
4243 ++++ linux-2.6.28.8/arch/x86/include/asm/checksum_32.h 2009-02-21 09:37:48.000000000 -0500
4244 +@@ -31,6 +31,14 @@ asmlinkage __wsum csum_partial_copy_gene
4245 + int len, __wsum sum,
4246 + int *src_err_ptr, int *dst_err_ptr);
4247 +
4248 ++asmlinkage __wsum csum_partial_copy_generic_to_user(const void *src, void *dst,
4249 ++ int len, __wsum sum,
4250 ++ int *src_err_ptr, int *dst_err_ptr);
4251 ++
4252 ++asmlinkage __wsum csum_partial_copy_generic_from_user(const void *src, void *dst,
4253 ++ int len, __wsum sum,
4254 ++ int *src_err_ptr, int *dst_err_ptr);
4255 ++
4256 + /*
4257 + * Note: when you get a NULL pointer exception here this means someone
4258 + * passed in an incorrect kernel address to one of these functions.
4259 +@@ -50,7 +58,7 @@ static inline __wsum csum_partial_copy_f
4260 + int *err_ptr)
4261 + {
4262 + might_sleep();
4263 +- return csum_partial_copy_generic((__force void *)src, dst,
4264 ++ return csum_partial_copy_generic_from_user((__force void *)src, dst,
4265 + len, sum, err_ptr, NULL);
4266 + }
4267 +
4268 +@@ -177,7 +185,7 @@ static inline __wsum csum_and_copy_to_us
4269 + {
4270 + might_sleep();
4271 + if (access_ok(VERIFY_WRITE, dst, len))
4272 +- return csum_partial_copy_generic(src, (__force void *)dst,
4273 ++ return csum_partial_copy_generic_to_user(src, (__force void *)dst,
4274 + len, sum, NULL, err_ptr);
4275 +
4276 + if (len)
4277 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/cpufeature.h linux-2.6.28.8/arch/x86/include/asm/cpufeature.h
4278 +--- linux-2.6.28.8/arch/x86/include/asm/cpufeature.h 2009-02-06 16:47:45.000000000 -0500
4279 ++++ linux-2.6.28.8/arch/x86/include/asm/cpufeature.h 2009-02-21 09:37:48.000000000 -0500
4280 +@@ -80,7 +80,6 @@
4281 + #define X86_FEATURE_UP (3*32+ 9) /* smp kernel running on up */
4282 + #define X86_FEATURE_FXSAVE_LEAK (3*32+10) /* "" FXSAVE leaks FOP/FIP/FOP */
4283 + #define X86_FEATURE_ARCH_PERFMON (3*32+11) /* Intel Architectural PerfMon */
4284 +-#define X86_FEATURE_NOPL (3*32+20) /* The NOPL (0F 1F) instructions */
4285 + #define X86_FEATURE_PEBS (3*32+12) /* Precise-Event Based Sampling */
4286 + #define X86_FEATURE_BTS (3*32+13) /* Branch Trace Store */
4287 + #define X86_FEATURE_SYSCALL32 (3*32+14) /* "" syscall in ia32 userspace */
4288 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/desc.h linux-2.6.28.8/arch/x86/include/asm/desc.h
4289 +--- linux-2.6.28.8/arch/x86/include/asm/desc.h 2009-02-06 16:47:45.000000000 -0500
4290 ++++ linux-2.6.28.8/arch/x86/include/asm/desc.h 2009-02-21 09:37:48.000000000 -0500
4291 +@@ -16,6 +16,7 @@ static inline void fill_ldt(struct desc_
4292 + desc->base1 = (info->base_addr & 0x00ff0000) >> 16;
4293 + desc->type = (info->read_exec_only ^ 1) << 1;
4294 + desc->type |= info->contents << 2;
4295 ++ desc->type |= info->seg_not_present ^ 1;
4296 + desc->s = 1;
4297 + desc->dpl = 0x3;
4298 + desc->p = info->seg_not_present ^ 1;
4299 +@@ -32,16 +33,12 @@ static inline void fill_ldt(struct desc_
4300 + }
4301 +
4302 + extern struct desc_ptr idt_descr;
4303 +-extern gate_desc idt_table[];
4304 +-
4305 +-struct gdt_page {
4306 +- struct desc_struct gdt[GDT_ENTRIES];
4307 +-} __attribute__((aligned(PAGE_SIZE)));
4308 +-DECLARE_PER_CPU(struct gdt_page, gdt_page);
4309 ++extern gate_desc idt_table[256];
4310 +
4311 ++extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
4312 + static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
4313 + {
4314 +- return per_cpu(gdt_page, cpu).gdt;
4315 ++ return cpu_gdt_table[cpu];
4316 + }
4317 +
4318 + #ifdef CONFIG_X86_64
4319 +@@ -115,19 +112,48 @@ static inline void paravirt_free_ldt(str
4320 + static inline void native_write_idt_entry(gate_desc *idt, int entry,
4321 + const gate_desc *gate)
4322 + {
4323 ++
4324 ++#ifdef CONFIG_PAX_KERNEXEC
4325 ++ unsigned long cr0;
4326 ++
4327 ++ pax_open_kernel(cr0);
4328 ++#endif
4329 ++
4330 + memcpy(&idt[entry], gate, sizeof(*gate));
4331 ++
4332 ++#ifdef CONFIG_PAX_KERNEXEC
4333 ++ pax_close_kernel(cr0);
4334 ++#endif
4335 ++
4336 + }
4337 +
4338 + static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry,
4339 + const void *desc)
4340 + {
4341 ++
4342 ++#ifdef CONFIG_PAX_KERNEXEC
4343 ++ unsigned long cr0;
4344 ++
4345 ++ pax_open_kernel(cr0);
4346 ++#endif
4347 ++
4348 + memcpy(&ldt[entry], desc, 8);
4349 ++
4350 ++#ifdef CONFIG_PAX_KERNEXEC
4351 ++ pax_close_kernel(cr0);
4352 ++#endif
4353 ++
4354 + }
4355 +
4356 + static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry,
4357 + const void *desc, int type)
4358 + {
4359 + unsigned int size;
4360 ++
4361 ++#ifdef CONFIG_PAX_KERNEXEC
4362 ++ unsigned long cr0;
4363 ++#endif
4364 ++
4365 + switch (type) {
4366 + case DESC_TSS:
4367 + size = sizeof(tss_desc);
4368 +@@ -139,7 +165,17 @@ static inline void native_write_gdt_entr
4369 + size = sizeof(struct desc_struct);
4370 + break;
4371 + }
4372 ++
4373 ++#ifdef CONFIG_PAX_KERNEXEC
4374 ++ pax_open_kernel(cr0);
4375 ++#endif
4376 ++
4377 + memcpy(&gdt[entry], desc, size);
4378 ++
4379 ++#ifdef CONFIG_PAX_KERNEXEC
4380 ++ pax_close_kernel(cr0);
4381 ++#endif
4382 ++
4383 + }
4384 +
4385 + static inline void pack_descriptor(struct desc_struct *desc, unsigned long base,
4386 +@@ -211,7 +247,19 @@ static inline void native_set_ldt(const
4387 +
4388 + static inline void native_load_tr_desc(void)
4389 + {
4390 ++
4391 ++#ifdef CONFIG_PAX_KERNEXEC
4392 ++ unsigned long cr0;
4393 ++
4394 ++ pax_open_kernel(cr0);
4395 ++#endif
4396 ++
4397 + asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
4398 ++
4399 ++#ifdef CONFIG_PAX_KERNEXEC
4400 ++ pax_close_kernel(cr0);
4401 ++#endif
4402 ++
4403 + }
4404 +
4405 + static inline void native_load_gdt(const struct desc_ptr *dtr)
4406 +@@ -246,8 +294,19 @@ static inline void native_load_tls(struc
4407 + unsigned int i;
4408 + struct desc_struct *gdt = get_cpu_gdt_table(cpu);
4409 +
4410 ++#ifdef CONFIG_PAX_KERNEXEC
4411 ++ unsigned long cr0;
4412 ++
4413 ++ pax_open_kernel(cr0);
4414 ++#endif
4415 ++
4416 + for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
4417 + gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
4418 ++
4419 ++#ifdef CONFIG_PAX_KERNEXEC
4420 ++ pax_close_kernel(cr0);
4421 ++#endif
4422 ++
4423 + }
4424 +
4425 + #define _LDT_empty(info) \
4426 +@@ -381,6 +440,18 @@ static inline void set_system_intr_gate_
4427 + _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS);
4428 + }
4429 +
4430 ++#ifdef CONFIG_X86_32
4431 ++static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
4432 ++{
4433 ++ struct desc_struct d;
4434 ++
4435 ++ if (likely(limit))
4436 ++ limit = (limit - 1UL) >> PAGE_SHIFT;
4437 ++ pack_descriptor(&d, base, limit, 0xFB, 0xC);
4438 ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, &d, DESCTYPE_S);
4439 ++}
4440 ++#endif
4441 ++
4442 + #else
4443 + /*
4444 + * GET_DESC_BASE reads the descriptor base of the specified segment.
4445 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/e820.h linux-2.6.28.8/arch/x86/include/asm/e820.h
4446 +--- linux-2.6.28.8/arch/x86/include/asm/e820.h 2009-02-06 16:47:45.000000000 -0500
4447 ++++ linux-2.6.28.8/arch/x86/include/asm/e820.h 2009-02-21 09:37:48.000000000 -0500
4448 +@@ -134,7 +134,7 @@ extern char *memory_setup(void);
4449 + #define ISA_END_ADDRESS 0x100000
4450 + #define is_ISA_range(s, e) ((s) >= ISA_START_ADDRESS && (e) < ISA_END_ADDRESS)
4451 +
4452 +-#define BIOS_BEGIN 0x000a0000
4453 ++#define BIOS_BEGIN 0x000c0000
4454 + #define BIOS_END 0x00100000
4455 +
4456 + #ifdef __KERNEL__
4457 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/elf.h linux-2.6.28.8/arch/x86/include/asm/elf.h
4458 +--- linux-2.6.28.8/arch/x86/include/asm/elf.h 2009-02-06 16:47:45.000000000 -0500
4459 ++++ linux-2.6.28.8/arch/x86/include/asm/elf.h 2009-02-21 09:37:48.000000000 -0500
4460 +@@ -252,7 +252,25 @@ extern int force_personality32;
4461 + the loader. We need to make sure that it is out of the way of the program
4462 + that it will "exec", and that there is sufficient room for the brk. */
4463 +
4464 ++#ifdef CONFIG_PAX_SEGMEXEC
4465 ++#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
4466 ++#else
4467 + #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
4468 ++#endif
4469 ++
4470 ++#ifdef CONFIG_PAX_ASLR
4471 ++#ifdef CONFIG_X86_32
4472 ++#define PAX_ELF_ET_DYN_BASE 0x10000000UL
4473 ++
4474 ++#define PAX_DELTA_MMAP_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
4475 ++#define PAX_DELTA_STACK_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
4476 ++#else
4477 ++#define PAX_ELF_ET_DYN_BASE 0x400000UL
4478 ++
4479 ++#define PAX_DELTA_MMAP_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
4480 ++#define PAX_DELTA_STACK_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
4481 ++#endif
4482 ++#endif
4483 +
4484 + /* This yields a mask that user programs can use to figure out what
4485 + instruction set this CPU supports. This could be done in user space,
4486 +@@ -304,8 +322,7 @@ do { \
4487 + #define ARCH_DLINFO \
4488 + do { \
4489 + if (vdso_enabled) \
4490 +- NEW_AUX_ENT(AT_SYSINFO_EHDR, \
4491 +- (unsigned long)current->mm->context.vdso); \
4492 ++ NEW_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso);\
4493 + } while (0)
4494 +
4495 + #define AT_SYSINFO 32
4496 +@@ -316,7 +333,7 @@ do { \
4497 +
4498 + #endif /* !CONFIG_X86_32 */
4499 +
4500 +-#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
4501 ++#define VDSO_CURRENT_BASE (current->mm->context.vdso)
4502 +
4503 + #define VDSO_ENTRY \
4504 + ((unsigned long)VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall))
4505 +@@ -330,7 +347,4 @@ extern int arch_setup_additional_pages(s
4506 + extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
4507 + #define compat_arch_setup_additional_pages syscall32_setup_pages
4508 +
4509 +-extern unsigned long arch_randomize_brk(struct mm_struct *mm);
4510 +-#define arch_randomize_brk arch_randomize_brk
4511 +-
4512 + #endif /* _ASM_X86_ELF_H */
4513 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/futex.h linux-2.6.28.8/arch/x86/include/asm/futex.h
4514 +--- linux-2.6.28.8/arch/x86/include/asm/futex.h 2009-02-06 16:47:45.000000000 -0500
4515 ++++ linux-2.6.28.8/arch/x86/include/asm/futex.h 2009-02-21 09:37:48.000000000 -0500
4516 +@@ -11,6 +11,40 @@
4517 + #include <asm/processor.h>
4518 + #include <asm/system.h>
4519 +
4520 ++#ifdef CONFIG_X86_32
4521 ++#define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
4522 ++ asm volatile( \
4523 ++ "movw\t%w6, %%ds\n" \
4524 ++ "1:\t" insn "\n" \
4525 ++ "2:\tpushl\t%%ss\n" \
4526 ++ "\tpopl\t%%ds\n" \
4527 ++ "\t.section .fixup,\"ax\"\n" \
4528 ++ "3:\tmov\t%3, %1\n" \
4529 ++ "\tjmp\t2b\n" \
4530 ++ "\t.previous\n" \
4531 ++ _ASM_EXTABLE(1b, 3b) \
4532 ++ : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
4533 ++ : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS))
4534 ++
4535 ++#define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
4536 ++ asm volatile("movw\t%w7, %%es\n" \
4537 ++ "1:\tmovl\t%%es:%2, %0\n" \
4538 ++ "\tmovl\t%0, %3\n" \
4539 ++ "\t" insn "\n" \
4540 ++ "2:\t" LOCK_PREFIX "cmpxchgl %3, %%es:%2\n"\
4541 ++ "\tjnz\t1b\n" \
4542 ++ "3:\tpushl\t%%ss\n" \
4543 ++ "\tpopl\t%%es\n" \
4544 ++ "\t.section .fixup,\"ax\"\n" \
4545 ++ "4:\tmov\t%5, %1\n" \
4546 ++ "\tjmp\t3b\n" \
4547 ++ "\t.previous\n" \
4548 ++ _ASM_EXTABLE(1b, 4b) \
4549 ++ _ASM_EXTABLE(2b, 4b) \
4550 ++ : "=&a" (oldval), "=&r" (ret), \
4551 ++ "+m" (*uaddr), "=&r" (tem) \
4552 ++ : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS))
4553 ++#else
4554 + #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
4555 + asm volatile("1:\t" insn "\n" \
4556 + "2:\t.section .fixup,\"ax\"\n" \
4557 +@@ -36,8 +70,9 @@
4558 + : "=&a" (oldval), "=&r" (ret), \
4559 + "+m" (*uaddr), "=&r" (tem) \
4560 + : "r" (oparg), "i" (-EFAULT), "1" (0))
4561 ++#endif
4562 +
4563 +-static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
4564 ++static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
4565 + {
4566 + int op = (encoded_op >> 28) & 7;
4567 + int cmp = (encoded_op >> 24) & 15;
4568 +@@ -61,11 +96,20 @@ static inline int futex_atomic_op_inuser
4569 +
4570 + switch (op) {
4571 + case FUTEX_OP_SET:
4572 ++#ifdef CONFIG_X86_32
4573 ++ __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg);
4574 ++#else
4575 + __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
4576 ++#endif
4577 + break;
4578 + case FUTEX_OP_ADD:
4579 ++#ifdef CONFIG_X86_32
4580 ++ __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %%ds:%2", ret, oldval,
4581 ++ uaddr, oparg);
4582 ++#else
4583 + __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, oldval,
4584 + uaddr, oparg);
4585 ++#endif
4586 + break;
4587 + case FUTEX_OP_OR:
4588 + __futex_atomic_op2("orl %4, %3", ret, oldval, uaddr, oparg);
4589 +@@ -109,7 +153,7 @@ static inline int futex_atomic_op_inuser
4590 + return ret;
4591 + }
4592 +
4593 +-static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval,
4594 ++static inline int futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval,
4595 + int newval)
4596 + {
4597 +
4598 +@@ -122,14 +166,27 @@ static inline int futex_atomic_cmpxchg_i
4599 + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
4600 + return -EFAULT;
4601 +
4602 +- asm volatile("1:\t" LOCK_PREFIX "cmpxchgl %3, %1\n"
4603 ++ asm volatile(
4604 ++#ifdef CONFIG_X86_32
4605 ++ "\tmovw %w5, %%ds\n"
4606 ++ "1:\t" LOCK_PREFIX "cmpxchgl %3, %1\n"
4607 ++ "2:\tpushl %%ss\n"
4608 ++ "\tpopl %%ds\n"
4609 ++ "\t.section .fixup, \"ax\"\n"
4610 ++#else
4611 ++ "1:\t" LOCK_PREFIX "cmpxchgl %3, %1\n"
4612 + "2:\t.section .fixup, \"ax\"\n"
4613 ++#endif
4614 + "3:\tmov %2, %0\n"
4615 + "\tjmp 2b\n"
4616 + "\t.previous\n"
4617 + _ASM_EXTABLE(1b, 3b)
4618 + : "=a" (oldval), "+m" (*uaddr)
4619 ++#ifdef CONFIG_X86_32
4620 ++ : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS)
4621 ++#else
4622 + : "i" (-EFAULT), "r" (newval), "0" (oldval)
4623 ++#endif
4624 + : "memory"
4625 + );
4626 +
4627 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/i387.h linux-2.6.28.8/arch/x86/include/asm/i387.h
4628 +--- linux-2.6.28.8/arch/x86/include/asm/i387.h 2009-02-06 16:47:45.000000000 -0500
4629 ++++ linux-2.6.28.8/arch/x86/include/asm/i387.h 2009-02-21 09:37:48.000000000 -0500
4630 +@@ -197,13 +197,8 @@ static inline void restore_fpu(struct ta
4631 + }
4632 +
4633 + /* We need a safe address that is cheap to find and that is already
4634 +- in L1 during context switch. The best choices are unfortunately
4635 +- different for UP and SMP */
4636 +-#ifdef CONFIG_SMP
4637 +-#define safe_address (__per_cpu_offset[0])
4638 +-#else
4639 +-#define safe_address (kstat_cpu(0).cpustat.user)
4640 +-#endif
4641 ++ in L1 during context switch. */
4642 ++#define safe_address (init_tss[smp_processor_id()].x86_tss.sp0)
4643 +
4644 + /*
4645 + * These must be called with preempt disabled
4646 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/io_64.h linux-2.6.28.8/arch/x86/include/asm/io_64.h
4647 +--- linux-2.6.28.8/arch/x86/include/asm/io_64.h 2009-02-06 16:47:45.000000000 -0500
4648 ++++ linux-2.6.28.8/arch/x86/include/asm/io_64.h 2009-02-21 09:37:48.000000000 -0500
4649 +@@ -158,6 +158,17 @@ static inline void *phys_to_virt(unsigne
4650 + }
4651 + #endif
4652 +
4653 ++#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
4654 ++static inline int valid_phys_addr_range (unsigned long addr, size_t count)
4655 ++{
4656 ++ return ((addr + count + PAGE_SIZE - 1) >> PAGE_SHIFT) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
4657 ++}
4658 ++
4659 ++static inline int valid_mmap_phys_addr_range (unsigned long pfn, size_t count)
4660 ++{
4661 ++ return (pfn + (count >> PAGE_SHIFT)) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
4662 ++}
4663 ++
4664 + /*
4665 + * Change "struct page" to physical address.
4666 + */
4667 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/irqflags.h linux-2.6.28.8/arch/x86/include/asm/irqflags.h
4668 +--- linux-2.6.28.8/arch/x86/include/asm/irqflags.h 2009-02-06 16:47:45.000000000 -0500
4669 ++++ linux-2.6.28.8/arch/x86/include/asm/irqflags.h 2009-02-21 09:37:48.000000000 -0500
4670 +@@ -141,6 +141,8 @@ static inline unsigned long __raw_local_
4671 + #define INTERRUPT_RETURN iret
4672 + #define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit
4673 + #define GET_CR0_INTO_EAX movl %cr0, %eax
4674 ++#define GET_CR0_INTO_EDX movl %cr0, %edx
4675 ++#define SET_CR0_FROM_EDX movl %edx, %cr0
4676 + #endif
4677 +
4678 +
4679 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/kmap_types.h linux-2.6.28.8/arch/x86/include/asm/kmap_types.h
4680 +--- linux-2.6.28.8/arch/x86/include/asm/kmap_types.h 2009-02-06 16:47:45.000000000 -0500
4681 ++++ linux-2.6.28.8/arch/x86/include/asm/kmap_types.h 2009-02-21 09:37:48.000000000 -0500
4682 +@@ -21,7 +21,8 @@ D(9) KM_IRQ0,
4683 + D(10) KM_IRQ1,
4684 + D(11) KM_SOFTIRQ0,
4685 + D(12) KM_SOFTIRQ1,
4686 +-D(13) KM_TYPE_NR
4687 ++D(13) KM_CLEARPAGE,
4688 ++D(14) KM_TYPE_NR
4689 + };
4690 +
4691 + #undef D
4692 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/kvm_host.h linux-2.6.28.8/arch/x86/include/asm/kvm_host.h
4693 +--- linux-2.6.28.8/arch/x86/include/asm/kvm_host.h 2009-02-06 16:47:45.000000000 -0500
4694 ++++ linux-2.6.28.8/arch/x86/include/asm/kvm_host.h 2009-02-21 09:37:48.000000000 -0500
4695 +@@ -479,7 +479,7 @@ struct kvm_x86_ops {
4696 + int (*get_tdp_level)(void);
4697 + };
4698 +
4699 +-extern struct kvm_x86_ops *kvm_x86_ops;
4700 ++extern const struct kvm_x86_ops *kvm_x86_ops;
4701 +
4702 + int kvm_mmu_module_init(void);
4703 + void kvm_mmu_module_exit(void);
4704 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/linkage.h linux-2.6.28.8/arch/x86/include/asm/linkage.h
4705 +--- linux-2.6.28.8/arch/x86/include/asm/linkage.h 2009-02-06 16:47:45.000000000 -0500
4706 ++++ linux-2.6.28.8/arch/x86/include/asm/linkage.h 2009-02-21 09:37:48.000000000 -0500
4707 +@@ -7,6 +7,11 @@
4708 + #ifdef CONFIG_X86_64
4709 + #define __ALIGN .p2align 4,,15
4710 + #define __ALIGN_STR ".p2align 4,,15"
4711 ++#else
4712 ++#ifdef CONFIG_X86_ALIGNMENT_16
4713 ++#define __ALIGN .align 16,0x90
4714 ++#define __ALIGN_STR ".align 16,0x90"
4715 ++#endif
4716 + #endif
4717 +
4718 + #ifdef CONFIG_X86_32
4719 +@@ -52,10 +57,5 @@
4720 +
4721 + #endif
4722 +
4723 +-#ifdef CONFIG_X86_ALIGNMENT_16
4724 +-#define __ALIGN .align 16,0x90
4725 +-#define __ALIGN_STR ".align 16,0x90"
4726 +-#endif
4727 +-
4728 + #endif /* _ASM_X86_LINKAGE_H */
4729 +
4730 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/local.h linux-2.6.28.8/arch/x86/include/asm/local.h
4731 +--- linux-2.6.28.8/arch/x86/include/asm/local.h 2009-02-06 16:47:45.000000000 -0500
4732 ++++ linux-2.6.28.8/arch/x86/include/asm/local.h 2009-02-21 09:37:48.000000000 -0500
4733 +@@ -18,26 +18,90 @@ typedef struct {
4734 +
4735 + static inline void local_inc(local_t *l)
4736 + {
4737 +- asm volatile(_ASM_INC "%0"
4738 ++ asm volatile(_ASM_INC "%0\n"
4739 ++
4740 ++#ifdef CONFIG_PAX_REFCOUNT
4741 ++#ifdef CONFIG_X86_32
4742 ++ "into\n0:\n"
4743 ++#else
4744 ++ "jno 0f\n"
4745 ++ "int $4\n0:\n"
4746 ++#endif
4747 ++ ".pushsection .fixup,\"ax\"\n"
4748 ++ "1:\n"
4749 ++ _ASM_DEC "%0\n"
4750 ++ "jmp 0b\n"
4751 ++ ".popsection\n"
4752 ++ _ASM_EXTABLE(0b, 1b)
4753 ++#endif
4754 ++
4755 + : "+m" (l->a.counter));
4756 + }
4757 +
4758 + static inline void local_dec(local_t *l)
4759 + {
4760 +- asm volatile(_ASM_DEC "%0"
4761 ++ asm volatile(_ASM_DEC "%0\n"
4762 ++
4763 ++#ifdef CONFIG_PAX_REFCOUNT
4764 ++#ifdef CONFIG_X86_32
4765 ++ "into\n0:\n"
4766 ++#else
4767 ++ "jno 0f\n"
4768 ++ "int $4\n0:\n"
4769 ++#endif
4770 ++ ".pushsection .fixup,\"ax\"\n"
4771 ++ "1:\n"
4772 ++ _ASM_INC "%0\n"
4773 ++ "jmp 0b\n"
4774 ++ ".popsection\n"
4775 ++ _ASM_EXTABLE(0b, 1b)
4776 ++#endif
4777 ++
4778 + : "+m" (l->a.counter));
4779 + }
4780 +
4781 + static inline void local_add(long i, local_t *l)
4782 + {
4783 +- asm volatile(_ASM_ADD "%1,%0"
4784 ++ asm volatile(_ASM_ADD "%1,%0\n"
4785 ++
4786 ++#ifdef CONFIG_PAX_REFCOUNT
4787 ++#ifdef CONFIG_X86_32
4788 ++ "into\n0:\n"
4789 ++#else
4790 ++ "jno 0f\n"
4791 ++ "int $4\n0:\n"
4792 ++#endif
4793 ++ ".pushsection .fixup,\"ax\"\n"
4794 ++ "1:\n"
4795 ++ _ASM_SUB "%1,%0\n"
4796 ++ "jmp 0b\n"
4797 ++ ".popsection\n"
4798 ++ _ASM_EXTABLE(0b, 1b)
4799 ++#endif
4800 ++
4801 + : "+m" (l->a.counter)
4802 + : "ir" (i));
4803 + }
4804 +
4805 + static inline void local_sub(long i, local_t *l)
4806 + {
4807 +- asm volatile(_ASM_SUB "%1,%0"
4808 ++ asm volatile(_ASM_SUB "%1,%0\n"
4809 ++
4810 ++#ifdef CONFIG_PAX_REFCOUNT
4811 ++#ifdef CONFIG_X86_32
4812 ++ "into\n0:\n"
4813 ++#else
4814 ++ "jno 0f\n"
4815 ++ "int $4\n0:\n"
4816 ++#endif
4817 ++ ".pushsection .fixup,\"ax\"\n"
4818 ++ "1:\n"
4819 ++ _ASM_ADD "%1,%0\n"
4820 ++ "jmp 0b\n"
4821 ++ ".popsection\n"
4822 ++ _ASM_EXTABLE(0b, 1b)
4823 ++#endif
4824 ++
4825 + : "+m" (l->a.counter)
4826 + : "ir" (i));
4827 + }
4828 +@@ -55,7 +119,24 @@ static inline int local_sub_and_test(lon
4829 + {
4830 + unsigned char c;
4831 +
4832 +- asm volatile(_ASM_SUB "%2,%0; sete %1"
4833 ++ asm volatile(_ASM_SUB "%2,%0\n"
4834 ++
4835 ++#ifdef CONFIG_PAX_REFCOUNT
4836 ++#ifdef CONFIG_X86_32
4837 ++ "into\n0:\n"
4838 ++#else
4839 ++ "jno 0f\n"
4840 ++ "int $4\n0:\n"
4841 ++#endif
4842 ++ ".pushsection .fixup,\"ax\"\n"
4843 ++ "1:\n"
4844 ++ _ASM_ADD "%2,%0\n"
4845 ++ "jmp 0b\n"
4846 ++ ".popsection\n"
4847 ++ _ASM_EXTABLE(0b, 1b)
4848 ++#endif
4849 ++
4850 ++ "sete %1\n"
4851 + : "+m" (l->a.counter), "=qm" (c)
4852 + : "ir" (i) : "memory");
4853 + return c;
4854 +@@ -73,7 +154,24 @@ static inline int local_dec_and_test(loc
4855 + {
4856 + unsigned char c;
4857 +
4858 +- asm volatile(_ASM_DEC "%0; sete %1"
4859 ++ asm volatile(_ASM_DEC "%0\n"
4860 ++
4861 ++#ifdef CONFIG_PAX_REFCOUNT
4862 ++#ifdef CONFIG_X86_32
4863 ++ "into\n0:\n"
4864 ++#else
4865 ++ "jno 0f\n"
4866 ++ "int $4\n0:\n"
4867 ++#endif
4868 ++ ".pushsection .fixup,\"ax\"\n"
4869 ++ "1:\n"
4870 ++ _ASM_INC "%0\n"
4871 ++ "jmp 0b\n"
4872 ++ ".popsection\n"
4873 ++ _ASM_EXTABLE(0b, 1b)
4874 ++#endif
4875 ++
4876 ++ "sete %1\n"
4877 + : "+m" (l->a.counter), "=qm" (c)
4878 + : : "memory");
4879 + return c != 0;
4880 +@@ -91,7 +189,24 @@ static inline int local_inc_and_test(loc
4881 + {
4882 + unsigned char c;
4883 +
4884 +- asm volatile(_ASM_INC "%0; sete %1"
4885 ++ asm volatile(_ASM_INC "%0\n"
4886 ++
4887 ++#ifdef CONFIG_PAX_REFCOUNT
4888 ++#ifdef CONFIG_X86_32
4889 ++ "into\n0:\n"
4890 ++#else
4891 ++ "jno 0f\n"
4892 ++ "int $4\n0:\n"
4893 ++#endif
4894 ++ ".pushsection .fixup,\"ax\"\n"
4895 ++ "1:\n"
4896 ++ _ASM_DEC "%0\n"
4897 ++ "jmp 0b\n"
4898 ++ ".popsection\n"
4899 ++ _ASM_EXTABLE(0b, 1b)
4900 ++#endif
4901 ++
4902 ++ "sete %1\n"
4903 + : "+m" (l->a.counter), "=qm" (c)
4904 + : : "memory");
4905 + return c != 0;
4906 +@@ -110,7 +225,24 @@ static inline int local_add_negative(lon
4907 + {
4908 + unsigned char c;
4909 +
4910 +- asm volatile(_ASM_ADD "%2,%0; sets %1"
4911 ++ asm volatile(_ASM_ADD "%2,%0\n"
4912 ++
4913 ++#ifdef CONFIG_PAX_REFCOUNT
4914 ++#ifdef CONFIG_X86_32
4915 ++ "into\n0:\n"
4916 ++#else
4917 ++ "jno 0f\n"
4918 ++ "int $4\n0:\n"
4919 ++#endif
4920 ++ ".pushsection .fixup,\"ax\"\n"
4921 ++ "1:\n"
4922 ++ _ASM_SUB "%2,%0\n"
4923 ++ "jmp 0b\n"
4924 ++ ".popsection\n"
4925 ++ _ASM_EXTABLE(0b, 1b)
4926 ++#endif
4927 ++
4928 ++ "sets %1\n"
4929 + : "+m" (l->a.counter), "=qm" (c)
4930 + : "ir" (i) : "memory");
4931 + return c;
4932 +@@ -133,7 +265,23 @@ static inline long local_add_return(long
4933 + #endif
4934 + /* Modern 486+ processor */
4935 + __i = i;
4936 +- asm volatile(_ASM_XADD "%0, %1;"
4937 ++ asm volatile(_ASM_XADD "%0, %1\n"
4938 ++
4939 ++#ifdef CONFIG_PAX_REFCOUNT
4940 ++#ifdef CONFIG_X86_32
4941 ++ "into\n0:\n"
4942 ++#else
4943 ++ "jno 0f\n"
4944 ++ "int $4\n0:\n"
4945 ++#endif
4946 ++ ".pushsection .fixup,\"ax\"\n"
4947 ++ "1:\n"
4948 ++ _ASM_MOV "%0,%1\n"
4949 ++ "jmp 0b\n"
4950 ++ ".popsection\n"
4951 ++ _ASM_EXTABLE(0b, 1b)
4952 ++#endif
4953 ++
4954 + : "+r" (i), "+m" (l->a.counter)
4955 + : : "memory");
4956 + return i + __i;
4957 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/mach-default/apm.h linux-2.6.28.8/arch/x86/include/asm/mach-default/apm.h
4958 +--- linux-2.6.28.8/arch/x86/include/asm/mach-default/apm.h 2009-02-06 16:47:45.000000000 -0500
4959 ++++ linux-2.6.28.8/arch/x86/include/asm/mach-default/apm.h 2009-02-21 09:37:48.000000000 -0500
4960 +@@ -34,7 +34,7 @@ static inline void apm_bios_call_asm(u32
4961 + __asm__ __volatile__(APM_DO_ZERO_SEGS
4962 + "pushl %%edi\n\t"
4963 + "pushl %%ebp\n\t"
4964 +- "lcall *%%cs:apm_bios_entry\n\t"
4965 ++ "lcall *%%ss:apm_bios_entry\n\t"
4966 + "setc %%al\n\t"
4967 + "popl %%ebp\n\t"
4968 + "popl %%edi\n\t"
4969 +@@ -58,7 +58,7 @@ static inline u8 apm_bios_call_simple_as
4970 + __asm__ __volatile__(APM_DO_ZERO_SEGS
4971 + "pushl %%edi\n\t"
4972 + "pushl %%ebp\n\t"
4973 +- "lcall *%%cs:apm_bios_entry\n\t"
4974 ++ "lcall *%%ss:apm_bios_entry\n\t"
4975 + "setc %%bl\n\t"
4976 + "popl %%ebp\n\t"
4977 + "popl %%edi\n\t"
4978 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/mman.h linux-2.6.28.8/arch/x86/include/asm/mman.h
4979 +--- linux-2.6.28.8/arch/x86/include/asm/mman.h 2009-02-06 16:47:45.000000000 -0500
4980 ++++ linux-2.6.28.8/arch/x86/include/asm/mman.h 2009-02-21 09:37:48.000000000 -0500
4981 +@@ -17,4 +17,14 @@
4982 + #define MCL_CURRENT 1 /* lock all current mappings */
4983 + #define MCL_FUTURE 2 /* lock all future mappings */
4984 +
4985 ++#ifdef __KERNEL__
4986 ++#ifndef __ASSEMBLY__
4987 ++#ifdef CONFIG_X86_32
4988 ++#define arch_mmap_check i386_mmap_check
4989 ++int i386_mmap_check(unsigned long addr, unsigned long len,
4990 ++ unsigned long flags);
4991 ++#endif
4992 ++#endif
4993 ++#endif
4994 ++
4995 + #endif /* _ASM_X86_MMAN_H */
4996 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/mmu_context_32.h linux-2.6.28.8/arch/x86/include/asm/mmu_context_32.h
4997 +--- linux-2.6.28.8/arch/x86/include/asm/mmu_context_32.h 2009-02-06 16:47:45.000000000 -0500
4998 ++++ linux-2.6.28.8/arch/x86/include/asm/mmu_context_32.h 2009-02-21 09:37:48.000000000 -0500
4999 +@@ -33,6 +33,22 @@ static inline void switch_mm(struct mm_s
5000 + */
5001 + if (unlikely(prev->context.ldt != next->context.ldt))
5002 + load_LDT_nolock(&next->context);
5003 ++
5004 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
5005 ++ if (!nx_enabled) {
5006 ++ smp_mb__before_clear_bit();
5007 ++ cpu_clear(cpu, prev->context.cpu_user_cs_mask);
5008 ++ smp_mb__after_clear_bit();
5009 ++ cpu_set(cpu, next->context.cpu_user_cs_mask);
5010 ++ }
5011 ++#endif
5012 ++
5013 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5014 ++ if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
5015 ++ prev->context.user_cs_limit != next->context.user_cs_limit))
5016 ++ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
5017 ++#endif
5018 ++
5019 + }
5020 + #ifdef CONFIG_SMP
5021 + else {
5022 +@@ -45,6 +61,19 @@ static inline void switch_mm(struct mm_s
5023 + */
5024 + load_cr3(next->pgd);
5025 + load_LDT_nolock(&next->context);
5026 ++
5027 ++#ifdef CONFIG_PAX_PAGEEXEC
5028 ++ if (!nx_enabled)
5029 ++ cpu_set(cpu, next->context.cpu_user_cs_mask);
5030 ++#endif
5031 ++
5032 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5033 ++#ifdef CONFIG_PAX_PAGEEXEC
5034 ++ if (!((next->pax_flags & MF_PAX_PAGEEXEC) && nx_enabled))
5035 ++#endif
5036 ++ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
5037 ++#endif
5038 ++
5039 + }
5040 + }
5041 + #endif
5042 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/mmu.h linux-2.6.28.8/arch/x86/include/asm/mmu.h
5043 +--- linux-2.6.28.8/arch/x86/include/asm/mmu.h 2009-02-06 16:47:45.000000000 -0500
5044 ++++ linux-2.6.28.8/arch/x86/include/asm/mmu.h 2009-02-21 09:37:48.000000000 -0500
5045 +@@ -9,10 +9,23 @@
5046 + * we put the segment information here.
5047 + */
5048 + typedef struct {
5049 +- void *ldt;
5050 ++ struct desc_struct *ldt;
5051 + int size;
5052 + struct mutex lock;
5053 +- void *vdso;
5054 ++ unsigned long vdso;
5055 ++
5056 ++#ifdef CONFIG_X86_32
5057 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5058 ++ unsigned long user_cs_base;
5059 ++ unsigned long user_cs_limit;
5060 ++
5061 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
5062 ++ cpumask_t cpu_user_cs_mask;
5063 ++#endif
5064 ++
5065 ++#endif
5066 ++#endif
5067 ++
5068 + } mm_context_t;
5069 +
5070 + #ifdef CONFIG_SMP
5071 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/module.h linux-2.6.28.8/arch/x86/include/asm/module.h
5072 +--- linux-2.6.28.8/arch/x86/include/asm/module.h 2009-02-06 16:47:45.000000000 -0500
5073 ++++ linux-2.6.28.8/arch/x86/include/asm/module.h 2009-02-21 09:37:48.000000000 -0500
5074 +@@ -74,7 +74,12 @@ struct mod_arch_specific {};
5075 + # else
5076 + # define MODULE_STACKSIZE ""
5077 + # endif
5078 +-# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
5079 ++# ifdef CONFIG_GRKERNSEC
5080 ++# define MODULE_GRSEC "GRSECURITY "
5081 ++# else
5082 ++# define MODULE_GRSEC ""
5083 ++# endif
5084 ++# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE MODULE_GRSEC
5085 + #endif
5086 +
5087 + #endif /* _ASM_X86_MODULE_H */
5088 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/page_32.h linux-2.6.28.8/arch/x86/include/asm/page_32.h
5089 +--- linux-2.6.28.8/arch/x86/include/asm/page_32.h 2009-02-06 16:47:45.000000000 -0500
5090 ++++ linux-2.6.28.8/arch/x86/include/asm/page_32.h 2009-02-21 09:37:48.000000000 -0500
5091 +@@ -13,6 +13,23 @@
5092 + */
5093 + #define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL)
5094 +
5095 ++#ifdef CONFIG_PAX_KERNEXEC
5096 ++#ifndef __ASSEMBLY__
5097 ++extern unsigned char MODULES_VADDR[];
5098 ++extern unsigned char MODULES_END[];
5099 ++extern unsigned char KERNEL_TEXT_OFFSET[];
5100 ++#define ktla_ktva(addr) (addr + (unsigned long)KERNEL_TEXT_OFFSET)
5101 ++#define ktva_ktla(addr) (addr - (unsigned long)KERNEL_TEXT_OFFSET)
5102 ++#endif
5103 ++#else
5104 ++#define ktla_ktva(addr) (addr)
5105 ++#define ktva_ktla(addr) (addr)
5106 ++#endif
5107 ++
5108 ++#ifdef CONFIG_PAX_PAGEEXEC
5109 ++#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
5110 ++#endif
5111 ++
5112 + #ifdef CONFIG_4KSTACKS
5113 + #define THREAD_ORDER 0
5114 + #else
5115 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/page_64.h linux-2.6.28.8/arch/x86/include/asm/page_64.h
5116 +--- linux-2.6.28.8/arch/x86/include/asm/page_64.h 2009-02-06 16:47:45.000000000 -0500
5117 ++++ linux-2.6.28.8/arch/x86/include/asm/page_64.h 2009-02-21 09:37:48.000000000 -0500
5118 +@@ -49,6 +49,9 @@
5119 + #define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START)
5120 + #define __START_KERNEL_map _AC(0xffffffff80000000, UL)
5121 +
5122 ++#define ktla_ktva(addr) (addr)
5123 ++#define ktva_ktla(addr) (addr)
5124 ++
5125 + /* See Documentation/x86_64/mm.txt for a description of the memory map. */
5126 + #define __PHYSICAL_MASK_SHIFT 46
5127 + #define __VIRTUAL_MASK_SHIFT 48
5128 +@@ -101,5 +104,6 @@ extern void init_extra_mapping_wb(unsign
5129 + #define pfn_valid(pfn) ((pfn) < max_pfn)
5130 + #endif
5131 +
5132 ++#define nx_enabled (1)
5133 +
5134 + #endif /* _ASM_X86_PAGE_64_H */
5135 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/paravirt.h linux-2.6.28.8/arch/x86/include/asm/paravirt.h
5136 +--- linux-2.6.28.8/arch/x86/include/asm/paravirt.h 2009-03-07 10:24:49.000000000 -0500
5137 ++++ linux-2.6.28.8/arch/x86/include/asm/paravirt.h 2009-03-07 10:29:51.000000000 -0500
5138 +@@ -1557,7 +1557,7 @@ static inline unsigned long __raw_local_
5139 + #define PV_RESTORE_REGS popl %edx; popl %ecx; popl %edi; popl %eax
5140 + #define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 4)
5141 + #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .long, 4)
5142 +-#define PARA_INDIRECT(addr) *%cs:addr
5143 ++#define PARA_INDIRECT(addr) *%ss:addr
5144 + #endif
5145 +
5146 + #define INTERRUPT_RETURN \
5147 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/pda.h linux-2.6.28.8/arch/x86/include/asm/pda.h
5148 +--- linux-2.6.28.8/arch/x86/include/asm/pda.h 2009-02-06 16:47:45.000000000 -0500
5149 ++++ linux-2.6.28.8/arch/x86/include/asm/pda.h 2009-02-21 09:37:48.000000000 -0500
5150 +@@ -16,11 +16,9 @@ struct x8664_pda {
5151 + unsigned long oldrsp; /* 24 user rsp for system call */
5152 + int irqcount; /* 32 Irq nesting counter. Starts -1 */
5153 + unsigned int cpunumber; /* 36 Logical CPU number */
5154 +-#ifdef CONFIG_CC_STACKPROTECTOR
5155 + unsigned long stack_canary; /* 40 stack canary value */
5156 + /* gcc-ABI: this canary MUST be at
5157 + offset 40!!! */
5158 +-#endif
5159 + char *irqstackptr;
5160 + short nodenumber; /* number of current node (32k max) */
5161 + short in_bootmem; /* pda lives in bootmem */
5162 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/percpu.h linux-2.6.28.8/arch/x86/include/asm/percpu.h
5163 +--- linux-2.6.28.8/arch/x86/include/asm/percpu.h 2009-02-06 16:47:45.000000000 -0500
5164 ++++ linux-2.6.28.8/arch/x86/include/asm/percpu.h 2009-02-21 09:37:48.000000000 -0500
5165 +@@ -93,6 +93,12 @@ DECLARE_PER_CPU(struct x8664_pda, pda);
5166 +
5167 + #define __my_cpu_offset x86_read_percpu(this_cpu_off)
5168 +
5169 ++#include <asm-generic/sections.h>
5170 ++#include <linux/threads.h>
5171 ++#define __per_cpu_offset __per_cpu_offset
5172 ++extern unsigned long __per_cpu_offset[NR_CPUS];
5173 ++#define per_cpu_offset(x) (__per_cpu_offset[x] + (unsigned long)__per_cpu_start)
5174 ++
5175 + /* fs segment starts at (positive) offset == __per_cpu_offset[cpu] */
5176 + #define __percpu_seg "%%fs:"
5177 +
5178 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/pgalloc.h linux-2.6.28.8/arch/x86/include/asm/pgalloc.h
5179 +--- linux-2.6.28.8/arch/x86/include/asm/pgalloc.h 2009-02-06 16:47:45.000000000 -0500
5180 ++++ linux-2.6.28.8/arch/x86/include/asm/pgalloc.h 2009-02-21 09:37:48.000000000 -0500
5181 +@@ -52,7 +52,7 @@ static inline void pmd_populate_kernel(s
5182 + pmd_t *pmd, pte_t *pte)
5183 + {
5184 + paravirt_alloc_pte(mm, __pa(pte) >> PAGE_SHIFT);
5185 +- set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
5186 ++ set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE));
5187 + }
5188 +
5189 + static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
5190 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/pgtable-2level.h linux-2.6.28.8/arch/x86/include/asm/pgtable-2level.h
5191 +--- linux-2.6.28.8/arch/x86/include/asm/pgtable-2level.h 2009-02-06 16:47:45.000000000 -0500
5192 ++++ linux-2.6.28.8/arch/x86/include/asm/pgtable-2level.h 2009-02-21 09:37:48.000000000 -0500
5193 +@@ -18,7 +18,19 @@ static inline void native_set_pte(pte_t
5194 +
5195 + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
5196 + {
5197 ++
5198 ++#ifdef CONFIG_PAX_KERNEXEC
5199 ++ unsigned long cr0;
5200 ++
5201 ++ pax_open_kernel(cr0);
5202 ++#endif
5203 ++
5204 + *pmdp = pmd;
5205 ++
5206 ++#ifdef CONFIG_PAX_KERNEXEC
5207 ++ pax_close_kernel(cr0);
5208 ++#endif
5209 ++
5210 + }
5211 +
5212 + static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
5213 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/pgtable_32.h linux-2.6.28.8/arch/x86/include/asm/pgtable_32.h
5214 +--- linux-2.6.28.8/arch/x86/include/asm/pgtable_32.h 2009-02-06 16:47:45.000000000 -0500
5215 ++++ linux-2.6.28.8/arch/x86/include/asm/pgtable_32.h 2009-02-21 09:37:48.000000000 -0500
5216 +@@ -25,8 +25,6 @@
5217 + struct mm_struct;
5218 + struct vm_area_struct;
5219 +
5220 +-extern pgd_t swapper_pg_dir[1024];
5221 +-
5222 + static inline void pgtable_cache_init(void) { }
5223 + static inline void check_pgt_cache(void) { }
5224 + void paging_init(void);
5225 +@@ -46,6 +44,11 @@ extern void set_pmd_pfn(unsigned long, u
5226 + # include <asm/pgtable-2level-defs.h>
5227 + #endif
5228 +
5229 ++extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
5230 ++#ifdef CONFIG_X86_PAE
5231 ++extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
5232 ++#endif
5233 ++
5234 + #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
5235 + #define PGDIR_MASK (~(PGDIR_SIZE - 1))
5236 +
5237 +@@ -83,7 +86,7 @@ extern void set_pmd_pfn(unsigned long, u
5238 + #undef TEST_ACCESS_OK
5239 +
5240 + /* The boot page tables (all created as a single array) */
5241 +-extern unsigned long pg0[];
5242 ++extern pte_t pg0[];
5243 +
5244 + #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
5245 +
5246 +@@ -175,6 +178,9 @@ do { \
5247 +
5248 + #endif /* !__ASSEMBLY__ */
5249 +
5250 ++#define HAVE_ARCH_UNMAPPED_AREA
5251 ++#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
5252 ++
5253 + /*
5254 + * kern_addr_valid() is (1) for FLATMEM and (0) for
5255 + * SPARSEMEM and DISCONTIGMEM
5256 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/pgtable-3level.h linux-2.6.28.8/arch/x86/include/asm/pgtable-3level.h
5257 +--- linux-2.6.28.8/arch/x86/include/asm/pgtable-3level.h 2009-02-06 16:47:45.000000000 -0500
5258 ++++ linux-2.6.28.8/arch/x86/include/asm/pgtable-3level.h 2009-02-21 09:37:48.000000000 -0500
5259 +@@ -70,12 +70,36 @@ static inline void native_set_pte_atomic
5260 +
5261 + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
5262 + {
5263 ++
5264 ++#ifdef CONFIG_PAX_KERNEXEC
5265 ++ unsigned long cr0;
5266 ++
5267 ++ pax_open_kernel(cr0);
5268 ++#endif
5269 ++
5270 + set_64bit((unsigned long long *)(pmdp), native_pmd_val(pmd));
5271 ++
5272 ++#ifdef CONFIG_PAX_KERNEXEC
5273 ++ pax_close_kernel(cr0);
5274 ++#endif
5275 ++
5276 + }
5277 +
5278 + static inline void native_set_pud(pud_t *pudp, pud_t pud)
5279 + {
5280 ++
5281 ++#ifdef CONFIG_PAX_KERNEXEC
5282 ++ unsigned long cr0;
5283 ++
5284 ++ pax_open_kernel(cr0);
5285 ++#endif
5286 ++
5287 + set_64bit((unsigned long long *)(pudp), native_pud_val(pud));
5288 ++
5289 ++#ifdef CONFIG_PAX_KERNEXEC
5290 ++ pax_close_kernel(cr0);
5291 ++#endif
5292 ++
5293 + }
5294 +
5295 + /*
5296 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/pgtable_64.h linux-2.6.28.8/arch/x86/include/asm/pgtable_64.h
5297 +--- linux-2.6.28.8/arch/x86/include/asm/pgtable_64.h 2009-02-06 16:47:45.000000000 -0500
5298 ++++ linux-2.6.28.8/arch/x86/include/asm/pgtable_64.h 2009-02-21 09:37:48.000000000 -0500
5299 +@@ -15,9 +15,12 @@
5300 +
5301 + extern pud_t level3_kernel_pgt[512];
5302 + extern pud_t level3_ident_pgt[512];
5303 ++extern pud_t level3_vmalloc_pgt[512];
5304 ++extern pud_t level3_vmemmap_pgt[512];
5305 + extern pmd_t level2_kernel_pgt[512];
5306 + extern pmd_t level2_fixmap_pgt[512];
5307 +-extern pmd_t level2_ident_pgt[512];
5308 ++extern pmd_t level2_ident_pgt[512*4];
5309 ++extern pte_t level1_fixmap_pgt[512];
5310 + extern pgd_t init_level4_pgt[];
5311 +
5312 + #define swapper_pg_dir init_level4_pgt
5313 +@@ -106,7 +109,19 @@ static inline pte_t native_ptep_get_and_
5314 +
5315 + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
5316 + {
5317 ++
5318 ++#ifdef CONFIG_PAX_KERNEXEC
5319 ++ unsigned long cr0;
5320 ++
5321 ++ pax_open_kernel(cr0);
5322 ++#endif
5323 ++
5324 + *pmdp = pmd;
5325 ++
5326 ++#ifdef CONFIG_PAX_KERNEXEC
5327 ++ pax_close_kernel(cr0);
5328 ++#endif
5329 ++
5330 + }
5331 +
5332 + static inline void native_pmd_clear(pmd_t *pmd)
5333 +@@ -158,17 +173,17 @@ static inline void native_pgd_clear(pgd_
5334 +
5335 + static inline int pgd_bad(pgd_t pgd)
5336 + {
5337 +- return (pgd_val(pgd) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
5338 ++ return (pgd_val(pgd) & ~(PTE_PFN_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
5339 + }
5340 +
5341 + static inline int pud_bad(pud_t pud)
5342 + {
5343 +- return (pud_val(pud) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
5344 ++ return (pud_val(pud) & ~(PTE_PFN_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
5345 + }
5346 +
5347 + static inline int pmd_bad(pmd_t pmd)
5348 + {
5349 +- return (pmd_val(pmd) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
5350 ++ return (pmd_val(pmd) & ~(PTE_PFN_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
5351 + }
5352 +
5353 + #define pte_none(x) (!pte_val((x)))
5354 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/pgtable.h linux-2.6.28.8/arch/x86/include/asm/pgtable.h
5355 +--- linux-2.6.28.8/arch/x86/include/asm/pgtable.h 2009-02-06 16:47:45.000000000 -0500
5356 ++++ linux-2.6.28.8/arch/x86/include/asm/pgtable.h 2009-02-21 09:37:48.000000000 -0500
5357 +@@ -14,12 +14,11 @@
5358 + #define _PAGE_BIT_PSE 7 /* 4 MB (or 2MB) page */
5359 + #define _PAGE_BIT_PAT 7 /* on 4KB pages */
5360 + #define _PAGE_BIT_GLOBAL 8 /* Global TLB entry PPro+ */
5361 +-#define _PAGE_BIT_UNUSED1 9 /* available for programmer */
5362 ++#define _PAGE_BIT_SPECIAL 9 /* special mappings, no associated struct page */
5363 + #define _PAGE_BIT_IOMAP 10 /* flag used to indicate IO mapping */
5364 + #define _PAGE_BIT_UNUSED3 11
5365 + #define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */
5366 +-#define _PAGE_BIT_SPECIAL _PAGE_BIT_UNUSED1
5367 +-#define _PAGE_BIT_CPA_TEST _PAGE_BIT_UNUSED1
5368 ++#define _PAGE_BIT_CPA_TEST _PAGE_BIT_SPECIAL
5369 + #define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */
5370 +
5371 + #define _PAGE_PRESENT (_AT(pteval_t, 1) << _PAGE_BIT_PRESENT)
5372 +@@ -31,7 +30,6 @@
5373 + #define _PAGE_DIRTY (_AT(pteval_t, 1) << _PAGE_BIT_DIRTY)
5374 + #define _PAGE_PSE (_AT(pteval_t, 1) << _PAGE_BIT_PSE)
5375 + #define _PAGE_GLOBAL (_AT(pteval_t, 1) << _PAGE_BIT_GLOBAL)
5376 +-#define _PAGE_UNUSED1 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED1)
5377 + #define _PAGE_IOMAP (_AT(pteval_t, 1) << _PAGE_BIT_IOMAP)
5378 + #define _PAGE_UNUSED3 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED3)
5379 + #define _PAGE_PAT (_AT(pteval_t, 1) << _PAGE_BIT_PAT)
5380 +@@ -43,7 +41,7 @@
5381 + #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
5382 + #define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_NX)
5383 + #else
5384 +-#define _PAGE_NX (_AT(pteval_t, 0))
5385 ++#define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED3)
5386 + #endif
5387 +
5388 + /* If _PAGE_PRESENT is clear, we use these: */
5389 +@@ -83,6 +81,9 @@
5390 + #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \
5391 + _PAGE_ACCESSED)
5392 +
5393 ++#define PAGE_READONLY_NOEXEC PAGE_READONLY
5394 ++#define PAGE_SHARED_NOEXEC PAGE_SHARED
5395 ++
5396 + #define __PAGE_KERNEL_EXEC \
5397 + (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL)
5398 + #define __PAGE_KERNEL (__PAGE_KERNEL_EXEC | _PAGE_NX)
5399 +@@ -94,7 +95,7 @@
5400 + #define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
5401 + #define __PAGE_KERNEL_UC_MINUS (__PAGE_KERNEL | _PAGE_PCD)
5402 + #define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER)
5403 +-#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
5404 ++#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_RO | _PAGE_PCD | _PAGE_PWT | _PAGE_USER)
5405 + #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE)
5406 + #define __PAGE_KERNEL_LARGE_NOCACHE (__PAGE_KERNEL | _PAGE_CACHE_UC | _PAGE_PSE)
5407 + #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE)
5408 +@@ -153,7 +154,7 @@
5409 + * bits are combined, this will alow user to access the high address mapped
5410 + * VDSO in the presence of CONFIG_COMPAT_VDSO
5411 + */
5412 +-#define PTE_IDENT_ATTR 0x003 /* PRESENT+RW */
5413 ++#define PTE_IDENT_ATTR 0x063 /* PRESENT+RW+DIRTY+ACCESSED */
5414 + #define PDE_IDENT_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
5415 + #define PGD_IDENT_ATTR 0x001 /* PRESENT (no other attributes) */
5416 + #endif
5417 +@@ -170,10 +171,17 @@ extern unsigned long empty_zero_page[PAG
5418 + extern spinlock_t pgd_lock;
5419 + extern struct list_head pgd_list;
5420 +
5421 ++extern pteval_t __supported_pte_mask;
5422 ++
5423 + /*
5424 + * The following only work if pte_present() is true.
5425 + * Undefined behaviour if not..
5426 + */
5427 ++static inline int pte_user(pte_t pte)
5428 ++{
5429 ++ return pte_val(pte) & _PAGE_USER;
5430 ++}
5431 ++
5432 + static inline int pte_dirty(pte_t pte)
5433 + {
5434 + return pte_flags(pte) & _PAGE_DIRTY;
5435 +@@ -242,9 +250,29 @@ static inline pte_t pte_wrprotect(pte_t
5436 + return __pte(pte_val(pte) & ~_PAGE_RW);
5437 + }
5438 +
5439 ++static inline pte_t pte_mkread(pte_t pte)
5440 ++{
5441 ++ return __pte(pte_val(pte) | _PAGE_USER);
5442 ++}
5443 ++
5444 + static inline pte_t pte_mkexec(pte_t pte)
5445 + {
5446 +- return __pte(pte_val(pte) & ~_PAGE_NX);
5447 ++#ifdef CONFIG_X86_PAE
5448 ++ if (__supported_pte_mask & _PAGE_NX)
5449 ++ return __pte(pte_val(pte) & ~(pteval_t)_PAGE_NX);
5450 ++ else
5451 ++#endif
5452 ++ return __pte(pte_val(pte) | _PAGE_USER);
5453 ++}
5454 ++
5455 ++static inline pte_t pte_exprotect(pte_t pte)
5456 ++{
5457 ++#ifdef CONFIG_X86_PAE
5458 ++ if (__supported_pte_mask & _PAGE_NX)
5459 ++ return __pte(pte_val(pte) | _PAGE_NX);
5460 ++ else
5461 ++#endif
5462 ++ return __pte(pte_val(pte) & ~_PAGE_USER);
5463 + }
5464 +
5465 + static inline pte_t pte_mkdirty(pte_t pte)
5466 +@@ -287,8 +315,6 @@ static inline pte_t pte_mkspecial(pte_t
5467 + return __pte(pte_val(pte) | _PAGE_SPECIAL);
5468 + }
5469 +
5470 +-extern pteval_t __supported_pte_mask;
5471 +-
5472 + static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
5473 + {
5474 + return __pte((((phys_addr_t)page_nr << PAGE_SHIFT) |
5475 +@@ -552,7 +578,19 @@ static inline void ptep_set_wrprotect(st
5476 + */
5477 + static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
5478 + {
5479 +- memcpy(dst, src, count * sizeof(pgd_t));
5480 ++
5481 ++#ifdef CONFIG_PAX_KERNEXEC
5482 ++ unsigned long cr0;
5483 ++
5484 ++ pax_open_kernel(cr0);
5485 ++#endif
5486 ++
5487 ++ memcpy(dst, src, count * sizeof(pgd_t));
5488 ++
5489 ++#ifdef CONFIG_PAX_KERNEXEC
5490 ++ pax_close_kernel(cr0);
5491 ++#endif
5492 ++
5493 + }
5494 +
5495 +
5496 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/processor.h linux-2.6.28.8/arch/x86/include/asm/processor.h
5497 +--- linux-2.6.28.8/arch/x86/include/asm/processor.h 2009-03-07 10:24:49.000000000 -0500
5498 ++++ linux-2.6.28.8/arch/x86/include/asm/processor.h 2009-03-07 10:29:51.000000000 -0500
5499 +@@ -271,7 +271,7 @@ struct tss_struct {
5500 +
5501 + } ____cacheline_aligned;
5502 +
5503 +-DECLARE_PER_CPU(struct tss_struct, init_tss);
5504 ++extern struct tss_struct init_tss[NR_CPUS];
5505 +
5506 + /*
5507 + * Save the original ist values for checking stack pointers during debugging
5508 +@@ -822,11 +822,20 @@ static inline void spin_lock_prefetch(co
5509 + * User space process size: 3GB (default).
5510 + */
5511 + #define TASK_SIZE PAGE_OFFSET
5512 ++
5513 ++#ifdef CONFIG_PAX_SEGMEXEC
5514 ++#define SEGMEXEC_TASK_SIZE (TASK_SIZE / 2)
5515 ++#endif
5516 ++
5517 ++#ifdef CONFIG_PAX_SEGMEXEC
5518 ++#define STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE:TASK_SIZE)
5519 ++#else
5520 + #define STACK_TOP TASK_SIZE
5521 +-#define STACK_TOP_MAX STACK_TOP
5522 ++#endif
5523 ++#define STACK_TOP_MAX TASK_SIZE
5524 +
5525 + #define INIT_THREAD { \
5526 +- .sp0 = sizeof(init_stack) + (long)&init_stack, \
5527 ++ .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
5528 + .vm86_info = NULL, \
5529 + .sysenter_cs = __KERNEL_CS, \
5530 + .io_bitmap_ptr = NULL, \
5531 +@@ -841,7 +850,7 @@ static inline void spin_lock_prefetch(co
5532 + */
5533 + #define INIT_TSS { \
5534 + .x86_tss = { \
5535 +- .sp0 = sizeof(init_stack) + (long)&init_stack, \
5536 ++ .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
5537 + .ss0 = __KERNEL_DS, \
5538 + .ss1 = __KERNEL_CS, \
5539 + .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
5540 +@@ -852,11 +861,7 @@ static inline void spin_lock_prefetch(co
5541 + extern unsigned long thread_saved_pc(struct task_struct *tsk);
5542 +
5543 + #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
5544 +-#define KSTK_TOP(info) \
5545 +-({ \
5546 +- unsigned long *__ptr = (unsigned long *)(info); \
5547 +- (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
5548 +-})
5549 ++#define KSTK_TOP(info) ((info)->task.thread.sp0)
5550 +
5551 + /*
5552 + * The below -8 is to reserve 8 bytes on top of the ring0 stack.
5553 +@@ -871,7 +876,7 @@ extern unsigned long thread_saved_pc(str
5554 + #define task_pt_regs(task) \
5555 + ({ \
5556 + struct pt_regs *__regs__; \
5557 +- __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
5558 ++ __regs__ = (struct pt_regs *)((task)->thread.sp0); \
5559 + __regs__ - 1; \
5560 + })
5561 +
5562 +@@ -887,7 +892,7 @@ extern unsigned long thread_saved_pc(str
5563 + * space during mmap's.
5564 + */
5565 + #define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? \
5566 +- 0xc0000000 : 0xFFFFe000)
5567 ++ 0xc0000000 : 0xFFFFf000)
5568 +
5569 + #define TASK_SIZE (test_thread_flag(TIF_IA32) ? \
5570 + IA32_PAGE_OFFSET : TASK_SIZE64)
5571 +@@ -924,6 +929,10 @@ extern void start_thread(struct pt_regs
5572 + */
5573 + #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
5574 +
5575 ++#ifdef CONFIG_PAX_SEGMEXEC
5576 ++#define SEGMEXEC_TASK_UNMAPPED_BASE (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3))
5577 ++#endif
5578 ++
5579 + #define KSTK_EIP(task) (task_pt_regs(task)->ip)
5580 +
5581 + /* Get/set a process' ability to use the timestamp counter instruction */
5582 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/ptrace.h linux-2.6.28.8/arch/x86/include/asm/ptrace.h
5583 +--- linux-2.6.28.8/arch/x86/include/asm/ptrace.h 2009-02-06 16:47:45.000000000 -0500
5584 ++++ linux-2.6.28.8/arch/x86/include/asm/ptrace.h 2009-02-21 09:37:48.000000000 -0500
5585 +@@ -187,28 +187,29 @@ static inline unsigned long regs_return_
5586 + }
5587 +
5588 + /*
5589 +- * user_mode_vm(regs) determines whether a register set came from user mode.
5590 ++ * user_mode(regs) determines whether a register set came from user mode.
5591 + * This is true if V8086 mode was enabled OR if the register set was from
5592 + * protected mode with RPL-3 CS value. This tricky test checks that with
5593 + * one comparison. Many places in the kernel can bypass this full check
5594 +- * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
5595 ++ * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
5596 ++ * be used.
5597 + */
5598 +-static inline int user_mode(struct pt_regs *regs)
5599 ++static inline int user_mode_novm(struct pt_regs *regs)
5600 + {
5601 + #ifdef CONFIG_X86_32
5602 + return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL;
5603 + #else
5604 +- return !!(regs->cs & 3);
5605 ++ return !!(regs->cs & SEGMENT_RPL_MASK);
5606 + #endif
5607 + }
5608 +
5609 +-static inline int user_mode_vm(struct pt_regs *regs)
5610 ++static inline int user_mode(struct pt_regs *regs)
5611 + {
5612 + #ifdef CONFIG_X86_32
5613 + return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >=
5614 + USER_RPL;
5615 + #else
5616 +- return user_mode(regs);
5617 ++ return user_mode_novm(regs);
5618 + #endif
5619 + }
5620 +
5621 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/reboot.h linux-2.6.28.8/arch/x86/include/asm/reboot.h
5622 +--- linux-2.6.28.8/arch/x86/include/asm/reboot.h 2009-02-06 16:47:45.000000000 -0500
5623 ++++ linux-2.6.28.8/arch/x86/include/asm/reboot.h 2009-02-21 09:37:48.000000000 -0500
5624 +@@ -16,6 +16,6 @@ extern struct machine_ops machine_ops;
5625 +
5626 + void native_machine_crash_shutdown(struct pt_regs *regs);
5627 + void native_machine_shutdown(void);
5628 +-void machine_real_restart(const unsigned char *code, int length);
5629 ++void machine_real_restart(const unsigned char *code, unsigned int length);
5630 +
5631 + #endif /* _ASM_X86_REBOOT_H */
5632 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/rwsem.h linux-2.6.28.8/arch/x86/include/asm/rwsem.h
5633 +--- linux-2.6.28.8/arch/x86/include/asm/rwsem.h 2009-02-06 16:47:45.000000000 -0500
5634 ++++ linux-2.6.28.8/arch/x86/include/asm/rwsem.h 2009-02-21 09:37:48.000000000 -0500
5635 +@@ -106,10 +106,26 @@ static inline void __down_read(struct rw
5636 + {
5637 + asm volatile("# beginning down_read\n\t"
5638 + LOCK_PREFIX " incl (%%eax)\n\t"
5639 ++
5640 ++#ifdef CONFIG_PAX_REFCOUNT
5641 ++#ifdef CONFIG_X86_32
5642 ++ "into\n0:\n"
5643 ++#else
5644 ++ "jno 0f\n"
5645 ++ "int $4\n0:\n"
5646 ++#endif
5647 ++ ".pushsection .fixup,\"ax\"\n"
5648 ++ "1:\n"
5649 ++ LOCK_PREFIX "decl (%%eax)\n"
5650 ++ "jmp 0b\n"
5651 ++ ".popsection\n"
5652 ++ _ASM_EXTABLE(0b, 1b)
5653 ++#endif
5654 ++
5655 + /* adds 0x00000001, returns the old value */
5656 +- " jns 1f\n"
5657 ++ " jns 2f\n"
5658 + " call call_rwsem_down_read_failed\n"
5659 +- "1:\n\t"
5660 ++ "2:\n\t"
5661 + "# ending down_read\n\t"
5662 + : "+m" (sem->count)
5663 + : "a" (sem)
5664 +@@ -124,13 +140,29 @@ static inline int __down_read_trylock(st
5665 + __s32 result, tmp;
5666 + asm volatile("# beginning __down_read_trylock\n\t"
5667 + " movl %0,%1\n\t"
5668 +- "1:\n\t"
5669 ++ "2:\n\t"
5670 + " movl %1,%2\n\t"
5671 + " addl %3,%2\n\t"
5672 +- " jle 2f\n\t"
5673 ++
5674 ++#ifdef CONFIG_PAX_REFCOUNT
5675 ++#ifdef CONFIG_X86_32
5676 ++ "into\n0:\n"
5677 ++#else
5678 ++ "jno 0f\n"
5679 ++ "int $4\n0:\n"
5680 ++#endif
5681 ++ ".pushsection .fixup,\"ax\"\n"
5682 ++ "1:\n"
5683 ++ "subl %3,%2\n"
5684 ++ "jmp 0b\n"
5685 ++ ".popsection\n"
5686 ++ _ASM_EXTABLE(0b, 1b)
5687 ++#endif
5688 ++
5689 ++ " jle 3f\n\t"
5690 + LOCK_PREFIX " cmpxchgl %2,%0\n\t"
5691 +- " jnz 1b\n\t"
5692 +- "2:\n\t"
5693 ++ " jnz 2b\n\t"
5694 ++ "3:\n\t"
5695 + "# ending __down_read_trylock\n\t"
5696 + : "+m" (sem->count), "=&a" (result), "=&r" (tmp)
5697 + : "i" (RWSEM_ACTIVE_READ_BIAS)
5698 +@@ -148,12 +180,28 @@ static inline void __down_write_nested(s
5699 + tmp = RWSEM_ACTIVE_WRITE_BIAS;
5700 + asm volatile("# beginning down_write\n\t"
5701 + LOCK_PREFIX " xadd %%edx,(%%eax)\n\t"
5702 ++
5703 ++#ifdef CONFIG_PAX_REFCOUNT
5704 ++#ifdef CONFIG_X86_32
5705 ++ "into\n0:\n"
5706 ++#else
5707 ++ "jno 0f\n"
5708 ++ "int $4\n0:\n"
5709 ++#endif
5710 ++ ".pushsection .fixup,\"ax\"\n"
5711 ++ "1:\n"
5712 ++ "movl %%edx,(%%eax)\n"
5713 ++ "jmp 0b\n"
5714 ++ ".popsection\n"
5715 ++ _ASM_EXTABLE(0b, 1b)
5716 ++#endif
5717 ++
5718 + /* subtract 0x0000ffff, returns the old value */
5719 + " testl %%edx,%%edx\n\t"
5720 + /* was the count 0 before? */
5721 +- " jz 1f\n"
5722 ++ " jz 2f\n"
5723 + " call call_rwsem_down_write_failed\n"
5724 +- "1:\n"
5725 ++ "2:\n"
5726 + "# ending down_write"
5727 + : "+m" (sem->count), "=d" (tmp)
5728 + : "a" (sem), "1" (tmp)
5729 +@@ -186,10 +234,26 @@ static inline void __up_read(struct rw_s
5730 + __s32 tmp = -RWSEM_ACTIVE_READ_BIAS;
5731 + asm volatile("# beginning __up_read\n\t"
5732 + LOCK_PREFIX " xadd %%edx,(%%eax)\n\t"
5733 ++
5734 ++#ifdef CONFIG_PAX_REFCOUNT
5735 ++#ifdef CONFIG_X86_32
5736 ++ "into\n0:\n"
5737 ++#else
5738 ++ "jno 0f\n"
5739 ++ "int $4\n0:\n"
5740 ++#endif
5741 ++ ".pushsection .fixup,\"ax\"\n"
5742 ++ "1:\n"
5743 ++ "movl %%edx,(%%eax)\n"
5744 ++ "jmp 0b\n"
5745 ++ ".popsection\n"
5746 ++ _ASM_EXTABLE(0b, 1b)
5747 ++#endif
5748 ++
5749 + /* subtracts 1, returns the old value */
5750 +- " jns 1f\n\t"
5751 ++ " jns 2f\n\t"
5752 + " call call_rwsem_wake\n"
5753 +- "1:\n"
5754 ++ "2:\n"
5755 + "# ending __up_read\n"
5756 + : "+m" (sem->count), "=d" (tmp)
5757 + : "a" (sem), "1" (tmp)
5758 +@@ -204,11 +268,27 @@ static inline void __up_write(struct rw_
5759 + asm volatile("# beginning __up_write\n\t"
5760 + " movl %2,%%edx\n\t"
5761 + LOCK_PREFIX " xaddl %%edx,(%%eax)\n\t"
5762 ++
5763 ++#ifdef CONFIG_PAX_REFCOUNT
5764 ++#ifdef CONFIG_X86_32
5765 ++ "into\n0:\n"
5766 ++#else
5767 ++ "jno 0f\n"
5768 ++ "int $4\n0:\n"
5769 ++#endif
5770 ++ ".pushsection .fixup,\"ax\"\n"
5771 ++ "1:\n"
5772 ++ "movl %%edx,(%%eax)\n"
5773 ++ "jmp 0b\n"
5774 ++ ".popsection\n"
5775 ++ _ASM_EXTABLE(0b, 1b)
5776 ++#endif
5777 ++
5778 + /* tries to transition
5779 + 0xffff0001 -> 0x00000000 */
5780 +- " jz 1f\n"
5781 ++ " jz 2f\n"
5782 + " call call_rwsem_wake\n"
5783 +- "1:\n\t"
5784 ++ "2:\n\t"
5785 + "# ending __up_write\n"
5786 + : "+m" (sem->count)
5787 + : "a" (sem), "i" (-RWSEM_ACTIVE_WRITE_BIAS)
5788 +@@ -222,10 +302,26 @@ static inline void __downgrade_write(str
5789 + {
5790 + asm volatile("# beginning __downgrade_write\n\t"
5791 + LOCK_PREFIX " addl %2,(%%eax)\n\t"
5792 ++
5793 ++#ifdef CONFIG_PAX_REFCOUNT
5794 ++#ifdef CONFIG_X86_32
5795 ++ "into\n0:\n"
5796 ++#else
5797 ++ "jno 0f\n"
5798 ++ "int $4\n0:\n"
5799 ++#endif
5800 ++ ".pushsection .fixup,\"ax\"\n"
5801 ++ "1:\n"
5802 ++ LOCK_PREFIX "subl %2,(%%eax)\n"
5803 ++ "jmp 0b\n"
5804 ++ ".popsection\n"
5805 ++ _ASM_EXTABLE(0b, 1b)
5806 ++#endif
5807 ++
5808 + /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
5809 +- " jns 1f\n\t"
5810 ++ " jns 2f\n\t"
5811 + " call call_rwsem_downgrade_wake\n"
5812 +- "1:\n\t"
5813 ++ "2:\n\t"
5814 + "# ending __downgrade_write\n"
5815 + : "+m" (sem->count)
5816 + : "a" (sem), "i" (-RWSEM_WAITING_BIAS)
5817 +@@ -237,7 +333,23 @@ static inline void __downgrade_write(str
5818 + */
5819 + static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
5820 + {
5821 +- asm volatile(LOCK_PREFIX "addl %1,%0"
5822 ++ asm volatile(LOCK_PREFIX "addl %1,%0\n"
5823 ++
5824 ++#ifdef CONFIG_PAX_REFCOUNT
5825 ++#ifdef CONFIG_X86_32
5826 ++ "into\n0:\n"
5827 ++#else
5828 ++ "jno 0f\n"
5829 ++ "int $4\n0:\n"
5830 ++#endif
5831 ++ ".pushsection .fixup,\"ax\"\n"
5832 ++ "1:\n"
5833 ++ LOCK_PREFIX "subl %1,%0\n"
5834 ++ "jmp 0b\n"
5835 ++ ".popsection\n"
5836 ++ _ASM_EXTABLE(0b, 1b)
5837 ++#endif
5838 ++
5839 + : "+m" (sem->count)
5840 + : "ir" (delta));
5841 + }
5842 +@@ -249,7 +361,23 @@ static inline int rwsem_atomic_update(in
5843 + {
5844 + int tmp = delta;
5845 +
5846 +- asm volatile(LOCK_PREFIX "xadd %0,%1"
5847 ++ asm volatile(LOCK_PREFIX "xadd %0,%1\n"
5848 ++
5849 ++#ifdef CONFIG_PAX_REFCOUNT
5850 ++#ifdef CONFIG_X86_32
5851 ++ "into\n0:\n"
5852 ++#else
5853 ++ "jno 0f\n"
5854 ++ "int $4\n0:\n"
5855 ++#endif
5856 ++ ".pushsection .fixup,\"ax\"\n"
5857 ++ "1:\n"
5858 ++ "movl %0,%1\n"
5859 ++ "jmp 0b\n"
5860 ++ ".popsection\n"
5861 ++ _ASM_EXTABLE(0b, 1b)
5862 ++#endif
5863 ++
5864 + : "+r" (tmp), "+m" (sem->count)
5865 + : : "memory");
5866 +
5867 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/segment.h linux-2.6.28.8/arch/x86/include/asm/segment.h
5868 +--- linux-2.6.28.8/arch/x86/include/asm/segment.h 2009-02-06 16:47:45.000000000 -0500
5869 ++++ linux-2.6.28.8/arch/x86/include/asm/segment.h 2009-02-21 09:37:48.000000000 -0500
5870 +@@ -88,13 +88,19 @@
5871 + #define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14)
5872 + #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
5873 +
5874 +-#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
5875 ++#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
5876 + #ifdef CONFIG_SMP
5877 + #define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
5878 + #else
5879 + #define __KERNEL_PERCPU 0
5880 + #endif
5881 +
5882 ++#define GDT_ENTRY_PCIBIOS_CS (GDT_ENTRY_KERNEL_BASE + 16)
5883 ++#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8)
5884 ++
5885 ++#define GDT_ENTRY_PCIBIOS_DS (GDT_ENTRY_KERNEL_BASE + 17)
5886 ++#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8)
5887 ++
5888 + #define GDT_ENTRY_DOUBLEFAULT_TSS 31
5889 +
5890 + /*
5891 +@@ -132,7 +138,7 @@
5892 + */
5893 +
5894 + /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
5895 +-#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
5896 ++#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
5897 +
5898 +
5899 + #else
5900 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/spinlock.h linux-2.6.28.8/arch/x86/include/asm/spinlock.h
5901 +--- linux-2.6.28.8/arch/x86/include/asm/spinlock.h 2009-02-06 16:47:45.000000000 -0500
5902 ++++ linux-2.6.28.8/arch/x86/include/asm/spinlock.h 2009-02-21 09:37:48.000000000 -0500
5903 +@@ -310,18 +310,50 @@ static inline int __raw_write_can_lock(r
5904 + static inline void __raw_read_lock(raw_rwlock_t *rw)
5905 + {
5906 + asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t"
5907 +- "jns 1f\n"
5908 +- "call __read_lock_failed\n\t"
5909 ++
5910 ++#ifdef CONFIG_PAX_REFCOUNT
5911 ++#ifdef CONFIG_X86_32
5912 ++ "into\n0:\n"
5913 ++#else
5914 ++ "jno 0f\n"
5915 ++ "int $4\n0:\n"
5916 ++#endif
5917 ++ ".pushsection .fixup,\"ax\"\n"
5918 + "1:\n"
5919 ++ LOCK_PREFIX " addl $1,(%0)\n"
5920 ++ "jmp 0b\n"
5921 ++ ".popsection\n"
5922 ++ _ASM_EXTABLE(0b, 1b)
5923 ++#endif
5924 ++
5925 ++ "jns 2f\n"
5926 ++ "call __read_lock_failed\n\t"
5927 ++ "2:\n"
5928 + ::LOCK_PTR_REG (rw) : "memory");
5929 + }
5930 +
5931 + static inline void __raw_write_lock(raw_rwlock_t *rw)
5932 + {
5933 + asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t"
5934 +- "jz 1f\n"
5935 +- "call __write_lock_failed\n\t"
5936 ++
5937 ++#ifdef CONFIG_PAX_REFCOUNT
5938 ++#ifdef CONFIG_X86_32
5939 ++ "into\n0:\n"
5940 ++#else
5941 ++ "jno 0f\n"
5942 ++ "int $4\n0:\n"
5943 ++#endif
5944 ++ ".pushsection .fixup,\"ax\"\n"
5945 + "1:\n"
5946 ++ LOCK_PREFIX " addl %1,(%0)\n"
5947 ++ "jmp 0b\n"
5948 ++ ".popsection\n"
5949 ++ _ASM_EXTABLE(0b, 1b)
5950 ++#endif
5951 ++
5952 ++ "jz 2f\n"
5953 ++ "call __write_lock_failed\n\t"
5954 ++ "2:\n"
5955 + ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory");
5956 + }
5957 +
5958 +@@ -348,12 +380,45 @@ static inline int __raw_write_trylock(ra
5959 +
5960 + static inline void __raw_read_unlock(raw_rwlock_t *rw)
5961 + {
5962 +- asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory");
5963 ++ asm volatile(LOCK_PREFIX "incl %0\n"
5964 ++
5965 ++#ifdef CONFIG_PAX_REFCOUNT
5966 ++#ifdef CONFIG_X86_32
5967 ++ "into\n0:\n"
5968 ++#else
5969 ++ "jno 0f\n"
5970 ++ "int $4\n0:\n"
5971 ++#endif
5972 ++ ".pushsection .fixup,\"ax\"\n"
5973 ++ "1:\n"
5974 ++ LOCK_PREFIX "decl %0\n"
5975 ++ "jmp 0b\n"
5976 ++ ".popsection\n"
5977 ++ _ASM_EXTABLE(0b, 1b)
5978 ++#endif
5979 ++
5980 ++ :"+m" (rw->lock) : : "memory");
5981 + }
5982 +
5983 + static inline void __raw_write_unlock(raw_rwlock_t *rw)
5984 + {
5985 +- asm volatile(LOCK_PREFIX "addl %1, %0"
5986 ++ asm volatile(LOCK_PREFIX "addl %1, %0\n"
5987 ++
5988 ++#ifdef CONFIG_PAX_REFCOUNT
5989 ++#ifdef CONFIG_X86_32
5990 ++ "into\n0:\n"
5991 ++#else
5992 ++ "jno 0f\n"
5993 ++ "int $4\n0:\n"
5994 ++#endif
5995 ++ ".pushsection .fixup,\"ax\"\n"
5996 ++ "1:\n"
5997 ++ LOCK_PREFIX "subl %1,%0\n"
5998 ++ "jmp 0b\n"
5999 ++ ".popsection\n"
6000 ++ _ASM_EXTABLE(0b, 1b)
6001 ++#endif
6002 ++
6003 + : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory");
6004 + }
6005 +
6006 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/system.h linux-2.6.28.8/arch/x86/include/asm/system.h
6007 +--- linux-2.6.28.8/arch/x86/include/asm/system.h 2009-02-06 16:47:45.000000000 -0500
6008 ++++ linux-2.6.28.8/arch/x86/include/asm/system.h 2009-02-21 09:37:48.000000000 -0500
6009 +@@ -95,6 +95,8 @@ do { \
6010 + ".globl thread_return\n" \
6011 + "thread_return:\n\t" \
6012 + "movq %%gs:%P[pda_pcurrent],%%rsi\n\t" \
6013 ++ "movq %P[task_canary](%%rsi),%%r8\n\t" \
6014 ++ "movq %%r8,%%gs:%P[pda_canary]\n\t" \
6015 + "movq %P[thread_info](%%rsi),%%r8\n\t" \
6016 + LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \
6017 + "movq %%rax,%%rdi\n\t" \
6018 +@@ -106,7 +108,9 @@ do { \
6019 + [ti_flags] "i" (offsetof(struct thread_info, flags)), \
6020 + [tif_fork] "i" (TIF_FORK), \
6021 + [thread_info] "i" (offsetof(struct task_struct, stack)), \
6022 +- [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \
6023 ++ [task_canary] "i" (offsetof(struct task_struct, stack_canary)), \
6024 ++ [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)), \
6025 ++ [pda_canary] "i" (offsetof(struct x8664_pda, stack_canary))\
6026 + : "memory", "cc" __EXTRA_CLOBBER)
6027 + #endif
6028 +
6029 +@@ -169,7 +173,7 @@ static inline unsigned long get_limit(un
6030 + {
6031 + unsigned long __limit;
6032 + asm("lsll %1,%0" : "=r" (__limit) : "r" (segment));
6033 +- return __limit + 1;
6034 ++ return __limit;
6035 + }
6036 +
6037 + static inline void native_clts(void)
6038 +@@ -295,6 +299,21 @@ static inline void native_wbinvd(void)
6039 +
6040 + #define stts() write_cr0(read_cr0() | X86_CR0_TS)
6041 +
6042 ++#define pax_open_kernel(cr0) \
6043 ++do { \
6044 ++ typecheck(unsigned long, cr0); \
6045 ++ preempt_disable(); \
6046 ++ cr0 = read_cr0(); \
6047 ++ write_cr0(cr0 & ~X86_CR0_WP); \
6048 ++} while (0)
6049 ++
6050 ++#define pax_close_kernel(cr0) \
6051 ++do { \
6052 ++ typecheck(unsigned long, cr0); \
6053 ++ write_cr0(cr0); \
6054 ++ preempt_enable_no_resched(); \
6055 ++} while (0)
6056 ++
6057 + #endif /* __KERNEL__ */
6058 +
6059 + static inline void clflush(volatile void *__p)
6060 +@@ -309,7 +328,7 @@ void enable_hlt(void);
6061 +
6062 + void cpu_idle_wait(void);
6063 +
6064 +-extern unsigned long arch_align_stack(unsigned long sp);
6065 ++#define arch_align_stack(x) ((x) & ~0xfUL)
6066 + extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
6067 +
6068 + void default_idle(void);
6069 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/uaccess_64.h linux-2.6.28.8/arch/x86/include/asm/uaccess_64.h
6070 +--- linux-2.6.28.8/arch/x86/include/asm/uaccess_64.h 2009-02-06 16:47:45.000000000 -0500
6071 ++++ linux-2.6.28.8/arch/x86/include/asm/uaccess_64.h 2009-02-21 09:37:48.000000000 -0500
6072 +@@ -10,6 +10,8 @@
6073 + #include <linux/lockdep.h>
6074 + #include <asm/page.h>
6075 +
6076 ++#define set_fs(x) (current_thread_info()->addr_limit = (x))
6077 ++
6078 + /*
6079 + * Copy To/From Userspace
6080 + */
6081 +diff -urNp linux-2.6.28.8/arch/x86/include/asm/uaccess.h linux-2.6.28.8/arch/x86/include/asm/uaccess.h
6082 +--- linux-2.6.28.8/arch/x86/include/asm/uaccess.h 2009-02-06 16:47:45.000000000 -0500
6083 ++++ linux-2.6.28.8/arch/x86/include/asm/uaccess.h 2009-02-21 09:37:48.000000000 -0500
6084 +@@ -10,6 +10,7 @@
6085 + #include <linux/string.h>
6086 + #include <asm/asm.h>
6087 + #include <asm/page.h>
6088 ++#include <asm/segment.h>
6089 +
6090 + #define VERIFY_READ 0
6091 + #define VERIFY_WRITE 1
6092 +@@ -29,7 +30,12 @@
6093 +
6094 + #define get_ds() (KERNEL_DS)
6095 + #define get_fs() (current_thread_info()->addr_limit)
6096 ++#ifdef CONFIG_X86_32
6097 ++void __set_fs(mm_segment_t x, int cpu);
6098 ++void set_fs(mm_segment_t x);
6099 ++#else
6100 + #define set_fs(x) (current_thread_info()->addr_limit = (x))
6101 ++#endif
6102 +
6103 + #define segment_eq(a, b) ((a).seg == (b).seg)
6104 +
6105 +@@ -186,9 +192,12 @@ extern int __get_user_bad(void);
6106 +
6107 + #ifdef CONFIG_X86_32
6108 + #define __put_user_u64(x, addr, err) \
6109 +- asm volatile("1: movl %%eax,0(%2)\n" \
6110 +- "2: movl %%edx,4(%2)\n" \
6111 ++ asm volatile(" movw %w5,%%ds\n" \
6112 ++ "1: movl %%eax,%%ds:0(%2)\n" \
6113 ++ "2: movl %%edx,%%ds:4(%2)\n" \
6114 + "3:\n" \
6115 ++ " pushl %%ss\n" \
6116 ++ " popl %%ds\n" \
6117 + ".section .fixup,\"ax\"\n" \
6118 + "4: movl %3,%0\n" \
6119 + " jmp 3b\n" \
6120 +@@ -196,7 +205,8 @@ extern int __get_user_bad(void);
6121 + _ASM_EXTABLE(1b, 4b) \
6122 + _ASM_EXTABLE(2b, 4b) \
6123 + : "=r" (err) \
6124 +- : "A" (x), "r" (addr), "i" (-EFAULT), "0" (err))
6125 ++ : "A" (x), "r" (addr), "i" (-EFAULT), "0" (err), \
6126 ++ "r"(__USER_DS))
6127 +
6128 + #define __put_user_x8(x, ptr, __ret_pu) \
6129 + asm volatile("call __put_user_8" : "=a" (__ret_pu) \
6130 +@@ -336,6 +346,22 @@ do { \
6131 + } \
6132 + } while (0)
6133 +
6134 ++#ifdef CONFIG_X86_32
6135 ++#define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
6136 ++ asm volatile(" movw %w5,%%ds\n" \
6137 ++ "1: mov"itype" %%ds:%2,%"rtype"1\n" \
6138 ++ "2:\n" \
6139 ++ " pushl %%ss\n" \
6140 ++ " popl %%ds\n" \
6141 ++ ".section .fixup,\"ax\"\n" \
6142 ++ "3: movl %3,%0\n" \
6143 ++ " xor"itype" %"rtype"1,%"rtype"1\n" \
6144 ++ " jmp 2b\n" \
6145 ++ ".previous\n" \
6146 ++ _ASM_EXTABLE(1b, 3b) \
6147 ++ : "=r" (err), ltype (x) \
6148 ++ : "m" (__m(addr)), "i" (errret), "0" (err), "r"(__USER_DS))
6149 ++#else
6150 + #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
6151 + asm volatile("1: mov"itype" %2,%"rtype"1\n" \
6152 + "2:\n" \
6153 +@@ -347,6 +373,7 @@ do { \
6154 + _ASM_EXTABLE(1b, 3b) \
6155 + : "=r" (err), ltype(x) \
6156 + : "m" (__m(addr)), "i" (errret), "0" (err))
6157 ++#endif
6158 +
6159 + #define __put_user_nocheck(x, ptr, size) \
6160 + ({ \
6161 +@@ -373,6 +400,22 @@ struct __large_struct { unsigned long bu
6162 + * we do not write to any memory gcc knows about, so there are no
6163 + * aliasing issues.
6164 + */
6165 ++#ifdef CONFIG_X86_32
6166 ++#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
6167 ++ asm volatile(" movw %w5,%%ds\n" \
6168 ++ "1: mov"itype" %"rtype"1,%%ds:%2\n" \
6169 ++ "2:\n" \
6170 ++ " pushl %%ss\n" \
6171 ++ " popl %%ds\n" \
6172 ++ ".section .fixup,\"ax\"\n" \
6173 ++ "3: movl %3,%0\n" \
6174 ++ " jmp 2b\n" \
6175 ++ ".previous\n" \
6176 ++ _ASM_EXTABLE(1b, 3b) \
6177 ++ : "=r"(err) \
6178 ++ : ltype (x), "m" (__m(addr)), "i" (errret), "0" (err),\
6179 ++ "r"(__USER_DS))
6180 ++#else
6181 + #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
6182 + asm volatile("1: mov"itype" %"rtype"1,%2\n" \
6183 + "2:\n" \
6184 +@@ -383,6 +426,7 @@ struct __large_struct { unsigned long bu
6185 + _ASM_EXTABLE(1b, 3b) \
6186 + : "=r"(err) \
6187 + : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err))
6188 ++#endif
6189 + /**
6190 + * __get_user: - Get a simple variable from user space, with less checking.
6191 + * @x: Variable to store result.
6192 +@@ -443,6 +487,7 @@ extern struct movsl_mask {
6193 +
6194 + #define ARCH_HAS_NOCACHE_UACCESS 1
6195 +
6196 ++#define ARCH_HAS_SORT_EXTABLE
6197 + #ifdef CONFIG_X86_32
6198 + # include "uaccess_32.h"
6199 + #else
6200 +diff -urNp linux-2.6.28.8/arch/x86/Kconfig linux-2.6.28.8/arch/x86/Kconfig
6201 +--- linux-2.6.28.8/arch/x86/Kconfig 2009-02-06 16:47:45.000000000 -0500
6202 ++++ linux-2.6.28.8/arch/x86/Kconfig 2009-02-21 09:37:48.000000000 -0500
6203 +@@ -935,7 +935,7 @@ config PAGE_OFFSET
6204 + hex
6205 + default 0xB0000000 if VMSPLIT_3G_OPT
6206 + default 0x80000000 if VMSPLIT_2G
6207 +- default 0x78000000 if VMSPLIT_2G_OPT
6208 ++ default 0x70000000 if VMSPLIT_2G_OPT
6209 + default 0x40000000 if VMSPLIT_1G
6210 + default 0xC0000000
6211 + depends on X86_32
6212 +@@ -1337,8 +1337,7 @@ config KEXEC_JUMP
6213 + config PHYSICAL_START
6214 + hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
6215 + default "0x1000000" if X86_NUMAQ
6216 +- default "0x200000" if X86_64
6217 +- default "0x100000"
6218 ++ default "0x200000"
6219 + help
6220 + This gives the physical address where the kernel is loaded.
6221 +
6222 +@@ -1430,9 +1429,9 @@ config HOTPLUG_CPU
6223 + Say N if you want to disable CPU hotplug.
6224 +
6225 + config COMPAT_VDSO
6226 +- def_bool y
6227 ++ def_bool n
6228 + prompt "Compat VDSO support"
6229 +- depends on X86_32 || IA32_EMULATION
6230 ++ depends on (X86_32 || IA32_EMULATION) && !PAX_NOEXEC
6231 + help
6232 + Map the 32-bit VDSO to the predictable old-style address too.
6233 + ---help---
6234 +diff -urNp linux-2.6.28.8/arch/x86/Kconfig.cpu linux-2.6.28.8/arch/x86/Kconfig.cpu
6235 +--- linux-2.6.28.8/arch/x86/Kconfig.cpu 2009-02-06 16:47:45.000000000 -0500
6236 ++++ linux-2.6.28.8/arch/x86/Kconfig.cpu 2009-02-21 09:37:48.000000000 -0500
6237 +@@ -331,7 +331,7 @@ config X86_PPRO_FENCE
6238 +
6239 + config X86_F00F_BUG
6240 + def_bool y
6241 +- depends on M586MMX || M586TSC || M586 || M486 || M386
6242 ++ depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
6243 +
6244 + config X86_WP_WORKS_OK
6245 + def_bool y
6246 +@@ -351,7 +351,7 @@ config X86_POPAD_OK
6247 +
6248 + config X86_ALIGNMENT_16
6249 + def_bool y
6250 +- depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
6251 ++ depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MCORE2 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
6252 +
6253 + config X86_INTEL_USERCOPY
6254 + def_bool y
6255 +@@ -397,7 +397,7 @@ config X86_CMPXCHG64
6256 + # generates cmov.
6257 + config X86_CMOV
6258 + def_bool y
6259 +- depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64)
6260 ++ depends on (MK8 || MK7 || MCORE2 || MPSC || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64)
6261 +
6262 + config X86_MINIMUM_CPU_FAMILY
6263 + int
6264 +diff -urNp linux-2.6.28.8/arch/x86/Kconfig.debug linux-2.6.28.8/arch/x86/Kconfig.debug
6265 +--- linux-2.6.28.8/arch/x86/Kconfig.debug 2009-02-06 16:47:45.000000000 -0500
6266 ++++ linux-2.6.28.8/arch/x86/Kconfig.debug 2009-02-21 09:37:48.000000000 -0500
6267 +@@ -107,7 +107,7 @@ config X86_PTDUMP
6268 + config DEBUG_RODATA
6269 + bool "Write protect kernel read-only data structures"
6270 + default y
6271 +- depends on DEBUG_KERNEL
6272 ++ depends on DEBUG_KERNEL && BROKEN
6273 + help
6274 + Mark the kernel read-only data as write-protected in the pagetables,
6275 + in order to catch accidental (and incorrect) writes to such const
6276 +diff -urNp linux-2.6.28.8/arch/x86/kernel/acpi/boot.c linux-2.6.28.8/arch/x86/kernel/acpi/boot.c
6277 +--- linux-2.6.28.8/arch/x86/kernel/acpi/boot.c 2009-02-06 16:47:45.000000000 -0500
6278 ++++ linux-2.6.28.8/arch/x86/kernel/acpi/boot.c 2009-02-21 09:37:48.000000000 -0500
6279 +@@ -1645,7 +1645,7 @@ static struct dmi_system_id __initdata a
6280 + DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6715b"),
6281 + },
6282 + },
6283 +- {}
6284 ++ { NULL, NULL, {{0, {0}}}, NULL}
6285 + };
6286 +
6287 + /*
6288 +diff -urNp linux-2.6.28.8/arch/x86/kernel/acpi/realmode/wakeup.S linux-2.6.28.8/arch/x86/kernel/acpi/realmode/wakeup.S
6289 +--- linux-2.6.28.8/arch/x86/kernel/acpi/realmode/wakeup.S 2009-02-06 16:47:45.000000000 -0500
6290 ++++ linux-2.6.28.8/arch/x86/kernel/acpi/realmode/wakeup.S 2009-02-21 09:37:48.000000000 -0500
6291 +@@ -104,7 +104,7 @@ _start:
6292 + movl %eax, %ecx
6293 + orl %edx, %ecx
6294 + jz 1f
6295 +- movl $0xc0000080, %ecx
6296 ++ mov $MSR_EFER, %ecx
6297 + wrmsr
6298 + 1:
6299 +
6300 +diff -urNp linux-2.6.28.8/arch/x86/kernel/acpi/sleep.c linux-2.6.28.8/arch/x86/kernel/acpi/sleep.c
6301 +--- linux-2.6.28.8/arch/x86/kernel/acpi/sleep.c 2009-02-06 16:47:45.000000000 -0500
6302 ++++ linux-2.6.28.8/arch/x86/kernel/acpi/sleep.c 2009-02-21 09:37:48.000000000 -0500
6303 +@@ -37,6 +37,10 @@ int acpi_save_state_mem(void)
6304 + {
6305 + struct wakeup_header *header;
6306 +
6307 ++#if defined(CONFIG_64BIT) && defined(CONFIG_SMP) && defined(CONFIG_PAX_KERNEXEC)
6308 ++ unsigned long cr0;
6309 ++#endif
6310 ++
6311 + if (!acpi_realmode) {
6312 + printk(KERN_ERR "Could not allocate memory during boot, "
6313 + "S3 disabled\n");
6314 +@@ -99,8 +103,18 @@ int acpi_save_state_mem(void)
6315 + header->trampoline_segment = setup_trampoline() >> 4;
6316 + #ifdef CONFIG_SMP
6317 + stack_start.sp = temp_stack + sizeof(temp_stack);
6318 ++
6319 ++#ifdef CONFIG_PAX_KERNEXEC
6320 ++ pax_open_kernel(cr0);
6321 ++#endif
6322 ++
6323 + early_gdt_descr.address =
6324 + (unsigned long)get_cpu_gdt_table(smp_processor_id());
6325 ++
6326 ++#ifdef CONFIG_PAX_KERNEXEC
6327 ++ pax_close_kernel(cr0);
6328 ++#endif
6329 ++
6330 + #endif
6331 + initial_code = (unsigned long)wakeup_long64;
6332 + saved_magic = 0x123456789abcdef0;
6333 +diff -urNp linux-2.6.28.8/arch/x86/kernel/acpi/wakeup_32.S linux-2.6.28.8/arch/x86/kernel/acpi/wakeup_32.S
6334 +--- linux-2.6.28.8/arch/x86/kernel/acpi/wakeup_32.S 2009-02-06 16:47:45.000000000 -0500
6335 ++++ linux-2.6.28.8/arch/x86/kernel/acpi/wakeup_32.S 2009-02-21 09:37:48.000000000 -0500
6336 +@@ -30,13 +30,11 @@ wakeup_pmode_return:
6337 + # and restore the stack ... but you need gdt for this to work
6338 + movl saved_context_esp, %esp
6339 +
6340 +- movl %cs:saved_magic, %eax
6341 +- cmpl $0x12345678, %eax
6342 ++ cmpl $0x12345678, saved_magic
6343 + jne bogus_magic
6344 +
6345 + # jump to place where we left off
6346 +- movl saved_eip, %eax
6347 +- jmp *%eax
6348 ++ jmp *(saved_eip)
6349 +
6350 + bogus_magic:
6351 + jmp bogus_magic
6352 +diff -urNp linux-2.6.28.8/arch/x86/kernel/alternative.c linux-2.6.28.8/arch/x86/kernel/alternative.c
6353 +--- linux-2.6.28.8/arch/x86/kernel/alternative.c 2009-02-06 16:47:45.000000000 -0500
6354 ++++ linux-2.6.28.8/arch/x86/kernel/alternative.c 2009-02-21 09:37:48.000000000 -0500
6355 +@@ -393,7 +393,7 @@ void apply_paravirt(struct paravirt_patc
6356 +
6357 + BUG_ON(p->len > MAX_PATCH_LEN);
6358 + /* prep the buffer with the original instructions */
6359 +- memcpy(insnbuf, p->instr, p->len);
6360 ++ memcpy(insnbuf, ktla_ktva(p->instr), p->len);
6361 + used = pv_init_ops.patch(p->instrtype, p->clobbers, insnbuf,
6362 + (unsigned long)p->instr, p->len);
6363 +
6364 +@@ -473,11 +473,26 @@ void __init alternative_instructions(voi
6365 + * instructions. And on the local CPU you need to be protected again NMI or MCE
6366 + * handlers seeing an inconsistent instruction while you patch.
6367 + */
6368 +-void *text_poke_early(void *addr, const void *opcode, size_t len)
6369 ++void *__kprobes text_poke_early(void *addr, const void *opcode, size_t len)
6370 + {
6371 + unsigned long flags;
6372 ++
6373 ++#ifdef CONFIG_PAX_KERNEXEC
6374 ++ unsigned long cr0;
6375 ++#endif
6376 ++
6377 + local_irq_save(flags);
6378 +- memcpy(addr, opcode, len);
6379 ++
6380 ++#ifdef CONFIG_PAX_KERNEXEC
6381 ++ pax_open_kernel(cr0);
6382 ++#endif
6383 ++
6384 ++ memcpy(ktla_ktva(addr), opcode, len);
6385 ++
6386 ++#ifdef CONFIG_PAX_KERNEXEC
6387 ++ pax_close_kernel(cr0);
6388 ++#endif
6389 ++
6390 + local_irq_restore(flags);
6391 + sync_core();
6392 + /* Could also do a CLFLUSH here to speed up CPU recovery; but
6393 +@@ -498,33 +513,27 @@ void *text_poke_early(void *addr, const
6394 + */
6395 + void *__kprobes text_poke(void *addr, const void *opcode, size_t len)
6396 + {
6397 +- unsigned long flags;
6398 +- char *vaddr;
6399 +- int nr_pages = 2;
6400 ++ unsigned char *vaddr = ktla_ktva(addr);
6401 + struct page *pages[2];
6402 +- int i;
6403 ++ size_t i;
6404 ++
6405 ++ if (!core_kernel_text((unsigned long)addr)
6406 +
6407 +- if (!core_kernel_text((unsigned long)addr)) {
6408 +- pages[0] = vmalloc_to_page(addr);
6409 +- pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
6410 ++#if defined(CONFIG_X86_32) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
6411 ++ && (vaddr < MODULES_VADDR || MODULES_END < vaddr)
6412 ++#endif
6413 ++
6414 ++ ) {
6415 ++ pages[0] = vmalloc_to_page(vaddr);
6416 ++ pages[1] = vmalloc_to_page(vaddr + PAGE_SIZE);
6417 + } else {
6418 +- pages[0] = virt_to_page(addr);
6419 ++ pages[0] = virt_to_page(vaddr);
6420 + WARN_ON(!PageReserved(pages[0]));
6421 +- pages[1] = virt_to_page(addr + PAGE_SIZE);
6422 ++ pages[1] = virt_to_page(vaddr + PAGE_SIZE);
6423 + }
6424 + BUG_ON(!pages[0]);
6425 +- if (!pages[1])
6426 +- nr_pages = 1;
6427 +- vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL);
6428 +- BUG_ON(!vaddr);
6429 +- local_irq_save(flags);
6430 +- memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len);
6431 +- local_irq_restore(flags);
6432 +- vunmap(vaddr);
6433 +- sync_core();
6434 +- /* Could also do a CLFLUSH here to speed up CPU recovery; but
6435 +- that causes hangs on some VIA CPUs. */
6436 ++ text_poke_early(addr, opcode, len);
6437 + for (i = 0; i < len; i++)
6438 +- BUG_ON(((char *)addr)[i] != ((char *)opcode)[i]);
6439 ++ BUG_ON((vaddr)[i] != ((unsigned char *)opcode)[i]);
6440 + return addr;
6441 + }
6442 +diff -urNp linux-2.6.28.8/arch/x86/kernel/apm_32.c linux-2.6.28.8/arch/x86/kernel/apm_32.c
6443 +--- linux-2.6.28.8/arch/x86/kernel/apm_32.c 2009-02-06 16:47:45.000000000 -0500
6444 ++++ linux-2.6.28.8/arch/x86/kernel/apm_32.c 2009-02-21 09:37:48.000000000 -0500
6445 +@@ -407,7 +407,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitq
6446 + static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
6447 + static struct apm_user *user_list;
6448 + static DEFINE_SPINLOCK(user_list_lock);
6449 +-static const struct desc_struct bad_bios_desc = { { { 0, 0x00409200 } } };
6450 ++static const struct desc_struct bad_bios_desc = { { { 0, 0x00409300 } } };
6451 +
6452 + static const char driver_version[] = "1.16ac"; /* no spaces */
6453 +
6454 +@@ -602,19 +602,42 @@ static u8 apm_bios_call(u32 func, u32 eb
6455 + struct desc_struct save_desc_40;
6456 + struct desc_struct *gdt;
6457 +
6458 ++#ifdef CONFIG_PAX_KERNEXEC
6459 ++ unsigned long cr0;
6460 ++#endif
6461 ++
6462 + cpus = apm_save_cpus();
6463 +
6464 + cpu = get_cpu();
6465 + gdt = get_cpu_gdt_table(cpu);
6466 + save_desc_40 = gdt[0x40 / 8];
6467 ++
6468 ++#ifdef CONFIG_PAX_KERNEXEC
6469 ++ pax_open_kernel(cr0);
6470 ++#endif
6471 ++
6472 + gdt[0x40 / 8] = bad_bios_desc;
6473 +
6474 ++#ifdef CONFIG_PAX_KERNEXEC
6475 ++ pax_close_kernel(cr0);
6476 ++#endif
6477 ++
6478 + apm_irq_save(flags);
6479 + APM_DO_SAVE_SEGS;
6480 + apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
6481 + APM_DO_RESTORE_SEGS;
6482 + apm_irq_restore(flags);
6483 ++
6484 ++#ifdef CONFIG_PAX_KERNEXEC
6485 ++ pax_open_kernel(cr0);
6486 ++#endif
6487 ++
6488 + gdt[0x40 / 8] = save_desc_40;
6489 ++
6490 ++#ifdef CONFIG_PAX_KERNEXEC
6491 ++ pax_close_kernel(cr0);
6492 ++#endif
6493 ++
6494 + put_cpu();
6495 + apm_restore_cpus(cpus);
6496 +
6497 +@@ -645,19 +668,42 @@ static u8 apm_bios_call_simple(u32 func,
6498 + struct desc_struct save_desc_40;
6499 + struct desc_struct *gdt;
6500 +
6501 ++#ifdef CONFIG_PAX_KERNEXEC
6502 ++ unsigned long cr0;
6503 ++#endif
6504 ++
6505 + cpus = apm_save_cpus();
6506 +
6507 + cpu = get_cpu();
6508 + gdt = get_cpu_gdt_table(cpu);
6509 + save_desc_40 = gdt[0x40 / 8];
6510 ++
6511 ++#ifdef CONFIG_PAX_KERNEXEC
6512 ++ pax_open_kernel(cr0);
6513 ++#endif
6514 ++
6515 + gdt[0x40 / 8] = bad_bios_desc;
6516 +
6517 ++#ifdef CONFIG_PAX_KERNEXEC
6518 ++ pax_close_kernel(cr0);
6519 ++#endif
6520 ++
6521 + apm_irq_save(flags);
6522 + APM_DO_SAVE_SEGS;
6523 + error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
6524 + APM_DO_RESTORE_SEGS;
6525 + apm_irq_restore(flags);
6526 ++
6527 ++#ifdef CONFIG_PAX_KERNEXEC
6528 ++ pax_open_kernel(cr0);
6529 ++#endif
6530 ++
6531 + gdt[0x40 / 8] = save_desc_40;
6532 ++
6533 ++#ifdef CONFIG_PAX_KERNEXEC
6534 ++ pax_close_kernel(cr0);
6535 ++#endif
6536 ++
6537 + put_cpu();
6538 + apm_restore_cpus(cpus);
6539 + return error;
6540 +@@ -929,7 +975,7 @@ recalc:
6541 +
6542 + static void apm_power_off(void)
6543 + {
6544 +- unsigned char po_bios_call[] = {
6545 ++ const unsigned char po_bios_call[] = {
6546 + 0xb8, 0x00, 0x10, /* movw $0x1000,ax */
6547 + 0x8e, 0xd0, /* movw ax,ss */
6548 + 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */
6549 +@@ -1876,7 +1922,10 @@ static const struct file_operations apm_
6550 + static struct miscdevice apm_device = {
6551 + APM_MINOR_DEV,
6552 + "apm_bios",
6553 +- &apm_bios_fops
6554 ++ &apm_bios_fops,
6555 ++ {NULL, NULL},
6556 ++ NULL,
6557 ++ NULL
6558 + };
6559 +
6560 +
6561 +@@ -2197,7 +2246,7 @@ static struct dmi_system_id __initdata a
6562 + { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
6563 + },
6564 +
6565 +- { }
6566 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL}
6567 + };
6568 +
6569 + /*
6570 +@@ -2215,6 +2264,10 @@ static int __init apm_init(void)
6571 + struct desc_struct *gdt;
6572 + int err;
6573 +
6574 ++#ifdef CONFIG_PAX_KERNEXEC
6575 ++ unsigned long cr0;
6576 ++#endif
6577 ++
6578 + dmi_check_system(apm_dmi_table);
6579 +
6580 + if (apm_info.bios.version == 0 || paravirt_enabled() || machine_is_olpc()) {
6581 +@@ -2288,9 +2341,18 @@ static int __init apm_init(void)
6582 + * This is for buggy BIOS's that refer to (real mode) segment 0x40
6583 + * even though they are called in protected mode.
6584 + */
6585 ++
6586 ++#ifdef CONFIG_PAX_KERNEXEC
6587 ++ pax_open_kernel(cr0);
6588 ++#endif
6589 ++
6590 + set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
6591 + _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
6592 +
6593 ++#ifdef CONFIG_PAX_KERNEXEC
6594 ++ pax_close_kernel(cr0);
6595 ++#endif
6596 ++
6597 + /*
6598 + * Set up the long jump entry point to the APM BIOS, which is called
6599 + * from inline assembly.
6600 +@@ -2309,6 +2371,11 @@ static int __init apm_init(void)
6601 + * code to that CPU.
6602 + */
6603 + gdt = get_cpu_gdt_table(0);
6604 ++
6605 ++#ifdef CONFIG_PAX_KERNEXEC
6606 ++ pax_open_kernel(cr0);
6607 ++#endif
6608 ++
6609 + set_base(gdt[APM_CS >> 3],
6610 + __va((unsigned long)apm_info.bios.cseg << 4));
6611 + set_base(gdt[APM_CS_16 >> 3],
6612 +@@ -2316,6 +2383,10 @@ static int __init apm_init(void)
6613 + set_base(gdt[APM_DS >> 3],
6614 + __va((unsigned long)apm_info.bios.dseg << 4));
6615 +
6616 ++#ifdef CONFIG_PAX_KERNEXEC
6617 ++ pax_close_kernel(cr0);
6618 ++#endif
6619 ++
6620 + proc_create("apm", 0, NULL, &apm_file_ops);
6621 +
6622 + kapmd_task = kthread_create(apm, NULL, "kapmd");
6623 +diff -urNp linux-2.6.28.8/arch/x86/kernel/asm-offsets_32.c linux-2.6.28.8/arch/x86/kernel/asm-offsets_32.c
6624 +--- linux-2.6.28.8/arch/x86/kernel/asm-offsets_32.c 2009-02-06 16:47:45.000000000 -0500
6625 ++++ linux-2.6.28.8/arch/x86/kernel/asm-offsets_32.c 2009-02-21 09:37:48.000000000 -0500
6626 +@@ -100,6 +100,7 @@ void foo(void)
6627 + DEFINE(PTRS_PER_PTE, PTRS_PER_PTE);
6628 + DEFINE(PTRS_PER_PMD, PTRS_PER_PMD);
6629 + DEFINE(PTRS_PER_PGD, PTRS_PER_PGD);
6630 ++ DEFINE(PERCPU_MODULE_RESERVE, PERCPU_MODULE_RESERVE);
6631 +
6632 + OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
6633 +
6634 +@@ -113,6 +114,7 @@ void foo(void)
6635 + OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
6636 + OFFSET(PV_CPU_irq_enable_sysexit, pv_cpu_ops, irq_enable_sysexit);
6637 + OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
6638 ++ OFFSET(PV_CPU_write_cr0, pv_cpu_ops, write_cr0);
6639 + #endif
6640 +
6641 + #ifdef CONFIG_XEN
6642 +diff -urNp linux-2.6.28.8/arch/x86/kernel/asm-offsets_64.c linux-2.6.28.8/arch/x86/kernel/asm-offsets_64.c
6643 +--- linux-2.6.28.8/arch/x86/kernel/asm-offsets_64.c 2009-02-06 16:47:45.000000000 -0500
6644 ++++ linux-2.6.28.8/arch/x86/kernel/asm-offsets_64.c 2009-02-21 09:37:48.000000000 -0500
6645 +@@ -122,6 +122,7 @@ int main(void)
6646 + ENTRY(cr8);
6647 + BLANK();
6648 + #undef ENTRY
6649 ++ DEFINE(TSS_size, sizeof(struct tss_struct));
6650 + DEFINE(TSS_ist, offsetof(struct tss_struct, x86_tss.ist));
6651 + BLANK();
6652 + DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
6653 +diff -urNp linux-2.6.28.8/arch/x86/kernel/cpu/common.c linux-2.6.28.8/arch/x86/kernel/cpu/common.c
6654 +--- linux-2.6.28.8/arch/x86/kernel/cpu/common.c 2009-02-06 16:47:45.000000000 -0500
6655 ++++ linux-2.6.28.8/arch/x86/kernel/cpu/common.c 2009-02-21 09:37:48.000000000 -0500
6656 +@@ -2,7 +2,6 @@
6657 + #include <linux/kernel.h>
6658 + #include <linux/sched.h>
6659 + #include <linux/string.h>
6660 +-#include <linux/bootmem.h>
6661 + #include <linux/bitops.h>
6662 + #include <linux/module.h>
6663 + #include <linux/kgdb.h>
6664 +@@ -41,59 +40,6 @@
6665 +
6666 + static struct cpu_dev *this_cpu __cpuinitdata;
6667 +
6668 +-#ifdef CONFIG_X86_64
6669 +-/* We need valid kernel segments for data and code in long mode too
6670 +- * IRET will check the segment types kkeil 2000/10/28
6671 +- * Also sysret mandates a special GDT layout
6672 +- */
6673 +-/* The TLS descriptors are currently at a different place compared to i386.
6674 +- Hopefully nobody expects them at a fixed place (Wine?) */
6675 +-DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
6676 +- [GDT_ENTRY_KERNEL32_CS] = { { { 0x0000ffff, 0x00cf9b00 } } },
6677 +- [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00af9b00 } } },
6678 +- [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9300 } } },
6679 +- [GDT_ENTRY_DEFAULT_USER32_CS] = { { { 0x0000ffff, 0x00cffb00 } } },
6680 +- [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff300 } } },
6681 +- [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00affb00 } } },
6682 +-} };
6683 +-#else
6684 +-DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
6685 +- [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } },
6686 +- [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } },
6687 +- [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } },
6688 +- [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } },
6689 +- /*
6690 +- * Segments used for calling PnP BIOS have byte granularity.
6691 +- * They code segments and data segments have fixed 64k limits,
6692 +- * the transfer segment sizes are set at run time.
6693 +- */
6694 +- /* 32-bit code */
6695 +- [GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } },
6696 +- /* 16-bit code */
6697 +- [GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } },
6698 +- /* 16-bit data */
6699 +- [GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } },
6700 +- /* 16-bit data */
6701 +- [GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } },
6702 +- /* 16-bit data */
6703 +- [GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } },
6704 +- /*
6705 +- * The APM segments have byte granularity and their bases
6706 +- * are set at run time. All have 64k limits.
6707 +- */
6708 +- /* 32-bit code */
6709 +- [GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } },
6710 +- /* 16-bit code */
6711 +- [GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } },
6712 +- /* data */
6713 +- [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } },
6714 +-
6715 +- [GDT_ENTRY_ESPFIX_SS] = { { { 0x00000000, 0x00c09200 } } },
6716 +- [GDT_ENTRY_PERCPU] = { { { 0x00000000, 0x00000000 } } },
6717 +-} };
6718 +-#endif
6719 +-EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
6720 +-
6721 + #ifdef CONFIG_X86_32
6722 + static int cachesize_override __cpuinitdata = -1;
6723 + static int disable_x86_serial_nr __cpuinitdata = 1;
6724 +@@ -227,7 +173,7 @@ void switch_to_new_gdt(void)
6725 + {
6726 + struct desc_ptr gdt_descr;
6727 +
6728 +- gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
6729 ++ gdt_descr.address = (unsigned long)get_cpu_gdt_table(smp_processor_id());
6730 + gdt_descr.size = GDT_SIZE - 1;
6731 + load_gdt(&gdt_descr);
6732 + #ifdef CONFIG_X86_32
6733 +@@ -687,6 +633,10 @@ static void __cpuinit identify_cpu(struc
6734 + * we do "generic changes."
6735 + */
6736 +
6737 ++#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
6738 ++ setup_clear_cpu_cap(X86_FEATURE_SEP);
6739 ++#endif
6740 ++
6741 + /* If the model name is still unset, do table lookup. */
6742 + if (!c->x86_model_id[0]) {
6743 + char *p;
6744 +@@ -854,13 +804,13 @@ static __init int setup_disablecpuid(cha
6745 + }
6746 + __setup("clearcpuid=", setup_disablecpuid);
6747 +
6748 +-cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
6749 ++cpumask_t cpu_initialized = CPU_MASK_NONE;
6750 +
6751 + #ifdef CONFIG_X86_64
6752 + struct x8664_pda **_cpu_pda __read_mostly;
6753 + EXPORT_SYMBOL(_cpu_pda);
6754 +
6755 +-struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
6756 ++struct desc_ptr idt_descr __read_only = { 256 * 16 - 1, (unsigned long) idt_table };
6757 +
6758 + char boot_cpu_stack[IRQSTACKSIZE] __page_aligned_bss;
6759 +
6760 +@@ -959,7 +909,7 @@ struct pt_regs * __cpuinit idle_regs(str
6761 + void __cpuinit cpu_init(void)
6762 + {
6763 + int cpu = stack_smp_processor_id();
6764 +- struct tss_struct *t = &per_cpu(init_tss, cpu);
6765 ++ struct tss_struct *t = init_tss + cpu;
6766 + struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu);
6767 + unsigned long v;
6768 + char *estacks = NULL;
6769 +@@ -1080,7 +1030,7 @@ void __cpuinit cpu_init(void)
6770 + {
6771 + int cpu = smp_processor_id();
6772 + struct task_struct *curr = current;
6773 +- struct tss_struct *t = &per_cpu(init_tss, cpu);
6774 ++ struct tss_struct *t = init_tss + cpu;
6775 + struct thread_struct *thread = &curr->thread;
6776 +
6777 + if (cpu_test_and_set(cpu, cpu_initialized)) {
6778 +diff -urNp linux-2.6.28.8/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c linux-2.6.28.8/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
6779 +--- linux-2.6.28.8/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2009-02-06 16:47:45.000000000 -0500
6780 ++++ linux-2.6.28.8/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2009-02-21 09:37:48.000000000 -0500
6781 +@@ -561,7 +561,7 @@ static const struct dmi_system_id sw_any
6782 + DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
6783 + },
6784 + },
6785 +- { }
6786 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
6787 + };
6788 + #endif
6789 +
6790 +diff -urNp linux-2.6.28.8/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c linux-2.6.28.8/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
6791 +--- linux-2.6.28.8/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2009-02-06 16:47:45.000000000 -0500
6792 ++++ linux-2.6.28.8/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2009-02-21 09:37:48.000000000 -0500
6793 +@@ -225,7 +225,7 @@ static struct cpu_model models[] =
6794 + { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
6795 + { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
6796 +
6797 +- { NULL, }
6798 ++ { NULL, NULL, 0, NULL}
6799 + };
6800 + #undef _BANIAS
6801 + #undef BANIAS
6802 +diff -urNp linux-2.6.28.8/arch/x86/kernel/cpu/intel.c linux-2.6.28.8/arch/x86/kernel/cpu/intel.c
6803 +--- linux-2.6.28.8/arch/x86/kernel/cpu/intel.c 2009-02-06 16:47:45.000000000 -0500
6804 ++++ linux-2.6.28.8/arch/x86/kernel/cpu/intel.c 2009-02-21 09:37:48.000000000 -0500
6805 +@@ -72,7 +72,7 @@ static void __cpuinit trap_init_f00f_bug
6806 + * Update the IDT descriptor and reload the IDT so that
6807 + * it uses the read-only mapped virtual address.
6808 + */
6809 +- idt_descr.address = fix_to_virt(FIX_F00F_IDT);
6810 ++ idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
6811 + load_idt(&idt_descr);
6812 + }
6813 + #endif
6814 +diff -urNp linux-2.6.28.8/arch/x86/kernel/cpu/mcheck/mce_64.c linux-2.6.28.8/arch/x86/kernel/cpu/mcheck/mce_64.c
6815 +--- linux-2.6.28.8/arch/x86/kernel/cpu/mcheck/mce_64.c 2009-02-06 16:47:45.000000000 -0500
6816 ++++ linux-2.6.28.8/arch/x86/kernel/cpu/mcheck/mce_64.c 2009-02-21 09:37:48.000000000 -0500
6817 +@@ -678,6 +678,7 @@ static struct miscdevice mce_log_device
6818 + MISC_MCELOG_MINOR,
6819 + "mcelog",
6820 + &mce_chrdev_ops,
6821 ++ {NULL, NULL}, NULL, NULL
6822 + };
6823 +
6824 + static unsigned long old_cr4 __initdata;
6825 +diff -urNp linux-2.6.28.8/arch/x86/kernel/cpu/mtrr/generic.c linux-2.6.28.8/arch/x86/kernel/cpu/mtrr/generic.c
6826 +--- linux-2.6.28.8/arch/x86/kernel/cpu/mtrr/generic.c 2009-02-06 16:47:45.000000000 -0500
6827 ++++ linux-2.6.28.8/arch/x86/kernel/cpu/mtrr/generic.c 2009-02-21 09:37:48.000000000 -0500
6828 +@@ -31,11 +31,11 @@ static struct fixed_range_block fixed_ra
6829 + { MTRRfix64K_00000_MSR, 1 }, /* one 64k MTRR */
6830 + { MTRRfix16K_80000_MSR, 2 }, /* two 16k MTRRs */
6831 + { MTRRfix4K_C0000_MSR, 8 }, /* eight 4k MTRRs */
6832 +- {}
6833 ++ { 0, 0 }
6834 + };
6835 +
6836 + static unsigned long smp_changes_mask;
6837 +-static struct mtrr_state mtrr_state = {};
6838 ++static struct mtrr_state mtrr_state;
6839 + static int mtrr_state_set;
6840 + u64 mtrr_tom2;
6841 +
6842 +diff -urNp linux-2.6.28.8/arch/x86/kernel/crash.c linux-2.6.28.8/arch/x86/kernel/crash.c
6843 +--- linux-2.6.28.8/arch/x86/kernel/crash.c 2009-02-06 16:47:45.000000000 -0500
6844 ++++ linux-2.6.28.8/arch/x86/kernel/crash.c 2009-02-21 09:37:48.000000000 -0500
6845 +@@ -59,7 +59,7 @@ static int crash_nmi_callback(struct not
6846 + local_irq_disable();
6847 +
6848 + #ifdef CONFIG_X86_32
6849 +- if (!user_mode_vm(regs)) {
6850 ++ if (!user_mode(regs)) {
6851 + crash_fixup_ss_esp(&fixed_regs, regs);
6852 + regs = &fixed_regs;
6853 + }
6854 +diff -urNp linux-2.6.28.8/arch/x86/kernel/doublefault_32.c linux-2.6.28.8/arch/x86/kernel/doublefault_32.c
6855 +--- linux-2.6.28.8/arch/x86/kernel/doublefault_32.c 2009-02-06 16:47:45.000000000 -0500
6856 ++++ linux-2.6.28.8/arch/x86/kernel/doublefault_32.c 2009-02-21 09:37:48.000000000 -0500
6857 +@@ -11,7 +11,7 @@
6858 +
6859 + #define DOUBLEFAULT_STACKSIZE (1024)
6860 + static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
6861 +-#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
6862 ++#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
6863 +
6864 + #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
6865 +
6866 +@@ -21,7 +21,7 @@ static void doublefault_fn(void)
6867 + unsigned long gdt, tss;
6868 +
6869 + store_gdt(&gdt_desc);
6870 +- gdt = gdt_desc.address;
6871 ++ gdt = (unsigned long)gdt_desc.address;
6872 +
6873 + printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
6874 +
6875 +@@ -60,10 +60,10 @@ struct tss_struct doublefault_tss __cach
6876 + /* 0x2 bit is always set */
6877 + .flags = X86_EFLAGS_SF | 0x2,
6878 + .sp = STACK_START,
6879 +- .es = __USER_DS,
6880 ++ .es = __KERNEL_DS,
6881 + .cs = __KERNEL_CS,
6882 + .ss = __KERNEL_DS,
6883 +- .ds = __USER_DS,
6884 ++ .ds = __KERNEL_DS,
6885 + .fs = __KERNEL_PERCPU,
6886 +
6887 + .__cr3 = __pa_nodebug(swapper_pg_dir),
6888 +diff -urNp linux-2.6.28.8/arch/x86/kernel/dumpstack_32.c linux-2.6.28.8/arch/x86/kernel/dumpstack_32.c
6889 +--- linux-2.6.28.8/arch/x86/kernel/dumpstack_32.c 2009-02-06 16:47:45.000000000 -0500
6890 ++++ linux-2.6.28.8/arch/x86/kernel/dumpstack_32.c 2009-02-21 09:37:48.000000000 -0500
6891 +@@ -238,11 +238,12 @@ void show_registers(struct pt_regs *regs
6892 + * When in-kernel, we also print out the stack and code at the
6893 + * time of the fault..
6894 + */
6895 +- if (!user_mode_vm(regs)) {
6896 ++ if (!user_mode(regs)) {
6897 + unsigned int code_prologue = code_bytes * 43 / 64;
6898 + unsigned int code_len = code_bytes;
6899 + unsigned char c;
6900 + u8 *ip;
6901 ++ unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->cs) >> 3]);
6902 +
6903 + printk(KERN_EMERG "Stack:\n");
6904 + show_stack_log_lvl(NULL, regs, &regs->sp,
6905 +@@ -250,10 +251,10 @@ void show_registers(struct pt_regs *regs
6906 +
6907 + printk(KERN_EMERG "Code: ");
6908 +
6909 +- ip = (u8 *)regs->ip - code_prologue;
6910 ++ ip = (u8 *)regs->ip - code_prologue + cs_base;
6911 + if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
6912 + /* try starting at IP */
6913 +- ip = (u8 *)regs->ip;
6914 ++ ip = (u8 *)regs->ip + cs_base;
6915 + code_len = code_len - code_prologue + 1;
6916 + }
6917 + for (i = 0; i < code_len; i++, ip++) {
6918 +@@ -262,7 +263,7 @@ void show_registers(struct pt_regs *regs
6919 + printk(" Bad EIP value.");
6920 + break;
6921 + }
6922 +- if (ip == (u8 *)regs->ip)
6923 ++ if (ip == (u8 *)regs->ip + cs_base)
6924 + printk("<%02x> ", c);
6925 + else
6926 + printk("%02x ", c);
6927 +@@ -275,6 +276,7 @@ int is_valid_bugaddr(unsigned long ip)
6928 + {
6929 + unsigned short ud2;
6930 +
6931 ++ ip = ktla_ktva(ip);
6932 + if (ip < PAGE_OFFSET)
6933 + return 0;
6934 + if (probe_kernel_address((unsigned short *)ip, ud2))
6935 +@@ -410,7 +412,7 @@ die_nmi(char *str, struct pt_regs *regs,
6936 + * If we are in kernel we are probably nested up pretty bad
6937 + * and might aswell get out now while we still can:
6938 + */
6939 +- if (!user_mode_vm(regs)) {
6940 ++ if (!user_mode(regs)) {
6941 + current->thread.trap_no = 2;
6942 + crash_kexec(regs);
6943 + }
6944 +diff -urNp linux-2.6.28.8/arch/x86/kernel/efi_32.c linux-2.6.28.8/arch/x86/kernel/efi_32.c
6945 +--- linux-2.6.28.8/arch/x86/kernel/efi_32.c 2009-02-06 16:47:45.000000000 -0500
6946 ++++ linux-2.6.28.8/arch/x86/kernel/efi_32.c 2009-02-21 09:37:48.000000000 -0500
6947 +@@ -38,70 +38,38 @@
6948 + */
6949 +
6950 + static unsigned long efi_rt_eflags;
6951 +-static pgd_t efi_bak_pg_dir_pointer[2];
6952 ++static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS];
6953 +
6954 +-void efi_call_phys_prelog(void)
6955 ++void __init efi_call_phys_prelog(void)
6956 + {
6957 +- unsigned long cr4;
6958 +- unsigned long temp;
6959 + struct desc_ptr gdt_descr;
6960 +
6961 + local_irq_save(efi_rt_eflags);
6962 +
6963 +- /*
6964 +- * If I don't have PAE, I should just duplicate two entries in page
6965 +- * directory. If I have PAE, I just need to duplicate one entry in
6966 +- * page directory.
6967 +- */
6968 +- cr4 = read_cr4_safe();
6969 +
6970 +- if (cr4 & X86_CR4_PAE) {
6971 +- efi_bak_pg_dir_pointer[0].pgd =
6972 +- swapper_pg_dir[pgd_index(0)].pgd;
6973 +- swapper_pg_dir[0].pgd =
6974 +- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
6975 +- } else {
6976 +- efi_bak_pg_dir_pointer[0].pgd =
6977 +- swapper_pg_dir[pgd_index(0)].pgd;
6978 +- efi_bak_pg_dir_pointer[1].pgd =
6979 +- swapper_pg_dir[pgd_index(0x400000)].pgd;
6980 +- swapper_pg_dir[pgd_index(0)].pgd =
6981 +- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
6982 +- temp = PAGE_OFFSET + 0x400000;
6983 +- swapper_pg_dir[pgd_index(0x400000)].pgd =
6984 +- swapper_pg_dir[pgd_index(temp)].pgd;
6985 +- }
6986 ++ clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
6987 ++ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
6988 ++ min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
6989 +
6990 + /*
6991 + * After the lock is released, the original page table is restored.
6992 + */
6993 + __flush_tlb_all();
6994 +
6995 +- gdt_descr.address = __pa(get_cpu_gdt_table(0));
6996 ++ gdt_descr.address = (struct desc_struct *)__pa(get_cpu_gdt_table(0));
6997 + gdt_descr.size = GDT_SIZE - 1;
6998 + load_gdt(&gdt_descr);
6999 + }
7000 +
7001 +-void efi_call_phys_epilog(void)
7002 ++void __init efi_call_phys_epilog(void)
7003 + {
7004 +- unsigned long cr4;
7005 + struct desc_ptr gdt_descr;
7006 +
7007 +- gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
7008 ++ gdt_descr.address = get_cpu_gdt_table(0);
7009 + gdt_descr.size = GDT_SIZE - 1;
7010 + load_gdt(&gdt_descr);
7011 +
7012 +- cr4 = read_cr4_safe();
7013 +-
7014 +- if (cr4 & X86_CR4_PAE) {
7015 +- swapper_pg_dir[pgd_index(0)].pgd =
7016 +- efi_bak_pg_dir_pointer[0].pgd;
7017 +- } else {
7018 +- swapper_pg_dir[pgd_index(0)].pgd =
7019 +- efi_bak_pg_dir_pointer[0].pgd;
7020 +- swapper_pg_dir[pgd_index(0x400000)].pgd =
7021 +- efi_bak_pg_dir_pointer[1].pgd;
7022 +- }
7023 ++ clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
7024 +
7025 + /*
7026 + * After the lock is released, the original page table is restored.
7027 +diff -urNp linux-2.6.28.8/arch/x86/kernel/efi_stub_32.S linux-2.6.28.8/arch/x86/kernel/efi_stub_32.S
7028 +--- linux-2.6.28.8/arch/x86/kernel/efi_stub_32.S 2009-02-06 16:47:45.000000000 -0500
7029 ++++ linux-2.6.28.8/arch/x86/kernel/efi_stub_32.S 2009-02-21 09:37:48.000000000 -0500
7030 +@@ -6,6 +6,7 @@
7031 + */
7032 +
7033 + #include <linux/linkage.h>
7034 ++#include <linux/init.h>
7035 + #include <asm/page.h>
7036 +
7037 + /*
7038 +@@ -20,7 +21,7 @@
7039 + * service functions will comply with gcc calling convention, too.
7040 + */
7041 +
7042 +-.text
7043 ++__INIT
7044 + ENTRY(efi_call_phys)
7045 + /*
7046 + * 0. The function can only be called in Linux kernel. So CS has been
7047 +@@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
7048 + * The mapping of lower virtual memory has been created in prelog and
7049 + * epilog.
7050 + */
7051 +- movl $1f, %edx
7052 +- subl $__PAGE_OFFSET, %edx
7053 +- jmp *%edx
7054 ++ jmp 1f-__PAGE_OFFSET
7055 + 1:
7056 +
7057 + /*
7058 +@@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
7059 + * parameter 2, ..., param n. To make things easy, we save the return
7060 + * address of efi_call_phys in a global variable.
7061 + */
7062 +- popl %edx
7063 +- movl %edx, saved_return_addr
7064 +- /* get the function pointer into ECX*/
7065 +- popl %ecx
7066 +- movl %ecx, efi_rt_function_ptr
7067 +- movl $2f, %edx
7068 +- subl $__PAGE_OFFSET, %edx
7069 +- pushl %edx
7070 ++ popl (saved_return_addr)
7071 ++ popl (efi_rt_function_ptr)
7072 +
7073 + /*
7074 + * 3. Clear PG bit in %CR0.
7075 +@@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
7076 + /*
7077 + * 5. Call the physical function.
7078 + */
7079 +- jmp *%ecx
7080 ++ call *(efi_rt_function_ptr-__PAGE_OFFSET)
7081 +
7082 +-2:
7083 + /*
7084 + * 6. After EFI runtime service returns, control will return to
7085 + * following instruction. We'd better readjust stack pointer first.
7086 +@@ -88,34 +80,27 @@ ENTRY(efi_call_phys)
7087 + movl %cr0, %edx
7088 + orl $0x80000000, %edx
7089 + movl %edx, %cr0
7090 +- jmp 1f
7091 +-1:
7092 ++
7093 + /*
7094 + * 8. Now restore the virtual mode from flat mode by
7095 + * adding EIP with PAGE_OFFSET.
7096 + */
7097 +- movl $1f, %edx
7098 +- jmp *%edx
7099 ++ jmp 1f+__PAGE_OFFSET
7100 + 1:
7101 +
7102 + /*
7103 + * 9. Balance the stack. And because EAX contain the return value,
7104 + * we'd better not clobber it.
7105 + */
7106 +- leal efi_rt_function_ptr, %edx
7107 +- movl (%edx), %ecx
7108 +- pushl %ecx
7109 ++ pushl (efi_rt_function_ptr)
7110 +
7111 + /*
7112 +- * 10. Push the saved return address onto the stack and return.
7113 ++ * 10. Return to the saved return address.
7114 + */
7115 +- leal saved_return_addr, %edx
7116 +- movl (%edx), %ecx
7117 +- pushl %ecx
7118 +- ret
7119 ++ jmpl *(saved_return_addr)
7120 + .previous
7121 +
7122 +-.data
7123 ++__INITDATA
7124 + saved_return_addr:
7125 + .long 0
7126 + efi_rt_function_ptr:
7127 +diff -urNp linux-2.6.28.8/arch/x86/kernel/entry_32.S linux-2.6.28.8/arch/x86/kernel/entry_32.S
7128 +--- linux-2.6.28.8/arch/x86/kernel/entry_32.S 2009-02-06 16:47:45.000000000 -0500
7129 ++++ linux-2.6.28.8/arch/x86/kernel/entry_32.S 2009-02-21 09:37:48.000000000 -0500
7130 +@@ -101,7 +101,7 @@
7131 + #define resume_userspace_sig resume_userspace
7132 + #endif
7133 +
7134 +-#define SAVE_ALL \
7135 ++#define __SAVE_ALL(_DS) \
7136 + cld; \
7137 + pushl %fs; \
7138 + CFI_ADJUST_CFA_OFFSET 4;\
7139 +@@ -133,12 +133,26 @@
7140 + pushl %ebx; \
7141 + CFI_ADJUST_CFA_OFFSET 4;\
7142 + CFI_REL_OFFSET ebx, 0;\
7143 +- movl $(__USER_DS), %edx; \
7144 ++ movl $(_DS), %edx; \
7145 + movl %edx, %ds; \
7146 + movl %edx, %es; \
7147 + movl $(__KERNEL_PERCPU), %edx; \
7148 + movl %edx, %fs
7149 +
7150 ++#ifdef CONFIG_PAX_KERNEXEC
7151 ++#define SAVE_ALL \
7152 ++ __SAVE_ALL(__KERNEL_DS); \
7153 ++ GET_CR0_INTO_EDX; \
7154 ++ movl %edx, %esi; \
7155 ++ orl $X86_CR0_WP, %edx; \
7156 ++ xorl %edx, %esi; \
7157 ++ SET_CR0_FROM_EDX
7158 ++#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
7159 ++#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
7160 ++#else
7161 ++#define SAVE_ALL __SAVE_ALL(__USER_DS)
7162 ++#endif
7163 ++
7164 + #define RESTORE_INT_REGS \
7165 + popl %ebx; \
7166 + CFI_ADJUST_CFA_OFFSET -4;\
7167 +@@ -229,6 +243,11 @@ ENTRY(ret_from_fork)
7168 + CFI_ADJUST_CFA_OFFSET 4
7169 + popfl
7170 + CFI_ADJUST_CFA_OFFSET -4
7171 ++
7172 ++#ifdef CONFIG_PAX_KERNEXEC
7173 ++ xorl %esi, %esi
7174 ++#endif
7175 ++
7176 + jmp syscall_exit
7177 + CFI_ENDPROC
7178 + END(ret_from_fork)
7179 +@@ -252,7 +271,17 @@ check_userspace:
7180 + movb PT_CS(%esp), %al
7181 + andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax
7182 + cmpl $USER_RPL, %eax
7183 ++
7184 ++#ifdef CONFIG_PAX_KERNEXEC
7185 ++ jae resume_userspace
7186 ++
7187 ++ GET_CR0_INTO_EDX
7188 ++ xorl %esi, %edx
7189 ++ SET_CR0_FROM_EDX
7190 ++ jmp resume_kernel
7191 ++#else
7192 + jb resume_kernel # not returning to v8086 or userspace
7193 ++#endif
7194 +
7195 + ENTRY(resume_userspace)
7196 + LOCKDEP_SYS_EXIT
7197 +@@ -314,10 +343,9 @@ sysenter_past_esp:
7198 + /*CFI_REL_OFFSET cs, 0*/
7199 + /*
7200 + * Push current_thread_info()->sysenter_return to the stack.
7201 +- * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
7202 +- * pushed above; +8 corresponds to copy_thread's esp0 setting.
7203 + */
7204 +- pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
7205 ++ GET_THREAD_INFO(%ebp)
7206 ++ pushl TI_sysenter_return(%ebp)
7207 + CFI_ADJUST_CFA_OFFSET 4
7208 + CFI_REL_OFFSET eip, 0
7209 +
7210 +@@ -330,9 +358,19 @@ sysenter_past_esp:
7211 + * Load the potential sixth argument from user stack.
7212 + * Careful about security.
7213 + */
7214 ++ movl PT_OLDESP(%esp),%ebp
7215 ++
7216 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
7217 ++ mov PT_OLDSS(%esp),%ds
7218 ++1: movl %ds:(%ebp),%ebp
7219 ++ push %ss
7220 ++ pop %ds
7221 ++#else
7222 + cmpl $__PAGE_OFFSET-3,%ebp
7223 + jae syscall_fault
7224 + 1: movl (%ebp),%ebp
7225 ++#endif
7226 ++
7227 + movl %ebp,PT_EBP(%esp)
7228 + .section __ex_table,"a"
7229 + .align 4
7230 +@@ -356,12 +394,23 @@ sysenter_do_call:
7231 + testw $_TIF_ALLWORK_MASK, %cx
7232 + jne sysexit_audit
7233 + sysenter_exit:
7234 ++
7235 ++#ifdef CONFIG_PAX_RANDKSTACK
7236 ++ pushl %eax
7237 ++ CFI_ADJUST_CFA_OFFSET 4
7238 ++ call pax_randomize_kstack
7239 ++ popl %eax
7240 ++ CFI_ADJUST_CFA_OFFSET -4
7241 ++#endif
7242 ++
7243 + /* if something modifies registers it must also disable sysexit */
7244 + movl PT_EIP(%esp), %edx
7245 + movl PT_OLDESP(%esp), %ecx
7246 + xorl %ebp,%ebp
7247 + TRACE_IRQS_ON
7248 + 1: mov PT_FS(%esp), %fs
7249 ++2: mov PT_DS(%esp), %ds
7250 ++3: mov PT_ES(%esp), %es
7251 + ENABLE_INTERRUPTS_SYSEXIT
7252 +
7253 + #ifdef CONFIG_AUDITSYSCALL
7254 +@@ -404,11 +453,17 @@ sysexit_audit:
7255 +
7256 + CFI_ENDPROC
7257 + .pushsection .fixup,"ax"
7258 +-2: movl $0,PT_FS(%esp)
7259 ++4: movl $0,PT_FS(%esp)
7260 ++ jmp 1b
7261 ++5: movl $0,PT_DS(%esp)
7262 ++ jmp 1b
7263 ++6: movl $0,PT_ES(%esp)
7264 + jmp 1b
7265 + .section __ex_table,"a"
7266 + .align 4
7267 +- .long 1b,2b
7268 ++ .long 1b,4b
7269 ++ .long 2b,5b
7270 ++ .long 3b,6b
7271 + .popsection
7272 + ENDPROC(ia32_sysenter_target)
7273 +
7274 +@@ -438,6 +493,10 @@ syscall_exit:
7275 + testw $_TIF_ALLWORK_MASK, %cx # current->work
7276 + jne syscall_exit_work
7277 +
7278 ++#ifdef CONFIG_PAX_RANDKSTACK
7279 ++ call pax_randomize_kstack
7280 ++#endif
7281 ++
7282 + restore_all:
7283 + movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
7284 + # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
7285 +@@ -531,25 +590,19 @@ work_resched:
7286 +
7287 + work_notifysig: # deal with pending signals and
7288 + # notify-resume requests
7289 ++ movl %esp, %eax
7290 + #ifdef CONFIG_VM86
7291 + testl $X86_EFLAGS_VM, PT_EFLAGS(%esp)
7292 +- movl %esp, %eax
7293 +- jne work_notifysig_v86 # returning to kernel-space or
7294 ++ jz 1f # returning to kernel-space or
7295 + # vm86-space
7296 +- xorl %edx, %edx
7297 +- call do_notify_resume
7298 +- jmp resume_userspace_sig
7299 +
7300 +- ALIGN
7301 +-work_notifysig_v86:
7302 + pushl %ecx # save ti_flags for do_notify_resume
7303 + CFI_ADJUST_CFA_OFFSET 4
7304 + call save_v86_state # %eax contains pt_regs pointer
7305 + popl %ecx
7306 + CFI_ADJUST_CFA_OFFSET -4
7307 + movl %eax, %esp
7308 +-#else
7309 +- movl %esp, %eax
7310 ++1:
7311 + #endif
7312 + xorl %edx, %edx
7313 + call do_notify_resume
7314 +@@ -584,6 +637,10 @@ END(syscall_exit_work)
7315 +
7316 + RING0_INT_FRAME # can't unwind into user space anyway
7317 + syscall_fault:
7318 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
7319 ++ push %ss
7320 ++ pop %ds
7321 ++#endif
7322 + GET_THREAD_INFO(%ebp)
7323 + movl $-EFAULT,PT_EAX(%esp)
7324 + jmp resume_userspace
7325 +@@ -595,17 +652,24 @@ syscall_badsys:
7326 + END(syscall_badsys)
7327 + CFI_ENDPROC
7328 +
7329 +-#define FIXUP_ESPFIX_STACK \
7330 +- /* since we are on a wrong stack, we cant make it a C code :( */ \
7331 +- PER_CPU(gdt_page, %ebx); \
7332 +- GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \
7333 +- addl %esp, %eax; \
7334 +- pushl $__KERNEL_DS; \
7335 +- CFI_ADJUST_CFA_OFFSET 4; \
7336 +- pushl %eax; \
7337 +- CFI_ADJUST_CFA_OFFSET 4; \
7338 +- lss (%esp), %esp; \
7339 ++.macro FIXUP_ESPFIX_STACK
7340 ++ /* since we are on a wrong stack, we cant make it a C code :( */
7341 ++#ifdef CONFIG_SMP
7342 ++ movl PER_CPU_VAR(cpu_number), %ebx;
7343 ++ shll $PAGE_SHIFT_asm, %ebx;
7344 ++ addl $cpu_gdt_table, %ebx;
7345 ++#else
7346 ++ movl $cpu_gdt_table, %ebx;
7347 ++#endif
7348 ++ GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah);
7349 ++ addl %esp, %eax;
7350 ++ pushl $__KERNEL_DS;
7351 ++ CFI_ADJUST_CFA_OFFSET 4;
7352 ++ pushl %eax;
7353 ++ CFI_ADJUST_CFA_OFFSET 4;
7354 ++ lss (%esp), %esp;
7355 + CFI_ADJUST_CFA_OFFSET -8;
7356 ++.endm
7357 + #define UNWIND_ESPFIX_STACK \
7358 + movl %ss, %eax; \
7359 + /* see if on espfix stack */ \
7360 +@@ -622,7 +686,7 @@ END(syscall_badsys)
7361 + * Build the entry stubs and pointer table with
7362 + * some assembler magic.
7363 + */
7364 +-.section .rodata,"a"
7365 ++.section .rodata,"a",@progbits
7366 + ENTRY(interrupt)
7367 + .text
7368 +
7369 +@@ -722,12 +786,21 @@ error_code:
7370 + popl %ecx
7371 + CFI_ADJUST_CFA_OFFSET -4
7372 + /*CFI_REGISTER es, ecx*/
7373 ++
7374 ++#ifdef CONFIG_PAX_KERNEXEC
7375 ++ GET_CR0_INTO_EDX
7376 ++ movl %edx, %esi
7377 ++ orl $X86_CR0_WP, %edx
7378 ++ xorl %edx, %esi
7379 ++ SET_CR0_FROM_EDX
7380 ++#endif
7381 ++
7382 + movl PT_FS(%esp), %edi # get the function address
7383 + movl PT_ORIG_EAX(%esp), %edx # get the error code
7384 + movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
7385 + mov %ecx, PT_FS(%esp)
7386 + /*CFI_REL_OFFSET fs, ES*/
7387 +- movl $(__USER_DS), %ecx
7388 ++ movl $(__KERNEL_DS), %ecx
7389 + movl %ecx, %ds
7390 + movl %ecx, %es
7391 + TRACE_IRQS_OFF
7392 +@@ -853,6 +926,13 @@ nmi_stack_correct:
7393 + xorl %edx,%edx # zero error code
7394 + movl %esp,%eax # pt_regs pointer
7395 + call do_nmi
7396 ++
7397 ++#ifdef CONFIG_PAX_KERNEXEC
7398 ++ GET_CR0_INTO_EDX
7399 ++ xorl %esi, %edx
7400 ++ SET_CR0_FROM_EDX
7401 ++#endif
7402 ++
7403 + jmp restore_nocheck_notrace
7404 + CFI_ENDPROC
7405 +
7406 +@@ -894,6 +974,13 @@ nmi_espfix_stack:
7407 + FIXUP_ESPFIX_STACK # %eax == %esp
7408 + xorl %edx,%edx # zero error code
7409 + call do_nmi
7410 ++
7411 ++#ifdef CONFIG_PAX_KERNEXEC
7412 ++ GET_CR0_INTO_EDX
7413 ++ xorl %esi, %edx
7414 ++ SET_CR0_FROM_EDX
7415 ++#endif
7416 ++
7417 + RESTORE_REGS
7418 + lss 12+4(%esp), %esp # back to espfix stack
7419 + CFI_ADJUST_CFA_OFFSET -24
7420 +@@ -1206,7 +1293,6 @@ END(mcount)
7421 + #endif /* CONFIG_DYNAMIC_FTRACE */
7422 + #endif /* CONFIG_FUNCTION_TRACER */
7423 +
7424 +-.section .rodata,"a"
7425 + #include "syscall_table_32.S"
7426 +
7427 + syscall_table_size=(.-sys_call_table)
7428 +diff -urNp linux-2.6.28.8/arch/x86/kernel/entry_64.S linux-2.6.28.8/arch/x86/kernel/entry_64.S
7429 +--- linux-2.6.28.8/arch/x86/kernel/entry_64.S 2009-02-06 16:47:45.000000000 -0500
7430 ++++ linux-2.6.28.8/arch/x86/kernel/entry_64.S 2009-02-21 09:37:48.000000000 -0500
7431 +@@ -911,7 +911,8 @@ END(spurious_interrupt)
7432 + xorl %ebx,%ebx
7433 + 1:
7434 + .if \ist
7435 +- movq %gs:pda_data_offset, %rbp
7436 ++ imul $TSS_size, %gs:pda_cpunumber, %ebp
7437 ++ lea init_tss(%rbp), %rbp
7438 + .endif
7439 + .if \irqtrace
7440 + TRACE_IRQS_OFF
7441 +@@ -920,11 +921,11 @@ END(spurious_interrupt)
7442 + movq ORIG_RAX(%rsp),%rsi
7443 + movq $-1,ORIG_RAX(%rsp)
7444 + .if \ist
7445 +- subq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
7446 ++ subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
7447 + .endif
7448 + call \sym
7449 + .if \ist
7450 +- addq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
7451 ++ addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
7452 + .endif
7453 + DISABLE_INTERRUPTS(CLBR_NONE)
7454 + .if \irqtrace
7455 +diff -urNp linux-2.6.28.8/arch/x86/kernel/ftrace.c linux-2.6.28.8/arch/x86/kernel/ftrace.c
7456 +--- linux-2.6.28.8/arch/x86/kernel/ftrace.c 2009-02-06 16:47:45.000000000 -0500
7457 ++++ linux-2.6.28.8/arch/x86/kernel/ftrace.c 2009-02-21 09:37:48.000000000 -0500
7458 +@@ -95,9 +95,9 @@ int ftrace_update_ftrace_func(ftrace_fun
7459 + unsigned char old[MCOUNT_INSN_SIZE], *new;
7460 + int ret;
7461 +
7462 +- memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE);
7463 ++ memcpy(old, (void *)ktla_ktva((unsigned long)ftrace_call), MCOUNT_INSN_SIZE);
7464 + new = ftrace_call_replace(ip, (unsigned long)func);
7465 +- ret = ftrace_modify_code(ip, old, new);
7466 ++ ret = ftrace_modify_code(ktla_ktva(ip), old, new);
7467 +
7468 + return ret;
7469 + }
7470 +diff -urNp linux-2.6.28.8/arch/x86/kernel/head32.c linux-2.6.28.8/arch/x86/kernel/head32.c
7471 +--- linux-2.6.28.8/arch/x86/kernel/head32.c 2009-02-06 16:47:45.000000000 -0500
7472 ++++ linux-2.6.28.8/arch/x86/kernel/head32.c 2009-02-21 09:37:48.000000000 -0500
7473 +@@ -12,10 +12,11 @@
7474 + #include <asm/sections.h>
7475 + #include <asm/e820.h>
7476 + #include <asm/bios_ebda.h>
7477 ++#include <asm/boot.h>
7478 +
7479 + void __init i386_start_kernel(void)
7480 + {
7481 +- reserve_early(__pa_symbol(&_text), __pa_symbol(&_end), "TEXT DATA BSS");
7482 ++ reserve_early(LOAD_PHYSICAL_ADDR, __pa_symbol(&_end), "TEXT DATA BSS");
7483 +
7484 + #ifdef CONFIG_BLK_DEV_INITRD
7485 + /* Reserve INITRD */
7486 +diff -urNp linux-2.6.28.8/arch/x86/kernel/head_32.S linux-2.6.28.8/arch/x86/kernel/head_32.S
7487 +--- linux-2.6.28.8/arch/x86/kernel/head_32.S 2009-02-06 16:47:45.000000000 -0500
7488 ++++ linux-2.6.28.8/arch/x86/kernel/head_32.S 2009-02-21 09:37:48.000000000 -0500
7489 +@@ -19,6 +19,7 @@
7490 + #include <asm/asm-offsets.h>
7491 + #include <asm/setup.h>
7492 + #include <asm/processor-flags.h>
7493 ++#include <asm/msr-index.h>
7494 +
7495 + /* Physical address */
7496 + #define pa(X) ((X) - __PAGE_OFFSET)
7497 +@@ -64,17 +65,22 @@ LOW_PAGES = 1<<(32-PAGE_SHIFT_asm)
7498 + LOW_PAGES = LOW_PAGES + 0x1000000
7499 + #endif
7500 +
7501 +-#if PTRS_PER_PMD > 1
7502 +-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD
7503 +-#else
7504 +-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD)
7505 +-#endif
7506 ++PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PTE)
7507 + BOOTBITMAP_SIZE = LOW_PAGES / 8
7508 + ALLOCATOR_SLOP = 4
7509 +
7510 + INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
7511 +
7512 + /*
7513 ++ * Real beginning of normal "text" segment
7514 ++ */
7515 ++ENTRY(stext)
7516 ++ENTRY(_stext)
7517 ++
7518 ++.section .text.startup,"ax",@progbits
7519 ++ ljmp $(__BOOT_CS),$phys_startup_32
7520 ++
7521 ++/*
7522 + * 32-bit kernel entrypoint; only used by the boot CPU. On entry,
7523 + * %esi points to the real-mode code as a 32-bit pointer.
7524 + * CS and DS must be 4 GB flat segments, but we don't depend on
7525 +@@ -82,6 +88,12 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE +
7526 + * can.
7527 + */
7528 + .section .text.head,"ax",@progbits
7529 ++
7530 ++#ifdef CONFIG_PAX_KERNEXEC
7531 ++/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
7532 ++.fill 4096,1,0xcc
7533 ++#endif
7534 ++
7535 + ENTRY(startup_32)
7536 + /* test KEEP_SEGMENTS flag to see if the bootloader is asking
7537 + us to not reload segments */
7538 +@@ -99,6 +111,56 @@ ENTRY(startup_32)
7539 + movl %eax,%gs
7540 + 2:
7541 +
7542 ++ movl $pa(cpu_gdt_table),%edi
7543 ++ movl $__per_cpu_start,%eax
7544 ++ movw %ax,__KERNEL_PERCPU + 2(%edi)
7545 ++ rorl $16,%eax
7546 ++ movb %al,__KERNEL_PERCPU + 4(%edi)
7547 ++ movb %ah,__KERNEL_PERCPU + 7(%edi)
7548 ++ movl $__per_cpu_end + PERCPU_MODULE_RESERVE - 1,%eax
7549 ++ subl $__per_cpu_start,%eax
7550 ++ movw %ax,__KERNEL_PERCPU + 0(%edi)
7551 ++
7552 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
7553 ++ /* check for VMware */
7554 ++ movl $0x564d5868,%eax
7555 ++ xorl %ebx,%ebx
7556 ++ movl $0xa,%ecx
7557 ++ movl $0x5658,%edx
7558 ++ in (%dx),%eax
7559 ++ cmpl $0x564d5868,%ebx
7560 ++ jz 2f
7561 ++
7562 ++ movl $NR_CPUS,%ecx
7563 ++ movl $pa(cpu_gdt_table),%edi
7564 ++1:
7565 ++ movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),GDT_ENTRY_KERNEL_DS * 8 + 4(%edi)
7566 ++ addl $PAGE_SIZE_asm,%edi
7567 ++ loop 1b
7568 ++2:
7569 ++#endif
7570 ++
7571 ++#ifdef CONFIG_PAX_KERNEXEC
7572 ++ movl $pa(boot_gdt),%edi
7573 ++ movl $KERNEL_TEXT_OFFSET,%eax
7574 ++ movw %ax,__BOOT_CS + 2(%edi)
7575 ++ rorl $16,%eax
7576 ++ movb %al,__BOOT_CS + 4(%edi)
7577 ++ movb %ah,__BOOT_CS + 7(%edi)
7578 ++ rorl $16,%eax
7579 ++
7580 ++ movl $NR_CPUS,%ecx
7581 ++ movl $pa(cpu_gdt_table),%edi
7582 ++1:
7583 ++ movw %ax,__KERNEL_CS + 2(%edi)
7584 ++ rorl $16,%eax
7585 ++ movb %al,__KERNEL_CS + 4(%edi)
7586 ++ movb %ah,__KERNEL_CS + 7(%edi)
7587 ++ rorl $16,%eax
7588 ++ addl $PAGE_SIZE_asm,%edi
7589 ++ loop 1b
7590 ++#endif
7591 ++
7592 + /*
7593 + * Clear BSS first so that there are no surprises...
7594 + */
7595 +@@ -142,9 +204,7 @@ ENTRY(startup_32)
7596 + cmpl $num_subarch_entries, %eax
7597 + jae bad_subarch
7598 +
7599 +- movl pa(subarch_entries)(,%eax,4), %eax
7600 +- subl $__PAGE_OFFSET, %eax
7601 +- jmp *%eax
7602 ++ jmp *pa(subarch_entries)(,%eax,4)
7603 +
7604 + bad_subarch:
7605 + WEAK(lguest_entry)
7606 +@@ -156,9 +216,9 @@ WEAK(xen_entry)
7607 + __INITDATA
7608 +
7609 + subarch_entries:
7610 +- .long default_entry /* normal x86/PC */
7611 +- .long lguest_entry /* lguest hypervisor */
7612 +- .long xen_entry /* Xen hypervisor */
7613 ++ .long pa(default_entry) /* normal x86/PC */
7614 ++ .long pa(lguest_entry) /* lguest hypervisor */
7615 ++ .long pa(xen_entry) /* Xen hypervisor */
7616 + num_subarch_entries = (. - subarch_entries) / 4
7617 + .previous
7618 + #endif /* CONFIG_PARAVIRT */
7619 +@@ -220,8 +280,7 @@ default_entry:
7620 + movl %eax, pa(max_pfn_mapped)
7621 +
7622 + /* Do early initialization of the fixmap area */
7623 +- movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,%eax
7624 +- movl %eax,pa(swapper_pg_pmd+0x1000*KPMDS-8)
7625 ++ movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,pa(swapper_pg_pmd+0x1000*KPMDS-8)
7626 + #else /* Not PAE */
7627 +
7628 + page_pde_offset = (__PAGE_OFFSET >> 20);
7629 +@@ -253,8 +312,7 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
7630 + movl %eax, pa(max_pfn_mapped)
7631 +
7632 + /* Do early initialization of the fixmap area */
7633 +- movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,%eax
7634 +- movl %eax,pa(swapper_pg_dir+0xffc)
7635 ++ movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,pa(swapper_pg_dir+0xffc)
7636 + #endif
7637 + jmp 3f
7638 + /*
7639 +@@ -318,13 +376,16 @@ ENTRY(startup_32_smp)
7640 + jnc 6f
7641 +
7642 + /* Setup EFER (Extended Feature Enable Register) */
7643 +- movl $0xc0000080, %ecx
7644 ++ movl $MSR_EFER, %ecx
7645 + rdmsr
7646 +
7647 + btsl $11, %eax
7648 + /* Make changes effective */
7649 + wrmsr
7650 +
7651 ++ btsl $_PAGE_BIT_NX-32,pa(__supported_pte_mask+4)
7652 ++ movl $1,pa(nx_enabled)
7653 ++
7654 + 6:
7655 +
7656 + /*
7657 +@@ -350,9 +411,7 @@ ENTRY(startup_32_smp)
7658 +
7659 + #ifdef CONFIG_SMP
7660 + cmpb $0, ready
7661 +- jz 1f /* Initial CPU cleans BSS */
7662 +- jmp checkCPUtype
7663 +-1:
7664 ++ jnz checkCPUtype /* Initial CPU cleans BSS */
7665 + #endif /* CONFIG_SMP */
7666 +
7667 + /*
7668 +@@ -429,12 +488,12 @@ is386: movl $2,%ecx # set MP
7669 + ljmp $(__KERNEL_CS),$1f
7670 + 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
7671 + movl %eax,%ss # after changing gdt.
7672 +- movl %eax,%fs # gets reset once there's real percpu
7673 +-
7674 +- movl $(__USER_DS),%eax # DS/ES contains default USER segment
7675 + movl %eax,%ds
7676 + movl %eax,%es
7677 +
7678 ++ movl $(__KERNEL_PERCPU), %eax
7679 ++ movl %eax,%fs # set this cpu's percpu
7680 ++
7681 + xorl %eax,%eax # Clear GS and LDT
7682 + movl %eax,%gs
7683 + lldt %ax
7684 +@@ -444,12 +503,6 @@ is386: movl $2,%ecx # set MP
7685 + #ifdef CONFIG_SMP
7686 + movb ready, %cl
7687 + movb $1, ready
7688 +- cmpb $0,%cl # the first CPU calls start_kernel
7689 +- je 1f
7690 +- movl $(__KERNEL_PERCPU), %eax
7691 +- movl %eax,%fs # set this cpu's percpu
7692 +- movl (stack_start), %esp
7693 +-1:
7694 + #endif /* CONFIG_SMP */
7695 + jmp *(initial_code)
7696 +
7697 +@@ -535,15 +588,15 @@ early_page_fault:
7698 + jmp early_fault
7699 +
7700 + early_fault:
7701 +- cld
7702 + #ifdef CONFIG_PRINTK
7703 ++ cmpl $2,%ss:early_recursion_flag
7704 ++ je hlt_loop
7705 ++ incl %ss:early_recursion_flag
7706 ++ cld
7707 + pusha
7708 + movl $(__KERNEL_DS),%eax
7709 + movl %eax,%ds
7710 + movl %eax,%es
7711 +- cmpl $2,early_recursion_flag
7712 +- je hlt_loop
7713 +- incl early_recursion_flag
7714 + movl %cr2,%eax
7715 + pushl %eax
7716 + pushl %edx /* trapno */
7717 +@@ -553,8 +606,8 @@ early_fault:
7718 + #else
7719 + call printk
7720 + #endif
7721 +-#endif
7722 + call dump_stack
7723 ++#endif
7724 + hlt_loop:
7725 + hlt
7726 + jmp hlt_loop
7727 +@@ -562,8 +615,11 @@ hlt_loop:
7728 + /* This is the default interrupt "handler" :-) */
7729 + ALIGN
7730 + ignore_int:
7731 +- cld
7732 + #ifdef CONFIG_PRINTK
7733 ++ cmpl $2,%ss:early_recursion_flag
7734 ++ je hlt_loop
7735 ++ incl %ss:early_recursion_flag
7736 ++ cld
7737 + pushl %eax
7738 + pushl %ecx
7739 + pushl %edx
7740 +@@ -572,9 +628,6 @@ ignore_int:
7741 + movl $(__KERNEL_DS),%eax
7742 + movl %eax,%ds
7743 + movl %eax,%es
7744 +- cmpl $2,early_recursion_flag
7745 +- je hlt_loop
7746 +- incl early_recursion_flag
7747 + pushl 16(%esp)
7748 + pushl 24(%esp)
7749 + pushl 32(%esp)
7750 +@@ -599,36 +652,41 @@ ignore_int:
7751 + ENTRY(initial_code)
7752 + .long i386_start_kernel
7753 +
7754 +-.section .text
7755 +-/*
7756 +- * Real beginning of normal "text" segment
7757 +- */
7758 +-ENTRY(stext)
7759 +-ENTRY(_stext)
7760 +-
7761 + /*
7762 + * BSS section
7763 + */
7764 +-.section ".bss.page_aligned","wa"
7765 +- .align PAGE_SIZE_asm
7766 + #ifdef CONFIG_X86_PAE
7767 ++.section .swapper_pg_pmd,"a",@progbits
7768 + swapper_pg_pmd:
7769 + .fill 1024*KPMDS,4,0
7770 + #else
7771 ++.section .swapper_pg_dir,"a",@progbits
7772 + ENTRY(swapper_pg_dir)
7773 + .fill 1024,4,0
7774 + #endif
7775 + swapper_pg_fixmap:
7776 + .fill 1024,4,0
7777 ++
7778 ++.section .empty_zero_page,"a",@progbits
7779 + ENTRY(empty_zero_page)
7780 + .fill 4096,1,0
7781 ++
7782 ++/*
7783 ++ * The IDT has to be page-aligned to simplify the Pentium
7784 ++ * F0 0F bug workaround.. We have a special link segment
7785 ++ * for this.
7786 ++ */
7787 ++.section .idt,"a",@progbits
7788 ++ENTRY(idt_table)
7789 ++ .fill 256,8,0
7790 ++
7791 + /*
7792 + * This starts the data section.
7793 + */
7794 ++.data
7795 ++
7796 + #ifdef CONFIG_X86_PAE
7797 +-.section ".data.page_aligned","wa"
7798 +- /* Page-aligned for the benefit of paravirt? */
7799 +- .align PAGE_SIZE_asm
7800 ++.section .swapper_pg_dir,"a",@progbits
7801 + ENTRY(swapper_pg_dir)
7802 + .long pa(swapper_pg_pmd+PGD_IDENT_ATTR),0 /* low identity map */
7803 + # if KPMDS == 3
7804 +@@ -651,11 +709,12 @@ ENTRY(swapper_pg_dir)
7805 +
7806 + .data
7807 + ENTRY(stack_start)
7808 +- .long init_thread_union+THREAD_SIZE
7809 ++ .long init_thread_union+THREAD_SIZE-8
7810 + .long __BOOT_DS
7811 +
7812 + ready: .byte 0
7813 +
7814 ++.section .rodata,"a",@progbits
7815 + early_recursion_flag:
7816 + .long 0
7817 +
7818 +@@ -691,7 +750,7 @@ fault_msg:
7819 + .word 0 # 32 bit align gdt_desc.address
7820 + boot_gdt_descr:
7821 + .word __BOOT_DS+7
7822 +- .long boot_gdt - __PAGE_OFFSET
7823 ++ .long pa(boot_gdt)
7824 +
7825 + .word 0 # 32-bit align idt_desc.address
7826 + idt_descr:
7827 +@@ -702,7 +761,7 @@ idt_descr:
7828 + .word 0 # 32 bit align gdt_desc.address
7829 + ENTRY(early_gdt_descr)
7830 + .word GDT_ENTRIES*8-1
7831 +- .long per_cpu__gdt_page /* Overwritten for secondary CPUs */
7832 ++ .long cpu_gdt_table /* Overwritten for secondary CPUs */
7833 +
7834 + /*
7835 + * The boot_gdt must mirror the equivalent in setup.S and is
7836 +@@ -711,5 +770,59 @@ ENTRY(early_gdt_descr)
7837 + .align L1_CACHE_BYTES
7838 + ENTRY(boot_gdt)
7839 + .fill GDT_ENTRY_BOOT_CS,8,0
7840 +- .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
7841 +- .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
7842 ++ .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */
7843 ++ .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */
7844 ++
7845 ++ .align PAGE_SIZE_asm
7846 ++ENTRY(cpu_gdt_table)
7847 ++ .rept NR_CPUS
7848 ++ .quad 0x0000000000000000 /* NULL descriptor */
7849 ++ .quad 0x0000000000000000 /* 0x0b reserved */
7850 ++ .quad 0x0000000000000000 /* 0x13 reserved */
7851 ++ .quad 0x0000000000000000 /* 0x1b reserved */
7852 ++ .quad 0x0000000000000000 /* 0x20 unused */
7853 ++ .quad 0x0000000000000000 /* 0x28 unused */
7854 ++ .quad 0x0000000000000000 /* 0x33 TLS entry 1 */
7855 ++ .quad 0x0000000000000000 /* 0x3b TLS entry 2 */
7856 ++ .quad 0x0000000000000000 /* 0x43 TLS entry 3 */
7857 ++ .quad 0x0000000000000000 /* 0x4b reserved */
7858 ++ .quad 0x0000000000000000 /* 0x53 reserved */
7859 ++ .quad 0x0000000000000000 /* 0x5b reserved */
7860 ++
7861 ++ .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
7862 ++ .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
7863 ++ .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */
7864 ++ .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */
7865 ++
7866 ++ .quad 0x0000000000000000 /* 0x80 TSS descriptor */
7867 ++ .quad 0x0000000000000000 /* 0x88 LDT descriptor */
7868 ++
7869 ++ /*
7870 ++ * Segments used for calling PnP BIOS have byte granularity.
7871 ++ * The code segments and data segments have fixed 64k limits,
7872 ++ * the transfer segment sizes are set at run time.
7873 ++ */
7874 ++ .quad 0x00409b000000ffff /* 0x90 32-bit code */
7875 ++ .quad 0x00009b000000ffff /* 0x98 16-bit code */
7876 ++ .quad 0x000093000000ffff /* 0xa0 16-bit data */
7877 ++ .quad 0x0000930000000000 /* 0xa8 16-bit data */
7878 ++ .quad 0x0000930000000000 /* 0xb0 16-bit data */
7879 ++
7880 ++ /*
7881 ++ * The APM segments have byte granularity and their bases
7882 ++ * are set at run time. All have 64k limits.
7883 ++ */
7884 ++ .quad 0x00409b000000ffff /* 0xb8 APM CS code */
7885 ++ .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */
7886 ++ .quad 0x004093000000ffff /* 0xc8 APM DS data */
7887 ++
7888 ++ .quad 0x00c0930000000000 /* 0xd0 - ESPFIX SS */
7889 ++ .quad 0x0040930000000000 /* 0xd8 - PERCPU */
7890 ++ .quad 0x0000000000000000 /* 0xe0 - PCIBIOS_CS */
7891 ++ .quad 0x0000000000000000 /* 0xe8 - PCIBIOS_DS */
7892 ++ .quad 0x0000000000000000 /* 0xf0 - unused */
7893 ++ .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
7894 ++
7895 ++ /* Be sure this is zeroed to avoid false validations in Xen */
7896 ++ .fill PAGE_SIZE_asm - GDT_SIZE,1,0
7897 ++ .endr
7898 +diff -urNp linux-2.6.28.8/arch/x86/kernel/head64.c linux-2.6.28.8/arch/x86/kernel/head64.c
7899 +--- linux-2.6.28.8/arch/x86/kernel/head64.c 2009-02-06 16:47:45.000000000 -0500
7900 ++++ linux-2.6.28.8/arch/x86/kernel/head64.c 2009-02-21 09:37:48.000000000 -0500
7901 +@@ -93,6 +93,8 @@ void __init x86_64_start_kernel(char * r
7902 + /* clear bss before set_intr_gate with early_idt_handler */
7903 + clear_bss();
7904 +
7905 ++ x86_64_init_pda();
7906 ++
7907 + /* Make NULL pointers segfault */
7908 + zap_identity_mappings();
7909 +
7910 +@@ -111,8 +113,6 @@ void __init x86_64_start_kernel(char * r
7911 + if (console_loglevel == 10)
7912 + early_printk("Kernel alive\n");
7913 +
7914 +- x86_64_init_pda();
7915 +-
7916 + x86_64_start_reservations(real_mode_data);
7917 + }
7918 +
7919 +diff -urNp linux-2.6.28.8/arch/x86/kernel/head_64.S linux-2.6.28.8/arch/x86/kernel/head_64.S
7920 +--- linux-2.6.28.8/arch/x86/kernel/head_64.S 2009-02-06 16:47:45.000000000 -0500
7921 ++++ linux-2.6.28.8/arch/x86/kernel/head_64.S 2009-02-21 09:37:48.000000000 -0500
7922 +@@ -38,6 +38,10 @@ L4_PAGE_OFFSET = pgd_index(__PAGE_OFFSET
7923 + L3_PAGE_OFFSET = pud_index(__PAGE_OFFSET)
7924 + L4_START_KERNEL = pgd_index(__START_KERNEL_map)
7925 + L3_START_KERNEL = pud_index(__START_KERNEL_map)
7926 ++L4_VMALLOC_START = pgd_index(VMALLOC_START)
7927 ++L3_VMALLOC_START = pud_index(VMALLOC_START)
7928 ++L4_VMEMMAP_START = pgd_index(VMEMMAP_START)
7929 ++L3_VMEMMAP_START = pud_index(VMEMMAP_START)
7930 +
7931 + .text
7932 + .section .text.head
7933 +@@ -85,35 +89,22 @@ startup_64:
7934 + */
7935 + addq %rbp, init_level4_pgt + 0(%rip)
7936 + addq %rbp, init_level4_pgt + (L4_PAGE_OFFSET*8)(%rip)
7937 ++ addq %rbp, init_level4_pgt + (L4_VMALLOC_START*8)(%rip)
7938 ++ addq %rbp, init_level4_pgt + (L4_VMEMMAP_START*8)(%rip)
7939 + addq %rbp, init_level4_pgt + (L4_START_KERNEL*8)(%rip)
7940 +
7941 + addq %rbp, level3_ident_pgt + 0(%rip)
7942 ++ addq %rbp, level3_ident_pgt + 8(%rip)
7943 ++ addq %rbp, level3_ident_pgt + 16(%rip)
7944 ++ addq %rbp, level3_ident_pgt + 24(%rip)
7945 +
7946 +- addq %rbp, level3_kernel_pgt + (510*8)(%rip)
7947 +- addq %rbp, level3_kernel_pgt + (511*8)(%rip)
7948 ++ addq %rbp, level3_vmemmap_pgt + (L3_VMEMMAP_START*8)(%rip)
7949 +
7950 +- addq %rbp, level2_fixmap_pgt + (506*8)(%rip)
7951 ++ addq %rbp, level3_kernel_pgt + (L3_START_KERNEL*8)(%rip)
7952 ++ addq %rbp, level3_kernel_pgt + (L3_START_KERNEL*8+8)(%rip)
7953 +
7954 +- /* Add an Identity mapping if I am above 1G */
7955 +- leaq _text(%rip), %rdi
7956 +- andq $PMD_PAGE_MASK, %rdi
7957 +-
7958 +- movq %rdi, %rax
7959 +- shrq $PUD_SHIFT, %rax
7960 +- andq $(PTRS_PER_PUD - 1), %rax
7961 +- jz ident_complete
7962 +-
7963 +- leaq (level2_spare_pgt - __START_KERNEL_map + _KERNPG_TABLE)(%rbp), %rdx
7964 +- leaq level3_ident_pgt(%rip), %rbx
7965 +- movq %rdx, 0(%rbx, %rax, 8)
7966 +-
7967 +- movq %rdi, %rax
7968 +- shrq $PMD_SHIFT, %rax
7969 +- andq $(PTRS_PER_PMD - 1), %rax
7970 +- leaq __PAGE_KERNEL_IDENT_LARGE_EXEC(%rdi), %rdx
7971 +- leaq level2_spare_pgt(%rip), %rbx
7972 +- movq %rdx, 0(%rbx, %rax, 8)
7973 +-ident_complete:
7974 ++ addq %rbp, level2_fixmap_pgt + (506*8)(%rip)
7975 ++ addq %rbp, level2_fixmap_pgt + (507*8)(%rip)
7976 +
7977 + /*
7978 + * Fixup the kernel text+data virtual addresses. Note that
7979 +@@ -187,6 +178,10 @@ ENTRY(secondary_startup_64)
7980 + btl $20,%edi /* No Execute supported? */
7981 + jnc 1f
7982 + btsl $_EFER_NX, %eax
7983 ++ leaq init_level4_pgt(%rip), %rdi
7984 ++ btsq $_PAGE_BIT_NX, 8*L4_PAGE_OFFSET(%rdi)
7985 ++ btsq $_PAGE_BIT_NX, 8*L4_VMALLOC_START(%rdi)
7986 ++ btsq $_PAGE_BIT_NX, 8*L4_VMEMMAP_START(%rdi)
7987 + 1: wrmsr /* Make changes effective */
7988 +
7989 + /* Setup cr0 */
7990 +@@ -257,16 +252,16 @@ ENTRY(secondary_startup_64)
7991 + .align 8
7992 + ENTRY(initial_code)
7993 + .quad x86_64_start_kernel
7994 +- __FINITDATA
7995 +
7996 + ENTRY(stack_start)
7997 + .quad init_thread_union+THREAD_SIZE-8
7998 + .word 0
7999 ++ __FINITDATA
8000 +
8001 + bad_address:
8002 + jmp bad_address
8003 +
8004 +- .section ".init.text","ax"
8005 ++ __INIT
8006 + #ifdef CONFIG_EARLY_PRINTK
8007 + .globl early_idt_handlers
8008 + early_idt_handlers:
8009 +@@ -311,18 +306,23 @@ ENTRY(early_idt_handler)
8010 + #endif /* EARLY_PRINTK */
8011 + 1: hlt
8012 + jmp 1b
8013 ++ .previous
8014 +
8015 + #ifdef CONFIG_EARLY_PRINTK
8016 ++ __INITDATA
8017 + early_recursion_flag:
8018 + .long 0
8019 ++ .previous
8020 +
8021 ++ .section .rodata,"a",@progbits
8022 + early_idt_msg:
8023 + .asciz "PANIC: early exception %02lx rip %lx:%lx error %lx cr2 %lx\n"
8024 + early_idt_ripmsg:
8025 + .asciz "RIP %s\n"
8026 +-#endif /* CONFIG_EARLY_PRINTK */
8027 + .previous
8028 ++#endif /* CONFIG_EARLY_PRINTK */
8029 +
8030 ++ .section .rodata,"a",@progbits
8031 + .balign PAGE_SIZE
8032 +
8033 + #define NEXT_PAGE(name) \
8034 +@@ -347,13 +347,27 @@ NEXT_PAGE(init_level4_pgt)
8035 + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
8036 + .org init_level4_pgt + L4_PAGE_OFFSET*8, 0
8037 + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
8038 ++ .org init_level4_pgt + L4_VMALLOC_START*8, 0
8039 ++ .quad level3_vmalloc_pgt - __START_KERNEL_map + _KERNPG_TABLE
8040 ++ .org init_level4_pgt + L4_VMEMMAP_START*8, 0
8041 ++ .quad level3_vmemmap_pgt - __START_KERNEL_map + _KERNPG_TABLE
8042 + .org init_level4_pgt + L4_START_KERNEL*8, 0
8043 + /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
8044 + .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE
8045 +
8046 + NEXT_PAGE(level3_ident_pgt)
8047 + .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
8048 +- .fill 511,8,0
8049 ++ .quad level2_ident_pgt + PAGE_SIZE - __START_KERNEL_map + _KERNPG_TABLE
8050 ++ .quad level2_ident_pgt + 2*PAGE_SIZE - __START_KERNEL_map + _KERNPG_TABLE
8051 ++ .quad level2_ident_pgt + 3*PAGE_SIZE - __START_KERNEL_map + _KERNPG_TABLE
8052 ++ .fill 508,8,0
8053 ++
8054 ++NEXT_PAGE(level3_vmalloc_pgt)
8055 ++ .fill 512,8,0
8056 ++
8057 ++NEXT_PAGE(level3_vmemmap_pgt)
8058 ++ .fill L3_VMEMMAP_START,8,0
8059 ++ .quad level2_vmemmap_pgt - __START_KERNEL_map + _KERNPG_TABLE
8060 +
8061 + NEXT_PAGE(level3_kernel_pgt)
8062 + .fill L3_START_KERNEL,8,0
8063 +@@ -361,20 +375,27 @@ NEXT_PAGE(level3_kernel_pgt)
8064 + .quad level2_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE
8065 + .quad level2_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE
8066 +
8067 ++NEXT_PAGE(level2_vmemmap_pgt)
8068 ++ .fill 512,8,0
8069 ++
8070 + NEXT_PAGE(level2_fixmap_pgt)
8071 + .fill 506,8,0
8072 + .quad level1_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE
8073 +- /* 8MB reserved for vsyscalls + a 2MB hole = 4 + 1 entries */
8074 +- .fill 5,8,0
8075 ++ .quad level1_vsyscall_pgt - __START_KERNEL_map + _PAGE_TABLE
8076 ++ /* 6MB reserved for vsyscalls + a 2MB hole = 3 + 1 entries */
8077 ++ .fill 4,8,0
8078 +
8079 + NEXT_PAGE(level1_fixmap_pgt)
8080 + .fill 512,8,0
8081 +
8082 +-NEXT_PAGE(level2_ident_pgt)
8083 +- /* Since I easily can, map the first 1G.
8084 ++NEXT_PAGE(level1_vsyscall_pgt)
8085 ++ .fill 512,8,0
8086 ++
8087 ++ /* Since I easily can, map the first 4G.
8088 + * Don't set NX because code runs from these pages.
8089 + */
8090 +- PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, PTRS_PER_PMD)
8091 ++NEXT_PAGE(level2_ident_pgt)
8092 ++ PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, 4*PTRS_PER_PMD)
8093 +
8094 + NEXT_PAGE(level2_kernel_pgt)
8095 + /*
8096 +@@ -387,32 +408,48 @@ NEXT_PAGE(level2_kernel_pgt)
8097 + * If you want to increase this then increase MODULES_VADDR
8098 + * too.)
8099 + */
8100 +- PMDS(0, __PAGE_KERNEL_LARGE_EXEC,
8101 +- KERNEL_IMAGE_SIZE/PMD_SIZE)
8102 +-
8103 +-NEXT_PAGE(level2_spare_pgt)
8104 +- .fill 512, 8, 0
8105 ++ PMDS(0, __PAGE_KERNEL_LARGE_EXEC, KERNEL_IMAGE_SIZE/PMD_SIZE)
8106 +
8107 + #undef PMDS
8108 + #undef NEXT_PAGE
8109 +
8110 +- .data
8111 ++ .align PAGE_SIZE
8112 ++ENTRY(cpu_gdt_table)
8113 ++ .rept NR_CPUS
8114 ++ .quad 0x0000000000000000 /* NULL descriptor */
8115 ++ .quad 0x00cf9b000000ffff /* __KERNEL32_CS */
8116 ++ .quad 0x00af9b000000ffff /* __KERNEL_CS */
8117 ++ .quad 0x00cf93000000ffff /* __KERNEL_DS */
8118 ++ .quad 0x00cffb000000ffff /* __USER32_CS */
8119 ++ .quad 0x00cff3000000ffff /* __USER_DS, __USER32_DS */
8120 ++ .quad 0x00affb000000ffff /* __USER_CS */
8121 ++ .quad 0x0 /* unused */
8122 ++ .quad 0,0 /* TSS */
8123 ++ .quad 0,0 /* LDT */
8124 ++ .quad 0,0,0 /* three TLS descriptors */
8125 ++ .quad 0x0000f40000000000 /* node/CPU stored in limit */
8126 ++ /* asm/segment.h:GDT_ENTRIES must match this */
8127 ++
8128 ++ /* zero the remaining page */
8129 ++ .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
8130 ++ .endr
8131 ++
8132 + .align 16
8133 + .globl early_gdt_descr
8134 + early_gdt_descr:
8135 + .word GDT_ENTRIES*8-1
8136 +- .quad per_cpu__gdt_page
8137 ++ .quad cpu_gdt_table
8138 +
8139 + ENTRY(phys_base)
8140 + /* This must match the first entry in level2_kernel_pgt */
8141 + .quad 0x0000000000000000
8142 +
8143 + #include "../../x86/xen/xen-head.S"
8144 +-
8145 +- .section .bss, "aw", @nobits
8146 ++
8147 ++ .section .rodata,"a",@progbits
8148 + .align L1_CACHE_BYTES
8149 + ENTRY(idt_table)
8150 +- .skip 256 * 16
8151 ++ .fill 512,8,0
8152 +
8153 + .section .bss.page_aligned, "aw", @nobits
8154 + .align PAGE_SIZE
8155 +diff -urNp linux-2.6.28.8/arch/x86/kernel/i386_ksyms_32.c linux-2.6.28.8/arch/x86/kernel/i386_ksyms_32.c
8156 +--- linux-2.6.28.8/arch/x86/kernel/i386_ksyms_32.c 2009-02-06 16:47:45.000000000 -0500
8157 ++++ linux-2.6.28.8/arch/x86/kernel/i386_ksyms_32.c 2009-02-21 09:37:48.000000000 -0500
8158 +@@ -10,8 +10,12 @@
8159 + EXPORT_SYMBOL(mcount);
8160 + #endif
8161 +
8162 ++EXPORT_SYMBOL_GPL(cpu_gdt_table);
8163 ++
8164 + /* Networking helper routines. */
8165 + EXPORT_SYMBOL(csum_partial_copy_generic);
8166 ++EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
8167 ++EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
8168 +
8169 + EXPORT_SYMBOL(__get_user_1);
8170 + EXPORT_SYMBOL(__get_user_2);
8171 +@@ -26,3 +30,7 @@ EXPORT_SYMBOL(strstr);
8172 +
8173 + EXPORT_SYMBOL(csum_partial);
8174 + EXPORT_SYMBOL(empty_zero_page);
8175 ++
8176 ++#ifdef CONFIG_PAX_KERNEXEC
8177 ++EXPORT_SYMBOL(KERNEL_TEXT_OFFSET);
8178 ++#endif
8179 +diff -urNp linux-2.6.28.8/arch/x86/kernel/init_task.c linux-2.6.28.8/arch/x86/kernel/init_task.c
8180 +--- linux-2.6.28.8/arch/x86/kernel/init_task.c 2009-02-06 16:47:45.000000000 -0500
8181 ++++ linux-2.6.28.8/arch/x86/kernel/init_task.c 2009-02-21 09:37:48.000000000 -0500
8182 +@@ -42,5 +42,5 @@ EXPORT_SYMBOL(init_task);
8183 + * section. Since TSS's are completely CPU-local, we want them
8184 + * on exact cacheline boundaries, to eliminate cacheline ping-pong.
8185 + */
8186 +-DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
8187 +-
8188 ++struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
8189 ++EXPORT_SYMBOL(init_tss);
8190 +diff -urNp linux-2.6.28.8/arch/x86/kernel/ioport.c linux-2.6.28.8/arch/x86/kernel/ioport.c
8191 +--- linux-2.6.28.8/arch/x86/kernel/ioport.c 2009-02-06 16:47:45.000000000 -0500
8192 ++++ linux-2.6.28.8/arch/x86/kernel/ioport.c 2009-02-21 09:37:48.000000000 -0500
8193 +@@ -6,6 +6,7 @@
8194 + #include <linux/sched.h>
8195 + #include <linux/kernel.h>
8196 + #include <linux/capability.h>
8197 ++#include <linux/security.h>
8198 + #include <linux/errno.h>
8199 + #include <linux/types.h>
8200 + #include <linux/ioport.h>
8201 +@@ -41,6 +42,12 @@ asmlinkage long sys_ioperm(unsigned long
8202 +
8203 + if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
8204 + return -EINVAL;
8205 ++#ifdef CONFIG_GRKERNSEC_IO
8206 ++ if (turn_on) {
8207 ++ gr_handle_ioperm();
8208 ++ return -EPERM;
8209 ++ }
8210 ++#endif
8211 + if (turn_on && !capable(CAP_SYS_RAWIO))
8212 + return -EPERM;
8213 +
8214 +@@ -67,7 +74,7 @@ asmlinkage long sys_ioperm(unsigned long
8215 + * because the ->io_bitmap_max value must match the bitmap
8216 + * contents:
8217 + */
8218 +- tss = &per_cpu(init_tss, get_cpu());
8219 ++ tss = init_tss + get_cpu();
8220 +
8221 + set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
8222 +
8223 +@@ -122,8 +129,13 @@ static int do_iopl(unsigned int level, s
8224 + return -EINVAL;
8225 + /* Trying to gain more privileges? */
8226 + if (level > old) {
8227 ++#ifdef CONFIG_GRKERNSEC_IO
8228 ++ gr_handle_iopl();
8229 ++ return -EPERM;
8230 ++#else
8231 + if (!capable(CAP_SYS_RAWIO))
8232 + return -EPERM;
8233 ++#endif
8234 + }
8235 + regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
8236 +
8237 +diff -urNp linux-2.6.28.8/arch/x86/kernel/irq_32.c linux-2.6.28.8/arch/x86/kernel/irq_32.c
8238 +--- linux-2.6.28.8/arch/x86/kernel/irq_32.c 2009-02-06 16:47:45.000000000 -0500
8239 ++++ linux-2.6.28.8/arch/x86/kernel/irq_32.c 2009-02-21 09:37:48.000000000 -0500
8240 +@@ -93,7 +93,7 @@ execute_on_irq_stack(int overflow, struc
8241 + return 0;
8242 +
8243 + /* build the stack frame on the IRQ stack */
8244 +- isp = (u32 *) ((char*)irqctx + sizeof(*irqctx));
8245 ++ isp = (u32 *) ((char*)irqctx + sizeof(*irqctx) - 8);
8246 + irqctx->tinfo.task = curctx->tinfo.task;
8247 + irqctx->tinfo.previous_esp = current_stack_pointer;
8248 +
8249 +@@ -174,7 +174,7 @@ asmlinkage void do_softirq(void)
8250 + irqctx->tinfo.previous_esp = current_stack_pointer;
8251 +
8252 + /* build the stack frame on the softirq stack */
8253 +- isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
8254 ++ isp = (u32*) ((char*)irqctx + sizeof(*irqctx) - 8);
8255 +
8256 + call_on_stack(__do_softirq, isp);
8257 + /*
8258 +diff -urNp linux-2.6.28.8/arch/x86/kernel/kprobes.c linux-2.6.28.8/arch/x86/kernel/kprobes.c
8259 +--- linux-2.6.28.8/arch/x86/kernel/kprobes.c 2009-02-06 16:47:45.000000000 -0500
8260 ++++ linux-2.6.28.8/arch/x86/kernel/kprobes.c 2009-02-21 09:37:48.000000000 -0500
8261 +@@ -166,9 +166,24 @@ static void __kprobes set_jmp_op(void *f
8262 + char op;
8263 + s32 raddr;
8264 + } __attribute__((packed)) * jop;
8265 +- jop = (struct __arch_jmp_op *)from;
8266 ++
8267 ++#ifdef CONFIG_PAX_KERNEXEC
8268 ++ unsigned long cr0;
8269 ++#endif
8270 ++
8271 ++ jop = (struct __arch_jmp_op *)(ktla_ktva(from));
8272 ++
8273 ++#ifdef CONFIG_PAX_KERNEXEC
8274 ++ pax_open_kernel(cr0);
8275 ++#endif
8276 ++
8277 + jop->raddr = (s32)((long)(to) - ((long)(from) + 5));
8278 + jop->op = RELATIVEJUMP_INSTRUCTION;
8279 ++
8280 ++#ifdef CONFIG_PAX_KERNEXEC
8281 ++ pax_close_kernel(cr0);
8282 ++#endif
8283 ++
8284 + }
8285 +
8286 + /*
8287 +@@ -342,16 +357,29 @@ static void __kprobes fix_riprel(struct
8288 +
8289 + static void __kprobes arch_copy_kprobe(struct kprobe *p)
8290 + {
8291 +- memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
8292 ++
8293 ++#ifdef CONFIG_PAX_KERNEXEC
8294 ++ unsigned long cr0;
8295 ++#endif
8296 ++
8297 ++#ifdef CONFIG_PAX_KERNEXEC
8298 ++ pax_open_kernel(cr0);
8299 ++#endif
8300 ++
8301 ++ memcpy(p->ainsn.insn, ktla_ktva(p->addr), MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
8302 ++
8303 ++#ifdef CONFIG_PAX_KERNEXEC
8304 ++ pax_close_kernel(cr0);
8305 ++#endif
8306 +
8307 + fix_riprel(p);
8308 +
8309 +- if (can_boost(p->addr))
8310 ++ if (can_boost(ktla_ktva(p->addr)))
8311 + p->ainsn.boostable = 0;
8312 + else
8313 + p->ainsn.boostable = -1;
8314 +
8315 +- p->opcode = *p->addr;
8316 ++ p->opcode = *(ktla_ktva(p->addr));
8317 + }
8318 +
8319 + int __kprobes arch_prepare_kprobe(struct kprobe *p)
8320 +@@ -428,7 +456,7 @@ static void __kprobes prepare_singlestep
8321 + if (p->opcode == BREAKPOINT_INSTRUCTION)
8322 + regs->ip = (unsigned long)p->addr;
8323 + else
8324 +- regs->ip = (unsigned long)p->ainsn.insn;
8325 ++ regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
8326 + }
8327 +
8328 + void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
8329 +@@ -449,7 +477,7 @@ static void __kprobes setup_singlestep(s
8330 + if (p->ainsn.boostable == 1 && !p->post_handler) {
8331 + /* Boost up -- we can execute copied instructions directly */
8332 + reset_current_kprobe();
8333 +- regs->ip = (unsigned long)p->ainsn.insn;
8334 ++ regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
8335 + preempt_enable_no_resched();
8336 + return;
8337 + }
8338 +@@ -519,7 +547,7 @@ static int __kprobes kprobe_handler(stru
8339 + struct kprobe_ctlblk *kcb;
8340 +
8341 + addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t));
8342 +- if (*addr != BREAKPOINT_INSTRUCTION) {
8343 ++ if (*(kprobe_opcode_t *)ktla_ktva((unsigned long)addr) != BREAKPOINT_INSTRUCTION) {
8344 + /*
8345 + * The breakpoint instruction was removed right
8346 + * after we hit it. Another cpu has removed
8347 +@@ -770,7 +798,7 @@ static void __kprobes resume_execution(s
8348 + struct pt_regs *regs, struct kprobe_ctlblk *kcb)
8349 + {
8350 + unsigned long *tos = stack_addr(regs);
8351 +- unsigned long copy_ip = (unsigned long)p->ainsn.insn;
8352 ++ unsigned long copy_ip = ktva_ktla((unsigned long)p->ainsn.insn);
8353 + unsigned long orig_ip = (unsigned long)p->addr;
8354 + kprobe_opcode_t *insn = p->ainsn.insn;
8355 +
8356 +@@ -953,7 +981,7 @@ int __kprobes kprobe_exceptions_notify(s
8357 + struct die_args *args = data;
8358 + int ret = NOTIFY_DONE;
8359 +
8360 +- if (args->regs && user_mode_vm(args->regs))
8361 ++ if (args->regs && user_mode(args->regs))
8362 + return ret;
8363 +
8364 + switch (val) {
8365 +diff -urNp linux-2.6.28.8/arch/x86/kernel/ldt.c linux-2.6.28.8/arch/x86/kernel/ldt.c
8366 +--- linux-2.6.28.8/arch/x86/kernel/ldt.c 2009-02-06 16:47:45.000000000 -0500
8367 ++++ linux-2.6.28.8/arch/x86/kernel/ldt.c 2009-02-21 09:37:48.000000000 -0500
8368 +@@ -66,13 +66,13 @@ static int alloc_ldt(mm_context_t *pc, i
8369 + if (reload) {
8370 + #ifdef CONFIG_SMP
8371 + preempt_disable();
8372 +- load_LDT(pc);
8373 ++ load_LDT_nolock(pc);
8374 + if (!cpus_equal(current->mm->cpu_vm_mask,
8375 + cpumask_of_cpu(smp_processor_id())))
8376 + smp_call_function(flush_ldt, current->mm, 1);
8377 + preempt_enable();
8378 + #else
8379 +- load_LDT(pc);
8380 ++ load_LDT_nolock(pc);
8381 + #endif
8382 + }
8383 + if (oldsize) {
8384 +@@ -94,7 +94,7 @@ static inline int copy_ldt(mm_context_t
8385 + return err;
8386 +
8387 + for(i = 0; i < old->size; i++)
8388 +- write_ldt_entry(new->ldt, i, old->ldt + i * LDT_ENTRY_SIZE);
8389 ++ write_ldt_entry(new->ldt, i, old->ldt + i);
8390 + return 0;
8391 + }
8392 +
8393 +@@ -115,6 +115,24 @@ int init_new_context(struct task_struct
8394 + retval = copy_ldt(&mm->context, &old_mm->context);
8395 + mutex_unlock(&old_mm->context.lock);
8396 + }
8397 ++
8398 ++ if (tsk == current) {
8399 ++ mm->context.vdso = ~0UL;
8400 ++
8401 ++#ifdef CONFIG_X86_32
8402 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
8403 ++ mm->context.user_cs_base = 0UL;
8404 ++ mm->context.user_cs_limit = ~0UL;
8405 ++
8406 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
8407 ++ cpus_clear(mm->context.cpu_user_cs_mask);
8408 ++#endif
8409 ++
8410 ++#endif
8411 ++#endif
8412 ++
8413 ++ }
8414 ++
8415 + return retval;
8416 + }
8417 +
8418 +@@ -229,6 +247,13 @@ static int write_ldt(void __user *ptr, u
8419 + }
8420 + }
8421 +
8422 ++#ifdef CONFIG_PAX_SEGMEXEC
8423 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
8424 ++ error = -EINVAL;
8425 ++ goto out_unlock;
8426 ++ }
8427 ++#endif
8428 ++
8429 + fill_ldt(&ldt, &ldt_info);
8430 + if (oldmode)
8431 + ldt.avl = 0;
8432 +diff -urNp linux-2.6.28.8/arch/x86/kernel/machine_kexec_32.c linux-2.6.28.8/arch/x86/kernel/machine_kexec_32.c
8433 +--- linux-2.6.28.8/arch/x86/kernel/machine_kexec_32.c 2009-02-06 16:47:45.000000000 -0500
8434 ++++ linux-2.6.28.8/arch/x86/kernel/machine_kexec_32.c 2009-02-21 09:37:48.000000000 -0500
8435 +@@ -34,7 +34,7 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED
8436 + static u32 kexec_pte0[1024] PAGE_ALIGNED;
8437 + static u32 kexec_pte1[1024] PAGE_ALIGNED;
8438 +
8439 +-static void set_idt(void *newidt, __u16 limit)
8440 ++static void set_idt(struct desc_struct *newidt, __u16 limit)
8441 + {
8442 + struct desc_ptr curidt;
8443 +
8444 +@@ -46,7 +46,7 @@ static void set_idt(void *newidt, __u16
8445 + }
8446 +
8447 +
8448 +-static void set_gdt(void *newgdt, __u16 limit)
8449 ++static void set_gdt(struct desc_struct *newgdt, __u16 limit)
8450 + {
8451 + struct desc_ptr curgdt;
8452 +
8453 +@@ -145,7 +145,7 @@ void machine_kexec(struct kimage *image)
8454 + }
8455 +
8456 + control_page = page_address(image->control_code_page);
8457 +- memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE);
8458 ++ memcpy(control_page, (void *)ktla_ktva((unsigned long)relocate_kernel), KEXEC_CONTROL_CODE_MAX_SIZE);
8459 +
8460 + relocate_kernel_ptr = control_page;
8461 + page_list[PA_CONTROL_PAGE] = __pa(control_page);
8462 +diff -urNp linux-2.6.28.8/arch/x86/kernel/module_32.c linux-2.6.28.8/arch/x86/kernel/module_32.c
8463 +--- linux-2.6.28.8/arch/x86/kernel/module_32.c 2009-02-06 16:47:45.000000000 -0500
8464 ++++ linux-2.6.28.8/arch/x86/kernel/module_32.c 2009-02-21 09:37:48.000000000 -0500
8465 +@@ -23,6 +23,9 @@
8466 + #include <linux/kernel.h>
8467 + #include <linux/bug.h>
8468 +
8469 ++#include <asm/desc.h>
8470 ++#include <asm/pgtable.h>
8471 ++
8472 + #if 0
8473 + #define DEBUGP printk
8474 + #else
8475 +@@ -33,9 +36,31 @@ void *module_alloc(unsigned long size)
8476 + {
8477 + if (size == 0)
8478 + return NULL;
8479 ++
8480 ++#ifdef CONFIG_PAX_KERNEXEC
8481 ++ return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
8482 ++#else
8483 + return vmalloc_exec(size);
8484 ++#endif
8485 ++
8486 + }
8487 +
8488 ++#ifdef CONFIG_PAX_KERNEXEC
8489 ++void *module_alloc_exec(unsigned long size)
8490 ++{
8491 ++ struct vm_struct *area;
8492 ++
8493 ++ if (size == 0)
8494 ++ return NULL;
8495 ++
8496 ++ area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
8497 ++ if (area)
8498 ++ return area->addr;
8499 ++
8500 ++ return NULL;
8501 ++}
8502 ++EXPORT_SYMBOL(module_alloc_exec);
8503 ++#endif
8504 +
8505 + /* Free memory returned from module_alloc */
8506 + void module_free(struct module *mod, void *module_region)
8507 +@@ -45,6 +70,45 @@ void module_free(struct module *mod, voi
8508 + table entries. */
8509 + }
8510 +
8511 ++#ifdef CONFIG_PAX_KERNEXEC
8512 ++void module_free_exec(struct module *mod, void *module_region)
8513 ++{
8514 ++ struct vm_struct **p, *tmp;
8515 ++
8516 ++ if (!module_region)
8517 ++ return;
8518 ++
8519 ++ if ((PAGE_SIZE-1) & (unsigned long)module_region) {
8520 ++ printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
8521 ++ WARN_ON(1);
8522 ++ return;
8523 ++ }
8524 ++
8525 ++ write_lock(&vmlist_lock);
8526 ++ for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next)
8527 ++ if (tmp->addr == module_region)
8528 ++ break;
8529 ++
8530 ++ if (tmp) {
8531 ++ unsigned long cr0;
8532 ++
8533 ++ pax_open_kernel(cr0);
8534 ++ memset(tmp->addr, 0xCC, tmp->size);
8535 ++ pax_close_kernel(cr0);
8536 ++
8537 ++ *p = tmp->next;
8538 ++ kfree(tmp);
8539 ++ }
8540 ++ write_unlock(&vmlist_lock);
8541 ++
8542 ++ if (!tmp) {
8543 ++ printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
8544 ++ module_region);
8545 ++ WARN_ON(1);
8546 ++ }
8547 ++}
8548 ++#endif
8549 ++
8550 + /* We don't need anything special. */
8551 + int module_frob_arch_sections(Elf_Ehdr *hdr,
8552 + Elf_Shdr *sechdrs,
8553 +@@ -63,14 +127,20 @@ int apply_relocate(Elf32_Shdr *sechdrs,
8554 + unsigned int i;
8555 + Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
8556 + Elf32_Sym *sym;
8557 +- uint32_t *location;
8558 ++ uint32_t *plocation, location;
8559 ++
8560 ++#ifdef CONFIG_PAX_KERNEXEC
8561 ++ unsigned long cr0;
8562 ++#endif
8563 +
8564 + DEBUGP("Applying relocate section %u to %u\n", relsec,
8565 + sechdrs[relsec].sh_info);
8566 + for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
8567 + /* This is where to make the change */
8568 +- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
8569 +- + rel[i].r_offset;
8570 ++ plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
8571 ++ location = (uint32_t)plocation;
8572 ++ if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
8573 ++ plocation = ktla_ktva((void *)plocation);
8574 + /* This is the symbol it is referring to. Note that all
8575 + undefined symbols have been resolved. */
8576 + sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
8577 +@@ -78,12 +148,32 @@ int apply_relocate(Elf32_Shdr *sechdrs,
8578 +
8579 + switch (ELF32_R_TYPE(rel[i].r_info)) {
8580 + case R_386_32:
8581 ++
8582 ++#ifdef CONFIG_PAX_KERNEXEC
8583 ++ pax_open_kernel(cr0);
8584 ++#endif
8585 ++
8586 + /* We add the value into the location given */
8587 +- *location += sym->st_value;
8588 ++ *plocation += sym->st_value;
8589 ++
8590 ++#ifdef CONFIG_PAX_KERNEXEC
8591 ++ pax_close_kernel(cr0);
8592 ++#endif
8593 ++
8594 + break;
8595 + case R_386_PC32:
8596 ++
8597 ++#ifdef CONFIG_PAX_KERNEXEC
8598 ++ pax_open_kernel(cr0);
8599 ++#endif
8600 ++
8601 + /* Add the value, subtract its postition */
8602 +- *location += sym->st_value - (uint32_t)location;
8603 ++ *plocation += sym->st_value - location;
8604 ++
8605 ++#ifdef CONFIG_PAX_KERNEXEC
8606 ++ pax_close_kernel(cr0);
8607 ++#endif
8608 ++
8609 + break;
8610 + default:
8611 + printk(KERN_ERR "module %s: Unknown relocation: %u\n",
8612 +diff -urNp linux-2.6.28.8/arch/x86/kernel/module_64.c linux-2.6.28.8/arch/x86/kernel/module_64.c
8613 +--- linux-2.6.28.8/arch/x86/kernel/module_64.c 2009-02-06 16:47:45.000000000 -0500
8614 ++++ linux-2.6.28.8/arch/x86/kernel/module_64.c 2009-02-21 09:37:48.000000000 -0500
8615 +@@ -40,7 +40,7 @@ void module_free(struct module *mod, voi
8616 + table entries. */
8617 + }
8618 +
8619 +-void *module_alloc(unsigned long size)
8620 ++static void *__module_alloc(unsigned long size, pgprot_t prot)
8621 + {
8622 + struct vm_struct *area;
8623 +
8624 +@@ -54,8 +54,31 @@ void *module_alloc(unsigned long size)
8625 + if (!area)
8626 + return NULL;
8627 +
8628 +- return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
8629 ++ return __vmalloc_area(area, GFP_KERNEL | __GFP_ZERO, prot);
8630 ++}
8631 ++
8632 ++#ifdef CONFIG_PAX_KERNEXEC
8633 ++void *module_alloc(unsigned long size)
8634 ++{
8635 ++ return __module_alloc(size, PAGE_KERNEL);
8636 ++}
8637 ++
8638 ++void module_free_exec(struct module *mod, void *module_region)
8639 ++{
8640 ++ module_free(mod, module_region);
8641 ++}
8642 ++
8643 ++void *module_alloc_exec(unsigned long size)
8644 ++{
8645 ++ return __module_alloc(size, PAGE_KERNEL_RX);
8646 + }
8647 ++#else
8648 ++void *module_alloc(unsigned long size)
8649 ++{
8650 ++ return __module_alloc(size, PAGE_KERNEL_EXEC);
8651 ++}
8652 ++#endif
8653 ++
8654 + #endif
8655 +
8656 + /* We don't need anything special. */
8657 +@@ -77,7 +100,11 @@ int apply_relocate_add(Elf64_Shdr *sechd
8658 + Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
8659 + Elf64_Sym *sym;
8660 + void *loc;
8661 +- u64 val;
8662 ++ u64 val;
8663 ++
8664 ++#ifdef CONFIG_PAX_KERNEXEC
8665 ++ unsigned long cr0;
8666 ++#endif
8667 +
8668 + DEBUGP("Applying relocate section %u to %u\n", relsec,
8669 + sechdrs[relsec].sh_info);
8670 +@@ -101,21 +128,61 @@ int apply_relocate_add(Elf64_Shdr *sechd
8671 + case R_X86_64_NONE:
8672 + break;
8673 + case R_X86_64_64:
8674 ++
8675 ++#ifdef CONFIG_PAX_KERNEXEC
8676 ++ pax_open_kernel(cr0);
8677 ++#endif
8678 ++
8679 + *(u64 *)loc = val;
8680 ++
8681 ++#ifdef CONFIG_PAX_KERNEXEC
8682 ++ pax_close_kernel(cr0);
8683 ++#endif
8684 ++
8685 + break;
8686 + case R_X86_64_32:
8687 ++
8688 ++#ifdef CONFIG_PAX_KERNEXEC
8689 ++ pax_open_kernel(cr0);
8690 ++#endif
8691 ++
8692 + *(u32 *)loc = val;
8693 ++
8694 ++#ifdef CONFIG_PAX_KERNEXEC
8695 ++ pax_close_kernel(cr0);
8696 ++#endif
8697 ++
8698 + if (val != *(u32 *)loc)
8699 + goto overflow;
8700 + break;
8701 + case R_X86_64_32S:
8702 ++
8703 ++#ifdef CONFIG_PAX_KERNEXEC
8704 ++ pax_open_kernel(cr0);
8705 ++#endif
8706 ++
8707 + *(s32 *)loc = val;
8708 ++
8709 ++#ifdef CONFIG_PAX_KERNEXEC
8710 ++ pax_close_kernel(cr0);
8711 ++#endif
8712 ++
8713 + if ((s64)val != *(s32 *)loc)
8714 + goto overflow;
8715 + break;
8716 + case R_X86_64_PC32:
8717 + val -= (u64)loc;
8718 ++
8719 ++#ifdef CONFIG_PAX_KERNEXEC
8720 ++ pax_open_kernel(cr0);
8721 ++#endif
8722 ++
8723 + *(u32 *)loc = val;
8724 ++
8725 ++#ifdef CONFIG_PAX_KERNEXEC
8726 ++ pax_close_kernel(cr0);
8727 ++#endif
8728 ++
8729 + #if 0
8730 + if ((s64)val != *(s32 *)loc)
8731 + goto overflow;
8732 +diff -urNp linux-2.6.28.8/arch/x86/kernel/paravirt.c linux-2.6.28.8/arch/x86/kernel/paravirt.c
8733 +--- linux-2.6.28.8/arch/x86/kernel/paravirt.c 2009-03-07 10:24:49.000000000 -0500
8734 ++++ linux-2.6.28.8/arch/x86/kernel/paravirt.c 2009-03-07 10:34:42.000000000 -0500
8735 +@@ -44,7 +44,7 @@ void _paravirt_nop(void)
8736 + {
8737 + }
8738 +
8739 +-static void __init default_banner(void)
8740 ++static void default_banner(void)
8741 + {
8742 + printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
8743 + pv_info.name);
8744 +@@ -164,7 +164,7 @@ unsigned paravirt_patch_insns(void *insn
8745 + if (insn_len > len || start == NULL)
8746 + insn_len = len;
8747 + else
8748 +- memcpy(insnbuf, start, insn_len);
8749 ++ memcpy(insnbuf, ktla_ktva(start), insn_len);
8750 +
8751 + return insn_len;
8752 + }
8753 +@@ -292,21 +292,21 @@ void arch_flush_lazy_cpu_mode(void)
8754 + preempt_enable();
8755 + }
8756 +
8757 +-struct pv_info pv_info = {
8758 ++struct pv_info pv_info __read_only = {
8759 + .name = "bare hardware",
8760 + .paravirt_enabled = 0,
8761 + .kernel_rpl = 0,
8762 + .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */
8763 + };
8764 +
8765 +-struct pv_init_ops pv_init_ops = {
8766 ++struct pv_init_ops pv_init_ops __read_only = {
8767 + .patch = native_patch,
8768 + .banner = default_banner,
8769 + .arch_setup = paravirt_nop,
8770 + .memory_setup = machine_specific_memory_setup,
8771 + };
8772 +
8773 +-struct pv_time_ops pv_time_ops = {
8774 ++struct pv_time_ops pv_time_ops __read_only = {
8775 + .time_init = hpet_time_init,
8776 + .get_wallclock = native_get_wallclock,
8777 + .set_wallclock = native_set_wallclock,
8778 +@@ -314,7 +314,7 @@ struct pv_time_ops pv_time_ops = {
8779 + .get_tsc_khz = native_calibrate_tsc,
8780 + };
8781 +
8782 +-struct pv_irq_ops pv_irq_ops = {
8783 ++struct pv_irq_ops pv_irq_ops __read_only = {
8784 + .init_IRQ = native_init_IRQ,
8785 + .save_fl = native_save_fl,
8786 + .restore_fl = native_restore_fl,
8787 +@@ -327,7 +327,7 @@ struct pv_irq_ops pv_irq_ops = {
8788 + #endif
8789 + };
8790 +
8791 +-struct pv_cpu_ops pv_cpu_ops = {
8792 ++struct pv_cpu_ops pv_cpu_ops __read_only = {
8793 + .cpuid = native_cpuid,
8794 + .get_debugreg = native_get_debugreg,
8795 + .set_debugreg = native_set_debugreg,
8796 +@@ -389,7 +389,7 @@ struct pv_cpu_ops pv_cpu_ops = {
8797 + },
8798 + };
8799 +
8800 +-struct pv_apic_ops pv_apic_ops = {
8801 ++struct pv_apic_ops pv_apic_ops __read_only = {
8802 + #ifdef CONFIG_X86_LOCAL_APIC
8803 + .setup_boot_clock = setup_boot_APIC_clock,
8804 + .setup_secondary_clock = setup_secondary_APIC_clock,
8805 +@@ -397,7 +397,7 @@ struct pv_apic_ops pv_apic_ops = {
8806 + #endif
8807 + };
8808 +
8809 +-struct pv_mmu_ops pv_mmu_ops = {
8810 ++struct pv_mmu_ops pv_mmu_ops __read_only = {
8811 + #ifndef CONFIG_X86_64
8812 + .pagetable_setup_start = native_pagetable_setup_start,
8813 + .pagetable_setup_done = native_pagetable_setup_done,
8814 +diff -urNp linux-2.6.28.8/arch/x86/kernel/paravirt-spinlocks.c linux-2.6.28.8/arch/x86/kernel/paravirt-spinlocks.c
8815 +--- linux-2.6.28.8/arch/x86/kernel/paravirt-spinlocks.c 2009-02-06 16:47:45.000000000 -0500
8816 ++++ linux-2.6.28.8/arch/x86/kernel/paravirt-spinlocks.c 2009-02-21 09:37:48.000000000 -0500
8817 +@@ -13,7 +13,7 @@ default_spin_lock_flags(raw_spinlock_t *
8818 + __raw_spin_lock(lock);
8819 + }
8820 +
8821 +-struct pv_lock_ops pv_lock_ops = {
8822 ++struct pv_lock_ops pv_lock_ops __read_only = {
8823 + #ifdef CONFIG_SMP
8824 + .spin_is_locked = __ticket_spin_is_locked,
8825 + .spin_is_contended = __ticket_spin_is_contended,
8826 +diff -urNp linux-2.6.28.8/arch/x86/kernel/process_32.c linux-2.6.28.8/arch/x86/kernel/process_32.c
8827 +--- linux-2.6.28.8/arch/x86/kernel/process_32.c 2009-02-06 16:47:45.000000000 -0500
8828 ++++ linux-2.6.28.8/arch/x86/kernel/process_32.c 2009-02-21 09:37:48.000000000 -0500
8829 +@@ -65,8 +65,10 @@ asmlinkage void ret_from_fork(void) __as
8830 + DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
8831 + EXPORT_PER_CPU_SYMBOL(current_task);
8832 +
8833 ++#ifdef CONFIG_SMP
8834 + DEFINE_PER_CPU(int, cpu_number);
8835 + EXPORT_PER_CPU_SYMBOL(cpu_number);
8836 ++#endif
8837 +
8838 + /*
8839 + * Return saved PC of a blocked thread.
8840 +@@ -74,6 +76,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_number);
8841 + unsigned long thread_saved_pc(struct task_struct *tsk)
8842 + {
8843 + return ((unsigned long *)tsk->thread.sp)[3];
8844 ++//XXX return tsk->thread.eip;
8845 + }
8846 +
8847 + #ifndef CONFIG_SMP
8848 +@@ -131,7 +134,7 @@ void __show_regs(struct pt_regs *regs, i
8849 + unsigned short ss, gs;
8850 + const char *board;
8851 +
8852 +- if (user_mode_vm(regs)) {
8853 ++ if (user_mode(regs)) {
8854 + sp = regs->sp;
8855 + ss = regs->ss & 0xffff;
8856 + savesegment(gs, gs);
8857 +@@ -212,8 +215,8 @@ int kernel_thread(int (*fn)(void *), voi
8858 + regs.bx = (unsigned long) fn;
8859 + regs.dx = (unsigned long) arg;
8860 +
8861 +- regs.ds = __USER_DS;
8862 +- regs.es = __USER_DS;
8863 ++ regs.ds = __KERNEL_DS;
8864 ++ regs.es = __KERNEL_DS;
8865 + regs.fs = __KERNEL_PERCPU;
8866 + regs.orig_ax = -1;
8867 + regs.ip = (unsigned long) kernel_thread_helper;
8868 +@@ -235,7 +238,7 @@ void exit_thread(void)
8869 + struct task_struct *tsk = current;
8870 + struct thread_struct *t = &tsk->thread;
8871 + int cpu = get_cpu();
8872 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
8873 ++ struct tss_struct *tss = init_tss + cpu;
8874 +
8875 + kfree(t->io_bitmap_ptr);
8876 + t->io_bitmap_ptr = NULL;
8877 +@@ -264,6 +267,7 @@ void flush_thread(void)
8878 + {
8879 + struct task_struct *tsk = current;
8880 +
8881 ++ loadsegment(gs, 0);
8882 + tsk->thread.debugreg0 = 0;
8883 + tsk->thread.debugreg1 = 0;
8884 + tsk->thread.debugreg2 = 0;
8885 +@@ -303,7 +307,7 @@ int copy_thread(int nr, unsigned long cl
8886 + struct task_struct *tsk;
8887 + int err;
8888 +
8889 +- childregs = task_pt_regs(p);
8890 ++ childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
8891 + *childregs = *regs;
8892 + childregs->ax = 0;
8893 + childregs->sp = sp;
8894 +@@ -332,6 +336,7 @@ int copy_thread(int nr, unsigned long cl
8895 + * Set a new TLS for the child thread?
8896 + */
8897 + if (clone_flags & CLONE_SETTLS)
8898 ++//XXX needs set_fs()?
8899 + err = do_set_thread_area(p, -1,
8900 + (struct user_desc __user *)childregs->si, 0);
8901 +
8902 +@@ -553,7 +558,7 @@ struct task_struct * __switch_to(struct
8903 + struct thread_struct *prev = &prev_p->thread,
8904 + *next = &next_p->thread;
8905 + int cpu = smp_processor_id();
8906 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
8907 ++ struct tss_struct *tss = init_tss + cpu;
8908 +
8909 + /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
8910 +
8911 +@@ -581,6 +586,11 @@ struct task_struct * __switch_to(struct
8912 + */
8913 + savesegment(gs, prev->gs);
8914 +
8915 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
8916 ++ if (!segment_eq(task_thread_info(prev_p)->addr_limit, task_thread_info(next_p)->addr_limit))
8917 ++ __set_fs(task_thread_info(next_p)->addr_limit, cpu);
8918 ++#endif
8919 ++
8920 + /*
8921 + * Load the per-thread Thread-Local Storage descriptor.
8922 + */
8923 +@@ -719,15 +729,27 @@ unsigned long get_wchan(struct task_stru
8924 + return 0;
8925 + }
8926 +
8927 +-unsigned long arch_align_stack(unsigned long sp)
8928 ++#ifdef CONFIG_PAX_RANDKSTACK
8929 ++asmlinkage void pax_randomize_kstack(void)
8930 + {
8931 +- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
8932 +- sp -= get_random_int() % 8192;
8933 +- return sp & ~0xf;
8934 +-}
8935 ++ struct thread_struct *thread = &current->thread;
8936 ++ unsigned long time;
8937 +
8938 +-unsigned long arch_randomize_brk(struct mm_struct *mm)
8939 +-{
8940 +- unsigned long range_end = mm->brk + 0x02000000;
8941 +- return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
8942 ++ if (!randomize_va_space)
8943 ++ return;
8944 ++
8945 ++ rdtscl(time);
8946 ++
8947 ++ /* P4 seems to return a 0 LSB, ignore it */
8948 ++#ifdef CONFIG_MPENTIUM4
8949 ++ time &= 0x1EUL;
8950 ++ time <<= 2;
8951 ++#else
8952 ++ time &= 0xFUL;
8953 ++ time <<= 3;
8954 ++#endif
8955 ++
8956 ++ thread->sp0 ^= time;
8957 ++ load_sp0(init_tss + smp_processor_id(), thread);
8958 + }
8959 ++#endif
8960 +diff -urNp linux-2.6.28.8/arch/x86/kernel/process_64.c linux-2.6.28.8/arch/x86/kernel/process_64.c
8961 +--- linux-2.6.28.8/arch/x86/kernel/process_64.c 2009-02-06 16:47:45.000000000 -0500
8962 ++++ linux-2.6.28.8/arch/x86/kernel/process_64.c 2009-02-21 09:37:48.000000000 -0500
8963 +@@ -109,6 +109,8 @@ static inline void play_dead(void)
8964 + void cpu_idle(void)
8965 + {
8966 + current_thread_info()->status |= TS_POLLING;
8967 ++ current->stack_canary = pax_get_random_long();
8968 ++ write_pda(stack_canary, current->stack_canary);
8969 + /* endless idle loop with no priority at all */
8970 + while (1) {
8971 + tick_nohz_stop_sched_tick(1);
8972 +@@ -223,7 +225,7 @@ void exit_thread(void)
8973 + struct thread_struct *t = &me->thread;
8974 +
8975 + if (me->thread.io_bitmap_ptr) {
8976 +- struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
8977 ++ struct tss_struct *tss = init_tss + get_cpu();
8978 +
8979 + kfree(t->io_bitmap_ptr);
8980 + t->io_bitmap_ptr = NULL;
8981 +@@ -558,7 +560,7 @@ __switch_to(struct task_struct *prev_p,
8982 + struct thread_struct *prev = &prev_p->thread;
8983 + struct thread_struct *next = &next_p->thread;
8984 + int cpu = smp_processor_id();
8985 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
8986 ++ struct tss_struct *tss = init_tss + cpu;
8987 + unsigned fsindex, gsindex;
8988 +
8989 + /* we're going to use this soon, after a few expensive things */
8990 +@@ -647,7 +649,6 @@ __switch_to(struct task_struct *prev_p,
8991 + (unsigned long)task_stack_page(next_p) +
8992 + THREAD_SIZE - PDA_STACKOFFSET);
8993 + #ifdef CONFIG_CC_STACKPROTECTOR
8994 +- write_pda(stack_canary, next_p->stack_canary);
8995 + /*
8996 + * Build time only check to make sure the stack_canary is at
8997 + * offset 40 in the pda; this is a gcc ABI requirement
8998 +@@ -746,12 +747,11 @@ unsigned long get_wchan(struct task_stru
8999 + if (!p || p == current || p->state == TASK_RUNNING)
9000 + return 0;
9001 + stack = (unsigned long)task_stack_page(p);
9002 +- if (p->thread.sp < stack || p->thread.sp >= stack+THREAD_SIZE)
9003 ++ if (p->thread.sp < stack || p->thread.sp > stack+THREAD_SIZE-8-sizeof(u64))
9004 + return 0;
9005 + fp = *(u64 *)(p->thread.sp);
9006 + do {
9007 +- if (fp < (unsigned long)stack ||
9008 +- fp >= (unsigned long)stack+THREAD_SIZE)
9009 ++ if (fp < stack || fp > stack+THREAD_SIZE-8-sizeof(u64))
9010 + return 0;
9011 + ip = *(u64 *)(fp+8);
9012 + if (!in_sched_functions(ip))
9013 +@@ -860,16 +860,3 @@ long sys_arch_prctl(int code, unsigned l
9014 + {
9015 + return do_arch_prctl(current, code, addr);
9016 + }
9017 +-
9018 +-unsigned long arch_align_stack(unsigned long sp)
9019 +-{
9020 +- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
9021 +- sp -= get_random_int() % 8192;
9022 +- return sp & ~0xf;
9023 +-}
9024 +-
9025 +-unsigned long arch_randomize_brk(struct mm_struct *mm)
9026 +-{
9027 +- unsigned long range_end = mm->brk + 0x02000000;
9028 +- return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
9029 +-}
9030 +diff -urNp linux-2.6.28.8/arch/x86/kernel/ptrace.c linux-2.6.28.8/arch/x86/kernel/ptrace.c
9031 +--- linux-2.6.28.8/arch/x86/kernel/ptrace.c 2009-03-07 10:24:49.000000000 -0500
9032 ++++ linux-2.6.28.8/arch/x86/kernel/ptrace.c 2009-03-07 10:29:51.000000000 -0500
9033 +@@ -1502,7 +1502,7 @@ void send_sigtrap(struct task_struct *ts
9034 + info.si_code = si_code;
9035 +
9036 + /* User-mode ip? */
9037 +- info.si_addr = user_mode_vm(regs) ? (void __user *) regs->ip : NULL;
9038 ++ info.si_addr = user_mode(regs) ? (void __user *) regs->ip : NULL;
9039 +
9040 + /* Send us the fake SIGTRAP */
9041 + force_sig_info(SIGTRAP, &info, tsk);
9042 +diff -urNp linux-2.6.28.8/arch/x86/kernel/reboot.c linux-2.6.28.8/arch/x86/kernel/reboot.c
9043 +--- linux-2.6.28.8/arch/x86/kernel/reboot.c 2009-03-07 10:24:49.000000000 -0500
9044 ++++ linux-2.6.28.8/arch/x86/kernel/reboot.c 2009-03-07 10:32:37.000000000 -0500
9045 +@@ -28,7 +28,7 @@ void (*pm_power_off)(void);
9046 + EXPORT_SYMBOL(pm_power_off);
9047 +
9048 + static const struct desc_ptr no_idt = {};
9049 +-static int reboot_mode;
9050 ++static unsigned short reboot_mode;
9051 + enum reboot_type reboot_type = BOOT_KBD;
9052 + int reboot_force;
9053 +
9054 +@@ -210,7 +210,7 @@ static struct dmi_system_id __initdata r
9055 + DMI_MATCH(DMI_PRODUCT_NAME, "Dell XPS710"),
9056 + },
9057 + },
9058 +- { }
9059 ++ { NULL, NULL, {{0, {0}}}, NULL}
9060 + };
9061 +
9062 + static int __init reboot_init(void)
9063 +@@ -226,12 +226,12 @@ core_initcall(reboot_init);
9064 + controller to pulse the CPU reset line, which is more thorough, but
9065 + doesn't work with at least one type of 486 motherboard. It is easy
9066 + to stop this code working; hence the copious comments. */
9067 +-static const unsigned long long
9068 +-real_mode_gdt_entries [3] =
9069 ++static struct desc_struct
9070 ++real_mode_gdt_entries [3] __read_only =
9071 + {
9072 +- 0x0000000000000000ULL, /* Null descriptor */
9073 +- 0x00009b000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
9074 +- 0x000093000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
9075 ++ {{{0x00000000, 0x00000000}}}, /* Null descriptor */
9076 ++ {{{0x0000ffff, 0x00009b00}}}, /* 16-bit real-mode 64k code at 0x00000000 */
9077 ++ {{{0x0100ffff, 0x00009300}}} /* 16-bit real-mode 64k data at 0x00000100 */
9078 + };
9079 +
9080 + static const struct desc_ptr
9081 +@@ -280,7 +280,7 @@ static const unsigned char jump_to_bios
9082 + * specified by the code and length parameters.
9083 + * We assume that length will aways be less that 100!
9084 + */
9085 +-void machine_real_restart(const unsigned char *code, int length)
9086 ++void machine_real_restart(const unsigned char *code, unsigned int length)
9087 + {
9088 + local_irq_disable();
9089 +
9090 +@@ -300,8 +300,8 @@ void machine_real_restart(const unsigned
9091 + /* Remap the kernel at virtual address zero, as well as offset zero
9092 + from the kernel segment. This assumes the kernel segment starts at
9093 + virtual address PAGE_OFFSET. */
9094 +- memcpy(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
9095 +- sizeof(swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
9096 ++ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
9097 ++ min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
9098 +
9099 + /*
9100 + * Use `swapper_pg_dir' as our page directory.
9101 +@@ -313,16 +313,15 @@ void machine_real_restart(const unsigned
9102 + boot)". This seems like a fairly standard thing that gets set by
9103 + REBOOT.COM programs, and the previous reset routine did this
9104 + too. */
9105 +- *((unsigned short *)0x472) = reboot_mode;
9106 ++ *(unsigned short *)(__va(0x472)) = reboot_mode;
9107 +
9108 + /* For the switch to real mode, copy some code to low memory. It has
9109 + to be in the first 64k because it is running in 16-bit mode, and it
9110 + has to have the same physical and virtual address, because it turns
9111 + off paging. Copy it near the end of the first page, out of the way
9112 + of BIOS variables. */
9113 +- memcpy((void *)(0x1000 - sizeof(real_mode_switch) - 100),
9114 +- real_mode_switch, sizeof (real_mode_switch));
9115 +- memcpy((void *)(0x1000 - 100), code, length);
9116 ++ memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch));
9117 ++ memcpy(__va(0x1000 - 100), code, length);
9118 +
9119 + /* Set up the IDT for real mode. */
9120 + load_idt(&real_mode_idt);
9121 +diff -urNp linux-2.6.28.8/arch/x86/kernel/setup.c linux-2.6.28.8/arch/x86/kernel/setup.c
9122 +--- linux-2.6.28.8/arch/x86/kernel/setup.c 2009-02-06 16:47:45.000000000 -0500
9123 ++++ linux-2.6.28.8/arch/x86/kernel/setup.c 2009-02-21 09:37:48.000000000 -0500
9124 +@@ -738,6 +738,7 @@ void start_periodic_check_for_corruption
9125 + }
9126 + #endif
9127 +
9128 ++#ifdef CONFIG_X86_RESERVE_LOW_64K
9129 + static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
9130 + {
9131 + printk(KERN_NOTICE
9132 +@@ -749,6 +750,7 @@ static int __init dmi_low_memory_corrupt
9133 +
9134 + return 0;
9135 + }
9136 ++#endif
9137 +
9138 + /* List of systems that have known low memory corruption BIOS problems */
9139 + static struct dmi_system_id __initdata bad_bios_dmi_table[] = {
9140 +@@ -845,8 +847,8 @@ void __init setup_arch(char **cmdline_p)
9141 +
9142 + if (!boot_params.hdr.root_flags)
9143 + root_mountflags &= ~MS_RDONLY;
9144 +- init_mm.start_code = (unsigned long) _text;
9145 +- init_mm.end_code = (unsigned long) _etext;
9146 ++ init_mm.start_code = ktla_ktva((unsigned long) _text);
9147 ++ init_mm.end_code = ktla_ktva((unsigned long) _etext);
9148 + init_mm.end_data = (unsigned long) _edata;
9149 + #ifdef CONFIG_X86_32
9150 + init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
9151 +@@ -854,9 +856,9 @@ void __init setup_arch(char **cmdline_p)
9152 + init_mm.brk = (unsigned long) &_end;
9153 + #endif
9154 +
9155 +- code_resource.start = virt_to_phys(_text);
9156 +- code_resource.end = virt_to_phys(_etext)-1;
9157 +- data_resource.start = virt_to_phys(_etext);
9158 ++ code_resource.start = virt_to_phys(ktla_ktva(_text));
9159 ++ code_resource.end = virt_to_phys(ktla_ktva(_etext))-1;
9160 ++ data_resource.start = virt_to_phys(_data);
9161 + data_resource.end = virt_to_phys(_edata)-1;
9162 + bss_resource.start = virt_to_phys(&__bss_start);
9163 + bss_resource.end = virt_to_phys(&__bss_stop)-1;
9164 +diff -urNp linux-2.6.28.8/arch/x86/kernel/setup_percpu.c linux-2.6.28.8/arch/x86/kernel/setup_percpu.c
9165 +--- linux-2.6.28.8/arch/x86/kernel/setup_percpu.c 2009-02-06 16:47:45.000000000 -0500
9166 ++++ linux-2.6.28.8/arch/x86/kernel/setup_percpu.c 2009-02-21 09:37:48.000000000 -0500
9167 +@@ -179,7 +179,11 @@ void __init setup_per_cpu_areas(void)
9168 + cpu, node, __pa(ptr));
9169 + }
9170 + #endif
9171 ++#ifdef CONFIG_X86_32
9172 ++ __per_cpu_offset[cpu] = ptr - __per_cpu_start;
9173 ++#else
9174 + per_cpu_offset(cpu) = ptr - __per_cpu_start;
9175 ++#endif
9176 + memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
9177 + }
9178 +
9179 +diff -urNp linux-2.6.28.8/arch/x86/kernel/signal_32.c linux-2.6.28.8/arch/x86/kernel/signal_32.c
9180 +--- linux-2.6.28.8/arch/x86/kernel/signal_32.c 2009-02-06 16:47:45.000000000 -0500
9181 ++++ linux-2.6.28.8/arch/x86/kernel/signal_32.c 2009-02-21 09:37:48.000000000 -0500
9182 +@@ -367,9 +367,9 @@ __setup_frame(int sig, struct k_sigactio
9183 + }
9184 +
9185 + if (current->mm->context.vdso)
9186 +- restorer = VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
9187 ++ restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
9188 + else
9189 +- restorer = &frame->retcode;
9190 ++ restorer = (void __user *)&frame->retcode;
9191 + if (ka->sa.sa_flags & SA_RESTORER)
9192 + restorer = ka->sa.sa_restorer;
9193 +
9194 +@@ -442,7 +442,7 @@ static int __setup_rt_frame(int sig, str
9195 + return -EFAULT;
9196 +
9197 + /* Set up to return from userspace. */
9198 +- restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
9199 ++ restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
9200 + if (ka->sa.sa_flags & SA_RESTORER)
9201 + restorer = ka->sa.sa_restorer;
9202 + err |= __put_user(restorer, &frame->pretcode);
9203 +@@ -612,7 +612,7 @@ static void do_signal(struct pt_regs *re
9204 + * X86_32: vm86 regs switched out by assembly code before reaching
9205 + * here, so testing against kernel CS suffices.
9206 + */
9207 +- if (!user_mode(regs))
9208 ++ if (!user_mode_novm(regs))
9209 + return;
9210 +
9211 + if (current_thread_info()->status & TS_RESTORE_SIGMASK)
9212 +diff -urNp linux-2.6.28.8/arch/x86/kernel/signal_64.c linux-2.6.28.8/arch/x86/kernel/signal_64.c
9213 +--- linux-2.6.28.8/arch/x86/kernel/signal_64.c 2009-02-06 16:47:45.000000000 -0500
9214 ++++ linux-2.6.28.8/arch/x86/kernel/signal_64.c 2009-02-21 09:37:48.000000000 -0500
9215 +@@ -239,8 +239,8 @@ static int __setup_rt_frame(int sig, str
9216 + err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
9217 + err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
9218 + if (sizeof(*set) == 16) {
9219 +- __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
9220 +- __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
9221 ++ err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
9222 ++ err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
9223 + } else
9224 + err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
9225 +
9226 +diff -urNp linux-2.6.28.8/arch/x86/kernel/smpboot.c linux-2.6.28.8/arch/x86/kernel/smpboot.c
9227 +--- linux-2.6.28.8/arch/x86/kernel/smpboot.c 2009-02-06 16:47:45.000000000 -0500
9228 ++++ linux-2.6.28.8/arch/x86/kernel/smpboot.c 2009-02-21 09:37:48.000000000 -0500
9229 +@@ -814,6 +814,11 @@ static int __cpuinit do_boot_cpu(int api
9230 + .cpu = cpu,
9231 + .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
9232 + };
9233 ++
9234 ++#ifdef CONFIG_PAX_KERNEXEC
9235 ++ unsigned long cr0;
9236 ++#endif
9237 ++
9238 + INIT_WORK(&c_idle.work, do_fork_idle);
9239 +
9240 + #ifdef CONFIG_X86_64
9241 +@@ -864,7 +869,17 @@ do_rest:
9242 + cpu_pda(cpu)->pcurrent = c_idle.idle;
9243 + clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
9244 + #endif
9245 ++
9246 ++#ifdef CONFIG_PAX_KERNEXEC
9247 ++ pax_open_kernel(cr0);
9248 ++#endif
9249 ++
9250 + early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
9251 ++
9252 ++#ifdef CONFIG_PAX_KERNEXEC
9253 ++ pax_close_kernel(cr0);
9254 ++#endif
9255 ++
9256 + initial_code = (unsigned long)start_secondary;
9257 + stack_start.sp = (void *) c_idle.idle->thread.sp;
9258 +
9259 +diff -urNp linux-2.6.28.8/arch/x86/kernel/smpcommon.c linux-2.6.28.8/arch/x86/kernel/smpcommon.c
9260 +--- linux-2.6.28.8/arch/x86/kernel/smpcommon.c 2009-02-06 16:47:45.000000000 -0500
9261 ++++ linux-2.6.28.8/arch/x86/kernel/smpcommon.c 2009-02-21 09:37:48.000000000 -0500
9262 +@@ -3,9 +3,10 @@
9263 + */
9264 + #include <linux/module.h>
9265 + #include <asm/smp.h>
9266 ++#include <asm/sections.h>
9267 +
9268 + #ifdef CONFIG_X86_32
9269 +-DEFINE_PER_CPU(unsigned long, this_cpu_off);
9270 ++DEFINE_PER_CPU(unsigned long, this_cpu_off) = (unsigned long)__per_cpu_start;
9271 + EXPORT_PER_CPU_SYMBOL(this_cpu_off);
9272 +
9273 + /*
9274 +@@ -15,16 +16,19 @@ EXPORT_PER_CPU_SYMBOL(this_cpu_off);
9275 + */
9276 + __cpuinit void init_gdt(int cpu)
9277 + {
9278 +- struct desc_struct gdt;
9279 ++ struct desc_struct d, *gdt = get_cpu_gdt_table(cpu);
9280 ++ unsigned long base, limit;
9281 +
9282 +- pack_descriptor(&gdt, __per_cpu_offset[cpu], 0xFFFFF,
9283 +- 0x2 | DESCTYPE_S, 0x8);
9284 +- gdt.s = 1;
9285 ++ base = per_cpu_offset(cpu);
9286 ++ limit = PERCPU_ENOUGH_ROOM - 1;
9287 ++ if (limit < 64*1024)
9288 ++ pack_descriptor(&d, base, limit, 0x80 | DESCTYPE_S | 0x3, 0x4);
9289 ++ else
9290 ++ pack_descriptor(&d, base, limit >> PAGE_SHIFT, 0x80 | DESCTYPE_S | 0x3, 0xC);
9291 +
9292 +- write_gdt_entry(get_cpu_gdt_table(cpu),
9293 +- GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S);
9294 ++ write_gdt_entry(gdt, GDT_ENTRY_PERCPU, &d, DESCTYPE_S);
9295 +
9296 +- per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu];
9297 ++ per_cpu(this_cpu_off, cpu) = base;
9298 + per_cpu(cpu_number, cpu) = cpu;
9299 + }
9300 + #endif
9301 +diff -urNp linux-2.6.28.8/arch/x86/kernel/step.c linux-2.6.28.8/arch/x86/kernel/step.c
9302 +--- linux-2.6.28.8/arch/x86/kernel/step.c 2009-02-06 16:47:45.000000000 -0500
9303 ++++ linux-2.6.28.8/arch/x86/kernel/step.c 2009-02-21 09:37:48.000000000 -0500
9304 +@@ -23,22 +23,20 @@ unsigned long convert_ip_to_linear(struc
9305 + * and APM bios ones we just ignore here.
9306 + */
9307 + if ((seg & SEGMENT_TI_MASK) == SEGMENT_LDT) {
9308 +- u32 *desc;
9309 ++ struct desc_struct *desc;
9310 + unsigned long base;
9311 +
9312 +- seg &= ~7UL;
9313 ++ seg >>= 3;
9314 +
9315 + mutex_lock(&child->mm->context.lock);
9316 +- if (unlikely((seg >> 3) >= child->mm->context.size))
9317 +- addr = -1L; /* bogus selector, access would fault */
9318 ++ if (unlikely(seg >= child->mm->context.size))
9319 ++ addr = -EINVAL;
9320 + else {
9321 +- desc = child->mm->context.ldt + seg;
9322 +- base = ((desc[0] >> 16) |
9323 +- ((desc[1] & 0xff) << 16) |
9324 +- (desc[1] & 0xff000000));
9325 ++ desc = &child->mm->context.ldt[seg];
9326 ++ base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000);
9327 +
9328 + /* 16-bit code segment? */
9329 +- if (!((desc[1] >> 22) & 1))
9330 ++ if (!((desc->b >> 22) & 1))
9331 + addr &= 0xffff;
9332 + addr += base;
9333 + }
9334 +@@ -54,6 +52,9 @@ static int is_setting_trap_flag(struct t
9335 + unsigned char opcode[15];
9336 + unsigned long addr = convert_ip_to_linear(child, regs);
9337 +
9338 ++ if (addr == -EINVAL)
9339 ++ return 0;
9340 ++
9341 + copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
9342 + for (i = 0; i < copied; i++) {
9343 + switch (opcode[i]) {
9344 +@@ -75,7 +76,7 @@ static int is_setting_trap_flag(struct t
9345 +
9346 + #ifdef CONFIG_X86_64
9347 + case 0x40 ... 0x4f:
9348 +- if (regs->cs != __USER_CS)
9349 ++ if ((regs->cs & 0xffff) != __USER_CS)
9350 + /* 32-bit mode: register increment */
9351 + return 0;
9352 + /* 64-bit mode: REX prefix */
9353 +diff -urNp linux-2.6.28.8/arch/x86/kernel/syscall_table_32.S linux-2.6.28.8/arch/x86/kernel/syscall_table_32.S
9354 +--- linux-2.6.28.8/arch/x86/kernel/syscall_table_32.S 2009-02-06 16:47:45.000000000 -0500
9355 ++++ linux-2.6.28.8/arch/x86/kernel/syscall_table_32.S 2009-02-21 09:37:48.000000000 -0500
9356 +@@ -1,3 +1,4 @@
9357 ++.section .rodata,"a",@progbits
9358 + ENTRY(sys_call_table)
9359 + .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
9360 + .long sys_exit
9361 +diff -urNp linux-2.6.28.8/arch/x86/kernel/sys_i386_32.c linux-2.6.28.8/arch/x86/kernel/sys_i386_32.c
9362 +--- linux-2.6.28.8/arch/x86/kernel/sys_i386_32.c 2009-02-06 16:47:45.000000000 -0500
9363 ++++ linux-2.6.28.8/arch/x86/kernel/sys_i386_32.c 2009-02-21 09:37:48.000000000 -0500
9364 +@@ -24,6 +24,21 @@
9365 +
9366 + #include <asm/syscalls.h>
9367 +
9368 ++int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
9369 ++{
9370 ++ unsigned long pax_task_size = TASK_SIZE;
9371 ++
9372 ++#ifdef CONFIG_PAX_SEGMEXEC
9373 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
9374 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
9375 ++#endif
9376 ++
9377 ++ if (len > pax_task_size || addr > pax_task_size - len)
9378 ++ return -EINVAL;
9379 ++
9380 ++ return 0;
9381 ++}
9382 ++
9383 + asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
9384 + unsigned long prot, unsigned long flags,
9385 + unsigned long fd, unsigned long pgoff)
9386 +@@ -83,6 +98,205 @@ out:
9387 + return err;
9388 + }
9389 +
9390 ++unsigned long
9391 ++arch_get_unmapped_area(struct file *filp, unsigned long addr,
9392 ++ unsigned long len, unsigned long pgoff, unsigned long flags)
9393 ++{
9394 ++ struct mm_struct *mm = current->mm;
9395 ++ struct vm_area_struct *vma;
9396 ++ unsigned long start_addr, pax_task_size = TASK_SIZE;
9397 ++
9398 ++#ifdef CONFIG_PAX_SEGMEXEC
9399 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
9400 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
9401 ++#endif
9402 ++
9403 ++ if (len > pax_task_size)
9404 ++ return -ENOMEM;
9405 ++
9406 ++ if (flags & MAP_FIXED)
9407 ++ return addr;
9408 ++
9409 ++#ifdef CONFIG_PAX_RANDMMAP
9410 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
9411 ++#endif
9412 ++
9413 ++ if (addr) {
9414 ++ addr = PAGE_ALIGN(addr);
9415 ++ vma = find_vma(mm, addr);
9416 ++ if (pax_task_size - len >= addr &&
9417 ++ (!vma || addr + len <= vma->vm_start))
9418 ++ return addr;
9419 ++ }
9420 ++ if (len > mm->cached_hole_size) {
9421 ++ start_addr = addr = mm->free_area_cache;
9422 ++ } else {
9423 ++ start_addr = addr = mm->mmap_base;
9424 ++ mm->cached_hole_size = 0;
9425 ++ }
9426 ++
9427 ++#ifdef CONFIG_PAX_PAGEEXEC
9428 ++ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
9429 ++ start_addr = 0x00110000UL;
9430 ++
9431 ++#ifdef CONFIG_PAX_RANDMMAP
9432 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
9433 ++ start_addr += mm->delta_mmap & 0x03FFF000UL;
9434 ++#endif
9435 ++
9436 ++ if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
9437 ++ start_addr = addr = mm->mmap_base;
9438 ++ else
9439 ++ addr = start_addr;
9440 ++ }
9441 ++#endif
9442 ++
9443 ++full_search:
9444 ++ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
9445 ++ /* At this point: (!vma || addr < vma->vm_end). */
9446 ++ if (pax_task_size - len < addr) {
9447 ++ /*
9448 ++ * Start a new search - just in case we missed
9449 ++ * some holes.
9450 ++ */
9451 ++ if (start_addr != mm->mmap_base) {
9452 ++ start_addr = addr = mm->mmap_base;
9453 ++ mm->cached_hole_size = 0;
9454 ++ goto full_search;
9455 ++ }
9456 ++ return -ENOMEM;
9457 ++ }
9458 ++ if (!vma || addr + len <= vma->vm_start) {
9459 ++ /*
9460 ++ * Remember the place where we stopped the search:
9461 ++ */
9462 ++ mm->free_area_cache = addr + len;
9463 ++ return addr;
9464 ++ }
9465 ++ if (addr + mm->cached_hole_size < vma->vm_start)
9466 ++ mm->cached_hole_size = vma->vm_start - addr;
9467 ++ addr = vma->vm_end;
9468 ++ if (mm->start_brk <= addr && addr < mm->mmap_base) {
9469 ++ start_addr = addr = mm->mmap_base;
9470 ++ mm->cached_hole_size = 0;
9471 ++ goto full_search;
9472 ++ }
9473 ++ }
9474 ++}
9475 ++
9476 ++unsigned long
9477 ++arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
9478 ++ const unsigned long len, const unsigned long pgoff,
9479 ++ const unsigned long flags)
9480 ++{
9481 ++ struct vm_area_struct *vma;
9482 ++ struct mm_struct *mm = current->mm;
9483 ++ unsigned long base = mm->mmap_base, addr = addr0, pax_task_size = TASK_SIZE;
9484 ++
9485 ++#ifdef CONFIG_PAX_SEGMEXEC
9486 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
9487 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
9488 ++#endif
9489 ++
9490 ++ /* requested length too big for entire address space */
9491 ++ if (len > pax_task_size)
9492 ++ return -ENOMEM;
9493 ++
9494 ++ if (flags & MAP_FIXED)
9495 ++ return addr;
9496 ++
9497 ++#ifdef CONFIG_PAX_PAGEEXEC
9498 ++ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
9499 ++ goto bottomup;
9500 ++#endif
9501 ++
9502 ++#ifdef CONFIG_PAX_RANDMMAP
9503 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
9504 ++#endif
9505 ++
9506 ++ /* requesting a specific address */
9507 ++ if (addr) {
9508 ++ addr = PAGE_ALIGN(addr);
9509 ++ vma = find_vma(mm, addr);
9510 ++ if (pax_task_size - len >= addr &&
9511 ++ (!vma || addr + len <= vma->vm_start))
9512 ++ return addr;
9513 ++ }
9514 ++
9515 ++ /* check if free_area_cache is useful for us */
9516 ++ if (len <= mm->cached_hole_size) {
9517 ++ mm->cached_hole_size = 0;
9518 ++ mm->free_area_cache = mm->mmap_base;
9519 ++ }
9520 ++
9521 ++ /* either no address requested or can't fit in requested address hole */
9522 ++ addr = mm->free_area_cache;
9523 ++
9524 ++ /* make sure it can fit in the remaining address space */
9525 ++ if (addr > len) {
9526 ++ vma = find_vma(mm, addr-len);
9527 ++ if (!vma || addr <= vma->vm_start)
9528 ++ /* remember the address as a hint for next time */
9529 ++ return (mm->free_area_cache = addr-len);
9530 ++ }
9531 ++
9532 ++ if (mm->mmap_base < len)
9533 ++ goto bottomup;
9534 ++
9535 ++ addr = mm->mmap_base-len;
9536 ++
9537 ++ do {
9538 ++ /*
9539 ++ * Lookup failure means no vma is above this address,
9540 ++ * else if new region fits below vma->vm_start,
9541 ++ * return with success:
9542 ++ */
9543 ++ vma = find_vma(mm, addr);
9544 ++ if (!vma || addr+len <= vma->vm_start)
9545 ++ /* remember the address as a hint for next time */
9546 ++ return (mm->free_area_cache = addr);
9547 ++
9548 ++ /* remember the largest hole we saw so far */
9549 ++ if (addr + mm->cached_hole_size < vma->vm_start)
9550 ++ mm->cached_hole_size = vma->vm_start - addr;
9551 ++
9552 ++ /* try just below the current vma->vm_start */
9553 ++ addr = vma->vm_start-len;
9554 ++ } while (len < vma->vm_start);
9555 ++
9556 ++bottomup:
9557 ++ /*
9558 ++ * A failed mmap() very likely causes application failure,
9559 ++ * so fall back to the bottom-up function here. This scenario
9560 ++ * can happen with large stack limits and large mmap()
9561 ++ * allocations.
9562 ++ */
9563 ++
9564 ++#ifdef CONFIG_PAX_SEGMEXEC
9565 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
9566 ++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
9567 ++ else
9568 ++#endif
9569 ++
9570 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
9571 ++
9572 ++#ifdef CONFIG_PAX_RANDMMAP
9573 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
9574 ++ mm->mmap_base += mm->delta_mmap;
9575 ++#endif
9576 ++
9577 ++ mm->free_area_cache = mm->mmap_base;
9578 ++ mm->cached_hole_size = ~0UL;
9579 ++ addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
9580 ++ /*
9581 ++ * Restore the topdown base:
9582 ++ */
9583 ++ mm->mmap_base = base;
9584 ++ mm->free_area_cache = base;
9585 ++ mm->cached_hole_size = ~0UL;
9586 ++
9587 ++ return addr;
9588 ++}
9589 +
9590 + struct sel_arg_struct {
9591 + unsigned long n;
9592 +diff -urNp linux-2.6.28.8/arch/x86/kernel/sys_x86_64.c linux-2.6.28.8/arch/x86/kernel/sys_x86_64.c
9593 +--- linux-2.6.28.8/arch/x86/kernel/sys_x86_64.c 2009-02-06 16:47:45.000000000 -0500
9594 ++++ linux-2.6.28.8/arch/x86/kernel/sys_x86_64.c 2009-02-21 09:37:48.000000000 -0500
9595 +@@ -47,8 +47,8 @@ out:
9596 + return error;
9597 + }
9598 +
9599 +-static void find_start_end(unsigned long flags, unsigned long *begin,
9600 +- unsigned long *end)
9601 ++static void find_start_end(struct mm_struct *mm, unsigned long flags,
9602 ++ unsigned long *begin, unsigned long *end)
9603 + {
9604 + if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
9605 + unsigned long new_begin;
9606 +@@ -67,7 +67,7 @@ static void find_start_end(unsigned long
9607 + *begin = new_begin;
9608 + }
9609 + } else {
9610 +- *begin = TASK_UNMAPPED_BASE;
9611 ++ *begin = mm->mmap_base;
9612 + *end = TASK_SIZE;
9613 + }
9614 + }
9615 +@@ -84,11 +84,15 @@ arch_get_unmapped_area(struct file *filp
9616 + if (flags & MAP_FIXED)
9617 + return addr;
9618 +
9619 +- find_start_end(flags, &begin, &end);
9620 ++ find_start_end(mm, flags, &begin, &end);
9621 +
9622 + if (len > end)
9623 + return -ENOMEM;
9624 +
9625 ++#ifdef CONFIG_PAX_RANDMMAP
9626 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
9627 ++#endif
9628 ++
9629 + if (addr) {
9630 + addr = PAGE_ALIGN(addr);
9631 + vma = find_vma(mm, addr);
9632 +@@ -143,7 +147,7 @@ arch_get_unmapped_area_topdown(struct fi
9633 + {
9634 + struct vm_area_struct *vma;
9635 + struct mm_struct *mm = current->mm;
9636 +- unsigned long addr = addr0;
9637 ++ unsigned long base = mm->mmap_base, addr = addr0;
9638 +
9639 + /* requested length too big for entire address space */
9640 + if (len > TASK_SIZE)
9641 +@@ -156,6 +160,10 @@ arch_get_unmapped_area_topdown(struct fi
9642 + if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT))
9643 + goto bottomup;
9644 +
9645 ++#ifdef CONFIG_PAX_RANDMMAP
9646 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
9647 ++#endif
9648 ++
9649 + /* requesting a specific address */
9650 + if (addr) {
9651 + addr = PAGE_ALIGN(addr);
9652 +@@ -213,13 +221,21 @@ bottomup:
9653 + * can happen with large stack limits and large mmap()
9654 + * allocations.
9655 + */
9656 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
9657 ++
9658 ++#ifdef CONFIG_PAX_RANDMMAP
9659 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
9660 ++ mm->mmap_base += mm->delta_mmap;
9661 ++#endif
9662 ++
9663 ++ mm->free_area_cache = mm->mmap_base;
9664 + mm->cached_hole_size = ~0UL;
9665 +- mm->free_area_cache = TASK_UNMAPPED_BASE;
9666 + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
9667 + /*
9668 + * Restore the topdown base:
9669 + */
9670 +- mm->free_area_cache = mm->mmap_base;
9671 ++ mm->mmap_base = base;
9672 ++ mm->free_area_cache = base;
9673 + mm->cached_hole_size = ~0UL;
9674 +
9675 + return addr;
9676 +diff -urNp linux-2.6.28.8/arch/x86/kernel/time_32.c linux-2.6.28.8/arch/x86/kernel/time_32.c
9677 +--- linux-2.6.28.8/arch/x86/kernel/time_32.c 2009-02-06 16:47:45.000000000 -0500
9678 ++++ linux-2.6.28.8/arch/x86/kernel/time_32.c 2009-02-21 09:37:48.000000000 -0500
9679 +@@ -47,22 +47,32 @@ unsigned long profile_pc(struct pt_regs
9680 + unsigned long pc = instruction_pointer(regs);
9681 +
9682 + #ifdef CONFIG_SMP
9683 +- if (!user_mode_vm(regs) && in_lock_functions(pc)) {
9684 ++ if (!user_mode(regs) && in_lock_functions(pc)) {
9685 + #ifdef CONFIG_FRAME_POINTER
9686 +- return *(unsigned long *)(regs->bp + sizeof(long));
9687 ++ return ktla_ktva(*(unsigned long *)(regs->bp + sizeof(long)));
9688 + #else
9689 + unsigned long *sp = (unsigned long *)&regs->sp;
9690 +
9691 + /* Return address is either directly at stack pointer
9692 + or above a saved flags. Eflags has bits 22-31 zero,
9693 + kernel addresses don't. */
9694 ++
9695 ++#ifdef CONFIG_PAX_KERNEXEC
9696 ++ return ktla_ktva(sp[0]);
9697 ++#else
9698 + if (sp[0] >> 22)
9699 + return sp[0];
9700 + if (sp[1] >> 22)
9701 + return sp[1];
9702 + #endif
9703 ++
9704 ++#endif
9705 + }
9706 + #endif
9707 ++
9708 ++ if (!user_mode(regs))
9709 ++ pc = ktla_ktva(pc);
9710 ++
9711 + return pc;
9712 + }
9713 + EXPORT_SYMBOL(profile_pc);
9714 +diff -urNp linux-2.6.28.8/arch/x86/kernel/time_64.c linux-2.6.28.8/arch/x86/kernel/time_64.c
9715 +--- linux-2.6.28.8/arch/x86/kernel/time_64.c 2009-02-06 16:47:45.000000000 -0500
9716 ++++ linux-2.6.28.8/arch/x86/kernel/time_64.c 2009-02-21 09:37:48.000000000 -0500
9717 +@@ -34,7 +34,7 @@ unsigned long profile_pc(struct pt_regs
9718 + /* Assume the lock function has either no stack frame or a copy
9719 + of flags from PUSHF
9720 + Eflags always has bits 22 and up cleared unlike kernel addresses. */
9721 +- if (!user_mode_vm(regs) && in_lock_functions(pc)) {
9722 ++ if (!user_mode(regs) && in_lock_functions(pc)) {
9723 + #ifdef CONFIG_FRAME_POINTER
9724 + return *(unsigned long *)(regs->bp + sizeof(long));
9725 + #else
9726 +diff -urNp linux-2.6.28.8/arch/x86/kernel/tlb_32.c linux-2.6.28.8/arch/x86/kernel/tlb_32.c
9727 +--- linux-2.6.28.8/arch/x86/kernel/tlb_32.c 2009-02-06 16:47:45.000000000 -0500
9728 ++++ linux-2.6.28.8/arch/x86/kernel/tlb_32.c 2009-02-21 09:37:48.000000000 -0500
9729 +@@ -5,7 +5,7 @@
9730 + #include <asm/tlbflush.h>
9731 +
9732 + DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate)
9733 +- ____cacheline_aligned = { &init_mm, 0, };
9734 ++ ____cacheline_aligned = { &init_mm, 0, {0} };
9735 +
9736 + /* must come after the send_IPI functions above for inlining */
9737 + #include <mach_ipi.h>
9738 +diff -urNp linux-2.6.28.8/arch/x86/kernel/tls.c linux-2.6.28.8/arch/x86/kernel/tls.c
9739 +--- linux-2.6.28.8/arch/x86/kernel/tls.c 2009-02-06 16:47:45.000000000 -0500
9740 ++++ linux-2.6.28.8/arch/x86/kernel/tls.c 2009-02-21 09:37:48.000000000 -0500
9741 +@@ -85,6 +85,11 @@ int do_set_thread_area(struct task_struc
9742 + if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
9743 + return -EINVAL;
9744 +
9745 ++#ifdef CONFIG_PAX_SEGMEXEC
9746 ++ if ((p->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
9747 ++ return -EINVAL;
9748 ++#endif
9749 ++
9750 + set_tls_desc(p, idx, &info, 1);
9751 +
9752 + return 0;
9753 +diff -urNp linux-2.6.28.8/arch/x86/kernel/traps.c linux-2.6.28.8/arch/x86/kernel/traps.c
9754 +--- linux-2.6.28.8/arch/x86/kernel/traps.c 2009-03-07 10:24:49.000000000 -0500
9755 ++++ linux-2.6.28.8/arch/x86/kernel/traps.c 2009-03-07 10:29:51.000000000 -0500
9756 +@@ -79,14 +79,6 @@ asmlinkage int system_call(void);
9757 +
9758 + /* Do we ignore FPU interrupts ? */
9759 + char ignore_fpu_irq;
9760 +-
9761 +-/*
9762 +- * The IDT has to be page-aligned to simplify the Pentium
9763 +- * F0 0F bug workaround.. We have a special link segment
9764 +- * for this.
9765 +- */
9766 +-gate_desc idt_table[256]
9767 +- __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, };
9768 + #endif
9769 +
9770 + static int ignore_nmis;
9771 +@@ -121,7 +113,7 @@ static inline void preempt_conditional_c
9772 + static inline void
9773 + die_if_kernel(const char *str, struct pt_regs *regs, long err)
9774 + {
9775 +- if (!user_mode_vm(regs))
9776 ++ if (!user_mode(regs))
9777 + die(str, regs, err);
9778 + }
9779 +
9780 +@@ -138,7 +130,7 @@ static int lazy_iobitmap_copy(void)
9781 + int cpu;
9782 +
9783 + cpu = get_cpu();
9784 +- tss = &per_cpu(init_tss, cpu);
9785 ++ tss = init_tss + cpu;
9786 + thread = &current->thread;
9787 +
9788 + if (tss->x86_tss.io_bitmap_base == INVALID_IO_BITMAP_OFFSET_LAZY &&
9789 +@@ -174,7 +166,7 @@ do_trap(int trapnr, int signr, char *str
9790 + struct task_struct *tsk = current;
9791 +
9792 + #ifdef CONFIG_X86_32
9793 +- if (regs->flags & X86_VM_MASK) {
9794 ++ if (v8086_mode(regs)) {
9795 + /*
9796 + * traps 0, 1, 3, 4, and 5 should be forwarded to vm86.
9797 + * On nmi (interrupt 2), do_trap should not be called.
9798 +@@ -185,7 +177,7 @@ do_trap(int trapnr, int signr, char *str
9799 + }
9800 + #endif
9801 +
9802 +- if (!user_mode(regs))
9803 ++ if (!user_mode_novm(regs))
9804 + goto kernel_trap;
9805 +
9806 + #ifdef CONFIG_X86_32
9807 +@@ -227,6 +219,12 @@ kernel_trap:
9808 + tsk->thread.trap_no = trapnr;
9809 + die(str, regs, error_code);
9810 + }
9811 ++
9812 ++#ifdef CONFIG_PAX_REFCOUNT
9813 ++ if (trapnr == 4)
9814 ++ pax_report_refcount_overflow(regs);
9815 ++#endif
9816 ++
9817 + return;
9818 +
9819 + #ifdef CONFIG_X86_32
9820 +@@ -318,14 +316,30 @@ do_general_protection(struct pt_regs *re
9821 + return;
9822 + }
9823 +
9824 +- if (regs->flags & X86_VM_MASK)
9825 ++ if (v8086_mode(regs))
9826 + goto gp_in_vm86;
9827 + #endif
9828 +
9829 + tsk = current;
9830 +- if (!user_mode(regs))
9831 ++ if (!user_mode_novm(regs))
9832 + goto gp_in_kernel;
9833 +
9834 ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
9835 ++ if (!nx_enabled && tsk->mm && (tsk->mm->pax_flags & MF_PAX_PAGEEXEC)) {
9836 ++ struct mm_struct *mm = tsk->mm;
9837 ++ unsigned long limit;
9838 ++
9839 ++ down_write(&mm->mmap_sem);
9840 ++ limit = mm->context.user_cs_limit;
9841 ++ if (limit < TASK_SIZE) {
9842 ++ track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC);
9843 ++ up_write(&mm->mmap_sem);
9844 ++ return;
9845 ++ }
9846 ++ up_write(&mm->mmap_sem);
9847 ++ }
9848 ++#endif
9849 ++
9850 + tsk->thread.error_code = error_code;
9851 + tsk->thread.trap_no = 13;
9852 +
9853 +@@ -358,6 +372,13 @@ gp_in_kernel:
9854 + if (notify_die(DIE_GPF, "general protection fault", regs,
9855 + error_code, 13, SIGSEGV) == NOTIFY_STOP)
9856 + return;
9857 ++
9858 ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
9859 ++ if ((regs->cs & 0xFFFF) == __KERNEL_CS)
9860 ++ die("PAX: suspicious general protection fault", regs, error_code);
9861 ++ else
9862 ++#endif
9863 ++
9864 + die("general protection fault", regs, error_code);
9865 + }
9866 +
9867 +@@ -604,7 +625,7 @@ dotraplinkage void __kprobes do_debug(st
9868 + }
9869 +
9870 + #ifdef CONFIG_X86_32
9871 +- if (regs->flags & X86_VM_MASK)
9872 ++ if (v8086_mode(regs))
9873 + goto debug_vm86;
9874 + #endif
9875 +
9876 +@@ -616,7 +637,7 @@ dotraplinkage void __kprobes do_debug(st
9877 + * kernel space (but re-enable TF when returning to user mode).
9878 + */
9879 + if (condition & DR_STEP) {
9880 +- if (!user_mode(regs))
9881 ++ if (!user_mode_novm(regs))
9882 + goto clear_TF_reenable;
9883 + }
9884 +
9885 +@@ -808,7 +829,7 @@ do_simd_coprocessor_error(struct pt_regs
9886 + * Handle strange cache flush from user space exception
9887 + * in all other cases. This is undocumented behaviour.
9888 + */
9889 +- if (regs->flags & X86_VM_MASK) {
9890 ++ if (v8086_mode(regs)) {
9891 + handle_vm86_fault((struct kernel_vm86_regs *)regs, error_code);
9892 + return;
9893 + }
9894 +@@ -837,19 +858,14 @@ do_spurious_interrupt_bug(struct pt_regs
9895 + #ifdef CONFIG_X86_32
9896 + unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp)
9897 + {
9898 +- struct desc_struct *gdt = get_cpu_gdt_table(smp_processor_id());
9899 + unsigned long base = (kesp - uesp) & -THREAD_SIZE;
9900 + unsigned long new_kesp = kesp - base;
9901 + unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
9902 +- __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
9903 ++ struct desc_struct ss;
9904 +
9905 + /* Set up base for espfix segment */
9906 +- desc &= 0x00f0ff0000000000ULL;
9907 +- desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
9908 +- ((((__u64)base) << 32) & 0xff00000000000000ULL) |
9909 +- ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
9910 +- (lim_pages & 0xffff);
9911 +- *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
9912 ++ pack_descriptor(&ss, base, lim_pages, 0x93, 0xC);
9913 ++ write_gdt_entry(get_cpu_gdt_table(smp_processor_id()), GDT_ENTRY_ESPFIX_SS, &ss, DESCTYPE_S);
9914 +
9915 + return new_kesp;
9916 + }
9917 +diff -urNp linux-2.6.28.8/arch/x86/kernel/tsc.c linux-2.6.28.8/arch/x86/kernel/tsc.c
9918 +--- linux-2.6.28.8/arch/x86/kernel/tsc.c 2009-02-06 16:47:45.000000000 -0500
9919 ++++ linux-2.6.28.8/arch/x86/kernel/tsc.c 2009-02-21 09:37:48.000000000 -0500
9920 +@@ -728,7 +728,7 @@ static struct dmi_system_id __initdata b
9921 + DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
9922 + },
9923 + },
9924 +- {}
9925 ++ { NULL, NULL, {{0, {0}}}, NULL}
9926 + };
9927 +
9928 + /*
9929 +diff -urNp linux-2.6.28.8/arch/x86/kernel/vm86_32.c linux-2.6.28.8/arch/x86/kernel/vm86_32.c
9930 +--- linux-2.6.28.8/arch/x86/kernel/vm86_32.c 2009-02-06 16:47:45.000000000 -0500
9931 ++++ linux-2.6.28.8/arch/x86/kernel/vm86_32.c 2009-02-21 09:37:48.000000000 -0500
9932 +@@ -148,7 +148,7 @@ struct pt_regs *save_v86_state(struct ke
9933 + do_exit(SIGSEGV);
9934 + }
9935 +
9936 +- tss = &per_cpu(init_tss, get_cpu());
9937 ++ tss = init_tss + get_cpu();
9938 + current->thread.sp0 = current->thread.saved_sp0;
9939 + current->thread.sysenter_cs = __KERNEL_CS;
9940 + load_sp0(tss, &current->thread);
9941 +@@ -325,7 +325,7 @@ static void do_sys_vm86(struct kernel_vm
9942 + tsk->thread.saved_fs = info->regs32->fs;
9943 + savesegment(gs, tsk->thread.saved_gs);
9944 +
9945 +- tss = &per_cpu(init_tss, get_cpu());
9946 ++ tss = init_tss + get_cpu();
9947 + tsk->thread.sp0 = (unsigned long) &info->VM86_TSS_ESP0;
9948 + if (cpu_has_sep)
9949 + tsk->thread.sysenter_cs = 0;
9950 +diff -urNp linux-2.6.28.8/arch/x86/kernel/vmi_32.c linux-2.6.28.8/arch/x86/kernel/vmi_32.c
9951 +--- linux-2.6.28.8/arch/x86/kernel/vmi_32.c 2009-02-08 00:54:27.000000000 -0500
9952 ++++ linux-2.6.28.8/arch/x86/kernel/vmi_32.c 2009-02-21 09:37:48.000000000 -0500
9953 +@@ -102,18 +102,43 @@ static unsigned patch_internal(int call,
9954 + {
9955 + u64 reloc;
9956 + struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
9957 ++
9958 ++#ifdef CONFIG_PAX_KERNEXEC
9959 ++ unsigned long cr0;
9960 ++#endif
9961 ++
9962 + reloc = call_vrom_long_func(vmi_rom, get_reloc, call);
9963 + switch(rel->type) {
9964 + case VMI_RELOCATION_CALL_REL:
9965 + BUG_ON(len < 5);
9966 ++
9967 ++#ifdef CONFIG_PAX_KERNEXEC
9968 ++ pax_open_kernel(cr0);
9969 ++#endif
9970 ++
9971 + *(char *)insnbuf = MNEM_CALL;
9972 + patch_offset(insnbuf, ip, (unsigned long)rel->eip);
9973 ++
9974 ++#ifdef CONFIG_PAX_KERNEXEC
9975 ++ pax_close_kernel(cr0);
9976 ++#endif
9977 ++
9978 + return 5;
9979 +
9980 + case VMI_RELOCATION_JUMP_REL:
9981 + BUG_ON(len < 5);
9982 ++
9983 ++#ifdef CONFIG_PAX_KERNEXEC
9984 ++ pax_open_kernel(cr0);
9985 ++#endif
9986 ++
9987 + *(char *)insnbuf = MNEM_JMP;
9988 + patch_offset(insnbuf, ip, (unsigned long)rel->eip);
9989 ++
9990 ++#ifdef CONFIG_PAX_KERNEXEC
9991 ++ pax_close_kernel(cr0);
9992 ++#endif
9993 ++
9994 + return 5;
9995 +
9996 + case VMI_RELOCATION_NOP:
9997 +@@ -526,14 +551,14 @@ static void vmi_set_pud(pud_t *pudp, pud
9998 +
9999 + static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
10000 + {
10001 +- const pte_t pte = { .pte = 0 };
10002 ++ const pte_t pte = __pte(0ULL);
10003 + vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE);
10004 + vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
10005 + }
10006 +
10007 + static void vmi_pmd_clear(pmd_t *pmd)
10008 + {
10009 +- const pte_t pte = { .pte = 0 };
10010 ++ const pte_t pte = __pte(0ULL);
10011 + vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD);
10012 + vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD);
10013 + }
10014 +@@ -562,8 +587,8 @@ vmi_startup_ipi_hook(int phys_apicid, un
10015 + ap.ss = __KERNEL_DS;
10016 + ap.esp = (unsigned long) start_esp;
10017 +
10018 +- ap.ds = __USER_DS;
10019 +- ap.es = __USER_DS;
10020 ++ ap.ds = __KERNEL_DS;
10021 ++ ap.es = __KERNEL_DS;
10022 + ap.fs = __KERNEL_PERCPU;
10023 + ap.gs = 0;
10024 +
10025 +@@ -758,12 +783,20 @@ static inline int __init activate_vmi(vo
10026 + u64 reloc;
10027 + const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc;
10028 +
10029 ++#ifdef CONFIG_PAX_KERNEXEC
10030 ++ unsigned long cr0;
10031 ++#endif
10032 ++
10033 + if (call_vrom_func(vmi_rom, vmi_init) != 0) {
10034 + printk(KERN_ERR "VMI ROM failed to initialize!");
10035 + return 0;
10036 + }
10037 + savesegment(cs, kernel_cs);
10038 +
10039 ++#ifdef CONFIG_PAX_KERNEXEC
10040 ++ pax_open_kernel(cr0);
10041 ++#endif
10042 ++
10043 + pv_info.paravirt_enabled = 1;
10044 + pv_info.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
10045 + pv_info.name = "vmi";
10046 +@@ -954,6 +987,10 @@ static inline int __init activate_vmi(vo
10047 +
10048 + para_fill(pv_irq_ops.safe_halt, Halt);
10049 +
10050 ++#ifdef CONFIG_PAX_KERNEXEC
10051 ++ pax_close_kernel(cr0);
10052 ++#endif
10053 ++
10054 + /*
10055 + * Alternative instruction rewriting doesn't happen soon enough
10056 + * to convert VMI_IRET to a call instead of a jump; so we have
10057 +diff -urNp linux-2.6.28.8/arch/x86/kernel/vmlinux_32.lds.S linux-2.6.28.8/arch/x86/kernel/vmlinux_32.lds.S
10058 +--- linux-2.6.28.8/arch/x86/kernel/vmlinux_32.lds.S 2009-02-06 16:47:45.000000000 -0500
10059 ++++ linux-2.6.28.8/arch/x86/kernel/vmlinux_32.lds.S 2009-03-07 10:35:39.000000000 -0500
10060 +@@ -15,6 +15,20 @@
10061 + #include <asm/page.h>
10062 + #include <asm/cache.h>
10063 + #include <asm/boot.h>
10064 ++#include <asm/segment.h>
10065 ++
10066 ++#ifdef CONFIG_X86_PAE
10067 ++#define PMD_SHIFT 21
10068 ++#else
10069 ++#define PMD_SHIFT 22
10070 ++#endif
10071 ++#define PMD_SIZE (1 << PMD_SHIFT)
10072 ++
10073 ++#ifdef CONFIG_PAX_KERNEXEC
10074 ++#define __KERNEL_TEXT_OFFSET (__PAGE_OFFSET + (((____LOAD_PHYSICAL_ADDR + 2*(PMD_SIZE - 1)) - 1) & ~(PMD_SIZE - 1)))
10075 ++#else
10076 ++#define __KERNEL_TEXT_OFFSET 0
10077 ++#endif
10078 +
10079 + OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
10080 + OUTPUT_ARCH(i386)
10081 +@@ -22,81 +36,23 @@ ENTRY(phys_startup_32)
10082 + jiffies = jiffies_64;
10083 +
10084 + PHDRS {
10085 +- text PT_LOAD FLAGS(5); /* R_E */
10086 +- data PT_LOAD FLAGS(7); /* RWE */
10087 +- note PT_NOTE FLAGS(0); /* ___ */
10088 ++ initdata PT_LOAD FLAGS(6); /* RW_ */
10089 ++ percpu PT_LOAD FLAGS(6); /* RW_ */
10090 ++ inittext PT_LOAD FLAGS(5); /* R_E */
10091 ++ text PT_LOAD FLAGS(5); /* R_E */
10092 ++ rodata PT_LOAD FLAGS(4); /* R__ */
10093 ++ data PT_LOAD FLAGS(6); /* RW_ */
10094 ++ note PT_NOTE FLAGS(0); /* ___ */
10095 + }
10096 + SECTIONS
10097 + {
10098 +- . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
10099 +- phys_startup_32 = startup_32 - LOAD_OFFSET;
10100 +-
10101 +- .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
10102 +- _text = .; /* Text and read-only data */
10103 +- *(.text.head)
10104 +- } :text = 0x9090
10105 +-
10106 +- /* read-only */
10107 +- .text : AT(ADDR(.text) - LOAD_OFFSET) {
10108 +- . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
10109 +- *(.text.page_aligned)
10110 +- TEXT_TEXT
10111 +- SCHED_TEXT
10112 +- LOCK_TEXT
10113 +- KPROBES_TEXT
10114 +- *(.fixup)
10115 +- *(.gnu.warning)
10116 +- _etext = .; /* End of text section */
10117 +- } :text = 0x9090
10118 +-
10119 +- NOTES :text :note
10120 +-
10121 +- . = ALIGN(16); /* Exception table */
10122 +- __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
10123 +- __start___ex_table = .;
10124 +- *(__ex_table)
10125 +- __stop___ex_table = .;
10126 +- } :text = 0x9090
10127 +-
10128 +- RODATA
10129 +-
10130 +- /* writeable */
10131 +- . = ALIGN(PAGE_SIZE);
10132 +- .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
10133 +- DATA_DATA
10134 +- CONSTRUCTORS
10135 +- } :data
10136 +-
10137 +- . = ALIGN(PAGE_SIZE);
10138 +- .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
10139 +- __nosave_begin = .;
10140 +- *(.data.nosave)
10141 +- . = ALIGN(PAGE_SIZE);
10142 +- __nosave_end = .;
10143 +- }
10144 ++ . = LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR;
10145 +
10146 +- . = ALIGN(PAGE_SIZE);
10147 +- .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
10148 +- *(.data.page_aligned)
10149 +- *(.data.idt)
10150 +- }
10151 +-
10152 +- . = ALIGN(32);
10153 +- .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
10154 +- *(.data.cacheline_aligned)
10155 +- }
10156 +-
10157 +- /* rarely changed data like cpu maps */
10158 +- . = ALIGN(32);
10159 +- .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
10160 +- *(.data.read_mostly)
10161 +- _edata = .; /* End of data section */
10162 +- }
10163 +-
10164 +- . = ALIGN(THREAD_SIZE); /* init_task */
10165 +- .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
10166 +- *(.data.init_task)
10167 +- }
10168 ++ .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
10169 ++ __LOAD_PHYSICAL_ADDR = . - LOAD_OFFSET;
10170 ++ phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
10171 ++ *(.text.startup)
10172 ++ } :initdata
10173 +
10174 + /* might get freed after init */
10175 + . = ALIGN(PAGE_SIZE);
10176 +@@ -114,14 +70,8 @@ SECTIONS
10177 + . = ALIGN(PAGE_SIZE);
10178 +
10179 + /* will be freed after init */
10180 +- . = ALIGN(PAGE_SIZE); /* Init code and data */
10181 +- .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
10182 +- __init_begin = .;
10183 +- _sinittext = .;
10184 +- INIT_TEXT
10185 +- _einittext = .;
10186 +- }
10187 + .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
10188 ++ __init_begin = .;
10189 + INIT_DATA
10190 + }
10191 + . = ALIGN(16);
10192 +@@ -161,11 +111,6 @@ SECTIONS
10193 + *(.parainstructions)
10194 + __parainstructions_end = .;
10195 + }
10196 +- /* .exit.text is discard at runtime, not link time, to deal with references
10197 +- from .altinstructions and .eh_frame */
10198 +- .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
10199 +- EXIT_TEXT
10200 +- }
10201 + .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
10202 + EXIT_DATA
10203 + }
10204 +@@ -178,18 +123,138 @@ SECTIONS
10205 + }
10206 + #endif
10207 + . = ALIGN(PAGE_SIZE);
10208 +- .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
10209 +- __per_cpu_start = .;
10210 +- *(.data.percpu.page_aligned)
10211 ++ per_cpu_start = .;
10212 ++ .data.percpu (0) : AT(ADDR(.data.percpu) - LOAD_OFFSET + per_cpu_start) {
10213 ++ __per_cpu_start = . + per_cpu_start;
10214 ++ LONG(0)
10215 + *(.data.percpu)
10216 + *(.data.percpu.shared_aligned)
10217 +- __per_cpu_end = .;
10218 +- }
10219 ++ . = ALIGN(PAGE_SIZE);
10220 ++ *(.data.percpu.page_aligned)
10221 ++ __per_cpu_end = . + per_cpu_start;
10222 ++ } :percpu
10223 ++ . += per_cpu_start;
10224 + . = ALIGN(PAGE_SIZE);
10225 + /* freed after init ends here */
10226 +
10227 ++ . = ALIGN(PAGE_SIZE); /* Init code and data */
10228 ++ .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
10229 ++ _sinittext = .;
10230 ++ INIT_TEXT
10231 ++ _einittext = .;
10232 ++ } :inittext
10233 ++
10234 ++ /* .exit.text is discard at runtime, not link time, to deal with references
10235 ++ from .altinstructions and .eh_frame */
10236 ++ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
10237 ++ EXIT_TEXT
10238 ++ }
10239 ++
10240 ++ .filler : AT(ADDR(.filler) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
10241 ++ BYTE(0)
10242 ++ . = ALIGN(2*PMD_SIZE) - 1;
10243 ++ }
10244 ++
10245 ++ /* freed after init ends here */
10246 ++
10247 ++ .text.head : AT(ADDR(.text.head) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
10248 ++ __init_end = . + __KERNEL_TEXT_OFFSET;
10249 ++ KERNEL_TEXT_OFFSET = . + __KERNEL_TEXT_OFFSET;
10250 ++ _text = .; /* Text and read-only data */
10251 ++ *(.text.head)
10252 ++ } :text = 0x9090
10253 ++
10254 ++ /* read-only */
10255 ++ .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
10256 ++ . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
10257 ++ *(.text.page_aligned)
10258 ++ TEXT_TEXT
10259 ++ SCHED_TEXT
10260 ++ LOCK_TEXT
10261 ++ KPROBES_TEXT
10262 ++ *(.fixup)
10263 ++ *(.gnu.warning)
10264 ++ _etext = .; /* End of text section */
10265 ++ } :text = 0x9090
10266 ++
10267 ++ . += __KERNEL_TEXT_OFFSET;
10268 ++
10269 ++ . = ALIGN(4096);
10270 ++ NOTES :rodata :note
10271 ++
10272 ++ . = ALIGN(16); /* Exception table */
10273 ++ __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
10274 ++ __start___ex_table = .;
10275 ++ *(__ex_table)
10276 ++ __stop___ex_table = .;
10277 ++ } :rodata
10278 ++
10279 ++ RO_DATA(PAGE_SIZE)
10280 ++
10281 ++ . = ALIGN(PAGE_SIZE);
10282 ++ .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
10283 ++ *(.idt)
10284 ++ . = ALIGN(PAGE_SIZE);
10285 ++ *(.empty_zero_page)
10286 ++ *(.swapper_pg_pmd)
10287 ++ *(.swapper_pg_dir)
10288 ++
10289 ++#if defined(CONFIG_PAX_KERNEXEC) && !defined(CONFIG_MODULES)
10290 ++ . = ALIGN(PMD_SIZE);
10291 ++#endif
10292 ++
10293 ++ }
10294 ++
10295 ++#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_MODULES)
10296 ++ . = ALIGN(PAGE_SIZE);
10297 ++ .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
10298 ++ MODULES_VADDR = .;
10299 ++ BYTE(0)
10300 ++ . += (6 * 1024 * 1024);
10301 ++ . = ALIGN(PMD_SIZE);
10302 ++ MODULES_END = . - 1;
10303 ++ }
10304 ++#endif
10305 ++
10306 ++ /* writeable */
10307 ++ . = ALIGN(PAGE_SIZE);
10308 ++ .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
10309 ++ _data = .;
10310 ++ DATA_DATA
10311 ++ CONSTRUCTORS
10312 ++ } :data
10313 ++
10314 ++ . = ALIGN(PAGE_SIZE);
10315 ++ .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
10316 ++ __nosave_begin = .;
10317 ++ *(.data.nosave)
10318 ++ . = ALIGN(PAGE_SIZE);
10319 ++ __nosave_end = .;
10320 ++ }
10321 ++
10322 ++ . = ALIGN(PAGE_SIZE);
10323 ++ .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
10324 ++ *(.data.page_aligned)
10325 ++ }
10326 ++
10327 ++ . = ALIGN(32);
10328 ++ .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
10329 ++ *(.data.cacheline_aligned)
10330 ++ }
10331 ++
10332 ++ /* rarely changed data like cpu maps */
10333 ++ . = ALIGN(32);
10334 ++ .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
10335 ++ *(.data.read_mostly)
10336 ++ _edata = .; /* End of data section */
10337 ++ }
10338 ++
10339 ++ . = ALIGN(THREAD_SIZE); /* init_task */
10340 ++ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
10341 ++ *(.data.init_task)
10342 ++ }
10343 ++
10344 + .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
10345 +- __init_end = .;
10346 + __bss_start = .; /* BSS */
10347 + *(.bss.page_aligned)
10348 + *(.bss)
10349 +diff -urNp linux-2.6.28.8/arch/x86/kernel/vmlinux_64.lds.S linux-2.6.28.8/arch/x86/kernel/vmlinux_64.lds.S
10350 +--- linux-2.6.28.8/arch/x86/kernel/vmlinux_64.lds.S 2009-02-06 16:47:45.000000000 -0500
10351 ++++ linux-2.6.28.8/arch/x86/kernel/vmlinux_64.lds.S 2009-02-21 09:37:48.000000000 -0500
10352 +@@ -16,7 +16,7 @@ jiffies_64 = jiffies;
10353 + _proxy_pda = 1;
10354 + PHDRS {
10355 + text PT_LOAD FLAGS(5); /* R_E */
10356 +- data PT_LOAD FLAGS(7); /* RWE */
10357 ++ data PT_LOAD FLAGS(6); /* RW_ */
10358 + user PT_LOAD FLAGS(7); /* RWE */
10359 + data.init PT_LOAD FLAGS(7); /* RWE */
10360 + note PT_NOTE FLAGS(0); /* ___ */
10361 +@@ -49,17 +49,20 @@ SECTIONS
10362 + __stop___ex_table = .;
10363 + } :text = 0x9090
10364 +
10365 +- RODATA
10366 ++ RO_DATA(PAGE_SIZE)
10367 +
10368 ++#ifdef CONFIG_PAX_KERNEXEC
10369 ++ . = ALIGN(2*1024*1024); /* Align data segment to PMD size boundary */
10370 ++#else
10371 + . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */
10372 ++#endif
10373 + /* Data */
10374 ++ _data = .;
10375 + .data : AT(ADDR(.data) - LOAD_OFFSET) {
10376 + DATA_DATA
10377 + CONSTRUCTORS
10378 + } :data
10379 +
10380 +- _edata = .; /* End of data section */
10381 +-
10382 + . = ALIGN(PAGE_SIZE);
10383 + . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
10384 + .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
10385 +@@ -70,9 +73,27 @@ SECTIONS
10386 + *(.data.read_mostly)
10387 + }
10388 +
10389 ++ . = ALIGN(THREAD_SIZE); /* init_task */
10390 ++ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
10391 ++ *(.data.init_task)
10392 ++ }
10393 ++
10394 ++ . = ALIGN(PAGE_SIZE);
10395 ++ .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
10396 ++ *(.data.page_aligned)
10397 ++ }
10398 ++
10399 ++ . = ALIGN(PAGE_SIZE);
10400 ++ __nosave_begin = .;
10401 ++ .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
10402 ++ . = ALIGN(PAGE_SIZE);
10403 ++ __nosave_end = .;
10404 ++
10405 ++ _edata = .; /* End of data section */
10406 ++
10407 + #define VSYSCALL_ADDR (-10*1024*1024)
10408 +-#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
10409 +-#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
10410 ++#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
10411 ++#define VSYSCALL_VIRT_ADDR ((ADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
10412 +
10413 + #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
10414 + #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
10415 +@@ -120,23 +141,13 @@ SECTIONS
10416 + #undef VVIRT_OFFSET
10417 + #undef VVIRT
10418 +
10419 +- . = ALIGN(THREAD_SIZE); /* init_task */
10420 +- .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
10421 +- *(.data.init_task)
10422 +- }:data.init
10423 +-
10424 +- . = ALIGN(PAGE_SIZE);
10425 +- .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
10426 +- *(.data.page_aligned)
10427 +- }
10428 +-
10429 + /* might get freed after init */
10430 + . = ALIGN(PAGE_SIZE);
10431 + __smp_alt_begin = .;
10432 + __smp_locks = .;
10433 + .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
10434 + *(.smp_locks)
10435 +- }
10436 ++ } :data.init
10437 + __smp_locks_end = .;
10438 + . = ALIGN(PAGE_SIZE);
10439 + __smp_alt_end = .;
10440 +@@ -212,16 +223,11 @@ SECTIONS
10441 + . = ALIGN(PAGE_SIZE);
10442 + __init_end = .;
10443 +
10444 +- . = ALIGN(PAGE_SIZE);
10445 +- __nosave_begin = .;
10446 +- .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
10447 +- . = ALIGN(PAGE_SIZE);
10448 +- __nosave_end = .;
10449 +-
10450 + __bss_start = .; /* BSS */
10451 + .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
10452 + *(.bss.page_aligned)
10453 + *(.bss)
10454 ++ . = ALIGN(2*1024*1024);
10455 + }
10456 + __bss_stop = .;
10457 +
10458 +diff -urNp linux-2.6.28.8/arch/x86/kernel/vsyscall_64.c linux-2.6.28.8/arch/x86/kernel/vsyscall_64.c
10459 +--- linux-2.6.28.8/arch/x86/kernel/vsyscall_64.c 2009-02-06 16:47:45.000000000 -0500
10460 ++++ linux-2.6.28.8/arch/x86/kernel/vsyscall_64.c 2009-02-21 09:37:48.000000000 -0500
10461 +@@ -236,13 +236,13 @@ static ctl_table kernel_table2[] = {
10462 + .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int),
10463 + .mode = 0644,
10464 + .proc_handler = vsyscall_sysctl_change },
10465 +- {}
10466 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
10467 + };
10468 +
10469 + static ctl_table kernel_root_table2[] = {
10470 + { .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555,
10471 + .child = kernel_table2 },
10472 +- {}
10473 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
10474 + };
10475 + #endif
10476 +
10477 +diff -urNp linux-2.6.28.8/arch/x86/kvm/svm.c linux-2.6.28.8/arch/x86/kvm/svm.c
10478 +--- linux-2.6.28.8/arch/x86/kvm/svm.c 2009-02-06 16:47:45.000000000 -0500
10479 ++++ linux-2.6.28.8/arch/x86/kvm/svm.c 2009-02-21 09:37:48.000000000 -0500
10480 +@@ -1505,7 +1505,19 @@ static void reload_tss(struct kvm_vcpu *
10481 + int cpu = raw_smp_processor_id();
10482 +
10483 + struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu);
10484 ++
10485 ++#ifdef CONFIG_PAX_KERNEXEC
10486 ++ unsigned long cr0;
10487 ++
10488 ++ pax_open_kernel(cr0);
10489 ++#endif
10490 ++
10491 + svm_data->tss_desc->type = 9; /* available 32/64-bit TSS */
10492 ++
10493 ++#ifdef CONFIG_PAX_KERNEXEC
10494 ++ pax_close_kernel(cr0);
10495 ++#endif
10496 ++
10497 + load_TR_desc();
10498 + }
10499 +
10500 +@@ -1912,7 +1924,7 @@ static int get_npt_level(void)
10501 + #endif
10502 + }
10503 +
10504 +-static struct kvm_x86_ops svm_x86_ops = {
10505 ++static const struct kvm_x86_ops svm_x86_ops = {
10506 + .cpu_has_kvm_support = has_svm,
10507 + .disabled_by_bios = is_disabled,
10508 + .hardware_setup = svm_hardware_setup,
10509 +diff -urNp linux-2.6.28.8/arch/x86/kvm/vmx.c linux-2.6.28.8/arch/x86/kvm/vmx.c
10510 +--- linux-2.6.28.8/arch/x86/kvm/vmx.c 2009-02-06 16:47:45.000000000 -0500
10511 ++++ linux-2.6.28.8/arch/x86/kvm/vmx.c 2009-02-21 09:37:48.000000000 -0500
10512 +@@ -122,7 +122,7 @@ static struct vmcs_config {
10513 + u32 vmentry_ctrl;
10514 + } vmcs_config;
10515 +
10516 +-struct vmx_capability {
10517 ++static struct vmx_capability {
10518 + u32 ept;
10519 + u32 vpid;
10520 + } vmx_capability;
10521 +@@ -491,9 +491,23 @@ static void reload_tss(void)
10522 + struct descriptor_table gdt;
10523 + struct desc_struct *descs;
10524 +
10525 ++#ifdef CONFIG_PAX_KERNEXEC
10526 ++ unsigned long cr0;
10527 ++#endif
10528 ++
10529 + kvm_get_gdt(&gdt);
10530 + descs = (void *)gdt.base;
10531 ++
10532 ++#ifdef CONFIG_PAX_KERNEXEC
10533 ++ pax_open_kernel(cr0);
10534 ++#endif
10535 ++
10536 + descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
10537 ++
10538 ++#ifdef CONFIG_PAX_KERNEXEC
10539 ++ pax_close_kernel(cr0);
10540 ++#endif
10541 ++
10542 + load_TR_desc();
10543 + }
10544 +
10545 +@@ -2164,7 +2178,7 @@ static int vmx_vcpu_setup(struct vcpu_vm
10546 + vmcs_writel(HOST_IDTR_BASE, dt.base); /* 22.2.4 */
10547 +
10548 + asm("mov $.Lkvm_vmx_return, %0" : "=r"(kvm_vmx_return));
10549 +- vmcs_writel(HOST_RIP, kvm_vmx_return); /* 22.2.5 */
10550 ++ vmcs_writel(HOST_RIP, ktla_ktva(kvm_vmx_return)); /* 22.2.5 */
10551 + vmcs_write32(VM_EXIT_MSR_STORE_COUNT, 0);
10552 + vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, 0);
10553 + vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, 0);
10554 +@@ -3267,6 +3281,12 @@ static void vmx_vcpu_run(struct kvm_vcpu
10555 + "jmp .Lkvm_vmx_return \n\t"
10556 + ".Llaunched: " __ex(ASM_VMX_VMRESUME) "\n\t"
10557 + ".Lkvm_vmx_return: "
10558 ++
10559 ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
10560 ++ "ljmp %[cs],$.Lkvm_vmx_return2\n\t"
10561 ++ ".Lkvm_vmx_return2: "
10562 ++#endif
10563 ++
10564 + /* Save guest registers, load host registers, keep flags */
10565 + "xchg %0, (%%"R"sp) \n\t"
10566 + "mov %%"R"ax, %c[rax](%0) \n\t"
10567 +@@ -3313,6 +3333,11 @@ static void vmx_vcpu_run(struct kvm_vcpu
10568 + [r15]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R15])),
10569 + #endif
10570 + [cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2))
10571 ++
10572 ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
10573 ++ ,[cs]"i"(__KERNEL_CS)
10574 ++#endif
10575 ++
10576 + : "cc", "memory"
10577 + , R"bx", R"di", R"si"
10578 + #ifdef CONFIG_X86_64
10579 +@@ -3331,7 +3356,7 @@ static void vmx_vcpu_run(struct kvm_vcpu
10580 + (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
10581 + (GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS)) == 0;
10582 +
10583 +- asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
10584 ++ asm("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS));
10585 + vmx->launched = 1;
10586 +
10587 + intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
10588 +@@ -3455,7 +3480,7 @@ static int get_ept_level(void)
10589 + return VMX_EPT_DEFAULT_GAW + 1;
10590 + }
10591 +
10592 +-static struct kvm_x86_ops vmx_x86_ops = {
10593 ++static const struct kvm_x86_ops vmx_x86_ops = {
10594 + .cpu_has_kvm_support = cpu_has_kvm_support,
10595 + .disabled_by_bios = vmx_disabled_by_bios,
10596 + .hardware_setup = hardware_setup,
10597 +diff -urNp linux-2.6.28.8/arch/x86/kvm/x86.c linux-2.6.28.8/arch/x86/kvm/x86.c
10598 +--- linux-2.6.28.8/arch/x86/kvm/x86.c 2009-02-06 16:47:45.000000000 -0500
10599 ++++ linux-2.6.28.8/arch/x86/kvm/x86.c 2009-02-21 09:37:48.000000000 -0500
10600 +@@ -68,41 +68,41 @@ static u64 __read_mostly efer_reserved_b
10601 + static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
10602 + struct kvm_cpuid_entry2 __user *entries);
10603 +
10604 +-struct kvm_x86_ops *kvm_x86_ops;
10605 ++const struct kvm_x86_ops *kvm_x86_ops;
10606 + EXPORT_SYMBOL_GPL(kvm_x86_ops);
10607 +
10608 + struct kvm_stats_debugfs_item debugfs_entries[] = {
10609 +- { "pf_fixed", VCPU_STAT(pf_fixed) },
10610 +- { "pf_guest", VCPU_STAT(pf_guest) },
10611 +- { "tlb_flush", VCPU_STAT(tlb_flush) },
10612 +- { "invlpg", VCPU_STAT(invlpg) },
10613 +- { "exits", VCPU_STAT(exits) },
10614 +- { "io_exits", VCPU_STAT(io_exits) },
10615 +- { "mmio_exits", VCPU_STAT(mmio_exits) },
10616 +- { "signal_exits", VCPU_STAT(signal_exits) },
10617 +- { "irq_window", VCPU_STAT(irq_window_exits) },
10618 +- { "nmi_window", VCPU_STAT(nmi_window_exits) },
10619 +- { "halt_exits", VCPU_STAT(halt_exits) },
10620 +- { "halt_wakeup", VCPU_STAT(halt_wakeup) },
10621 +- { "hypercalls", VCPU_STAT(hypercalls) },
10622 +- { "request_irq", VCPU_STAT(request_irq_exits) },
10623 +- { "irq_exits", VCPU_STAT(irq_exits) },
10624 +- { "host_state_reload", VCPU_STAT(host_state_reload) },
10625 +- { "efer_reload", VCPU_STAT(efer_reload) },
10626 +- { "fpu_reload", VCPU_STAT(fpu_reload) },
10627 +- { "insn_emulation", VCPU_STAT(insn_emulation) },
10628 +- { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail) },
10629 +- { "irq_injections", VCPU_STAT(irq_injections) },
10630 +- { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped) },
10631 +- { "mmu_pte_write", VM_STAT(mmu_pte_write) },
10632 +- { "mmu_pte_updated", VM_STAT(mmu_pte_updated) },
10633 +- { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped) },
10634 +- { "mmu_flooded", VM_STAT(mmu_flooded) },
10635 +- { "mmu_recycled", VM_STAT(mmu_recycled) },
10636 +- { "mmu_cache_miss", VM_STAT(mmu_cache_miss) },
10637 +- { "mmu_unsync", VM_STAT(mmu_unsync) },
10638 +- { "remote_tlb_flush", VM_STAT(remote_tlb_flush) },
10639 +- { "largepages", VM_STAT(lpages) },
10640 ++ { "pf_fixed", VCPU_STAT(pf_fixed), NULL },
10641 ++ { "pf_guest", VCPU_STAT(pf_guest), NULL },
10642 ++ { "tlb_flush", VCPU_STAT(tlb_flush), NULL },
10643 ++ { "invlpg", VCPU_STAT(invlpg), NULL },
10644 ++ { "exits", VCPU_STAT(exits), NULL },
10645 ++ { "io_exits", VCPU_STAT(io_exits), NULL },
10646 ++ { "mmio_exits", VCPU_STAT(mmio_exits), NULL },
10647 ++ { "signal_exits", VCPU_STAT(signal_exits), NULL },
10648 ++ { "irq_window", VCPU_STAT(irq_window_exits), NULL },
10649 ++ { "nmi_window", VCPU_STAT(nmi_window_exits), NULL },
10650 ++ { "halt_exits", VCPU_STAT(halt_exits), NULL },
10651 ++ { "halt_wakeup", VCPU_STAT(halt_wakeup), NULL },
10652 ++ { "hypercalls", VCPU_STAT(hypercalls), NULL },
10653 ++ { "request_irq", VCPU_STAT(request_irq_exits), NULL },
10654 ++ { "irq_exits", VCPU_STAT(irq_exits), NULL },
10655 ++ { "host_state_reload", VCPU_STAT(host_state_reload), NULL },
10656 ++ { "efer_reload", VCPU_STAT(efer_reload), NULL },
10657 ++ { "fpu_reload", VCPU_STAT(fpu_reload), NULL },
10658 ++ { "insn_emulation", VCPU_STAT(insn_emulation), NULL },
10659 ++ { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail), NULL },
10660 ++ { "irq_injections", VCPU_STAT(irq_injections), NULL },
10661 ++ { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped), NULL },
10662 ++ { "mmu_pte_write", VM_STAT(mmu_pte_write), NULL },
10663 ++ { "mmu_pte_updated", VM_STAT(mmu_pte_updated), NULL },
10664 ++ { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped), NULL },
10665 ++ { "mmu_flooded", VM_STAT(mmu_flooded), NULL },
10666 ++ { "mmu_recycled", VM_STAT(mmu_recycled), NULL },
10667 ++ { "mmu_cache_miss", VM_STAT(mmu_cache_miss), NULL },
10668 ++ { "mmu_unsync", VM_STAT(mmu_unsync), NULL },
10669 ++ { "remote_tlb_flush", VM_STAT(remote_tlb_flush), NULL },
10670 ++ { "largepages", VM_STAT(lpages), NULL },
10671 + { NULL }
10672 + };
10673 +
10674 +@@ -1304,7 +1304,7 @@ static int kvm_vcpu_ioctl_set_lapic(stru
10675 + static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
10676 + struct kvm_interrupt *irq)
10677 + {
10678 +- if (irq->irq < 0 || irq->irq >= 256)
10679 ++ if (irq->irq >= 256)
10680 + return -EINVAL;
10681 + if (irqchip_in_kernel(vcpu->kvm))
10682 + return -ENXIO;
10683 +@@ -2509,10 +2509,10 @@ int kvm_emulate_pio_string(struct kvm_vc
10684 + }
10685 + EXPORT_SYMBOL_GPL(kvm_emulate_pio_string);
10686 +
10687 +-int kvm_arch_init(void *opaque)
10688 ++int kvm_arch_init(const void *opaque)
10689 + {
10690 + int r;
10691 +- struct kvm_x86_ops *ops = (struct kvm_x86_ops *)opaque;
10692 ++ const struct kvm_x86_ops *ops = (const struct kvm_x86_ops *)opaque;
10693 +
10694 + if (kvm_x86_ops) {
10695 + printk(KERN_ERR "kvm: already loaded the other module\n");
10696 +diff -urNp linux-2.6.28.8/arch/x86/lib/checksum_32.S linux-2.6.28.8/arch/x86/lib/checksum_32.S
10697 +--- linux-2.6.28.8/arch/x86/lib/checksum_32.S 2009-02-06 16:47:45.000000000 -0500
10698 ++++ linux-2.6.28.8/arch/x86/lib/checksum_32.S 2009-02-21 09:37:48.000000000 -0500
10699 +@@ -28,7 +28,8 @@
10700 + #include <linux/linkage.h>
10701 + #include <asm/dwarf2.h>
10702 + #include <asm/errno.h>
10703 +-
10704 ++#include <asm/segment.h>
10705 ++
10706 + /*
10707 + * computes a partial checksum, e.g. for TCP/UDP fragments
10708 + */
10709 +@@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic (
10710 +
10711 + #define ARGBASE 16
10712 + #define FP 12
10713 +-
10714 +-ENTRY(csum_partial_copy_generic)
10715 ++
10716 ++ENTRY(csum_partial_copy_generic_to_user)
10717 + CFI_STARTPROC
10718 ++ pushl $(__USER_DS)
10719 ++ CFI_ADJUST_CFA_OFFSET 4
10720 ++ popl %es
10721 ++ CFI_ADJUST_CFA_OFFSET -4
10722 ++ jmp csum_partial_copy_generic
10723 ++
10724 ++ENTRY(csum_partial_copy_generic_from_user)
10725 ++ pushl $(__USER_DS)
10726 ++ CFI_ADJUST_CFA_OFFSET 4
10727 ++ popl %ds
10728 ++ CFI_ADJUST_CFA_OFFSET -4
10729 ++
10730 ++ENTRY(csum_partial_copy_generic)
10731 + subl $4,%esp
10732 + CFI_ADJUST_CFA_OFFSET 4
10733 + pushl %edi
10734 +@@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic)
10735 + jmp 4f
10736 + SRC(1: movw (%esi), %bx )
10737 + addl $2, %esi
10738 +-DST( movw %bx, (%edi) )
10739 ++DST( movw %bx, %es:(%edi) )
10740 + addl $2, %edi
10741 + addw %bx, %ax
10742 + adcl $0, %eax
10743 +@@ -343,30 +357,30 @@ DST( movw %bx, (%edi) )
10744 + SRC(1: movl (%esi), %ebx )
10745 + SRC( movl 4(%esi), %edx )
10746 + adcl %ebx, %eax
10747 +-DST( movl %ebx, (%edi) )
10748 ++DST( movl %ebx, %es:(%edi) )
10749 + adcl %edx, %eax
10750 +-DST( movl %edx, 4(%edi) )
10751 ++DST( movl %edx, %es:4(%edi) )
10752 +
10753 + SRC( movl 8(%esi), %ebx )
10754 + SRC( movl 12(%esi), %edx )
10755 + adcl %ebx, %eax
10756 +-DST( movl %ebx, 8(%edi) )
10757 ++DST( movl %ebx, %es:8(%edi) )
10758 + adcl %edx, %eax
10759 +-DST( movl %edx, 12(%edi) )
10760 ++DST( movl %edx, %es:12(%edi) )
10761 +
10762 + SRC( movl 16(%esi), %ebx )
10763 + SRC( movl 20(%esi), %edx )
10764 + adcl %ebx, %eax
10765 +-DST( movl %ebx, 16(%edi) )
10766 ++DST( movl %ebx, %es:16(%edi) )
10767 + adcl %edx, %eax
10768 +-DST( movl %edx, 20(%edi) )
10769 ++DST( movl %edx, %es:20(%edi) )
10770 +
10771 + SRC( movl 24(%esi), %ebx )
10772 + SRC( movl 28(%esi), %edx )
10773 + adcl %ebx, %eax
10774 +-DST( movl %ebx, 24(%edi) )
10775 ++DST( movl %ebx, %es:24(%edi) )
10776 + adcl %edx, %eax
10777 +-DST( movl %edx, 28(%edi) )
10778 ++DST( movl %edx, %es:28(%edi) )
10779 +
10780 + lea 32(%esi), %esi
10781 + lea 32(%edi), %edi
10782 +@@ -380,7 +394,7 @@ DST( movl %edx, 28(%edi) )
10783 + shrl $2, %edx # This clears CF
10784 + SRC(3: movl (%esi), %ebx )
10785 + adcl %ebx, %eax
10786 +-DST( movl %ebx, (%edi) )
10787 ++DST( movl %ebx, %es:(%edi) )
10788 + lea 4(%esi), %esi
10789 + lea 4(%edi), %edi
10790 + dec %edx
10791 +@@ -392,12 +406,12 @@ DST( movl %ebx, (%edi) )
10792 + jb 5f
10793 + SRC( movw (%esi), %cx )
10794 + leal 2(%esi), %esi
10795 +-DST( movw %cx, (%edi) )
10796 ++DST( movw %cx, %es:(%edi) )
10797 + leal 2(%edi), %edi
10798 + je 6f
10799 + shll $16,%ecx
10800 + SRC(5: movb (%esi), %cl )
10801 +-DST( movb %cl, (%edi) )
10802 ++DST( movb %cl, %es:(%edi) )
10803 + 6: addl %ecx, %eax
10804 + adcl $0, %eax
10805 + 7:
10806 +@@ -408,7 +422,7 @@ DST( movb %cl, (%edi) )
10807 +
10808 + 6001:
10809 + movl ARGBASE+20(%esp), %ebx # src_err_ptr
10810 +- movl $-EFAULT, (%ebx)
10811 ++ movl $-EFAULT, %ss:(%ebx)
10812 +
10813 + # zero the complete destination - computing the rest
10814 + # is too much work
10815 +@@ -421,11 +435,19 @@ DST( movb %cl, (%edi) )
10816 +
10817 + 6002:
10818 + movl ARGBASE+24(%esp), %ebx # dst_err_ptr
10819 +- movl $-EFAULT,(%ebx)
10820 ++ movl $-EFAULT,%ss:(%ebx)
10821 + jmp 5000b
10822 +
10823 + .previous
10824 +
10825 ++ pushl %ss
10826 ++ CFI_ADJUST_CFA_OFFSET 4
10827 ++ popl %ds
10828 ++ CFI_ADJUST_CFA_OFFSET -4
10829 ++ pushl %ss
10830 ++ CFI_ADJUST_CFA_OFFSET 4
10831 ++ popl %es
10832 ++ CFI_ADJUST_CFA_OFFSET -4
10833 + popl %ebx
10834 + CFI_ADJUST_CFA_OFFSET -4
10835 + CFI_RESTORE ebx
10836 +@@ -439,26 +461,41 @@ DST( movb %cl, (%edi) )
10837 + CFI_ADJUST_CFA_OFFSET -4
10838 + ret
10839 + CFI_ENDPROC
10840 +-ENDPROC(csum_partial_copy_generic)
10841 ++ENDPROC(csum_partial_copy_generic_to_user)
10842 +
10843 + #else
10844 +
10845 + /* Version for PentiumII/PPro */
10846 +
10847 + #define ROUND1(x) \
10848 ++ nop; nop; nop; \
10849 + SRC(movl x(%esi), %ebx ) ; \
10850 + addl %ebx, %eax ; \
10851 +- DST(movl %ebx, x(%edi) ) ;
10852 ++ DST(movl %ebx, %es:x(%edi)) ;
10853 +
10854 + #define ROUND(x) \
10855 ++ nop; nop; nop; \
10856 + SRC(movl x(%esi), %ebx ) ; \
10857 + adcl %ebx, %eax ; \
10858 +- DST(movl %ebx, x(%edi) ) ;
10859 ++ DST(movl %ebx, %es:x(%edi)) ;
10860 +
10861 + #define ARGBASE 12
10862 +-
10863 +-ENTRY(csum_partial_copy_generic)
10864 ++
10865 ++ENTRY(csum_partial_copy_generic_to_user)
10866 + CFI_STARTPROC
10867 ++ pushl $(__USER_DS)
10868 ++ CFI_ADJUST_CFA_OFFSET 4
10869 ++ popl %es
10870 ++ CFI_ADJUST_CFA_OFFSET -4
10871 ++ jmp csum_partial_copy_generic
10872 ++
10873 ++ENTRY(csum_partial_copy_generic_from_user)
10874 ++ pushl $(__USER_DS)
10875 ++ CFI_ADJUST_CFA_OFFSET 4
10876 ++ popl %ds
10877 ++ CFI_ADJUST_CFA_OFFSET -4
10878 ++
10879 ++ENTRY(csum_partial_copy_generic)
10880 + pushl %ebx
10881 + CFI_ADJUST_CFA_OFFSET 4
10882 + CFI_REL_OFFSET ebx, 0
10883 +@@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic)
10884 + subl %ebx, %edi
10885 + lea -1(%esi),%edx
10886 + andl $-32,%edx
10887 +- lea 3f(%ebx,%ebx), %ebx
10888 ++ lea 3f(%ebx,%ebx,2), %ebx
10889 + testl %esi, %esi
10890 + jmp *%ebx
10891 + 1: addl $64,%esi
10892 +@@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic)
10893 + jb 5f
10894 + SRC( movw (%esi), %dx )
10895 + leal 2(%esi), %esi
10896 +-DST( movw %dx, (%edi) )
10897 ++DST( movw %dx, %es:(%edi) )
10898 + leal 2(%edi), %edi
10899 + je 6f
10900 + shll $16,%edx
10901 + 5:
10902 + SRC( movb (%esi), %dl )
10903 +-DST( movb %dl, (%edi) )
10904 ++DST( movb %dl, %es:(%edi) )
10905 + 6: addl %edx, %eax
10906 + adcl $0, %eax
10907 + 7:
10908 + .section .fixup, "ax"
10909 + 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
10910 +- movl $-EFAULT, (%ebx)
10911 ++ movl $-EFAULT, %ss:(%ebx)
10912 + # zero the complete destination (computing the rest is too much work)
10913 + movl ARGBASE+8(%esp),%edi # dst
10914 + movl ARGBASE+12(%esp),%ecx # len
10915 +@@ -523,10 +560,18 @@ DST( movb %dl, (%edi) )
10916 + rep; stosb
10917 + jmp 7b
10918 + 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
10919 +- movl $-EFAULT, (%ebx)
10920 ++ movl $-EFAULT, %ss:(%ebx)
10921 + jmp 7b
10922 + .previous
10923 +
10924 ++ pushl %ss
10925 ++ CFI_ADJUST_CFA_OFFSET 4
10926 ++ popl %ds
10927 ++ CFI_ADJUST_CFA_OFFSET -4
10928 ++ pushl %ss
10929 ++ CFI_ADJUST_CFA_OFFSET 4
10930 ++ popl %es
10931 ++ CFI_ADJUST_CFA_OFFSET -4
10932 + popl %esi
10933 + CFI_ADJUST_CFA_OFFSET -4
10934 + CFI_RESTORE esi
10935 +@@ -538,7 +583,7 @@ DST( movb %dl, (%edi) )
10936 + CFI_RESTORE ebx
10937 + ret
10938 + CFI_ENDPROC
10939 +-ENDPROC(csum_partial_copy_generic)
10940 ++ENDPROC(csum_partial_copy_generic_to_user)
10941 +
10942 + #undef ROUND
10943 + #undef ROUND1
10944 +diff -urNp linux-2.6.28.8/arch/x86/lib/clear_page_64.S linux-2.6.28.8/arch/x86/lib/clear_page_64.S
10945 +--- linux-2.6.28.8/arch/x86/lib/clear_page_64.S 2009-02-06 16:47:45.000000000 -0500
10946 ++++ linux-2.6.28.8/arch/x86/lib/clear_page_64.S 2009-02-21 09:37:48.000000000 -0500
10947 +@@ -44,7 +44,7 @@ ENDPROC(clear_page)
10948 +
10949 + #include <asm/cpufeature.h>
10950 +
10951 +- .section .altinstr_replacement,"ax"
10952 ++ .section .altinstr_replacement,"a"
10953 + 1: .byte 0xeb /* jmp <disp8> */
10954 + .byte (clear_page_c - clear_page) - (2f - 1b) /* offset */
10955 + 2:
10956 +diff -urNp linux-2.6.28.8/arch/x86/lib/copy_page_64.S linux-2.6.28.8/arch/x86/lib/copy_page_64.S
10957 +--- linux-2.6.28.8/arch/x86/lib/copy_page_64.S 2009-02-06 16:47:45.000000000 -0500
10958 ++++ linux-2.6.28.8/arch/x86/lib/copy_page_64.S 2009-02-21 09:37:48.000000000 -0500
10959 +@@ -104,7 +104,7 @@ ENDPROC(copy_page)
10960 +
10961 + #include <asm/cpufeature.h>
10962 +
10963 +- .section .altinstr_replacement,"ax"
10964 ++ .section .altinstr_replacement,"a"
10965 + 1: .byte 0xeb /* jmp <disp8> */
10966 + .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */
10967 + 2:
10968 +diff -urNp linux-2.6.28.8/arch/x86/lib/copy_user_64.S linux-2.6.28.8/arch/x86/lib/copy_user_64.S
10969 +--- linux-2.6.28.8/arch/x86/lib/copy_user_64.S 2009-02-06 16:47:45.000000000 -0500
10970 ++++ linux-2.6.28.8/arch/x86/lib/copy_user_64.S 2009-02-21 09:37:48.000000000 -0500
10971 +@@ -21,7 +21,7 @@
10972 + .byte 0xe9 /* 32bit jump */
10973 + .long \orig-1f /* by default jump to orig */
10974 + 1:
10975 +- .section .altinstr_replacement,"ax"
10976 ++ .section .altinstr_replacement,"a"
10977 + 2: .byte 0xe9 /* near jump with 32bit immediate */
10978 + .long \alt-1b /* offset */ /* or alternatively to alt */
10979 + .previous
10980 +@@ -106,6 +106,8 @@ ENDPROC(__copy_from_user_inatomic)
10981 + ENTRY(bad_from_user)
10982 + bad_from_user:
10983 + CFI_STARTPROC
10984 ++ testl %edx,%edx
10985 ++ js bad_to_user
10986 + movl %edx,%ecx
10987 + xorl %eax,%eax
10988 + rep
10989 +diff -urNp linux-2.6.28.8/arch/x86/lib/getuser.S linux-2.6.28.8/arch/x86/lib/getuser.S
10990 +--- linux-2.6.28.8/arch/x86/lib/getuser.S 2009-02-06 16:47:45.000000000 -0500
10991 ++++ linux-2.6.28.8/arch/x86/lib/getuser.S 2009-02-21 09:37:48.000000000 -0500
10992 +@@ -33,6 +33,7 @@
10993 + #include <asm/asm-offsets.h>
10994 + #include <asm/thread_info.h>
10995 + #include <asm/asm.h>
10996 ++#include <asm/segment.h>
10997 +
10998 + .text
10999 + ENTRY(__get_user_1)
11000 +@@ -40,7 +41,19 @@ ENTRY(__get_user_1)
11001 + GET_THREAD_INFO(%_ASM_DX)
11002 + cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
11003 + jae bad_get_user
11004 ++
11005 ++#ifdef CONFIG_X86_32
11006 ++ pushl $(__USER_DS)
11007 ++ popl %ds
11008 ++#endif
11009 ++
11010 + 1: movzb (%_ASM_AX),%edx
11011 ++
11012 ++#ifdef CONFIG_X86_32
11013 ++ pushl %ss
11014 ++ pop %ds
11015 ++#endif
11016 ++
11017 + xor %eax,%eax
11018 + ret
11019 + CFI_ENDPROC
11020 +@@ -53,7 +66,19 @@ ENTRY(__get_user_2)
11021 + GET_THREAD_INFO(%_ASM_DX)
11022 + cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
11023 + jae bad_get_user
11024 ++
11025 ++#ifdef CONFIG_X86_32
11026 ++ pushl $(__USER_DS)
11027 ++ popl %ds
11028 ++#endif
11029 ++
11030 + 2: movzwl -1(%_ASM_AX),%edx
11031 ++
11032 ++#ifdef CONFIG_X86_32
11033 ++ pushl %ss
11034 ++ pop %ds
11035 ++#endif
11036 ++
11037 + xor %eax,%eax
11038 + ret
11039 + CFI_ENDPROC
11040 +@@ -66,7 +91,19 @@ ENTRY(__get_user_4)
11041 + GET_THREAD_INFO(%_ASM_DX)
11042 + cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
11043 + jae bad_get_user
11044 ++
11045 ++#ifdef CONFIG_X86_32
11046 ++ pushl $(__USER_DS)
11047 ++ popl %ds
11048 ++#endif
11049 ++
11050 + 3: mov -3(%_ASM_AX),%edx
11051 ++
11052 ++#ifdef CONFIG_X86_32
11053 ++ pushl %ss
11054 ++ pop %ds
11055 ++#endif
11056 ++
11057 + xor %eax,%eax
11058 + ret
11059 + CFI_ENDPROC
11060 +@@ -89,6 +126,12 @@ ENDPROC(__get_user_8)
11061 +
11062 + bad_get_user:
11063 + CFI_STARTPROC
11064 ++
11065 ++#ifdef CONFIG_X86_32
11066 ++ pushl %ss
11067 ++ pop %ds
11068 ++#endif
11069 ++
11070 + xor %edx,%edx
11071 + mov $(-EFAULT),%_ASM_AX
11072 + ret
11073 +diff -urNp linux-2.6.28.8/arch/x86/lib/memcpy_64.S linux-2.6.28.8/arch/x86/lib/memcpy_64.S
11074 +--- linux-2.6.28.8/arch/x86/lib/memcpy_64.S 2009-02-06 16:47:45.000000000 -0500
11075 ++++ linux-2.6.28.8/arch/x86/lib/memcpy_64.S 2009-02-21 09:37:48.000000000 -0500
11076 +@@ -114,7 +114,7 @@ ENDPROC(__memcpy)
11077 + /* Some CPUs run faster using the string copy instructions.
11078 + It is also a lot simpler. Use this when possible */
11079 +
11080 +- .section .altinstr_replacement,"ax"
11081 ++ .section .altinstr_replacement,"a"
11082 + 1: .byte 0xeb /* jmp <disp8> */
11083 + .byte (memcpy_c - memcpy) - (2f - 1b) /* offset */
11084 + 2:
11085 +diff -urNp linux-2.6.28.8/arch/x86/lib/memset_64.S linux-2.6.28.8/arch/x86/lib/memset_64.S
11086 +--- linux-2.6.28.8/arch/x86/lib/memset_64.S 2009-02-06 16:47:45.000000000 -0500
11087 ++++ linux-2.6.28.8/arch/x86/lib/memset_64.S 2009-02-21 09:37:48.000000000 -0500
11088 +@@ -118,7 +118,7 @@ ENDPROC(__memset)
11089 +
11090 + #include <asm/cpufeature.h>
11091 +
11092 +- .section .altinstr_replacement,"ax"
11093 ++ .section .altinstr_replacement,"a"
11094 + 1: .byte 0xeb /* jmp <disp8> */
11095 + .byte (memset_c - memset) - (2f - 1b) /* offset */
11096 + 2:
11097 +diff -urNp linux-2.6.28.8/arch/x86/lib/mmx_32.c linux-2.6.28.8/arch/x86/lib/mmx_32.c
11098 +--- linux-2.6.28.8/arch/x86/lib/mmx_32.c 2009-02-06 16:47:45.000000000 -0500
11099 ++++ linux-2.6.28.8/arch/x86/lib/mmx_32.c 2009-02-21 09:37:48.000000000 -0500
11100 +@@ -29,6 +29,7 @@ void *_mmx_memcpy(void *to, const void *
11101 + {
11102 + void *p;
11103 + int i;
11104 ++ unsigned long cr0;
11105 +
11106 + if (unlikely(in_interrupt()))
11107 + return __memcpy(to, from, len);
11108 +@@ -39,44 +40,72 @@ void *_mmx_memcpy(void *to, const void *
11109 + kernel_fpu_begin();
11110 +
11111 + __asm__ __volatile__ (
11112 +- "1: prefetch (%0)\n" /* This set is 28 bytes */
11113 +- " prefetch 64(%0)\n"
11114 +- " prefetch 128(%0)\n"
11115 +- " prefetch 192(%0)\n"
11116 +- " prefetch 256(%0)\n"
11117 ++ "1: prefetch (%1)\n" /* This set is 28 bytes */
11118 ++ " prefetch 64(%1)\n"
11119 ++ " prefetch 128(%1)\n"
11120 ++ " prefetch 192(%1)\n"
11121 ++ " prefetch 256(%1)\n"
11122 + "2: \n"
11123 + ".section .fixup, \"ax\"\n"
11124 +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
11125 ++ "3: \n"
11126 ++
11127 ++#ifdef CONFIG_PAX_KERNEXEC
11128 ++ " movl %%cr0, %0\n"
11129 ++ " movl %0, %%eax\n"
11130 ++ " andl $0xFFFEFFFF, %%eax\n"
11131 ++ " movl %%eax, %%cr0\n"
11132 ++#endif
11133 ++
11134 ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
11135 ++
11136 ++#ifdef CONFIG_PAX_KERNEXEC
11137 ++ " movl %0, %%cr0\n"
11138 ++#endif
11139 ++
11140 + " jmp 2b\n"
11141 + ".previous\n"
11142 + _ASM_EXTABLE(1b, 3b)
11143 +- : : "r" (from));
11144 ++ : "=&r" (cr0) : "r" (from) : "ax");
11145 +
11146 + for ( ; i > 5; i--) {
11147 + __asm__ __volatile__ (
11148 +- "1: prefetch 320(%0)\n"
11149 +- "2: movq (%0), %%mm0\n"
11150 +- " movq 8(%0), %%mm1\n"
11151 +- " movq 16(%0), %%mm2\n"
11152 +- " movq 24(%0), %%mm3\n"
11153 +- " movq %%mm0, (%1)\n"
11154 +- " movq %%mm1, 8(%1)\n"
11155 +- " movq %%mm2, 16(%1)\n"
11156 +- " movq %%mm3, 24(%1)\n"
11157 +- " movq 32(%0), %%mm0\n"
11158 +- " movq 40(%0), %%mm1\n"
11159 +- " movq 48(%0), %%mm2\n"
11160 +- " movq 56(%0), %%mm3\n"
11161 +- " movq %%mm0, 32(%1)\n"
11162 +- " movq %%mm1, 40(%1)\n"
11163 +- " movq %%mm2, 48(%1)\n"
11164 +- " movq %%mm3, 56(%1)\n"
11165 ++ "1: prefetch 320(%1)\n"
11166 ++ "2: movq (%1), %%mm0\n"
11167 ++ " movq 8(%1), %%mm1\n"
11168 ++ " movq 16(%1), %%mm2\n"
11169 ++ " movq 24(%1), %%mm3\n"
11170 ++ " movq %%mm0, (%2)\n"
11171 ++ " movq %%mm1, 8(%2)\n"
11172 ++ " movq %%mm2, 16(%2)\n"
11173 ++ " movq %%mm3, 24(%2)\n"
11174 ++ " movq 32(%1), %%mm0\n"
11175 ++ " movq 40(%1), %%mm1\n"
11176 ++ " movq 48(%1), %%mm2\n"
11177 ++ " movq 56(%1), %%mm3\n"
11178 ++ " movq %%mm0, 32(%2)\n"
11179 ++ " movq %%mm1, 40(%2)\n"
11180 ++ " movq %%mm2, 48(%2)\n"
11181 ++ " movq %%mm3, 56(%2)\n"
11182 + ".section .fixup, \"ax\"\n"
11183 +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
11184 ++ "3:\n"
11185 ++
11186 ++#ifdef CONFIG_PAX_KERNEXEC
11187 ++ " movl %%cr0, %0\n"
11188 ++ " movl %0, %%eax\n"
11189 ++ " andl $0xFFFEFFFF, %%eax\n"
11190 ++ " movl %%eax, %%cr0\n"
11191 ++#endif
11192 ++
11193 ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
11194 ++
11195 ++#ifdef CONFIG_PAX_KERNEXEC
11196 ++ " movl %0, %%cr0\n"
11197 ++#endif
11198 ++
11199 + " jmp 2b\n"
11200 + ".previous\n"
11201 + _ASM_EXTABLE(1b, 3b)
11202 +- : : "r" (from), "r" (to) : "memory");
11203 ++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
11204 +
11205 + from += 64;
11206 + to += 64;
11207 +@@ -158,6 +187,7 @@ static void fast_clear_page(void *page)
11208 + static void fast_copy_page(void *to, void *from)
11209 + {
11210 + int i;
11211 ++ unsigned long cr0;
11212 +
11213 + kernel_fpu_begin();
11214 +
11215 +@@ -166,42 +196,70 @@ static void fast_copy_page(void *to, voi
11216 + * but that is for later. -AV
11217 + */
11218 + __asm__ __volatile__(
11219 +- "1: prefetch (%0)\n"
11220 +- " prefetch 64(%0)\n"
11221 +- " prefetch 128(%0)\n"
11222 +- " prefetch 192(%0)\n"
11223 +- " prefetch 256(%0)\n"
11224 ++ "1: prefetch (%1)\n"
11225 ++ " prefetch 64(%1)\n"
11226 ++ " prefetch 128(%1)\n"
11227 ++ " prefetch 192(%1)\n"
11228 ++ " prefetch 256(%1)\n"
11229 + "2: \n"
11230 + ".section .fixup, \"ax\"\n"
11231 +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
11232 ++ "3: \n"
11233 ++
11234 ++#ifdef CONFIG_PAX_KERNEXEC
11235 ++ " movl %%cr0, %0\n"
11236 ++ " movl %0, %%eax\n"
11237 ++ " andl $0xFFFEFFFF, %%eax\n"
11238 ++ " movl %%eax, %%cr0\n"
11239 ++#endif
11240 ++
11241 ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
11242 ++
11243 ++#ifdef CONFIG_PAX_KERNEXEC
11244 ++ " movl %0, %%cr0\n"
11245 ++#endif
11246 ++
11247 + " jmp 2b\n"
11248 + ".previous\n"
11249 +- _ASM_EXTABLE(1b, 3b) : : "r" (from));
11250 ++ _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
11251 +
11252 + for (i = 0; i < (4096-320)/64; i++) {
11253 + __asm__ __volatile__ (
11254 +- "1: prefetch 320(%0)\n"
11255 +- "2: movq (%0), %%mm0\n"
11256 +- " movntq %%mm0, (%1)\n"
11257 +- " movq 8(%0), %%mm1\n"
11258 +- " movntq %%mm1, 8(%1)\n"
11259 +- " movq 16(%0), %%mm2\n"
11260 +- " movntq %%mm2, 16(%1)\n"
11261 +- " movq 24(%0), %%mm3\n"
11262 +- " movntq %%mm3, 24(%1)\n"
11263 +- " movq 32(%0), %%mm4\n"
11264 +- " movntq %%mm4, 32(%1)\n"
11265 +- " movq 40(%0), %%mm5\n"
11266 +- " movntq %%mm5, 40(%1)\n"
11267 +- " movq 48(%0), %%mm6\n"
11268 +- " movntq %%mm6, 48(%1)\n"
11269 +- " movq 56(%0), %%mm7\n"
11270 +- " movntq %%mm7, 56(%1)\n"
11271 ++ "1: prefetch 320(%1)\n"
11272 ++ "2: movq (%1), %%mm0\n"
11273 ++ " movntq %%mm0, (%2)\n"
11274 ++ " movq 8(%1), %%mm1\n"
11275 ++ " movntq %%mm1, 8(%2)\n"
11276 ++ " movq 16(%1), %%mm2\n"
11277 ++ " movntq %%mm2, 16(%2)\n"
11278 ++ " movq 24(%1), %%mm3\n"
11279 ++ " movntq %%mm3, 24(%2)\n"
11280 ++ " movq 32(%1), %%mm4\n"
11281 ++ " movntq %%mm4, 32(%2)\n"
11282 ++ " movq 40(%1), %%mm5\n"
11283 ++ " movntq %%mm5, 40(%2)\n"
11284 ++ " movq 48(%1), %%mm6\n"
11285 ++ " movntq %%mm6, 48(%2)\n"
11286 ++ " movq 56(%1), %%mm7\n"
11287 ++ " movntq %%mm7, 56(%2)\n"
11288 + ".section .fixup, \"ax\"\n"
11289 +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
11290 ++ "3:\n"
11291 ++
11292 ++#ifdef CONFIG_PAX_KERNEXEC
11293 ++ " movl %%cr0, %0\n"
11294 ++ " movl %0, %%eax\n"
11295 ++ " andl $0xFFFEFFFF, %%eax\n"
11296 ++ " movl %%eax, %%cr0\n"
11297 ++#endif
11298 ++
11299 ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
11300 ++
11301 ++#ifdef CONFIG_PAX_KERNEXEC
11302 ++ " movl %0, %%cr0\n"
11303 ++#endif
11304 ++
11305 + " jmp 2b\n"
11306 + ".previous\n"
11307 +- _ASM_EXTABLE(1b, 3b) : : "r" (from), "r" (to) : "memory");
11308 ++ _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
11309 +
11310 + from += 64;
11311 + to += 64;
11312 +@@ -280,47 +338,76 @@ static void fast_clear_page(void *page)
11313 + static void fast_copy_page(void *to, void *from)
11314 + {
11315 + int i;
11316 ++ unsigned long cr0;
11317 +
11318 + kernel_fpu_begin();
11319 +
11320 + __asm__ __volatile__ (
11321 +- "1: prefetch (%0)\n"
11322 +- " prefetch 64(%0)\n"
11323 +- " prefetch 128(%0)\n"
11324 +- " prefetch 192(%0)\n"
11325 +- " prefetch 256(%0)\n"
11326 ++ "1: prefetch (%1)\n"
11327 ++ " prefetch 64(%1)\n"
11328 ++ " prefetch 128(%1)\n"
11329 ++ " prefetch 192(%1)\n"
11330 ++ " prefetch 256(%1)\n"
11331 + "2: \n"
11332 + ".section .fixup, \"ax\"\n"
11333 +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
11334 ++ "3: \n"
11335 ++
11336 ++#ifdef CONFIG_PAX_KERNEXEC
11337 ++ " movl %%cr0, %0\n"
11338 ++ " movl %0, %%eax\n"
11339 ++ " andl $0xFFFEFFFF, %%eax\n"
11340 ++ " movl %%eax, %%cr0\n"
11341 ++#endif
11342 ++
11343 ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
11344 ++
11345 ++#ifdef CONFIG_PAX_KERNEXEC
11346 ++ " movl %0, %%cr0\n"
11347 ++#endif
11348 ++
11349 + " jmp 2b\n"
11350 + ".previous\n"
11351 +- _ASM_EXTABLE(1b, 3b) : : "r" (from));
11352 ++ _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
11353 +
11354 + for (i = 0; i < 4096/64; i++) {
11355 + __asm__ __volatile__ (
11356 +- "1: prefetch 320(%0)\n"
11357 +- "2: movq (%0), %%mm0\n"
11358 +- " movq 8(%0), %%mm1\n"
11359 +- " movq 16(%0), %%mm2\n"
11360 +- " movq 24(%0), %%mm3\n"
11361 +- " movq %%mm0, (%1)\n"
11362 +- " movq %%mm1, 8(%1)\n"
11363 +- " movq %%mm2, 16(%1)\n"
11364 +- " movq %%mm3, 24(%1)\n"
11365 +- " movq 32(%0), %%mm0\n"
11366 +- " movq 40(%0), %%mm1\n"
11367 +- " movq 48(%0), %%mm2\n"
11368 +- " movq 56(%0), %%mm3\n"
11369 +- " movq %%mm0, 32(%1)\n"
11370 +- " movq %%mm1, 40(%1)\n"
11371 +- " movq %%mm2, 48(%1)\n"
11372 +- " movq %%mm3, 56(%1)\n"
11373 ++ "1: prefetch 320(%1)\n"
11374 ++ "2: movq (%1), %%mm0\n"
11375 ++ " movq 8(%1), %%mm1\n"
11376 ++ " movq 16(%1), %%mm2\n"
11377 ++ " movq 24(%1), %%mm3\n"
11378 ++ " movq %%mm0, (%2)\n"
11379 ++ " movq %%mm1, 8(%2)\n"
11380 ++ " movq %%mm2, 16(%2)\n"
11381 ++ " movq %%mm3, 24(%2)\n"
11382 ++ " movq 32(%1), %%mm0\n"
11383 ++ " movq 40(%1), %%mm1\n"
11384 ++ " movq 48(%1), %%mm2\n"
11385 ++ " movq 56(%1), %%mm3\n"
11386 ++ " movq %%mm0, 32(%2)\n"
11387 ++ " movq %%mm1, 40(%2)\n"
11388 ++ " movq %%mm2, 48(%2)\n"
11389 ++ " movq %%mm3, 56(%2)\n"
11390 + ".section .fixup, \"ax\"\n"
11391 +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
11392 ++ "3:\n"
11393 ++
11394 ++#ifdef CONFIG_PAX_KERNEXEC
11395 ++ " movl %%cr0, %0\n"
11396 ++ " movl %0, %%eax\n"
11397 ++ " andl $0xFFFEFFFF, %%eax\n"
11398 ++ " movl %%eax, %%cr0\n"
11399 ++#endif
11400 ++
11401 ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
11402 ++
11403 ++#ifdef CONFIG_PAX_KERNEXEC
11404 ++ " movl %0, %%cr0\n"
11405 ++#endif
11406 ++
11407 + " jmp 2b\n"
11408 + ".previous\n"
11409 + _ASM_EXTABLE(1b, 3b)
11410 +- : : "r" (from), "r" (to) : "memory");
11411 ++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
11412 +
11413 + from += 64;
11414 + to += 64;
11415 +diff -urNp linux-2.6.28.8/arch/x86/lib/putuser.S linux-2.6.28.8/arch/x86/lib/putuser.S
11416 +--- linux-2.6.28.8/arch/x86/lib/putuser.S 2009-02-06 16:47:45.000000000 -0500
11417 ++++ linux-2.6.28.8/arch/x86/lib/putuser.S 2009-02-21 09:37:48.000000000 -0500
11418 +@@ -15,6 +15,7 @@
11419 + #include <asm/thread_info.h>
11420 + #include <asm/errno.h>
11421 + #include <asm/asm.h>
11422 ++#include <asm/segment.h>
11423 +
11424 +
11425 + /*
11426 +@@ -39,7 +40,19 @@ ENTRY(__put_user_1)
11427 + ENTER
11428 + cmp TI_addr_limit(%_ASM_BX),%_ASM_CX
11429 + jae bad_put_user
11430 ++
11431 ++#ifdef CONFIG_X86_32
11432 ++ pushl $(__USER_DS)
11433 ++ popl %ds
11434 ++#endif
11435 ++
11436 + 1: movb %al,(%_ASM_CX)
11437 ++
11438 ++#ifdef CONFIG_X86_32
11439 ++ pushl %ss
11440 ++ popl %ds
11441 ++#endif
11442 ++
11443 + xor %eax,%eax
11444 + EXIT
11445 + ENDPROC(__put_user_1)
11446 +@@ -50,7 +63,19 @@ ENTRY(__put_user_2)
11447 + sub $1,%_ASM_BX
11448 + cmp %_ASM_BX,%_ASM_CX
11449 + jae bad_put_user
11450 ++
11451 ++#ifdef CONFIG_X86_32
11452 ++ pushl $(__USER_DS)
11453 ++ popl %ds
11454 ++#endif
11455 ++
11456 + 2: movw %ax,(%_ASM_CX)
11457 ++
11458 ++#ifdef CONFIG_X86_32
11459 ++ pushl %ss
11460 ++ popl %ds
11461 ++#endif
11462 ++
11463 + xor %eax,%eax
11464 + EXIT
11465 + ENDPROC(__put_user_2)
11466 +@@ -61,7 +86,19 @@ ENTRY(__put_user_4)
11467 + sub $3,%_ASM_BX
11468 + cmp %_ASM_BX,%_ASM_CX
11469 + jae bad_put_user
11470 ++
11471 ++#ifdef CONFIG_X86_32
11472 ++ pushl $(__USER_DS)
11473 ++ popl %ds
11474 ++#endif
11475 ++
11476 + 3: movl %eax,(%_ASM_CX)
11477 ++
11478 ++#ifdef CONFIG_X86_32
11479 ++ pushl %ss
11480 ++ popl %ds
11481 ++#endif
11482 ++
11483 + xor %eax,%eax
11484 + EXIT
11485 + ENDPROC(__put_user_4)
11486 +@@ -72,16 +109,34 @@ ENTRY(__put_user_8)
11487 + sub $7,%_ASM_BX
11488 + cmp %_ASM_BX,%_ASM_CX
11489 + jae bad_put_user
11490 ++
11491 ++#ifdef CONFIG_X86_32
11492 ++ pushl $(__USER_DS)
11493 ++ popl %ds
11494 ++#endif
11495 ++
11496 + 4: mov %_ASM_AX,(%_ASM_CX)
11497 + #ifdef CONFIG_X86_32
11498 + 5: movl %edx,4(%_ASM_CX)
11499 + #endif
11500 ++
11501 ++#ifdef CONFIG_X86_32
11502 ++ pushl %ss
11503 ++ popl %ds
11504 ++#endif
11505 ++
11506 + xor %eax,%eax
11507 + EXIT
11508 + ENDPROC(__put_user_8)
11509 +
11510 + bad_put_user:
11511 + CFI_STARTPROC
11512 ++
11513 ++#ifdef CONFIG_X86_32
11514 ++ pushl %ss
11515 ++ popl %ds
11516 ++#endif
11517 ++
11518 + movl $-EFAULT,%eax
11519 + EXIT
11520 + END(bad_put_user)
11521 +diff -urNp linux-2.6.28.8/arch/x86/lib/usercopy_32.c linux-2.6.28.8/arch/x86/lib/usercopy_32.c
11522 +--- linux-2.6.28.8/arch/x86/lib/usercopy_32.c 2009-02-06 16:47:45.000000000 -0500
11523 ++++ linux-2.6.28.8/arch/x86/lib/usercopy_32.c 2009-02-21 09:39:27.000000000 -0500
11524 +@@ -36,31 +36,38 @@ static inline int __movsl_is_ok(unsigned
11525 + * Copy a null terminated string from userspace.
11526 + */
11527 +
11528 +-#define __do_strncpy_from_user(dst, src, count, res) \
11529 +-do { \
11530 +- int __d0, __d1, __d2; \
11531 +- might_sleep(); \
11532 +- __asm__ __volatile__( \
11533 +- " testl %1,%1\n" \
11534 +- " jz 2f\n" \
11535 +- "0: lodsb\n" \
11536 +- " stosb\n" \
11537 +- " testb %%al,%%al\n" \
11538 +- " jz 1f\n" \
11539 +- " decl %1\n" \
11540 +- " jnz 0b\n" \
11541 +- "1: subl %1,%0\n" \
11542 +- "2:\n" \
11543 +- ".section .fixup,\"ax\"\n" \
11544 +- "3: movl %5,%0\n" \
11545 +- " jmp 2b\n" \
11546 +- ".previous\n" \
11547 +- _ASM_EXTABLE(0b,3b) \
11548 +- : "=&d"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1), \
11549 +- "=&D" (__d2) \
11550 +- : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
11551 +- : "memory"); \
11552 +-} while (0)
11553 ++static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
11554 ++{
11555 ++ int __d0, __d1, __d2;
11556 ++ long res = -EFAULT;
11557 ++
11558 ++ might_sleep();
11559 ++ __asm__ __volatile__(
11560 ++ " movw %w10,%%ds\n"
11561 ++ " testl %1,%1\n"
11562 ++ " jz 2f\n"
11563 ++ "0: lodsb\n"
11564 ++ " stosb\n"
11565 ++ " testb %%al,%%al\n"
11566 ++ " jz 1f\n"
11567 ++ " decl %1\n"
11568 ++ " jnz 0b\n"
11569 ++ "1: subl %1,%0\n"
11570 ++ "2:\n"
11571 ++ " pushl %%ss\n"
11572 ++ " popl %%ds\n"
11573 ++ ".section .fixup,\"ax\"\n"
11574 ++ "3: movl %5,%0\n"
11575 ++ " jmp 2b\n"
11576 ++ ".previous\n"
11577 ++ _ASM_EXTABLE(0b,3b)
11578 ++ : "=&d"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1),
11579 ++ "=&D" (__d2)
11580 ++ : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
11581 ++ "r"(__USER_DS)
11582 ++ : "memory");
11583 ++ return res;
11584 ++}
11585 +
11586 + /**
11587 + * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
11588 +@@ -85,9 +92,7 @@ do { \
11589 + long
11590 + __strncpy_from_user(char *dst, const char __user *src, long count)
11591 + {
11592 +- long res;
11593 +- __do_strncpy_from_user(dst, src, count, res);
11594 +- return res;
11595 ++ return __do_strncpy_from_user(dst, src, count);
11596 + }
11597 + EXPORT_SYMBOL(__strncpy_from_user);
11598 +
11599 +@@ -114,7 +119,7 @@ strncpy_from_user(char *dst, const char
11600 + {
11601 + long res = -EFAULT;
11602 + if (access_ok(VERIFY_READ, src, 1))
11603 +- __do_strncpy_from_user(dst, src, count, res);
11604 ++ res = __do_strncpy_from_user(dst, src, count);
11605 + return res;
11606 + }
11607 + EXPORT_SYMBOL(strncpy_from_user);
11608 +@@ -123,24 +128,30 @@ EXPORT_SYMBOL(strncpy_from_user);
11609 + * Zero Userspace
11610 + */
11611 +
11612 +-#define __do_clear_user(addr,size) \
11613 +-do { \
11614 +- int __d0; \
11615 +- might_sleep(); \
11616 +- __asm__ __volatile__( \
11617 +- "0: rep; stosl\n" \
11618 +- " movl %2,%0\n" \
11619 +- "1: rep; stosb\n" \
11620 +- "2:\n" \
11621 +- ".section .fixup,\"ax\"\n" \
11622 +- "3: lea 0(%2,%0,4),%0\n" \
11623 +- " jmp 2b\n" \
11624 +- ".previous\n" \
11625 +- _ASM_EXTABLE(0b,3b) \
11626 +- _ASM_EXTABLE(1b,2b) \
11627 +- : "=&c"(size), "=&D" (__d0) \
11628 +- : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
11629 +-} while (0)
11630 ++static unsigned long __do_clear_user(void __user *addr, unsigned long size)
11631 ++{
11632 ++ int __d0;
11633 ++
11634 ++ might_sleep();
11635 ++ __asm__ __volatile__(
11636 ++ " movw %w6,%%es\n"
11637 ++ "0: rep; stosl\n"
11638 ++ " movl %2,%0\n"
11639 ++ "1: rep; stosb\n"
11640 ++ "2:\n"
11641 ++ " pushl %%ss\n"
11642 ++ " popl %%es\n"
11643 ++ ".section .fixup,\"ax\"\n"
11644 ++ "3: lea 0(%2,%0,4),%0\n"
11645 ++ " jmp 2b\n"
11646 ++ ".previous\n"
11647 ++ _ASM_EXTABLE(0b,3b)
11648 ++ _ASM_EXTABLE(1b,2b)
11649 ++ : "=&c"(size), "=&D" (__d0)
11650 ++ : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
11651 ++ "r"(__USER_DS));
11652 ++ return size;
11653 ++}
11654 +
11655 + /**
11656 + * clear_user: - Zero a block of memory in user space.
11657 +@@ -157,7 +168,7 @@ clear_user(void __user *to, unsigned lon
11658 + {
11659 + might_sleep();
11660 + if (access_ok(VERIFY_WRITE, to, n))
11661 +- __do_clear_user(to, n);
11662 ++ n = __do_clear_user(to, n);
11663 + return n;
11664 + }
11665 + EXPORT_SYMBOL(clear_user);
11666 +@@ -176,8 +187,7 @@ EXPORT_SYMBOL(clear_user);
11667 + unsigned long
11668 + __clear_user(void __user *to, unsigned long n)
11669 + {
11670 +- __do_clear_user(to, n);
11671 +- return n;
11672 ++ return __do_clear_user(to, n);
11673 + }
11674 + EXPORT_SYMBOL(__clear_user);
11675 +
11676 +@@ -200,14 +210,17 @@ long strnlen_user(const char __user *s,
11677 + might_sleep();
11678 +
11679 + __asm__ __volatile__(
11680 ++ " movw %w8,%%es\n"
11681 + " testl %0, %0\n"
11682 + " jz 3f\n"
11683 +- " andl %0,%%ecx\n"
11684 ++ " movl %0,%%ecx\n"
11685 + "0: repne; scasb\n"
11686 + " setne %%al\n"
11687 + " subl %%ecx,%0\n"
11688 + " addl %0,%%eax\n"
11689 + "1:\n"
11690 ++ " pushl %%ss\n"
11691 ++ " popl %%es\n"
11692 + ".section .fixup,\"ax\"\n"
11693 + "2: xorl %%eax,%%eax\n"
11694 + " jmp 1b\n"
11695 +@@ -219,7 +232,7 @@ long strnlen_user(const char __user *s,
11696 + " .long 0b,2b\n"
11697 + ".previous"
11698 + :"=&r" (n), "=&D" (s), "=&a" (res), "=&c" (tmp)
11699 +- :"0" (n), "1" (s), "2" (0), "3" (mask)
11700 ++ :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
11701 + :"cc");
11702 + return res & mask;
11703 + }
11704 +@@ -227,10 +240,11 @@ EXPORT_SYMBOL(strnlen_user);
11705 +
11706 + #ifdef CONFIG_X86_INTEL_USERCOPY
11707 + static unsigned long
11708 +-__copy_user_intel(void __user *to, const void *from, unsigned long size)
11709 ++__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
11710 + {
11711 + int d0, d1;
11712 + __asm__ __volatile__(
11713 ++ " movw %w6, %%es\n"
11714 + " .align 2,0x90\n"
11715 + "1: movl 32(%4), %%eax\n"
11716 + " cmpl $67, %0\n"
11717 +@@ -239,36 +253,36 @@ __copy_user_intel(void __user *to, const
11718 + " .align 2,0x90\n"
11719 + "3: movl 0(%4), %%eax\n"
11720 + "4: movl 4(%4), %%edx\n"
11721 +- "5: movl %%eax, 0(%3)\n"
11722 +- "6: movl %%edx, 4(%3)\n"
11723 ++ "5: movl %%eax, %%es:0(%3)\n"
11724 ++ "6: movl %%edx, %%es:4(%3)\n"
11725 + "7: movl 8(%4), %%eax\n"
11726 + "8: movl 12(%4),%%edx\n"
11727 +- "9: movl %%eax, 8(%3)\n"
11728 +- "10: movl %%edx, 12(%3)\n"
11729 ++ "9: movl %%eax, %%es:8(%3)\n"
11730 ++ "10: movl %%edx, %%es:12(%3)\n"
11731 + "11: movl 16(%4), %%eax\n"
11732 + "12: movl 20(%4), %%edx\n"
11733 +- "13: movl %%eax, 16(%3)\n"
11734 +- "14: movl %%edx, 20(%3)\n"
11735 ++ "13: movl %%eax, %%es:16(%3)\n"
11736 ++ "14: movl %%edx, %%es:20(%3)\n"
11737 + "15: movl 24(%4), %%eax\n"
11738 + "16: movl 28(%4), %%edx\n"
11739 +- "17: movl %%eax, 24(%3)\n"
11740 +- "18: movl %%edx, 28(%3)\n"
11741 ++ "17: movl %%eax, %%es:24(%3)\n"
11742 ++ "18: movl %%edx, %%es:28(%3)\n"
11743 + "19: movl 32(%4), %%eax\n"
11744 + "20: movl 36(%4), %%edx\n"
11745 +- "21: movl %%eax, 32(%3)\n"
11746 +- "22: movl %%edx, 36(%3)\n"
11747 ++ "21: movl %%eax, %%es:32(%3)\n"
11748 ++ "22: movl %%edx, %%es:36(%3)\n"
11749 + "23: movl 40(%4), %%eax\n"
11750 + "24: movl 44(%4), %%edx\n"
11751 +- "25: movl %%eax, 40(%3)\n"
11752 +- "26: movl %%edx, 44(%3)\n"
11753 ++ "25: movl %%eax, %%es:40(%3)\n"
11754 ++ "26: movl %%edx, %%es:44(%3)\n"
11755 + "27: movl 48(%4), %%eax\n"
11756 + "28: movl 52(%4), %%edx\n"
11757 +- "29: movl %%eax, 48(%3)\n"
11758 +- "30: movl %%edx, 52(%3)\n"
11759 ++ "29: movl %%eax, %%es:48(%3)\n"
11760 ++ "30: movl %%edx, %%es:52(%3)\n"
11761 + "31: movl 56(%4), %%eax\n"
11762 + "32: movl 60(%4), %%edx\n"
11763 +- "33: movl %%eax, 56(%3)\n"
11764 +- "34: movl %%edx, 60(%3)\n"
11765 ++ "33: movl %%eax, %%es:56(%3)\n"
11766 ++ "34: movl %%edx, %%es:60(%3)\n"
11767 + " addl $-64, %0\n"
11768 + " addl $64, %4\n"
11769 + " addl $64, %3\n"
11770 +@@ -282,6 +296,8 @@ __copy_user_intel(void __user *to, const
11771 + "36: movl %%eax, %0\n"
11772 + "37: rep; movsb\n"
11773 + "100:\n"
11774 ++ " pushl %%ss\n"
11775 ++ " popl %%es\n"
11776 + ".section .fixup,\"ax\"\n"
11777 + "101: lea 0(%%eax,%0,4),%0\n"
11778 + " jmp 100b\n"
11779 +@@ -328,7 +344,117 @@ __copy_user_intel(void __user *to, const
11780 + " .long 99b,101b\n"
11781 + ".previous"
11782 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
11783 +- : "1"(to), "2"(from), "0"(size)
11784 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
11785 ++ : "eax", "edx", "memory");
11786 ++ return size;
11787 ++}
11788 ++
11789 ++static unsigned long
11790 ++__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
11791 ++{
11792 ++ int d0, d1;
11793 ++ __asm__ __volatile__(
11794 ++ " movw %w6, %%ds\n"
11795 ++ " .align 2,0x90\n"
11796 ++ "1: movl 32(%4), %%eax\n"
11797 ++ " cmpl $67, %0\n"
11798 ++ " jbe 3f\n"
11799 ++ "2: movl 64(%4), %%eax\n"
11800 ++ " .align 2,0x90\n"
11801 ++ "3: movl 0(%4), %%eax\n"
11802 ++ "4: movl 4(%4), %%edx\n"
11803 ++ "5: movl %%eax, %%es:0(%3)\n"
11804 ++ "6: movl %%edx, %%es:4(%3)\n"
11805 ++ "7: movl 8(%4), %%eax\n"
11806 ++ "8: movl 12(%4),%%edx\n"
11807 ++ "9: movl %%eax, %%es:8(%3)\n"
11808 ++ "10: movl %%edx, %%es:12(%3)\n"
11809 ++ "11: movl 16(%4), %%eax\n"
11810 ++ "12: movl 20(%4), %%edx\n"
11811 ++ "13: movl %%eax, %%es:16(%3)\n"
11812 ++ "14: movl %%edx, %%es:20(%3)\n"
11813 ++ "15: movl 24(%4), %%eax\n"
11814 ++ "16: movl 28(%4), %%edx\n"
11815 ++ "17: movl %%eax, %%es:24(%3)\n"
11816 ++ "18: movl %%edx, %%es:28(%3)\n"
11817 ++ "19: movl 32(%4), %%eax\n"
11818 ++ "20: movl 36(%4), %%edx\n"
11819 ++ "21: movl %%eax, %%es:32(%3)\n"
11820 ++ "22: movl %%edx, %%es:36(%3)\n"
11821 ++ "23: movl 40(%4), %%eax\n"
11822 ++ "24: movl 44(%4), %%edx\n"
11823 ++ "25: movl %%eax, %%es:40(%3)\n"
11824 ++ "26: movl %%edx, %%es:44(%3)\n"
11825 ++ "27: movl 48(%4), %%eax\n"
11826 ++ "28: movl 52(%4), %%edx\n"
11827 ++ "29: movl %%eax, %%es:48(%3)\n"
11828 ++ "30: movl %%edx, %%es:52(%3)\n"
11829 ++ "31: movl 56(%4), %%eax\n"
11830 ++ "32: movl 60(%4), %%edx\n"
11831 ++ "33: movl %%eax, %%es:56(%3)\n"
11832 ++ "34: movl %%edx, %%es:60(%3)\n"
11833 ++ " addl $-64, %0\n"
11834 ++ " addl $64, %4\n"
11835 ++ " addl $64, %3\n"
11836 ++ " cmpl $63, %0\n"
11837 ++ " ja 1b\n"
11838 ++ "35: movl %0, %%eax\n"
11839 ++ " shrl $2, %0\n"
11840 ++ " andl $3, %%eax\n"
11841 ++ " cld\n"
11842 ++ "99: rep; movsl\n"
11843 ++ "36: movl %%eax, %0\n"
11844 ++ "37: rep; movsb\n"
11845 ++ "100:\n"
11846 ++ " pushl %%ss\n"
11847 ++ " popl %%ds\n"
11848 ++ ".section .fixup,\"ax\"\n"
11849 ++ "101: lea 0(%%eax,%0,4),%0\n"
11850 ++ " jmp 100b\n"
11851 ++ ".previous\n"
11852 ++ ".section __ex_table,\"a\"\n"
11853 ++ " .align 4\n"
11854 ++ " .long 1b,100b\n"
11855 ++ " .long 2b,100b\n"
11856 ++ " .long 3b,100b\n"
11857 ++ " .long 4b,100b\n"
11858 ++ " .long 5b,100b\n"
11859 ++ " .long 6b,100b\n"
11860 ++ " .long 7b,100b\n"
11861 ++ " .long 8b,100b\n"
11862 ++ " .long 9b,100b\n"
11863 ++ " .long 10b,100b\n"
11864 ++ " .long 11b,100b\n"
11865 ++ " .long 12b,100b\n"
11866 ++ " .long 13b,100b\n"
11867 ++ " .long 14b,100b\n"
11868 ++ " .long 15b,100b\n"
11869 ++ " .long 16b,100b\n"
11870 ++ " .long 17b,100b\n"
11871 ++ " .long 18b,100b\n"
11872 ++ " .long 19b,100b\n"
11873 ++ " .long 20b,100b\n"
11874 ++ " .long 21b,100b\n"
11875 ++ " .long 22b,100b\n"
11876 ++ " .long 23b,100b\n"
11877 ++ " .long 24b,100b\n"
11878 ++ " .long 25b,100b\n"
11879 ++ " .long 26b,100b\n"
11880 ++ " .long 27b,100b\n"
11881 ++ " .long 28b,100b\n"
11882 ++ " .long 29b,100b\n"
11883 ++ " .long 30b,100b\n"
11884 ++ " .long 31b,100b\n"
11885 ++ " .long 32b,100b\n"
11886 ++ " .long 33b,100b\n"
11887 ++ " .long 34b,100b\n"
11888 ++ " .long 35b,100b\n"
11889 ++ " .long 36b,100b\n"
11890 ++ " .long 37b,100b\n"
11891 ++ " .long 99b,101b\n"
11892 ++ ".previous"
11893 ++ : "=&c"(size), "=&D" (d0), "=&S" (d1)
11894 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
11895 + : "eax", "edx", "memory");
11896 + return size;
11897 + }
11898 +@@ -338,6 +464,7 @@ __copy_user_zeroing_intel(void *to, cons
11899 + {
11900 + int d0, d1;
11901 + __asm__ __volatile__(
11902 ++ " movw %w6, %%ds\n"
11903 + " .align 2,0x90\n"
11904 + "0: movl 32(%4), %%eax\n"
11905 + " cmpl $67, %0\n"
11906 +@@ -346,36 +473,36 @@ __copy_user_zeroing_intel(void *to, cons
11907 + " .align 2,0x90\n"
11908 + "2: movl 0(%4), %%eax\n"
11909 + "21: movl 4(%4), %%edx\n"
11910 +- " movl %%eax, 0(%3)\n"
11911 +- " movl %%edx, 4(%3)\n"
11912 ++ " movl %%eax, %%es:0(%3)\n"
11913 ++ " movl %%edx, %%es:4(%3)\n"
11914 + "3: movl 8(%4), %%eax\n"
11915 + "31: movl 12(%4),%%edx\n"
11916 +- " movl %%eax, 8(%3)\n"
11917 +- " movl %%edx, 12(%3)\n"
11918 ++ " movl %%eax, %%es:8(%3)\n"
11919 ++ " movl %%edx, %%es:12(%3)\n"
11920 + "4: movl 16(%4), %%eax\n"
11921 + "41: movl 20(%4), %%edx\n"
11922 +- " movl %%eax, 16(%3)\n"
11923 +- " movl %%edx, 20(%3)\n"
11924 ++ " movl %%eax, %%es:16(%3)\n"
11925 ++ " movl %%edx, %%es:20(%3)\n"
11926 + "10: movl 24(%4), %%eax\n"
11927 + "51: movl 28(%4), %%edx\n"
11928 +- " movl %%eax, 24(%3)\n"
11929 +- " movl %%edx, 28(%3)\n"
11930 ++ " movl %%eax, %%es:24(%3)\n"
11931 ++ " movl %%edx, %%es:28(%3)\n"
11932 + "11: movl 32(%4), %%eax\n"
11933 + "61: movl 36(%4), %%edx\n"
11934 +- " movl %%eax, 32(%3)\n"
11935 +- " movl %%edx, 36(%3)\n"
11936 ++ " movl %%eax, %%es:32(%3)\n"
11937 ++ " movl %%edx, %%es:36(%3)\n"
11938 + "12: movl 40(%4), %%eax\n"
11939 + "71: movl 44(%4), %%edx\n"
11940 +- " movl %%eax, 40(%3)\n"
11941 +- " movl %%edx, 44(%3)\n"
11942 ++ " movl %%eax, %%es:40(%3)\n"
11943 ++ " movl %%edx, %%es:44(%3)\n"
11944 + "13: movl 48(%4), %%eax\n"
11945 + "81: movl 52(%4), %%edx\n"
11946 +- " movl %%eax, 48(%3)\n"
11947 +- " movl %%edx, 52(%3)\n"
11948 ++ " movl %%eax, %%es:48(%3)\n"
11949 ++ " movl %%edx, %%es:52(%3)\n"
11950 + "14: movl 56(%4), %%eax\n"
11951 + "91: movl 60(%4), %%edx\n"
11952 +- " movl %%eax, 56(%3)\n"
11953 +- " movl %%edx, 60(%3)\n"
11954 ++ " movl %%eax, %%es:56(%3)\n"
11955 ++ " movl %%edx, %%es:60(%3)\n"
11956 + " addl $-64, %0\n"
11957 + " addl $64, %4\n"
11958 + " addl $64, %3\n"
11959 +@@ -389,6 +516,8 @@ __copy_user_zeroing_intel(void *to, cons
11960 + " movl %%eax,%0\n"
11961 + "7: rep; movsb\n"
11962 + "8:\n"
11963 ++ " pushl %%ss\n"
11964 ++ " popl %%ds\n"
11965 + ".section .fixup,\"ax\"\n"
11966 + "9: lea 0(%%eax,%0,4),%0\n"
11967 + "16: pushl %0\n"
11968 +@@ -423,7 +552,7 @@ __copy_user_zeroing_intel(void *to, cons
11969 + " .long 7b,16b\n"
11970 + ".previous"
11971 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
11972 +- : "1"(to), "2"(from), "0"(size)
11973 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
11974 + : "eax", "edx", "memory");
11975 + return size;
11976 + }
11977 +@@ -439,6 +568,7 @@ static unsigned long __copy_user_zeroing
11978 + int d0, d1;
11979 +
11980 + __asm__ __volatile__(
11981 ++ " movw %w6, %%ds\n"
11982 + " .align 2,0x90\n"
11983 + "0: movl 32(%4), %%eax\n"
11984 + " cmpl $67, %0\n"
11985 +@@ -447,36 +577,36 @@ static unsigned long __copy_user_zeroing
11986 + " .align 2,0x90\n"
11987 + "2: movl 0(%4), %%eax\n"
11988 + "21: movl 4(%4), %%edx\n"
11989 +- " movnti %%eax, 0(%3)\n"
11990 +- " movnti %%edx, 4(%3)\n"
11991 ++ " movnti %%eax, %%es:0(%3)\n"
11992 ++ " movnti %%edx, %%es:4(%3)\n"
11993 + "3: movl 8(%4), %%eax\n"
11994 + "31: movl 12(%4),%%edx\n"
11995 +- " movnti %%eax, 8(%3)\n"
11996 +- " movnti %%edx, 12(%3)\n"
11997 ++ " movnti %%eax, %%es:8(%3)\n"
11998 ++ " movnti %%edx, %%es:12(%3)\n"
11999 + "4: movl 16(%4), %%eax\n"
12000 + "41: movl 20(%4), %%edx\n"
12001 +- " movnti %%eax, 16(%3)\n"
12002 +- " movnti %%edx, 20(%3)\n"
12003 ++ " movnti %%eax, %%es:16(%3)\n"
12004 ++ " movnti %%edx, %%es:20(%3)\n"
12005 + "10: movl 24(%4), %%eax\n"
12006 + "51: movl 28(%4), %%edx\n"
12007 +- " movnti %%eax, 24(%3)\n"
12008 +- " movnti %%edx, 28(%3)\n"
12009 ++ " movnti %%eax, %%es:24(%3)\n"
12010 ++ " movnti %%edx, %%es:28(%3)\n"
12011 + "11: movl 32(%4), %%eax\n"
12012 + "61: movl 36(%4), %%edx\n"
12013 +- " movnti %%eax, 32(%3)\n"
12014 +- " movnti %%edx, 36(%3)\n"
12015 ++ " movnti %%eax, %%es:32(%3)\n"
12016 ++ " movnti %%edx, %%es:36(%3)\n"
12017 + "12: movl 40(%4), %%eax\n"
12018 + "71: movl 44(%4), %%edx\n"
12019 +- " movnti %%eax, 40(%3)\n"
12020 +- " movnti %%edx, 44(%3)\n"
12021 ++ " movnti %%eax, %%es:40(%3)\n"
12022 ++ " movnti %%edx, %%es:44(%3)\n"
12023 + "13: movl 48(%4), %%eax\n"
12024 + "81: movl 52(%4), %%edx\n"
12025 +- " movnti %%eax, 48(%3)\n"
12026 +- " movnti %%edx, 52(%3)\n"
12027 ++ " movnti %%eax, %%es:48(%3)\n"
12028 ++ " movnti %%edx, %%es:52(%3)\n"
12029 + "14: movl 56(%4), %%eax\n"
12030 + "91: movl 60(%4), %%edx\n"
12031 +- " movnti %%eax, 56(%3)\n"
12032 +- " movnti %%edx, 60(%3)\n"
12033 ++ " movnti %%eax, %%es:56(%3)\n"
12034 ++ " movnti %%edx, %%es:60(%3)\n"
12035 + " addl $-64, %0\n"
12036 + " addl $64, %4\n"
12037 + " addl $64, %3\n"
12038 +@@ -491,6 +621,8 @@ static unsigned long __copy_user_zeroing
12039 + " movl %%eax,%0\n"
12040 + "7: rep; movsb\n"
12041 + "8:\n"
12042 ++ " pushl %%ss\n"
12043 ++ " popl %%ds\n"
12044 + ".section .fixup,\"ax\"\n"
12045 + "9: lea 0(%%eax,%0,4),%0\n"
12046 + "16: pushl %0\n"
12047 +@@ -525,7 +657,7 @@ static unsigned long __copy_user_zeroing
12048 + " .long 7b,16b\n"
12049 + ".previous"
12050 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
12051 +- : "1"(to), "2"(from), "0"(size)
12052 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
12053 + : "eax", "edx", "memory");
12054 + return size;
12055 + }
12056 +@@ -536,6 +668,7 @@ static unsigned long __copy_user_intel_n
12057 + int d0, d1;
12058 +
12059 + __asm__ __volatile__(
12060 ++ " movw %w6, %%ds\n"
12061 + " .align 2,0x90\n"
12062 + "0: movl 32(%4), %%eax\n"
12063 + " cmpl $67, %0\n"
12064 +@@ -544,36 +677,36 @@ static unsigned long __copy_user_intel_n
12065 + " .align 2,0x90\n"
12066 + "2: movl 0(%4), %%eax\n"
12067 + "21: movl 4(%4), %%edx\n"
12068 +- " movnti %%eax, 0(%3)\n"
12069 +- " movnti %%edx, 4(%3)\n"
12070 ++ " movnti %%eax, %%es:0(%3)\n"
12071 ++ " movnti %%edx, %%es:4(%3)\n"
12072 + "3: movl 8(%4), %%eax\n"
12073 + "31: movl 12(%4),%%edx\n"
12074 +- " movnti %%eax, 8(%3)\n"
12075 +- " movnti %%edx, 12(%3)\n"
12076 ++ " movnti %%eax, %%es:8(%3)\n"
12077 ++ " movnti %%edx, %%es:12(%3)\n"
12078 + "4: movl 16(%4), %%eax\n"
12079 + "41: movl 20(%4), %%edx\n"
12080 +- " movnti %%eax, 16(%3)\n"
12081 +- " movnti %%edx, 20(%3)\n"
12082 ++ " movnti %%eax, %%es:16(%3)\n"
12083 ++ " movnti %%edx, %%es:20(%3)\n"
12084 + "10: movl 24(%4), %%eax\n"
12085 + "51: movl 28(%4), %%edx\n"
12086 +- " movnti %%eax, 24(%3)\n"
12087 +- " movnti %%edx, 28(%3)\n"
12088 ++ " movnti %%eax, %%es:24(%3)\n"
12089 ++ " movnti %%edx, %%es:28(%3)\n"
12090 + "11: movl 32(%4), %%eax\n"
12091 + "61: movl 36(%4), %%edx\n"
12092 +- " movnti %%eax, 32(%3)\n"
12093 +- " movnti %%edx, 36(%3)\n"
12094 ++ " movnti %%eax, %%es:32(%3)\n"
12095 ++ " movnti %%edx, %%es:36(%3)\n"
12096 + "12: movl 40(%4), %%eax\n"
12097 + "71: movl 44(%4), %%edx\n"
12098 +- " movnti %%eax, 40(%3)\n"
12099 +- " movnti %%edx, 44(%3)\n"
12100 ++ " movnti %%eax, %%es:40(%3)\n"
12101 ++ " movnti %%edx, %%es:44(%3)\n"
12102 + "13: movl 48(%4), %%eax\n"
12103 + "81: movl 52(%4), %%edx\n"
12104 +- " movnti %%eax, 48(%3)\n"
12105 +- " movnti %%edx, 52(%3)\n"
12106 ++ " movnti %%eax, %%es:48(%3)\n"
12107 ++ " movnti %%edx, %%es:52(%3)\n"
12108 + "14: movl 56(%4), %%eax\n"
12109 + "91: movl 60(%4), %%edx\n"
12110 +- " movnti %%eax, 56(%3)\n"
12111 +- " movnti %%edx, 60(%3)\n"
12112 ++ " movnti %%eax, %%es:56(%3)\n"
12113 ++ " movnti %%edx, %%es:60(%3)\n"
12114 + " addl $-64, %0\n"
12115 + " addl $64, %4\n"
12116 + " addl $64, %3\n"
12117 +@@ -588,6 +721,8 @@ static unsigned long __copy_user_intel_n
12118 + " movl %%eax,%0\n"
12119 + "7: rep; movsb\n"
12120 + "8:\n"
12121 ++ " pushl %%ss\n"
12122 ++ " popl %%ds\n"
12123 + ".section .fixup,\"ax\"\n"
12124 + "9: lea 0(%%eax,%0,4),%0\n"
12125 + "16: jmp 8b\n"
12126 +@@ -616,7 +751,7 @@ static unsigned long __copy_user_intel_n
12127 + " .long 7b,16b\n"
12128 + ".previous"
12129 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
12130 +- : "1"(to), "2"(from), "0"(size)
12131 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
12132 + : "eax", "edx", "memory");
12133 + return size;
12134 + }
12135 +@@ -629,90 +764,146 @@ static unsigned long __copy_user_intel_n
12136 + */
12137 + unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
12138 + unsigned long size);
12139 +-unsigned long __copy_user_intel(void __user *to, const void *from,
12140 ++unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
12141 ++ unsigned long size);
12142 ++unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
12143 + unsigned long size);
12144 + unsigned long __copy_user_zeroing_intel_nocache(void *to,
12145 + const void __user *from, unsigned long size);
12146 + #endif /* CONFIG_X86_INTEL_USERCOPY */
12147 +
12148 + /* Generic arbitrary sized copy. */
12149 +-#define __copy_user(to, from, size) \
12150 +-do { \
12151 +- int __d0, __d1, __d2; \
12152 +- __asm__ __volatile__( \
12153 +- " cmp $7,%0\n" \
12154 +- " jbe 1f\n" \
12155 +- " movl %1,%0\n" \
12156 +- " negl %0\n" \
12157 +- " andl $7,%0\n" \
12158 +- " subl %0,%3\n" \
12159 +- "4: rep; movsb\n" \
12160 +- " movl %3,%0\n" \
12161 +- " shrl $2,%0\n" \
12162 +- " andl $3,%3\n" \
12163 +- " .align 2,0x90\n" \
12164 +- "0: rep; movsl\n" \
12165 +- " movl %3,%0\n" \
12166 +- "1: rep; movsb\n" \
12167 +- "2:\n" \
12168 +- ".section .fixup,\"ax\"\n" \
12169 +- "5: addl %3,%0\n" \
12170 +- " jmp 2b\n" \
12171 +- "3: lea 0(%3,%0,4),%0\n" \
12172 +- " jmp 2b\n" \
12173 +- ".previous\n" \
12174 +- ".section __ex_table,\"a\"\n" \
12175 +- " .align 4\n" \
12176 +- " .long 4b,5b\n" \
12177 +- " .long 0b,3b\n" \
12178 +- " .long 1b,2b\n" \
12179 +- ".previous" \
12180 +- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
12181 +- : "3"(size), "0"(size), "1"(to), "2"(from) \
12182 +- : "memory"); \
12183 +-} while (0)
12184 +-
12185 +-#define __copy_user_zeroing(to, from, size) \
12186 +-do { \
12187 +- int __d0, __d1, __d2; \
12188 +- __asm__ __volatile__( \
12189 +- " cmp $7,%0\n" \
12190 +- " jbe 1f\n" \
12191 +- " movl %1,%0\n" \
12192 +- " negl %0\n" \
12193 +- " andl $7,%0\n" \
12194 +- " subl %0,%3\n" \
12195 +- "4: rep; movsb\n" \
12196 +- " movl %3,%0\n" \
12197 +- " shrl $2,%0\n" \
12198 +- " andl $3,%3\n" \
12199 +- " .align 2,0x90\n" \
12200 +- "0: rep; movsl\n" \
12201 +- " movl %3,%0\n" \
12202 +- "1: rep; movsb\n" \
12203 +- "2:\n" \
12204 +- ".section .fixup,\"ax\"\n" \
12205 +- "5: addl %3,%0\n" \
12206 +- " jmp 6f\n" \
12207 +- "3: lea 0(%3,%0,4),%0\n" \
12208 +- "6: pushl %0\n" \
12209 +- " pushl %%eax\n" \
12210 +- " xorl %%eax,%%eax\n" \
12211 +- " rep; stosb\n" \
12212 +- " popl %%eax\n" \
12213 +- " popl %0\n" \
12214 +- " jmp 2b\n" \
12215 +- ".previous\n" \
12216 +- ".section __ex_table,\"a\"\n" \
12217 +- " .align 4\n" \
12218 +- " .long 4b,5b\n" \
12219 +- " .long 0b,3b\n" \
12220 +- " .long 1b,6b\n" \
12221 +- ".previous" \
12222 +- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
12223 +- : "3"(size), "0"(size), "1"(to), "2"(from) \
12224 +- : "memory"); \
12225 +-} while (0)
12226 ++static unsigned long
12227 ++__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
12228 ++{
12229 ++ int __d0, __d1, __d2;
12230 ++
12231 ++ __asm__ __volatile__(
12232 ++ " movw %w8,%%es\n"
12233 ++ " cmp $7,%0\n"
12234 ++ " jbe 1f\n"
12235 ++ " movl %1,%0\n"
12236 ++ " negl %0\n"
12237 ++ " andl $7,%0\n"
12238 ++ " subl %0,%3\n"
12239 ++ "4: rep; movsb\n"
12240 ++ " movl %3,%0\n"
12241 ++ " shrl $2,%0\n"
12242 ++ " andl $3,%3\n"
12243 ++ " .align 2,0x90\n"
12244 ++ "0: rep; movsl\n"
12245 ++ " movl %3,%0\n"
12246 ++ "1: rep; movsb\n"
12247 ++ "2:\n"
12248 ++ " pushl %%ss\n"
12249 ++ " popl %%es\n"
12250 ++ ".section .fixup,\"ax\"\n"
12251 ++ "5: addl %3,%0\n"
12252 ++ " jmp 2b\n"
12253 ++ "3: lea 0(%3,%0,4),%0\n"
12254 ++ " jmp 2b\n"
12255 ++ ".previous\n"
12256 ++ ".section __ex_table,\"a\"\n"
12257 ++ " .align 4\n"
12258 ++ " .long 4b,5b\n"
12259 ++ " .long 0b,3b\n"
12260 ++ " .long 1b,2b\n"
12261 ++ ".previous"
12262 ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
12263 ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
12264 ++ : "memory");
12265 ++ return size;
12266 ++}
12267 ++
12268 ++static unsigned long
12269 ++__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
12270 ++{
12271 ++ int __d0, __d1, __d2;
12272 ++
12273 ++ __asm__ __volatile__(
12274 ++ " movw %w8,%%ds\n"
12275 ++ " cmp $7,%0\n"
12276 ++ " jbe 1f\n"
12277 ++ " movl %1,%0\n"
12278 ++ " negl %0\n"
12279 ++ " andl $7,%0\n"
12280 ++ " subl %0,%3\n"
12281 ++ "4: rep; movsb\n"
12282 ++ " movl %3,%0\n"
12283 ++ " shrl $2,%0\n"
12284 ++ " andl $3,%3\n"
12285 ++ " .align 2,0x90\n"
12286 ++ "0: rep; movsl\n"
12287 ++ " movl %3,%0\n"
12288 ++ "1: rep; movsb\n"
12289 ++ "2:\n"
12290 ++ " pushl %%ss\n"
12291 ++ " popl %%ds\n"
12292 ++ ".section .fixup,\"ax\"\n"
12293 ++ "5: addl %3,%0\n"
12294 ++ " jmp 2b\n"
12295 ++ "3: lea 0(%3,%0,4),%0\n"
12296 ++ " jmp 2b\n"
12297 ++ ".previous\n"
12298 ++ ".section __ex_table,\"a\"\n"
12299 ++ " .align 4\n"
12300 ++ " .long 4b,5b\n"
12301 ++ " .long 0b,3b\n"
12302 ++ " .long 1b,2b\n"
12303 ++ ".previous"
12304 ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
12305 ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
12306 ++ : "memory");
12307 ++ return size;
12308 ++}
12309 ++
12310 ++static unsigned long
12311 ++__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
12312 ++{
12313 ++ int __d0, __d1, __d2;
12314 ++
12315 ++ __asm__ __volatile__(
12316 ++ " movw %w8,%%ds\n"
12317 ++ " cmp $7,%0\n"
12318 ++ " jbe 1f\n"
12319 ++ " movl %1,%0\n"
12320 ++ " negl %0\n"
12321 ++ " andl $7,%0\n"
12322 ++ " subl %0,%3\n"
12323 ++ "4: rep; movsb\n"
12324 ++ " movl %3,%0\n"
12325 ++ " shrl $2,%0\n"
12326 ++ " andl $3,%3\n"
12327 ++ " .align 2,0x90\n"
12328 ++ "0: rep; movsl\n"
12329 ++ " movl %3,%0\n"
12330 ++ "1: rep; movsb\n"
12331 ++ "2:\n"
12332 ++ " pushl %%ss\n"
12333 ++ " popl %%ds\n"
12334 ++ ".section .fixup,\"ax\"\n"
12335 ++ "5: addl %3,%0\n"
12336 ++ " jmp 6f\n"
12337 ++ "3: lea 0(%3,%0,4),%0\n"
12338 ++ "6: pushl %0\n"
12339 ++ " pushl %%eax\n"
12340 ++ " xorl %%eax,%%eax\n"
12341 ++ " rep; stosb\n"
12342 ++ " popl %%eax\n"
12343 ++ " popl %0\n"
12344 ++ " jmp 2b\n"
12345 ++ ".previous\n"
12346 ++ ".section __ex_table,\"a\"\n"
12347 ++ " .align 4\n"
12348 ++ " .long 4b,5b\n"
12349 ++ " .long 0b,3b\n"
12350 ++ " .long 1b,6b\n"
12351 ++ ".previous"
12352 ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
12353 ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
12354 ++ : "memory");
12355 ++ return size;
12356 ++}
12357 +
12358 + unsigned long __copy_to_user_ll(void __user *to, const void *from,
12359 + unsigned long n)
12360 +@@ -775,9 +966,9 @@ survive:
12361 + }
12362 + #endif
12363 + if (movsl_is_ok(to, from, n))
12364 +- __copy_user(to, from, n);
12365 ++ n = __generic_copy_to_user(to, from, n);
12366 + else
12367 +- n = __copy_user_intel(to, from, n);
12368 ++ n = __generic_copy_to_user_intel(to, from, n);
12369 + return n;
12370 + }
12371 + EXPORT_SYMBOL(__copy_to_user_ll);
12372 +@@ -786,7 +977,7 @@ unsigned long __copy_from_user_ll(void *
12373 + unsigned long n)
12374 + {
12375 + if (movsl_is_ok(to, from, n))
12376 +- __copy_user_zeroing(to, from, n);
12377 ++ n = __copy_user_zeroing(to, from, n);
12378 + else
12379 + n = __copy_user_zeroing_intel(to, from, n);
12380 + return n;
12381 +@@ -797,10 +988,9 @@ unsigned long __copy_from_user_ll_nozero
12382 + unsigned long n)
12383 + {
12384 + if (movsl_is_ok(to, from, n))
12385 +- __copy_user(to, from, n);
12386 ++ n = __generic_copy_from_user(to, from, n);
12387 + else
12388 +- n = __copy_user_intel((void __user *)to,
12389 +- (const void *)from, n);
12390 ++ n = __generic_copy_from_user_intel(to, from, n);
12391 + return n;
12392 + }
12393 + EXPORT_SYMBOL(__copy_from_user_ll_nozero);
12394 +@@ -812,9 +1002,9 @@ unsigned long __copy_from_user_ll_nocach
12395 + if (n > 64 && cpu_has_xmm2)
12396 + n = __copy_user_zeroing_intel_nocache(to, from, n);
12397 + else
12398 +- __copy_user_zeroing(to, from, n);
12399 ++ n = __copy_user_zeroing(to, from, n);
12400 + #else
12401 +- __copy_user_zeroing(to, from, n);
12402 ++ n = __copy_user_zeroing(to, from, n);
12403 + #endif
12404 + return n;
12405 + }
12406 +@@ -827,9 +1017,9 @@ unsigned long __copy_from_user_ll_nocach
12407 + if (n > 64 && cpu_has_xmm2)
12408 + n = __copy_user_intel_nocache(to, from, n);
12409 + else
12410 +- __copy_user(to, from, n);
12411 ++ n = __generic_copy_from_user(to, from, n);
12412 + #else
12413 +- __copy_user(to, from, n);
12414 ++ n = __generic_copy_from_user(to, from, n);
12415 + #endif
12416 + return n;
12417 + }
12418 +@@ -878,8 +1068,35 @@ copy_from_user(void *to, const void __us
12419 + {
12420 + if (access_ok(VERIFY_READ, from, n))
12421 + n = __copy_from_user(to, from, n);
12422 +- else
12423 ++ else if ((long)n > 0)
12424 + memset(to, 0, n);
12425 + return n;
12426 + }
12427 + EXPORT_SYMBOL(copy_from_user);
12428 ++
12429 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
12430 ++void __set_fs(mm_segment_t x, int cpu)
12431 ++{
12432 ++ unsigned long limit = x.seg;
12433 ++ struct desc_struct d;
12434 ++
12435 ++ current_thread_info()->addr_limit = x;
12436 ++ if (likely(limit))
12437 ++ limit = (limit - 1UL) >> PAGE_SHIFT;
12438 ++ pack_descriptor(&d, 0UL, limit, 0xF3, 0xC);
12439 ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, &d, DESCTYPE_S);
12440 ++}
12441 ++
12442 ++void set_fs(mm_segment_t x)
12443 ++{
12444 ++ __set_fs(x, get_cpu());
12445 ++ put_cpu_no_resched();
12446 ++}
12447 ++#else
12448 ++void set_fs(mm_segment_t x)
12449 ++{
12450 ++ current_thread_info()->addr_limit = x;
12451 ++}
12452 ++#endif
12453 ++
12454 ++EXPORT_SYMBOL(set_fs);
12455 +diff -urNp linux-2.6.28.8/arch/x86/mach-voyager/voyager_basic.c linux-2.6.28.8/arch/x86/mach-voyager/voyager_basic.c
12456 +--- linux-2.6.28.8/arch/x86/mach-voyager/voyager_basic.c 2009-02-06 16:47:45.000000000 -0500
12457 ++++ linux-2.6.28.8/arch/x86/mach-voyager/voyager_basic.c 2009-02-21 09:37:48.000000000 -0500
12458 +@@ -123,7 +123,7 @@ int __init voyager_memory_detect(int reg
12459 + __u8 cmos[4];
12460 + ClickMap_t *map;
12461 + unsigned long map_addr;
12462 +- unsigned long old;
12463 ++ pte_t old;
12464 +
12465 + if (region >= CLICK_ENTRIES) {
12466 + printk("Voyager: Illegal ClickMap region %d\n", region);
12467 +@@ -138,7 +138,7 @@ int __init voyager_memory_detect(int reg
12468 +
12469 + /* steal page 0 for this */
12470 + old = pg0[0];
12471 +- pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
12472 ++ pg0[0] = __pte((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
12473 + local_flush_tlb();
12474 + /* now clear everything out but page 0 */
12475 + map = (ClickMap_t *) (map_addr & (~PAGE_MASK));
12476 +diff -urNp linux-2.6.28.8/arch/x86/mach-voyager/voyager_smp.c linux-2.6.28.8/arch/x86/mach-voyager/voyager_smp.c
12477 +--- linux-2.6.28.8/arch/x86/mach-voyager/voyager_smp.c 2009-02-06 16:47:45.000000000 -0500
12478 ++++ linux-2.6.28.8/arch/x86/mach-voyager/voyager_smp.c 2009-02-21 09:37:48.000000000 -0500
12479 +@@ -521,6 +521,10 @@ static void __init do_boot_cpu(__u8 cpu)
12480 + __u32 *hijack_vector;
12481 + __u32 start_phys_address = setup_trampoline();
12482 +
12483 ++#ifdef CONFIG_PAX_KERNEXEC
12484 ++ unsigned long cr0;
12485 ++#endif
12486 ++
12487 + /* There's a clever trick to this: The linux trampoline is
12488 + * compiled to begin at absolute location zero, so make the
12489 + * address zero but have the data segment selector compensate
12490 +@@ -540,7 +544,17 @@ static void __init do_boot_cpu(__u8 cpu)
12491 +
12492 + init_gdt(cpu);
12493 + per_cpu(current_task, cpu) = idle;
12494 +- early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
12495 ++
12496 ++#ifdef CONFIG_PAX_KERNEXEC
12497 ++ pax_open_kernel(cr0);
12498 ++#endif
12499 ++
12500 ++ early_gdt_descr.address = get_cpu_gdt_table(cpu);
12501 ++
12502 ++#ifdef CONFIG_PAX_KERNEXEC
12503 ++ pax_close_kernel(cr0);
12504 ++#endif
12505 ++
12506 + irq_ctx_init(cpu);
12507 +
12508 + /* Note: Don't modify initial ss override */
12509 +@@ -1154,7 +1168,7 @@ void smp_local_timer_interrupt(void)
12510 + per_cpu(prof_counter, cpu);
12511 + }
12512 +
12513 +- update_process_times(user_mode_vm(get_irq_regs()));
12514 ++ update_process_times(user_mode(get_irq_regs()));
12515 + }
12516 +
12517 + if (((1 << cpu) & voyager_extended_vic_processors) == 0)
12518 +diff -urNp linux-2.6.28.8/arch/x86/Makefile linux-2.6.28.8/arch/x86/Makefile
12519 +--- linux-2.6.28.8/arch/x86/Makefile 2009-02-06 16:47:45.000000000 -0500
12520 ++++ linux-2.6.28.8/arch/x86/Makefile 2009-02-21 09:37:48.000000000 -0500
12521 +@@ -232,3 +232,12 @@ endef
12522 + CLEAN_FILES += arch/x86/boot/fdimage \
12523 + arch/x86/boot/image.iso \
12524 + arch/x86/boot/mtools.conf
12525 ++
12526 ++define OLD_LD
12527 ++
12528 ++*** ${VERSION}.${PATCHLEVEL} PaX kernels no longer build correctly with old versions of binutils.
12529 ++*** Please upgrade your binutils to 2.18 or newer
12530 ++endef
12531 ++
12532 ++archprepare:
12533 ++ $(if $(LDFLAGS_BUILD_ID),,$(error $(OLD_LD)))
12534 +diff -urNp linux-2.6.28.8/arch/x86/mm/extable.c linux-2.6.28.8/arch/x86/mm/extable.c
12535 +--- linux-2.6.28.8/arch/x86/mm/extable.c 2009-02-06 16:47:45.000000000 -0500
12536 ++++ linux-2.6.28.8/arch/x86/mm/extable.c 2009-02-21 09:37:48.000000000 -0500
12537 +@@ -1,14 +1,62 @@
12538 + #include <linux/module.h>
12539 + #include <linux/spinlock.h>
12540 ++#include <linux/sort.h>
12541 + #include <asm/uaccess.h>
12542 +
12543 ++/*
12544 ++ * The exception table needs to be sorted so that the binary
12545 ++ * search that we use to find entries in it works properly.
12546 ++ * This is used both for the kernel exception table and for
12547 ++ * the exception tables of modules that get loaded.
12548 ++ */
12549 ++static int cmp_ex(const void *a, const void *b)
12550 ++{
12551 ++ const struct exception_table_entry *x = a, *y = b;
12552 ++
12553 ++ /* avoid overflow */
12554 ++ if (x->insn > y->insn)
12555 ++ return 1;
12556 ++ if (x->insn < y->insn)
12557 ++ return -1;
12558 ++ return 0;
12559 ++}
12560 ++
12561 ++static void swap_ex(void *a, void *b, int size)
12562 ++{
12563 ++ struct exception_table_entry t, *x = a, *y = b;
12564 ++
12565 ++#ifdef CONFIG_PAX_KERNEXEC
12566 ++ unsigned long cr0;
12567 ++#endif
12568 ++
12569 ++ t = *x;
12570 ++
12571 ++#ifdef CONFIG_PAX_KERNEXEC
12572 ++ pax_open_kernel(cr0);
12573 ++#endif
12574 ++
12575 ++ *x = *y;
12576 ++ *y = t;
12577 ++
12578 ++#ifdef CONFIG_PAX_KERNEXEC
12579 ++ pax_close_kernel(cr0);
12580 ++#endif
12581 ++
12582 ++}
12583 ++
12584 ++void sort_extable(struct exception_table_entry *start,
12585 ++ struct exception_table_entry *finish)
12586 ++{
12587 ++ sort(start, finish - start, sizeof(struct exception_table_entry),
12588 ++ cmp_ex, swap_ex);
12589 ++}
12590 +
12591 + int fixup_exception(struct pt_regs *regs)
12592 + {
12593 + const struct exception_table_entry *fixup;
12594 +
12595 + #ifdef CONFIG_PNPBIOS
12596 +- if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) {
12597 ++ if (unlikely(!v8086_mode(regs) && SEGMENT_IS_PNP_CODE(regs->cs))) {
12598 + extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
12599 + extern u32 pnp_bios_is_utter_crap;
12600 + pnp_bios_is_utter_crap = 1;
12601 +diff -urNp linux-2.6.28.8/arch/x86/mm/fault.c linux-2.6.28.8/arch/x86/mm/fault.c
12602 +--- linux-2.6.28.8/arch/x86/mm/fault.c 2009-02-07 16:10:45.000000000 -0500
12603 ++++ linux-2.6.28.8/arch/x86/mm/fault.c 2009-02-21 09:37:48.000000000 -0500
12604 +@@ -26,6 +26,8 @@
12605 + #include <linux/kprobes.h>
12606 + #include <linux/uaccess.h>
12607 + #include <linux/kdebug.h>
12608 ++#include <linux/unistd.h>
12609 ++#include <linux/compiler.h>
12610 +
12611 + #include <asm/system.h>
12612 + #include <asm/desc.h>
12613 +@@ -67,7 +69,7 @@ static inline int notify_page_fault(stru
12614 + int ret = 0;
12615 +
12616 + /* kprobe_running() needs smp_processor_id() */
12617 +- if (!user_mode_vm(regs)) {
12618 ++ if (!user_mode(regs)) {
12619 + preempt_disable();
12620 + if (kprobe_running() && kprobe_fault_handler(regs, 14))
12621 + ret = 1;
12622 +@@ -265,6 +267,30 @@ bad:
12623 + #endif
12624 + }
12625 +
12626 ++#ifdef CONFIG_PAX_EMUTRAMP
12627 ++static int pax_handle_fetch_fault(struct pt_regs *regs);
12628 ++#endif
12629 ++
12630 ++#ifdef CONFIG_PAX_PAGEEXEC
12631 ++static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
12632 ++{
12633 ++ pgd_t *pgd;
12634 ++ pud_t *pud;
12635 ++ pmd_t *pmd;
12636 ++
12637 ++ pgd = pgd_offset(mm, address);
12638 ++ if (!pgd_present(*pgd))
12639 ++ return NULL;
12640 ++ pud = pud_offset(pgd, address);
12641 ++ if (!pud_present(*pud))
12642 ++ return NULL;
12643 ++ pmd = pmd_offset(pud, address);
12644 ++ if (!pmd_present(*pmd))
12645 ++ return NULL;
12646 ++ return pmd;
12647 ++}
12648 ++#endif
12649 ++
12650 + #ifdef CONFIG_X86_32
12651 + static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
12652 + {
12653 +@@ -351,7 +377,7 @@ static int is_errata93(struct pt_regs *r
12654 + static int is_errata100(struct pt_regs *regs, unsigned long address)
12655 + {
12656 + #ifdef CONFIG_X86_64
12657 +- if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) &&
12658 ++ if ((regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT)) &&
12659 + (address >> 32))
12660 + return 1;
12661 + #endif
12662 +@@ -386,14 +412,31 @@ static void show_fault_oops(struct pt_re
12663 + #endif
12664 +
12665 + #ifdef CONFIG_X86_PAE
12666 +- if (error_code & PF_INSTR) {
12667 ++ if (nx_enabled && (error_code & PF_INSTR)) {
12668 + unsigned int level;
12669 + pte_t *pte = lookup_address(address, &level);
12670 +
12671 + if (pte && pte_present(*pte) && !pte_exec(*pte))
12672 + printk(KERN_CRIT "kernel tried to execute "
12673 + "NX-protected page - exploit attempt? "
12674 +- "(uid: %d)\n", current->uid);
12675 ++ "(uid: %d, task: %s, pid: %d)\n",
12676 ++ current->uid, current->comm, task_pid_nr(current));
12677 ++ }
12678 ++#endif
12679 ++
12680 ++#ifdef CONFIG_PAX_KERNEXEC
12681 ++#ifdef CONFIG_MODULES
12682 ++ if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
12683 ++#else
12684 ++ if (init_mm.start_code <= address && address < init_mm.end_code)
12685 ++#endif
12686 ++ {
12687 ++ if (current->signal->curr_ip)
12688 ++ printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
12689 ++ NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current->uid, current->euid);
12690 ++ else
12691 ++ printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
12692 ++ current->comm, task_pid_nr(current), current->uid, current->euid);
12693 + }
12694 + #endif
12695 +
12696 +@@ -585,20 +628,26 @@ void __kprobes do_page_fault(struct pt_r
12697 + struct task_struct *tsk;
12698 + struct mm_struct *mm;
12699 + struct vm_area_struct *vma;
12700 +- unsigned long address;
12701 + int write, si_code;
12702 + int fault;
12703 + #ifdef CONFIG_X86_64
12704 + unsigned long flags;
12705 + #endif
12706 +
12707 ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
12708 ++ pte_t *pte;
12709 ++ pmd_t *pmd;
12710 ++ spinlock_t *ptl;
12711 ++ unsigned char pte_mask;
12712 ++#endif
12713 ++
12714 ++ /* get the address */
12715 ++ const unsigned long address = read_cr2();
12716 ++
12717 + tsk = current;
12718 + mm = tsk->mm;
12719 + prefetchw(&mm->mmap_sem);
12720 +
12721 +- /* get the address */
12722 +- address = read_cr2();
12723 +-
12724 + si_code = SEGV_MAPERR;
12725 +
12726 + if (unlikely(kmmio_fault(regs, address)))
12727 +@@ -651,7 +700,7 @@ void __kprobes do_page_fault(struct pt_r
12728 + * User-mode registers count as a user access even for any
12729 + * potential system fault or CPU buglet.
12730 + */
12731 +- if (user_mode_vm(regs)) {
12732 ++ if (user_mode(regs)) {
12733 + local_irq_enable();
12734 + error_code |= PF_USER;
12735 + } else if (regs->flags & X86_EFLAGS_IF)
12736 +@@ -667,7 +716,7 @@ void __kprobes do_page_fault(struct pt_r
12737 + * atomic region then we must not take the fault.
12738 + */
12739 + if (unlikely(in_atomic() || !mm))
12740 +- goto bad_area_nosemaphore;
12741 ++ goto bad_area_nopax;
12742 +
12743 + again:
12744 + /*
12745 +@@ -689,10 +738,104 @@ again:
12746 + if (!down_read_trylock(&mm->mmap_sem)) {
12747 + if ((error_code & PF_USER) == 0 &&
12748 + !search_exception_tables(regs->ip))
12749 +- goto bad_area_nosemaphore;
12750 ++ goto bad_area_nopax;
12751 + down_read(&mm->mmap_sem);
12752 + }
12753 +
12754 ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
12755 ++ if (nx_enabled || (error_code & (PF_PROT|PF_USER)) != (PF_PROT|PF_USER) || v8086_mode(regs) ||
12756 ++ !(mm->pax_flags & MF_PAX_PAGEEXEC))
12757 ++ goto not_pax_fault;
12758 ++
12759 ++ /* PaX: it's our fault, let's handle it if we can */
12760 ++
12761 ++ /* PaX: take a look at read faults before acquiring any locks */
12762 ++ if (unlikely(!(error_code & PF_WRITE) && (regs->ip == address))) {
12763 ++ /* instruction fetch attempt from a protected page in user mode */
12764 ++ up_read(&mm->mmap_sem);
12765 ++
12766 ++#ifdef CONFIG_PAX_EMUTRAMP
12767 ++ switch (pax_handle_fetch_fault(regs)) {
12768 ++ case 2:
12769 ++ return;
12770 ++ }
12771 ++#endif
12772 ++
12773 ++ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
12774 ++ do_group_exit(SIGKILL);
12775 ++ }
12776 ++
12777 ++ pmd = pax_get_pmd(mm, address);
12778 ++ if (unlikely(!pmd))
12779 ++ goto not_pax_fault;
12780 ++
12781 ++ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
12782 ++ if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
12783 ++ pte_unmap_unlock(pte, ptl);
12784 ++ goto not_pax_fault;
12785 ++ }
12786 ++
12787 ++ if (unlikely((error_code & PF_WRITE) && !pte_write(*pte))) {
12788 ++ /* write attempt to a protected page in user mode */
12789 ++ pte_unmap_unlock(pte, ptl);
12790 ++ goto not_pax_fault;
12791 ++ }
12792 ++
12793 ++#ifdef CONFIG_SMP
12794 ++ if (likely(address > get_limit(regs->cs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
12795 ++#else
12796 ++ if (likely(address > get_limit(regs->cs)))
12797 ++#endif
12798 ++ {
12799 ++ set_pte(pte, pte_mkread(*pte));
12800 ++ __flush_tlb_one(address);
12801 ++ pte_unmap_unlock(pte, ptl);
12802 ++ up_read(&mm->mmap_sem);
12803 ++ return;
12804 ++ }
12805 ++
12806 ++ pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & PF_WRITE) << (_PAGE_BIT_DIRTY-1));
12807 ++
12808 ++ /*
12809 ++ * PaX: fill DTLB with user rights and retry
12810 ++ */
12811 ++ __asm__ __volatile__ (
12812 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
12813 ++ "movw %w4,%%es\n"
12814 ++#endif
12815 ++ "orb %2,(%1)\n"
12816 ++#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
12817 ++/*
12818 ++ * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
12819 ++ * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
12820 ++ * page fault when examined during a TLB load attempt. this is true not only
12821 ++ * for PTEs holding a non-present entry but also present entries that will
12822 ++ * raise a page fault (such as those set up by PaX, or the copy-on-write
12823 ++ * mechanism). in effect it means that we do *not* need to flush the TLBs
12824 ++ * for our target pages since their PTEs are simply not in the TLBs at all.
12825 ++
12826 ++ * the best thing in omitting it is that we gain around 15-20% speed in the
12827 ++ * fast path of the page fault handler and can get rid of tracing since we
12828 ++ * can no longer flush unintended entries.
12829 ++ */
12830 ++ "invlpg (%0)\n"
12831 ++#endif
12832 ++ "testb $0,%%es:(%0)\n"
12833 ++ "xorb %3,(%1)\n"
12834 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
12835 ++ "pushl %%ss\n"
12836 ++ "popl %%es\n"
12837 ++#endif
12838 ++ :
12839 ++ : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
12840 ++ : "memory", "cc");
12841 ++ pte_unmap_unlock(pte, ptl);
12842 ++ up_read(&mm->mmap_sem);
12843 ++ return;
12844 ++
12845 ++not_pax_fault:
12846 ++#endif
12847 ++
12848 + vma = find_vma(mm, address);
12849 + if (!vma)
12850 + goto bad_area;
12851 +@@ -700,16 +843,20 @@ again:
12852 + goto good_area;
12853 + if (!(vma->vm_flags & VM_GROWSDOWN))
12854 + goto bad_area;
12855 +- if (error_code & PF_USER) {
12856 +- /*
12857 +- * Accessing the stack below %sp is always a bug.
12858 +- * The large cushion allows instructions like enter
12859 +- * and pusha to work. ("enter $65535,$31" pushes
12860 +- * 32 pointers and then decrements %sp by 65535.)
12861 +- */
12862 +- if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp)
12863 +- goto bad_area;
12864 +- }
12865 ++ /*
12866 ++ * Accessing the stack below %sp is always a bug.
12867 ++ * The large cushion allows instructions like enter
12868 ++ * and pusha to work. ("enter $65535,$31" pushes
12869 ++ * 32 pointers and then decrements %sp by 65535.)
12870 ++ */
12871 ++ if (address + 65536 + 32 * sizeof(unsigned long) < task_pt_regs(tsk)->sp)
12872 ++ goto bad_area;
12873 ++
12874 ++#ifdef CONFIG_PAX_SEGMEXEC
12875 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)
12876 ++ goto bad_area;
12877 ++#endif
12878 ++
12879 + if (expand_stack(vma, address))
12880 + goto bad_area;
12881 + /*
12882 +@@ -719,6 +866,8 @@ again:
12883 + good_area:
12884 + si_code = SEGV_ACCERR;
12885 + write = 0;
12886 ++ if (nx_enabled && (error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
12887 ++ goto bad_area;
12888 + switch (error_code & (PF_PROT|PF_WRITE)) {
12889 + default: /* 3: write, present */
12890 + /* fall through */
12891 +@@ -773,6 +922,54 @@ bad_area:
12892 + up_read(&mm->mmap_sem);
12893 +
12894 + bad_area_nosemaphore:
12895 ++
12896 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
12897 ++ if (mm && (error_code & PF_USER)) {
12898 ++ unsigned long ip = regs->ip;
12899 ++
12900 ++ if (v8086_mode(regs))
12901 ++ ip = ((regs->cs & 0xffff) << 4) + (regs->ip & 0xffff);
12902 ++
12903 ++ /*
12904 ++ * It's possible to have interrupts off here.
12905 ++ */
12906 ++ local_irq_enable();
12907 ++
12908 ++#ifdef CONFIG_PAX_PAGEEXEC
12909 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) &&
12910 ++ ((nx_enabled && (error_code & PF_INSTR)) || (!(error_code & (PF_PROT | PF_WRITE)) && regs->ip == address))) {
12911 ++
12912 ++#ifdef CONFIG_PAX_EMUTRAMP
12913 ++ switch (pax_handle_fetch_fault(regs)) {
12914 ++ case 2:
12915 ++ return;
12916 ++ }
12917 ++#endif
12918 ++
12919 ++ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
12920 ++ do_group_exit(SIGKILL);
12921 ++ }
12922 ++#endif
12923 ++
12924 ++#ifdef CONFIG_PAX_SEGMEXEC
12925 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & (PF_PROT | PF_WRITE)) && (regs->ip + SEGMEXEC_TASK_SIZE == address)) {
12926 ++
12927 ++#ifdef CONFIG_PAX_EMUTRAMP
12928 ++ switch (pax_handle_fetch_fault(regs)) {
12929 ++ case 2:
12930 ++ return;
12931 ++ }
12932 ++#endif
12933 ++
12934 ++ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
12935 ++ do_group_exit(SIGKILL);
12936 ++ }
12937 ++#endif
12938 ++
12939 ++ }
12940 ++#endif
12941 ++
12942 ++bad_area_nopax:
12943 + /* User mode accesses just cause a SIGSEGV */
12944 + if (error_code & PF_USER) {
12945 + /*
12946 +@@ -851,7 +1048,7 @@ no_context:
12947 + #ifdef CONFIG_X86_32
12948 + die("Oops", regs, error_code);
12949 + bust_spinlocks(0);
12950 +- do_exit(SIGKILL);
12951 ++ do_group_exit(SIGKILL);
12952 + #else
12953 + if (__die("Oops", regs, error_code))
12954 + regs = NULL;
12955 +@@ -944,3 +1141,174 @@ void vmalloc_sync_all(void)
12956 + }
12957 + #endif
12958 + }
12959 ++
12960 ++#ifdef CONFIG_PAX_EMUTRAMP
12961 ++static int pax_handle_fetch_fault_32(struct pt_regs *regs)
12962 ++{
12963 ++ int err;
12964 ++
12965 ++ do { /* PaX: gcc trampoline emulation #1 */
12966 ++ unsigned char mov1, mov2;
12967 ++ unsigned short jmp;
12968 ++ unsigned int addr1, addr2;
12969 ++
12970 ++#ifdef CONFIG_X86_64
12971 ++ if ((regs->ip + 11) >> 32)
12972 ++ break;
12973 ++#endif
12974 ++
12975 ++ err = get_user(mov1, (unsigned char __user *)regs->ip);
12976 ++ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
12977 ++ err |= get_user(mov2, (unsigned char __user *)(regs->ip + 5));
12978 ++ err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
12979 ++ err |= get_user(jmp, (unsigned short __user *)(regs->ip + 10));
12980 ++
12981 ++ if (err)
12982 ++ break;
12983 ++
12984 ++ if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
12985 ++ regs->cx = addr1;
12986 ++ regs->ax = addr2;
12987 ++ regs->ip = addr2;
12988 ++ return 2;
12989 ++ }
12990 ++ } while (0);
12991 ++
12992 ++ do { /* PaX: gcc trampoline emulation #2 */
12993 ++ unsigned char mov, jmp;
12994 ++ unsigned int addr1, addr2;
12995 ++
12996 ++#ifdef CONFIG_X86_64
12997 ++ if ((regs->ip + 9) >> 32)
12998 ++ break;
12999 ++#endif
13000 ++
13001 ++ err = get_user(mov, (unsigned char __user *)regs->ip);
13002 ++ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
13003 ++ err |= get_user(jmp, (unsigned char __user *)(regs->ip + 5));
13004 ++ err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
13005 ++
13006 ++ if (err)
13007 ++ break;
13008 ++
13009 ++ if (mov == 0xB9 && jmp == 0xE9) {
13010 ++ regs->cx = addr1;
13011 ++ regs->ip = (unsigned int)(regs->ip + addr2 + 10);
13012 ++ return 2;
13013 ++ }
13014 ++ } while (0);
13015 ++
13016 ++ return 1; /* PaX in action */
13017 ++}
13018 ++
13019 ++#ifdef CONFIG_X86_64
13020 ++static int pax_handle_fetch_fault_64(struct pt_regs *regs)
13021 ++{
13022 ++ int err;
13023 ++
13024 ++ do { /* PaX: gcc trampoline emulation #1 */
13025 ++ unsigned short mov1, mov2, jmp1;
13026 ++ unsigned char jmp2;
13027 ++ unsigned int addr1;
13028 ++ unsigned long addr2;
13029 ++
13030 ++ err = get_user(mov1, (unsigned short __user *)regs->ip);
13031 ++ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 2));
13032 ++ err |= get_user(mov2, (unsigned short __user *)(regs->ip + 6));
13033 ++ err |= get_user(addr2, (unsigned long __user *)(regs->ip + 8));
13034 ++ err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 16));
13035 ++ err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 18));
13036 ++
13037 ++ if (err)
13038 ++ break;
13039 ++
13040 ++ if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
13041 ++ regs->r11 = addr1;
13042 ++ regs->r10 = addr2;
13043 ++ regs->ip = addr1;
13044 ++ return 2;
13045 ++ }
13046 ++ } while (0);
13047 ++
13048 ++ do { /* PaX: gcc trampoline emulation #2 */
13049 ++ unsigned short mov1, mov2, jmp1;
13050 ++ unsigned char jmp2;
13051 ++ unsigned long addr1, addr2;
13052 ++
13053 ++ err = get_user(mov1, (unsigned short __user *)regs->ip);
13054 ++ err |= get_user(addr1, (unsigned long __user *)(regs->ip + 2));
13055 ++ err |= get_user(mov2, (unsigned short __user *)(regs->ip + 10));
13056 ++ err |= get_user(addr2, (unsigned long __user *)(regs->ip + 12));
13057 ++ err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 20));
13058 ++ err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 22));
13059 ++
13060 ++ if (err)
13061 ++ break;
13062 ++
13063 ++ if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
13064 ++ regs->r11 = addr1;
13065 ++ regs->r10 = addr2;
13066 ++ regs->ip = addr1;
13067 ++ return 2;
13068 ++ }
13069 ++ } while (0);
13070 ++
13071 ++ return 1; /* PaX in action */
13072 ++}
13073 ++#endif
13074 ++
13075 ++/*
13076 ++ * PaX: decide what to do with offenders (regs->ip = fault address)
13077 ++ *
13078 ++ * returns 1 when task should be killed
13079 ++ * 2 when gcc trampoline was detected
13080 ++ */
13081 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
13082 ++{
13083 ++ if (v8086_mode(regs))
13084 ++ return 1;
13085 ++
13086 ++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
13087 ++ return 1;
13088 ++
13089 ++#ifdef CONFIG_X86_32
13090 ++ return pax_handle_fetch_fault_32(regs);
13091 ++#else
13092 ++ if (regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT))
13093 ++ return pax_handle_fetch_fault_32(regs);
13094 ++ else
13095 ++ return pax_handle_fetch_fault_64(regs);
13096 ++#endif
13097 ++}
13098 ++#endif
13099 ++
13100 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
13101 ++void pax_report_insns(void *pc, void *sp)
13102 ++{
13103 ++ long i;
13104 ++
13105 ++ printk(KERN_ERR "PAX: bytes at PC: ");
13106 ++ for (i = 0; i < 20; i++) {
13107 ++ unsigned char c;
13108 ++ if (get_user(c, (unsigned char __user *)pc+i))
13109 ++ printk(KERN_CONT "?? ");
13110 ++ else
13111 ++ printk(KERN_CONT "%02x ", c);
13112 ++ }
13113 ++ printk("\n");
13114 ++
13115 ++ printk(KERN_ERR "PAX: bytes at SP-%lu: ", (unsigned long)sizeof(long));
13116 ++ for (i = -1; i < 80 / sizeof(long); i++) {
13117 ++ unsigned long c;
13118 ++ if (get_user(c, (unsigned long __user *)sp+i))
13119 ++#ifdef CONFIG_X86_32
13120 ++ printk(KERN_CONT "???????? ");
13121 ++#else
13122 ++ printk(KERN_CONT "???????????????? ");
13123 ++#endif
13124 ++ else
13125 ++ printk(KERN_CONT "%0*lx ", 2 * (int)sizeof(long), c);
13126 ++ }
13127 ++ printk("\n");
13128 ++}
13129 ++#endif
13130 +diff -urNp linux-2.6.28.8/arch/x86/mm/highmem_32.c linux-2.6.28.8/arch/x86/mm/highmem_32.c
13131 +--- linux-2.6.28.8/arch/x86/mm/highmem_32.c 2009-02-06 16:47:45.000000000 -0500
13132 ++++ linux-2.6.28.8/arch/x86/mm/highmem_32.c 2009-02-21 09:37:48.000000000 -0500
13133 +@@ -74,6 +74,10 @@ void *kmap_atomic_prot(struct page *page
13134 + enum fixed_addresses idx;
13135 + unsigned long vaddr;
13136 +
13137 ++#ifdef CONFIG_PAX_KERNEXEC
13138 ++ unsigned long cr0;
13139 ++#endif
13140 ++
13141 + /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
13142 + pagefault_disable();
13143 +
13144 +@@ -85,7 +89,17 @@ void *kmap_atomic_prot(struct page *page
13145 + idx = type + KM_TYPE_NR*smp_processor_id();
13146 + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
13147 + BUG_ON(!pte_none(*(kmap_pte-idx)));
13148 ++
13149 ++#ifdef CONFIG_PAX_KERNEXEC
13150 ++ pax_open_kernel(cr0);
13151 ++#endif
13152 ++
13153 + set_pte(kmap_pte-idx, mk_pte(page, prot));
13154 ++
13155 ++#ifdef CONFIG_PAX_KERNEXEC
13156 ++ pax_close_kernel(cr0);
13157 ++#endif
13158 ++
13159 + arch_flush_lazy_mmu_mode();
13160 +
13161 + return (void *)vaddr;
13162 +@@ -101,15 +115,29 @@ void kunmap_atomic(void *kvaddr, enum km
13163 + unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
13164 + enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
13165 +
13166 ++#ifdef CONFIG_PAX_KERNEXEC
13167 ++ unsigned long cr0;
13168 ++#endif
13169 ++
13170 + /*
13171 + * Force other mappings to Oops if they'll try to access this pte
13172 + * without first remap it. Keeping stale mappings around is a bad idea
13173 + * also, in case the page changes cacheability attributes or becomes
13174 + * a protected page in a hypervisor.
13175 + */
13176 +- if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx))
13177 ++ if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) {
13178 ++
13179 ++#ifdef CONFIG_PAX_KERNEXEC
13180 ++ pax_open_kernel(cr0);
13181 ++#endif
13182 ++
13183 + kpte_clear_flush(kmap_pte-idx, vaddr);
13184 +- else {
13185 ++
13186 ++#ifdef CONFIG_PAX_KERNEXEC
13187 ++ pax_close_kernel(cr0);
13188 ++#endif
13189 ++
13190 ++ } else {
13191 + #ifdef CONFIG_DEBUG_HIGHMEM
13192 + BUG_ON(vaddr < PAGE_OFFSET);
13193 + BUG_ON(vaddr >= (unsigned long)high_memory);
13194 +@@ -128,11 +156,25 @@ void *kmap_atomic_pfn(unsigned long pfn,
13195 + enum fixed_addresses idx;
13196 + unsigned long vaddr;
13197 +
13198 ++#ifdef CONFIG_PAX_KERNEXEC
13199 ++ unsigned long cr0;
13200 ++#endif
13201 ++
13202 + pagefault_disable();
13203 +
13204 + idx = type + KM_TYPE_NR*smp_processor_id();
13205 + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
13206 ++
13207 ++#ifdef CONFIG_PAX_KERNEXEC
13208 ++ pax_open_kernel(cr0);
13209 ++#endif
13210 ++
13211 + set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
13212 ++
13213 ++#ifdef CONFIG_PAX_KERNEXEC
13214 ++ pax_close_kernel(cr0);
13215 ++#endif
13216 ++
13217 + arch_flush_lazy_mmu_mode();
13218 +
13219 + return (void*) vaddr;
13220 +diff -urNp linux-2.6.28.8/arch/x86/mm/hugetlbpage.c linux-2.6.28.8/arch/x86/mm/hugetlbpage.c
13221 +--- linux-2.6.28.8/arch/x86/mm/hugetlbpage.c 2009-02-06 16:47:45.000000000 -0500
13222 ++++ linux-2.6.28.8/arch/x86/mm/hugetlbpage.c 2009-02-21 09:37:48.000000000 -0500
13223 +@@ -263,13 +263,18 @@ static unsigned long hugetlb_get_unmappe
13224 + struct hstate *h = hstate_file(file);
13225 + struct mm_struct *mm = current->mm;
13226 + struct vm_area_struct *vma;
13227 +- unsigned long start_addr;
13228 ++ unsigned long start_addr, pax_task_size = TASK_SIZE;
13229 ++
13230 ++#ifdef CONFIG_PAX_SEGMEXEC
13231 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
13232 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
13233 ++#endif
13234 +
13235 + if (len > mm->cached_hole_size) {
13236 +- start_addr = mm->free_area_cache;
13237 ++ start_addr = mm->free_area_cache;
13238 + } else {
13239 +- start_addr = TASK_UNMAPPED_BASE;
13240 +- mm->cached_hole_size = 0;
13241 ++ start_addr = mm->mmap_base;
13242 ++ mm->cached_hole_size = 0;
13243 + }
13244 +
13245 + full_search:
13246 +@@ -277,13 +282,13 @@ full_search:
13247 +
13248 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
13249 + /* At this point: (!vma || addr < vma->vm_end). */
13250 +- if (TASK_SIZE - len < addr) {
13251 ++ if (pax_task_size - len < addr) {
13252 + /*
13253 + * Start a new search - just in case we missed
13254 + * some holes.
13255 + */
13256 +- if (start_addr != TASK_UNMAPPED_BASE) {
13257 +- start_addr = TASK_UNMAPPED_BASE;
13258 ++ if (start_addr != mm->mmap_base) {
13259 ++ start_addr = mm->mmap_base;
13260 + mm->cached_hole_size = 0;
13261 + goto full_search;
13262 + }
13263 +@@ -306,9 +311,8 @@ static unsigned long hugetlb_get_unmappe
13264 + struct hstate *h = hstate_file(file);
13265 + struct mm_struct *mm = current->mm;
13266 + struct vm_area_struct *vma, *prev_vma;
13267 +- unsigned long base = mm->mmap_base, addr = addr0;
13268 ++ unsigned long base = mm->mmap_base, addr;
13269 + unsigned long largest_hole = mm->cached_hole_size;
13270 +- int first_time = 1;
13271 +
13272 + /* don't allow allocations above current base */
13273 + if (mm->free_area_cache > base)
13274 +@@ -318,7 +322,7 @@ static unsigned long hugetlb_get_unmappe
13275 + largest_hole = 0;
13276 + mm->free_area_cache = base;
13277 + }
13278 +-try_again:
13279 ++
13280 + /* make sure it can fit in the remaining address space */
13281 + if (mm->free_area_cache < len)
13282 + goto fail;
13283 +@@ -360,22 +364,26 @@ try_again:
13284 +
13285 + fail:
13286 + /*
13287 +- * if hint left us with no space for the requested
13288 +- * mapping then try again:
13289 +- */
13290 +- if (first_time) {
13291 +- mm->free_area_cache = base;
13292 +- largest_hole = 0;
13293 +- first_time = 0;
13294 +- goto try_again;
13295 +- }
13296 +- /*
13297 + * A failed mmap() very likely causes application failure,
13298 + * so fall back to the bottom-up function here. This scenario
13299 + * can happen with large stack limits and large mmap()
13300 + * allocations.
13301 + */
13302 +- mm->free_area_cache = TASK_UNMAPPED_BASE;
13303 ++
13304 ++#ifdef CONFIG_PAX_SEGMEXEC
13305 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
13306 ++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
13307 ++ else
13308 ++#endif
13309 ++
13310 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
13311 ++
13312 ++#ifdef CONFIG_PAX_RANDMMAP
13313 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
13314 ++ mm->mmap_base += mm->delta_mmap;
13315 ++#endif
13316 ++
13317 ++ mm->free_area_cache = mm->mmap_base;
13318 + mm->cached_hole_size = ~0UL;
13319 + addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
13320 + len, pgoff, flags);
13321 +@@ -383,6 +391,7 @@ fail:
13322 + /*
13323 + * Restore the topdown base:
13324 + */
13325 ++ mm->mmap_base = base;
13326 + mm->free_area_cache = base;
13327 + mm->cached_hole_size = ~0UL;
13328 +
13329 +@@ -396,10 +405,17 @@ hugetlb_get_unmapped_area(struct file *f
13330 + struct hstate *h = hstate_file(file);
13331 + struct mm_struct *mm = current->mm;
13332 + struct vm_area_struct *vma;
13333 ++ unsigned long pax_task_size = TASK_SIZE;
13334 +
13335 + if (len & ~huge_page_mask(h))
13336 + return -EINVAL;
13337 +- if (len > TASK_SIZE)
13338 ++
13339 ++#ifdef CONFIG_PAX_SEGMEXEC
13340 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
13341 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
13342 ++#endif
13343 ++
13344 ++ if (len > pax_task_size)
13345 + return -ENOMEM;
13346 +
13347 + if (flags & MAP_FIXED) {
13348 +@@ -411,7 +427,7 @@ hugetlb_get_unmapped_area(struct file *f
13349 + if (addr) {
13350 + addr = ALIGN(addr, huge_page_size(h));
13351 + vma = find_vma(mm, addr);
13352 +- if (TASK_SIZE - len >= addr &&
13353 ++ if (pax_task_size - len >= addr &&
13354 + (!vma || addr + len <= vma->vm_start))
13355 + return addr;
13356 + }
13357 +diff -urNp linux-2.6.28.8/arch/x86/mm/init_32.c linux-2.6.28.8/arch/x86/mm/init_32.c
13358 +--- linux-2.6.28.8/arch/x86/mm/init_32.c 2009-02-06 16:47:45.000000000 -0500
13359 ++++ linux-2.6.28.8/arch/x86/mm/init_32.c 2009-02-21 09:37:48.000000000 -0500
13360 +@@ -49,6 +49,7 @@
13361 + #include <asm/setup.h>
13362 + #include <asm/cacheflush.h>
13363 + #include <asm/smp.h>
13364 ++#include <asm/desc.h>
13365 +
13366 + unsigned int __VMALLOC_RESERVE = 128 << 20;
13367 +
13368 +@@ -82,35 +83,6 @@ static __init void *alloc_low_page(unsig
13369 + }
13370 +
13371 + /*
13372 +- * Creates a middle page table and puts a pointer to it in the
13373 +- * given global directory entry. This only returns the gd entry
13374 +- * in non-PAE compilation mode, since the middle layer is folded.
13375 +- */
13376 +-static pmd_t * __init one_md_table_init(pgd_t *pgd)
13377 +-{
13378 +- pud_t *pud;
13379 +- pmd_t *pmd_table;
13380 +-
13381 +-#ifdef CONFIG_X86_PAE
13382 +- unsigned long phys;
13383 +- if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
13384 +- if (after_init_bootmem)
13385 +- pmd_table = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
13386 +- else
13387 +- pmd_table = (pmd_t *)alloc_low_page(&phys);
13388 +- paravirt_alloc_pmd(&init_mm, __pa(pmd_table) >> PAGE_SHIFT);
13389 +- set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
13390 +- pud = pud_offset(pgd, 0);
13391 +- BUG_ON(pmd_table != pmd_offset(pud, 0));
13392 +- }
13393 +-#endif
13394 +- pud = pud_offset(pgd, 0);
13395 +- pmd_table = pmd_offset(pud, 0);
13396 +-
13397 +- return pmd_table;
13398 +-}
13399 +-
13400 +-/*
13401 + * Create a page table and place a pointer to it in a middle page
13402 + * directory entry:
13403 + */
13404 +@@ -132,7 +104,11 @@ static pte_t * __init one_page_table_ini
13405 + }
13406 +
13407 + paravirt_alloc_pte(&init_mm, __pa(page_table) >> PAGE_SHIFT);
13408 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
13409 ++ set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
13410 ++#else
13411 + set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
13412 ++#endif
13413 + BUG_ON(page_table != pte_offset_kernel(pmd, 0));
13414 + }
13415 +
13416 +@@ -154,6 +130,7 @@ page_table_range_init(unsigned long star
13417 + int pgd_idx, pmd_idx;
13418 + unsigned long vaddr;
13419 + pgd_t *pgd;
13420 ++ pud_t *pud;
13421 + pmd_t *pmd;
13422 +
13423 + vaddr = start;
13424 +@@ -162,8 +139,13 @@ page_table_range_init(unsigned long star
13425 + pgd = pgd_base + pgd_idx;
13426 +
13427 + for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
13428 +- pmd = one_md_table_init(pgd);
13429 +- pmd = pmd + pmd_index(vaddr);
13430 ++ pud = pud_offset(pgd, vaddr);
13431 ++ pmd = pmd_offset(pud, vaddr);
13432 ++
13433 ++#ifdef CONFIG_X86_PAE
13434 ++ paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
13435 ++#endif
13436 ++
13437 + for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end);
13438 + pmd++, pmd_idx++) {
13439 + one_page_table_init(pmd);
13440 +@@ -174,11 +156,23 @@ page_table_range_init(unsigned long star
13441 + }
13442 + }
13443 +
13444 +-static inline int is_kernel_text(unsigned long addr)
13445 ++static inline int is_kernel_text(unsigned long start, unsigned long end)
13446 + {
13447 +- if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
13448 +- return 1;
13449 +- return 0;
13450 ++ unsigned long etext;
13451 ++
13452 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13453 ++ etext = ktva_ktla((unsigned long)&MODULES_END);
13454 ++#else
13455 ++ etext = (unsigned long)&_etext;
13456 ++#endif
13457 ++
13458 ++ if ((start > ktla_ktva(etext) ||
13459 ++ end <= ktla_ktva((unsigned long)_stext)) &&
13460 ++ (start > ktla_ktva((unsigned long)_einittext) ||
13461 ++ end <= ktla_ktva((unsigned long)_sinittext)) &&
13462 ++ (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000)))
13463 ++ return 0;
13464 ++ return 1;
13465 + }
13466 +
13467 + /*
13468 +@@ -191,9 +185,10 @@ static void __init kernel_physical_mappi
13469 + unsigned long end_pfn,
13470 + int use_pse)
13471 + {
13472 +- int pgd_idx, pmd_idx, pte_ofs;
13473 ++ unsigned int pgd_idx, pmd_idx, pte_ofs;
13474 + unsigned long pfn;
13475 + pgd_t *pgd;
13476 ++ pud_t *pud;
13477 + pmd_t *pmd;
13478 + pte_t *pte;
13479 + unsigned pages_2m, pages_4k;
13480 +@@ -223,8 +218,13 @@ repeat:
13481 + pfn = start_pfn;
13482 + pgd_idx = pgd_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET);
13483 + pgd = pgd_base + pgd_idx;
13484 +- for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
13485 +- pmd = one_md_table_init(pgd);
13486 ++ for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
13487 ++ pud = pud_offset(pgd, 0);
13488 ++ pmd = pmd_offset(pud, 0);
13489 ++
13490 ++#ifdef CONFIG_X86_PAE
13491 ++ paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
13492 ++#endif
13493 +
13494 + if (pfn >= end_pfn)
13495 + continue;
13496 +@@ -236,14 +236,13 @@ repeat:
13497 + #endif
13498 + for (; pmd_idx < PTRS_PER_PMD && pfn < end_pfn;
13499 + pmd++, pmd_idx++) {
13500 +- unsigned int addr = pfn * PAGE_SIZE + PAGE_OFFSET;
13501 ++ unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
13502 +
13503 + /*
13504 + * Map with big pages if possible, otherwise
13505 + * create normal page tables:
13506 + */
13507 + if (use_pse) {
13508 +- unsigned int addr2;
13509 + pgprot_t prot = PAGE_KERNEL_LARGE;
13510 + /*
13511 + * first pass will use the same initial
13512 +@@ -253,11 +252,7 @@ repeat:
13513 + __pgprot(PTE_IDENT_ATTR |
13514 + _PAGE_PSE);
13515 +
13516 +- addr2 = (pfn + PTRS_PER_PTE-1) * PAGE_SIZE +
13517 +- PAGE_OFFSET + PAGE_SIZE-1;
13518 +-
13519 +- if (is_kernel_text(addr) ||
13520 +- is_kernel_text(addr2))
13521 ++ if (is_kernel_text(address, address + PMD_SIZE))
13522 + prot = PAGE_KERNEL_LARGE_EXEC;
13523 +
13524 + pages_2m++;
13525 +@@ -274,7 +269,7 @@ repeat:
13526 + pte_ofs = pte_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET);
13527 + pte += pte_ofs;
13528 + for (; pte_ofs < PTRS_PER_PTE && pfn < end_pfn;
13529 +- pte++, pfn++, pte_ofs++, addr += PAGE_SIZE) {
13530 ++ pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
13531 + pgprot_t prot = PAGE_KERNEL;
13532 + /*
13533 + * first pass will use the same initial
13534 +@@ -282,7 +277,7 @@ repeat:
13535 + */
13536 + pgprot_t init_prot = __pgprot(PTE_IDENT_ATTR);
13537 +
13538 +- if (is_kernel_text(addr))
13539 ++ if (is_kernel_text(address, address + PAGE_SIZE))
13540 + prot = PAGE_KERNEL_EXEC;
13541 +
13542 + pages_4k++;
13543 +@@ -327,7 +322,9 @@ repeat:
13544 + */
13545 + int devmem_is_allowed(unsigned long pagenr)
13546 + {
13547 +- if (pagenr <= 256)
13548 ++ if (!pagenr)
13549 ++ return 1;
13550 ++ if ((ISA_START_ADDRESS >> PAGE_SHIFT) <= pagenr && pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
13551 + return 1;
13552 + if (!page_is_ram(pagenr))
13553 + return 1;
13554 +@@ -460,7 +457,7 @@ void __init native_pagetable_setup_start
13555 +
13556 + pud = pud_offset(pgd, va);
13557 + pmd = pmd_offset(pud, va);
13558 +- if (!pmd_present(*pmd))
13559 ++ if (!pmd_present(*pmd) || pmd_huge(*pmd))
13560 + break;
13561 +
13562 + pte = pte_offset_kernel(pmd, va);
13563 +@@ -512,9 +509,7 @@ static void __init early_ioremap_page_ta
13564 +
13565 + static void __init pagetable_init(void)
13566 + {
13567 +- pgd_t *pgd_base = swapper_pg_dir;
13568 +-
13569 +- permanent_kmaps_init(pgd_base);
13570 ++ permanent_kmaps_init(swapper_pg_dir);
13571 + }
13572 +
13573 + #ifdef CONFIG_ACPI_SLEEP
13574 +@@ -522,12 +517,12 @@ static void __init pagetable_init(void)
13575 + * ACPI suspend needs this for resume, because things like the intel-agp
13576 + * driver might have split up a kernel 4MB mapping.
13577 + */
13578 +-char swsusp_pg_dir[PAGE_SIZE]
13579 ++pgd_t swsusp_pg_dir[PTRS_PER_PGD]
13580 + __attribute__ ((aligned(PAGE_SIZE)));
13581 +
13582 + static inline void save_pg_dir(void)
13583 + {
13584 +- memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
13585 ++ clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD);
13586 + }
13587 + #else /* !CONFIG_ACPI_SLEEP */
13588 + static inline void save_pg_dir(void)
13589 +@@ -557,13 +552,11 @@ void zap_low_mappings(void)
13590 +
13591 + int nx_enabled;
13592 +
13593 +-pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL | _PAGE_IOMAP);
13594 ++pteval_t __supported_pte_mask __read_only = ~(_PAGE_NX | _PAGE_GLOBAL | _PAGE_IOMAP);
13595 + EXPORT_SYMBOL_GPL(__supported_pte_mask);
13596 +
13597 + #ifdef CONFIG_X86_PAE
13598 +
13599 +-static int disable_nx __initdata;
13600 +-
13601 + /*
13602 + * noexec = on|off
13603 + *
13604 +@@ -572,40 +565,33 @@ static int disable_nx __initdata;
13605 + * on Enable
13606 + * off Disable
13607 + */
13608 ++#if !defined(CONFIG_PAX_PAGEEXEC)
13609 + static int __init noexec_setup(char *str)
13610 + {
13611 + if (!str || !strcmp(str, "on")) {
13612 +- if (cpu_has_nx) {
13613 +- __supported_pte_mask |= _PAGE_NX;
13614 +- disable_nx = 0;
13615 +- }
13616 ++ if (cpu_has_nx)
13617 ++ nx_enabled = 1;
13618 + } else {
13619 +- if (!strcmp(str, "off")) {
13620 +- disable_nx = 1;
13621 +- __supported_pte_mask &= ~_PAGE_NX;
13622 +- } else {
13623 ++ if (!strcmp(str, "off"))
13624 ++ nx_enabled = 0;
13625 ++ else
13626 + return -EINVAL;
13627 +- }
13628 + }
13629 +
13630 + return 0;
13631 + }
13632 + early_param("noexec", noexec_setup);
13633 ++#endif
13634 +
13635 + static void __init set_nx(void)
13636 + {
13637 +- unsigned int v[4], l, h;
13638 +-
13639 +- if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
13640 +- cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
13641 ++ if (!nx_enabled && cpu_has_nx) {
13642 ++ unsigned l, h;
13643 +
13644 +- if ((v[3] & (1 << 20)) && !disable_nx) {
13645 +- rdmsr(MSR_EFER, l, h);
13646 +- l |= EFER_NX;
13647 +- wrmsr(MSR_EFER, l, h);
13648 +- nx_enabled = 1;
13649 +- __supported_pte_mask |= _PAGE_NX;
13650 +- }
13651 ++ __supported_pte_mask &= ~_PAGE_NX;
13652 ++ rdmsr(MSR_EFER, l, h);
13653 ++ l &= ~EFER_NX;
13654 ++ wrmsr(MSR_EFER, l, h);
13655 + }
13656 + }
13657 + #endif
13658 +@@ -988,7 +974,7 @@ void __init mem_init(void)
13659 + set_highmem_pages_init();
13660 +
13661 + codesize = (unsigned long) &_etext - (unsigned long) &_text;
13662 +- datasize = (unsigned long) &_edata - (unsigned long) &_etext;
13663 ++ datasize = (unsigned long) &_edata - (unsigned long) &_data;
13664 + initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
13665 +
13666 + kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
13667 +@@ -1034,10 +1020,10 @@ void __init mem_init(void)
13668 + ((unsigned long)&__init_end -
13669 + (unsigned long)&__init_begin) >> 10,
13670 +
13671 +- (unsigned long)&_etext, (unsigned long)&_edata,
13672 +- ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
13673 ++ (unsigned long)&_data, (unsigned long)&_edata,
13674 ++ ((unsigned long)&_edata - (unsigned long)&_data) >> 10,
13675 +
13676 +- (unsigned long)&_text, (unsigned long)&_etext,
13677 ++ ktla_ktva((unsigned long)&_text), ktla_ktva((unsigned long)&_etext),
13678 + ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
13679 +
13680 + #ifdef CONFIG_HIGHMEM
13681 +@@ -1166,6 +1152,46 @@ void free_init_pages(char *what, unsigne
13682 +
13683 + void free_initmem(void)
13684 + {
13685 ++
13686 ++#ifdef CONFIG_PAX_KERNEXEC
13687 ++ /* PaX: limit KERNEL_CS to actual size */
13688 ++ unsigned long addr, limit;
13689 ++ struct desc_struct d;
13690 ++ int cpu;
13691 ++ pgd_t *pgd;
13692 ++ pud_t *pud;
13693 ++ pmd_t *pmd;
13694 ++
13695 ++#ifdef CONFIG_MODULES
13696 ++ limit = ktva_ktla((unsigned long)&MODULES_END);
13697 ++#else
13698 ++ limit = (unsigned long)&_etext;
13699 ++#endif
13700 ++ limit = (limit - 1UL) >> PAGE_SHIFT;
13701 ++
13702 ++ for (cpu = 0; cpu < NR_CPUS; cpu++) {
13703 ++ pack_descriptor(&d, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC);
13704 ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, &d, DESCTYPE_S);
13705 ++ }
13706 ++
13707 ++ /* PaX: make KERNEL_CS read-only */
13708 ++ for (addr = ktla_ktva((unsigned long)&_text); addr < (unsigned long)&_data; addr += PMD_SIZE) {
13709 ++ pgd = pgd_offset_k(addr);
13710 ++ pud = pud_offset(pgd, addr);
13711 ++ pmd = pmd_offset(pud, addr);
13712 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
13713 ++ }
13714 ++#ifdef CONFIG_X86_PAE
13715 ++ for (addr = (unsigned long)&__init_begin; addr < (unsigned long)&__init_end; addr += PMD_SIZE) {
13716 ++ pgd = pgd_offset_k(addr);
13717 ++ pud = pud_offset(pgd, addr);
13718 ++ pmd = pmd_offset(pud, addr);
13719 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
13720 ++ }
13721 ++#endif
13722 ++ flush_tlb_all();
13723 ++#endif
13724 ++
13725 + free_init_pages("unused kernel memory",
13726 + (unsigned long)(&__init_begin),
13727 + (unsigned long)(&__init_end));
13728 +diff -urNp linux-2.6.28.8/arch/x86/mm/init_64.c linux-2.6.28.8/arch/x86/mm/init_64.c
13729 +--- linux-2.6.28.8/arch/x86/mm/init_64.c 2009-02-06 16:47:45.000000000 -0500
13730 ++++ linux-2.6.28.8/arch/x86/mm/init_64.c 2009-02-21 09:37:48.000000000 -0500
13731 +@@ -175,6 +175,10 @@ set_pte_vaddr_pud(pud_t *pud_page, unsig
13732 + pmd_t *pmd;
13733 + pte_t *pte;
13734 +
13735 ++#ifdef CONFIG_PAX_KERNEXEC
13736 ++ unsigned long cr0;
13737 ++#endif
13738 ++
13739 + pud = pud_page + pud_index(vaddr);
13740 + if (pud_none(*pud)) {
13741 + pmd = (pmd_t *) spp_getpage();
13742 +@@ -196,8 +200,17 @@ set_pte_vaddr_pud(pud_t *pud_page, unsig
13743 + }
13744 +
13745 + pte = pte_offset_kernel(pmd, vaddr);
13746 ++
13747 ++#ifdef CONFIG_PAX_KERNEXEC
13748 ++ pax_open_kernel(cr0);
13749 ++#endif
13750 ++
13751 + set_pte(pte, new_pte);
13752 +
13753 ++#ifdef CONFIG_PAX_KERNEXEC
13754 ++ pax_close_kernel(cr0);
13755 ++#endif
13756 ++
13757 + /*
13758 + * It's enough to flush this one mapping.
13759 + * (PGE mappings get flushed as well)
13760 +@@ -238,14 +251,12 @@ static void __init __init_extra_mapping(
13761 + pgd = pgd_offset_k((unsigned long)__va(phys));
13762 + if (pgd_none(*pgd)) {
13763 + pud = (pud_t *) spp_getpage();
13764 +- set_pgd(pgd, __pgd(__pa(pud) | _KERNPG_TABLE |
13765 +- _PAGE_USER));
13766 ++ set_pgd(pgd, __pgd(__pa(pud) | _PAGE_TABLE));
13767 + }
13768 + pud = pud_offset(pgd, (unsigned long)__va(phys));
13769 + if (pud_none(*pud)) {
13770 + pmd = (pmd_t *) spp_getpage();
13771 +- set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE |
13772 +- _PAGE_USER));
13773 ++ set_pud(pud, __pud(__pa(pmd) | _PAGE_TABLE));
13774 + }
13775 + pmd = pmd_offset(pud, phys);
13776 + BUG_ON(!pmd_none(*pmd));
13777 +@@ -886,7 +897,9 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to
13778 + */
13779 + int devmem_is_allowed(unsigned long pagenr)
13780 + {
13781 +- if (pagenr <= 256)
13782 ++ if (!pagenr)
13783 ++ return 1;
13784 ++ if ((ISA_START_ADDRESS >> PAGE_SHIFT) <= pagenr && pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
13785 + return 1;
13786 + if (!page_is_ram(pagenr))
13787 + return 1;
13788 +@@ -977,6 +990,39 @@ void free_init_pages(char *what, unsigne
13789 +
13790 + void free_initmem(void)
13791 + {
13792 ++
13793 ++#ifdef CONFIG_PAX_KERNEXEC
13794 ++ unsigned long addr, end;
13795 ++ pgd_t *pgd;
13796 ++ pud_t *pud;
13797 ++ pmd_t *pmd;
13798 ++
13799 ++ /* PaX: make kernel code/rodata read-only, rest non-executable */
13800 ++ for (addr = __START_KERNEL_map; addr < __START_KERNEL_map + KERNEL_IMAGE_SIZE; addr += PMD_SIZE) {
13801 ++ pgd = pgd_offset_k(addr);
13802 ++ pud = pud_offset(pgd, addr);
13803 ++ pmd = pmd_offset(pud, addr);
13804 ++ if ((unsigned long)_text <= addr && addr < (unsigned long)_data)
13805 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
13806 ++ else
13807 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
13808 ++ }
13809 ++
13810 ++ addr = (unsigned long)__va(__pa(__START_KERNEL_map));
13811 ++ end = addr + KERNEL_IMAGE_SIZE;
13812 ++ for (; addr < end; addr += PMD_SIZE) {
13813 ++ pgd = pgd_offset_k(addr);
13814 ++ pud = pud_offset(pgd, addr);
13815 ++ pmd = pmd_offset(pud, addr);
13816 ++ if ((unsigned long)__va(__pa(_text)) <= addr && addr < (unsigned long)__va(__pa(_data)))
13817 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
13818 ++ else
13819 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
13820 ++ }
13821 ++
13822 ++ flush_tlb_all();
13823 ++#endif
13824 ++
13825 + free_init_pages("unused kernel memory",
13826 + (unsigned long)(&__init_begin),
13827 + (unsigned long)(&__init_end));
13828 +@@ -1149,7 +1195,7 @@ int in_gate_area_no_task(unsigned long a
13829 +
13830 + const char *arch_vma_name(struct vm_area_struct *vma)
13831 + {
13832 +- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
13833 ++ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
13834 + return "[vdso]";
13835 + if (vma == &gate_vma)
13836 + return "[vsyscall]";
13837 +diff -urNp linux-2.6.28.8/arch/x86/mm/ioremap.c linux-2.6.28.8/arch/x86/mm/ioremap.c
13838 +--- linux-2.6.28.8/arch/x86/mm/ioremap.c 2009-02-06 16:47:45.000000000 -0500
13839 ++++ linux-2.6.28.8/arch/x86/mm/ioremap.c 2009-02-21 09:37:48.000000000 -0500
13840 +@@ -114,8 +114,8 @@ int page_is_ram(unsigned long pagenr)
13841 + * Second special case: Some BIOSen report the PC BIOS
13842 + * area (640->1Mb) as ram even though it is not.
13843 + */
13844 +- if (pagenr >= (BIOS_BEGIN >> PAGE_SHIFT) &&
13845 +- pagenr < (BIOS_END >> PAGE_SHIFT))
13846 ++ if (pagenr >= (ISA_START_ADDRESS >> PAGE_SHIFT) &&
13847 ++ pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
13848 + return 0;
13849 +
13850 + for (i = 0; i < e820.nr_map; i++) {
13851 +@@ -293,6 +293,8 @@ static void __iomem *__ioremap_caller(re
13852 + break;
13853 + }
13854 +
13855 ++ prot = canon_pgprot(prot);
13856 ++
13857 + /*
13858 + * Ok, go for it..
13859 + */
13860 +@@ -508,7 +510,7 @@ static int __init early_ioremap_debug_se
13861 + early_param("early_ioremap_debug", early_ioremap_debug_setup);
13862 +
13863 + static __initdata int after_paging_init;
13864 +-static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __page_aligned_bss;
13865 ++static __initdata pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __aligned(PAGE_SIZE);
13866 +
13867 + static inline pmd_t * __init early_ioremap_pmd(unsigned long addr)
13868 + {
13869 +@@ -523,7 +525,11 @@ static inline pmd_t * __init early_iorem
13870 +
13871 + static inline pte_t * __init early_ioremap_pte(unsigned long addr)
13872 + {
13873 ++#ifdef CONFIG_X86_32
13874 + return &bm_pte[pte_index(addr)];
13875 ++#else
13876 ++ return &level1_fixmap_pgt[pte_index(addr)];
13877 ++#endif
13878 + }
13879 +
13880 + void __init early_ioremap_init(void)
13881 +@@ -534,8 +540,10 @@ void __init early_ioremap_init(void)
13882 + printk(KERN_INFO "early_ioremap_init()\n");
13883 +
13884 + pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));
13885 ++#ifdef CONFIG_X86_32
13886 + memset(bm_pte, 0, sizeof(bm_pte));
13887 + pmd_populate_kernel(&init_mm, pmd, bm_pte);
13888 ++#endif
13889 +
13890 + /*
13891 + * The boot-ioremap range spans multiple pmds, for which
13892 +diff -urNp linux-2.6.28.8/arch/x86/mm/mmap.c linux-2.6.28.8/arch/x86/mm/mmap.c
13893 +--- linux-2.6.28.8/arch/x86/mm/mmap.c 2009-02-06 16:47:45.000000000 -0500
13894 ++++ linux-2.6.28.8/arch/x86/mm/mmap.c 2009-02-21 09:37:48.000000000 -0500
13895 +@@ -36,7 +36,7 @@
13896 + * Leave an at least ~128 MB hole.
13897 + */
13898 + #define MIN_GAP (128*1024*1024)
13899 +-#define MAX_GAP (TASK_SIZE/6*5)
13900 ++#define MAX_GAP (pax_task_size/6*5)
13901 +
13902 + /*
13903 + * True on X86_32 or when emulating IA32 on X86_64
13904 +@@ -81,27 +81,40 @@ static unsigned long mmap_rnd(void)
13905 + return rnd << PAGE_SHIFT;
13906 + }
13907 +
13908 +-static unsigned long mmap_base(void)
13909 ++static unsigned long mmap_base(struct mm_struct *mm)
13910 + {
13911 + unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
13912 ++ unsigned long pax_task_size = TASK_SIZE;
13913 ++
13914 ++#ifdef CONFIG_PAX_SEGMEXEC
13915 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
13916 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
13917 ++#endif
13918 +
13919 + if (gap < MIN_GAP)
13920 + gap = MIN_GAP;
13921 + else if (gap > MAX_GAP)
13922 + gap = MAX_GAP;
13923 +
13924 +- return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
13925 ++ return PAGE_ALIGN(pax_task_size - gap - mmap_rnd());
13926 + }
13927 +
13928 + /*
13929 + * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64
13930 + * does, but not when emulating X86_32
13931 + */
13932 +-static unsigned long mmap_legacy_base(void)
13933 ++static unsigned long mmap_legacy_base(struct mm_struct *mm)
13934 + {
13935 +- if (mmap_is_ia32())
13936 ++ if (mmap_is_ia32()) {
13937 ++
13938 ++#ifdef CONFIG_PAX_SEGMEXEC
13939 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
13940 ++ return SEGMEXEC_TASK_UNMAPPED_BASE;
13941 ++ else
13942 ++#endif
13943 ++
13944 + return TASK_UNMAPPED_BASE;
13945 +- else
13946 ++ } else
13947 + return TASK_UNMAPPED_BASE + mmap_rnd();
13948 + }
13949 +
13950 +@@ -112,11 +125,23 @@ static unsigned long mmap_legacy_base(vo
13951 + void arch_pick_mmap_layout(struct mm_struct *mm)
13952 + {
13953 + if (mmap_is_legacy()) {
13954 +- mm->mmap_base = mmap_legacy_base();
13955 ++ mm->mmap_base = mmap_legacy_base(mm);
13956 ++
13957 ++#ifdef CONFIG_PAX_RANDMMAP
13958 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
13959 ++ mm->mmap_base += mm->delta_mmap;
13960 ++#endif
13961 ++
13962 + mm->get_unmapped_area = arch_get_unmapped_area;
13963 + mm->unmap_area = arch_unmap_area;
13964 + } else {
13965 +- mm->mmap_base = mmap_base();
13966 ++ mm->mmap_base = mmap_base(mm);
13967 ++
13968 ++#ifdef CONFIG_PAX_RANDMMAP
13969 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
13970 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
13971 ++#endif
13972 ++
13973 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
13974 + mm->unmap_area = arch_unmap_area_topdown;
13975 + }
13976 +diff -urNp linux-2.6.28.8/arch/x86/mm/numa_32.c linux-2.6.28.8/arch/x86/mm/numa_32.c
13977 +--- linux-2.6.28.8/arch/x86/mm/numa_32.c 2009-02-06 16:47:45.000000000 -0500
13978 ++++ linux-2.6.28.8/arch/x86/mm/numa_32.c 2009-02-21 09:37:48.000000000 -0500
13979 +@@ -98,7 +98,6 @@ unsigned long node_memmap_size_bytes(int
13980 + }
13981 + #endif
13982 +
13983 +-extern unsigned long find_max_low_pfn(void);
13984 + extern unsigned long highend_pfn, highstart_pfn;
13985 +
13986 + #define LARGE_PAGE_BYTES (PTRS_PER_PTE * PAGE_SIZE)
13987 +diff -urNp linux-2.6.28.8/arch/x86/mm/pageattr.c linux-2.6.28.8/arch/x86/mm/pageattr.c
13988 +--- linux-2.6.28.8/arch/x86/mm/pageattr.c 2009-02-20 22:26:38.000000000 -0500
13989 ++++ linux-2.6.28.8/arch/x86/mm/pageattr.c 2009-02-21 09:37:48.000000000 -0500
13990 +@@ -20,6 +20,7 @@
13991 + #include <asm/pgalloc.h>
13992 + #include <asm/proto.h>
13993 + #include <asm/pat.h>
13994 ++#include <asm/desc.h>
13995 +
13996 + /*
13997 + * The current flushing context - we pass it instead of 5 arguments:
13998 +@@ -259,7 +260,7 @@ static inline pgprot_t static_protection
13999 + * Does not cover __inittext since that is gone later on. On
14000 + * 64bit we do not enforce !NX on the low mapping
14001 + */
14002 +- if (within(address, (unsigned long)_text, (unsigned long)_etext))
14003 ++ if (within(address, ktla_ktva((unsigned long)_text), ktla_ktva((unsigned long)_etext)))
14004 + pgprot_val(forbidden) |= _PAGE_NX;
14005 +
14006 + /*
14007 +@@ -321,8 +322,20 @@ EXPORT_SYMBOL_GPL(lookup_address);
14008 + */
14009 + static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
14010 + {
14011 ++
14012 ++#ifdef CONFIG_PAX_KERNEXEC
14013 ++ unsigned long cr0;
14014 ++
14015 ++ pax_open_kernel(cr0);
14016 ++#endif
14017 ++
14018 + /* change init_mm */
14019 + set_pte_atomic(kpte, pte);
14020 ++
14021 ++#ifdef CONFIG_PAX_KERNEXEC
14022 ++ pax_close_kernel(cr0);
14023 ++#endif
14024 ++
14025 + #ifdef CONFIG_X86_32
14026 + if (!SHARED_KERNEL_PMD) {
14027 + struct page *page;
14028 +diff -urNp linux-2.6.28.8/arch/x86/mm/pageattr-test.c linux-2.6.28.8/arch/x86/mm/pageattr-test.c
14029 +--- linux-2.6.28.8/arch/x86/mm/pageattr-test.c 2009-02-06 16:47:45.000000000 -0500
14030 ++++ linux-2.6.28.8/arch/x86/mm/pageattr-test.c 2009-03-07 10:35:39.000000000 -0500
14031 +@@ -36,7 +36,7 @@ enum {
14032 +
14033 + static int pte_testbit(pte_t pte)
14034 + {
14035 +- return pte_flags(pte) & _PAGE_UNUSED1;
14036 ++ return pte_flags(pte) & _PAGE_CPA_TEST;
14037 + }
14038 +
14039 + struct split_state {
14040 +diff -urNp linux-2.6.28.8/arch/x86/mm/pat.c linux-2.6.28.8/arch/x86/mm/pat.c
14041 +--- linux-2.6.28.8/arch/x86/mm/pat.c 2009-02-06 16:47:45.000000000 -0500
14042 ++++ linux-2.6.28.8/arch/x86/mm/pat.c 2009-03-07 14:05:58.000000000 -0500
14043 +@@ -491,7 +491,7 @@ pgprot_t phys_mem_access_prot(struct fil
14044 + return vma_prot;
14045 + }
14046 +
14047 +-#ifdef CONFIG_STRICT_DEVMEM
14048 ++#ifndef CONFIG_STRICT_DEVMEM
14049 + /* This check is done in drivers/char/mem.c in case of STRICT_DEVMEM*/
14050 + static inline int range_is_allowed(unsigned long pfn, unsigned long size)
14051 + {
14052 +diff -urNp linux-2.6.28.8/arch/x86/mm/pgtable_32.c linux-2.6.28.8/arch/x86/mm/pgtable_32.c
14053 +--- linux-2.6.28.8/arch/x86/mm/pgtable_32.c 2009-02-06 16:47:45.000000000 -0500
14054 ++++ linux-2.6.28.8/arch/x86/mm/pgtable_32.c 2009-02-21 09:37:48.000000000 -0500
14055 +@@ -31,6 +31,10 @@ void set_pte_vaddr(unsigned long vaddr,
14056 + pmd_t *pmd;
14057 + pte_t *pte;
14058 +
14059 ++#ifdef CONFIG_PAX_KERNEXEC
14060 ++ unsigned long cr0;
14061 ++#endif
14062 ++
14063 + pgd = swapper_pg_dir + pgd_index(vaddr);
14064 + if (pgd_none(*pgd)) {
14065 + BUG();
14066 +@@ -47,11 +51,20 @@ void set_pte_vaddr(unsigned long vaddr,
14067 + return;
14068 + }
14069 + pte = pte_offset_kernel(pmd, vaddr);
14070 ++
14071 ++#ifdef CONFIG_PAX_KERNEXEC
14072 ++ pax_open_kernel(cr0);
14073 ++#endif
14074 ++
14075 + if (pte_val(pteval))
14076 + set_pte_present(&init_mm, vaddr, pte, pteval);
14077 + else
14078 + pte_clear(&init_mm, vaddr, pte);
14079 +
14080 ++#ifdef CONFIG_PAX_KERNEXEC
14081 ++ pax_close_kernel(cr0);
14082 ++#endif
14083 ++
14084 + /*
14085 + * It's enough to flush this one mapping.
14086 + * (PGE mappings get flushed as well)
14087 +diff -urNp linux-2.6.28.8/arch/x86/oprofile/backtrace.c linux-2.6.28.8/arch/x86/oprofile/backtrace.c
14088 +--- linux-2.6.28.8/arch/x86/oprofile/backtrace.c 2009-02-06 16:47:45.000000000 -0500
14089 ++++ linux-2.6.28.8/arch/x86/oprofile/backtrace.c 2009-02-21 09:37:48.000000000 -0500
14090 +@@ -37,7 +37,7 @@ static void backtrace_address(void *data
14091 + unsigned int *depth = data;
14092 +
14093 + if ((*depth)--)
14094 +- oprofile_add_trace(addr);
14095 ++ oprofile_add_trace(ktla_ktva(addr));
14096 + }
14097 +
14098 + static struct stacktrace_ops backtrace_ops = {
14099 +@@ -78,7 +78,7 @@ x86_backtrace(struct pt_regs * const reg
14100 + struct frame_head *head = (struct frame_head *)frame_pointer(regs);
14101 + unsigned long stack = kernel_trap_sp(regs);
14102 +
14103 +- if (!user_mode_vm(regs)) {
14104 ++ if (!user_mode(regs)) {
14105 + if (depth)
14106 + dump_trace(NULL, regs, (unsigned long *)stack, 0,
14107 + &backtrace_ops, &depth);
14108 +diff -urNp linux-2.6.28.8/arch/x86/oprofile/op_model_p4.c linux-2.6.28.8/arch/x86/oprofile/op_model_p4.c
14109 +--- linux-2.6.28.8/arch/x86/oprofile/op_model_p4.c 2009-02-06 16:47:45.000000000 -0500
14110 ++++ linux-2.6.28.8/arch/x86/oprofile/op_model_p4.c 2009-02-21 09:37:48.000000000 -0500
14111 +@@ -48,7 +48,7 @@ static inline void setup_num_counters(vo
14112 + #endif
14113 + }
14114 +
14115 +-static int inline addr_increment(void)
14116 ++static inline int addr_increment(void)
14117 + {
14118 + #ifdef CONFIG_SMP
14119 + return smp_num_siblings == 2 ? 2 : 1;
14120 +diff -urNp linux-2.6.28.8/arch/x86/pci/common.c linux-2.6.28.8/arch/x86/pci/common.c
14121 +--- linux-2.6.28.8/arch/x86/pci/common.c 2009-02-06 16:47:45.000000000 -0500
14122 ++++ linux-2.6.28.8/arch/x86/pci/common.c 2009-02-21 09:37:48.000000000 -0500
14123 +@@ -362,7 +362,7 @@ static struct dmi_system_id __devinitdat
14124 + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"),
14125 + },
14126 + },
14127 +- {}
14128 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL}
14129 + };
14130 +
14131 + void __init dmi_check_pciprobe(void)
14132 +diff -urNp linux-2.6.28.8/arch/x86/pci/fixup.c linux-2.6.28.8/arch/x86/pci/fixup.c
14133 +--- linux-2.6.28.8/arch/x86/pci/fixup.c 2009-02-06 16:47:45.000000000 -0500
14134 ++++ linux-2.6.28.8/arch/x86/pci/fixup.c 2009-02-21 09:37:48.000000000 -0500
14135 +@@ -365,7 +365,7 @@ static struct dmi_system_id __devinitdat
14136 + DMI_MATCH(DMI_PRODUCT_NAME, "MS-6702E"),
14137 + },
14138 + },
14139 +- {}
14140 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
14141 + };
14142 +
14143 + /*
14144 +@@ -436,7 +436,7 @@ static struct dmi_system_id __devinitdat
14145 + DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
14146 + },
14147 + },
14148 +- { }
14149 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
14150 + };
14151 +
14152 + static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
14153 +diff -urNp linux-2.6.28.8/arch/x86/pci/irq.c linux-2.6.28.8/arch/x86/pci/irq.c
14154 +--- linux-2.6.28.8/arch/x86/pci/irq.c 2009-02-06 16:47:45.000000000 -0500
14155 ++++ linux-2.6.28.8/arch/x86/pci/irq.c 2009-02-21 09:37:48.000000000 -0500
14156 +@@ -544,7 +544,7 @@ static __init int intel_router_probe(str
14157 + static struct pci_device_id __initdata pirq_440gx[] = {
14158 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
14159 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
14160 +- { },
14161 ++ { PCI_DEVICE(0, 0) }
14162 + };
14163 +
14164 + /* 440GX has a proprietary PIRQ router -- don't use it */
14165 +@@ -1148,7 +1148,7 @@ static struct dmi_system_id __initdata p
14166 + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
14167 + },
14168 + },
14169 +- { }
14170 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
14171 + };
14172 +
14173 + int __init pcibios_irq_init(void)
14174 +diff -urNp linux-2.6.28.8/arch/x86/pci/pcbios.c linux-2.6.28.8/arch/x86/pci/pcbios.c
14175 +--- linux-2.6.28.8/arch/x86/pci/pcbios.c 2009-02-06 16:47:45.000000000 -0500
14176 ++++ linux-2.6.28.8/arch/x86/pci/pcbios.c 2009-02-21 09:37:48.000000000 -0500
14177 +@@ -57,50 +57,120 @@ union bios32 {
14178 + static struct {
14179 + unsigned long address;
14180 + unsigned short segment;
14181 +-} bios32_indirect = { 0, __KERNEL_CS };
14182 ++} bios32_indirect __read_only = { 0, __PCIBIOS_CS };
14183 +
14184 + /*
14185 + * Returns the entry point for the given service, NULL on error
14186 + */
14187 +
14188 +-static unsigned long bios32_service(unsigned long service)
14189 ++static unsigned long __devinit bios32_service(unsigned long service)
14190 + {
14191 + unsigned char return_code; /* %al */
14192 + unsigned long address; /* %ebx */
14193 + unsigned long length; /* %ecx */
14194 + unsigned long entry; /* %edx */
14195 + unsigned long flags;
14196 ++ struct desc_struct d, *gdt;
14197 ++
14198 ++#ifdef CONFIG_PAX_KERNEXEC
14199 ++ unsigned long cr0;
14200 ++#endif
14201 +
14202 + local_irq_save(flags);
14203 +- __asm__("lcall *(%%edi); cld"
14204 ++
14205 ++ gdt = get_cpu_gdt_table(smp_processor_id());
14206 ++
14207 ++#ifdef CONFIG_PAX_KERNEXEC
14208 ++ pax_open_kernel(cr0);
14209 ++#endif
14210 ++
14211 ++ pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x9B, 0xC);
14212 ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
14213 ++ pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x93, 0xC);
14214 ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
14215 ++
14216 ++#ifdef CONFIG_PAX_KERNEXEC
14217 ++ pax_close_kernel(cr0);
14218 ++#endif
14219 ++
14220 ++ __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld"
14221 + : "=a" (return_code),
14222 + "=b" (address),
14223 + "=c" (length),
14224 + "=d" (entry)
14225 + : "0" (service),
14226 + "1" (0),
14227 +- "D" (&bios32_indirect));
14228 ++ "D" (&bios32_indirect),
14229 ++ "r"(__PCIBIOS_DS)
14230 ++ : "memory");
14231 ++
14232 ++#ifdef CONFIG_PAX_KERNEXEC
14233 ++ pax_open_kernel(cr0);
14234 ++#endif
14235 ++
14236 ++ gdt[GDT_ENTRY_PCIBIOS_CS].a = 0;
14237 ++ gdt[GDT_ENTRY_PCIBIOS_CS].b = 0;
14238 ++ gdt[GDT_ENTRY_PCIBIOS_DS].a = 0;
14239 ++ gdt[GDT_ENTRY_PCIBIOS_DS].b = 0;
14240 ++
14241 ++#ifdef CONFIG_PAX_KERNEXEC
14242 ++ pax_close_kernel(cr0);
14243 ++#endif
14244 ++
14245 + local_irq_restore(flags);
14246 +
14247 + switch (return_code) {
14248 +- case 0:
14249 +- return address + entry;
14250 +- case 0x80: /* Not present */
14251 +- printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
14252 +- return 0;
14253 +- default: /* Shouldn't happen */
14254 +- printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
14255 +- service, return_code);
14256 ++ case 0: {
14257 ++ int cpu;
14258 ++ unsigned char flags;
14259 ++
14260 ++ printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry);
14261 ++ if (address >= 0xFFFF0 || length > 0x100000 - address || length <= entry) {
14262 ++ printk(KERN_WARNING "bios32_service: not valid\n");
14263 + return 0;
14264 ++ }
14265 ++ address = address + PAGE_OFFSET;
14266 ++ length += 16UL; /* some BIOSs underreport this... */
14267 ++ flags = 4;
14268 ++ if (length >= 64*1024*1024) {
14269 ++ length >>= PAGE_SHIFT;
14270 ++ flags |= 8;
14271 ++ }
14272 ++
14273 ++#ifdef CONFIG_PAX_KERNEXEC
14274 ++ pax_open_kernel(cr0);
14275 ++#endif
14276 ++
14277 ++ for (cpu = 0; cpu < NR_CPUS; cpu++) {
14278 ++ gdt = get_cpu_gdt_table(cpu);
14279 ++ pack_descriptor(&d, address, length, 0x9b, flags);
14280 ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
14281 ++ pack_descriptor(&d, address, length, 0x93, flags);
14282 ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
14283 ++ }
14284 ++
14285 ++#ifdef CONFIG_PAX_KERNEXEC
14286 ++ pax_close_kernel(cr0);
14287 ++#endif
14288 ++
14289 ++ return entry;
14290 ++ }
14291 ++ case 0x80: /* Not present */
14292 ++ printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
14293 ++ return 0;
14294 ++ default: /* Shouldn't happen */
14295 ++ printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
14296 ++ service, return_code);
14297 ++ return 0;
14298 + }
14299 + }
14300 +
14301 + static struct {
14302 + unsigned long address;
14303 + unsigned short segment;
14304 +-} pci_indirect = { 0, __KERNEL_CS };
14305 ++} pci_indirect __read_only = { 0, __PCIBIOS_CS };
14306 +
14307 +-static int pci_bios_present;
14308 ++static int pci_bios_present __read_only;
14309 +
14310 + static int __devinit check_pcibios(void)
14311 + {
14312 +@@ -109,11 +179,13 @@ static int __devinit check_pcibios(void)
14313 + unsigned long flags, pcibios_entry;
14314 +
14315 + if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
14316 +- pci_indirect.address = pcibios_entry + PAGE_OFFSET;
14317 ++ pci_indirect.address = pcibios_entry;
14318 +
14319 + local_irq_save(flags);
14320 +- __asm__(
14321 +- "lcall *(%%edi); cld\n\t"
14322 ++ __asm__("movw %w6, %%ds\n\t"
14323 ++ "lcall *%%ss:(%%edi); cld\n\t"
14324 ++ "push %%ss\n\t"
14325 ++ "pop %%ds\n\t"
14326 + "jc 1f\n\t"
14327 + "xor %%ah, %%ah\n"
14328 + "1:"
14329 +@@ -122,7 +194,8 @@ static int __devinit check_pcibios(void)
14330 + "=b" (ebx),
14331 + "=c" (ecx)
14332 + : "1" (PCIBIOS_PCI_BIOS_PRESENT),
14333 +- "D" (&pci_indirect)
14334 ++ "D" (&pci_indirect),
14335 ++ "r" (__PCIBIOS_DS)
14336 + : "memory");
14337 + local_irq_restore(flags);
14338 +
14339 +@@ -166,7 +239,10 @@ static int pci_bios_read(unsigned int se
14340 +
14341 + switch (len) {
14342 + case 1:
14343 +- __asm__("lcall *(%%esi); cld\n\t"
14344 ++ __asm__("movw %w6, %%ds\n\t"
14345 ++ "lcall *%%ss:(%%esi); cld\n\t"
14346 ++ "push %%ss\n\t"
14347 ++ "pop %%ds\n\t"
14348 + "jc 1f\n\t"
14349 + "xor %%ah, %%ah\n"
14350 + "1:"
14351 +@@ -175,7 +251,8 @@ static int pci_bios_read(unsigned int se
14352 + : "1" (PCIBIOS_READ_CONFIG_BYTE),
14353 + "b" (bx),
14354 + "D" ((long)reg),
14355 +- "S" (&pci_indirect));
14356 ++ "S" (&pci_indirect),
14357 ++ "r" (__PCIBIOS_DS));
14358 + /*
14359 + * Zero-extend the result beyond 8 bits, do not trust the
14360 + * BIOS having done it:
14361 +@@ -183,7 +260,10 @@ static int pci_bios_read(unsigned int se
14362 + *value &= 0xff;
14363 + break;
14364 + case 2:
14365 +- __asm__("lcall *(%%esi); cld\n\t"
14366 ++ __asm__("movw %w6, %%ds\n\t"
14367 ++ "lcall *%%ss:(%%esi); cld\n\t"
14368 ++ "push %%ss\n\t"
14369 ++ "pop %%ds\n\t"
14370 + "jc 1f\n\t"
14371 + "xor %%ah, %%ah\n"
14372 + "1:"
14373 +@@ -192,7 +272,8 @@ static int pci_bios_read(unsigned int se
14374 + : "1" (PCIBIOS_READ_CONFIG_WORD),
14375 + "b" (bx),
14376 + "D" ((long)reg),
14377 +- "S" (&pci_indirect));
14378 ++ "S" (&pci_indirect),
14379 ++ "r" (__PCIBIOS_DS));
14380 + /*
14381 + * Zero-extend the result beyond 16 bits, do not trust the
14382 + * BIOS having done it:
14383 +@@ -200,7 +281,10 @@ static int pci_bios_read(unsigned int se
14384 + *value &= 0xffff;
14385 + break;
14386 + case 4:
14387 +- __asm__("lcall *(%%esi); cld\n\t"
14388 ++ __asm__("movw %w6, %%ds\n\t"
14389 ++ "lcall *%%ss:(%%esi); cld\n\t"
14390 ++ "push %%ss\n\t"
14391 ++ "pop %%ds\n\t"
14392 + "jc 1f\n\t"
14393 + "xor %%ah, %%ah\n"
14394 + "1:"
14395 +@@ -209,7 +293,8 @@ static int pci_bios_read(unsigned int se
14396 + : "1" (PCIBIOS_READ_CONFIG_DWORD),
14397 + "b" (bx),
14398 + "D" ((long)reg),
14399 +- "S" (&pci_indirect));
14400 ++ "S" (&pci_indirect),
14401 ++ "r" (__PCIBIOS_DS));
14402 + break;
14403 + }
14404 +
14405 +@@ -232,7 +317,10 @@ static int pci_bios_write(unsigned int s
14406 +
14407 + switch (len) {
14408 + case 1:
14409 +- __asm__("lcall *(%%esi); cld\n\t"
14410 ++ __asm__("movw %w6, %%ds\n\t"
14411 ++ "lcall *%%ss:(%%esi); cld\n\t"
14412 ++ "push %%ss\n\t"
14413 ++ "pop %%ds\n\t"
14414 + "jc 1f\n\t"
14415 + "xor %%ah, %%ah\n"
14416 + "1:"
14417 +@@ -241,10 +329,14 @@ static int pci_bios_write(unsigned int s
14418 + "c" (value),
14419 + "b" (bx),
14420 + "D" ((long)reg),
14421 +- "S" (&pci_indirect));
14422 ++ "S" (&pci_indirect),
14423 ++ "r" (__PCIBIOS_DS));
14424 + break;
14425 + case 2:
14426 +- __asm__("lcall *(%%esi); cld\n\t"
14427 ++ __asm__("movw %w6, %%ds\n\t"
14428 ++ "lcall *%%ss:(%%esi); cld\n\t"
14429 ++ "push %%ss\n\t"
14430 ++ "pop %%ds\n\t"
14431 + "jc 1f\n\t"
14432 + "xor %%ah, %%ah\n"
14433 + "1:"
14434 +@@ -253,10 +345,14 @@ static int pci_bios_write(unsigned int s
14435 + "c" (value),
14436 + "b" (bx),
14437 + "D" ((long)reg),
14438 +- "S" (&pci_indirect));
14439 ++ "S" (&pci_indirect),
14440 ++ "r" (__PCIBIOS_DS));
14441 + break;
14442 + case 4:
14443 +- __asm__("lcall *(%%esi); cld\n\t"
14444 ++ __asm__("movw %w6, %%ds\n\t"
14445 ++ "lcall *%%ss:(%%esi); cld\n\t"
14446 ++ "push %%ss\n\t"
14447 ++ "pop %%ds\n\t"
14448 + "jc 1f\n\t"
14449 + "xor %%ah, %%ah\n"
14450 + "1:"
14451 +@@ -265,7 +361,8 @@ static int pci_bios_write(unsigned int s
14452 + "c" (value),
14453 + "b" (bx),
14454 + "D" ((long)reg),
14455 +- "S" (&pci_indirect));
14456 ++ "S" (&pci_indirect),
14457 ++ "r" (__PCIBIOS_DS));
14458 + break;
14459 + }
14460 +
14461 +@@ -369,10 +466,13 @@ struct irq_routing_table * pcibios_get_i
14462 +
14463 + DBG("PCI: Fetching IRQ routing table... ");
14464 + __asm__("push %%es\n\t"
14465 ++ "movw %w8, %%ds\n\t"
14466 + "push %%ds\n\t"
14467 + "pop %%es\n\t"
14468 +- "lcall *(%%esi); cld\n\t"
14469 ++ "lcall *%%ss:(%%esi); cld\n\t"
14470 + "pop %%es\n\t"
14471 ++ "push %%ss\n\t"
14472 ++ "pop %%ds\n"
14473 + "jc 1f\n\t"
14474 + "xor %%ah, %%ah\n"
14475 + "1:"
14476 +@@ -383,7 +483,8 @@ struct irq_routing_table * pcibios_get_i
14477 + "1" (0),
14478 + "D" ((long) &opt),
14479 + "S" (&pci_indirect),
14480 +- "m" (opt)
14481 ++ "m" (opt),
14482 ++ "r" (__PCIBIOS_DS)
14483 + : "memory");
14484 + DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map);
14485 + if (ret & 0xff00)
14486 +@@ -407,7 +508,10 @@ int pcibios_set_irq_routing(struct pci_d
14487 + {
14488 + int ret;
14489 +
14490 +- __asm__("lcall *(%%esi); cld\n\t"
14491 ++ __asm__("movw %w5, %%ds\n\t"
14492 ++ "lcall *%%ss:(%%esi); cld\n\t"
14493 ++ "push %%ss\n\t"
14494 ++ "pop %%ds\n"
14495 + "jc 1f\n\t"
14496 + "xor %%ah, %%ah\n"
14497 + "1:"
14498 +@@ -415,7 +519,8 @@ int pcibios_set_irq_routing(struct pci_d
14499 + : "0" (PCIBIOS_SET_PCI_HW_INT),
14500 + "b" ((dev->bus->number << 8) | dev->devfn),
14501 + "c" ((irq << 8) | (pin + 10)),
14502 +- "S" (&pci_indirect));
14503 ++ "S" (&pci_indirect),
14504 ++ "r" (__PCIBIOS_DS));
14505 + return !(ret & 0xff00);
14506 + }
14507 + EXPORT_SYMBOL(pcibios_set_irq_routing);
14508 +diff -urNp linux-2.6.28.8/arch/x86/power/cpu_32.c linux-2.6.28.8/arch/x86/power/cpu_32.c
14509 +--- linux-2.6.28.8/arch/x86/power/cpu_32.c 2009-02-06 16:47:45.000000000 -0500
14510 ++++ linux-2.6.28.8/arch/x86/power/cpu_32.c 2009-02-21 09:37:48.000000000 -0500
14511 +@@ -67,7 +67,7 @@ static void do_fpu_end(void)
14512 + static void fix_processor_context(void)
14513 + {
14514 + int cpu = smp_processor_id();
14515 +- struct tss_struct *t = &per_cpu(init_tss, cpu);
14516 ++ struct tss_struct *t = init_tss + cpu;
14517 +
14518 + set_tss_desc(cpu, t); /*
14519 + * This just modifies memory; should not be
14520 +diff -urNp linux-2.6.28.8/arch/x86/power/cpu_64.c linux-2.6.28.8/arch/x86/power/cpu_64.c
14521 +--- linux-2.6.28.8/arch/x86/power/cpu_64.c 2009-02-06 16:47:45.000000000 -0500
14522 ++++ linux-2.6.28.8/arch/x86/power/cpu_64.c 2009-02-21 09:37:48.000000000 -0500
14523 +@@ -143,7 +143,11 @@ void restore_processor_state(void)
14524 + static void fix_processor_context(void)
14525 + {
14526 + int cpu = smp_processor_id();
14527 +- struct tss_struct *t = &per_cpu(init_tss, cpu);
14528 ++ struct tss_struct *t = init_tss + cpu;
14529 ++
14530 ++#ifdef CONFIG_PAX_KERNEXEC
14531 ++ unsigned long cr0;
14532 ++#endif
14533 +
14534 + /*
14535 + * This just modifies memory; should not be necessary. But... This
14536 +@@ -152,8 +156,16 @@ static void fix_processor_context(void)
14537 + */
14538 + set_tss_desc(cpu, t);
14539 +
14540 ++#ifdef CONFIG_PAX_KERNEXEC
14541 ++ pax_open_kernel(cr0);
14542 ++#endif
14543 ++
14544 + get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9;
14545 +
14546 ++#ifdef CONFIG_PAX_KERNEXEC
14547 ++ pax_close_kernel(cr0);
14548 ++#endif
14549 ++
14550 + syscall_init(); /* This sets MSR_*STAR and related */
14551 + load_TR_desc(); /* This does ltr */
14552 + load_LDT(&current->active_mm->context); /* This does lldt */
14553 +diff -urNp linux-2.6.28.8/arch/x86/vdso/vdso32-setup.c linux-2.6.28.8/arch/x86/vdso/vdso32-setup.c
14554 +--- linux-2.6.28.8/arch/x86/vdso/vdso32-setup.c 2009-02-06 16:47:45.000000000 -0500
14555 ++++ linux-2.6.28.8/arch/x86/vdso/vdso32-setup.c 2009-02-21 09:37:48.000000000 -0500
14556 +@@ -226,7 +226,7 @@ static inline void map_compat_vdso(int m
14557 + void enable_sep_cpu(void)
14558 + {
14559 + int cpu = get_cpu();
14560 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
14561 ++ struct tss_struct *tss = init_tss + cpu;
14562 +
14563 + if (!boot_cpu_has(X86_FEATURE_SEP)) {
14564 + put_cpu();
14565 +@@ -249,7 +249,7 @@ static int __init gate_vma_init(void)
14566 + gate_vma.vm_start = FIXADDR_USER_START;
14567 + gate_vma.vm_end = FIXADDR_USER_END;
14568 + gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
14569 +- gate_vma.vm_page_prot = __P101;
14570 ++ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
14571 + /*
14572 + * Make sure the vDSO gets into every core dump.
14573 + * Dumping its contents makes post-mortem fully interpretable later
14574 +@@ -331,7 +331,7 @@ int arch_setup_additional_pages(struct l
14575 + if (compat)
14576 + addr = VDSO_HIGH_BASE;
14577 + else {
14578 +- addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
14579 ++ addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
14580 + if (IS_ERR_VALUE(addr)) {
14581 + ret = addr;
14582 + goto up_fail;
14583 +@@ -358,7 +358,7 @@ int arch_setup_additional_pages(struct l
14584 + goto up_fail;
14585 + }
14586 +
14587 +- current->mm->context.vdso = (void *)addr;
14588 ++ current->mm->context.vdso = addr;
14589 + current_thread_info()->sysenter_return =
14590 + VDSO32_SYMBOL(addr, SYSENTER_RETURN);
14591 +
14592 +@@ -384,7 +384,7 @@ static ctl_table abi_table2[] = {
14593 + .mode = 0644,
14594 + .proc_handler = proc_dointvec
14595 + },
14596 +- {}
14597 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
14598 + };
14599 +
14600 + static ctl_table abi_root_table2[] = {
14601 +@@ -394,7 +394,7 @@ static ctl_table abi_root_table2[] = {
14602 + .mode = 0555,
14603 + .child = abi_table2
14604 + },
14605 +- {}
14606 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
14607 + };
14608 +
14609 + static __init int ia32_binfmt_init(void)
14610 +@@ -409,8 +409,14 @@ __initcall(ia32_binfmt_init);
14611 +
14612 + const char *arch_vma_name(struct vm_area_struct *vma)
14613 + {
14614 +- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
14615 ++ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
14616 + return "[vdso]";
14617 ++
14618 ++#ifdef CONFIG_PAX_SEGMEXEC
14619 ++ if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso)
14620 ++ return "[vdso]";
14621 ++#endif
14622 ++
14623 + return NULL;
14624 + }
14625 +
14626 +@@ -419,7 +425,7 @@ struct vm_area_struct *get_gate_vma(stru
14627 + struct mm_struct *mm = tsk->mm;
14628 +
14629 + /* Check to see if this task was created in compat vdso mode */
14630 +- if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
14631 ++ if (mm && mm->context.vdso == VDSO_HIGH_BASE)
14632 + return &gate_vma;
14633 + return NULL;
14634 + }
14635 +diff -urNp linux-2.6.28.8/arch/x86/vdso/vma.c linux-2.6.28.8/arch/x86/vdso/vma.c
14636 +--- linux-2.6.28.8/arch/x86/vdso/vma.c 2009-02-06 16:47:45.000000000 -0500
14637 ++++ linux-2.6.28.8/arch/x86/vdso/vma.c 2009-02-21 09:37:48.000000000 -0500
14638 +@@ -123,7 +123,7 @@ int arch_setup_additional_pages(struct l
14639 + if (ret)
14640 + goto up_fail;
14641 +
14642 +- current->mm->context.vdso = (void *)addr;
14643 ++ current->mm->context.vdso = addr;
14644 + up_fail:
14645 + up_write(&mm->mmap_sem);
14646 + return ret;
14647 +diff -urNp linux-2.6.28.8/arch/x86/xen/enlighten.c linux-2.6.28.8/arch/x86/xen/enlighten.c
14648 +--- linux-2.6.28.8/arch/x86/xen/enlighten.c 2009-03-07 10:24:49.000000000 -0500
14649 ++++ linux-2.6.28.8/arch/x86/xen/enlighten.c 2009-03-07 10:29:51.000000000 -0500
14650 +@@ -318,7 +318,7 @@ static void xen_set_ldt(const void *addr
14651 + static void xen_load_gdt(const struct desc_ptr *dtr)
14652 + {
14653 + unsigned long *frames;
14654 +- unsigned long va = dtr->address;
14655 ++ unsigned long va = (unsigned long)dtr->address;
14656 + unsigned int size = dtr->size + 1;
14657 + unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
14658 + int f;
14659 +@@ -333,7 +333,7 @@ static void xen_load_gdt(const struct de
14660 + mcs = xen_mc_entry(sizeof(*frames) * pages);
14661 + frames = mcs.args;
14662 +
14663 +- for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
14664 ++ for (f = 0; va < (unsigned long)dtr->address + size; va += PAGE_SIZE, f++) {
14665 + frames[f] = virt_to_mfn(va);
14666 + make_lowmem_page_readonly((void *)va);
14667 + }
14668 +@@ -441,7 +441,7 @@ static void xen_write_idt_entry(gate_des
14669 +
14670 + preempt_disable();
14671 +
14672 +- start = __get_cpu_var(idt_desc).address;
14673 ++ start = (unsigned long)__get_cpu_var(idt_desc).address;
14674 + end = start + __get_cpu_var(idt_desc).size + 1;
14675 +
14676 + xen_mc_flush();
14677 +@@ -1526,6 +1526,8 @@ static __init pgd_t *xen_setup_kernel_pa
14678 + convert_pfn_mfn(init_level4_pgt);
14679 + convert_pfn_mfn(level3_ident_pgt);
14680 + convert_pfn_mfn(level3_kernel_pgt);
14681 ++ convert_pfn_mfn(level3_vmalloc_pgt);
14682 ++ convert_pfn_mfn(level3_vmemmap_pgt);
14683 +
14684 + l3 = m2v(pgd[pgd_index(__START_KERNEL_map)].pgd);
14685 + l2 = m2v(l3[pud_index(__START_KERNEL_map)].pud);
14686 +@@ -1544,9 +1546,12 @@ static __init pgd_t *xen_setup_kernel_pa
14687 + set_page_prot(init_level4_pgt, PAGE_KERNEL_RO);
14688 + set_page_prot(level3_ident_pgt, PAGE_KERNEL_RO);
14689 + set_page_prot(level3_kernel_pgt, PAGE_KERNEL_RO);
14690 ++ set_page_prot(level3_vmalloc_pgt, PAGE_KERNEL_RO);
14691 ++ set_page_prot(level3_vmemmap_pgt, PAGE_KERNEL_RO);
14692 + set_page_prot(level3_user_vsyscall, PAGE_KERNEL_RO);
14693 + set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO);
14694 + set_page_prot(level2_fixmap_pgt, PAGE_KERNEL_RO);
14695 ++ set_page_prot(level1_fixmap_pgt, PAGE_KERNEL_RO);
14696 +
14697 + /* Pin down new L4 */
14698 + pin_pagetable_pfn(MMUEXT_PIN_L4_TABLE,
14699 +diff -urNp linux-2.6.28.8/arch/x86/xen/smp.c linux-2.6.28.8/arch/x86/xen/smp.c
14700 +--- linux-2.6.28.8/arch/x86/xen/smp.c 2009-02-06 16:47:45.000000000 -0500
14701 ++++ linux-2.6.28.8/arch/x86/xen/smp.c 2009-02-21 09:37:48.000000000 -0500
14702 +@@ -171,11 +171,6 @@ static void __init xen_smp_prepare_boot_
14703 + {
14704 + BUG_ON(smp_processor_id() != 0);
14705 + native_smp_prepare_boot_cpu();
14706 +-
14707 +- /* We've switched to the "real" per-cpu gdt, so make sure the
14708 +- old memory can be recycled */
14709 +- make_lowmem_page_readwrite(&per_cpu_var(gdt_page));
14710 +-
14711 + xen_setup_vcpu_info_placement();
14712 + }
14713 +
14714 +@@ -231,8 +226,8 @@ cpu_initialize_context(unsigned int cpu,
14715 + gdt = get_cpu_gdt_table(cpu);
14716 +
14717 + ctxt->flags = VGCF_IN_KERNEL;
14718 +- ctxt->user_regs.ds = __USER_DS;
14719 +- ctxt->user_regs.es = __USER_DS;
14720 ++ ctxt->user_regs.ds = __KERNEL_DS;
14721 ++ ctxt->user_regs.es = __KERNEL_DS;
14722 + ctxt->user_regs.ss = __KERNEL_DS;
14723 + #ifdef CONFIG_X86_32
14724 + ctxt->user_regs.fs = __KERNEL_PERCPU;
14725 +diff -urNp linux-2.6.28.8/crypto/async_tx/async_tx.c linux-2.6.28.8/crypto/async_tx/async_tx.c
14726 +--- linux-2.6.28.8/crypto/async_tx/async_tx.c 2009-02-06 16:47:45.000000000 -0500
14727 ++++ linux-2.6.28.8/crypto/async_tx/async_tx.c 2009-02-21 09:37:48.000000000 -0500
14728 +@@ -358,8 +358,8 @@ async_tx_init(void)
14729 + err:
14730 + printk(KERN_ERR "async_tx: initialization failure\n");
14731 +
14732 +- while (--cap >= 0)
14733 +- free_percpu(channel_table[cap]);
14734 ++ while (cap)
14735 ++ free_percpu(channel_table[--cap]);
14736 +
14737 + return 1;
14738 + }
14739 +diff -urNp linux-2.6.28.8/crypto/lrw.c linux-2.6.28.8/crypto/lrw.c
14740 +--- linux-2.6.28.8/crypto/lrw.c 2009-02-06 16:47:45.000000000 -0500
14741 ++++ linux-2.6.28.8/crypto/lrw.c 2009-02-21 09:37:48.000000000 -0500
14742 +@@ -54,7 +54,7 @@ static int setkey(struct crypto_tfm *par
14743 + struct priv *ctx = crypto_tfm_ctx(parent);
14744 + struct crypto_cipher *child = ctx->child;
14745 + int err, i;
14746 +- be128 tmp = { 0 };
14747 ++ be128 tmp = { 0, 0 };
14748 + int bsize = crypto_cipher_blocksize(child);
14749 +
14750 + crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
14751 +diff -urNp linux-2.6.28.8/Documentation/dontdiff linux-2.6.28.8/Documentation/dontdiff
14752 +--- linux-2.6.28.8/Documentation/dontdiff 2009-02-06 16:47:45.000000000 -0500
14753 ++++ linux-2.6.28.8/Documentation/dontdiff 2009-02-21 09:37:48.000000000 -0500
14754 +@@ -3,6 +3,7 @@
14755 + *.bin
14756 + *.cpio
14757 + *.csp
14758 ++*.dbg
14759 + *.dsp
14760 + *.dvi
14761 + *.elf
14762 +@@ -49,6 +50,10 @@
14763 + 53c700_d.h
14764 + CVS
14765 + ChangeSet
14766 ++GPATH
14767 ++GRTAGS
14768 ++GSYMS
14769 ++GTAGS
14770 + Image
14771 + Kerntypes
14772 + Module.markers
14773 +@@ -62,7 +67,6 @@ aic7*reg_print.c*
14774 + aic7*seq.h*
14775 + aicasm
14776 + aicdb.h*
14777 +-asm
14778 + asm-offsets.h
14779 + asm_offsets.h
14780 + autoconf.h*
14781 +@@ -77,6 +81,7 @@ btfixupprep
14782 + build
14783 + bvmlinux
14784 + bzImage*
14785 ++capflags.c
14786 + classlist.h*
14787 + comp*.log
14788 + compile.h*
14789 +@@ -188,12 +193,15 @@ version.h*
14790 + vmlinux
14791 + vmlinux-*
14792 + vmlinux.aout
14793 ++vmlinux.bin.all
14794 + vmlinux.lds
14795 ++vmlinux.relocs
14796 + vsyscall.lds
14797 + vsyscall_32.lds
14798 + wanxlfw.inc
14799 + uImage
14800 + unifdef
14801 ++utsrelease.h
14802 + wakeup.bin
14803 + wakeup.elf
14804 + wakeup.lds
14805 +diff -urNp linux-2.6.28.8/drivers/acpi/blacklist.c linux-2.6.28.8/drivers/acpi/blacklist.c
14806 +--- linux-2.6.28.8/drivers/acpi/blacklist.c 2009-02-06 16:47:45.000000000 -0500
14807 ++++ linux-2.6.28.8/drivers/acpi/blacklist.c 2009-02-21 09:37:48.000000000 -0500
14808 +@@ -71,7 +71,7 @@ static struct acpi_blacklist_item acpi_b
14809 + {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
14810 + "Incorrect _ADR", 1},
14811 +
14812 +- {""}
14813 ++ {"", "", 0, 0, 0, all_versions, 0}
14814 + };
14815 +
14816 + #if CONFIG_ACPI_BLACKLIST_YEAR
14817 +diff -urNp linux-2.6.28.8/drivers/acpi/osl.c linux-2.6.28.8/drivers/acpi/osl.c
14818 +--- linux-2.6.28.8/drivers/acpi/osl.c 2009-02-06 16:47:45.000000000 -0500
14819 ++++ linux-2.6.28.8/drivers/acpi/osl.c 2009-02-21 09:37:48.000000000 -0500
14820 +@@ -483,6 +483,8 @@ acpi_os_read_memory(acpi_physical_addres
14821 + void __iomem *virt_addr;
14822 +
14823 + virt_addr = ioremap(phys_addr, width);
14824 ++ if (!virt_addr)
14825 ++ return AE_NO_MEMORY;
14826 + if (!value)
14827 + value = &dummy;
14828 +
14829 +@@ -511,6 +513,8 @@ acpi_os_write_memory(acpi_physical_addre
14830 + void __iomem *virt_addr;
14831 +
14832 + virt_addr = ioremap(phys_addr, width);
14833 ++ if (!virt_addr)
14834 ++ return AE_NO_MEMORY;
14835 +
14836 + switch (width) {
14837 + case 8:
14838 +diff -urNp linux-2.6.28.8/drivers/acpi/processor_core.c linux-2.6.28.8/drivers/acpi/processor_core.c
14839 +--- linux-2.6.28.8/drivers/acpi/processor_core.c 2009-02-06 16:47:45.000000000 -0500
14840 ++++ linux-2.6.28.8/drivers/acpi/processor_core.c 2009-02-21 09:37:48.000000000 -0500
14841 +@@ -678,7 +678,7 @@ static int __cpuinit acpi_processor_star
14842 + return 0;
14843 + }
14844 +
14845 +- BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
14846 ++ BUG_ON(pr->id >= nr_cpu_ids);
14847 +
14848 + /*
14849 + * Buggy BIOS check
14850 +diff -urNp linux-2.6.28.8/drivers/acpi/processor_idle.c linux-2.6.28.8/drivers/acpi/processor_idle.c
14851 +--- linux-2.6.28.8/drivers/acpi/processor_idle.c 2009-02-06 16:47:45.000000000 -0500
14852 ++++ linux-2.6.28.8/drivers/acpi/processor_idle.c 2009-02-21 09:37:48.000000000 -0500
14853 +@@ -181,7 +181,7 @@ static struct dmi_system_id __cpuinitdat
14854 + DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
14855 + DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
14856 + (void *)2},
14857 +- {},
14858 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL},
14859 + };
14860 +
14861 + static inline u32 ticks_elapsed(u32 t1, u32 t2)
14862 +diff -urNp linux-2.6.28.8/drivers/acpi/tables/tbfadt.c linux-2.6.28.8/drivers/acpi/tables/tbfadt.c
14863 +--- linux-2.6.28.8/drivers/acpi/tables/tbfadt.c 2009-02-06 16:47:45.000000000 -0500
14864 ++++ linux-2.6.28.8/drivers/acpi/tables/tbfadt.c 2009-02-21 09:37:48.000000000 -0500
14865 +@@ -48,7 +48,7 @@
14866 + ACPI_MODULE_NAME("tbfadt")
14867 +
14868 + /* Local prototypes */
14869 +-static void inline
14870 ++static inline void
14871 + acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
14872 + u8 byte_width, u64 address);
14873 +
14874 +@@ -122,7 +122,7 @@ static struct acpi_fadt_info fadt_info_t
14875 + *
14876 + ******************************************************************************/
14877 +
14878 +-static void inline
14879 ++static inline void
14880 + acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
14881 + u8 byte_width, u64 address)
14882 + {
14883 +diff -urNp linux-2.6.28.8/drivers/ata/ahci.c linux-2.6.28.8/drivers/ata/ahci.c
14884 +--- linux-2.6.28.8/drivers/ata/ahci.c 2009-02-06 16:47:45.000000000 -0500
14885 ++++ linux-2.6.28.8/drivers/ata/ahci.c 2009-02-21 09:37:48.000000000 -0500
14886 +@@ -606,7 +606,7 @@ static const struct pci_device_id ahci_p
14887 + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
14888 + PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
14889 +
14890 +- { } /* terminate list */
14891 ++ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
14892 + };
14893 +
14894 +
14895 +diff -urNp linux-2.6.28.8/drivers/ata/ata_piix.c linux-2.6.28.8/drivers/ata/ata_piix.c
14896 +--- linux-2.6.28.8/drivers/ata/ata_piix.c 2009-02-06 16:47:45.000000000 -0500
14897 ++++ linux-2.6.28.8/drivers/ata/ata_piix.c 2009-02-21 09:37:48.000000000 -0500
14898 +@@ -289,7 +289,7 @@ static const struct pci_device_id piix_p
14899 + { 0x8086, 0x3b2d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
14900 + /* SATA Controller IDE (PCH) */
14901 + { 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
14902 +- { } /* terminate list */
14903 ++ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
14904 + };
14905 +
14906 + static struct pci_driver piix_pci_driver = {
14907 +@@ -593,7 +593,7 @@ static const struct ich_laptop ich_lapto
14908 + { 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */
14909 + { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */
14910 + /* end marker */
14911 +- { 0, }
14912 ++ { 0, 0, 0 }
14913 + };
14914 +
14915 + /**
14916 +@@ -1052,7 +1052,7 @@ static int piix_broken_suspend(void)
14917 + },
14918 + },
14919 +
14920 +- { } /* terminate list */
14921 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL } /* terminate list */
14922 + };
14923 + static const char *oemstrs[] = {
14924 + "Tecra M3,",
14925 +diff -urNp linux-2.6.28.8/drivers/ata/libata-core.c linux-2.6.28.8/drivers/ata/libata-core.c
14926 +--- linux-2.6.28.8/drivers/ata/libata-core.c 2009-03-07 10:24:49.000000000 -0500
14927 ++++ linux-2.6.28.8/drivers/ata/libata-core.c 2009-03-07 10:29:51.000000000 -0500
14928 +@@ -807,7 +807,7 @@ static const struct ata_xfer_ent {
14929 + { ATA_SHIFT_PIO, ATA_NR_PIO_MODES, XFER_PIO_0 },
14930 + { ATA_SHIFT_MWDMA, ATA_NR_MWDMA_MODES, XFER_MW_DMA_0 },
14931 + { ATA_SHIFT_UDMA, ATA_NR_UDMA_MODES, XFER_UDMA_0 },
14932 +- { -1, },
14933 ++ { -1, 0, 0 }
14934 + };
14935 +
14936 + /**
14937 +@@ -2983,7 +2983,7 @@ static const struct ata_timing ata_timin
14938 + { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 20 },
14939 + { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 15 },
14940 +
14941 +- { 0xFF }
14942 ++ { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
14943 + };
14944 +
14945 + #define ENOUGH(v, unit) (((v)-1)/(unit)+1)
14946 +@@ -4149,7 +4149,7 @@ static const struct ata_blacklist_entry
14947 + { "MTRON MSP-SATA*", NULL, ATA_HORKAGE_BRIDGE_OK, },
14948 +
14949 + /* End Marker */
14950 +- { }
14951 ++ { NULL, NULL, 0 }
14952 + };
14953 +
14954 + static int strn_pattern_cmp(const char *patt, const char *name, int wildchar)
14955 +diff -urNp linux-2.6.28.8/drivers/char/agp/frontend.c linux-2.6.28.8/drivers/char/agp/frontend.c
14956 +--- linux-2.6.28.8/drivers/char/agp/frontend.c 2009-02-06 16:47:45.000000000 -0500
14957 ++++ linux-2.6.28.8/drivers/char/agp/frontend.c 2009-02-21 09:37:48.000000000 -0500
14958 +@@ -824,7 +824,7 @@ static int agpioc_reserve_wrap(struct ag
14959 + if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
14960 + return -EFAULT;
14961 +
14962 +- if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
14963 ++ if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
14964 + return -EFAULT;
14965 +
14966 + client = agp_find_client_by_pid(reserve.pid);
14967 +diff -urNp linux-2.6.28.8/drivers/char/agp/intel-agp.c linux-2.6.28.8/drivers/char/agp/intel-agp.c
14968 +--- linux-2.6.28.8/drivers/char/agp/intel-agp.c 2009-03-07 10:24:49.000000000 -0500
14969 ++++ linux-2.6.28.8/drivers/char/agp/intel-agp.c 2009-03-07 10:29:51.000000000 -0500
14970 +@@ -2369,7 +2369,7 @@ static struct pci_device_id agp_intel_pc
14971 + ID(PCI_DEVICE_ID_INTEL_Q45_HB),
14972 + ID(PCI_DEVICE_ID_INTEL_G45_HB),
14973 + ID(PCI_DEVICE_ID_INTEL_G41_HB),
14974 +- { }
14975 ++ { 0, 0, 0, 0, 0, 0, 0 }
14976 + };
14977 +
14978 + MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
14979 +diff -urNp linux-2.6.28.8/drivers/char/hpet.c linux-2.6.28.8/drivers/char/hpet.c
14980 +--- linux-2.6.28.8/drivers/char/hpet.c 2009-02-06 16:47:45.000000000 -0500
14981 ++++ linux-2.6.28.8/drivers/char/hpet.c 2009-02-21 09:37:48.000000000 -0500
14982 +@@ -975,7 +975,7 @@ static struct acpi_driver hpet_acpi_driv
14983 + },
14984 + };
14985 +
14986 +-static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
14987 ++static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL };
14988 +
14989 + static int __init hpet_init(void)
14990 + {
14991 +diff -urNp linux-2.6.28.8/drivers/char/keyboard.c linux-2.6.28.8/drivers/char/keyboard.c
14992 +--- linux-2.6.28.8/drivers/char/keyboard.c 2009-02-06 16:47:45.000000000 -0500
14993 ++++ linux-2.6.28.8/drivers/char/keyboard.c 2009-02-21 09:37:48.000000000 -0500
14994 +@@ -635,6 +635,16 @@ static void k_spec(struct vc_data *vc, u
14995 + kbd->kbdmode == VC_MEDIUMRAW) &&
14996 + value != KVAL(K_SAK))
14997 + return; /* SAK is allowed even in raw mode */
14998 ++
14999 ++#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
15000 ++ {
15001 ++ void *func = fn_handler[value];
15002 ++ if (func == fn_show_state || func == fn_show_ptregs ||
15003 ++ func == fn_show_mem)
15004 ++ return;
15005 ++ }
15006 ++#endif
15007 ++
15008 + fn_handler[value](vc);
15009 + }
15010 +
15011 +@@ -1388,7 +1398,7 @@ static const struct input_device_id kbd_
15012 + .evbit = { BIT_MASK(EV_SND) },
15013 + },
15014 +
15015 +- { }, /* Terminating entry */
15016 ++ { 0 }, /* Terminating entry */
15017 + };
15018 +
15019 + MODULE_DEVICE_TABLE(input, kbd_ids);
15020 +diff -urNp linux-2.6.28.8/drivers/char/mem.c linux-2.6.28.8/drivers/char/mem.c
15021 +--- linux-2.6.28.8/drivers/char/mem.c 2009-02-06 16:47:45.000000000 -0500
15022 ++++ linux-2.6.28.8/drivers/char/mem.c 2009-02-21 09:37:48.000000000 -0500
15023 +@@ -18,6 +18,7 @@
15024 + #include <linux/raw.h>
15025 + #include <linux/tty.h>
15026 + #include <linux/capability.h>
15027 ++#include <linux/security.h>
15028 + #include <linux/ptrace.h>
15029 + #include <linux/device.h>
15030 + #include <linux/highmem.h>
15031 +@@ -35,6 +36,10 @@
15032 + # include <linux/efi.h>
15033 + #endif
15034 +
15035 ++#ifdef CONFIG_GRKERNSEC
15036 ++extern struct file_operations grsec_fops;
15037 ++#endif
15038 ++
15039 + /*
15040 + * Architectures vary in how they handle caching for addresses
15041 + * outside of main memory.
15042 +@@ -192,6 +197,11 @@ static ssize_t write_mem(struct file * f
15043 + if (!valid_phys_addr_range(p, count))
15044 + return -EFAULT;
15045 +
15046 ++#ifdef CONFIG_GRKERNSEC_KMEM
15047 ++ gr_handle_mem_write();
15048 ++ return -EPERM;
15049 ++#endif
15050 ++
15051 + written = 0;
15052 +
15053 + #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
15054 +@@ -350,6 +360,11 @@ static int mmap_mem(struct file * file,
15055 + &vma->vm_page_prot))
15056 + return -EINVAL;
15057 +
15058 ++#ifdef CONFIG_GRKERNSEC_KMEM
15059 ++ if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
15060 ++ return -EPERM;
15061 ++#endif
15062 ++
15063 + vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
15064 + size,
15065 + vma->vm_page_prot);
15066 +@@ -588,6 +603,11 @@ static ssize_t write_kmem(struct file *
15067 + ssize_t written;
15068 + char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
15069 +
15070 ++#ifdef CONFIG_GRKERNSEC_KMEM
15071 ++ gr_handle_kmem_write();
15072 ++ return -EPERM;
15073 ++#endif
15074 ++
15075 + if (p < (unsigned long) high_memory) {
15076 +
15077 + wrote = count;
15078 +@@ -791,6 +811,16 @@ static loff_t memory_lseek(struct file *
15079 +
15080 + static int open_port(struct inode * inode, struct file * filp)
15081 + {
15082 ++#ifdef CONFIG_GRKERNSEC_KMEM
15083 ++ gr_handle_open_port();
15084 ++ return -EPERM;
15085 ++#endif
15086 ++
15087 ++ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
15088 ++}
15089 ++
15090 ++static int open_mem(struct inode * inode, struct file * filp)
15091 ++{
15092 + return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
15093 + }
15094 +
15095 +@@ -798,7 +828,6 @@ static int open_port(struct inode * inod
15096 + #define full_lseek null_lseek
15097 + #define write_zero write_null
15098 + #define read_full read_zero
15099 +-#define open_mem open_port
15100 + #define open_kmem open_mem
15101 + #define open_oldmem open_mem
15102 +
15103 +@@ -938,6 +967,11 @@ static int memory_open(struct inode * in
15104 + filp->f_op = &oldmem_fops;
15105 + break;
15106 + #endif
15107 ++#ifdef CONFIG_GRKERNSEC
15108 ++ case 13:
15109 ++ filp->f_op = &grsec_fops;
15110 ++ break;
15111 ++#endif
15112 + default:
15113 + unlock_kernel();
15114 + return -ENXIO;
15115 +@@ -974,6 +1008,9 @@ static const struct {
15116 + #ifdef CONFIG_CRASH_DUMP
15117 + {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
15118 + #endif
15119 ++#ifdef CONFIG_GRKERNSEC
15120 ++ {13,"grsec", S_IRUSR | S_IWUGO, &grsec_fops},
15121 ++#endif
15122 + };
15123 +
15124 + static struct class *mem_class;
15125 +diff -urNp linux-2.6.28.8/drivers/char/nvram.c linux-2.6.28.8/drivers/char/nvram.c
15126 +--- linux-2.6.28.8/drivers/char/nvram.c 2009-02-06 16:47:45.000000000 -0500
15127 ++++ linux-2.6.28.8/drivers/char/nvram.c 2009-02-21 09:37:48.000000000 -0500
15128 +@@ -433,7 +433,10 @@ static const struct file_operations nvra
15129 + static struct miscdevice nvram_dev = {
15130 + NVRAM_MINOR,
15131 + "nvram",
15132 +- &nvram_fops
15133 ++ &nvram_fops,
15134 ++ {NULL, NULL},
15135 ++ NULL,
15136 ++ NULL
15137 + };
15138 +
15139 + static int __init
15140 +diff -urNp linux-2.6.28.8/drivers/char/random.c linux-2.6.28.8/drivers/char/random.c
15141 +--- linux-2.6.28.8/drivers/char/random.c 2009-02-06 16:47:45.000000000 -0500
15142 ++++ linux-2.6.28.8/drivers/char/random.c 2009-02-21 09:37:48.000000000 -0500
15143 +@@ -249,8 +249,13 @@
15144 + /*
15145 + * Configuration information
15146 + */
15147 ++#ifdef CONFIG_GRKERNSEC_RANDNET
15148 ++#define INPUT_POOL_WORDS 512
15149 ++#define OUTPUT_POOL_WORDS 128
15150 ++#else
15151 + #define INPUT_POOL_WORDS 128
15152 + #define OUTPUT_POOL_WORDS 32
15153 ++#endif
15154 + #define SEC_XFER_SIZE 512
15155 +
15156 + /*
15157 +@@ -287,10 +292,17 @@ static struct poolinfo {
15158 + int poolwords;
15159 + int tap1, tap2, tap3, tap4, tap5;
15160 + } poolinfo_table[] = {
15161 ++#ifdef CONFIG_GRKERNSEC_RANDNET
15162 ++ /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
15163 ++ { 512, 411, 308, 208, 104, 1 },
15164 ++ /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
15165 ++ { 128, 103, 76, 51, 25, 1 },
15166 ++#else
15167 + /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
15168 + { 128, 103, 76, 51, 25, 1 },
15169 + /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
15170 + { 32, 26, 20, 14, 7, 1 },
15171 ++#endif
15172 + #if 0
15173 + /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
15174 + { 2048, 1638, 1231, 819, 411, 1 },
15175 +@@ -1185,7 +1197,7 @@ EXPORT_SYMBOL(generate_random_uuid);
15176 + #include <linux/sysctl.h>
15177 +
15178 + static int min_read_thresh = 8, min_write_thresh;
15179 +-static int max_read_thresh = INPUT_POOL_WORDS * 32;
15180 ++static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
15181 + static int max_write_thresh = INPUT_POOL_WORDS * 32;
15182 + static char sysctl_bootid[16];
15183 +
15184 +diff -urNp linux-2.6.28.8/drivers/char/tpm/tpm.c linux-2.6.28.8/drivers/char/tpm/tpm.c
15185 +--- linux-2.6.28.8/drivers/char/tpm/tpm.c 2009-02-06 16:47:45.000000000 -0500
15186 ++++ linux-2.6.28.8/drivers/char/tpm/tpm.c 2009-02-21 09:37:48.000000000 -0500
15187 +@@ -1035,7 +1035,7 @@ ssize_t tpm_write(struct file *file, con
15188 +
15189 + mutex_lock(&chip->buffer_mutex);
15190 +
15191 +- if (in_size > TPM_BUFSIZE)
15192 ++ if (in_size > (unsigned int)TPM_BUFSIZE)
15193 + in_size = TPM_BUFSIZE;
15194 +
15195 + if (copy_from_user
15196 +diff -urNp linux-2.6.28.8/drivers/char/vt_ioctl.c linux-2.6.28.8/drivers/char/vt_ioctl.c
15197 +--- linux-2.6.28.8/drivers/char/vt_ioctl.c 2009-02-06 16:47:45.000000000 -0500
15198 ++++ linux-2.6.28.8/drivers/char/vt_ioctl.c 2009-02-21 09:37:48.000000000 -0500
15199 +@@ -96,6 +96,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
15200 + case KDSKBENT:
15201 + if (!perm)
15202 + return -EPERM;
15203 ++
15204 ++#ifdef CONFIG_GRKERNSEC
15205 ++ if (!capable(CAP_SYS_TTY_CONFIG))
15206 ++ return -EPERM;
15207 ++#endif
15208 ++
15209 + if (!i && v == K_NOSUCHMAP) {
15210 + /* deallocate map */
15211 + key_map = key_maps[s];
15212 +@@ -236,6 +242,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry
15213 + goto reterr;
15214 + }
15215 +
15216 ++#ifdef CONFIG_GRKERNSEC
15217 ++ if (!capable(CAP_SYS_TTY_CONFIG)) {
15218 ++ ret = -EPERM;
15219 ++ goto reterr;
15220 ++ }
15221 ++#endif
15222 ++
15223 + q = func_table[i];
15224 + first_free = funcbufptr + (funcbufsize - funcbufleft);
15225 + for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
15226 +diff -urNp linux-2.6.28.8/drivers/edac/edac_core.h linux-2.6.28.8/drivers/edac/edac_core.h
15227 +--- linux-2.6.28.8/drivers/edac/edac_core.h 2009-02-06 16:47:45.000000000 -0500
15228 ++++ linux-2.6.28.8/drivers/edac/edac_core.h 2009-02-21 09:37:48.000000000 -0500
15229 +@@ -85,11 +85,11 @@ extern int edac_debug_level;
15230 +
15231 + #else /* !CONFIG_EDAC_DEBUG */
15232 +
15233 +-#define debugf0( ... )
15234 +-#define debugf1( ... )
15235 +-#define debugf2( ... )
15236 +-#define debugf3( ... )
15237 +-#define debugf4( ... )
15238 ++#define debugf0( ... ) do {} while (0)
15239 ++#define debugf1( ... ) do {} while (0)
15240 ++#define debugf2( ... ) do {} while (0)
15241 ++#define debugf3( ... ) do {} while (0)
15242 ++#define debugf4( ... ) do {} while (0)
15243 +
15244 + #endif /* !CONFIG_EDAC_DEBUG */
15245 +
15246 +diff -urNp linux-2.6.28.8/drivers/firmware/dmi_scan.c linux-2.6.28.8/drivers/firmware/dmi_scan.c
15247 +--- linux-2.6.28.8/drivers/firmware/dmi_scan.c 2009-02-06 16:47:45.000000000 -0500
15248 ++++ linux-2.6.28.8/drivers/firmware/dmi_scan.c 2009-02-21 09:37:48.000000000 -0500
15249 +@@ -389,11 +389,6 @@ void __init dmi_scan_machine(void)
15250 + }
15251 + }
15252 + else {
15253 +- /*
15254 +- * no iounmap() for that ioremap(); it would be a no-op, but
15255 +- * it's so early in setup that sucker gets confused into doing
15256 +- * what it shouldn't if we actually call it.
15257 +- */
15258 + p = dmi_ioremap(0xF0000, 0x10000);
15259 + if (p == NULL)
15260 + goto error;
15261 +diff -urNp linux-2.6.28.8/drivers/hwmon/fscpos.c linux-2.6.28.8/drivers/hwmon/fscpos.c
15262 +--- linux-2.6.28.8/drivers/hwmon/fscpos.c 2009-02-06 16:47:45.000000000 -0500
15263 ++++ linux-2.6.28.8/drivers/hwmon/fscpos.c 2009-02-21 09:37:48.000000000 -0500
15264 +@@ -240,7 +240,6 @@ static ssize_t set_pwm(struct i2c_client
15265 + unsigned long v = simple_strtoul(buf, NULL, 10);
15266 +
15267 + /* Range: 0..255 */
15268 +- if (v < 0) v = 0;
15269 + if (v > 255) v = 255;
15270 +
15271 + mutex_lock(&data->update_lock);
15272 +diff -urNp linux-2.6.28.8/drivers/hwmon/k8temp.c linux-2.6.28.8/drivers/hwmon/k8temp.c
15273 +--- linux-2.6.28.8/drivers/hwmon/k8temp.c 2009-02-06 16:47:45.000000000 -0500
15274 ++++ linux-2.6.28.8/drivers/hwmon/k8temp.c 2009-02-21 09:37:48.000000000 -0500
15275 +@@ -130,7 +130,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
15276 +
15277 + static struct pci_device_id k8temp_ids[] = {
15278 + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
15279 +- { 0 },
15280 ++ { 0, 0, 0, 0, 0, 0, 0 },
15281 + };
15282 +
15283 + MODULE_DEVICE_TABLE(pci, k8temp_ids);
15284 +diff -urNp linux-2.6.28.8/drivers/hwmon/sis5595.c linux-2.6.28.8/drivers/hwmon/sis5595.c
15285 +--- linux-2.6.28.8/drivers/hwmon/sis5595.c 2009-02-06 16:47:45.000000000 -0500
15286 ++++ linux-2.6.28.8/drivers/hwmon/sis5595.c 2009-02-21 09:37:48.000000000 -0500
15287 +@@ -698,7 +698,7 @@ static struct sis5595_data *sis5595_upda
15288 +
15289 + static struct pci_device_id sis5595_pci_ids[] = {
15290 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
15291 +- { 0, }
15292 ++ { 0, 0, 0, 0, 0, 0, 0 }
15293 + };
15294 +
15295 + MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
15296 +diff -urNp linux-2.6.28.8/drivers/hwmon/via686a.c linux-2.6.28.8/drivers/hwmon/via686a.c
15297 +--- linux-2.6.28.8/drivers/hwmon/via686a.c 2009-02-06 16:47:45.000000000 -0500
15298 ++++ linux-2.6.28.8/drivers/hwmon/via686a.c 2009-02-21 09:37:48.000000000 -0500
15299 +@@ -768,7 +768,7 @@ static struct via686a_data *via686a_upda
15300 +
15301 + static struct pci_device_id via686a_pci_ids[] = {
15302 + { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
15303 +- { 0, }
15304 ++ { 0, 0, 0, 0, 0, 0, 0 }
15305 + };
15306 +
15307 + MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
15308 +diff -urNp linux-2.6.28.8/drivers/hwmon/vt8231.c linux-2.6.28.8/drivers/hwmon/vt8231.c
15309 +--- linux-2.6.28.8/drivers/hwmon/vt8231.c 2009-02-06 16:47:45.000000000 -0500
15310 ++++ linux-2.6.28.8/drivers/hwmon/vt8231.c 2009-02-21 09:37:48.000000000 -0500
15311 +@@ -698,7 +698,7 @@ static struct platform_driver vt8231_dri
15312 +
15313 + static struct pci_device_id vt8231_pci_ids[] = {
15314 + { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
15315 +- { 0, }
15316 ++ { 0, 0, 0, 0, 0, 0, 0 }
15317 + };
15318 +
15319 + MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
15320 +diff -urNp linux-2.6.28.8/drivers/hwmon/w83791d.c linux-2.6.28.8/drivers/hwmon/w83791d.c
15321 +--- linux-2.6.28.8/drivers/hwmon/w83791d.c 2009-02-06 16:47:45.000000000 -0500
15322 ++++ linux-2.6.28.8/drivers/hwmon/w83791d.c 2009-02-21 09:37:48.000000000 -0500
15323 +@@ -327,8 +327,8 @@ static int w83791d_detect(struct i2c_cli
15324 + struct i2c_board_info *info);
15325 + static int w83791d_remove(struct i2c_client *client);
15326 +
15327 +-static int w83791d_read(struct i2c_client *client, u8 register);
15328 +-static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
15329 ++static int w83791d_read(struct i2c_client *client, u8 reg);
15330 ++static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
15331 + static struct w83791d_data *w83791d_update_device(struct device *dev);
15332 +
15333 + #ifdef DEBUG
15334 +diff -urNp linux-2.6.28.8/drivers/i2c/busses/i2c-i801.c linux-2.6.28.8/drivers/i2c/busses/i2c-i801.c
15335 +--- linux-2.6.28.8/drivers/i2c/busses/i2c-i801.c 2009-02-06 16:47:45.000000000 -0500
15336 ++++ linux-2.6.28.8/drivers/i2c/busses/i2c-i801.c 2009-02-21 09:37:48.000000000 -0500
15337 +@@ -578,7 +578,7 @@ static struct pci_device_id i801_ids[] =
15338 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) },
15339 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) },
15340 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PCH_SMBUS) },
15341 +- { 0, }
15342 ++ { 0, 0, 0, 0, 0, 0, 0 }
15343 + };
15344 +
15345 + MODULE_DEVICE_TABLE (pci, i801_ids);
15346 +diff -urNp linux-2.6.28.8/drivers/i2c/busses/i2c-piix4.c linux-2.6.28.8/drivers/i2c/busses/i2c-piix4.c
15347 +--- linux-2.6.28.8/drivers/i2c/busses/i2c-piix4.c 2009-02-06 16:47:45.000000000 -0500
15348 ++++ linux-2.6.28.8/drivers/i2c/busses/i2c-piix4.c 2009-02-21 09:37:48.000000000 -0500
15349 +@@ -123,7 +123,7 @@ static struct dmi_system_id __devinitdat
15350 + .ident = "IBM",
15351 + .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
15352 + },
15353 +- { },
15354 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL },
15355 + };
15356 +
15357 + static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
15358 +@@ -424,7 +424,7 @@ static struct pci_device_id piix4_ids[]
15359 + PCI_DEVICE_ID_SERVERWORKS_CSB6) },
15360 + { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
15361 + PCI_DEVICE_ID_SERVERWORKS_HT1000SB) },
15362 +- { 0, }
15363 ++ { 0, 0, 0, 0, 0, 0, 0 }
15364 + };
15365 +
15366 + MODULE_DEVICE_TABLE (pci, piix4_ids);
15367 +diff -urNp linux-2.6.28.8/drivers/i2c/busses/i2c-sis630.c linux-2.6.28.8/drivers/i2c/busses/i2c-sis630.c
15368 +--- linux-2.6.28.8/drivers/i2c/busses/i2c-sis630.c 2009-02-06 16:47:45.000000000 -0500
15369 ++++ linux-2.6.28.8/drivers/i2c/busses/i2c-sis630.c 2009-02-21 09:37:48.000000000 -0500
15370 +@@ -472,7 +472,7 @@ static struct i2c_adapter sis630_adapter
15371 + static struct pci_device_id sis630_ids[] __devinitdata = {
15372 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
15373 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
15374 +- { 0, }
15375 ++ { 0, 0, 0, 0, 0, 0, 0 }
15376 + };
15377 +
15378 + MODULE_DEVICE_TABLE (pci, sis630_ids);
15379 +diff -urNp linux-2.6.28.8/drivers/i2c/busses/i2c-sis96x.c linux-2.6.28.8/drivers/i2c/busses/i2c-sis96x.c
15380 +--- linux-2.6.28.8/drivers/i2c/busses/i2c-sis96x.c 2009-02-06 16:47:45.000000000 -0500
15381 ++++ linux-2.6.28.8/drivers/i2c/busses/i2c-sis96x.c 2009-02-21 09:37:48.000000000 -0500
15382 +@@ -248,7 +248,7 @@ static struct i2c_adapter sis96x_adapter
15383 +
15384 + static struct pci_device_id sis96x_ids[] = {
15385 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
15386 +- { 0, }
15387 ++ { 0, 0, 0, 0, 0, 0, 0 }
15388 + };
15389 +
15390 + MODULE_DEVICE_TABLE (pci, sis96x_ids);
15391 +diff -urNp linux-2.6.28.8/drivers/ieee1394/dv1394.c linux-2.6.28.8/drivers/ieee1394/dv1394.c
15392 +--- linux-2.6.28.8/drivers/ieee1394/dv1394.c 2009-02-06 16:47:45.000000000 -0500
15393 ++++ linux-2.6.28.8/drivers/ieee1394/dv1394.c 2009-02-21 09:37:48.000000000 -0500
15394 +@@ -739,7 +739,7 @@ static void frame_prepare(struct video_c
15395 + based upon DIF section and sequence
15396 + */
15397 +
15398 +-static void inline
15399 ++static inline void
15400 + frame_put_packet (struct frame *f, struct packet *p)
15401 + {
15402 + int section_type = p->data[0] >> 5; /* section type is in bits 5 - 7 */
15403 +@@ -2177,7 +2177,7 @@ static struct ieee1394_device_id dv1394_
15404 + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
15405 + .version = AVC_SW_VERSION_ENTRY & 0xffffff
15406 + },
15407 +- { }
15408 ++ { 0, 0, 0, 0, 0, 0 }
15409 + };
15410 +
15411 + MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
15412 +diff -urNp linux-2.6.28.8/drivers/ieee1394/eth1394.c linux-2.6.28.8/drivers/ieee1394/eth1394.c
15413 +--- linux-2.6.28.8/drivers/ieee1394/eth1394.c 2009-02-06 16:47:45.000000000 -0500
15414 ++++ linux-2.6.28.8/drivers/ieee1394/eth1394.c 2009-02-21 09:37:48.000000000 -0500
15415 +@@ -451,7 +451,7 @@ static struct ieee1394_device_id eth1394
15416 + .specifier_id = ETHER1394_GASP_SPECIFIER_ID,
15417 + .version = ETHER1394_GASP_VERSION,
15418 + },
15419 +- {}
15420 ++ { 0, 0, 0, 0, 0, 0 }
15421 + };
15422 +
15423 + MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
15424 +diff -urNp linux-2.6.28.8/drivers/ieee1394/hosts.c linux-2.6.28.8/drivers/ieee1394/hosts.c
15425 +--- linux-2.6.28.8/drivers/ieee1394/hosts.c 2009-02-06 16:47:45.000000000 -0500
15426 ++++ linux-2.6.28.8/drivers/ieee1394/hosts.c 2009-02-21 09:37:48.000000000 -0500
15427 +@@ -78,6 +78,7 @@ static int dummy_isoctl(struct hpsb_iso
15428 + }
15429 +
15430 + static struct hpsb_host_driver dummy_driver = {
15431 ++ .name = "dummy",
15432 + .transmit_packet = dummy_transmit_packet,
15433 + .devctl = dummy_devctl,
15434 + .isoctl = dummy_isoctl
15435 +diff -urNp linux-2.6.28.8/drivers/ieee1394/ohci1394.c linux-2.6.28.8/drivers/ieee1394/ohci1394.c
15436 +--- linux-2.6.28.8/drivers/ieee1394/ohci1394.c 2009-02-06 16:47:45.000000000 -0500
15437 ++++ linux-2.6.28.8/drivers/ieee1394/ohci1394.c 2009-02-21 09:37:48.000000000 -0500
15438 +@@ -147,9 +147,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
15439 + printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
15440 +
15441 + /* Module Parameters */
15442 +-static int phys_dma = 1;
15443 ++static int phys_dma;
15444 + module_param(phys_dma, int, 0444);
15445 +-MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 1).");
15446 ++MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 0).");
15447 +
15448 + static void dma_trm_tasklet(unsigned long data);
15449 + static void dma_trm_reset(struct dma_trm_ctx *d);
15450 +@@ -3437,7 +3437,7 @@ static struct pci_device_id ohci1394_pci
15451 + .subvendor = PCI_ANY_ID,
15452 + .subdevice = PCI_ANY_ID,
15453 + },
15454 +- { 0, },
15455 ++ { 0, 0, 0, 0, 0, 0, 0 },
15456 + };
15457 +
15458 + MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
15459 +diff -urNp linux-2.6.28.8/drivers/ieee1394/raw1394.c linux-2.6.28.8/drivers/ieee1394/raw1394.c
15460 +--- linux-2.6.28.8/drivers/ieee1394/raw1394.c 2009-02-06 16:47:45.000000000 -0500
15461 ++++ linux-2.6.28.8/drivers/ieee1394/raw1394.c 2009-02-21 09:37:48.000000000 -0500
15462 +@@ -2995,7 +2995,7 @@ static struct ieee1394_device_id raw1394
15463 + .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
15464 + .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
15465 + .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff},
15466 +- {}
15467 ++ { 0, 0, 0, 0, 0, 0 }
15468 + };
15469 +
15470 + MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
15471 +diff -urNp linux-2.6.28.8/drivers/ieee1394/sbp2.c linux-2.6.28.8/drivers/ieee1394/sbp2.c
15472 +--- linux-2.6.28.8/drivers/ieee1394/sbp2.c 2009-02-07 16:10:45.000000000 -0500
15473 ++++ linux-2.6.28.8/drivers/ieee1394/sbp2.c 2009-02-21 09:37:48.000000000 -0500
15474 +@@ -290,7 +290,7 @@ static struct ieee1394_device_id sbp2_id
15475 + .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
15476 + .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
15477 + .version = SBP2_SW_VERSION_ENTRY & 0xffffff},
15478 +- {}
15479 ++ { 0, 0, 0, 0, 0, 0 }
15480 + };
15481 + MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
15482 +
15483 +@@ -2110,7 +2110,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot
15484 + MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
15485 + MODULE_LICENSE("GPL");
15486 +
15487 +-static int sbp2_module_init(void)
15488 ++static int __init sbp2_module_init(void)
15489 + {
15490 + int ret;
15491 +
15492 +diff -urNp linux-2.6.28.8/drivers/ieee1394/video1394.c linux-2.6.28.8/drivers/ieee1394/video1394.c
15493 +--- linux-2.6.28.8/drivers/ieee1394/video1394.c 2009-02-06 16:47:45.000000000 -0500
15494 ++++ linux-2.6.28.8/drivers/ieee1394/video1394.c 2009-02-21 09:37:48.000000000 -0500
15495 +@@ -1310,7 +1310,7 @@ static struct ieee1394_device_id video13
15496 + .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
15497 + .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff
15498 + },
15499 +- { }
15500 ++ { 0, 0, 0, 0, 0, 0 }
15501 + };
15502 +
15503 + MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
15504 +diff -urNp linux-2.6.28.8/drivers/input/keyboard/atkbd.c linux-2.6.28.8/drivers/input/keyboard/atkbd.c
15505 +--- linux-2.6.28.8/drivers/input/keyboard/atkbd.c 2009-02-06 16:47:45.000000000 -0500
15506 ++++ linux-2.6.28.8/drivers/input/keyboard/atkbd.c 2009-02-21 09:37:48.000000000 -0500
15507 +@@ -1164,7 +1164,7 @@ static struct serio_device_id atkbd_seri
15508 + .id = SERIO_ANY,
15509 + .extra = SERIO_ANY,
15510 + },
15511 +- { 0 }
15512 ++ { 0, 0, 0, 0 }
15513 + };
15514 +
15515 + MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
15516 +diff -urNp linux-2.6.28.8/drivers/input/mouse/lifebook.c linux-2.6.28.8/drivers/input/mouse/lifebook.c
15517 +--- linux-2.6.28.8/drivers/input/mouse/lifebook.c 2009-02-06 16:47:45.000000000 -0500
15518 ++++ linux-2.6.28.8/drivers/input/mouse/lifebook.c 2009-02-21 09:37:48.000000000 -0500
15519 +@@ -110,7 +110,7 @@ static const struct dmi_system_id lifebo
15520 + DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
15521 + },
15522 + },
15523 +- { }
15524 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL}
15525 + };
15526 +
15527 + static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
15528 +diff -urNp linux-2.6.28.8/drivers/input/mouse/psmouse-base.c linux-2.6.28.8/drivers/input/mouse/psmouse-base.c
15529 +--- linux-2.6.28.8/drivers/input/mouse/psmouse-base.c 2009-02-06 16:47:45.000000000 -0500
15530 ++++ linux-2.6.28.8/drivers/input/mouse/psmouse-base.c 2009-02-21 09:37:48.000000000 -0500
15531 +@@ -1378,7 +1378,7 @@ static struct serio_device_id psmouse_se
15532 + .id = SERIO_ANY,
15533 + .extra = SERIO_ANY,
15534 + },
15535 +- { 0 }
15536 ++ { 0, 0, 0, 0 }
15537 + };
15538 +
15539 + MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
15540 +diff -urNp linux-2.6.28.8/drivers/input/mouse/synaptics.c linux-2.6.28.8/drivers/input/mouse/synaptics.c
15541 +--- linux-2.6.28.8/drivers/input/mouse/synaptics.c 2009-02-06 16:47:45.000000000 -0500
15542 ++++ linux-2.6.28.8/drivers/input/mouse/synaptics.c 2009-02-21 09:37:48.000000000 -0500
15543 +@@ -417,7 +417,7 @@ static void synaptics_process_packet(str
15544 + break;
15545 + case 2:
15546 + if (SYN_MODEL_PEN(priv->model_id))
15547 +- ; /* Nothing, treat a pen as a single finger */
15548 ++ break; /* Nothing, treat a pen as a single finger */
15549 + break;
15550 + case 4 ... 15:
15551 + if (SYN_CAP_PALMDETECT(priv->capabilities))
15552 +@@ -624,7 +624,7 @@ static const struct dmi_system_id toshib
15553 + DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
15554 + },
15555 + },
15556 +- { }
15557 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
15558 + };
15559 + #endif
15560 +
15561 +diff -urNp linux-2.6.28.8/drivers/input/mousedev.c linux-2.6.28.8/drivers/input/mousedev.c
15562 +--- linux-2.6.28.8/drivers/input/mousedev.c 2009-02-06 16:47:45.000000000 -0500
15563 ++++ linux-2.6.28.8/drivers/input/mousedev.c 2009-02-21 09:37:48.000000000 -0500
15564 +@@ -1063,7 +1063,7 @@ static struct input_handler mousedev_han
15565 +
15566 + #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
15567 + static struct miscdevice psaux_mouse = {
15568 +- PSMOUSE_MINOR, "psaux", &mousedev_fops
15569 ++ PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL
15570 + };
15571 + static int psaux_registered;
15572 + #endif
15573 +diff -urNp linux-2.6.28.8/drivers/input/serio/i8042-x86ia64io.h linux-2.6.28.8/drivers/input/serio/i8042-x86ia64io.h
15574 +--- linux-2.6.28.8/drivers/input/serio/i8042-x86ia64io.h 2009-02-06 16:47:45.000000000 -0500
15575 ++++ linux-2.6.28.8/drivers/input/serio/i8042-x86ia64io.h 2009-02-21 09:37:48.000000000 -0500
15576 +@@ -143,7 +143,7 @@ static struct dmi_system_id __initdata i
15577 + DMI_MATCH(DMI_PRODUCT_VERSION, "M606"),
15578 + },
15579 + },
15580 +- { }
15581 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
15582 + };
15583 +
15584 + /*
15585 +@@ -351,7 +351,7 @@ static struct dmi_system_id __initdata i
15586 + DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"),
15587 + },
15588 + },
15589 +- { }
15590 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
15591 + };
15592 +
15593 + #ifdef CONFIG_PNP
15594 +@@ -363,7 +363,7 @@ static struct dmi_system_id __initdata i
15595 + DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
15596 + },
15597 + },
15598 +- { }
15599 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
15600 + };
15601 + #endif
15602 +
15603 +@@ -430,7 +430,7 @@ static struct dmi_system_id __initdata i
15604 + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"),
15605 + },
15606 + },
15607 +- { }
15608 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
15609 + };
15610 +
15611 + #endif /* CONFIG_X86 */
15612 +diff -urNp linux-2.6.28.8/drivers/input/serio/serio_raw.c linux-2.6.28.8/drivers/input/serio/serio_raw.c
15613 +--- linux-2.6.28.8/drivers/input/serio/serio_raw.c 2009-02-06 16:47:45.000000000 -0500
15614 ++++ linux-2.6.28.8/drivers/input/serio/serio_raw.c 2009-02-21 09:37:48.000000000 -0500
15615 +@@ -378,7 +378,7 @@ static struct serio_device_id serio_raw_
15616 + .id = SERIO_ANY,
15617 + .extra = SERIO_ANY,
15618 + },
15619 +- { 0 }
15620 ++ { 0, 0, 0, 0 }
15621 + };
15622 +
15623 + MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
15624 +diff -urNp linux-2.6.28.8/drivers/lguest/core.c linux-2.6.28.8/drivers/lguest/core.c
15625 +--- linux-2.6.28.8/drivers/lguest/core.c 2009-02-06 16:47:45.000000000 -0500
15626 ++++ linux-2.6.28.8/drivers/lguest/core.c 2009-03-07 10:28:24.000000000 -0500
15627 +@@ -80,9 +80,17 @@ static __init int map_switcher(void)
15628 + * (SWITCHER_ADDR). We might not get it in theory, but in practice
15629 + * it's worked so far. The end address needs +1 because __get_vm_area
15630 + * allocates an extra guard page, so we need space for that. */
15631 ++
15632 ++#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
15633 ++ switcher_vma = __get_vm_area(TOTAL_SWITCHER_PAGES * PAGE_SIZE,
15634 ++ VM_ALLOC | VM_KERNEXEC, SWITCHER_ADDR, SWITCHER_ADDR
15635 ++ + (TOTAL_SWITCHER_PAGES+1) * PAGE_SIZE);
15636 ++#else
15637 + switcher_vma = __get_vm_area(TOTAL_SWITCHER_PAGES * PAGE_SIZE,
15638 + VM_ALLOC, SWITCHER_ADDR, SWITCHER_ADDR
15639 + + (TOTAL_SWITCHER_PAGES+1) * PAGE_SIZE);
15640 ++#endif
15641 ++
15642 + if (!switcher_vma) {
15643 + err = -ENOMEM;
15644 + printk("lguest: could not map switcher pages high\n");
15645 +diff -urNp linux-2.6.28.8/drivers/md/bitmap.c linux-2.6.28.8/drivers/md/bitmap.c
15646 +--- linux-2.6.28.8/drivers/md/bitmap.c 2009-02-06 16:47:45.000000000 -0500
15647 ++++ linux-2.6.28.8/drivers/md/bitmap.c 2009-02-21 09:37:48.000000000 -0500
15648 +@@ -57,7 +57,7 @@
15649 + # if DEBUG > 0
15650 + # define PRINTK(x...) printk(KERN_DEBUG x)
15651 + # else
15652 +-# define PRINTK(x...)
15653 ++# define PRINTK(x...) do {} while (0)
15654 + # endif
15655 + #endif
15656 +
15657 +diff -urNp linux-2.6.28.8/drivers/mtd/devices/doc2000.c linux-2.6.28.8/drivers/mtd/devices/doc2000.c
15658 +--- linux-2.6.28.8/drivers/mtd/devices/doc2000.c 2009-02-06 16:47:45.000000000 -0500
15659 ++++ linux-2.6.28.8/drivers/mtd/devices/doc2000.c 2009-02-21 09:37:48.000000000 -0500
15660 +@@ -777,7 +777,7 @@ static int doc_write(struct mtd_info *mt
15661 +
15662 + /* The ECC will not be calculated correctly if less than 512 is written */
15663 + /* DBB-
15664 +- if (len != 0x200 && eccbuf)
15665 ++ if (len != 0x200)
15666 + printk(KERN_WARNING
15667 + "ECC needs a full sector write (adr: %lx size %lx)\n",
15668 + (long) to, (long) len);
15669 +diff -urNp linux-2.6.28.8/drivers/mtd/devices/doc2001.c linux-2.6.28.8/drivers/mtd/devices/doc2001.c
15670 +--- linux-2.6.28.8/drivers/mtd/devices/doc2001.c 2009-02-06 16:47:45.000000000 -0500
15671 ++++ linux-2.6.28.8/drivers/mtd/devices/doc2001.c 2009-02-21 09:37:48.000000000 -0500
15672 +@@ -396,6 +396,8 @@ static int doc_read (struct mtd_info *mt
15673 + /* Don't allow read past end of device */
15674 + if (from >= this->totlen)
15675 + return -EINVAL;
15676 ++ if (!len)
15677 ++ return -EINVAL;
15678 +
15679 + /* Don't allow a single read to cross a 512-byte block boundary */
15680 + if (from + len > ((from | 0x1ff) + 1))
15681 +diff -urNp linux-2.6.28.8/drivers/mtd/devices/slram.c linux-2.6.28.8/drivers/mtd/devices/slram.c
15682 +--- linux-2.6.28.8/drivers/mtd/devices/slram.c 2009-02-06 16:47:45.000000000 -0500
15683 ++++ linux-2.6.28.8/drivers/mtd/devices/slram.c 2009-02-21 09:37:48.000000000 -0500
15684 +@@ -273,7 +273,7 @@ static int parse_cmdline(char *devname,
15685 + }
15686 + T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n",
15687 + devname, devstart, devlength);
15688 +- if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) {
15689 ++ if (devlength % SLRAM_BLK_SZ != 0) {
15690 + E("slram: Illegal start / length parameter.\n");
15691 + return(-EINVAL);
15692 + }
15693 +diff -urNp linux-2.6.28.8/drivers/mtd/ubi/build.c linux-2.6.28.8/drivers/mtd/ubi/build.c
15694 +--- linux-2.6.28.8/drivers/mtd/ubi/build.c 2009-02-06 16:47:45.000000000 -0500
15695 ++++ linux-2.6.28.8/drivers/mtd/ubi/build.c 2009-02-21 09:37:48.000000000 -0500
15696 +@@ -1104,7 +1104,7 @@ static int __init bytes_str_to_int(const
15697 + unsigned long result;
15698 +
15699 + result = simple_strtoul(str, &endp, 0);
15700 +- if (str == endp || result < 0) {
15701 ++ if (str == endp) {
15702 + printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n",
15703 + str);
15704 + return -EINVAL;
15705 +diff -urNp linux-2.6.28.8/drivers/net/eepro100.c linux-2.6.28.8/drivers/net/eepro100.c
15706 +--- linux-2.6.28.8/drivers/net/eepro100.c 2009-02-06 16:47:45.000000000 -0500
15707 ++++ linux-2.6.28.8/drivers/net/eepro100.c 2009-02-21 09:37:48.000000000 -0500
15708 +@@ -47,7 +47,7 @@ static int rxdmacount /* = 0 */;
15709 + # define rx_align(skb) skb_reserve((skb), 2)
15710 + # define RxFD_ALIGNMENT __attribute__ ((aligned (2), packed))
15711 + #else
15712 +-# define rx_align(skb)
15713 ++# define rx_align(skb) do {} while (0)
15714 + # define RxFD_ALIGNMENT
15715 + #endif
15716 +
15717 +@@ -2334,33 +2334,33 @@ static void __devexit eepro100_remove_on
15718 + }
15719 +
15720 + static struct pci_device_id eepro100_pci_tbl[] = {
15721 +- { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, },
15722 +- { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, },
15723 +- { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, },
15724 +- { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, },
15725 +- { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, },
15726 +- { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, },
15727 +- { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, },
15728 +- { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, },
15729 +- { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, },
15730 +- { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, },
15731 +- { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, },
15732 +- { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, },
15733 +- { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, },
15734 +- { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, },
15735 +- { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, },
15736 +- { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, },
15737 +- { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, },
15738 +- { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, },
15739 +- { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, },
15740 +- { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, },
15741 +- { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
15742 +- { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, },
15743 +- { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, },
15744 +- { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, },
15745 +- { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, },
15746 +- { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, },
15747 +- { 0,}
15748 ++ { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15749 ++ { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15750 ++ { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15751 ++ { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15752 ++ { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15753 ++ { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15754 ++ { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15755 ++ { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15756 ++ { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15757 ++ { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15758 ++ { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15759 ++ { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15760 ++ { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15761 ++ { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15762 ++ { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15763 ++ { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15764 ++ { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15765 ++ { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15766 ++ { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15767 ++ { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15768 ++ { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15769 ++ { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15770 ++ { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15771 ++ { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15772 ++ { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15773 ++ { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15774 ++ { 0, 0, 0, 0, 0, 0, 0 }
15775 + };
15776 + MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
15777 +
15778 +diff -urNp linux-2.6.28.8/drivers/net/irda/vlsi_ir.c linux-2.6.28.8/drivers/net/irda/vlsi_ir.c
15779 +--- linux-2.6.28.8/drivers/net/irda/vlsi_ir.c 2009-02-06 16:47:45.000000000 -0500
15780 ++++ linux-2.6.28.8/drivers/net/irda/vlsi_ir.c 2009-02-21 09:37:48.000000000 -0500
15781 +@@ -906,13 +906,12 @@ static int vlsi_hard_start_xmit(struct s
15782 + /* no race - tx-ring already empty */
15783 + vlsi_set_baud(idev, iobase);
15784 + netif_wake_queue(ndev);
15785 +- }
15786 +- else
15787 +- ;
15788 ++ } else {
15789 + /* keep the speed change pending like it would
15790 + * for any len>0 packet. tx completion interrupt
15791 + * will apply it when the tx ring becomes empty.
15792 + */
15793 ++ }
15794 + spin_unlock_irqrestore(&idev->lock, flags);
15795 + dev_kfree_skb_any(skb);
15796 + return 0;
15797 +diff -urNp linux-2.6.28.8/drivers/net/pcnet32.c linux-2.6.28.8/drivers/net/pcnet32.c
15798 +--- linux-2.6.28.8/drivers/net/pcnet32.c 2009-02-06 16:47:45.000000000 -0500
15799 ++++ linux-2.6.28.8/drivers/net/pcnet32.c 2009-02-21 09:37:48.000000000 -0500
15800 +@@ -78,7 +78,7 @@ static int cards_found;
15801 + /*
15802 + * VLB I/O addresses
15803 + */
15804 +-static unsigned int pcnet32_portlist[] __initdata =
15805 ++static unsigned int pcnet32_portlist[] __devinitdata =
15806 + { 0x300, 0x320, 0x340, 0x360, 0 };
15807 +
15808 + static int pcnet32_debug = 0;
15809 +diff -urNp linux-2.6.28.8/drivers/net/tg3.h linux-2.6.28.8/drivers/net/tg3.h
15810 +--- linux-2.6.28.8/drivers/net/tg3.h 2009-02-06 16:47:45.000000000 -0500
15811 ++++ linux-2.6.28.8/drivers/net/tg3.h 2009-02-21 09:37:48.000000000 -0500
15812 +@@ -102,6 +102,7 @@
15813 + #define CHIPREV_ID_5750_A0 0x4000
15814 + #define CHIPREV_ID_5750_A1 0x4001
15815 + #define CHIPREV_ID_5750_A3 0x4003
15816 ++#define CHIPREV_ID_5750_C1 0x4201
15817 + #define CHIPREV_ID_5750_C2 0x4202
15818 + #define CHIPREV_ID_5752_A0_HW 0x5000
15819 + #define CHIPREV_ID_5752_A0 0x6000
15820 +diff -urNp linux-2.6.28.8/drivers/net/wireless/iwlwifi/iwl3945-base.c linux-2.6.28.8/drivers/net/wireless/iwlwifi/iwl3945-base.c
15821 +--- linux-2.6.28.8/drivers/net/wireless/iwlwifi/iwl3945-base.c 2009-02-06 16:47:45.000000000 -0500
15822 ++++ linux-2.6.28.8/drivers/net/wireless/iwlwifi/iwl3945-base.c 2009-02-21 09:37:48.000000000 -0500
15823 +@@ -785,7 +785,7 @@ static int iwl3945_send_cmd_sync(struct
15824 + IWL_ERROR("Error: Response NULL in '%s'\n",
15825 + get_cmd_string(cmd->id));
15826 + ret = -EIO;
15827 +- goto out;
15828 ++ goto cancel;
15829 + }
15830 +
15831 + ret = 0;
15832 +diff -urNp linux-2.6.28.8/drivers/pci/hotplug/cpqphp_nvram.c linux-2.6.28.8/drivers/pci/hotplug/cpqphp_nvram.c
15833 +--- linux-2.6.28.8/drivers/pci/hotplug/cpqphp_nvram.c 2009-02-06 16:47:45.000000000 -0500
15834 ++++ linux-2.6.28.8/drivers/pci/hotplug/cpqphp_nvram.c 2009-02-21 09:37:48.000000000 -0500
15835 +@@ -425,9 +425,13 @@ static u32 store_HRT (void __iomem *rom_
15836 +
15837 + void compaq_nvram_init (void __iomem *rom_start)
15838 + {
15839 ++
15840 ++#ifndef CONFIG_PAX_KERNEXEC
15841 + if (rom_start) {
15842 + compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
15843 + }
15844 ++#endif
15845 ++
15846 + dbg("int15 entry = %p\n", compaq_int15_entry_point);
15847 +
15848 + /* initialize our int15 lock */
15849 +diff -urNp linux-2.6.28.8/drivers/pci/pcie/aer/aerdrv.c linux-2.6.28.8/drivers/pci/pcie/aer/aerdrv.c
15850 +--- linux-2.6.28.8/drivers/pci/pcie/aer/aerdrv.c 2009-02-06 16:47:45.000000000 -0500
15851 ++++ linux-2.6.28.8/drivers/pci/pcie/aer/aerdrv.c 2009-02-21 09:37:48.000000000 -0500
15852 +@@ -59,7 +59,7 @@ static struct pcie_port_service_id aer_i
15853 + .port_type = PCIE_RC_PORT,
15854 + .service_type = PCIE_PORT_SERVICE_AER,
15855 + },
15856 +- { /* end: all zeroes */ }
15857 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
15858 + };
15859 +
15860 + static struct pci_error_handlers aer_error_handlers = {
15861 +diff -urNp linux-2.6.28.8/drivers/pci/pcie/aer/aerdrv_core.c linux-2.6.28.8/drivers/pci/pcie/aer/aerdrv_core.c
15862 +--- linux-2.6.28.8/drivers/pci/pcie/aer/aerdrv_core.c 2009-03-07 10:24:49.000000000 -0500
15863 ++++ linux-2.6.28.8/drivers/pci/pcie/aer/aerdrv_core.c 2009-03-07 10:29:51.000000000 -0500
15864 +@@ -667,7 +667,7 @@ static void aer_isr_one_error(struct pci
15865 + struct aer_err_source *e_src)
15866 + {
15867 + struct device *s_device;
15868 +- struct aer_err_info e_info = {0, 0, 0,};
15869 ++ struct aer_err_info e_info = {0, 0, 0, {0, 0, 0, 0}};
15870 + int i;
15871 + u16 id;
15872 +
15873 +diff -urNp linux-2.6.28.8/drivers/pci/pcie/portdrv_pci.c linux-2.6.28.8/drivers/pci/pcie/portdrv_pci.c
15874 +--- linux-2.6.28.8/drivers/pci/pcie/portdrv_pci.c 2009-03-07 10:24:49.000000000 -0500
15875 ++++ linux-2.6.28.8/drivers/pci/pcie/portdrv_pci.c 2009-03-07 10:29:51.000000000 -0500
15876 +@@ -263,7 +263,7 @@ static void pcie_portdrv_err_resume(stru
15877 + static const struct pci_device_id port_pci_ids[] = { {
15878 + /* handle any PCI-Express port */
15879 + PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
15880 +- }, { /* end: all zeroes */ }
15881 ++ }, { 0, 0, 0, 0, 0, 0, 0 }
15882 + };
15883 + MODULE_DEVICE_TABLE(pci, port_pci_ids);
15884 +
15885 +diff -urNp linux-2.6.28.8/drivers/pci/proc.c linux-2.6.28.8/drivers/pci/proc.c
15886 +--- linux-2.6.28.8/drivers/pci/proc.c 2009-02-06 16:47:45.000000000 -0500
15887 ++++ linux-2.6.28.8/drivers/pci/proc.c 2009-02-21 09:37:48.000000000 -0500
15888 +@@ -470,7 +470,16 @@ static const struct file_operations proc
15889 + static int __init pci_proc_init(void)
15890 + {
15891 + struct pci_dev *dev = NULL;
15892 ++
15893 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
15894 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
15895 ++ proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR, NULL);
15896 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
15897 ++ proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
15898 ++#endif
15899 ++#else
15900 + proc_bus_pci_dir = proc_mkdir("bus/pci", NULL);
15901 ++#endif
15902 + proc_create("devices", 0, proc_bus_pci_dir,
15903 + &proc_bus_pci_dev_operations);
15904 + proc_initialized = 1;
15905 +diff -urNp linux-2.6.28.8/drivers/pcmcia/ti113x.h linux-2.6.28.8/drivers/pcmcia/ti113x.h
15906 +--- linux-2.6.28.8/drivers/pcmcia/ti113x.h 2009-02-06 16:47:45.000000000 -0500
15907 ++++ linux-2.6.28.8/drivers/pcmcia/ti113x.h 2009-02-21 09:37:48.000000000 -0500
15908 +@@ -903,7 +903,7 @@ static struct pci_device_id ene_tune_tbl
15909 + DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
15910 + ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
15911 +
15912 +- {}
15913 ++ { 0, 0, 0, 0, 0, 0, 0 }
15914 + };
15915 +
15916 + static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
15917 +diff -urNp linux-2.6.28.8/drivers/pcmcia/yenta_socket.c linux-2.6.28.8/drivers/pcmcia/yenta_socket.c
15918 +--- linux-2.6.28.8/drivers/pcmcia/yenta_socket.c 2009-02-06 16:47:45.000000000 -0500
15919 ++++ linux-2.6.28.8/drivers/pcmcia/yenta_socket.c 2009-02-21 09:37:48.000000000 -0500
15920 +@@ -1366,7 +1366,7 @@ static struct pci_device_id yenta_table
15921 +
15922 + /* match any cardbus bridge */
15923 + CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
15924 +- { /* all zeroes */ }
15925 ++ { 0, 0, 0, 0, 0, 0, 0 }
15926 + };
15927 + MODULE_DEVICE_TABLE(pci, yenta_table);
15928 +
15929 +diff -urNp linux-2.6.28.8/drivers/pnp/pnpbios/bioscalls.c linux-2.6.28.8/drivers/pnp/pnpbios/bioscalls.c
15930 +--- linux-2.6.28.8/drivers/pnp/pnpbios/bioscalls.c 2009-02-06 16:47:45.000000000 -0500
15931 ++++ linux-2.6.28.8/drivers/pnp/pnpbios/bioscalls.c 2009-02-21 09:37:48.000000000 -0500
15932 +@@ -60,7 +60,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
15933 + set_limit(gdt[(selname) >> 3], size); \
15934 + } while(0)
15935 +
15936 +-static struct desc_struct bad_bios_desc;
15937 ++static struct desc_struct bad_bios_desc __read_only;
15938 +
15939 + /*
15940 + * At some point we want to use this stack frame pointer to unwind
15941 +@@ -87,6 +87,10 @@ static inline u16 call_pnp_bios(u16 func
15942 + struct desc_struct save_desc_40;
15943 + int cpu;
15944 +
15945 ++#ifdef CONFIG_PAX_KERNEXEC
15946 ++ unsigned long cr0;
15947 ++#endif
15948 ++
15949 + /*
15950 + * PnP BIOSes are generally not terribly re-entrant.
15951 + * Also, don't rely on them to save everything correctly.
15952 +@@ -96,8 +100,17 @@ static inline u16 call_pnp_bios(u16 func
15953 +
15954 + cpu = get_cpu();
15955 + save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
15956 ++
15957 ++#ifdef CONFIG_PAX_KERNEXEC
15958 ++ pax_open_kernel(cr0);
15959 ++#endif
15960 ++
15961 + get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
15962 +
15963 ++#ifdef CONFIG_PAX_KERNEXEC
15964 ++ pax_close_kernel(cr0);
15965 ++#endif
15966 ++
15967 + /* On some boxes IRQ's during PnP BIOS calls are deadly. */
15968 + spin_lock_irqsave(&pnp_bios_lock, flags);
15969 +
15970 +@@ -134,7 +147,16 @@ static inline u16 call_pnp_bios(u16 func
15971 + :"memory");
15972 + spin_unlock_irqrestore(&pnp_bios_lock, flags);
15973 +
15974 ++#ifdef CONFIG_PAX_KERNEXEC
15975 ++ pax_open_kernel(cr0);
15976 ++#endif
15977 ++
15978 + get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
15979 ++
15980 ++#ifdef CONFIG_PAX_KERNEXEC
15981 ++ pax_close_kernel(cr0);
15982 ++#endif
15983 ++
15984 + put_cpu();
15985 +
15986 + /* If we get here and this is set then the PnP BIOS faulted on us. */
15987 +@@ -468,16 +490,24 @@ int pnp_bios_read_escd(char *data, u32 n
15988 + return status;
15989 + }
15990 +
15991 +-void pnpbios_calls_init(union pnp_bios_install_struct *header)
15992 ++void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
15993 + {
15994 + int i;
15995 +
15996 ++#ifdef CONFIG_PAX_KERNEXEC
15997 ++ unsigned long cr0;
15998 ++#endif
15999 ++
16000 + spin_lock_init(&pnp_bios_lock);
16001 + pnp_bios_callpoint.offset = header->fields.pm16offset;
16002 + pnp_bios_callpoint.segment = PNP_CS16;
16003 +
16004 ++#ifdef CONFIG_PAX_KERNEXEC
16005 ++ pax_open_kernel(cr0);
16006 ++#endif
16007 ++
16008 + bad_bios_desc.a = 0;
16009 +- bad_bios_desc.b = 0x00409200;
16010 ++ bad_bios_desc.b = 0x00409300;
16011 +
16012 + set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
16013 + _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
16014 +@@ -491,4 +521,9 @@ void pnpbios_calls_init(union pnp_bios_i
16015 + set_base(gdt[GDT_ENTRY_PNPBIOS_DS],
16016 + __va(header->fields.pm16dseg));
16017 + }
16018 ++
16019 ++#ifdef CONFIG_PAX_KERNEXEC
16020 ++ pax_close_kernel(cr0);
16021 ++#endif
16022 ++
16023 + }
16024 +diff -urNp linux-2.6.28.8/drivers/pnp/quirks.c linux-2.6.28.8/drivers/pnp/quirks.c
16025 +--- linux-2.6.28.8/drivers/pnp/quirks.c 2009-02-06 16:47:45.000000000 -0500
16026 ++++ linux-2.6.28.8/drivers/pnp/quirks.c 2009-02-21 09:37:48.000000000 -0500
16027 +@@ -327,7 +327,7 @@ static struct pnp_fixup pnp_fixups[] = {
16028 + /* PnP resources that might overlap PCI BARs */
16029 + {"PNP0c01", quirk_system_pci_resources},
16030 + {"PNP0c02", quirk_system_pci_resources},
16031 +- {""}
16032 ++ {"", NULL}
16033 + };
16034 +
16035 + void pnp_fixup_device(struct pnp_dev *dev)
16036 +diff -urNp linux-2.6.28.8/drivers/pnp/resource.c linux-2.6.28.8/drivers/pnp/resource.c
16037 +--- linux-2.6.28.8/drivers/pnp/resource.c 2009-02-06 16:47:45.000000000 -0500
16038 ++++ linux-2.6.28.8/drivers/pnp/resource.c 2009-02-21 09:37:48.000000000 -0500
16039 +@@ -355,7 +355,7 @@ int pnp_check_irq(struct pnp_dev *dev, s
16040 + return 1;
16041 +
16042 + /* check if the resource is valid */
16043 +- if (*irq < 0 || *irq > 15)
16044 ++ if (*irq > 15)
16045 + return 0;
16046 +
16047 + /* check if the resource is reserved */
16048 +@@ -419,7 +419,7 @@ int pnp_check_dma(struct pnp_dev *dev, s
16049 + return 1;
16050 +
16051 + /* check if the resource is valid */
16052 +- if (*dma < 0 || *dma == 4 || *dma > 7)
16053 ++ if (*dma == 4 || *dma > 7)
16054 + return 0;
16055 +
16056 + /* check if the resource is reserved */
16057 +diff -urNp linux-2.6.28.8/drivers/scsi/scsi_logging.h linux-2.6.28.8/drivers/scsi/scsi_logging.h
16058 +--- linux-2.6.28.8/drivers/scsi/scsi_logging.h 2009-02-06 16:47:45.000000000 -0500
16059 ++++ linux-2.6.28.8/drivers/scsi/scsi_logging.h 2009-02-21 09:37:48.000000000 -0500
16060 +@@ -51,7 +51,7 @@ do { \
16061 + } while (0); \
16062 + } while (0)
16063 + #else
16064 +-#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
16065 ++#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
16066 + #endif /* CONFIG_SCSI_LOGGING */
16067 +
16068 + /*
16069 +diff -urNp linux-2.6.28.8/drivers/serial/8250_pci.c linux-2.6.28.8/drivers/serial/8250_pci.c
16070 +--- linux-2.6.28.8/drivers/serial/8250_pci.c 2009-03-07 10:24:49.000000000 -0500
16071 ++++ linux-2.6.28.8/drivers/serial/8250_pci.c 2009-03-07 10:29:51.000000000 -0500
16072 +@@ -3138,7 +3138,7 @@ static struct pci_device_id serial_pci_t
16073 + PCI_ANY_ID, PCI_ANY_ID,
16074 + PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
16075 + 0xffff00, pbn_default },
16076 +- { 0, }
16077 ++ { 0, 0, 0, 0, 0, 0, 0 }
16078 + };
16079 +
16080 + static struct pci_driver serial_pci_driver = {
16081 +diff -urNp linux-2.6.28.8/drivers/usb/class/cdc-acm.c linux-2.6.28.8/drivers/usb/class/cdc-acm.c
16082 +--- linux-2.6.28.8/drivers/usb/class/cdc-acm.c 2009-03-07 10:24:49.000000000 -0500
16083 ++++ linux-2.6.28.8/drivers/usb/class/cdc-acm.c 2009-03-07 10:29:51.000000000 -0500
16084 +@@ -1388,7 +1388,7 @@ static struct usb_device_id acm_ids[] =
16085 + USB_CDC_ACM_PROTO_AT_CDMA) },
16086 +
16087 + /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */
16088 +- { }
16089 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
16090 + };
16091 +
16092 + MODULE_DEVICE_TABLE (usb, acm_ids);
16093 +diff -urNp linux-2.6.28.8/drivers/usb/class/usblp.c linux-2.6.28.8/drivers/usb/class/usblp.c
16094 +--- linux-2.6.28.8/drivers/usb/class/usblp.c 2009-02-06 16:47:45.000000000 -0500
16095 ++++ linux-2.6.28.8/drivers/usb/class/usblp.c 2009-02-21 09:37:48.000000000 -0500
16096 +@@ -227,7 +227,7 @@ static const struct quirk_printer_struct
16097 + { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
16098 + { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@×××.de> */
16099 + { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
16100 +- { 0, 0 }
16101 ++ { 0, 0, 0 }
16102 + };
16103 +
16104 + static int usblp_wwait(struct usblp *usblp, int nonblock);
16105 +@@ -1402,7 +1402,7 @@ static struct usb_device_id usblp_ids []
16106 + { USB_INTERFACE_INFO(7, 1, 2) },
16107 + { USB_INTERFACE_INFO(7, 1, 3) },
16108 + { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */
16109 +- { } /* Terminating entry */
16110 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
16111 + };
16112 +
16113 + MODULE_DEVICE_TABLE (usb, usblp_ids);
16114 +diff -urNp linux-2.6.28.8/drivers/usb/core/hub.c linux-2.6.28.8/drivers/usb/core/hub.c
16115 +--- linux-2.6.28.8/drivers/usb/core/hub.c 2009-02-06 16:47:45.000000000 -0500
16116 ++++ linux-2.6.28.8/drivers/usb/core/hub.c 2009-02-21 09:37:48.000000000 -0500
16117 +@@ -3194,7 +3194,7 @@ static struct usb_device_id hub_id_table
16118 + .bDeviceClass = USB_CLASS_HUB},
16119 + { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
16120 + .bInterfaceClass = USB_CLASS_HUB},
16121 +- { } /* Terminating entry */
16122 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
16123 + };
16124 +
16125 + MODULE_DEVICE_TABLE (usb, hub_id_table);
16126 +diff -urNp linux-2.6.28.8/drivers/usb/host/ehci-pci.c linux-2.6.28.8/drivers/usb/host/ehci-pci.c
16127 +--- linux-2.6.28.8/drivers/usb/host/ehci-pci.c 2009-02-06 16:47:45.000000000 -0500
16128 ++++ linux-2.6.28.8/drivers/usb/host/ehci-pci.c 2009-02-21 09:37:48.000000000 -0500
16129 +@@ -414,7 +414,7 @@ static const struct pci_device_id pci_id
16130 + PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
16131 + .driver_data = (unsigned long) &ehci_pci_hc_driver,
16132 + },
16133 +- { /* end: all zeroes */ }
16134 ++ { 0, 0, 0, 0, 0, 0, 0 }
16135 + };
16136 + MODULE_DEVICE_TABLE(pci, pci_ids);
16137 +
16138 +diff -urNp linux-2.6.28.8/drivers/usb/host/uhci-hcd.c linux-2.6.28.8/drivers/usb/host/uhci-hcd.c
16139 +--- linux-2.6.28.8/drivers/usb/host/uhci-hcd.c 2009-02-06 16:47:45.000000000 -0500
16140 ++++ linux-2.6.28.8/drivers/usb/host/uhci-hcd.c 2009-02-21 09:37:48.000000000 -0500
16141 +@@ -927,7 +927,7 @@ static const struct pci_device_id uhci_p
16142 + /* handle any USB UHCI controller */
16143 + PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),
16144 + .driver_data = (unsigned long) &uhci_driver,
16145 +- }, { /* end: all zeroes */ }
16146 ++ }, { 0, 0, 0, 0, 0, 0, 0 }
16147 + };
16148 +
16149 + MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
16150 +diff -urNp linux-2.6.28.8/drivers/usb/storage/debug.h linux-2.6.28.8/drivers/usb/storage/debug.h
16151 +--- linux-2.6.28.8/drivers/usb/storage/debug.h 2009-02-06 16:47:45.000000000 -0500
16152 ++++ linux-2.6.28.8/drivers/usb/storage/debug.h 2009-02-21 09:37:48.000000000 -0500
16153 +@@ -54,9 +54,9 @@ void usb_stor_show_sense( unsigned char
16154 + #define US_DEBUGPX(x...) printk( x )
16155 + #define US_DEBUG(x) x
16156 + #else
16157 +-#define US_DEBUGP(x...)
16158 +-#define US_DEBUGPX(x...)
16159 +-#define US_DEBUG(x)
16160 ++#define US_DEBUGP(x...) do {} while (0)
16161 ++#define US_DEBUGPX(x...) do {} while (0)
16162 ++#define US_DEBUG(x) do {} while (0)
16163 + #endif
16164 +
16165 + #endif
16166 +diff -urNp linux-2.6.28.8/drivers/usb/storage/usb.c linux-2.6.28.8/drivers/usb/storage/usb.c
16167 +--- linux-2.6.28.8/drivers/usb/storage/usb.c 2009-02-06 16:47:45.000000000 -0500
16168 ++++ linux-2.6.28.8/drivers/usb/storage/usb.c 2009-02-21 09:37:48.000000000 -0500
16169 +@@ -139,7 +139,7 @@ static struct usb_device_id storage_usb_
16170 + #undef COMPLIANT_DEV
16171 + #undef USUAL_DEV
16172 + /* Terminating entry */
16173 +- { }
16174 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
16175 + };
16176 +
16177 + MODULE_DEVICE_TABLE (usb, storage_usb_ids);
16178 +@@ -182,7 +182,7 @@ static struct us_unusual_dev us_unusual_
16179 + # undef USUAL_DEV
16180 +
16181 + /* Terminating entry */
16182 +- { NULL }
16183 ++ { NULL, NULL, 0, 0, NULL }
16184 + };
16185 +
16186 +
16187 +diff -urNp linux-2.6.28.8/drivers/uwb/wlp/messages.c linux-2.6.28.8/drivers/uwb/wlp/messages.c
16188 +--- linux-2.6.28.8/drivers/uwb/wlp/messages.c 2009-02-06 16:47:45.000000000 -0500
16189 ++++ linux-2.6.28.8/drivers/uwb/wlp/messages.c 2009-02-21 09:37:48.000000000 -0500
16190 +@@ -988,7 +988,7 @@ int wlp_parse_f0(struct wlp *wlp, struct
16191 + size_t len = skb->len;
16192 + size_t used;
16193 + ssize_t result;
16194 +- struct wlp_nonce enonce, rnonce;
16195 ++ struct wlp_nonce enonce = {{0}}, rnonce = {{0}};
16196 + enum wlp_assc_error assc_err;
16197 + char enonce_buf[WLP_WSS_NONCE_STRSIZE];
16198 + char rnonce_buf[WLP_WSS_NONCE_STRSIZE];
16199 +diff -urNp linux-2.6.28.8/drivers/video/fbcmap.c linux-2.6.28.8/drivers/video/fbcmap.c
16200 +--- linux-2.6.28.8/drivers/video/fbcmap.c 2009-02-06 16:47:45.000000000 -0500
16201 ++++ linux-2.6.28.8/drivers/video/fbcmap.c 2009-02-21 09:37:48.000000000 -0500
16202 +@@ -250,8 +250,7 @@ int fb_set_user_cmap(struct fb_cmap_user
16203 + int rc, size = cmap->len * sizeof(u16);
16204 + struct fb_cmap umap;
16205 +
16206 +- if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
16207 +- !info->fbops->fb_setcmap))
16208 ++ if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)
16209 + return -EINVAL;
16210 +
16211 + memset(&umap, 0, sizeof(struct fb_cmap));
16212 +diff -urNp linux-2.6.28.8/drivers/video/fbmem.c linux-2.6.28.8/drivers/video/fbmem.c
16213 +--- linux-2.6.28.8/drivers/video/fbmem.c 2009-02-06 16:47:45.000000000 -0500
16214 ++++ linux-2.6.28.8/drivers/video/fbmem.c 2009-02-21 09:37:48.000000000 -0500
16215 +@@ -393,7 +393,7 @@ static void fb_do_show_logo(struct fb_in
16216 + image->dx += image->width + 8;
16217 + }
16218 + } else if (rotate == FB_ROTATE_UD) {
16219 +- for (x = 0; x < num && image->dx >= 0; x++) {
16220 ++ for (x = 0; x < num && (__s32)image->dx >= 0; x++) {
16221 + info->fbops->fb_imageblit(info, image);
16222 + image->dx -= image->width + 8;
16223 + }
16224 +@@ -405,7 +405,7 @@ static void fb_do_show_logo(struct fb_in
16225 + image->dy += image->height + 8;
16226 + }
16227 + } else if (rotate == FB_ROTATE_CCW) {
16228 +- for (x = 0; x < num && image->dy >= 0; x++) {
16229 ++ for (x = 0; x < num && (__s32)image->dy >= 0; x++) {
16230 + info->fbops->fb_imageblit(info, image);
16231 + image->dy -= image->height + 8;
16232 + }
16233 +@@ -1090,7 +1090,7 @@ static long do_fb_ioctl(struct fb_info *
16234 + ret = -EINVAL;
16235 + break;
16236 + }
16237 +- if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX) {
16238 ++ if (con2fb.framebuffer >= FB_MAX) {
16239 + ret = -EINVAL;
16240 + break;
16241 + }
16242 +diff -urNp linux-2.6.28.8/drivers/video/fbmon.c linux-2.6.28.8/drivers/video/fbmon.c
16243 +--- linux-2.6.28.8/drivers/video/fbmon.c 2009-02-06 16:47:45.000000000 -0500
16244 ++++ linux-2.6.28.8/drivers/video/fbmon.c 2009-02-21 09:37:48.000000000 -0500
16245 +@@ -45,7 +45,7 @@
16246 + #ifdef DEBUG
16247 + #define DPRINTK(fmt, args...) printk(fmt,## args)
16248 + #else
16249 +-#define DPRINTK(fmt, args...)
16250 ++#define DPRINTK(fmt, args...) do {} while (0)
16251 + #endif
16252 +
16253 + #define FBMON_FIX_HEADER 1
16254 +diff -urNp linux-2.6.28.8/drivers/video/i810/i810_accel.c linux-2.6.28.8/drivers/video/i810/i810_accel.c
16255 +--- linux-2.6.28.8/drivers/video/i810/i810_accel.c 2009-02-06 16:47:45.000000000 -0500
16256 ++++ linux-2.6.28.8/drivers/video/i810/i810_accel.c 2009-02-21 09:37:48.000000000 -0500
16257 +@@ -73,6 +73,7 @@ static inline int wait_for_space(struct
16258 + }
16259 + }
16260 + printk("ringbuffer lockup!!!\n");
16261 ++ printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
16262 + i810_report_error(mmio);
16263 + par->dev_flags |= LOCKUP;
16264 + info->pixmap.scan_align = 1;
16265 +diff -urNp linux-2.6.28.8/drivers/video/i810/i810_main.c linux-2.6.28.8/drivers/video/i810/i810_main.c
16266 +--- linux-2.6.28.8/drivers/video/i810/i810_main.c 2009-02-06 16:47:45.000000000 -0500
16267 ++++ linux-2.6.28.8/drivers/video/i810/i810_main.c 2009-03-07 14:10:58.000000000 -0500
16268 +@@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t
16269 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
16270 + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,
16271 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
16272 +- { 0 },
16273 ++ { 0, 0, 0, 0, 0, 0, 0 },
16274 + };
16275 +
16276 + static struct pci_driver i810fb_driver = {
16277 +diff -urNp linux-2.6.28.8/drivers/video/modedb.c linux-2.6.28.8/drivers/video/modedb.c
16278 +--- linux-2.6.28.8/drivers/video/modedb.c 2009-02-06 16:47:45.000000000 -0500
16279 ++++ linux-2.6.28.8/drivers/video/modedb.c 2009-02-21 09:37:48.000000000 -0500
16280 +@@ -38,232 +38,232 @@ static const struct fb_videomode modedb[
16281 + {
16282 + /* 640x400 @ 70 Hz, 31.5 kHz hsync */
16283 + NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
16284 +- 0, FB_VMODE_NONINTERLACED
16285 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16286 + }, {
16287 + /* 640x480 @ 60 Hz, 31.5 kHz hsync */
16288 + NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
16289 +- 0, FB_VMODE_NONINTERLACED
16290 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16291 + }, {
16292 + /* 800x600 @ 56 Hz, 35.15 kHz hsync */
16293 + NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
16294 +- 0, FB_VMODE_NONINTERLACED
16295 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16296 + }, {
16297 + /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
16298 + NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
16299 +- 0, FB_VMODE_INTERLACED
16300 ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
16301 + }, {
16302 + /* 640x400 @ 85 Hz, 37.86 kHz hsync */
16303 + NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
16304 +- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16305 ++ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16306 + }, {
16307 + /* 640x480 @ 72 Hz, 36.5 kHz hsync */
16308 + NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
16309 +- 0, FB_VMODE_NONINTERLACED
16310 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16311 + }, {
16312 + /* 640x480 @ 75 Hz, 37.50 kHz hsync */
16313 + NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
16314 +- 0, FB_VMODE_NONINTERLACED
16315 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16316 + }, {
16317 + /* 800x600 @ 60 Hz, 37.8 kHz hsync */
16318 + NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
16319 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16320 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16321 + }, {
16322 + /* 640x480 @ 85 Hz, 43.27 kHz hsync */
16323 + NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
16324 +- 0, FB_VMODE_NONINTERLACED
16325 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16326 + }, {
16327 + /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
16328 + NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
16329 +- 0, FB_VMODE_INTERLACED
16330 ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
16331 + }, {
16332 + /* 800x600 @ 72 Hz, 48.0 kHz hsync */
16333 + NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
16334 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16335 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16336 + }, {
16337 + /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
16338 + NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
16339 +- 0, FB_VMODE_NONINTERLACED
16340 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16341 + }, {
16342 + /* 640x480 @ 100 Hz, 53.01 kHz hsync */
16343 + NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
16344 +- 0, FB_VMODE_NONINTERLACED
16345 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16346 + }, {
16347 + /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
16348 + NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
16349 +- 0, FB_VMODE_NONINTERLACED
16350 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16351 + }, {
16352 + /* 800x600 @ 85 Hz, 55.84 kHz hsync */
16353 + NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
16354 +- 0, FB_VMODE_NONINTERLACED
16355 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16356 + }, {
16357 + /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
16358 + NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
16359 +- 0, FB_VMODE_NONINTERLACED
16360 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16361 + }, {
16362 + /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
16363 + NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
16364 +- 0, FB_VMODE_INTERLACED
16365 ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
16366 + }, {
16367 + /* 800x600 @ 100 Hz, 64.02 kHz hsync */
16368 + NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
16369 +- 0, FB_VMODE_NONINTERLACED
16370 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16371 + }, {
16372 + /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
16373 + NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
16374 +- 0, FB_VMODE_NONINTERLACED
16375 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16376 + }, {
16377 + /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
16378 + NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
16379 +- 0, FB_VMODE_NONINTERLACED
16380 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16381 + }, {
16382 + /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
16383 + NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
16384 +- 0, FB_VMODE_NONINTERLACED
16385 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16386 + }, {
16387 + /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
16388 + NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
16389 +- 0, FB_VMODE_NONINTERLACED
16390 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16391 + }, {
16392 + /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
16393 + NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13,
16394 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16395 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16396 + }, {
16397 + /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
16398 + NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
16399 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16400 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16401 + }, {
16402 + /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
16403 + NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
16404 +- 0, FB_VMODE_NONINTERLACED
16405 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16406 + }, {
16407 + /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
16408 + NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
16409 +- 0, FB_VMODE_NONINTERLACED
16410 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16411 + }, {
16412 + /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
16413 + NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
16414 +- 0, FB_VMODE_NONINTERLACED
16415 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16416 + }, {
16417 + /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
16418 + NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
16419 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16420 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16421 + }, {
16422 + /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
16423 + NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
16424 +- 0, FB_VMODE_NONINTERLACED
16425 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16426 + }, {
16427 + /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
16428 + NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
16429 +- 0, FB_VMODE_NONINTERLACED
16430 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16431 + }, {
16432 + /* 1024x768 @ 100Hz, 80.21 kHz hsync */
16433 + NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
16434 +- 0, FB_VMODE_NONINTERLACED
16435 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16436 + }, {
16437 + /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
16438 + NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
16439 +- 0, FB_VMODE_NONINTERLACED
16440 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16441 + }, {
16442 + /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
16443 + NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
16444 +- 0, FB_VMODE_NONINTERLACED
16445 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16446 + }, {
16447 + /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
16448 + NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
16449 +- 0, FB_VMODE_NONINTERLACED
16450 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16451 + }, {
16452 + /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
16453 + NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
16454 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16455 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16456 + }, {
16457 + /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
16458 + NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
16459 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16460 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16461 + }, {
16462 + /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
16463 + NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
16464 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16465 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16466 + }, {
16467 + /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
16468 + NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
16469 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16470 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16471 + }, {
16472 + /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
16473 + NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
16474 +- 0, FB_VMODE_NONINTERLACED
16475 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16476 + }, {
16477 + /* 1800x1440 @ 64Hz, 96.15 kHz hsync */
16478 + NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
16479 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16480 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16481 + }, {
16482 + /* 1800x1440 @ 70Hz, 104.52 kHz hsync */
16483 + NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
16484 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16485 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16486 + }, {
16487 + /* 512x384 @ 78 Hz, 31.50 kHz hsync */
16488 + NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
16489 +- 0, FB_VMODE_NONINTERLACED
16490 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16491 + }, {
16492 + /* 512x384 @ 85 Hz, 34.38 kHz hsync */
16493 + NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
16494 +- 0, FB_VMODE_NONINTERLACED
16495 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16496 + }, {
16497 + /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
16498 + NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
16499 +- 0, FB_VMODE_DOUBLE
16500 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16501 + }, {
16502 + /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
16503 + NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
16504 +- 0, FB_VMODE_DOUBLE
16505 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16506 + }, {
16507 + /* 320x240 @ 72 Hz, 36.5 kHz hsync */
16508 + NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
16509 +- 0, FB_VMODE_DOUBLE
16510 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16511 + }, {
16512 + /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
16513 + NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
16514 +- 0, FB_VMODE_DOUBLE
16515 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16516 + }, {
16517 + /* 400x300 @ 60 Hz, 37.8 kHz hsync */
16518 + NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
16519 +- 0, FB_VMODE_DOUBLE
16520 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16521 + }, {
16522 + /* 400x300 @ 72 Hz, 48.0 kHz hsync */
16523 + NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
16524 +- 0, FB_VMODE_DOUBLE
16525 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16526 + }, {
16527 + /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
16528 + NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
16529 +- 0, FB_VMODE_DOUBLE
16530 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16531 + }, {
16532 + /* 480x300 @ 60 Hz, 37.8 kHz hsync */
16533 + NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
16534 +- 0, FB_VMODE_DOUBLE
16535 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16536 + }, {
16537 + /* 480x300 @ 63 Hz, 39.6 kHz hsync */
16538 + NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
16539 +- 0, FB_VMODE_DOUBLE
16540 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16541 + }, {
16542 + /* 480x300 @ 72 Hz, 48.0 kHz hsync */
16543 + NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
16544 +- 0, FB_VMODE_DOUBLE
16545 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16546 + }, {
16547 + /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
16548 + NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
16549 + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
16550 +- FB_VMODE_NONINTERLACED
16551 ++ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16552 + }, {
16553 + /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
16554 + NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6,
16555 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16556 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16557 + }, {
16558 + /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
16559 + NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
16560 +- 0, FB_VMODE_NONINTERLACED
16561 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16562 + }, {
16563 + /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */
16564 + NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3,
16565 +- 0, FB_VMODE_NONINTERLACED
16566 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16567 + },
16568 + };
16569 +
16570 +diff -urNp linux-2.6.28.8/drivers/video/uvesafb.c linux-2.6.28.8/drivers/video/uvesafb.c
16571 +--- linux-2.6.28.8/drivers/video/uvesafb.c 2009-02-06 16:47:45.000000000 -0500
16572 ++++ linux-2.6.28.8/drivers/video/uvesafb.c 2009-02-21 09:37:48.000000000 -0500
16573 +@@ -18,6 +18,7 @@
16574 + #include <linux/fb.h>
16575 + #include <linux/io.h>
16576 + #include <linux/mutex.h>
16577 ++#include <linux/moduleloader.h>
16578 + #include <video/edid.h>
16579 + #include <video/uvesafb.h>
16580 + #ifdef CONFIG_X86
16581 +@@ -117,7 +118,7 @@ static int uvesafb_helper_start(void)
16582 + NULL,
16583 + };
16584 +
16585 +- return call_usermodehelper(v86d_path, argv, envp, 1);
16586 ++ return call_usermodehelper(v86d_path, argv, envp, UMH_WAIT_PROC);
16587 + }
16588 +
16589 + /*
16590 +@@ -574,10 +575,34 @@ static int __devinit uvesafb_vbe_getpmi(
16591 + if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000) {
16592 + par->pmi_setpal = par->ypan = 0;
16593 + } else {
16594 ++
16595 ++#ifdef CONFIG_PAX_KERNEXEC
16596 ++#ifdef CONFIG_MODULES
16597 ++ unsigned long cr0;
16598 ++
16599 ++ par->pmi_code = module_alloc_exec((u16)task->t.regs.ecx);
16600 ++#endif
16601 ++ if (!par->pmi_code) {
16602 ++ par->pmi_setpal = par->ypan = 0;
16603 ++ return 0;
16604 ++ }
16605 ++#endif
16606 ++
16607 + par->pmi_base = (u16 *)phys_to_virt(((u32)task->t.regs.es << 4)
16608 + + task->t.regs.edi);
16609 ++
16610 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16611 ++ pax_open_kernel(cr0);
16612 ++ memcpy(par->pmi_code, par->pmi_base, (u16)task->t.regs.ecx);
16613 ++ pax_close_kernel(cr0);
16614 ++
16615 ++ par->pmi_start = ktva_ktla(par->pmi_code + par->pmi_base[1]);
16616 ++ par->pmi_pal = ktva_ktla(par->pmi_code + par->pmi_base[2]);
16617 ++#else
16618 + par->pmi_start = (u8 *)par->pmi_base + par->pmi_base[1];
16619 + par->pmi_pal = (u8 *)par->pmi_base + par->pmi_base[2];
16620 ++#endif
16621 ++
16622 + printk(KERN_INFO "uvesafb: protected mode interface info at "
16623 + "%04x:%04x\n",
16624 + (u16)task->t.regs.es, (u16)task->t.regs.edi);
16625 +@@ -1832,6 +1857,11 @@ out:
16626 + if (par->vbe_modes)
16627 + kfree(par->vbe_modes);
16628 +
16629 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16630 ++ if (par->pmi_code)
16631 ++ module_free_exec(NULL, par->pmi_code);
16632 ++#endif
16633 ++
16634 + framebuffer_release(info);
16635 + return err;
16636 + }
16637 +@@ -1858,6 +1888,12 @@ static int uvesafb_remove(struct platfor
16638 + kfree(par->vbe_state_orig);
16639 + if (par->vbe_state_saved)
16640 + kfree(par->vbe_state_saved);
16641 ++
16642 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16643 ++ if (par->pmi_code)
16644 ++ module_free_exec(NULL, par->pmi_code);
16645 ++#endif
16646 ++
16647 + }
16648 +
16649 + framebuffer_release(info);
16650 +diff -urNp linux-2.6.28.8/drivers/video/vesafb.c linux-2.6.28.8/drivers/video/vesafb.c
16651 +--- linux-2.6.28.8/drivers/video/vesafb.c 2009-02-06 16:47:45.000000000 -0500
16652 ++++ linux-2.6.28.8/drivers/video/vesafb.c 2009-02-21 09:37:48.000000000 -0500
16653 +@@ -9,6 +9,7 @@
16654 + */
16655 +
16656 + #include <linux/module.h>
16657 ++#include <linux/moduleloader.h>
16658 + #include <linux/kernel.h>
16659 + #include <linux/errno.h>
16660 + #include <linux/string.h>
16661 +@@ -53,8 +54,8 @@ static int vram_remap __initdata; /*
16662 + static int vram_total __initdata; /* Set total amount of memory */
16663 + static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */
16664 + static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */
16665 +-static void (*pmi_start)(void) __read_mostly;
16666 +-static void (*pmi_pal) (void) __read_mostly;
16667 ++static void (*pmi_start)(void) __read_only;
16668 ++static void (*pmi_pal) (void) __read_only;
16669 + static int depth __read_mostly;
16670 + static int vga_compat __read_mostly;
16671 + /* --------------------------------------------------------------------- */
16672 +@@ -224,6 +225,7 @@ static int __init vesafb_probe(struct pl
16673 + unsigned int size_vmode;
16674 + unsigned int size_remap;
16675 + unsigned int size_total;
16676 ++ void *pmi_code = NULL;
16677 +
16678 + if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
16679 + return -ENODEV;
16680 +@@ -266,10 +268,6 @@ static int __init vesafb_probe(struct pl
16681 + size_remap = size_total;
16682 + vesafb_fix.smem_len = size_remap;
16683 +
16684 +-#ifndef __i386__
16685 +- screen_info.vesapm_seg = 0;
16686 +-#endif
16687 +-
16688 + if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
16689 + printk(KERN_WARNING
16690 + "vesafb: cannot reserve video memory at 0x%lx\n",
16691 +@@ -302,9 +300,21 @@ static int __init vesafb_probe(struct pl
16692 + printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
16693 + vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
16694 +
16695 ++#ifdef __i386__
16696 ++
16697 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16698 ++ pmi_code = module_alloc_exec(screen_info.vesapm_size);
16699 ++ if (!pmi_code)
16700 ++#elif !defined(CONFIG_PAX_KERNEXEC)
16701 ++ if (0)
16702 ++#endif
16703 ++
16704 ++#endif
16705 ++ screen_info.vesapm_seg = 0;
16706 ++
16707 + if (screen_info.vesapm_seg) {
16708 +- printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
16709 +- screen_info.vesapm_seg,screen_info.vesapm_off);
16710 ++ printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n",
16711 ++ screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size);
16712 + }
16713 +
16714 + if (screen_info.vesapm_seg < 0xc000)
16715 +@@ -312,9 +322,29 @@ static int __init vesafb_probe(struct pl
16716 +
16717 + if (ypan || pmi_setpal) {
16718 + unsigned short *pmi_base;
16719 +- pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
16720 +- pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
16721 +- pmi_pal = (void*)((char*)pmi_base + pmi_base[2]);
16722 ++
16723 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16724 ++ unsigned long cr0;
16725 ++#endif
16726 ++
16727 ++ pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
16728 ++
16729 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16730 ++ pax_open_kernel(cr0);
16731 ++ memcpy(pmi_code, pmi_base, screen_info.vesapm_size);
16732 ++#else
16733 ++ pmi_code = pmi_base;
16734 ++#endif
16735 ++
16736 ++ pmi_start = (void*)((char*)pmi_code + pmi_base[1]);
16737 ++ pmi_pal = (void*)((char*)pmi_code + pmi_base[2]);
16738 ++
16739 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16740 ++ pmi_start = ktva_ktla(pmi_start);
16741 ++ pmi_pal = ktva_ktla(pmi_pal);
16742 ++ pax_close_kernel(cr0);
16743 ++#endif
16744 ++
16745 + printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
16746 + if (pmi_base[3]) {
16747 + printk(KERN_INFO "vesafb: pmi: ports = ");
16748 +@@ -456,6 +486,11 @@ static int __init vesafb_probe(struct pl
16749 + info->node, info->fix.id);
16750 + return 0;
16751 + err:
16752 ++
16753 ++#if defined(__i386__) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16754 ++ module_free_exec(NULL, pmi_code);
16755 ++#endif
16756 ++
16757 + if (info->screen_base)
16758 + iounmap(info->screen_base);
16759 + framebuffer_release(info);
16760 +diff -urNp linux-2.6.28.8/fs/9p/vfs_inode.c linux-2.6.28.8/fs/9p/vfs_inode.c
16761 +--- linux-2.6.28.8/fs/9p/vfs_inode.c 2009-02-06 16:47:45.000000000 -0500
16762 ++++ linux-2.6.28.8/fs/9p/vfs_inode.c 2009-02-21 09:37:48.000000000 -0500
16763 +@@ -1021,7 +1021,7 @@ static void *v9fs_vfs_follow_link(struct
16764 + static void
16765 + v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
16766 + {
16767 +- char *s = nd_get_link(nd);
16768 ++ const char *s = nd_get_link(nd);
16769 +
16770 + P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name,
16771 + IS_ERR(s) ? "<error>" : s);
16772 +diff -urNp linux-2.6.28.8/fs/aio.c linux-2.6.28.8/fs/aio.c
16773 +--- linux-2.6.28.8/fs/aio.c 2009-02-06 16:47:45.000000000 -0500
16774 ++++ linux-2.6.28.8/fs/aio.c 2009-02-21 09:37:48.000000000 -0500
16775 +@@ -114,7 +114,7 @@ static int aio_setup_ring(struct kioctx
16776 + size += sizeof(struct io_event) * nr_events;
16777 + nr_pages = (size + PAGE_SIZE-1) >> PAGE_SHIFT;
16778 +
16779 +- if (nr_pages < 0)
16780 ++ if (nr_pages <= 0)
16781 + return -EINVAL;
16782 +
16783 + nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) / sizeof(struct io_event);
16784 +diff -urNp linux-2.6.28.8/fs/autofs4/symlink.c linux-2.6.28.8/fs/autofs4/symlink.c
16785 +--- linux-2.6.28.8/fs/autofs4/symlink.c 2009-02-06 16:47:45.000000000 -0500
16786 ++++ linux-2.6.28.8/fs/autofs4/symlink.c 2009-02-21 09:37:48.000000000 -0500
16787 +@@ -15,7 +15,7 @@
16788 + static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
16789 + {
16790 + struct autofs_info *ino = autofs4_dentry_ino(dentry);
16791 +- nd_set_link(nd, (char *)ino->u.symlink);
16792 ++ nd_set_link(nd, ino->u.symlink);
16793 + return NULL;
16794 + }
16795 +
16796 +diff -urNp linux-2.6.28.8/fs/befs/linuxvfs.c linux-2.6.28.8/fs/befs/linuxvfs.c
16797 +--- linux-2.6.28.8/fs/befs/linuxvfs.c 2009-02-06 16:47:45.000000000 -0500
16798 ++++ linux-2.6.28.8/fs/befs/linuxvfs.c 2009-02-21 09:37:48.000000000 -0500
16799 +@@ -490,7 +490,7 @@ static void befs_put_link(struct dentry
16800 + {
16801 + befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
16802 + if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
16803 +- char *link = nd_get_link(nd);
16804 ++ const char *link = nd_get_link(nd);
16805 + if (!IS_ERR(link))
16806 + kfree(link);
16807 + }
16808 +diff -urNp linux-2.6.28.8/fs/binfmt_aout.c linux-2.6.28.8/fs/binfmt_aout.c
16809 +--- linux-2.6.28.8/fs/binfmt_aout.c 2009-02-06 16:47:45.000000000 -0500
16810 ++++ linux-2.6.28.8/fs/binfmt_aout.c 2009-02-21 09:37:48.000000000 -0500
16811 +@@ -16,6 +16,7 @@
16812 + #include <linux/string.h>
16813 + #include <linux/fs.h>
16814 + #include <linux/file.h>
16815 ++#include <linux/security.h>
16816 + #include <linux/stat.h>
16817 + #include <linux/fcntl.h>
16818 + #include <linux/ptrace.h>
16819 +@@ -124,18 +125,22 @@ static int aout_core_dump(long signr, st
16820 + /* If the size of the dump file exceeds the rlimit, then see what would happen
16821 + if we wrote the stack, but not the data area. */
16822 + #ifdef __sparc__
16823 ++ gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize + dump.u_ssize, 1);
16824 + if ((dump.u_dsize + dump.u_ssize) > limit)
16825 + dump.u_dsize = 0;
16826 + #else
16827 ++ gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE, 1);
16828 + if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > limit)
16829 + dump.u_dsize = 0;
16830 + #endif
16831 +
16832 + /* Make sure we have enough room to write the stack and data areas. */
16833 + #ifdef __sparc__
16834 ++ gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
16835 + if (dump.u_ssize > limit)
16836 + dump.u_ssize = 0;
16837 + #else
16838 ++ gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize + 1) * PAGE_SIZE, 1);
16839 + if ((dump.u_ssize + 1) * PAGE_SIZE > limit)
16840 + dump.u_ssize = 0;
16841 + #endif
16842 +@@ -291,6 +296,8 @@ static int load_aout_binary(struct linux
16843 + rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
16844 + if (rlim >= RLIM_INFINITY)
16845 + rlim = ~0;
16846 ++
16847 ++ gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
16848 + if (ex.a_data + ex.a_bss > rlim)
16849 + return -ENOMEM;
16850 +
16851 +@@ -322,6 +329,28 @@ static int load_aout_binary(struct linux
16852 +
16853 + compute_creds(bprm);
16854 + current->flags &= ~PF_FORKNOEXEC;
16855 ++
16856 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
16857 ++ current->mm->pax_flags = 0UL;
16858 ++#endif
16859 ++
16860 ++#ifdef CONFIG_PAX_PAGEEXEC
16861 ++ if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
16862 ++ current->mm->pax_flags |= MF_PAX_PAGEEXEC;
16863 ++
16864 ++#ifdef CONFIG_PAX_EMUTRAMP
16865 ++ if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
16866 ++ current->mm->pax_flags |= MF_PAX_EMUTRAMP;
16867 ++#endif
16868 ++
16869 ++#ifdef CONFIG_PAX_MPROTECT
16870 ++ if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
16871 ++ current->mm->pax_flags |= MF_PAX_MPROTECT;
16872 ++#endif
16873 ++
16874 ++ }
16875 ++#endif
16876 ++
16877 + #ifdef __sparc__
16878 + if (N_MAGIC(ex) == NMAGIC) {
16879 + loff_t pos = fd_offset;
16880 +@@ -413,7 +442,7 @@ static int load_aout_binary(struct linux
16881 +
16882 + down_write(&current->mm->mmap_sem);
16883 + error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
16884 +- PROT_READ | PROT_WRITE | PROT_EXEC,
16885 ++ PROT_READ | PROT_WRITE,
16886 + MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
16887 + fd_offset + ex.a_text);
16888 + up_write(&current->mm->mmap_sem);
16889 +diff -urNp linux-2.6.28.8/fs/binfmt_elf.c linux-2.6.28.8/fs/binfmt_elf.c
16890 +--- linux-2.6.28.8/fs/binfmt_elf.c 2009-02-07 16:10:45.000000000 -0500
16891 ++++ linux-2.6.28.8/fs/binfmt_elf.c 2009-03-07 04:29:14.000000000 -0500
16892 +@@ -42,6 +42,10 @@
16893 + #include <asm/param.h>
16894 + #include <asm/page.h>
16895 +
16896 ++#ifdef CONFIG_PAX_SEGMEXEC
16897 ++#include <asm/desc.h>
16898 ++#endif
16899 ++
16900 + static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
16901 + static int load_elf_library(struct file *);
16902 + static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *,
16903 +@@ -57,6 +61,10 @@ static int elf_core_dump(long signr, str
16904 + #define elf_core_dump NULL
16905 + #endif
16906 +
16907 ++#ifdef CONFIG_PAX_MPROTECT
16908 ++static void elf_handle_mprotect(struct vm_area_struct *vma, unsigned long newflags);
16909 ++#endif
16910 ++
16911 + #if ELF_EXEC_PAGESIZE > PAGE_SIZE
16912 + #define ELF_MIN_ALIGN ELF_EXEC_PAGESIZE
16913 + #else
16914 +@@ -76,6 +84,11 @@ static struct linux_binfmt elf_format =
16915 + .load_binary = load_elf_binary,
16916 + .load_shlib = load_elf_library,
16917 + .core_dump = elf_core_dump,
16918 ++
16919 ++#ifdef CONFIG_PAX_MPROTECT
16920 ++ .handle_mprotect= elf_handle_mprotect,
16921 ++#endif
16922 ++
16923 + .min_coredump = ELF_EXEC_PAGESIZE,
16924 + .hasvdso = 1
16925 + };
16926 +@@ -84,6 +97,8 @@ static struct linux_binfmt elf_format =
16927 +
16928 + static int set_brk(unsigned long start, unsigned long end)
16929 + {
16930 ++ unsigned long e = end;
16931 ++
16932 + start = ELF_PAGEALIGN(start);
16933 + end = ELF_PAGEALIGN(end);
16934 + if (end > start) {
16935 +@@ -94,7 +109,7 @@ static int set_brk(unsigned long start,
16936 + if (BAD_ADDR(addr))
16937 + return addr;
16938 + }
16939 +- current->mm->start_brk = current->mm->brk = end;
16940 ++ current->mm->start_brk = current->mm->brk = e;
16941 + return 0;
16942 + }
16943 +
16944 +@@ -380,10 +395,10 @@ static unsigned long load_elf_interp(str
16945 + {
16946 + struct elf_phdr *elf_phdata;
16947 + struct elf_phdr *eppnt;
16948 +- unsigned long load_addr = 0;
16949 ++ unsigned long load_addr = 0, pax_task_size = TASK_SIZE;
16950 + int load_addr_set = 0;
16951 + unsigned long last_bss = 0, elf_bss = 0;
16952 +- unsigned long error = ~0UL;
16953 ++ unsigned long error = -EINVAL;
16954 + unsigned long total_size;
16955 + int retval, i, size;
16956 +
16957 +@@ -429,6 +444,11 @@ static unsigned long load_elf_interp(str
16958 + goto out_close;
16959 + }
16960 +
16961 ++#ifdef CONFIG_PAX_SEGMEXEC
16962 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
16963 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
16964 ++#endif
16965 ++
16966 + eppnt = elf_phdata;
16967 + for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
16968 + if (eppnt->p_type == PT_LOAD) {
16969 +@@ -472,8 +492,8 @@ static unsigned long load_elf_interp(str
16970 + k = load_addr + eppnt->p_vaddr;
16971 + if (BAD_ADDR(k) ||
16972 + eppnt->p_filesz > eppnt->p_memsz ||
16973 +- eppnt->p_memsz > TASK_SIZE ||
16974 +- TASK_SIZE - eppnt->p_memsz < k) {
16975 ++ eppnt->p_memsz > pax_task_size ||
16976 ++ pax_task_size - eppnt->p_memsz < k) {
16977 + error = -ENOMEM;
16978 + goto out_close;
16979 + }
16980 +@@ -527,6 +547,177 @@ out:
16981 + return error;
16982 + }
16983 +
16984 ++#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
16985 ++static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
16986 ++{
16987 ++ unsigned long pax_flags = 0UL;
16988 ++
16989 ++#ifdef CONFIG_PAX_PAGEEXEC
16990 ++ if (elf_phdata->p_flags & PF_PAGEEXEC)
16991 ++ pax_flags |= MF_PAX_PAGEEXEC;
16992 ++#endif
16993 ++
16994 ++#ifdef CONFIG_PAX_SEGMEXEC
16995 ++ if (elf_phdata->p_flags & PF_SEGMEXEC)
16996 ++ pax_flags |= MF_PAX_SEGMEXEC;
16997 ++#endif
16998 ++
16999 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
17000 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
17001 ++ if (nx_enabled)
17002 ++ pax_flags &= ~MF_PAX_SEGMEXEC;
17003 ++ else
17004 ++ pax_flags &= ~MF_PAX_PAGEEXEC;
17005 ++ }
17006 ++#endif
17007 ++
17008 ++#ifdef CONFIG_PAX_EMUTRAMP
17009 ++ if (elf_phdata->p_flags & PF_EMUTRAMP)
17010 ++ pax_flags |= MF_PAX_EMUTRAMP;
17011 ++#endif
17012 ++
17013 ++#ifdef CONFIG_PAX_MPROTECT
17014 ++ if (elf_phdata->p_flags & PF_MPROTECT)
17015 ++ pax_flags |= MF_PAX_MPROTECT;
17016 ++#endif
17017 ++
17018 ++#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
17019 ++ if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
17020 ++ pax_flags |= MF_PAX_RANDMMAP;
17021 ++#endif
17022 ++
17023 ++ return pax_flags;
17024 ++}
17025 ++#endif
17026 ++
17027 ++#ifdef CONFIG_PAX_PT_PAX_FLAGS
17028 ++static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
17029 ++{
17030 ++ unsigned long pax_flags = 0UL;
17031 ++
17032 ++#ifdef CONFIG_PAX_PAGEEXEC
17033 ++ if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
17034 ++ pax_flags |= MF_PAX_PAGEEXEC;
17035 ++#endif
17036 ++
17037 ++#ifdef CONFIG_PAX_SEGMEXEC
17038 ++ if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
17039 ++ pax_flags |= MF_PAX_SEGMEXEC;
17040 ++#endif
17041 ++
17042 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
17043 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
17044 ++ if (nx_enabled)
17045 ++ pax_flags &= ~MF_PAX_SEGMEXEC;
17046 ++ else
17047 ++ pax_flags &= ~MF_PAX_PAGEEXEC;
17048 ++ }
17049 ++#endif
17050 ++
17051 ++#ifdef CONFIG_PAX_EMUTRAMP
17052 ++ if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
17053 ++ pax_flags |= MF_PAX_EMUTRAMP;
17054 ++#endif
17055 ++
17056 ++#ifdef CONFIG_PAX_MPROTECT
17057 ++ if (!(elf_phdata->p_flags & PF_NOMPROTECT))
17058 ++ pax_flags |= MF_PAX_MPROTECT;
17059 ++#endif
17060 ++
17061 ++#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
17062 ++ if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
17063 ++ pax_flags |= MF_PAX_RANDMMAP;
17064 ++#endif
17065 ++
17066 ++ return pax_flags;
17067 ++}
17068 ++#endif
17069 ++
17070 ++#ifdef CONFIG_PAX_EI_PAX
17071 ++static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
17072 ++{
17073 ++ unsigned long pax_flags = 0UL;
17074 ++
17075 ++#ifdef CONFIG_PAX_PAGEEXEC
17076 ++ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
17077 ++ pax_flags |= MF_PAX_PAGEEXEC;
17078 ++#endif
17079 ++
17080 ++#ifdef CONFIG_PAX_SEGMEXEC
17081 ++ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
17082 ++ pax_flags |= MF_PAX_SEGMEXEC;
17083 ++#endif
17084 ++
17085 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
17086 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
17087 ++ if (nx_enabled)
17088 ++ pax_flags &= ~MF_PAX_SEGMEXEC;
17089 ++ else
17090 ++ pax_flags &= ~MF_PAX_PAGEEXEC;
17091 ++ }
17092 ++#endif
17093 ++
17094 ++#ifdef CONFIG_PAX_EMUTRAMP
17095 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
17096 ++ pax_flags |= MF_PAX_EMUTRAMP;
17097 ++#endif
17098 ++
17099 ++#ifdef CONFIG_PAX_MPROTECT
17100 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
17101 ++ pax_flags |= MF_PAX_MPROTECT;
17102 ++#endif
17103 ++
17104 ++#ifdef CONFIG_PAX_ASLR
17105 ++ if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
17106 ++ pax_flags |= MF_PAX_RANDMMAP;
17107 ++#endif
17108 ++
17109 ++ return pax_flags;
17110 ++}
17111 ++#endif
17112 ++
17113 ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
17114 ++static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
17115 ++{
17116 ++ unsigned long pax_flags = 0UL;
17117 ++
17118 ++#ifdef CONFIG_PAX_PT_PAX_FLAGS
17119 ++ unsigned long i;
17120 ++#endif
17121 ++
17122 ++#ifdef CONFIG_PAX_EI_PAX
17123 ++ pax_flags = pax_parse_ei_pax(elf_ex);
17124 ++#endif
17125 ++
17126 ++#ifdef CONFIG_PAX_PT_PAX_FLAGS
17127 ++ for (i = 0UL; i < elf_ex->e_phnum; i++)
17128 ++ if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
17129 ++ if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
17130 ++ ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
17131 ++ ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
17132 ++ ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
17133 ++ ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
17134 ++ return -EINVAL;
17135 ++
17136 ++#ifdef CONFIG_PAX_SOFTMODE
17137 ++ if (pax_softmode)
17138 ++ pax_flags = pax_parse_softmode(&elf_phdata[i]);
17139 ++ else
17140 ++#endif
17141 ++
17142 ++ pax_flags = pax_parse_hardmode(&elf_phdata[i]);
17143 ++ break;
17144 ++ }
17145 ++#endif
17146 ++
17147 ++ if (0 > pax_check_flags(&pax_flags))
17148 ++ return -EINVAL;
17149 ++
17150 ++ current->mm->pax_flags = pax_flags;
17151 ++ return 0;
17152 ++}
17153 ++#endif
17154 ++
17155 + /*
17156 + * These are the functions used to load ELF style executables and shared
17157 + * libraries. There is no binary dependent code anywhere else.
17158 +@@ -543,6 +734,11 @@ static unsigned long randomize_stack_top
17159 + {
17160 + unsigned int random_variable = 0;
17161 +
17162 ++#ifdef CONFIG_PAX_RANDUSTACK
17163 ++ if (randomize_va_space)
17164 ++ return stack_top - current->mm->delta_stack;
17165 ++#endif
17166 ++
17167 + if ((current->flags & PF_RANDOMIZE) &&
17168 + !(current->personality & ADDR_NO_RANDOMIZE)) {
17169 + random_variable = get_random_int() & STACK_RND_MASK;
17170 +@@ -561,7 +757,7 @@ static int load_elf_binary(struct linux_
17171 + unsigned long load_addr = 0, load_bias = 0;
17172 + int load_addr_set = 0;
17173 + char * elf_interpreter = NULL;
17174 +- unsigned long error;
17175 ++ unsigned long error = 0;
17176 + struct elf_phdr *elf_ppnt, *elf_phdata;
17177 + unsigned long elf_bss, elf_brk;
17178 + int elf_exec_fileno;
17179 +@@ -572,11 +768,11 @@ static int load_elf_binary(struct linux_
17180 + unsigned long start_code, end_code, start_data, end_data;
17181 + unsigned long reloc_func_desc = 0;
17182 + int executable_stack = EXSTACK_DEFAULT;
17183 +- unsigned long def_flags = 0;
17184 + struct {
17185 + struct elfhdr elf_ex;
17186 + struct elfhdr interp_elf_ex;
17187 + } *loc;
17188 ++ unsigned long pax_task_size = TASK_SIZE;
17189 +
17190 + loc = kmalloc(sizeof(*loc), GFP_KERNEL);
17191 + if (!loc) {
17192 +@@ -744,11 +940,80 @@ static int load_elf_binary(struct linux_
17193 +
17194 + /* OK, This is the point of no return */
17195 + current->flags &= ~PF_FORKNOEXEC;
17196 +- current->mm->def_flags = def_flags;
17197 ++
17198 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
17199 ++ current->mm->pax_flags = 0UL;
17200 ++#endif
17201 ++
17202 ++#ifdef CONFIG_PAX_DLRESOLVE
17203 ++ current->mm->call_dl_resolve = 0UL;
17204 ++#endif
17205 ++
17206 ++#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
17207 ++ current->mm->call_syscall = 0UL;
17208 ++#endif
17209 ++
17210 ++#ifdef CONFIG_PAX_ASLR
17211 ++ current->mm->delta_mmap = 0UL;
17212 ++ current->mm->delta_stack = 0UL;
17213 ++#endif
17214 ++
17215 ++ current->mm->def_flags = 0;
17216 ++
17217 ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
17218 ++ if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
17219 ++ send_sig(SIGKILL, current, 0);
17220 ++ goto out_free_dentry;
17221 ++ }
17222 ++#endif
17223 ++
17224 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
17225 ++ pax_set_initial_flags(bprm);
17226 ++#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
17227 ++ if (pax_set_initial_flags_func)
17228 ++ (pax_set_initial_flags_func)(bprm);
17229 ++#endif
17230 ++
17231 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
17232 ++ if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !nx_enabled) {
17233 ++ current->mm->context.user_cs_limit = PAGE_SIZE;
17234 ++ current->mm->def_flags |= VM_PAGEEXEC;
17235 ++ }
17236 ++#endif
17237 ++
17238 ++#ifdef CONFIG_PAX_SEGMEXEC
17239 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
17240 ++ current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
17241 ++ current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE;
17242 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
17243 ++ }
17244 ++#endif
17245 ++
17246 ++#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
17247 ++ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
17248 ++ set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
17249 ++ put_cpu_no_resched();
17250 ++ }
17251 ++#endif
17252 ++
17253 ++#ifdef CONFIG_PAX_ASLR
17254 ++ if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
17255 ++ current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT;
17256 ++ current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT;
17257 ++ }
17258 ++#endif
17259 +
17260 + /* Do this immediately, since STACK_TOP as used in setup_arg_pages
17261 + may depend on the personality. */
17262 + SET_PERSONALITY(loc->elf_ex);
17263 ++
17264 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
17265 ++ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
17266 ++ executable_stack = EXSTACK_DISABLE_X;
17267 ++ current->personality &= ~READ_IMPLIES_EXEC;
17268 ++ } else
17269 ++#endif
17270 ++
17271 + if (elf_read_implies_exec(loc->elf_ex, executable_stack))
17272 + current->personality |= READ_IMPLIES_EXEC;
17273 +
17274 +@@ -829,6 +1094,20 @@ static int load_elf_binary(struct linux_
17275 + #else
17276 + load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
17277 + #endif
17278 ++
17279 ++#ifdef CONFIG_PAX_RANDMMAP
17280 ++ /* PaX: randomize base address at the default exe base if requested */
17281 ++ if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) {
17282 ++#ifdef CONFIG_SPARC64
17283 ++ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1);
17284 ++#else
17285 ++ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT;
17286 ++#endif
17287 ++ load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias);
17288 ++ elf_flags |= MAP_FIXED;
17289 ++ }
17290 ++#endif
17291 ++
17292 + }
17293 +
17294 + error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
17295 +@@ -861,9 +1140,9 @@ static int load_elf_binary(struct linux_
17296 + * allowed task size. Note that p_filesz must always be
17297 + * <= p_memsz so it is only necessary to check p_memsz.
17298 + */
17299 +- if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
17300 +- elf_ppnt->p_memsz > TASK_SIZE ||
17301 +- TASK_SIZE - elf_ppnt->p_memsz < k) {
17302 ++ if (k >= pax_task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
17303 ++ elf_ppnt->p_memsz > pax_task_size ||
17304 ++ pax_task_size - elf_ppnt->p_memsz < k) {
17305 + /* set_brk can never work. Avoid overflows. */
17306 + send_sig(SIGKILL, current, 0);
17307 + retval = -EINVAL;
17308 +@@ -891,6 +1170,11 @@ static int load_elf_binary(struct linux_
17309 + start_data += load_bias;
17310 + end_data += load_bias;
17311 +
17312 ++#ifdef CONFIG_PAX_RANDMMAP
17313 ++ if (current->mm->pax_flags & MF_PAX_RANDMMAP)
17314 ++ elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4);
17315 ++#endif
17316 ++
17317 + /* Calling set_brk effectively mmaps the pages that we need
17318 + * for the bss and break sections. We must do this before
17319 + * mapping in the interpreter, to make sure it doesn't wind
17320 +@@ -902,9 +1186,11 @@ static int load_elf_binary(struct linux_
17321 + goto out_free_dentry;
17322 + }
17323 + if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
17324 +- send_sig(SIGSEGV, current, 0);
17325 +- retval = -EFAULT; /* Nobody gets to see this, but.. */
17326 +- goto out_free_dentry;
17327 ++ /*
17328 ++ * This bss-zeroing can fail if the ELF
17329 ++ * file specifies odd protections. So
17330 ++ * we don't check the return value
17331 ++ */
17332 + }
17333 +
17334 + if (elf_interpreter) {
17335 +@@ -1141,8 +1427,10 @@ static int dump_seek(struct file *file,
17336 + unsigned long n = off;
17337 + if (n > PAGE_SIZE)
17338 + n = PAGE_SIZE;
17339 +- if (!dump_write(file, buf, n))
17340 ++ if (!dump_write(file, buf, n)) {
17341 ++ free_page((unsigned long)buf);
17342 + return 0;
17343 ++ }
17344 + off -= n;
17345 + }
17346 + free_page((unsigned long)buf);
17347 +@@ -1154,7 +1442,7 @@ static int dump_seek(struct file *file,
17348 + * Decide what to dump of a segment, part, all or none.
17349 + */
17350 + static unsigned long vma_dump_size(struct vm_area_struct *vma,
17351 +- unsigned long mm_flags)
17352 ++ unsigned long mm_flags, long signr)
17353 + {
17354 + #define FILTER(type) (mm_flags & (1UL << MMF_DUMP_##type))
17355 +
17356 +@@ -1188,7 +1476,7 @@ static unsigned long vma_dump_size(struc
17357 + if (vma->vm_file == NULL)
17358 + return 0;
17359 +
17360 +- if (FILTER(MAPPED_PRIVATE))
17361 ++ if (signr == SIGKILL || FILTER(MAPPED_PRIVATE))
17362 + goto whole;
17363 +
17364 + /*
17365 +@@ -1284,8 +1572,11 @@ static int writenote(struct memelfnote *
17366 + #undef DUMP_WRITE
17367 +
17368 + #define DUMP_WRITE(addr, nr) \
17369 ++ do { \
17370 ++ gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
17371 + if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
17372 +- goto end_coredump;
17373 ++ goto end_coredump; \
17374 ++ } while (0);
17375 + #define DUMP_SEEK(off) \
17376 + if (!dump_seek(file, (off))) \
17377 + goto end_coredump;
17378 +@@ -1986,7 +2277,7 @@ static int elf_core_dump(long signr, str
17379 + phdr.p_offset = offset;
17380 + phdr.p_vaddr = vma->vm_start;
17381 + phdr.p_paddr = 0;
17382 +- phdr.p_filesz = vma_dump_size(vma, mm_flags);
17383 ++ phdr.p_filesz = vma_dump_size(vma, mm_flags, signr);
17384 + phdr.p_memsz = vma->vm_end - vma->vm_start;
17385 + offset += phdr.p_filesz;
17386 + phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
17387 +@@ -2018,7 +2309,7 @@ static int elf_core_dump(long signr, str
17388 + unsigned long addr;
17389 + unsigned long end;
17390 +
17391 +- end = vma->vm_start + vma_dump_size(vma, mm_flags);
17392 ++ end = vma->vm_start + vma_dump_size(vma, mm_flags, signr);
17393 +
17394 + for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
17395 + struct page *page;
17396 +@@ -2038,6 +2329,7 @@ static int elf_core_dump(long signr, str
17397 + flush_cache_page(tmp_vma, addr,
17398 + page_to_pfn(page));
17399 + kaddr = kmap(page);
17400 ++ gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
17401 + if ((size += PAGE_SIZE) > limit ||
17402 + !dump_write(file, kaddr,
17403 + PAGE_SIZE)) {
17404 +@@ -2068,6 +2360,99 @@ out:
17405 +
17406 + #endif /* USE_ELF_CORE_DUMP */
17407 +
17408 ++#ifdef CONFIG_PAX_MPROTECT
17409 ++/* PaX: non-PIC ELF libraries need relocations on their executable segments
17410 ++ * therefore we'll grant them VM_MAYWRITE once during their life. Similarly
17411 ++ * we'll remove VM_MAYWRITE for good on RELRO segments.
17412 ++ *
17413 ++ * The checks favour ld-linux.so behaviour which operates on a per ELF segment
17414 ++ * basis because we want to allow the common case and not the special ones.
17415 ++ */
17416 ++static void elf_handle_mprotect(struct vm_area_struct *vma, unsigned long newflags)
17417 ++{
17418 ++ struct elfhdr elf_h;
17419 ++ struct elf_phdr elf_p;
17420 ++ unsigned long i;
17421 ++ unsigned long oldflags;
17422 ++ bool is_textrel_rw, is_textrel_rx, is_relro;
17423 ++
17424 ++ if (!(vma->vm_mm->pax_flags & MF_PAX_MPROTECT))
17425 ++ return;
17426 ++
17427 ++ oldflags = vma->vm_flags & (VM_MAYEXEC | VM_MAYWRITE | VM_MAYREAD | VM_EXEC | VM_WRITE | VM_READ);
17428 ++ newflags &= VM_MAYEXEC | VM_MAYWRITE | VM_MAYREAD | VM_EXEC | VM_WRITE | VM_READ;
17429 ++
17430 ++#ifdef CONFIG_PAX_NOELFRELOCS
17431 ++ is_textrel_rw = false;
17432 ++ is_textrel_rx = false;
17433 ++#else
17434 ++ /* possible TEXTREL */
17435 ++ is_textrel_rw = vma->vm_file && !vma->anon_vma && oldflags == (VM_MAYEXEC | VM_MAYREAD | VM_EXEC | VM_READ) && newflags == (VM_WRITE | VM_READ);
17436 ++ is_textrel_rx = vma->vm_file && vma->anon_vma && oldflags == (VM_MAYEXEC | VM_MAYWRITE | VM_MAYREAD | VM_WRITE | VM_READ) && newflags == (VM_EXEC | VM_READ);
17437 ++#endif
17438 ++
17439 ++ /* possible RELRO */
17440 ++ is_relro = vma->vm_file && vma->anon_vma && oldflags == (VM_MAYWRITE | VM_MAYREAD | VM_READ) && newflags == (VM_MAYWRITE | VM_MAYREAD | VM_READ);
17441 ++
17442 ++ if (!is_textrel_rw && !is_textrel_rx && !is_relro)
17443 ++ return;
17444 ++
17445 ++ if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) ||
17446 ++ memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
17447 ++
17448 ++#ifdef CONFIG_PAX_ETEXECRELOCS
17449 ++ ((is_textrel_rw || is_textrel_rx) && (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC)) ||
17450 ++#else
17451 ++ ((is_textrel_rw || is_textrel_rx) && elf_h.e_type != ET_DYN) ||
17452 ++#endif
17453 ++
17454 ++ (is_relro && (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC)) ||
17455 ++ !elf_check_arch(&elf_h) ||
17456 ++ elf_h.e_phentsize != sizeof(struct elf_phdr) ||
17457 ++ elf_h.e_phnum > 65536UL / sizeof(struct elf_phdr))
17458 ++ return;
17459 ++
17460 ++ for (i = 0UL; i < elf_h.e_phnum; i++) {
17461 ++ if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p)))
17462 ++ return;
17463 ++ switch (elf_p.p_type) {
17464 ++ case PT_DYNAMIC: {
17465 ++ elf_addr_t dyn_offset = 0UL;
17466 ++ elf_dyn dyn;
17467 ++
17468 ++ if (!is_textrel_rw && !is_textrel_rx)
17469 ++ continue;
17470 ++ dyn_offset = elf_p.p_offset;
17471 ++ i = 0UL;
17472 ++ do {
17473 ++ if (sizeof(dyn) != kernel_read(vma->vm_file, dyn_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn)))
17474 ++ return;
17475 ++ if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
17476 ++ gr_log_textrel(vma);
17477 ++ if (is_textrel_rw)
17478 ++ vma->vm_flags |= VM_MAYWRITE;
17479 ++ else
17480 ++ /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
17481 ++ vma->vm_flags &= ~VM_MAYWRITE;
17482 ++ return;
17483 ++ }
17484 ++ i++;
17485 ++ } while (dyn.d_tag != DT_NULL);
17486 ++ return;
17487 ++ }
17488 ++
17489 ++ case PT_GNU_RELRO:
17490 ++ if (!is_relro)
17491 ++ continue;
17492 ++ if ((elf_p.p_offset >> PAGE_SHIFT) == vma->vm_pgoff && ELF_PAGEALIGN(elf_p.p_memsz) == vma->vm_end - vma->vm_start) {
17493 ++ vma->vm_flags &= ~VM_MAYWRITE;
17494 ++ }
17495 ++ return;
17496 ++ }
17497 ++ }
17498 ++}
17499 ++#endif
17500 ++
17501 + static int __init init_elf_binfmt(void)
17502 + {
17503 + return register_binfmt(&elf_format);
17504 +diff -urNp linux-2.6.28.8/fs/binfmt_flat.c linux-2.6.28.8/fs/binfmt_flat.c
17505 +--- linux-2.6.28.8/fs/binfmt_flat.c 2009-02-06 16:47:45.000000000 -0500
17506 ++++ linux-2.6.28.8/fs/binfmt_flat.c 2009-02-21 09:37:48.000000000 -0500
17507 +@@ -561,7 +561,9 @@ static int load_flat_file(struct linux_b
17508 + realdatastart = (unsigned long) -ENOMEM;
17509 + printk("Unable to allocate RAM for process data, errno %d\n",
17510 + (int)-realdatastart);
17511 ++ down_write(&current->mm->mmap_sem);
17512 + do_munmap(current->mm, textpos, text_len);
17513 ++ up_write(&current->mm->mmap_sem);
17514 + ret = realdatastart;
17515 + goto err;
17516 + }
17517 +@@ -583,8 +585,10 @@ static int load_flat_file(struct linux_b
17518 + }
17519 + if (result >= (unsigned long)-4096) {
17520 + printk("Unable to read data+bss, errno %d\n", (int)-result);
17521 ++ down_write(&current->mm->mmap_sem);
17522 + do_munmap(current->mm, textpos, text_len);
17523 + do_munmap(current->mm, realdatastart, data_len + extra);
17524 ++ up_write(&current->mm->mmap_sem);
17525 + ret = result;
17526 + goto err;
17527 + }
17528 +@@ -657,8 +661,10 @@ static int load_flat_file(struct linux_b
17529 + }
17530 + if (result >= (unsigned long)-4096) {
17531 + printk("Unable to read code+data+bss, errno %d\n",(int)-result);
17532 ++ down_write(&current->mm->mmap_sem);
17533 + do_munmap(current->mm, textpos, text_len + data_len + extra +
17534 + MAX_SHARED_LIBS * sizeof(unsigned long));
17535 ++ up_write(&current->mm->mmap_sem);
17536 + ret = result;
17537 + goto err;
17538 + }
17539 +diff -urNp linux-2.6.28.8/fs/binfmt_misc.c linux-2.6.28.8/fs/binfmt_misc.c
17540 +--- linux-2.6.28.8/fs/binfmt_misc.c 2009-02-06 16:47:45.000000000 -0500
17541 ++++ linux-2.6.28.8/fs/binfmt_misc.c 2009-02-21 09:37:48.000000000 -0500
17542 +@@ -696,7 +696,7 @@ static int bm_fill_super(struct super_bl
17543 + static struct tree_descr bm_files[] = {
17544 + [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
17545 + [3] = {"register", &bm_register_operations, S_IWUSR},
17546 +- /* last one */ {""}
17547 ++ /* last one */ {"", NULL, 0}
17548 + };
17549 + int err = simple_fill_super(sb, 0x42494e4d, bm_files);
17550 + if (!err)
17551 +diff -urNp linux-2.6.28.8/fs/bio.c linux-2.6.28.8/fs/bio.c
17552 +--- linux-2.6.28.8/fs/bio.c 2009-02-06 16:47:45.000000000 -0500
17553 ++++ linux-2.6.28.8/fs/bio.c 2009-02-21 09:37:48.000000000 -0500
17554 +@@ -554,7 +554,7 @@ static int __bio_copy_iov(struct bio *bi
17555 +
17556 + while (bv_len && iov_idx < iov_count) {
17557 + unsigned int bytes;
17558 +- char *iov_addr;
17559 ++ char __user *iov_addr;
17560 +
17561 + bytes = min_t(unsigned int,
17562 + iov[iov_idx].iov_len - iov_off, bv_len);
17563 +diff -urNp linux-2.6.28.8/fs/buffer.c linux-2.6.28.8/fs/buffer.c
17564 +--- linux-2.6.28.8/fs/buffer.c 2009-02-06 16:47:45.000000000 -0500
17565 ++++ linux-2.6.28.8/fs/buffer.c 2009-02-21 09:37:48.000000000 -0500
17566 +@@ -25,6 +25,7 @@
17567 + #include <linux/percpu.h>
17568 + #include <linux/slab.h>
17569 + #include <linux/capability.h>
17570 ++#include <linux/security.h>
17571 + #include <linux/blkdev.h>
17572 + #include <linux/file.h>
17573 + #include <linux/quotaops.h>
17574 +@@ -2249,6 +2250,7 @@ int generic_cont_expand_simple(struct in
17575 +
17576 + err = -EFBIG;
17577 + limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
17578 ++ gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
17579 + if (limit != RLIM_INFINITY && size > (loff_t)limit) {
17580 + send_sig(SIGXFSZ, current, 0);
17581 + goto out;
17582 +diff -urNp linux-2.6.28.8/fs/cifs/cifs_uniupr.h linux-2.6.28.8/fs/cifs/cifs_uniupr.h
17583 +--- linux-2.6.28.8/fs/cifs/cifs_uniupr.h 2009-02-06 16:47:45.000000000 -0500
17584 ++++ linux-2.6.28.8/fs/cifs/cifs_uniupr.h 2009-02-21 09:37:48.000000000 -0500
17585 +@@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa
17586 + {0x0490, 0x04cc, UniCaseRangeU0490},
17587 + {0x1e00, 0x1ffc, UniCaseRangeU1e00},
17588 + {0xff40, 0xff5a, UniCaseRangeUff40},
17589 +- {0}
17590 ++ {0, 0, NULL}
17591 + };
17592 + #endif
17593 +
17594 +diff -urNp linux-2.6.28.8/fs/cifs/link.c linux-2.6.28.8/fs/cifs/link.c
17595 +--- linux-2.6.28.8/fs/cifs/link.c 2009-02-06 16:47:45.000000000 -0500
17596 ++++ linux-2.6.28.8/fs/cifs/link.c 2009-02-21 09:37:48.000000000 -0500
17597 +@@ -318,7 +318,7 @@ cifs_readlink(struct dentry *direntry, c
17598 +
17599 + void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
17600 + {
17601 +- char *p = nd_get_link(nd);
17602 ++ const char *p = nd_get_link(nd);
17603 + if (!IS_ERR(p))
17604 + kfree(p);
17605 + }
17606 +diff -urNp linux-2.6.28.8/fs/compat.c linux-2.6.28.8/fs/compat.c
17607 +--- linux-2.6.28.8/fs/compat.c 2009-02-06 16:47:45.000000000 -0500
17608 ++++ linux-2.6.28.8/fs/compat.c 2009-02-21 09:37:48.000000000 -0500
17609 +@@ -1331,14 +1331,12 @@ static int compat_copy_strings(int argc,
17610 + if (!kmapped_page || kpos != (pos & PAGE_MASK)) {
17611 + struct page *page;
17612 +
17613 +-#ifdef CONFIG_STACK_GROWSUP
17614 + ret = expand_stack_downwards(bprm->vma, pos);
17615 + if (ret < 0) {
17616 + /* We've exceed the stack rlimit. */
17617 + ret = -E2BIG;
17618 + goto out;
17619 + }
17620 +-#endif
17621 + ret = get_user_pages(current, bprm->mm, pos,
17622 + 1, 1, 1, &page, NULL);
17623 + if (ret <= 0) {
17624 +@@ -1384,6 +1382,11 @@ int compat_do_execve(char * filename,
17625 + compat_uptr_t __user *envp,
17626 + struct pt_regs * regs)
17627 + {
17628 ++#ifdef CONFIG_GRKERNSEC
17629 ++ struct file *old_exec_file;
17630 ++ struct acl_subject_label *old_acl;
17631 ++ struct rlimit old_rlim[RLIM_NLIMITS];
17632 ++#endif
17633 + struct linux_binprm *bprm;
17634 + struct file *file;
17635 + int retval;
17636 +@@ -1404,6 +1407,14 @@ int compat_do_execve(char * filename,
17637 + bprm->filename = filename;
17638 + bprm->interp = filename;
17639 +
17640 ++ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
17641 ++ retval = -EAGAIN;
17642 ++ if (gr_handle_nproc())
17643 ++ goto out_file;
17644 ++ retval = -EACCES;
17645 ++ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
17646 ++ goto out_file;
17647 ++
17648 + retval = bprm_mm_init(bprm);
17649 + if (retval)
17650 + goto out_file;
17651 +@@ -1437,8 +1448,36 @@ int compat_do_execve(char * filename,
17652 + if (retval < 0)
17653 + goto out;
17654 +
17655 ++ if (!gr_tpe_allow(file)) {
17656 ++ retval = -EACCES;
17657 ++ goto out;
17658 ++ }
17659 ++
17660 ++ if (gr_check_crash_exec(file)) {
17661 ++ retval = -EACCES;
17662 ++ goto out;
17663 ++ }
17664 ++
17665 ++ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
17666 ++
17667 ++ gr_handle_exec_args(bprm, (char __user * __user *)argv);
17668 ++
17669 ++#ifdef CONFIG_GRKERNSEC
17670 ++ old_acl = current->acl;
17671 ++ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
17672 ++ old_exec_file = current->exec_file;
17673 ++ get_file(file);
17674 ++ current->exec_file = file;
17675 ++#endif
17676 ++
17677 ++ gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
17678 ++
17679 + retval = search_binary_handler(bprm, regs);
17680 + if (retval >= 0) {
17681 ++#ifdef CONFIG_GRKERNSEC
17682 ++ if (old_exec_file)
17683 ++ fput(old_exec_file);
17684 ++#endif
17685 + /* execve success */
17686 + security_bprm_free(bprm);
17687 + acct_update_integrals(current);
17688 +@@ -1446,6 +1485,13 @@ int compat_do_execve(char * filename,
17689 + return retval;
17690 + }
17691 +
17692 ++#ifdef CONFIG_GRKERNSEC
17693 ++ current->acl = old_acl;
17694 ++ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
17695 ++ fput(current->exec_file);
17696 ++ current->exec_file = old_exec_file;
17697 ++#endif
17698 ++
17699 + out:
17700 + if (bprm->security)
17701 + security_bprm_free(bprm);
17702 +diff -urNp linux-2.6.28.8/fs/compat_ioctl.c linux-2.6.28.8/fs/compat_ioctl.c
17703 +--- linux-2.6.28.8/fs/compat_ioctl.c 2009-03-07 10:24:49.000000000 -0500
17704 ++++ linux-2.6.28.8/fs/compat_ioctl.c 2009-03-07 10:29:51.000000000 -0500
17705 +@@ -1832,15 +1832,15 @@ struct ioctl_trans {
17706 + };
17707 +
17708 + #define HANDLE_IOCTL(cmd,handler) \
17709 +- { (cmd), (ioctl_trans_handler_t)(handler) },
17710 ++ { (cmd), (ioctl_trans_handler_t)(handler), NULL },
17711 +
17712 + /* pointer to compatible structure or no argument */
17713 + #define COMPATIBLE_IOCTL(cmd) \
17714 +- { (cmd), do_ioctl32_pointer },
17715 ++ { (cmd), do_ioctl32_pointer, NULL },
17716 +
17717 + /* argument is an unsigned long integer, not a pointer */
17718 + #define ULONG_IOCTL(cmd) \
17719 +- { (cmd), (ioctl_trans_handler_t)sys_ioctl },
17720 ++ { (cmd), (ioctl_trans_handler_t)sys_ioctl, NULL },
17721 +
17722 + /* ioctl should not be warned about even if it's not implemented.
17723 + Valid reasons to use this:
17724 +diff -urNp linux-2.6.28.8/fs/debugfs/inode.c linux-2.6.28.8/fs/debugfs/inode.c
17725 +--- linux-2.6.28.8/fs/debugfs/inode.c 2009-02-06 16:47:45.000000000 -0500
17726 ++++ linux-2.6.28.8/fs/debugfs/inode.c 2009-02-21 09:37:48.000000000 -0500
17727 +@@ -120,7 +120,7 @@ static inline int debugfs_positive(struc
17728 +
17729 + static int debug_fill_super(struct super_block *sb, void *data, int silent)
17730 + {
17731 +- static struct tree_descr debug_files[] = {{""}};
17732 ++ static struct tree_descr debug_files[] = {{"", NULL, 0}};
17733 +
17734 + return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
17735 + }
17736 +diff -urNp linux-2.6.28.8/fs/exec.c linux-2.6.28.8/fs/exec.c
17737 +--- linux-2.6.28.8/fs/exec.c 2009-02-06 16:47:45.000000000 -0500
17738 ++++ linux-2.6.28.8/fs/exec.c 2009-02-21 09:37:48.000000000 -0500
17739 +@@ -51,6 +51,12 @@
17740 + #include <linux/audit.h>
17741 + #include <linux/tracehook.h>
17742 + #include <linux/kmod.h>
17743 ++#include <linux/random.h>
17744 ++
17745 ++#ifdef CONFIG_PAX_REFCOUNT
17746 ++#include <linux/kallsyms.h>
17747 ++#include <linux/kdebug.h>
17748 ++#endif
17749 +
17750 + #include <asm/uaccess.h>
17751 + #include <asm/mmu_context.h>
17752 +@@ -61,6 +67,11 @@
17753 + #include <linux/a.out.h>
17754 + #endif
17755 +
17756 ++#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
17757 ++void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
17758 ++EXPORT_SYMBOL(pax_set_initial_flags_func);
17759 ++#endif
17760 ++
17761 + int core_uses_pid;
17762 + char core_pattern[CORENAME_MAX_SIZE] = "core";
17763 + int suid_dumpable = 0;
17764 +@@ -169,18 +180,10 @@ static struct page *get_arg_page(struct
17765 + int write)
17766 + {
17767 + struct page *page;
17768 +- int ret;
17769 +
17770 +-#ifdef CONFIG_STACK_GROWSUP
17771 +- if (write) {
17772 +- ret = expand_stack_downwards(bprm->vma, pos);
17773 +- if (ret < 0)
17774 +- return NULL;
17775 +- }
17776 +-#endif
17777 +- ret = get_user_pages(current, bprm->mm, pos,
17778 +- 1, write, 1, &page, NULL);
17779 +- if (ret <= 0)
17780 ++ if (0 > expand_stack_downwards(bprm->vma, pos))
17781 ++ return NULL;
17782 ++ if (0 >= get_user_pages(current, bprm->mm, pos, 1, write, 1, &page, NULL))
17783 + return NULL;
17784 +
17785 + if (write) {
17786 +@@ -253,6 +256,11 @@ static int __bprm_mm_init(struct linux_b
17787 + vma->vm_start = vma->vm_end - PAGE_SIZE;
17788 +
17789 + vma->vm_flags = VM_STACK_FLAGS;
17790 ++
17791 ++#ifdef CONFIG_PAX_SEGMEXEC
17792 ++ vma->vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
17793 ++#endif
17794 ++
17795 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
17796 + err = insert_vm_struct(mm, vma);
17797 + if (err) {
17798 +@@ -265,6 +273,11 @@ static int __bprm_mm_init(struct linux_b
17799 +
17800 + bprm->p = vma->vm_end - sizeof(void *);
17801 +
17802 ++#ifdef CONFIG_PAX_RANDUSTACK
17803 ++ if (randomize_va_space)
17804 ++ bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK;
17805 ++#endif
17806 ++
17807 + return 0;
17808 +
17809 + err:
17810 +@@ -528,6 +541,10 @@ static int shift_arg_pages(struct vm_are
17811 + if (vma != find_vma(mm, new_start))
17812 + return -EFAULT;
17813 +
17814 ++#ifdef CONFIG_PAX_SEGMEXEC
17815 ++ BUG_ON(pax_find_mirror_vma(vma));
17816 ++#endif
17817 ++
17818 + /*
17819 + * cover the whole range: [new_start, old_end)
17820 + */
17821 +@@ -616,6 +633,14 @@ int setup_arg_pages(struct linux_binprm
17822 + bprm->exec -= stack_shift;
17823 +
17824 + down_write(&mm->mmap_sem);
17825 ++
17826 ++ /* Move stack pages down in memory. */
17827 ++ if (stack_shift) {
17828 ++ ret = shift_arg_pages(vma, stack_shift);
17829 ++ if (ret)
17830 ++ goto out_unlock;
17831 ++ }
17832 ++
17833 + vm_flags = VM_STACK_FLAGS;
17834 +
17835 + /*
17836 +@@ -629,21 +654,24 @@ int setup_arg_pages(struct linux_binprm
17837 + vm_flags &= ~VM_EXEC;
17838 + vm_flags |= mm->def_flags;
17839 +
17840 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
17841 ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
17842 ++ vm_flags &= ~VM_EXEC;
17843 ++
17844 ++#ifdef CONFIG_PAX_MPROTECT
17845 ++ if (mm->pax_flags & MF_PAX_MPROTECT)
17846 ++ vm_flags &= ~VM_MAYEXEC;
17847 ++#endif
17848 ++
17849 ++ }
17850 ++#endif
17851 ++
17852 + ret = mprotect_fixup(vma, &prev, vma->vm_start, vma->vm_end,
17853 + vm_flags);
17854 + if (ret)
17855 + goto out_unlock;
17856 + BUG_ON(prev != vma);
17857 +
17858 +- /* Move stack pages down in memory. */
17859 +- if (stack_shift) {
17860 +- ret = shift_arg_pages(vma, stack_shift);
17861 +- if (ret) {
17862 +- up_write(&mm->mmap_sem);
17863 +- return ret;
17864 +- }
17865 +- }
17866 +-
17867 + #ifdef CONFIG_STACK_GROWSUP
17868 + stack_base = vma->vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
17869 + #else
17870 +@@ -655,7 +683,7 @@ int setup_arg_pages(struct linux_binprm
17871 +
17872 + out_unlock:
17873 + up_write(&mm->mmap_sem);
17874 +- return 0;
17875 ++ return ret;
17876 + }
17877 + EXPORT_SYMBOL(setup_arg_pages);
17878 +
17879 +@@ -1281,6 +1309,11 @@ int do_execve(char * filename,
17880 + char __user *__user *envp,
17881 + struct pt_regs * regs)
17882 + {
17883 ++#ifdef CONFIG_GRKERNSEC
17884 ++ struct file *old_exec_file;
17885 ++ struct acl_subject_label *old_acl;
17886 ++ struct rlimit old_rlim[RLIM_NLIMITS];
17887 ++#endif
17888 + struct linux_binprm *bprm;
17889 + struct file *file;
17890 + struct files_struct *displaced;
17891 +@@ -1300,6 +1333,20 @@ int do_execve(char * filename,
17892 + if (IS_ERR(file))
17893 + goto out_kfree;
17894 +
17895 ++ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
17896 ++
17897 ++ if (gr_handle_nproc()) {
17898 ++ allow_write_access(file);
17899 ++ fput(file);
17900 ++ return -EAGAIN;
17901 ++ }
17902 ++
17903 ++ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
17904 ++ allow_write_access(file);
17905 ++ fput(file);
17906 ++ return -EACCES;
17907 ++ }
17908 ++
17909 + sched_exec();
17910 +
17911 + bprm->file = file;
17912 +@@ -1339,9 +1386,39 @@ int do_execve(char * filename,
17913 + if (retval < 0)
17914 + goto out;
17915 +
17916 ++ if (!gr_tpe_allow(file)) {
17917 ++ retval = -EACCES;
17918 ++ goto out;
17919 ++ }
17920 ++
17921 ++ if (gr_check_crash_exec(file)) {
17922 ++ retval = -EACCES;
17923 ++ goto out;
17924 ++ }
17925 ++
17926 ++ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
17927 ++
17928 ++ gr_handle_exec_args(bprm, argv);
17929 ++
17930 ++#ifdef CONFIG_GRKERNSEC
17931 ++ old_acl = current->acl;
17932 ++ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
17933 ++ old_exec_file = current->exec_file;
17934 ++ get_file(file);
17935 ++ current->exec_file = file;
17936 ++#endif
17937 ++
17938 ++ retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
17939 ++ if (retval < 0)
17940 ++ goto out_fail;
17941 ++
17942 + current->flags &= ~PF_KTHREAD;
17943 + retval = search_binary_handler(bprm,regs);
17944 + if (retval >= 0) {
17945 ++#ifdef CONFIG_GRKERNSEC
17946 ++ if (old_exec_file)
17947 ++ fput(old_exec_file);
17948 ++#endif
17949 + /* execve success */
17950 + security_bprm_free(bprm);
17951 + acct_update_integrals(current);
17952 +@@ -1351,6 +1428,14 @@ int do_execve(char * filename,
17953 + return retval;
17954 + }
17955 +
17956 ++out_fail:
17957 ++#ifdef CONFIG_GRKERNSEC
17958 ++ current->acl = old_acl;
17959 ++ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
17960 ++ fput(current->exec_file);
17961 ++ current->exec_file = old_exec_file;
17962 ++#endif
17963 ++
17964 + out:
17965 + if (bprm->security)
17966 + security_bprm_free(bprm);
17967 +@@ -1513,6 +1598,129 @@ out:
17968 + return ispipe;
17969 + }
17970 +
17971 ++int pax_check_flags(unsigned long *flags)
17972 ++{
17973 ++ int retval = 0;
17974 ++
17975 ++#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC)
17976 ++ if (*flags & MF_PAX_SEGMEXEC)
17977 ++ {
17978 ++ *flags &= ~MF_PAX_SEGMEXEC;
17979 ++ retval = -EINVAL;
17980 ++ }
17981 ++#endif
17982 ++
17983 ++ if ((*flags & MF_PAX_PAGEEXEC)
17984 ++
17985 ++#ifdef CONFIG_PAX_PAGEEXEC
17986 ++ && (*flags & MF_PAX_SEGMEXEC)
17987 ++#endif
17988 ++
17989 ++ )
17990 ++ {
17991 ++ *flags &= ~MF_PAX_PAGEEXEC;
17992 ++ retval = -EINVAL;
17993 ++ }
17994 ++
17995 ++ if ((*flags & MF_PAX_MPROTECT)
17996 ++
17997 ++#ifdef CONFIG_PAX_MPROTECT
17998 ++ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
17999 ++#endif
18000 ++
18001 ++ )
18002 ++ {
18003 ++ *flags &= ~MF_PAX_MPROTECT;
18004 ++ retval = -EINVAL;
18005 ++ }
18006 ++
18007 ++ if ((*flags & MF_PAX_EMUTRAMP)
18008 ++
18009 ++#ifdef CONFIG_PAX_EMUTRAMP
18010 ++ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
18011 ++#endif
18012 ++
18013 ++ )
18014 ++ {
18015 ++ *flags &= ~MF_PAX_EMUTRAMP;
18016 ++ retval = -EINVAL;
18017 ++ }
18018 ++
18019 ++ return retval;
18020 ++}
18021 ++
18022 ++EXPORT_SYMBOL(pax_check_flags);
18023 ++
18024 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
18025 ++void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
18026 ++{
18027 ++ struct task_struct *tsk = current;
18028 ++ struct mm_struct *mm = current->mm;
18029 ++ char *buffer_exec = (char *)__get_free_page(GFP_KERNEL);
18030 ++ char *buffer_fault = (char *)__get_free_page(GFP_KERNEL);
18031 ++ char *path_exec = NULL;
18032 ++ char *path_fault = NULL;
18033 ++ unsigned long start = 0UL, end = 0UL, offset = 0UL;
18034 ++
18035 ++ if (buffer_exec && buffer_fault) {
18036 ++ struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL;
18037 ++
18038 ++ down_read(&mm->mmap_sem);
18039 ++ vma = mm->mmap;
18040 ++ while (vma && (!vma_exec || !vma_fault)) {
18041 ++ if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
18042 ++ vma_exec = vma;
18043 ++ if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
18044 ++ vma_fault = vma;
18045 ++ vma = vma->vm_next;
18046 ++ }
18047 ++ if (vma_exec) {
18048 ++ path_exec = d_path(&vma_exec->vm_file->f_path, buffer_exec, PAGE_SIZE);
18049 ++ if (IS_ERR(path_exec))
18050 ++ path_exec = "<path too long>";
18051 ++ }
18052 ++ if (vma_fault) {
18053 ++ start = vma_fault->vm_start;
18054 ++ end = vma_fault->vm_end;
18055 ++ offset = vma_fault->vm_pgoff << PAGE_SHIFT;
18056 ++ if (vma_fault->vm_file) {
18057 ++ path_fault = d_path(&vma_fault->vm_file->f_path, buffer_fault, PAGE_SIZE);
18058 ++ if (IS_ERR(path_fault))
18059 ++ path_fault = "<path too long>";
18060 ++ } else
18061 ++ path_fault = "<anonymous mapping>";
18062 ++ }
18063 ++ up_read(&mm->mmap_sem);
18064 ++ }
18065 ++ if (tsk->signal->curr_ip)
18066 ++ 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);
18067 ++ else
18068 ++ printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
18069 ++ printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
18070 ++ "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
18071 ++ tsk->uid, tsk->euid, pc, sp);
18072 ++ free_page((unsigned long)buffer_exec);
18073 ++ free_page((unsigned long)buffer_fault);
18074 ++ pax_report_insns(pc, sp);
18075 ++ do_coredump(SIGKILL, SIGKILL, regs);
18076 ++}
18077 ++#endif
18078 ++
18079 ++#ifdef CONFIG_PAX_REFCOUNT
18080 ++void pax_report_refcount_overflow(struct pt_regs *regs)
18081 ++{
18082 ++ if (current->signal->curr_ip)
18083 ++ printk(KERN_ERR "PAX: From %u.%u.%u.%u: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n",
18084 ++ NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current->uid, current->euid);
18085 ++ else
18086 ++ printk(KERN_ERR "PAX: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n",
18087 ++ current->comm, task_pid_nr(current), current->uid, current->euid);
18088 ++ print_symbol(KERN_ERR "PAX: refcount overflow occured at: %s\n", instruction_pointer(regs));
18089 ++ show_registers(regs);
18090 ++ force_sig_specific(SIGKILL, current);
18091 ++}
18092 ++#endif
18093 ++
18094 + static int zap_process(struct task_struct *start)
18095 + {
18096 + struct task_struct *t;
18097 +@@ -1759,6 +1967,10 @@ int do_coredump(long signr, int exit_cod
18098 + */
18099 + clear_thread_flag(TIF_SIGPENDING);
18100 +
18101 ++ if (signr == SIGKILL || signr == SIGILL)
18102 ++ gr_handle_brute_attach(current);
18103 ++ gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
18104 ++
18105 + /*
18106 + * lock_kernel() because format_corename() is controlled by sysctl, which
18107 + * uses lock_kernel()
18108 +@@ -1779,6 +1991,8 @@ int do_coredump(long signr, int exit_cod
18109 +
18110 + if (ispipe) {
18111 + helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc);
18112 ++ if (!helper_argv)
18113 ++ goto fail_unlock;
18114 + /* Terminate the string before the first option */
18115 + delimit = strchr(corename, ' ');
18116 + if (delimit)
18117 +diff -urNp linux-2.6.28.8/fs/ext2/balloc.c linux-2.6.28.8/fs/ext2/balloc.c
18118 +--- linux-2.6.28.8/fs/ext2/balloc.c 2009-02-06 16:47:45.000000000 -0500
18119 ++++ linux-2.6.28.8/fs/ext2/balloc.c 2009-02-21 09:37:49.000000000 -0500
18120 +@@ -1192,7 +1192,7 @@ static int ext2_has_free_blocks(struct e
18121 +
18122 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
18123 + root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
18124 +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
18125 ++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
18126 + sbi->s_resuid != current->fsuid &&
18127 + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
18128 + return 0;
18129 +diff -urNp linux-2.6.28.8/fs/ext3/balloc.c linux-2.6.28.8/fs/ext3/balloc.c
18130 +--- linux-2.6.28.8/fs/ext3/balloc.c 2009-02-06 16:47:45.000000000 -0500
18131 ++++ linux-2.6.28.8/fs/ext3/balloc.c 2009-02-21 09:37:49.000000000 -0500
18132 +@@ -1421,7 +1421,7 @@ static int ext3_has_free_blocks(struct e
18133 +
18134 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
18135 + root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
18136 +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
18137 ++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
18138 + sbi->s_resuid != current->fsuid &&
18139 + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
18140 + return 0;
18141 +diff -urNp linux-2.6.28.8/fs/ext3/namei.c linux-2.6.28.8/fs/ext3/namei.c
18142 +--- linux-2.6.28.8/fs/ext3/namei.c 2009-02-06 16:47:45.000000000 -0500
18143 ++++ linux-2.6.28.8/fs/ext3/namei.c 2009-02-21 09:37:49.000000000 -0500
18144 +@@ -1156,9 +1156,9 @@ static struct ext3_dir_entry_2 *do_split
18145 + u32 hash2;
18146 + struct dx_map_entry *map;
18147 + char *data1 = (*bh)->b_data, *data2;
18148 +- unsigned split, move, size, i;
18149 ++ unsigned split, move, size;
18150 + struct ext3_dir_entry_2 *de = NULL, *de2;
18151 +- int err = 0;
18152 ++ int i, err = 0;
18153 +
18154 + bh2 = ext3_append (handle, dir, &newblock, &err);
18155 + if (!(bh2)) {
18156 +diff -urNp linux-2.6.28.8/fs/ext3/xattr.c linux-2.6.28.8/fs/ext3/xattr.c
18157 +--- linux-2.6.28.8/fs/ext3/xattr.c 2009-02-06 16:47:45.000000000 -0500
18158 ++++ linux-2.6.28.8/fs/ext3/xattr.c 2009-02-21 09:37:49.000000000 -0500
18159 +@@ -89,8 +89,8 @@
18160 + printk("\n"); \
18161 + } while (0)
18162 + #else
18163 +-# define ea_idebug(f...)
18164 +-# define ea_bdebug(f...)
18165 ++# define ea_idebug(f...) do {} while (0)
18166 ++# define ea_bdebug(f...) do {} while (0)
18167 + #endif
18168 +
18169 + static void ext3_xattr_cache_insert(struct buffer_head *);
18170 +diff -urNp linux-2.6.28.8/fs/ext4/balloc.c linux-2.6.28.8/fs/ext4/balloc.c
18171 +--- linux-2.6.28.8/fs/ext4/balloc.c 2009-02-20 22:26:39.000000000 -0500
18172 ++++ linux-2.6.28.8/fs/ext4/balloc.c 2009-02-21 09:37:49.000000000 -0500
18173 +@@ -576,7 +576,7 @@ int ext4_has_free_blocks(struct ext4_sb_
18174 + /* Hm, nope. Are (enough) root reserved blocks available? */
18175 + if (sbi->s_resuid == current->fsuid ||
18176 + ((sbi->s_resgid != 0) && in_group_p(sbi->s_resgid)) ||
18177 +- capable(CAP_SYS_RESOURCE)) {
18178 ++ capable_nolog(CAP_SYS_RESOURCE)) {
18179 + if (free_blocks >= (nblocks + dirty_blocks))
18180 + return 1;
18181 + }
18182 +diff -urNp linux-2.6.28.8/fs/ext4/namei.c linux-2.6.28.8/fs/ext4/namei.c
18183 +--- linux-2.6.28.8/fs/ext4/namei.c 2009-02-20 22:26:39.000000000 -0500
18184 ++++ linux-2.6.28.8/fs/ext4/namei.c 2009-02-21 09:37:49.000000000 -0500
18185 +@@ -1171,9 +1171,9 @@ static struct ext4_dir_entry_2 *do_split
18186 + u32 hash2;
18187 + struct dx_map_entry *map;
18188 + char *data1 = (*bh)->b_data, *data2;
18189 +- unsigned split, move, size, i;
18190 ++ unsigned split, move, size;
18191 + struct ext4_dir_entry_2 *de = NULL, *de2;
18192 +- int err = 0;
18193 ++ int i, err = 0;
18194 +
18195 + bh2 = ext4_append (handle, dir, &newblock, &err);
18196 + if (!(bh2)) {
18197 +diff -urNp linux-2.6.28.8/fs/fcntl.c linux-2.6.28.8/fs/fcntl.c
18198 +--- linux-2.6.28.8/fs/fcntl.c 2009-02-06 16:47:45.000000000 -0500
18199 ++++ linux-2.6.28.8/fs/fcntl.c 2009-02-21 09:37:49.000000000 -0500
18200 +@@ -266,6 +266,7 @@ static long do_fcntl(int fd, unsigned in
18201 + switch (cmd) {
18202 + case F_DUPFD:
18203 + case F_DUPFD_CLOEXEC:
18204 ++ gr_learn_resource(current, RLIMIT_NOFILE, arg, 0);
18205 + if (arg >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
18206 + break;
18207 + err = alloc_fd(arg, cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0);
18208 +@@ -411,7 +412,8 @@ static inline int sigio_perm(struct task
18209 + return (((fown->euid == 0) ||
18210 + (fown->euid == p->suid) || (fown->euid == p->uid) ||
18211 + (fown->uid == p->suid) || (fown->uid == p->uid)) &&
18212 +- !security_file_send_sigiotask(p, fown, sig));
18213 ++ !security_file_send_sigiotask(p, fown, sig) &&
18214 ++ !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
18215 + }
18216 +
18217 + static void send_sigio_to_task(struct task_struct *p,
18218 +diff -urNp linux-2.6.28.8/fs/file.c linux-2.6.28.8/fs/file.c
18219 +--- linux-2.6.28.8/fs/file.c 2009-02-06 16:47:45.000000000 -0500
18220 ++++ linux-2.6.28.8/fs/file.c 2009-02-21 09:37:49.000000000 -0500
18221 +@@ -13,6 +13,7 @@
18222 + #include <linux/slab.h>
18223 + #include <linux/vmalloc.h>
18224 + #include <linux/file.h>
18225 ++#include <linux/security.h>
18226 + #include <linux/fdtable.h>
18227 + #include <linux/bitops.h>
18228 + #include <linux/interrupt.h>
18229 +@@ -256,6 +257,8 @@ int expand_files(struct files_struct *fi
18230 + * N.B. For clone tasks sharing a files structure, this test
18231 + * will limit the total number of files that can be opened.
18232 + */
18233 ++
18234 ++ gr_learn_resource(current, RLIMIT_NOFILE, nr, 0);
18235 + if (nr >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
18236 + return -EMFILE;
18237 +
18238 +diff -urNp linux-2.6.28.8/fs/fuse/control.c linux-2.6.28.8/fs/fuse/control.c
18239 +--- linux-2.6.28.8/fs/fuse/control.c 2009-02-06 16:47:45.000000000 -0500
18240 ++++ linux-2.6.28.8/fs/fuse/control.c 2009-02-21 09:37:49.000000000 -0500
18241 +@@ -159,7 +159,7 @@ void fuse_ctl_remove_conn(struct fuse_co
18242 +
18243 + static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
18244 + {
18245 +- struct tree_descr empty_descr = {""};
18246 ++ struct tree_descr empty_descr = {"", NULL, 0};
18247 + struct fuse_conn *fc;
18248 + int err;
18249 +
18250 +diff -urNp linux-2.6.28.8/fs/fuse/dir.c linux-2.6.28.8/fs/fuse/dir.c
18251 +--- linux-2.6.28.8/fs/fuse/dir.c 2009-02-06 16:47:45.000000000 -0500
18252 ++++ linux-2.6.28.8/fs/fuse/dir.c 2009-02-21 09:37:49.000000000 -0500
18253 +@@ -1072,7 +1072,7 @@ static char *read_link(struct dentry *de
18254 + return link;
18255 + }
18256 +
18257 +-static void free_link(char *link)
18258 ++static void free_link(const char *link)
18259 + {
18260 + if (!IS_ERR(link))
18261 + free_page((unsigned long) link);
18262 +diff -urNp linux-2.6.28.8/fs/hfs/inode.c linux-2.6.28.8/fs/hfs/inode.c
18263 +--- linux-2.6.28.8/fs/hfs/inode.c 2009-02-06 16:47:45.000000000 -0500
18264 ++++ linux-2.6.28.8/fs/hfs/inode.c 2009-02-21 09:37:49.000000000 -0500
18265 +@@ -419,7 +419,7 @@ int hfs_write_inode(struct inode *inode,
18266 +
18267 + if (S_ISDIR(main_inode->i_mode)) {
18268 + if (fd.entrylength < sizeof(struct hfs_cat_dir))
18269 +- /* panic? */;
18270 ++ {/* panic? */}
18271 + hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
18272 + sizeof(struct hfs_cat_dir));
18273 + if (rec.type != HFS_CDR_DIR ||
18274 +@@ -440,7 +440,7 @@ int hfs_write_inode(struct inode *inode,
18275 + sizeof(struct hfs_cat_file));
18276 + } else {
18277 + if (fd.entrylength < sizeof(struct hfs_cat_file))
18278 +- /* panic? */;
18279 ++ {/* panic? */}
18280 + hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
18281 + sizeof(struct hfs_cat_file));
18282 + if (rec.type != HFS_CDR_FIL ||
18283 +diff -urNp linux-2.6.28.8/fs/hfsplus/inode.c linux-2.6.28.8/fs/hfsplus/inode.c
18284 +--- linux-2.6.28.8/fs/hfsplus/inode.c 2009-02-06 16:47:45.000000000 -0500
18285 ++++ linux-2.6.28.8/fs/hfsplus/inode.c 2009-02-21 09:37:49.000000000 -0500
18286 +@@ -406,7 +406,7 @@ int hfsplus_cat_read_inode(struct inode
18287 + struct hfsplus_cat_folder *folder = &entry.folder;
18288 +
18289 + if (fd->entrylength < sizeof(struct hfsplus_cat_folder))
18290 +- /* panic? */;
18291 ++ {/* panic? */}
18292 + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
18293 + sizeof(struct hfsplus_cat_folder));
18294 + hfsplus_get_perms(inode, &folder->permissions, 1);
18295 +@@ -423,7 +423,7 @@ int hfsplus_cat_read_inode(struct inode
18296 + struct hfsplus_cat_file *file = &entry.file;
18297 +
18298 + if (fd->entrylength < sizeof(struct hfsplus_cat_file))
18299 +- /* panic? */;
18300 ++ {/* panic? */}
18301 + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
18302 + sizeof(struct hfsplus_cat_file));
18303 +
18304 +@@ -479,7 +479,7 @@ int hfsplus_cat_write_inode(struct inode
18305 + struct hfsplus_cat_folder *folder = &entry.folder;
18306 +
18307 + if (fd.entrylength < sizeof(struct hfsplus_cat_folder))
18308 +- /* panic? */;
18309 ++ {/* panic? */}
18310 + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
18311 + sizeof(struct hfsplus_cat_folder));
18312 + /* simple node checks? */
18313 +@@ -501,7 +501,7 @@ int hfsplus_cat_write_inode(struct inode
18314 + struct hfsplus_cat_file *file = &entry.file;
18315 +
18316 + if (fd.entrylength < sizeof(struct hfsplus_cat_file))
18317 +- /* panic? */;
18318 ++ {/* panic? */}
18319 + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
18320 + sizeof(struct hfsplus_cat_file));
18321 + hfsplus_inode_write_fork(inode, &file->data_fork);
18322 +diff -urNp linux-2.6.28.8/fs/jffs2/debug.h linux-2.6.28.8/fs/jffs2/debug.h
18323 +--- linux-2.6.28.8/fs/jffs2/debug.h 2009-02-06 16:47:45.000000000 -0500
18324 ++++ linux-2.6.28.8/fs/jffs2/debug.h 2009-02-21 09:37:49.000000000 -0500
18325 +@@ -52,13 +52,13 @@
18326 + #if CONFIG_JFFS2_FS_DEBUG > 0
18327 + #define D1(x) x
18328 + #else
18329 +-#define D1(x)
18330 ++#define D1(x) do {} while (0);
18331 + #endif
18332 +
18333 + #if CONFIG_JFFS2_FS_DEBUG > 1
18334 + #define D2(x) x
18335 + #else
18336 +-#define D2(x)
18337 ++#define D2(x) do {} while (0);
18338 + #endif
18339 +
18340 + /* The prefixes of JFFS2 messages */
18341 +@@ -114,73 +114,73 @@
18342 + #ifdef JFFS2_DBG_READINODE_MESSAGES
18343 + #define dbg_readinode(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
18344 + #else
18345 +-#define dbg_readinode(fmt, ...)
18346 ++#define dbg_readinode(fmt, ...) do {} while (0)
18347 + #endif
18348 + #ifdef JFFS2_DBG_READINODE2_MESSAGES
18349 + #define dbg_readinode2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
18350 + #else
18351 +-#define dbg_readinode2(fmt, ...)
18352 ++#define dbg_readinode2(fmt, ...) do {} while (0)
18353 + #endif
18354 +
18355 + /* Fragtree build debugging messages */
18356 + #ifdef JFFS2_DBG_FRAGTREE_MESSAGES
18357 + #define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
18358 + #else
18359 +-#define dbg_fragtree(fmt, ...)
18360 ++#define dbg_fragtree(fmt, ...) do {} while (0)
18361 + #endif
18362 + #ifdef JFFS2_DBG_FRAGTREE2_MESSAGES
18363 + #define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
18364 + #else
18365 +-#define dbg_fragtree2(fmt, ...)
18366 ++#define dbg_fragtree2(fmt, ...) do {} while (0)
18367 + #endif
18368 +
18369 + /* Directory entry list manilulation debugging messages */
18370 + #ifdef JFFS2_DBG_DENTLIST_MESSAGES
18371 + #define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
18372 + #else
18373 +-#define dbg_dentlist(fmt, ...)
18374 ++#define dbg_dentlist(fmt, ...) do {} while (0)
18375 + #endif
18376 +
18377 + /* Print the messages about manipulating node_refs */
18378 + #ifdef JFFS2_DBG_NODEREF_MESSAGES
18379 + #define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
18380 + #else
18381 +-#define dbg_noderef(fmt, ...)
18382 ++#define dbg_noderef(fmt, ...) do {} while (0)
18383 + #endif
18384 +
18385 + /* Manipulations with the list of inodes (JFFS2 inocache) */
18386 + #ifdef JFFS2_DBG_INOCACHE_MESSAGES
18387 + #define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
18388 + #else
18389 +-#define dbg_inocache(fmt, ...)
18390 ++#define dbg_inocache(fmt, ...) do {} while (0)
18391 + #endif
18392 +
18393 + /* Summary debugging messages */
18394 + #ifdef JFFS2_DBG_SUMMARY_MESSAGES
18395 + #define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
18396 + #else
18397 +-#define dbg_summary(fmt, ...)
18398 ++#define dbg_summary(fmt, ...) do {} while (0)
18399 + #endif
18400 +
18401 + /* File system build messages */
18402 + #ifdef JFFS2_DBG_FSBUILD_MESSAGES
18403 + #define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
18404 + #else
18405 +-#define dbg_fsbuild(fmt, ...)
18406 ++#define dbg_fsbuild(fmt, ...) do {} while (0)
18407 + #endif
18408 +
18409 + /* Watch the object allocations */
18410 + #ifdef JFFS2_DBG_MEMALLOC_MESSAGES
18411 + #define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
18412 + #else
18413 +-#define dbg_memalloc(fmt, ...)
18414 ++#define dbg_memalloc(fmt, ...) do {} while (0)
18415 + #endif
18416 +
18417 + /* Watch the XATTR subsystem */
18418 + #ifdef JFFS2_DBG_XATTR_MESSAGES
18419 + #define dbg_xattr(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
18420 + #else
18421 +-#define dbg_xattr(fmt, ...)
18422 ++#define dbg_xattr(fmt, ...) do {} while (0)
18423 + #endif
18424 +
18425 + /* "Sanity" checks */
18426 +diff -urNp linux-2.6.28.8/fs/jffs2/erase.c linux-2.6.28.8/fs/jffs2/erase.c
18427 +--- linux-2.6.28.8/fs/jffs2/erase.c 2009-02-06 16:47:45.000000000 -0500
18428 ++++ linux-2.6.28.8/fs/jffs2/erase.c 2009-02-21 09:37:49.000000000 -0500
18429 +@@ -431,7 +431,8 @@ static void jffs2_mark_erased_block(stru
18430 + struct jffs2_unknown_node marker = {
18431 + .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
18432 + .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
18433 +- .totlen = cpu_to_je32(c->cleanmarker_size)
18434 ++ .totlen = cpu_to_je32(c->cleanmarker_size),
18435 ++ .hdr_crc = cpu_to_je32(0)
18436 + };
18437 +
18438 + jffs2_prealloc_raw_node_refs(c, jeb, 1);
18439 +diff -urNp linux-2.6.28.8/fs/jffs2/summary.h linux-2.6.28.8/fs/jffs2/summary.h
18440 +--- linux-2.6.28.8/fs/jffs2/summary.h 2009-02-06 16:47:45.000000000 -0500
18441 ++++ linux-2.6.28.8/fs/jffs2/summary.h 2009-02-21 09:37:49.000000000 -0500
18442 +@@ -194,18 +194,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_
18443 +
18444 + #define jffs2_sum_active() (0)
18445 + #define jffs2_sum_init(a) (0)
18446 +-#define jffs2_sum_exit(a)
18447 +-#define jffs2_sum_disable_collecting(a)
18448 ++#define jffs2_sum_exit(a) do {} while (0)
18449 ++#define jffs2_sum_disable_collecting(a) do {} while (0)
18450 + #define jffs2_sum_is_disabled(a) (0)
18451 +-#define jffs2_sum_reset_collected(a)
18452 ++#define jffs2_sum_reset_collected(a) do {} while (0)
18453 + #define jffs2_sum_add_kvec(a,b,c,d) (0)
18454 +-#define jffs2_sum_move_collected(a,b)
18455 ++#define jffs2_sum_move_collected(a,b) do {} while (0)
18456 + #define jffs2_sum_write_sumnode(a) (0)
18457 +-#define jffs2_sum_add_padding_mem(a,b)
18458 +-#define jffs2_sum_add_inode_mem(a,b,c)
18459 +-#define jffs2_sum_add_dirent_mem(a,b,c)
18460 +-#define jffs2_sum_add_xattr_mem(a,b,c)
18461 +-#define jffs2_sum_add_xref_mem(a,b,c)
18462 ++#define jffs2_sum_add_padding_mem(a,b) do {} while (0)
18463 ++#define jffs2_sum_add_inode_mem(a,b,c) do {} while (0)
18464 ++#define jffs2_sum_add_dirent_mem(a,b,c) do {} while (0)
18465 ++#define jffs2_sum_add_xattr_mem(a,b,c) do {} while (0)
18466 ++#define jffs2_sum_add_xref_mem(a,b,c) do {} while (0)
18467 + #define jffs2_sum_scan_sumnode(a,b,c,d,e) (0)
18468 +
18469 + #endif /* CONFIG_JFFS2_SUMMARY */
18470 +diff -urNp linux-2.6.28.8/fs/jffs2/wbuf.c linux-2.6.28.8/fs/jffs2/wbuf.c
18471 +--- linux-2.6.28.8/fs/jffs2/wbuf.c 2009-02-06 16:47:45.000000000 -0500
18472 ++++ linux-2.6.28.8/fs/jffs2/wbuf.c 2009-02-21 09:37:49.000000000 -0500
18473 +@@ -1012,7 +1012,8 @@ static const struct jffs2_unknown_node o
18474 + {
18475 + .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK),
18476 + .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
18477 +- .totlen = constant_cpu_to_je32(8)
18478 ++ .totlen = constant_cpu_to_je32(8),
18479 ++ .hdr_crc = constant_cpu_to_je32(0)
18480 + };
18481 +
18482 + /*
18483 +diff -urNp linux-2.6.28.8/fs/locks.c linux-2.6.28.8/fs/locks.c
18484 +--- linux-2.6.28.8/fs/locks.c 2009-02-06 16:47:45.000000000 -0500
18485 ++++ linux-2.6.28.8/fs/locks.c 2009-02-21 09:37:49.000000000 -0500
18486 +@@ -2006,16 +2006,16 @@ void locks_remove_flock(struct file *fil
18487 + return;
18488 +
18489 + if (filp->f_op && filp->f_op->flock) {
18490 +- struct file_lock fl = {
18491 ++ struct file_lock flock = {
18492 + .fl_pid = current->tgid,
18493 + .fl_file = filp,
18494 + .fl_flags = FL_FLOCK,
18495 + .fl_type = F_UNLCK,
18496 + .fl_end = OFFSET_MAX,
18497 + };
18498 +- filp->f_op->flock(filp, F_SETLKW, &fl);
18499 +- if (fl.fl_ops && fl.fl_ops->fl_release_private)
18500 +- fl.fl_ops->fl_release_private(&fl);
18501 ++ filp->f_op->flock(filp, F_SETLKW, &flock);
18502 ++ if (flock.fl_ops && flock.fl_ops->fl_release_private)
18503 ++ flock.fl_ops->fl_release_private(&flock);
18504 + }
18505 +
18506 + lock_kernel();
18507 +diff -urNp linux-2.6.28.8/fs/namei.c linux-2.6.28.8/fs/namei.c
18508 +--- linux-2.6.28.8/fs/namei.c 2009-02-06 16:47:45.000000000 -0500
18509 ++++ linux-2.6.28.8/fs/namei.c 2009-03-07 04:29:14.000000000 -0500
18510 +@@ -633,7 +633,7 @@ static __always_inline int __do_follow_l
18511 + cookie = dentry->d_inode->i_op->follow_link(dentry, nd);
18512 + error = PTR_ERR(cookie);
18513 + if (!IS_ERR(cookie)) {
18514 +- char *s = nd_get_link(nd);
18515 ++ const char *s = nd_get_link(nd);
18516 + error = 0;
18517 + if (s)
18518 + error = __vfs_follow_link(nd, s);
18519 +@@ -664,6 +664,13 @@ static inline int do_follow_link(struct
18520 + err = security_inode_follow_link(path->dentry, nd);
18521 + if (err)
18522 + goto loop;
18523 ++
18524 ++ if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
18525 ++ path->dentry->d_inode, path->dentry, nd->path.mnt)) {
18526 ++ err = -EACCES;
18527 ++ goto loop;
18528 ++ }
18529 ++
18530 + current->link_count++;
18531 + current->total_link_count++;
18532 + nd->depth++;
18533 +@@ -1012,11 +1019,18 @@ return_reval:
18534 + break;
18535 + }
18536 + return_base:
18537 ++ if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt)) {
18538 ++ path_put(&nd->path);
18539 ++ return -ENOENT;
18540 ++ }
18541 + return 0;
18542 + out_dput:
18543 + path_put_conditional(&next, nd);
18544 + break;
18545 + }
18546 ++ if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt))
18547 ++ err = -ENOENT;
18548 ++
18549 + path_put(&nd->path);
18550 + return_err:
18551 + return err;
18552 +@@ -1582,9 +1596,17 @@ static int __open_namei_create(struct na
18553 + int error;
18554 + struct dentry *dir = nd->path.dentry;
18555 +
18556 ++ if (!gr_acl_handle_creat(path->dentry, nd->path.dentry, nd->path.mnt, flag, mode)) {
18557 ++ error = -EACCES;
18558 ++ goto out_unlock_dput;
18559 ++ }
18560 ++
18561 + if (!IS_POSIXACL(dir->d_inode))
18562 + mode &= ~current->fs->umask;
18563 + error = vfs_create(dir->d_inode, path->dentry, mode, nd);
18564 ++ if (!error)
18565 ++ gr_handle_create(path->dentry, nd->path.mnt);
18566 ++out_unlock_dput:
18567 + mutex_unlock(&dir->d_inode->i_mutex);
18568 + dput(nd->path.dentry);
18569 + nd->path.dentry = path->dentry;
18570 +@@ -1665,6 +1687,17 @@ struct file *do_filp_open(int dfd, const
18571 + &nd, flag);
18572 + if (error)
18573 + return ERR_PTR(error);
18574 ++
18575 ++ if (gr_handle_rawio(nd.path.dentry->d_inode)) {
18576 ++ error = -EPERM;
18577 ++ goto exit;
18578 ++ }
18579 ++
18580 ++ if (!gr_acl_handle_open(nd.path.dentry, nd.path.mnt, flag)) {
18581 ++ error = -EACCES;
18582 ++ goto exit;
18583 ++ }
18584 ++
18585 + goto ok;
18586 + }
18587 +
18588 +@@ -1737,6 +1770,20 @@ do_last:
18589 + /*
18590 + * It already exists.
18591 + */
18592 ++
18593 ++ if (gr_handle_rawio(path.dentry->d_inode)) {
18594 ++ error = -EPERM;
18595 ++ goto exit_mutex_unlock;
18596 ++ }
18597 ++ if (!gr_acl_handle_open(path.dentry, nd.path.mnt, flag)) {
18598 ++ error = -EACCES;
18599 ++ goto exit_mutex_unlock;
18600 ++ }
18601 ++ if (gr_handle_fifo(path.dentry, nd.path.mnt, dir, flag, acc_mode)) {
18602 ++ error = -EACCES;
18603 ++ goto exit_mutex_unlock;
18604 ++ }
18605 ++
18606 + mutex_unlock(&dir->d_inode->i_mutex);
18607 + audit_inode(pathname, path.dentry);
18608 +
18609 +@@ -1822,6 +1869,13 @@ do_link:
18610 + error = security_inode_follow_link(path.dentry, &nd);
18611 + if (error)
18612 + goto exit_dput;
18613 ++
18614 ++ if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
18615 ++ path.dentry, nd.path.mnt)) {
18616 ++ error = -EACCES;
18617 ++ goto exit_dput;
18618 ++ }
18619 ++
18620 + error = __do_follow_link(&path, &nd);
18621 + if (error) {
18622 + /* Does someone understand code flow here? Or it is only
18623 +@@ -1994,6 +2048,17 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const
18624 + error = may_mknod(mode);
18625 + if (error)
18626 + goto out_dput;
18627 ++
18628 ++ if (gr_handle_chroot_mknod(dentry, nd.path.mnt, mode)) {
18629 ++ error = -EPERM;
18630 ++ goto out_dput;
18631 ++ }
18632 ++
18633 ++ if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
18634 ++ error = -EACCES;
18635 ++ goto out_dput;
18636 ++ }
18637 ++
18638 + error = mnt_want_write(nd.path.mnt);
18639 + if (error)
18640 + goto out_dput;
18641 +@@ -2010,6 +2075,9 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const
18642 + break;
18643 + }
18644 + mnt_drop_write(nd.path.mnt);
18645 ++
18646 ++ if (!error)
18647 ++ gr_handle_create(dentry, nd.path.mnt);
18648 + out_dput:
18649 + dput(dentry);
18650 + out_unlock:
18651 +@@ -2063,6 +2131,11 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const
18652 + if (IS_ERR(dentry))
18653 + goto out_unlock;
18654 +
18655 ++ if (!gr_acl_handle_mkdir(dentry, nd.path.dentry, nd.path.mnt)) {
18656 ++ error = -EACCES;
18657 ++ goto out_dput;
18658 ++ }
18659 ++
18660 + if (!IS_POSIXACL(nd.path.dentry->d_inode))
18661 + mode &= ~current->fs->umask;
18662 + error = mnt_want_write(nd.path.mnt);
18663 +@@ -2070,6 +2143,10 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const
18664 + goto out_dput;
18665 + error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
18666 + mnt_drop_write(nd.path.mnt);
18667 ++
18668 ++ if (!error)
18669 ++ gr_handle_create(dentry, nd.path.mnt);
18670 ++
18671 + out_dput:
18672 + dput(dentry);
18673 + out_unlock:
18674 +@@ -2151,6 +2228,8 @@ static long do_rmdir(int dfd, const char
18675 + char * name;
18676 + struct dentry *dentry;
18677 + struct nameidata nd;
18678 ++ ino_t saved_ino = 0;
18679 ++ dev_t saved_dev = 0;
18680 +
18681 + error = user_path_parent(dfd, pathname, &nd, &name);
18682 + if (error)
18683 +@@ -2175,11 +2254,26 @@ static long do_rmdir(int dfd, const char
18684 + error = PTR_ERR(dentry);
18685 + if (IS_ERR(dentry))
18686 + goto exit2;
18687 ++
18688 ++ if (dentry->d_inode != NULL) {
18689 ++ if (dentry->d_inode->i_nlink <= 1) {
18690 ++ saved_ino = dentry->d_inode->i_ino;
18691 ++ saved_dev = dentry->d_inode->i_sb->s_dev;
18692 ++ }
18693 ++
18694 ++ if (!gr_acl_handle_rmdir(dentry, nd.path.mnt)) {
18695 ++ error = -EACCES;
18696 ++ goto exit3;
18697 ++ }
18698 ++ }
18699 ++
18700 + error = mnt_want_write(nd.path.mnt);
18701 + if (error)
18702 + goto exit3;
18703 + error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
18704 + mnt_drop_write(nd.path.mnt);
18705 ++ if (!error && (saved_dev || saved_ino))
18706 ++ gr_handle_delete(saved_ino, saved_dev);
18707 + exit3:
18708 + dput(dentry);
18709 + exit2:
18710 +@@ -2239,6 +2333,8 @@ static long do_unlinkat(int dfd, const c
18711 + struct dentry *dentry;
18712 + struct nameidata nd;
18713 + struct inode *inode = NULL;
18714 ++ ino_t saved_ino = 0;
18715 ++ dev_t saved_dev = 0;
18716 +
18717 + error = user_path_parent(dfd, pathname, &nd, &name);
18718 + if (error)
18719 +@@ -2258,12 +2354,25 @@ static long do_unlinkat(int dfd, const c
18720 + if (nd.last.name[nd.last.len])
18721 + goto slashes;
18722 + inode = dentry->d_inode;
18723 +- if (inode)
18724 ++ if (inode) {
18725 ++ if (inode->i_nlink <= 1) {
18726 ++ saved_ino = inode->i_ino;
18727 ++ saved_dev = inode->i_sb->s_dev;
18728 ++ }
18729 ++
18730 + atomic_inc(&inode->i_count);
18731 ++
18732 ++ if (!gr_acl_handle_unlink(dentry, nd.path.mnt)) {
18733 ++ error = -EACCES;
18734 ++ goto exit2;
18735 ++ }
18736 ++ }
18737 + error = mnt_want_write(nd.path.mnt);
18738 + if (error)
18739 + goto exit2;
18740 + error = vfs_unlink(nd.path.dentry->d_inode, dentry);
18741 ++ if (!error && (saved_ino || saved_dev))
18742 ++ gr_handle_delete(saved_ino, saved_dev);
18743 + mnt_drop_write(nd.path.mnt);
18744 + exit2:
18745 + dput(dentry);
18746 +@@ -2341,10 +2450,17 @@ SYSCALL_DEFINE3(symlinkat, const char __
18747 + if (IS_ERR(dentry))
18748 + goto out_unlock;
18749 +
18750 ++ if (!gr_acl_handle_symlink(dentry, nd.path.dentry, nd.path.mnt, from)) {
18751 ++ error = -EACCES;
18752 ++ goto out_dput;
18753 ++ }
18754 ++
18755 + error = mnt_want_write(nd.path.mnt);
18756 + if (error)
18757 + goto out_dput;
18758 + error = vfs_symlink(nd.path.dentry->d_inode, dentry, from);
18759 ++ if (!error)
18760 ++ gr_handle_create(dentry, nd.path.mnt);
18761 + mnt_drop_write(nd.path.mnt);
18762 + out_dput:
18763 + dput(dentry);
18764 +@@ -2437,10 +2553,26 @@ SYSCALL_DEFINE5(linkat, int, olddfd, con
18765 + error = PTR_ERR(new_dentry);
18766 + if (IS_ERR(new_dentry))
18767 + goto out_unlock;
18768 ++
18769 ++ if (gr_handle_hardlink(old_path.dentry, old_path.mnt,
18770 ++ old_path.dentry->d_inode,
18771 ++ old_path.dentry->d_inode->i_mode, to)) {
18772 ++ error = -EACCES;
18773 ++ goto out_dput;
18774 ++ }
18775 ++
18776 ++ if (!gr_acl_handle_link(new_dentry, nd.path.dentry, nd.path.mnt,
18777 ++ old_path.dentry, old_path.mnt, to)) {
18778 ++ error = -EACCES;
18779 ++ goto out_dput;
18780 ++ }
18781 ++
18782 + error = mnt_want_write(nd.path.mnt);
18783 + if (error)
18784 + goto out_dput;
18785 + error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry);
18786 ++ if (!error)
18787 ++ gr_handle_create(new_dentry, nd.path.mnt);
18788 + mnt_drop_write(nd.path.mnt);
18789 + out_dput:
18790 + dput(new_dentry);
18791 +@@ -2673,11 +2805,21 @@ SYSCALL_DEFINE4(renameat, int, olddfd, c
18792 + if (new_dentry == trap)
18793 + goto exit5;
18794 +
18795 ++ error = gr_acl_handle_rename(new_dentry, new_dir, newnd.path.mnt,
18796 ++ old_dentry, old_dir->d_inode, oldnd.path.mnt,
18797 ++ to);
18798 ++ if (error)
18799 ++ goto exit5;
18800 ++
18801 + error = mnt_want_write(oldnd.path.mnt);
18802 + if (error)
18803 + goto exit5;
18804 + error = vfs_rename(old_dir->d_inode, old_dentry,
18805 + new_dir->d_inode, new_dentry);
18806 ++ if (!error)
18807 ++ gr_handle_rename(old_dir->d_inode, new_dir->d_inode, old_dentry,
18808 ++ new_dentry, oldnd.path.mnt, new_dentry->d_inode ? 1 : 0);
18809 ++
18810 + mnt_drop_write(oldnd.path.mnt);
18811 + exit5:
18812 + dput(new_dentry);
18813 +diff -urNp linux-2.6.28.8/fs/namespace.c linux-2.6.28.8/fs/namespace.c
18814 +--- linux-2.6.28.8/fs/namespace.c 2009-02-06 16:47:45.000000000 -0500
18815 ++++ linux-2.6.28.8/fs/namespace.c 2009-02-21 09:37:49.000000000 -0500
18816 +@@ -1094,6 +1094,8 @@ static int do_umount(struct vfsmount *mn
18817 + lock_kernel();
18818 + retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
18819 + unlock_kernel();
18820 ++
18821 ++ gr_log_remount(mnt->mnt_devname, retval);
18822 + }
18823 + up_write(&sb->s_umount);
18824 + return retval;
18825 +@@ -1117,6 +1119,9 @@ static int do_umount(struct vfsmount *mn
18826 + security_sb_umount_busy(mnt);
18827 + up_write(&namespace_sem);
18828 + release_mounts(&umount_list);
18829 ++
18830 ++ gr_log_unmount(mnt->mnt_devname, retval);
18831 ++
18832 + return retval;
18833 + }
18834 +
18835 +@@ -1946,6 +1951,11 @@ long do_mount(char *dev_name, char *dir_
18836 + if (retval)
18837 + goto dput_out;
18838 +
18839 ++ if (gr_handle_chroot_mount(path.dentry, path.mnt, dev_name)) {
18840 ++ retval = -EPERM;
18841 ++ goto dput_out;
18842 ++ }
18843 ++
18844 + if (flags & MS_REMOUNT)
18845 + retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags,
18846 + data_page);
18847 +@@ -1960,6 +1970,9 @@ long do_mount(char *dev_name, char *dir_
18848 + dev_name, data_page);
18849 + dput_out:
18850 + path_put(&path);
18851 ++
18852 ++ gr_log_mount(dev_name, dir_name, retval);
18853 ++
18854 + return retval;
18855 + }
18856 +
18857 +@@ -2071,6 +2084,9 @@ SYSCALL_DEFINE5(mount, char __user *, de
18858 + if (retval < 0)
18859 + goto out3;
18860 +
18861 ++ if (gr_handle_chroot_pivot())
18862 ++ return -EPERM;
18863 ++
18864 + lock_kernel();
18865 + retval = do_mount((char *)dev_page, dir_page, (char *)type_page,
18866 + flags, (void *)data_page);
18867 +diff -urNp linux-2.6.28.8/fs/nfs/nfs4proc.c linux-2.6.28.8/fs/nfs/nfs4proc.c
18868 +--- linux-2.6.28.8/fs/nfs/nfs4proc.c 2009-02-06 16:47:45.000000000 -0500
18869 ++++ linux-2.6.28.8/fs/nfs/nfs4proc.c 2009-02-21 09:37:49.000000000 -0500
18870 +@@ -653,7 +653,7 @@ static int _nfs4_do_open_reclaim(struct
18871 + static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
18872 + {
18873 + struct nfs_server *server = NFS_SERVER(state->inode);
18874 +- struct nfs4_exception exception = { };
18875 ++ struct nfs4_exception exception = {0, 0};
18876 + int err;
18877 + do {
18878 + err = _nfs4_do_open_reclaim(ctx, state);
18879 +@@ -695,7 +695,7 @@ static int _nfs4_open_delegation_recall(
18880 +
18881 + int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
18882 + {
18883 +- struct nfs4_exception exception = { };
18884 ++ struct nfs4_exception exception = {0, 0};
18885 + struct nfs_server *server = NFS_SERVER(state->inode);
18886 + int err;
18887 + do {
18888 +@@ -988,7 +988,7 @@ static int _nfs4_open_expired(struct nfs
18889 + static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
18890 + {
18891 + struct nfs_server *server = NFS_SERVER(state->inode);
18892 +- struct nfs4_exception exception = { };
18893 ++ struct nfs4_exception exception = {0, 0};
18894 + int err;
18895 +
18896 + do {
18897 +@@ -1090,7 +1090,7 @@ out_err:
18898 +
18899 + static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred)
18900 + {
18901 +- struct nfs4_exception exception = { };
18902 ++ struct nfs4_exception exception = {0, 0};
18903 + struct nfs4_state *res;
18904 + int status;
18905 +
18906 +@@ -1181,7 +1181,7 @@ static int nfs4_do_setattr(struct inode
18907 + struct nfs4_state *state)
18908 + {
18909 + struct nfs_server *server = NFS_SERVER(inode);
18910 +- struct nfs4_exception exception = { };
18911 ++ struct nfs4_exception exception = {0, 0};
18912 + int err;
18913 + do {
18914 + err = nfs4_handle_exception(server,
18915 +@@ -1494,7 +1494,7 @@ static int _nfs4_server_capabilities(str
18916 +
18917 + int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
18918 + {
18919 +- struct nfs4_exception exception = { };
18920 ++ struct nfs4_exception exception = {0, 0};
18921 + int err;
18922 + do {
18923 + err = nfs4_handle_exception(server,
18924 +@@ -1527,7 +1527,7 @@ static int _nfs4_lookup_root(struct nfs_
18925 + static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
18926 + struct nfs_fsinfo *info)
18927 + {
18928 +- struct nfs4_exception exception = { };
18929 ++ struct nfs4_exception exception = {0, 0};
18930 + int err;
18931 + do {
18932 + err = nfs4_handle_exception(server,
18933 +@@ -1616,7 +1616,7 @@ static int _nfs4_proc_getattr(struct nfs
18934 +
18935 + static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
18936 + {
18937 +- struct nfs4_exception exception = { };
18938 ++ struct nfs4_exception exception = {0, 0};
18939 + int err;
18940 + do {
18941 + err = nfs4_handle_exception(server,
18942 +@@ -1704,7 +1704,7 @@ static int nfs4_proc_lookupfh(struct nfs
18943 + struct qstr *name, struct nfs_fh *fhandle,
18944 + struct nfs_fattr *fattr)
18945 + {
18946 +- struct nfs4_exception exception = { };
18947 ++ struct nfs4_exception exception = {0, 0};
18948 + int err;
18949 + do {
18950 + err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr);
18951 +@@ -1733,7 +1733,7 @@ static int _nfs4_proc_lookup(struct inod
18952 +
18953 + static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
18954 + {
18955 +- struct nfs4_exception exception = { };
18956 ++ struct nfs4_exception exception = {0, 0};
18957 + int err;
18958 + do {
18959 + err = nfs4_handle_exception(NFS_SERVER(dir),
18960 +@@ -1797,7 +1797,7 @@ static int _nfs4_proc_access(struct inod
18961 +
18962 + static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
18963 + {
18964 +- struct nfs4_exception exception = { };
18965 ++ struct nfs4_exception exception = {0, 0};
18966 + int err;
18967 + do {
18968 + err = nfs4_handle_exception(NFS_SERVER(inode),
18969 +@@ -1852,7 +1852,7 @@ static int _nfs4_proc_readlink(struct in
18970 + static int nfs4_proc_readlink(struct inode *inode, struct page *page,
18971 + unsigned int pgbase, unsigned int pglen)
18972 + {
18973 +- struct nfs4_exception exception = { };
18974 ++ struct nfs4_exception exception = {0, 0};
18975 + int err;
18976 + do {
18977 + err = nfs4_handle_exception(NFS_SERVER(inode),
18978 +@@ -1949,7 +1949,7 @@ static int _nfs4_proc_remove(struct inod
18979 +
18980 + static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
18981 + {
18982 +- struct nfs4_exception exception = { };
18983 ++ struct nfs4_exception exception = {0, 0};
18984 + int err;
18985 + do {
18986 + err = nfs4_handle_exception(NFS_SERVER(dir),
18987 +@@ -2021,7 +2021,7 @@ static int _nfs4_proc_rename(struct inod
18988 + static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
18989 + struct inode *new_dir, struct qstr *new_name)
18990 + {
18991 +- struct nfs4_exception exception = { };
18992 ++ struct nfs4_exception exception = {0, 0};
18993 + int err;
18994 + do {
18995 + err = nfs4_handle_exception(NFS_SERVER(old_dir),
18996 +@@ -2068,7 +2068,7 @@ static int _nfs4_proc_link(struct inode
18997 +
18998 + static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
18999 + {
19000 +- struct nfs4_exception exception = { };
19001 ++ struct nfs4_exception exception = {0, 0};
19002 + int err;
19003 + do {
19004 + err = nfs4_handle_exception(NFS_SERVER(inode),
19005 +@@ -2159,7 +2159,7 @@ out:
19006 + static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
19007 + struct page *page, unsigned int len, struct iattr *sattr)
19008 + {
19009 +- struct nfs4_exception exception = { };
19010 ++ struct nfs4_exception exception = {0, 0};
19011 + int err;
19012 + do {
19013 + err = nfs4_handle_exception(NFS_SERVER(dir),
19014 +@@ -2190,7 +2190,7 @@ out:
19015 + static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
19016 + struct iattr *sattr)
19017 + {
19018 +- struct nfs4_exception exception = { };
19019 ++ struct nfs4_exception exception = {0, 0};
19020 + int err;
19021 + do {
19022 + err = nfs4_handle_exception(NFS_SERVER(dir),
19023 +@@ -2239,7 +2239,7 @@ static int _nfs4_proc_readdir(struct den
19024 + static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
19025 + u64 cookie, struct page *page, unsigned int count, int plus)
19026 + {
19027 +- struct nfs4_exception exception = { };
19028 ++ struct nfs4_exception exception = {0, 0};
19029 + int err;
19030 + do {
19031 + err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode),
19032 +@@ -2287,7 +2287,7 @@ out:
19033 + static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
19034 + struct iattr *sattr, dev_t rdev)
19035 + {
19036 +- struct nfs4_exception exception = { };
19037 ++ struct nfs4_exception exception = {0, 0};
19038 + int err;
19039 + do {
19040 + err = nfs4_handle_exception(NFS_SERVER(dir),
19041 +@@ -2316,7 +2316,7 @@ static int _nfs4_proc_statfs(struct nfs_
19042 +
19043 + static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
19044 + {
19045 +- struct nfs4_exception exception = { };
19046 ++ struct nfs4_exception exception = {0, 0};
19047 + int err;
19048 + do {
19049 + err = nfs4_handle_exception(server,
19050 +@@ -2344,7 +2344,7 @@ static int _nfs4_do_fsinfo(struct nfs_se
19051 +
19052 + static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
19053 + {
19054 +- struct nfs4_exception exception = { };
19055 ++ struct nfs4_exception exception = {0, 0};
19056 + int err;
19057 +
19058 + do {
19059 +@@ -2387,7 +2387,7 @@ static int _nfs4_proc_pathconf(struct nf
19060 + static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
19061 + struct nfs_pathconf *pathconf)
19062 + {
19063 +- struct nfs4_exception exception = { };
19064 ++ struct nfs4_exception exception = {0, 0};
19065 + int err;
19066 +
19067 + do {
19068 +@@ -2674,7 +2674,7 @@ out_free:
19069 +
19070 + static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
19071 + {
19072 +- struct nfs4_exception exception = { };
19073 ++ struct nfs4_exception exception = {0, 0};
19074 + ssize_t ret;
19075 + do {
19076 + ret = __nfs4_get_acl_uncached(inode, buf, buflen);
19077 +@@ -2731,7 +2731,7 @@ static int __nfs4_proc_set_acl(struct in
19078 +
19079 + static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
19080 + {
19081 +- struct nfs4_exception exception = { };
19082 ++ struct nfs4_exception exception = {0, 0};
19083 + int err;
19084 + do {
19085 + err = nfs4_handle_exception(NFS_SERVER(inode),
19086 +@@ -3022,7 +3022,7 @@ out:
19087 + int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync)
19088 + {
19089 + struct nfs_server *server = NFS_SERVER(inode);
19090 +- struct nfs4_exception exception = { };
19091 ++ struct nfs4_exception exception = {0, 0};
19092 + int err;
19093 + do {
19094 + err = _nfs4_proc_delegreturn(inode, cred, stateid, issync);
19095 +@@ -3097,7 +3097,7 @@ out:
19096 +
19097 + static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
19098 + {
19099 +- struct nfs4_exception exception = { };
19100 ++ struct nfs4_exception exception = {0, 0};
19101 + int err;
19102 +
19103 + do {
19104 +@@ -3447,7 +3447,7 @@ static int _nfs4_do_setlk(struct nfs4_st
19105 + static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
19106 + {
19107 + struct nfs_server *server = NFS_SERVER(state->inode);
19108 +- struct nfs4_exception exception = { };
19109 ++ struct nfs4_exception exception = {0, 0};
19110 + int err;
19111 +
19112 + do {
19113 +@@ -3465,7 +3465,7 @@ static int nfs4_lock_reclaim(struct nfs4
19114 + static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
19115 + {
19116 + struct nfs_server *server = NFS_SERVER(state->inode);
19117 +- struct nfs4_exception exception = { };
19118 ++ struct nfs4_exception exception = {0, 0};
19119 + int err;
19120 +
19121 + err = nfs4_set_lock_state(state, request);
19122 +@@ -3526,7 +3526,7 @@ out:
19123 +
19124 + static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
19125 + {
19126 +- struct nfs4_exception exception = { };
19127 ++ struct nfs4_exception exception = {0, 0};
19128 + int err;
19129 +
19130 + do {
19131 +@@ -3576,7 +3576,7 @@ nfs4_proc_lock(struct file *filp, int cm
19132 + int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
19133 + {
19134 + struct nfs_server *server = NFS_SERVER(state->inode);
19135 +- struct nfs4_exception exception = { };
19136 ++ struct nfs4_exception exception = {0, 0};
19137 + int err;
19138 +
19139 + err = nfs4_set_lock_state(state, fl);
19140 +diff -urNp linux-2.6.28.8/fs/nfsd/export.c linux-2.6.28.8/fs/nfsd/export.c
19141 +--- linux-2.6.28.8/fs/nfsd/export.c 2009-02-06 16:47:45.000000000 -0500
19142 ++++ linux-2.6.28.8/fs/nfsd/export.c 2009-02-21 09:37:49.000000000 -0500
19143 +@@ -472,7 +472,7 @@ static int secinfo_parse(char **mesg, ch
19144 + * probably discover the problem when someone fails to
19145 + * authenticate.
19146 + */
19147 +- if (f->pseudoflavor < 0)
19148 ++ if ((s32)f->pseudoflavor < 0)
19149 + return -EINVAL;
19150 + err = get_int(mesg, &f->flags);
19151 + if (err)
19152 +diff -urNp linux-2.6.28.8/fs/nls/nls_base.c linux-2.6.28.8/fs/nls/nls_base.c
19153 +--- linux-2.6.28.8/fs/nls/nls_base.c 2009-02-06 16:47:45.000000000 -0500
19154 ++++ linux-2.6.28.8/fs/nls/nls_base.c 2009-02-21 09:37:49.000000000 -0500
19155 +@@ -40,7 +40,7 @@ static const struct utf8_table utf8_tabl
19156 + {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */},
19157 + {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */},
19158 + {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */},
19159 +- {0, /* end of table */}
19160 ++ {0, 0, 0, 0, 0, /* end of table */}
19161 + };
19162 +
19163 + int
19164 +diff -urNp linux-2.6.28.8/fs/ntfs/file.c linux-2.6.28.8/fs/ntfs/file.c
19165 +--- linux-2.6.28.8/fs/ntfs/file.c 2009-02-06 16:47:45.000000000 -0500
19166 ++++ linux-2.6.28.8/fs/ntfs/file.c 2009-02-21 09:37:49.000000000 -0500
19167 +@@ -2291,6 +2291,6 @@ const struct inode_operations ntfs_file_
19168 + #endif /* NTFS_RW */
19169 + };
19170 +
19171 +-const struct file_operations ntfs_empty_file_ops = {};
19172 ++const struct file_operations ntfs_empty_file_ops;
19173 +
19174 +-const struct inode_operations ntfs_empty_inode_ops = {};
19175 ++const struct inode_operations ntfs_empty_inode_ops;
19176 +diff -urNp linux-2.6.28.8/fs/open.c linux-2.6.28.8/fs/open.c
19177 +--- linux-2.6.28.8/fs/open.c 2009-02-06 16:47:45.000000000 -0500
19178 ++++ linux-2.6.28.8/fs/open.c 2009-02-21 09:37:49.000000000 -0500
19179 +@@ -205,6 +205,9 @@ int do_truncate(struct dentry *dentry, l
19180 + if (length < 0)
19181 + return -EINVAL;
19182 +
19183 ++ if (filp && !gr_acl_handle_truncate(dentry, filp->f_path.mnt))
19184 ++ return -EACCES;
19185 ++
19186 + newattrs.ia_size = length;
19187 + newattrs.ia_valid = ATTR_SIZE | time_attrs;
19188 + if (filp) {
19189 +@@ -510,6 +513,9 @@ SYSCALL_DEFINE3(faccessat, int, dfd, con
19190 + if (__mnt_is_readonly(path.mnt))
19191 + res = -EROFS;
19192 +
19193 ++ if (!res && !gr_acl_handle_access(path.dentry, path.mnt, mode))
19194 ++ res = -EACCES;
19195 ++
19196 + out_path_release:
19197 + path_put(&path);
19198 + out:
19199 +@@ -540,6 +546,8 @@ SYSCALL_DEFINE1(chdir, const char __user
19200 + if (error)
19201 + goto dput_and_out;
19202 +
19203 ++ gr_log_chdir(path.dentry, path.mnt);
19204 ++
19205 + set_fs_pwd(current->fs, &path);
19206 +
19207 + dput_and_out:
19208 +@@ -566,6 +574,13 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd
19209 + goto out_putf;
19210 +
19211 + error = inode_permission(inode, MAY_EXEC | MAY_ACCESS);
19212 ++
19213 ++ if (!error && !gr_chroot_fchdir(file->f_path.dentry, file->f_path.mnt))
19214 ++ error = -EPERM;
19215 ++
19216 ++ if (!error)
19217 ++ gr_log_chdir(file->f_path.dentry, file->f_path.mnt);
19218 ++
19219 + if (!error)
19220 + set_fs_pwd(current->fs, &file->f_path);
19221 + out_putf:
19222 +@@ -591,7 +606,14 @@ SYSCALL_DEFINE1(chroot, const char __use
19223 + if (!capable(CAP_SYS_CHROOT))
19224 + goto dput_and_out;
19225 +
19226 ++ if (gr_handle_chroot_chroot(path.dentry, path.mnt))
19227 ++ goto dput_and_out;
19228 ++
19229 + set_fs_root(current->fs, &path);
19230 ++
19231 ++ gr_handle_chroot_caps(current);
19232 ++ gr_handle_chroot_chdir(&path);
19233 ++
19234 + error = 0;
19235 + dput_and_out:
19236 + path_put(&path);
19237 +@@ -619,13 +641,28 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd
19238 + err = mnt_want_write(file->f_path.mnt);
19239 + if (err)
19240 + goto out_putf;
19241 ++
19242 ++ if (!gr_acl_handle_fchmod(dentry, file->f_path.mnt, mode)) {
19243 ++ err = -EACCES;
19244 ++ goto out_drop_write;
19245 ++ }
19246 ++
19247 + mutex_lock(&inode->i_mutex);
19248 + if (mode == (mode_t) -1)
19249 + mode = inode->i_mode;
19250 ++
19251 ++ if (gr_handle_chroot_chmod(dentry, file->f_path.mnt, mode)) {
19252 ++ err = -EPERM;
19253 ++ mutex_unlock(&inode->i_mutex);
19254 ++ goto out_drop_write;
19255 ++ }
19256 ++
19257 + newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
19258 + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
19259 + err = notify_change(dentry, &newattrs);
19260 + mutex_unlock(&inode->i_mutex);
19261 ++
19262 ++out_drop_write:
19263 + mnt_drop_write(file->f_path.mnt);
19264 + out_putf:
19265 + fput(file);
19266 +@@ -648,13 +685,28 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, cons
19267 + error = mnt_want_write(path.mnt);
19268 + if (error)
19269 + goto dput_and_out;
19270 ++
19271 ++ if (!gr_acl_handle_chmod(path.dentry, path.mnt, mode)) {
19272 ++ error = -EACCES;
19273 ++ goto out_drop_write;
19274 ++ }
19275 ++
19276 + mutex_lock(&inode->i_mutex);
19277 + if (mode == (mode_t) -1)
19278 + mode = inode->i_mode;
19279 ++
19280 ++ if (gr_handle_chroot_chmod(path.dentry, path.mnt, mode)) {
19281 ++ error = -EACCES;
19282 ++ mutex_unlock(&inode->i_mutex);
19283 ++ goto out_drop_write;
19284 ++ }
19285 ++
19286 + newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
19287 + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
19288 + error = notify_change(path.dentry, &newattrs);
19289 + mutex_unlock(&inode->i_mutex);
19290 ++
19291 ++out_drop_write:
19292 + mnt_drop_write(path.mnt);
19293 + dput_and_out:
19294 + path_put(&path);
19295 +@@ -667,12 +719,15 @@ SYSCALL_DEFINE2(chmod, const char __user
19296 + return sys_fchmodat(AT_FDCWD, filename, mode);
19297 + }
19298 +
19299 +-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
19300 ++static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
19301 + {
19302 + struct inode *inode = dentry->d_inode;
19303 + int error;
19304 + struct iattr newattrs;
19305 +
19306 ++ if (!gr_acl_handle_chown(dentry, mnt))
19307 ++ return -EACCES;
19308 ++
19309 + newattrs.ia_valid = ATTR_CTIME;
19310 + if (user != (uid_t) -1) {
19311 + newattrs.ia_valid |= ATTR_UID;
19312 +@@ -703,7 +758,7 @@ SYSCALL_DEFINE3(chown, const char __user
19313 + error = mnt_want_write(path.mnt);
19314 + if (error)
19315 + goto out_release;
19316 +- error = chown_common(path.dentry, user, group);
19317 ++ error = chown_common(path.dentry, user, group, path.mnt);
19318 + mnt_drop_write(path.mnt);
19319 + out_release:
19320 + path_put(&path);
19321 +@@ -728,7 +783,7 @@ SYSCALL_DEFINE5(fchownat, int, dfd, cons
19322 + error = mnt_want_write(path.mnt);
19323 + if (error)
19324 + goto out_release;
19325 +- error = chown_common(path.dentry, user, group);
19326 ++ error = chown_common(path.dentry, user, group, path.mnt);
19327 + mnt_drop_write(path.mnt);
19328 + out_release:
19329 + path_put(&path);
19330 +@@ -747,7 +802,7 @@ SYSCALL_DEFINE3(lchown, const char __use
19331 + error = mnt_want_write(path.mnt);
19332 + if (error)
19333 + goto out_release;
19334 +- error = chown_common(path.dentry, user, group);
19335 ++ error = chown_common(path.dentry, user, group, path.mnt);
19336 + mnt_drop_write(path.mnt);
19337 + out_release:
19338 + path_put(&path);
19339 +@@ -770,7 +825,7 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd
19340 + goto out_fput;
19341 + dentry = file->f_path.dentry;
19342 + audit_inode(NULL, dentry);
19343 +- error = chown_common(dentry, user, group);
19344 ++ error = chown_common(dentry, user, group, file->f_path.mnt);
19345 + mnt_drop_write(file->f_path.mnt);
19346 + out_fput:
19347 + fput(file);
19348 +diff -urNp linux-2.6.28.8/fs/pipe.c linux-2.6.28.8/fs/pipe.c
19349 +--- linux-2.6.28.8/fs/pipe.c 2009-03-07 10:24:49.000000000 -0500
19350 ++++ linux-2.6.28.8/fs/pipe.c 2009-03-07 14:13:22.000000000 -0500
19351 +@@ -848,7 +848,7 @@ void free_pipe_info(struct inode *inode)
19352 + inode->i_pipe = NULL;
19353 + }
19354 +
19355 +-static struct vfsmount *pipe_mnt __read_mostly;
19356 ++struct vfsmount *pipe_mnt __read_mostly;
19357 + static int pipefs_delete_dentry(struct dentry *dentry)
19358 + {
19359 + /*
19360 +diff -urNp linux-2.6.28.8/fs/proc/array.c linux-2.6.28.8/fs/proc/array.c
19361 +--- linux-2.6.28.8/fs/proc/array.c 2009-02-06 16:47:45.000000000 -0500
19362 ++++ linux-2.6.28.8/fs/proc/array.c 2009-02-21 09:37:49.000000000 -0500
19363 +@@ -308,6 +308,21 @@ static inline void task_context_switch_c
19364 + p->nivcsw);
19365 + }
19366 +
19367 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
19368 ++static inline void task_pax(struct seq_file *m, struct task_struct *p)
19369 ++{
19370 ++ if (p->mm)
19371 ++ seq_printf(m, "PaX:\t%c%c%c%c%c\n",
19372 ++ p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
19373 ++ p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
19374 ++ p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
19375 ++ p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
19376 ++ p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
19377 ++ else
19378 ++ seq_printf(m, "PaX:\t-----\n");
19379 ++}
19380 ++#endif
19381 ++
19382 + int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
19383 + struct pid *pid, struct task_struct *task)
19384 + {
19385 +@@ -327,9 +342,20 @@ int proc_pid_status(struct seq_file *m,
19386 + task_show_regs(m, task);
19387 + #endif
19388 + task_context_switch_counts(m, task);
19389 ++
19390 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
19391 ++ task_pax(m, task);
19392 ++#endif
19393 ++
19394 + return 0;
19395 + }
19396 +
19397 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19398 ++#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
19399 ++ (_mm->pax_flags & MF_PAX_RANDMMAP || \
19400 ++ _mm->pax_flags & MF_PAX_SEGMEXEC))
19401 ++#endif
19402 ++
19403 + static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
19404 + struct pid *pid, struct task_struct *task, int whole)
19405 + {
19406 +@@ -422,6 +448,19 @@ static int do_task_stat(struct seq_file
19407 + gtime = task_gtime(task);
19408 + }
19409 +
19410 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19411 ++ if (PAX_RAND_FLAGS(mm)) {
19412 ++ eip = 0;
19413 ++ esp = 0;
19414 ++ wchan = 0;
19415 ++ }
19416 ++#endif
19417 ++#ifdef CONFIG_GRKERNSEC_HIDESYM
19418 ++ wchan = 0;
19419 ++ eip =0;
19420 ++ esp =0;
19421 ++#endif
19422 ++
19423 + /* scale priority and nice values from timeslices to -20..20 */
19424 + /* to make it look like a "normal" Unix priority/nice value */
19425 + priority = task_prio(task);
19426 +@@ -462,9 +501,15 @@ static int do_task_stat(struct seq_file
19427 + vsize,
19428 + mm ? get_mm_rss(mm) : 0,
19429 + rsslim,
19430 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19431 ++ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
19432 ++ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
19433 ++ PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0),
19434 ++#else
19435 + mm ? mm->start_code : 0,
19436 + mm ? mm->end_code : 0,
19437 + mm ? mm->start_stack : 0,
19438 ++#endif
19439 + esp,
19440 + eip,
19441 + /* The signal information here is obsolete.
19442 +@@ -517,3 +562,10 @@ int proc_pid_statm(struct seq_file *m, s
19443 +
19444 + return 0;
19445 + }
19446 ++
19447 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
19448 ++int proc_pid_ipaddr(struct task_struct *task, char *buffer)
19449 ++{
19450 ++ return sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
19451 ++}
19452 ++#endif
19453 +diff -urNp linux-2.6.28.8/fs/proc/base.c linux-2.6.28.8/fs/proc/base.c
19454 +--- linux-2.6.28.8/fs/proc/base.c 2009-02-06 16:47:45.000000000 -0500
19455 ++++ linux-2.6.28.8/fs/proc/base.c 2009-03-07 05:50:38.000000000 -0500
19456 +@@ -225,6 +225,9 @@ static int check_mem_permission(struct t
19457 + if (task == current)
19458 + return 0;
19459 +
19460 ++ if (gr_handle_proc_ptrace(task) || gr_acl_handle_procpidmem(task))
19461 ++ return -EPERM;
19462 ++
19463 + /*
19464 + * If current is actively ptrace'ing, and would also be
19465 + * permitted to freshly attach with ptrace now, permit it.
19466 +@@ -302,15 +305,29 @@ out:
19467 + return res;
19468 + }
19469 +
19470 +-static int proc_pid_auxv(struct task_struct *task, char *buffer)
19471 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19472 ++#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
19473 ++ (_mm->pax_flags & MF_PAX_RANDMMAP || \
19474 ++ _mm->pax_flags & MF_PAX_SEGMEXEC))
19475 ++#endif
19476 ++
19477 ++static
19478 ++int proc_pid_auxv(struct task_struct *task, char *buffer)
19479 + {
19480 + int res = 0;
19481 + struct mm_struct *mm = get_task_mm(task);
19482 + if (mm) {
19483 + unsigned int nwords = 0;
19484 +- do
19485 ++
19486 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19487 ++ if (PAX_RAND_FLAGS(mm)) {
19488 ++ mmput(mm);
19489 ++ return res;
19490 ++ }
19491 ++#endif
19492 ++ do {
19493 + nwords += 2;
19494 +- while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
19495 ++ } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
19496 + res = nwords * sizeof(mm->saved_auxv[0]);
19497 + if (res > PAGE_SIZE)
19498 + res = PAGE_SIZE;
19499 +@@ -502,7 +519,7 @@ static int proc_pid_limits(struct task_s
19500 + return count;
19501 + }
19502 +
19503 +-#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
19504 ++#if defined(CONFIG_HAVE_ARCH_TRACEHOOK) && !defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
19505 + static int proc_pid_syscall(struct task_struct *task, char *buffer)
19506 + {
19507 + long nr;
19508 +@@ -1429,7 +1446,11 @@ static struct inode *proc_pid_make_inode
19509 + inode->i_gid = 0;
19510 + if (task_dumpable(task)) {
19511 + inode->i_uid = task->euid;
19512 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
19513 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
19514 ++#else
19515 + inode->i_gid = task->egid;
19516 ++#endif
19517 + }
19518 + security_task_to_inode(task, inode);
19519 +
19520 +@@ -1445,17 +1466,45 @@ static int pid_getattr(struct vfsmount *
19521 + {
19522 + struct inode *inode = dentry->d_inode;
19523 + struct task_struct *task;
19524 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19525 ++ struct task_struct *tmp = current;
19526 ++#endif
19527 ++
19528 + generic_fillattr(inode, stat);
19529 +
19530 + rcu_read_lock();
19531 + stat->uid = 0;
19532 + stat->gid = 0;
19533 + task = pid_task(proc_pid(inode), PIDTYPE_PID);
19534 +- if (task) {
19535 ++
19536 ++ if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) {
19537 ++ rcu_read_unlock();
19538 ++ return -ENOENT;
19539 ++ }
19540 ++
19541 ++
19542 ++ if (task
19543 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19544 ++ && (!tmp->uid || (tmp->uid == task->uid)
19545 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
19546 ++ || in_group_p(CONFIG_GRKERNSEC_PROC_GID)
19547 ++#endif
19548 ++ )
19549 ++#endif
19550 ++ ) {
19551 + if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
19552 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
19553 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
19554 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19555 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
19556 ++#endif
19557 + task_dumpable(task)) {
19558 + stat->uid = task->euid;
19559 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
19560 ++ stat->gid = CONFIG_GRKERNSEC_PROC_GID;
19561 ++#else
19562 + stat->gid = task->egid;
19563 ++#endif
19564 + }
19565 + }
19566 + rcu_read_unlock();
19567 +@@ -1483,11 +1532,21 @@ static int pid_revalidate(struct dentry
19568 + {
19569 + struct inode *inode = dentry->d_inode;
19570 + struct task_struct *task = get_proc_task(inode);
19571 ++
19572 + if (task) {
19573 + if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
19574 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
19575 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
19576 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19577 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
19578 ++#endif
19579 + task_dumpable(task)) {
19580 + inode->i_uid = task->euid;
19581 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
19582 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
19583 ++#else
19584 + inode->i_gid = task->egid;
19585 ++#endif
19586 + } else {
19587 + inode->i_uid = 0;
19588 + inode->i_gid = 0;
19589 +@@ -1855,12 +1914,22 @@ static const struct file_operations proc
19590 + static int proc_fd_permission(struct inode *inode, int mask)
19591 + {
19592 + int rv;
19593 ++ struct task_struct *task;
19594 +
19595 + rv = generic_permission(inode, mask, NULL);
19596 +- if (rv == 0)
19597 +- return 0;
19598 ++
19599 + if (task_pid(current) == proc_pid(inode))
19600 + rv = 0;
19601 ++
19602 ++ task = get_proc_task(inode);
19603 ++ if (task == NULL)
19604 ++ return rv;
19605 ++
19606 ++ if (gr_acl_handle_procpidmem(task))
19607 ++ rv = -EACCES;
19608 ++
19609 ++ put_task_struct(task);
19610 ++
19611 + return rv;
19612 + }
19613 +
19614 +@@ -1971,6 +2040,9 @@ static struct dentry *proc_pident_lookup
19615 + if (!task)
19616 + goto out_no_task;
19617 +
19618 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
19619 ++ goto out;
19620 ++
19621 + /*
19622 + * Yes, it does not scale. And it should not. Don't add
19623 + * new entries into /proc/<tgid>/ without very good reasons.
19624 +@@ -2015,6 +2087,9 @@ static int proc_pident_readdir(struct fi
19625 + if (!task)
19626 + goto out_no_task;
19627 +
19628 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
19629 ++ goto out;
19630 ++
19631 + ret = 0;
19632 + i = filp->f_pos;
19633 + switch (i) {
19634 +@@ -2377,6 +2452,9 @@ static struct dentry *proc_base_lookup(s
19635 + if (p > last)
19636 + goto out;
19637 +
19638 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
19639 ++ goto out;
19640 ++
19641 + error = proc_base_instantiate(dir, dentry, task, p);
19642 +
19643 + out:
19644 +@@ -2463,7 +2541,7 @@ static const struct pid_entry tgid_base_
19645 + #ifdef CONFIG_SCHED_DEBUG
19646 + REG("sched", S_IRUGO|S_IWUSR, pid_sched),
19647 + #endif
19648 +-#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
19649 ++#if defined(CONFIG_HAVE_ARCH_TRACEHOOK) && !defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
19650 + INF("syscall", S_IRUSR, pid_syscall),
19651 + #endif
19652 + INF("cmdline", S_IRUGO, pid_cmdline),
19653 +@@ -2518,6 +2596,9 @@ static const struct pid_entry tgid_base_
19654 + #ifdef CONFIG_TASK_IO_ACCOUNTING
19655 + INF("io", S_IRUGO, tgid_io_accounting),
19656 + #endif
19657 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
19658 ++ INF("ipaddr", S_IRUSR, pid_ipaddr),
19659 ++#endif
19660 + };
19661 +
19662 + static int proc_tgid_base_readdir(struct file * filp,
19663 +@@ -2647,7 +2728,14 @@ static struct dentry *proc_pid_instantia
19664 + if (!inode)
19665 + goto out;
19666 +
19667 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
19668 ++ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
19669 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19670 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
19671 ++ inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP;
19672 ++#else
19673 + inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
19674 ++#endif
19675 + inode->i_op = &proc_tgid_base_inode_operations;
19676 + inode->i_fop = &proc_tgid_base_operations;
19677 + inode->i_flags|=S_IMMUTABLE;
19678 +@@ -2689,7 +2777,11 @@ struct dentry *proc_pid_lookup(struct in
19679 + if (!task)
19680 + goto out;
19681 +
19682 ++ if (gr_check_hidden_task(task))
19683 ++ goto out_put_task;
19684 ++
19685 + result = proc_pid_instantiate(dir, dentry, task, NULL);
19686 ++out_put_task:
19687 + put_task_struct(task);
19688 + out:
19689 + return result;
19690 +@@ -2754,6 +2846,9 @@ int proc_pid_readdir(struct file * filp,
19691 + {
19692 + unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
19693 + struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode);
19694 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19695 ++ struct task_struct *tmp = current;
19696 ++#endif
19697 + struct tgid_iter iter;
19698 + struct pid_namespace *ns;
19699 +
19700 +@@ -2772,6 +2867,17 @@ int proc_pid_readdir(struct file * filp,
19701 + for (iter = next_tgid(ns, iter);
19702 + iter.task;
19703 + iter.tgid += 1, iter = next_tgid(ns, iter)) {
19704 ++ if (gr_pid_is_chrooted(iter.task) || gr_check_hidden_task(iter.task)
19705 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19706 ++ || (tmp->uid && (iter.task->uid != tmp->uid)
19707 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
19708 ++ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
19709 ++#endif
19710 ++ )
19711 ++#endif
19712 ++ )
19713 ++ continue;
19714 ++
19715 + filp->f_pos = iter.tgid + TGID_OFFSET;
19716 + if (proc_pid_fill_cache(filp, dirent, filldir, iter) < 0) {
19717 + put_task_struct(iter.task);
19718 +@@ -2799,7 +2905,7 @@ static const struct pid_entry tid_base_s
19719 + #ifdef CONFIG_SCHED_DEBUG
19720 + REG("sched", S_IRUGO|S_IWUSR, pid_sched),
19721 + #endif
19722 +-#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
19723 ++#if defined(CONFIG_HAVE_ARCH_TRACEHOOK) && !defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
19724 + INF("syscall", S_IRUSR, pid_syscall),
19725 + #endif
19726 + INF("cmdline", S_IRUGO, pid_cmdline),
19727 +diff -urNp linux-2.6.28.8/fs/proc/cmdline.c linux-2.6.28.8/fs/proc/cmdline.c
19728 +--- linux-2.6.28.8/fs/proc/cmdline.c 2009-02-06 16:47:45.000000000 -0500
19729 ++++ linux-2.6.28.8/fs/proc/cmdline.c 2009-02-21 09:37:49.000000000 -0500
19730 +@@ -23,7 +23,11 @@ static const struct file_operations cmdl
19731 +
19732 + static int __init proc_cmdline_init(void)
19733 + {
19734 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
19735 ++ proc_create_grsec("cmdline", 0, NULL, &cmdline_proc_fops);
19736 ++#else
19737 + proc_create("cmdline", 0, NULL, &cmdline_proc_fops);
19738 ++#endif
19739 + return 0;
19740 + }
19741 + module_init(proc_cmdline_init);
19742 +diff -urNp linux-2.6.28.8/fs/proc/devices.c linux-2.6.28.8/fs/proc/devices.c
19743 +--- linux-2.6.28.8/fs/proc/devices.c 2009-02-06 16:47:45.000000000 -0500
19744 ++++ linux-2.6.28.8/fs/proc/devices.c 2009-02-21 09:37:49.000000000 -0500
19745 +@@ -64,7 +64,11 @@ static const struct file_operations proc
19746 +
19747 + static int __init proc_devices_init(void)
19748 + {
19749 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
19750 ++ proc_create_grsec("devices", 0, NULL, &proc_devinfo_operations);
19751 ++#else
19752 + proc_create("devices", 0, NULL, &proc_devinfo_operations);
19753 ++#endif
19754 + return 0;
19755 + }
19756 + module_init(proc_devices_init);
19757 +diff -urNp linux-2.6.28.8/fs/proc/inode.c linux-2.6.28.8/fs/proc/inode.c
19758 +--- linux-2.6.28.8/fs/proc/inode.c 2009-02-06 16:47:45.000000000 -0500
19759 ++++ linux-2.6.28.8/fs/proc/inode.c 2009-02-21 09:37:49.000000000 -0500
19760 +@@ -466,7 +466,11 @@ struct inode *proc_get_inode(struct supe
19761 + if (de->mode) {
19762 + inode->i_mode = de->mode;
19763 + inode->i_uid = de->uid;
19764 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
19765 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
19766 ++#else
19767 + inode->i_gid = de->gid;
19768 ++#endif
19769 + }
19770 + if (de->size)
19771 + inode->i_size = de->size;
19772 +diff -urNp linux-2.6.28.8/fs/proc/internal.h linux-2.6.28.8/fs/proc/internal.h
19773 +--- linux-2.6.28.8/fs/proc/internal.h 2009-02-06 16:47:45.000000000 -0500
19774 ++++ linux-2.6.28.8/fs/proc/internal.h 2009-02-21 09:37:49.000000000 -0500
19775 +@@ -53,6 +53,9 @@ extern int proc_pid_status(struct seq_fi
19776 + struct pid *pid, struct task_struct *task);
19777 + extern int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
19778 + struct pid *pid, struct task_struct *task);
19779 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
19780 ++extern int proc_pid_ipaddr(struct task_struct *task, char *buffer);
19781 ++#endif
19782 + extern loff_t mem_lseek(struct file *file, loff_t offset, int orig);
19783 +
19784 + extern const struct file_operations proc_maps_operations;
19785 +diff -urNp linux-2.6.28.8/fs/proc/Kconfig linux-2.6.28.8/fs/proc/Kconfig
19786 +--- linux-2.6.28.8/fs/proc/Kconfig 2009-02-06 16:47:45.000000000 -0500
19787 ++++ linux-2.6.28.8/fs/proc/Kconfig 2009-02-21 09:37:49.000000000 -0500
19788 +@@ -30,12 +30,12 @@ config PROC_FS
19789 +
19790 + config PROC_KCORE
19791 + bool "/proc/kcore support" if !ARM
19792 +- depends on PROC_FS && MMU
19793 ++ depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
19794 +
19795 + config PROC_VMCORE
19796 + bool "/proc/vmcore support (EXPERIMENTAL)"
19797 +- depends on PROC_FS && CRASH_DUMP
19798 +- default y
19799 ++ depends on PROC_FS && CRASH_DUMP && !GRKERNSEC
19800 ++ default n
19801 + help
19802 + Exports the dump image of crashed kernel in ELF format.
19803 +
19804 +@@ -59,8 +59,8 @@ config PROC_SYSCTL
19805 + limited in memory.
19806 +
19807 + config PROC_PAGE_MONITOR
19808 +- default y
19809 +- depends on PROC_FS && MMU
19810 ++ default n
19811 ++ depends on PROC_FS && MMU && !GRKERNSEC
19812 + bool "Enable /proc page monitoring" if EMBEDDED
19813 + help
19814 + Various /proc files exist to monitor process memory utilization:
19815 +diff -urNp linux-2.6.28.8/fs/proc/kcore.c linux-2.6.28.8/fs/proc/kcore.c
19816 +--- linux-2.6.28.8/fs/proc/kcore.c 2009-02-06 16:47:45.000000000 -0500
19817 ++++ linux-2.6.28.8/fs/proc/kcore.c 2009-02-21 09:37:49.000000000 -0500
19818 +@@ -404,10 +404,12 @@ read_kcore(struct file *file, char __use
19819 +
19820 + static int __init proc_kcore_init(void)
19821 + {
19822 ++#if !defined(CONFIG_GRKERNSEC_PROC_ADD)
19823 + proc_root_kcore = proc_create("kcore", S_IRUSR, NULL, &proc_kcore_operations);
19824 + if (proc_root_kcore)
19825 + proc_root_kcore->size =
19826 + (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
19827 ++#endif
19828 + return 0;
19829 + }
19830 + module_init(proc_kcore_init);
19831 +diff -urNp linux-2.6.28.8/fs/proc/proc_net.c linux-2.6.28.8/fs/proc/proc_net.c
19832 +--- linux-2.6.28.8/fs/proc/proc_net.c 2009-02-06 16:47:45.000000000 -0500
19833 ++++ linux-2.6.28.8/fs/proc/proc_net.c 2009-02-21 09:37:49.000000000 -0500
19834 +@@ -106,6 +106,14 @@ static struct net *get_proc_task_net(str
19835 + struct nsproxy *ns;
19836 + struct net *net = NULL;
19837 +
19838 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
19839 ++ if (current->fsuid)
19840 ++ return net;
19841 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19842 ++ if (current->fsuid && !in_group_p(CONFIG_GRKERNSEC_PROC_GID))
19843 ++ return net;
19844 ++#endif
19845 ++
19846 + rcu_read_lock();
19847 + task = pid_task(proc_pid(dir), PIDTYPE_PID);
19848 + if (task != NULL) {
19849 +diff -urNp linux-2.6.28.8/fs/proc/proc_sysctl.c linux-2.6.28.8/fs/proc/proc_sysctl.c
19850 +--- linux-2.6.28.8/fs/proc/proc_sysctl.c 2009-02-06 16:47:45.000000000 -0500
19851 ++++ linux-2.6.28.8/fs/proc/proc_sysctl.c 2009-02-21 09:37:49.000000000 -0500
19852 +@@ -7,6 +7,8 @@
19853 + #include <linux/security.h>
19854 + #include "internal.h"
19855 +
19856 ++extern __u32 gr_handle_sysctl(const struct ctl_table *table, const int op);
19857 ++
19858 + static struct dentry_operations proc_sys_dentry_operations;
19859 + static const struct file_operations proc_sys_file_operations;
19860 + static const struct inode_operations proc_sys_inode_operations;
19861 +@@ -110,6 +112,9 @@ static struct dentry *proc_sys_lookup(st
19862 + if (!p)
19863 + goto out;
19864 +
19865 ++ if (gr_handle_sysctl(p, MAY_EXEC))
19866 ++ goto out;
19867 ++
19868 + err = ERR_PTR(-ENOMEM);
19869 + inode = proc_sys_make_inode(dir->i_sb, h ? h : head, p);
19870 + if (h)
19871 +@@ -229,6 +234,9 @@ static int scan(struct ctl_table_header
19872 + if (*pos < file->f_pos)
19873 + continue;
19874 +
19875 ++ if (gr_handle_sysctl(table, 0))
19876 ++ continue;
19877 ++
19878 + res = proc_sys_fill_cache(file, dirent, filldir, head, table);
19879 + if (res)
19880 + return res;
19881 +@@ -345,6 +353,9 @@ static int proc_sys_getattr(struct vfsmo
19882 + if (IS_ERR(head))
19883 + return PTR_ERR(head);
19884 +
19885 ++ if (table && gr_handle_sysctl(table, MAY_EXEC))
19886 ++ return -ENOENT;
19887 ++
19888 + generic_fillattr(inode, stat);
19889 + if (table)
19890 + stat->mode = (stat->mode & S_IFMT) | table->mode;
19891 +diff -urNp linux-2.6.28.8/fs/proc/root.c linux-2.6.28.8/fs/proc/root.c
19892 +--- linux-2.6.28.8/fs/proc/root.c 2009-02-06 16:47:45.000000000 -0500
19893 ++++ linux-2.6.28.8/fs/proc/root.c 2009-02-21 09:37:49.000000000 -0500
19894 +@@ -135,7 +135,15 @@ void __init proc_root_init(void)
19895 + #ifdef CONFIG_PROC_DEVICETREE
19896 + proc_device_tree_init();
19897 + #endif
19898 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
19899 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
19900 ++ proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
19901 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19902 ++ proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
19903 ++#endif
19904 ++#else
19905 + proc_mkdir("bus", NULL);
19906 ++#endif
19907 + proc_sys_init();
19908 + }
19909 +
19910 +diff -urNp linux-2.6.28.8/fs/proc/task_mmu.c linux-2.6.28.8/fs/proc/task_mmu.c
19911 +--- linux-2.6.28.8/fs/proc/task_mmu.c 2009-02-06 16:47:45.000000000 -0500
19912 ++++ linux-2.6.28.8/fs/proc/task_mmu.c 2009-02-21 09:37:49.000000000 -0500
19913 +@@ -46,15 +46,26 @@ void task_mem(struct seq_file *m, struct
19914 + "VmStk:\t%8lu kB\n"
19915 + "VmExe:\t%8lu kB\n"
19916 + "VmLib:\t%8lu kB\n"
19917 +- "VmPTE:\t%8lu kB\n",
19918 +- hiwater_vm << (PAGE_SHIFT-10),
19919 ++ "VmPTE:\t%8lu kB\n"
19920 ++
19921 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
19922 ++ "CsBase:\t%8lx\nCsLim:\t%8lx\n"
19923 ++#endif
19924 ++
19925 ++ ,hiwater_vm << (PAGE_SHIFT-10),
19926 + (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
19927 + mm->locked_vm << (PAGE_SHIFT-10),
19928 + hiwater_rss << (PAGE_SHIFT-10),
19929 + total_rss << (PAGE_SHIFT-10),
19930 + data << (PAGE_SHIFT-10),
19931 + mm->stack_vm << (PAGE_SHIFT-10), text, lib,
19932 +- (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
19933 ++ (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
19934 ++
19935 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
19936 ++ , mm->context.user_cs_base, mm->context.user_cs_limit
19937 ++#endif
19938 ++
19939 ++ );
19940 + }
19941 +
19942 + unsigned long task_vsize(struct mm_struct *mm)
19943 +@@ -198,6 +209,12 @@ static int do_maps_open(struct inode *in
19944 + return ret;
19945 + }
19946 +
19947 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19948 ++#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
19949 ++ (_mm->pax_flags & MF_PAX_RANDMMAP || \
19950 ++ _mm->pax_flags & MF_PAX_SEGMEXEC))
19951 ++#endif
19952 ++
19953 + static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
19954 + {
19955 + struct mm_struct *mm = vma->vm_mm;
19956 +@@ -214,13 +231,22 @@ static void show_map_vma(struct seq_file
19957 + }
19958 +
19959 + seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n",
19960 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19961 ++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
19962 ++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
19963 ++#else
19964 + vma->vm_start,
19965 + vma->vm_end,
19966 ++#endif
19967 + flags & VM_READ ? 'r' : '-',
19968 + flags & VM_WRITE ? 'w' : '-',
19969 + flags & VM_EXEC ? 'x' : '-',
19970 + flags & VM_MAYSHARE ? 's' : 'p',
19971 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19972 ++ PAX_RAND_FLAGS(mm) ? 0UL : ((loff_t)vma->vm_pgoff) << PAGE_SHIFT,
19973 ++#else
19974 + ((loff_t)vma->vm_pgoff) << PAGE_SHIFT,
19975 ++#endif
19976 + MAJOR(dev), MINOR(dev), ino, &len);
19977 +
19978 + /*
19979 +@@ -234,11 +260,11 @@ static void show_map_vma(struct seq_file
19980 + const char *name = arch_vma_name(vma);
19981 + if (!name) {
19982 + if (mm) {
19983 +- if (vma->vm_start <= mm->start_brk &&
19984 +- vma->vm_end >= mm->brk) {
19985 ++ if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
19986 + name = "[heap]";
19987 +- } else if (vma->vm_start <= mm->start_stack &&
19988 +- vma->vm_end >= mm->start_stack) {
19989 ++ } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
19990 ++ (vma->vm_start <= mm->start_stack &&
19991 ++ vma->vm_end >= mm->start_stack)) {
19992 + name = "[stack]";
19993 + }
19994 + } else {
19995 +@@ -381,9 +407,16 @@ static int show_smap(struct seq_file *m,
19996 + };
19997 +
19998 + memset(&mss, 0, sizeof mss);
19999 +- mss.vma = vma;
20000 +- if (vma->vm_mm && !is_vm_hugetlb_page(vma))
20001 +- walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
20002 ++
20003 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
20004 ++ if (!PAX_RAND_FLAGS(vma->vm_mm)) {
20005 ++#endif
20006 ++ mss.vma = vma;
20007 ++ if (vma->vm_mm && !is_vm_hugetlb_page(vma))
20008 ++ walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
20009 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
20010 ++ }
20011 ++#endif
20012 +
20013 + show_map_vma(m, vma);
20014 +
20015 +@@ -397,7 +430,11 @@ static int show_smap(struct seq_file *m,
20016 + "Private_Dirty: %8lu kB\n"
20017 + "Referenced: %8lu kB\n"
20018 + "Swap: %8lu kB\n",
20019 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
20020 ++ PAX_RAND_FLAGS(vma->vm_mm) ? 0UL : (vma->vm_end - vma->vm_start) >> 10,
20021 ++#else
20022 + (vma->vm_end - vma->vm_start) >> 10,
20023 ++#endif
20024 + mss.resident >> 10,
20025 + (unsigned long)(mss.pss >> (10 + PSS_SHIFT)),
20026 + mss.shared_clean >> 10,
20027 +diff -urNp linux-2.6.28.8/fs/readdir.c linux-2.6.28.8/fs/readdir.c
20028 +--- linux-2.6.28.8/fs/readdir.c 2009-02-06 16:47:45.000000000 -0500
20029 ++++ linux-2.6.28.8/fs/readdir.c 2009-02-21 09:37:49.000000000 -0500
20030 +@@ -16,6 +16,7 @@
20031 + #include <linux/security.h>
20032 + #include <linux/syscalls.h>
20033 + #include <linux/unistd.h>
20034 ++#include <linux/namei.h>
20035 +
20036 + #include <asm/uaccess.h>
20037 +
20038 +@@ -67,6 +68,7 @@ struct old_linux_dirent {
20039 +
20040 + struct readdir_callback {
20041 + struct old_linux_dirent __user * dirent;
20042 ++ struct file * file;
20043 + int result;
20044 + };
20045 +
20046 +@@ -84,6 +86,10 @@ static int fillonedir(void * __buf, cons
20047 + buf->result = -EOVERFLOW;
20048 + return -EOVERFLOW;
20049 + }
20050 ++
20051 ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
20052 ++ return 0;
20053 ++
20054 + buf->result++;
20055 + dirent = buf->dirent;
20056 + if (!access_ok(VERIFY_WRITE, dirent,
20057 +@@ -116,6 +122,7 @@ SYSCALL_DEFINE3(old_readdir, unsigned in
20058 +
20059 + buf.result = 0;
20060 + buf.dirent = dirent;
20061 ++ buf.file = file;
20062 +
20063 + error = vfs_readdir(file, fillonedir, &buf);
20064 + if (buf.result)
20065 +@@ -142,6 +149,7 @@ struct linux_dirent {
20066 + struct getdents_callback {
20067 + struct linux_dirent __user * current_dir;
20068 + struct linux_dirent __user * previous;
20069 ++ struct file * file;
20070 + int count;
20071 + int error;
20072 + };
20073 +@@ -162,6 +170,10 @@ static int filldir(void * __buf, const c
20074 + buf->error = -EOVERFLOW;
20075 + return -EOVERFLOW;
20076 + }
20077 ++
20078 ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
20079 ++ return 0;
20080 ++
20081 + dirent = buf->previous;
20082 + if (dirent) {
20083 + if (__put_user(offset, &dirent->d_off))
20084 +@@ -209,6 +221,7 @@ SYSCALL_DEFINE3(getdents, unsigned int,
20085 + buf.previous = NULL;
20086 + buf.count = count;
20087 + buf.error = 0;
20088 ++ buf.file = file;
20089 +
20090 + error = vfs_readdir(file, filldir, &buf);
20091 + if (error >= 0)
20092 +@@ -228,6 +241,7 @@ out:
20093 + struct getdents_callback64 {
20094 + struct linux_dirent64 __user * current_dir;
20095 + struct linux_dirent64 __user * previous;
20096 ++ struct file *file;
20097 + int count;
20098 + int error;
20099 + };
20100 +@@ -242,6 +256,10 @@ static int filldir64(void * __buf, const
20101 + buf->error = -EINVAL; /* only used if we fail.. */
20102 + if (reclen > buf->count)
20103 + return -EINVAL;
20104 ++
20105 ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
20106 ++ return 0;
20107 ++
20108 + dirent = buf->previous;
20109 + if (dirent) {
20110 + if (__put_user(offset, &dirent->d_off))
20111 +@@ -289,6 +307,7 @@ SYSCALL_DEFINE3(getdents64, unsigned int
20112 +
20113 + buf.current_dir = dirent;
20114 + buf.previous = NULL;
20115 ++ buf.file = file;
20116 + buf.count = count;
20117 + buf.error = 0;
20118 +
20119 +diff -urNp linux-2.6.28.8/fs/select.c linux-2.6.28.8/fs/select.c
20120 +--- linux-2.6.28.8/fs/select.c 2009-02-06 16:47:45.000000000 -0500
20121 ++++ linux-2.6.28.8/fs/select.c 2009-02-21 09:37:49.000000000 -0500
20122 +@@ -19,6 +19,7 @@
20123 + #include <linux/module.h>
20124 + #include <linux/slab.h>
20125 + #include <linux/poll.h>
20126 ++#include <linux/security.h>
20127 + #include <linux/personality.h> /* for STICKY_TIMEOUTS */
20128 + #include <linux/file.h>
20129 + #include <linux/fdtable.h>
20130 +@@ -733,6 +734,7 @@ int do_sys_poll(struct pollfd __user *uf
20131 + struct poll_list *walk = head;
20132 + unsigned long todo = nfds;
20133 +
20134 ++ gr_learn_resource(current, RLIMIT_NOFILE, nfds, 1);
20135 + if (nfds > current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
20136 + return -EINVAL;
20137 +
20138 +diff -urNp linux-2.6.28.8/fs/smbfs/symlink.c linux-2.6.28.8/fs/smbfs/symlink.c
20139 +--- linux-2.6.28.8/fs/smbfs/symlink.c 2009-02-06 16:47:45.000000000 -0500
20140 ++++ linux-2.6.28.8/fs/smbfs/symlink.c 2009-02-21 09:37:49.000000000 -0500
20141 +@@ -55,7 +55,7 @@ static void *smb_follow_link(struct dent
20142 +
20143 + static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
20144 + {
20145 +- char *s = nd_get_link(nd);
20146 ++ const char *s = nd_get_link(nd);
20147 + if (!IS_ERR(s))
20148 + __putname(s);
20149 + }
20150 +diff -urNp linux-2.6.28.8/fs/sysfs/symlink.c linux-2.6.28.8/fs/sysfs/symlink.c
20151 +--- linux-2.6.28.8/fs/sysfs/symlink.c 2009-02-06 16:47:45.000000000 -0500
20152 ++++ linux-2.6.28.8/fs/sysfs/symlink.c 2009-02-21 09:37:49.000000000 -0500
20153 +@@ -200,7 +200,7 @@ static void *sysfs_follow_link(struct de
20154 +
20155 + static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
20156 + {
20157 +- char *page = nd_get_link(nd);
20158 ++ const char *page = nd_get_link(nd);
20159 + if (!IS_ERR(page))
20160 + free_page((unsigned long)page);
20161 + }
20162 +diff -urNp linux-2.6.28.8/fs/udf/balloc.c linux-2.6.28.8/fs/udf/balloc.c
20163 +--- linux-2.6.28.8/fs/udf/balloc.c 2009-02-06 16:47:45.000000000 -0500
20164 ++++ linux-2.6.28.8/fs/udf/balloc.c 2009-02-21 09:37:49.000000000 -0500
20165 +@@ -169,9 +169,7 @@ static void udf_bitmap_free_blocks(struc
20166 + unsigned long overflow;
20167 +
20168 + mutex_lock(&sbi->s_alloc_mutex);
20169 +- if (bloc.logicalBlockNum < 0 ||
20170 +- (bloc.logicalBlockNum + count) >
20171 +- sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
20172 ++ if (bloc.logicalBlockNum + count > sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
20173 + udf_debug("%d < %d || %d + %d > %d\n",
20174 + bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
20175 + sbi->s_partmaps[bloc.partitionReferenceNum].
20176 +@@ -239,7 +237,7 @@ static int udf_bitmap_prealloc_blocks(st
20177 +
20178 + mutex_lock(&sbi->s_alloc_mutex);
20179 + part_len = sbi->s_partmaps[partition].s_partition_len;
20180 +- if (first_block < 0 || first_block >= part_len)
20181 ++ if (first_block >= part_len)
20182 + goto out;
20183 +
20184 + if (first_block + block_count > part_len)
20185 +@@ -300,7 +298,7 @@ static int udf_bitmap_new_block(struct s
20186 + mutex_lock(&sbi->s_alloc_mutex);
20187 +
20188 + repeat:
20189 +- if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
20190 ++ if (goal >= sbi->s_partmaps[partition].s_partition_len)
20191 + goal = 0;
20192 +
20193 + nr_groups = bitmap->s_nr_groups;
20194 +@@ -438,9 +436,7 @@ static void udf_table_free_blocks(struct
20195 + struct udf_inode_info *iinfo;
20196 +
20197 + mutex_lock(&sbi->s_alloc_mutex);
20198 +- if (bloc.logicalBlockNum < 0 ||
20199 +- (bloc.logicalBlockNum + count) >
20200 +- sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
20201 ++ if (bloc.logicalBlockNum + count > sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
20202 + udf_debug("%d < %d || %d + %d > %d\n",
20203 + bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
20204 + sbi->s_partmaps[bloc.partitionReferenceNum].
20205 +@@ -671,8 +667,7 @@ static int udf_table_prealloc_blocks(str
20206 + int8_t etype = -1;
20207 + struct udf_inode_info *iinfo;
20208 +
20209 +- if (first_block < 0 ||
20210 +- first_block >= sbi->s_partmaps[partition].s_partition_len)
20211 ++ if (first_block >= sbi->s_partmaps[partition].s_partition_len)
20212 + return 0;
20213 +
20214 + iinfo = UDF_I(table);
20215 +@@ -750,7 +745,7 @@ static int udf_table_new_block(struct su
20216 + return newblock;
20217 +
20218 + mutex_lock(&sbi->s_alloc_mutex);
20219 +- if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
20220 ++ if (goal >= sbi->s_partmaps[partition].s_partition_len)
20221 + goal = 0;
20222 +
20223 + /* We search for the closest matching block to goal. If we find
20224 +diff -urNp linux-2.6.28.8/fs/ufs/inode.c linux-2.6.28.8/fs/ufs/inode.c
20225 +--- linux-2.6.28.8/fs/ufs/inode.c 2009-02-06 16:47:45.000000000 -0500
20226 ++++ linux-2.6.28.8/fs/ufs/inode.c 2009-02-21 09:37:49.000000000 -0500
20227 +@@ -56,9 +56,7 @@ static int ufs_block_to_path(struct inod
20228 +
20229 +
20230 + UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
20231 +- if (i_block < 0) {
20232 +- ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
20233 +- } else if (i_block < direct_blocks) {
20234 ++ if (i_block < direct_blocks) {
20235 + offsets[n++] = i_block;
20236 + } else if ((i_block -= direct_blocks) < indirect_blocks) {
20237 + offsets[n++] = UFS_IND_BLOCK;
20238 +@@ -440,8 +438,6 @@ int ufs_getfrag_block(struct inode *inod
20239 + lock_kernel();
20240 +
20241 + UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
20242 +- if (fragment < 0)
20243 +- goto abort_negative;
20244 + if (fragment >
20245 + ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
20246 + << uspi->s_fpbshift))
20247 +@@ -504,10 +500,6 @@ abort:
20248 + unlock_kernel();
20249 + return err;
20250 +
20251 +-abort_negative:
20252 +- ufs_warning(sb, "ufs_get_block", "block < 0");
20253 +- goto abort;
20254 +-
20255 + abort_too_big:
20256 + ufs_warning(sb, "ufs_get_block", "block > big");
20257 + goto abort;
20258 +diff -urNp linux-2.6.28.8/fs/utimes.c linux-2.6.28.8/fs/utimes.c
20259 +--- linux-2.6.28.8/fs/utimes.c 2009-02-06 16:47:45.000000000 -0500
20260 ++++ linux-2.6.28.8/fs/utimes.c 2009-02-21 09:37:49.000000000 -0500
20261 +@@ -1,6 +1,7 @@
20262 + #include <linux/compiler.h>
20263 + #include <linux/file.h>
20264 + #include <linux/fs.h>
20265 ++#include <linux/security.h>
20266 + #include <linux/linkage.h>
20267 + #include <linux/mount.h>
20268 + #include <linux/namei.h>
20269 +@@ -101,6 +102,12 @@ static int utimes_common(struct path *pa
20270 + goto mnt_drop_write_and_out;
20271 + }
20272 + }
20273 ++
20274 ++ if (!gr_acl_handle_utime(path->dentry, path->mnt)) {
20275 ++ error = -EACCES;
20276 ++ goto mnt_drop_write_and_out;
20277 ++ }
20278 ++
20279 + mutex_lock(&inode->i_mutex);
20280 + error = notify_change(path->dentry, &newattrs);
20281 + mutex_unlock(&inode->i_mutex);
20282 +diff -urNp linux-2.6.28.8/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.28.8/fs/xfs/linux-2.6/xfs_iops.c
20283 +--- linux-2.6.28.8/fs/xfs/linux-2.6/xfs_iops.c 2009-02-06 16:47:45.000000000 -0500
20284 ++++ linux-2.6.28.8/fs/xfs/linux-2.6/xfs_iops.c 2009-02-21 09:37:49.000000000 -0500
20285 +@@ -500,7 +500,7 @@ xfs_vn_put_link(
20286 + struct nameidata *nd,
20287 + void *p)
20288 + {
20289 +- char *s = nd_get_link(nd);
20290 ++ const char *s = nd_get_link(nd);
20291 +
20292 + if (!IS_ERR(s))
20293 + kfree(s);
20294 +diff -urNp linux-2.6.28.8/fs/xfs/xfs_bmap.c linux-2.6.28.8/fs/xfs/xfs_bmap.c
20295 +--- linux-2.6.28.8/fs/xfs/xfs_bmap.c 2009-02-06 16:47:45.000000000 -0500
20296 ++++ linux-2.6.28.8/fs/xfs/xfs_bmap.c 2009-02-21 09:37:49.000000000 -0500
20297 +@@ -360,7 +360,7 @@ xfs_bmap_validate_ret(
20298 + int nmap,
20299 + int ret_nmap);
20300 + #else
20301 +-#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
20302 ++#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
20303 + #endif /* DEBUG */
20304 +
20305 + #if defined(XFS_RW_TRACE)
20306 +diff -urNp linux-2.6.28.8/grsecurity/gracl_alloc.c linux-2.6.28.8/grsecurity/gracl_alloc.c
20307 +--- linux-2.6.28.8/grsecurity/gracl_alloc.c 1969-12-31 19:00:00.000000000 -0500
20308 ++++ linux-2.6.28.8/grsecurity/gracl_alloc.c 2009-02-21 09:37:49.000000000 -0500
20309 +@@ -0,0 +1,91 @@
20310 ++#include <linux/kernel.h>
20311 ++#include <linux/mm.h>
20312 ++#include <linux/slab.h>
20313 ++#include <linux/vmalloc.h>
20314 ++#include <linux/gracl.h>
20315 ++#include <linux/grsecurity.h>
20316 ++
20317 ++static unsigned long alloc_stack_next = 1;
20318 ++static unsigned long alloc_stack_size = 1;
20319 ++static void **alloc_stack;
20320 ++
20321 ++static __inline__ int
20322 ++alloc_pop(void)
20323 ++{
20324 ++ if (alloc_stack_next == 1)
20325 ++ return 0;
20326 ++
20327 ++ kfree(alloc_stack[alloc_stack_next - 2]);
20328 ++
20329 ++ alloc_stack_next--;
20330 ++
20331 ++ return 1;
20332 ++}
20333 ++
20334 ++static __inline__ void
20335 ++alloc_push(void *buf)
20336 ++{
20337 ++ if (alloc_stack_next >= alloc_stack_size)
20338 ++ BUG();
20339 ++
20340 ++ alloc_stack[alloc_stack_next - 1] = buf;
20341 ++
20342 ++ alloc_stack_next++;
20343 ++
20344 ++ return;
20345 ++}
20346 ++
20347 ++void *
20348 ++acl_alloc(unsigned long len)
20349 ++{
20350 ++ void *ret;
20351 ++
20352 ++ if (len > PAGE_SIZE)
20353 ++ BUG();
20354 ++
20355 ++ ret = kmalloc(len, GFP_KERNEL);
20356 ++
20357 ++ if (ret)
20358 ++ alloc_push(ret);
20359 ++
20360 ++ return ret;
20361 ++}
20362 ++
20363 ++void
20364 ++acl_free_all(void)
20365 ++{
20366 ++ if (gr_acl_is_enabled() || !alloc_stack)
20367 ++ return;
20368 ++
20369 ++ while (alloc_pop()) ;
20370 ++
20371 ++ if (alloc_stack) {
20372 ++ if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
20373 ++ kfree(alloc_stack);
20374 ++ else
20375 ++ vfree(alloc_stack);
20376 ++ }
20377 ++
20378 ++ alloc_stack = NULL;
20379 ++ alloc_stack_size = 1;
20380 ++ alloc_stack_next = 1;
20381 ++
20382 ++ return;
20383 ++}
20384 ++
20385 ++int
20386 ++acl_alloc_stack_init(unsigned long size)
20387 ++{
20388 ++ if ((size * sizeof (void *)) <= PAGE_SIZE)
20389 ++ alloc_stack =
20390 ++ (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
20391 ++ else
20392 ++ alloc_stack = (void **) vmalloc(size * sizeof (void *));
20393 ++
20394 ++ alloc_stack_size = size;
20395 ++
20396 ++ if (!alloc_stack)
20397 ++ return 0;
20398 ++ else
20399 ++ return 1;
20400 ++}
20401 +diff -urNp linux-2.6.28.8/grsecurity/gracl.c linux-2.6.28.8/grsecurity/gracl.c
20402 +--- linux-2.6.28.8/grsecurity/gracl.c 1969-12-31 19:00:00.000000000 -0500
20403 ++++ linux-2.6.28.8/grsecurity/gracl.c 2009-02-21 09:37:49.000000000 -0500
20404 +@@ -0,0 +1,3722 @@
20405 ++#include <linux/kernel.h>
20406 ++#include <linux/module.h>
20407 ++#include <linux/sched.h>
20408 ++#include <linux/mm.h>
20409 ++#include <linux/file.h>
20410 ++#include <linux/fs.h>
20411 ++#include <linux/namei.h>
20412 ++#include <linux/mount.h>
20413 ++#include <linux/tty.h>
20414 ++#include <linux/proc_fs.h>
20415 ++#include <linux/smp_lock.h>
20416 ++#include <linux/slab.h>
20417 ++#include <linux/vmalloc.h>
20418 ++#include <linux/types.h>
20419 ++#include <linux/sysctl.h>
20420 ++#include <linux/netdevice.h>
20421 ++#include <linux/ptrace.h>
20422 ++#include <linux/gracl.h>
20423 ++#include <linux/gralloc.h>
20424 ++#include <linux/grsecurity.h>
20425 ++#include <linux/grinternal.h>
20426 ++#include <linux/pid_namespace.h>
20427 ++#include <linux/fdtable.h>
20428 ++#include <linux/percpu.h>
20429 ++
20430 ++#include <asm/uaccess.h>
20431 ++#include <asm/errno.h>
20432 ++#include <asm/mman.h>
20433 ++
20434 ++static struct acl_role_db acl_role_set;
20435 ++static struct name_db name_set;
20436 ++static struct inodev_db inodev_set;
20437 ++
20438 ++/* for keeping track of userspace pointers used for subjects, so we
20439 ++ can share references in the kernel as well
20440 ++*/
20441 ++
20442 ++static struct dentry *real_root;
20443 ++static struct vfsmount *real_root_mnt;
20444 ++
20445 ++static struct acl_subj_map_db subj_map_set;
20446 ++
20447 ++static struct acl_role_label *default_role;
20448 ++
20449 ++static u16 acl_sp_role_value;
20450 ++
20451 ++extern char *gr_shared_page[4];
20452 ++static DECLARE_MUTEX(gr_dev_sem);
20453 ++DEFINE_RWLOCK(gr_inode_lock);
20454 ++
20455 ++struct gr_arg *gr_usermode;
20456 ++
20457 ++static unsigned int gr_status = GR_STATUS_INIT;
20458 ++
20459 ++extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
20460 ++extern void gr_clear_learn_entries(void);
20461 ++
20462 ++#ifdef CONFIG_GRKERNSEC_RESLOG
20463 ++extern void gr_log_resource(const struct task_struct *task,
20464 ++ const int res, const unsigned long wanted, const int gt);
20465 ++#endif
20466 ++
20467 ++unsigned char *gr_system_salt;
20468 ++unsigned char *gr_system_sum;
20469 ++
20470 ++static struct sprole_pw **acl_special_roles = NULL;
20471 ++static __u16 num_sprole_pws = 0;
20472 ++
20473 ++static struct acl_role_label *kernel_role = NULL;
20474 ++
20475 ++static unsigned int gr_auth_attempts = 0;
20476 ++static unsigned long gr_auth_expires = 0UL;
20477 ++
20478 ++extern struct vfsmount *sock_mnt;
20479 ++extern struct vfsmount *pipe_mnt;
20480 ++extern struct vfsmount *shm_mnt;
20481 ++static struct acl_object_label *fakefs_obj;
20482 ++
20483 ++extern int gr_init_uidset(void);
20484 ++extern void gr_free_uidset(void);
20485 ++extern void gr_remove_uid(uid_t uid);
20486 ++extern int gr_find_uid(uid_t uid);
20487 ++
20488 ++__inline__ int
20489 ++gr_acl_is_enabled(void)
20490 ++{
20491 ++ return (gr_status & GR_READY);
20492 ++}
20493 ++
20494 ++char gr_roletype_to_char(void)
20495 ++{
20496 ++ switch (current->role->roletype &
20497 ++ (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
20498 ++ GR_ROLE_SPECIAL)) {
20499 ++ case GR_ROLE_DEFAULT:
20500 ++ return 'D';
20501 ++ case GR_ROLE_USER:
20502 ++ return 'U';
20503 ++ case GR_ROLE_GROUP:
20504 ++ return 'G';
20505 ++ case GR_ROLE_SPECIAL:
20506 ++ return 'S';
20507 ++ }
20508 ++
20509 ++ return 'X';
20510 ++}
20511 ++
20512 ++__inline__ int
20513 ++gr_acl_tpe_check(void)
20514 ++{
20515 ++ if (unlikely(!(gr_status & GR_READY)))
20516 ++ return 0;
20517 ++ if (current->role->roletype & GR_ROLE_TPE)
20518 ++ return 1;
20519 ++ else
20520 ++ return 0;
20521 ++}
20522 ++
20523 ++int
20524 ++gr_handle_rawio(const struct inode *inode)
20525 ++{
20526 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
20527 ++ if (inode && S_ISBLK(inode->i_mode) &&
20528 ++ grsec_enable_chroot_caps && proc_is_chrooted(current) &&
20529 ++ !capable(CAP_SYS_RAWIO))
20530 ++ return 1;
20531 ++#endif
20532 ++ return 0;
20533 ++}
20534 ++
20535 ++static int
20536 ++gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
20537 ++{
20538 ++ int i;
20539 ++ unsigned long *l1;
20540 ++ unsigned long *l2;
20541 ++ unsigned char *c1;
20542 ++ unsigned char *c2;
20543 ++ int num_longs;
20544 ++
20545 ++ if (likely(lena != lenb))
20546 ++ return 0;
20547 ++
20548 ++ l1 = (unsigned long *)a;
20549 ++ l2 = (unsigned long *)b;
20550 ++
20551 ++ num_longs = lena / sizeof(unsigned long);
20552 ++
20553 ++ for (i = num_longs; i--; l1++, l2++) {
20554 ++ if (unlikely(*l1 != *l2))
20555 ++ return 0;
20556 ++ }
20557 ++
20558 ++ c1 = (unsigned char *) l1;
20559 ++ c2 = (unsigned char *) l2;
20560 ++
20561 ++ i = lena - (num_longs * sizeof(unsigned long));
20562 ++
20563 ++ for (; i--; c1++, c2++) {
20564 ++ if (unlikely(*c1 != *c2))
20565 ++ return 0;
20566 ++ }
20567 ++
20568 ++ return 1;
20569 ++}
20570 ++
20571 ++static char * __our_d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
20572 ++ struct dentry *root, struct vfsmount *rootmnt,
20573 ++ char *buffer, int buflen)
20574 ++{
20575 ++ char * end = buffer+buflen;
20576 ++ char * retval;
20577 ++ int namelen;
20578 ++
20579 ++ *--end = '\0';
20580 ++ buflen--;
20581 ++
20582 ++ if (buflen < 1)
20583 ++ goto Elong;
20584 ++ /* Get '/' right */
20585 ++ retval = end-1;
20586 ++ *retval = '/';
20587 ++
20588 ++ for (;;) {
20589 ++ struct dentry * parent;
20590 ++
20591 ++ if (dentry == root && vfsmnt == rootmnt)
20592 ++ break;
20593 ++ if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
20594 ++ /* Global root? */
20595 ++ spin_lock(&vfsmount_lock);
20596 ++ if (vfsmnt->mnt_parent == vfsmnt) {
20597 ++ spin_unlock(&vfsmount_lock);
20598 ++ goto global_root;
20599 ++ }
20600 ++ dentry = vfsmnt->mnt_mountpoint;
20601 ++ vfsmnt = vfsmnt->mnt_parent;
20602 ++ spin_unlock(&vfsmount_lock);
20603 ++ continue;
20604 ++ }
20605 ++ parent = dentry->d_parent;
20606 ++ prefetch(parent);
20607 ++ namelen = dentry->d_name.len;
20608 ++ buflen -= namelen + 1;
20609 ++ if (buflen < 0)
20610 ++ goto Elong;
20611 ++ end -= namelen;
20612 ++ memcpy(end, dentry->d_name.name, namelen);
20613 ++ *--end = '/';
20614 ++ retval = end;
20615 ++ dentry = parent;
20616 ++ }
20617 ++
20618 ++ return retval;
20619 ++
20620 ++global_root:
20621 ++ namelen = dentry->d_name.len;
20622 ++ buflen -= namelen;
20623 ++ if (buflen < 0)
20624 ++ goto Elong;
20625 ++ retval -= namelen-1; /* hit the slash */
20626 ++ memcpy(retval, dentry->d_name.name, namelen);
20627 ++ return retval;
20628 ++Elong:
20629 ++ return ERR_PTR(-ENAMETOOLONG);
20630 ++}
20631 ++
20632 ++static char *
20633 ++gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
20634 ++ struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
20635 ++{
20636 ++ char *retval;
20637 ++
20638 ++ retval = __our_d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
20639 ++ if (unlikely(IS_ERR(retval)))
20640 ++ retval = strcpy(buf, "<path too long>");
20641 ++ else if (unlikely(retval[1] == '/' && retval[2] == '\0'))
20642 ++ retval[1] = '\0';
20643 ++
20644 ++ return retval;
20645 ++}
20646 ++
20647 ++static char *
20648 ++__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
20649 ++ char *buf, int buflen)
20650 ++{
20651 ++ char *res;
20652 ++
20653 ++ /* we can use real_root, real_root_mnt, because this is only called
20654 ++ by the RBAC system */
20655 ++ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
20656 ++
20657 ++ return res;
20658 ++}
20659 ++
20660 ++static char *
20661 ++d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
20662 ++ char *buf, int buflen)
20663 ++{
20664 ++ char *res;
20665 ++ struct dentry *root;
20666 ++ struct vfsmount *rootmnt;
20667 ++ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
20668 ++
20669 ++ /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
20670 ++ read_lock(&reaper->fs->lock);
20671 ++ root = dget(reaper->fs->root.dentry);
20672 ++ rootmnt = mntget(reaper->fs->root.mnt);
20673 ++ read_unlock(&reaper->fs->lock);
20674 ++
20675 ++ spin_lock(&dcache_lock);
20676 ++ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
20677 ++ spin_unlock(&dcache_lock);
20678 ++
20679 ++ dput(root);
20680 ++ mntput(rootmnt);
20681 ++ return res;
20682 ++}
20683 ++
20684 ++static char *
20685 ++gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
20686 ++{
20687 ++ char *ret;
20688 ++ spin_lock(&dcache_lock);
20689 ++ ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
20690 ++ PAGE_SIZE);
20691 ++ spin_unlock(&dcache_lock);
20692 ++ return ret;
20693 ++}
20694 ++
20695 ++char *
20696 ++gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
20697 ++{
20698 ++ return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
20699 ++ PAGE_SIZE);
20700 ++}
20701 ++
20702 ++char *
20703 ++gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
20704 ++{
20705 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
20706 ++ PAGE_SIZE);
20707 ++}
20708 ++
20709 ++char *
20710 ++gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
20711 ++{
20712 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
20713 ++ PAGE_SIZE);
20714 ++}
20715 ++
20716 ++char *
20717 ++gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
20718 ++{
20719 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
20720 ++ PAGE_SIZE);
20721 ++}
20722 ++
20723 ++char *
20724 ++gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
20725 ++{
20726 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
20727 ++ PAGE_SIZE);
20728 ++}
20729 ++
20730 ++__inline__ __u32
20731 ++to_gr_audit(const __u32 reqmode)
20732 ++{
20733 ++ /* masks off auditable permission flags, then shifts them to create
20734 ++ auditing flags, and adds the special case of append auditing if
20735 ++ we're requesting write */
20736 ++ return (((reqmode & ~GR_AUDITS) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
20737 ++}
20738 ++
20739 ++struct acl_subject_label *
20740 ++lookup_subject_map(const struct acl_subject_label *userp)
20741 ++{
20742 ++ unsigned int index = shash(userp, subj_map_set.s_size);
20743 ++ struct subject_map *match;
20744 ++
20745 ++ match = subj_map_set.s_hash[index];
20746 ++
20747 ++ while (match && match->user != userp)
20748 ++ match = match->next;
20749 ++
20750 ++ if (match != NULL)
20751 ++ return match->kernel;
20752 ++ else
20753 ++ return NULL;
20754 ++}
20755 ++
20756 ++static void
20757 ++insert_subj_map_entry(struct subject_map *subjmap)
20758 ++{
20759 ++ unsigned int index = shash(subjmap->user, subj_map_set.s_size);
20760 ++ struct subject_map **curr;
20761 ++
20762 ++ subjmap->prev = NULL;
20763 ++
20764 ++ curr = &subj_map_set.s_hash[index];
20765 ++ if (*curr != NULL)
20766 ++ (*curr)->prev = subjmap;
20767 ++
20768 ++ subjmap->next = *curr;
20769 ++ *curr = subjmap;
20770 ++
20771 ++ return;
20772 ++}
20773 ++
20774 ++static struct acl_role_label *
20775 ++lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
20776 ++ const gid_t gid)
20777 ++{
20778 ++ unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
20779 ++ struct acl_role_label *match;
20780 ++ struct role_allowed_ip *ipp;
20781 ++ unsigned int x;
20782 ++
20783 ++ match = acl_role_set.r_hash[index];
20784 ++
20785 ++ while (match) {
20786 ++ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
20787 ++ for (x = 0; x < match->domain_child_num; x++) {
20788 ++ if (match->domain_children[x] == uid)
20789 ++ goto found;
20790 ++ }
20791 ++ } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
20792 ++ break;
20793 ++ match = match->next;
20794 ++ }
20795 ++found:
20796 ++ if (match == NULL) {
20797 ++ try_group:
20798 ++ index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
20799 ++ match = acl_role_set.r_hash[index];
20800 ++
20801 ++ while (match) {
20802 ++ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
20803 ++ for (x = 0; x < match->domain_child_num; x++) {
20804 ++ if (match->domain_children[x] == gid)
20805 ++ goto found2;
20806 ++ }
20807 ++ } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
20808 ++ break;
20809 ++ match = match->next;
20810 ++ }
20811 ++found2:
20812 ++ if (match == NULL)
20813 ++ match = default_role;
20814 ++ if (match->allowed_ips == NULL)
20815 ++ return match;
20816 ++ else {
20817 ++ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
20818 ++ if (likely
20819 ++ ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
20820 ++ (ntohl(ipp->addr) & ipp->netmask)))
20821 ++ return match;
20822 ++ }
20823 ++ match = default_role;
20824 ++ }
20825 ++ } else if (match->allowed_ips == NULL) {
20826 ++ return match;
20827 ++ } else {
20828 ++ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
20829 ++ if (likely
20830 ++ ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
20831 ++ (ntohl(ipp->addr) & ipp->netmask)))
20832 ++ return match;
20833 ++ }
20834 ++ goto try_group;
20835 ++ }
20836 ++
20837 ++ return match;
20838 ++}
20839 ++
20840 ++struct acl_subject_label *
20841 ++lookup_acl_subj_label(const ino_t ino, const dev_t dev,
20842 ++ const struct acl_role_label *role)
20843 ++{
20844 ++ unsigned int index = fhash(ino, dev, role->subj_hash_size);
20845 ++ struct acl_subject_label *match;
20846 ++
20847 ++ match = role->subj_hash[index];
20848 ++
20849 ++ while (match && (match->inode != ino || match->device != dev ||
20850 ++ (match->mode & GR_DELETED))) {
20851 ++ match = match->next;
20852 ++ }
20853 ++
20854 ++ if (match && !(match->mode & GR_DELETED))
20855 ++ return match;
20856 ++ else
20857 ++ return NULL;
20858 ++}
20859 ++
20860 ++static struct acl_object_label *
20861 ++lookup_acl_obj_label(const ino_t ino, const dev_t dev,
20862 ++ const struct acl_subject_label *subj)
20863 ++{
20864 ++ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
20865 ++ struct acl_object_label *match;
20866 ++
20867 ++ match = subj->obj_hash[index];
20868 ++
20869 ++ while (match && (match->inode != ino || match->device != dev ||
20870 ++ (match->mode & GR_DELETED))) {
20871 ++ match = match->next;
20872 ++ }
20873 ++
20874 ++ if (match && !(match->mode & GR_DELETED))
20875 ++ return match;
20876 ++ else
20877 ++ return NULL;
20878 ++}
20879 ++
20880 ++static struct acl_object_label *
20881 ++lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
20882 ++ const struct acl_subject_label *subj)
20883 ++{
20884 ++ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
20885 ++ struct acl_object_label *match;
20886 ++
20887 ++ match = subj->obj_hash[index];
20888 ++
20889 ++ while (match && (match->inode != ino || match->device != dev ||
20890 ++ !(match->mode & GR_DELETED))) {
20891 ++ match = match->next;
20892 ++ }
20893 ++
20894 ++ if (match && (match->mode & GR_DELETED))
20895 ++ return match;
20896 ++
20897 ++ match = subj->obj_hash[index];
20898 ++
20899 ++ while (match && (match->inode != ino || match->device != dev ||
20900 ++ (match->mode & GR_DELETED))) {
20901 ++ match = match->next;
20902 ++ }
20903 ++
20904 ++ if (match && !(match->mode & GR_DELETED))
20905 ++ return match;
20906 ++ else
20907 ++ return NULL;
20908 ++}
20909 ++
20910 ++static struct name_entry *
20911 ++lookup_name_entry(const char *name)
20912 ++{
20913 ++ unsigned int len = strlen(name);
20914 ++ unsigned int key = full_name_hash(name, len);
20915 ++ unsigned int index = key % name_set.n_size;
20916 ++ struct name_entry *match;
20917 ++
20918 ++ match = name_set.n_hash[index];
20919 ++
20920 ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
20921 ++ match = match->next;
20922 ++
20923 ++ return match;
20924 ++}
20925 ++
20926 ++static struct name_entry *
20927 ++lookup_name_entry_create(const char *name)
20928 ++{
20929 ++ unsigned int len = strlen(name);
20930 ++ unsigned int key = full_name_hash(name, len);
20931 ++ unsigned int index = key % name_set.n_size;
20932 ++ struct name_entry *match;
20933 ++
20934 ++ match = name_set.n_hash[index];
20935 ++
20936 ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
20937 ++ !match->deleted))
20938 ++ match = match->next;
20939 ++
20940 ++ if (match && match->deleted)
20941 ++ return match;
20942 ++
20943 ++ match = name_set.n_hash[index];
20944 ++
20945 ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
20946 ++ match->deleted))
20947 ++ match = match->next;
20948 ++
20949 ++ if (match && !match->deleted)
20950 ++ return match;
20951 ++ else
20952 ++ return NULL;
20953 ++}
20954 ++
20955 ++static struct inodev_entry *
20956 ++lookup_inodev_entry(const ino_t ino, const dev_t dev)
20957 ++{
20958 ++ unsigned int index = fhash(ino, dev, inodev_set.i_size);
20959 ++ struct inodev_entry *match;
20960 ++
20961 ++ match = inodev_set.i_hash[index];
20962 ++
20963 ++ while (match && (match->nentry->inode != ino || match->nentry->device != dev))
20964 ++ match = match->next;
20965 ++
20966 ++ return match;
20967 ++}
20968 ++
20969 ++static void
20970 ++insert_inodev_entry(struct inodev_entry *entry)
20971 ++{
20972 ++ unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
20973 ++ inodev_set.i_size);
20974 ++ struct inodev_entry **curr;
20975 ++
20976 ++ entry->prev = NULL;
20977 ++
20978 ++ curr = &inodev_set.i_hash[index];
20979 ++ if (*curr != NULL)
20980 ++ (*curr)->prev = entry;
20981 ++
20982 ++ entry->next = *curr;
20983 ++ *curr = entry;
20984 ++
20985 ++ return;
20986 ++}
20987 ++
20988 ++static void
20989 ++__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
20990 ++{
20991 ++ unsigned int index =
20992 ++ rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
20993 ++ struct acl_role_label **curr;
20994 ++
20995 ++ role->prev = NULL;
20996 ++
20997 ++ curr = &acl_role_set.r_hash[index];
20998 ++ if (*curr != NULL)
20999 ++ (*curr)->prev = role;
21000 ++
21001 ++ role->next = *curr;
21002 ++ *curr = role;
21003 ++
21004 ++ return;
21005 ++}
21006 ++
21007 ++static void
21008 ++insert_acl_role_label(struct acl_role_label *role)
21009 ++{
21010 ++ int i;
21011 ++
21012 ++ if (role->roletype & GR_ROLE_DOMAIN) {
21013 ++ for (i = 0; i < role->domain_child_num; i++)
21014 ++ __insert_acl_role_label(role, role->domain_children[i]);
21015 ++ } else
21016 ++ __insert_acl_role_label(role, role->uidgid);
21017 ++}
21018 ++
21019 ++static int
21020 ++insert_name_entry(char *name, const ino_t inode, const dev_t device, __u8 deleted)
21021 ++{
21022 ++ struct name_entry **curr, *nentry;
21023 ++ struct inodev_entry *ientry;
21024 ++ unsigned int len = strlen(name);
21025 ++ unsigned int key = full_name_hash(name, len);
21026 ++ unsigned int index = key % name_set.n_size;
21027 ++
21028 ++ curr = &name_set.n_hash[index];
21029 ++
21030 ++ while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
21031 ++ curr = &((*curr)->next);
21032 ++
21033 ++ if (*curr != NULL)
21034 ++ return 1;
21035 ++
21036 ++ nentry = acl_alloc(sizeof (struct name_entry));
21037 ++ if (nentry == NULL)
21038 ++ return 0;
21039 ++ ientry = acl_alloc(sizeof (struct inodev_entry));
21040 ++ if (ientry == NULL)
21041 ++ return 0;
21042 ++ ientry->nentry = nentry;
21043 ++
21044 ++ nentry->key = key;
21045 ++ nentry->name = name;
21046 ++ nentry->inode = inode;
21047 ++ nentry->device = device;
21048 ++ nentry->len = len;
21049 ++ nentry->deleted = deleted;
21050 ++
21051 ++ nentry->prev = NULL;
21052 ++ curr = &name_set.n_hash[index];
21053 ++ if (*curr != NULL)
21054 ++ (*curr)->prev = nentry;
21055 ++ nentry->next = *curr;
21056 ++ *curr = nentry;
21057 ++
21058 ++ /* insert us into the table searchable by inode/dev */
21059 ++ insert_inodev_entry(ientry);
21060 ++
21061 ++ return 1;
21062 ++}
21063 ++
21064 ++static void
21065 ++insert_acl_obj_label(struct acl_object_label *obj,
21066 ++ struct acl_subject_label *subj)
21067 ++{
21068 ++ unsigned int index =
21069 ++ fhash(obj->inode, obj->device, subj->obj_hash_size);
21070 ++ struct acl_object_label **curr;
21071 ++
21072 ++
21073 ++ obj->prev = NULL;
21074 ++
21075 ++ curr = &subj->obj_hash[index];
21076 ++ if (*curr != NULL)
21077 ++ (*curr)->prev = obj;
21078 ++
21079 ++ obj->next = *curr;
21080 ++ *curr = obj;
21081 ++
21082 ++ return;
21083 ++}
21084 ++
21085 ++static void
21086 ++insert_acl_subj_label(struct acl_subject_label *obj,
21087 ++ struct acl_role_label *role)
21088 ++{
21089 ++ unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
21090 ++ struct acl_subject_label **curr;
21091 ++
21092 ++ obj->prev = NULL;
21093 ++
21094 ++ curr = &role->subj_hash[index];
21095 ++ if (*curr != NULL)
21096 ++ (*curr)->prev = obj;
21097 ++
21098 ++ obj->next = *curr;
21099 ++ *curr = obj;
21100 ++
21101 ++ return;
21102 ++}
21103 ++
21104 ++/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
21105 ++
21106 ++static void *
21107 ++create_table(__u32 * len, int elementsize)
21108 ++{
21109 ++ unsigned int table_sizes[] = {
21110 ++ 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
21111 ++ 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
21112 ++ 4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
21113 ++ 268435399, 536870909, 1073741789, 2147483647
21114 ++ };
21115 ++ void *newtable = NULL;
21116 ++ unsigned int pwr = 0;
21117 ++
21118 ++ while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
21119 ++ table_sizes[pwr] <= *len)
21120 ++ pwr++;
21121 ++
21122 ++ if (table_sizes[pwr] <= *len)
21123 ++ return newtable;
21124 ++
21125 ++ if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
21126 ++ newtable =
21127 ++ kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
21128 ++ else
21129 ++ newtable = vmalloc(table_sizes[pwr] * elementsize);
21130 ++
21131 ++ *len = table_sizes[pwr];
21132 ++
21133 ++ return newtable;
21134 ++}
21135 ++
21136 ++static int
21137 ++init_variables(const struct gr_arg *arg)
21138 ++{
21139 ++ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
21140 ++ unsigned int stacksize;
21141 ++
21142 ++ subj_map_set.s_size = arg->role_db.num_subjects;
21143 ++ acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
21144 ++ name_set.n_size = arg->role_db.num_objects;
21145 ++ inodev_set.i_size = arg->role_db.num_objects;
21146 ++
21147 ++ if (!subj_map_set.s_size || !acl_role_set.r_size ||
21148 ++ !name_set.n_size || !inodev_set.i_size)
21149 ++ return 1;
21150 ++
21151 ++ if (!gr_init_uidset())
21152 ++ return 1;
21153 ++
21154 ++ /* set up the stack that holds allocation info */
21155 ++
21156 ++ stacksize = arg->role_db.num_pointers + 5;
21157 ++
21158 ++ if (!acl_alloc_stack_init(stacksize))
21159 ++ return 1;
21160 ++
21161 ++ /* grab reference for the real root dentry and vfsmount */
21162 ++ read_lock(&reaper->fs->lock);
21163 ++ real_root_mnt = mntget(reaper->fs->root.mnt);
21164 ++ real_root = dget(reaper->fs->root.dentry);
21165 ++ read_unlock(&reaper->fs->lock);
21166 ++
21167 ++ fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
21168 ++ if (fakefs_obj == NULL)
21169 ++ return 1;
21170 ++ fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
21171 ++
21172 ++ subj_map_set.s_hash =
21173 ++ (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
21174 ++ acl_role_set.r_hash =
21175 ++ (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
21176 ++ name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
21177 ++ inodev_set.i_hash =
21178 ++ (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
21179 ++
21180 ++ if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
21181 ++ !name_set.n_hash || !inodev_set.i_hash)
21182 ++ return 1;
21183 ++
21184 ++ memset(subj_map_set.s_hash, 0,
21185 ++ sizeof(struct subject_map *) * subj_map_set.s_size);
21186 ++ memset(acl_role_set.r_hash, 0,
21187 ++ sizeof (struct acl_role_label *) * acl_role_set.r_size);
21188 ++ memset(name_set.n_hash, 0,
21189 ++ sizeof (struct name_entry *) * name_set.n_size);
21190 ++ memset(inodev_set.i_hash, 0,
21191 ++ sizeof (struct inodev_entry *) * inodev_set.i_size);
21192 ++
21193 ++ return 0;
21194 ++}
21195 ++
21196 ++/* free information not needed after startup
21197 ++ currently contains user->kernel pointer mappings for subjects
21198 ++*/
21199 ++
21200 ++static void
21201 ++free_init_variables(void)
21202 ++{
21203 ++ __u32 i;
21204 ++
21205 ++ if (subj_map_set.s_hash) {
21206 ++ for (i = 0; i < subj_map_set.s_size; i++) {
21207 ++ if (subj_map_set.s_hash[i]) {
21208 ++ kfree(subj_map_set.s_hash[i]);
21209 ++ subj_map_set.s_hash[i] = NULL;
21210 ++ }
21211 ++ }
21212 ++
21213 ++ if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
21214 ++ PAGE_SIZE)
21215 ++ kfree(subj_map_set.s_hash);
21216 ++ else
21217 ++ vfree(subj_map_set.s_hash);
21218 ++ }
21219 ++
21220 ++ return;
21221 ++}
21222 ++
21223 ++static void
21224 ++free_variables(void)
21225 ++{
21226 ++ struct acl_subject_label *s;
21227 ++ struct acl_role_label *r;
21228 ++ struct task_struct *task, *task2;
21229 ++ unsigned int i, x;
21230 ++
21231 ++ gr_clear_learn_entries();
21232 ++
21233 ++ read_lock(&tasklist_lock);
21234 ++ do_each_thread(task2, task) {
21235 ++ task->acl_sp_role = 0;
21236 ++ task->acl_role_id = 0;
21237 ++ task->acl = NULL;
21238 ++ task->role = NULL;
21239 ++ } while_each_thread(task2, task);
21240 ++ read_unlock(&tasklist_lock);
21241 ++
21242 ++ /* release the reference to the real root dentry and vfsmount */
21243 ++ if (real_root)
21244 ++ dput(real_root);
21245 ++ real_root = NULL;
21246 ++ if (real_root_mnt)
21247 ++ mntput(real_root_mnt);
21248 ++ real_root_mnt = NULL;
21249 ++
21250 ++ /* free all object hash tables */
21251 ++
21252 ++ FOR_EACH_ROLE_START(r, i)
21253 ++ if (r->subj_hash == NULL)
21254 ++ break;
21255 ++ FOR_EACH_SUBJECT_START(r, s, x)
21256 ++ if (s->obj_hash == NULL)
21257 ++ break;
21258 ++ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
21259 ++ kfree(s->obj_hash);
21260 ++ else
21261 ++ vfree(s->obj_hash);
21262 ++ FOR_EACH_SUBJECT_END(s, x)
21263 ++ FOR_EACH_NESTED_SUBJECT_START(r, s)
21264 ++ if (s->obj_hash == NULL)
21265 ++ break;
21266 ++ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
21267 ++ kfree(s->obj_hash);
21268 ++ else
21269 ++ vfree(s->obj_hash);
21270 ++ FOR_EACH_NESTED_SUBJECT_END(s)
21271 ++ if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
21272 ++ kfree(r->subj_hash);
21273 ++ else
21274 ++ vfree(r->subj_hash);
21275 ++ r->subj_hash = NULL;
21276 ++ FOR_EACH_ROLE_END(r,i)
21277 ++
21278 ++ acl_free_all();
21279 ++
21280 ++ if (acl_role_set.r_hash) {
21281 ++ if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
21282 ++ PAGE_SIZE)
21283 ++ kfree(acl_role_set.r_hash);
21284 ++ else
21285 ++ vfree(acl_role_set.r_hash);
21286 ++ }
21287 ++ if (name_set.n_hash) {
21288 ++ if ((name_set.n_size * sizeof (struct name_entry *)) <=
21289 ++ PAGE_SIZE)
21290 ++ kfree(name_set.n_hash);
21291 ++ else
21292 ++ vfree(name_set.n_hash);
21293 ++ }
21294 ++
21295 ++ if (inodev_set.i_hash) {
21296 ++ if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
21297 ++ PAGE_SIZE)
21298 ++ kfree(inodev_set.i_hash);
21299 ++ else
21300 ++ vfree(inodev_set.i_hash);
21301 ++ }
21302 ++
21303 ++ gr_free_uidset();
21304 ++
21305 ++ memset(&name_set, 0, sizeof (struct name_db));
21306 ++ memset(&inodev_set, 0, sizeof (struct inodev_db));
21307 ++ memset(&acl_role_set, 0, sizeof (struct acl_role_db));
21308 ++ memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
21309 ++
21310 ++ default_role = NULL;
21311 ++
21312 ++ return;
21313 ++}
21314 ++
21315 ++static __u32
21316 ++count_user_objs(struct acl_object_label *userp)
21317 ++{
21318 ++ struct acl_object_label o_tmp;
21319 ++ __u32 num = 0;
21320 ++
21321 ++ while (userp) {
21322 ++ if (copy_from_user(&o_tmp, userp,
21323 ++ sizeof (struct acl_object_label)))
21324 ++ break;
21325 ++
21326 ++ userp = o_tmp.prev;
21327 ++ num++;
21328 ++ }
21329 ++
21330 ++ return num;
21331 ++}
21332 ++
21333 ++static struct acl_subject_label *
21334 ++do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
21335 ++
21336 ++static int
21337 ++copy_user_glob(struct acl_object_label *obj)
21338 ++{
21339 ++ struct acl_object_label *g_tmp, **guser;
21340 ++ unsigned int len;
21341 ++ char *tmp;
21342 ++
21343 ++ if (obj->globbed == NULL)
21344 ++ return 0;
21345 ++
21346 ++ guser = &obj->globbed;
21347 ++ while (*guser) {
21348 ++ g_tmp = (struct acl_object_label *)
21349 ++ acl_alloc(sizeof (struct acl_object_label));
21350 ++ if (g_tmp == NULL)
21351 ++ return -ENOMEM;
21352 ++
21353 ++ if (copy_from_user(g_tmp, *guser,
21354 ++ sizeof (struct acl_object_label)))
21355 ++ return -EFAULT;
21356 ++
21357 ++ len = strnlen_user(g_tmp->filename, PATH_MAX);
21358 ++
21359 ++ if (!len || len >= PATH_MAX)
21360 ++ return -EINVAL;
21361 ++
21362 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
21363 ++ return -ENOMEM;
21364 ++
21365 ++ if (copy_from_user(tmp, g_tmp->filename, len))
21366 ++ return -EFAULT;
21367 ++
21368 ++ g_tmp->filename = tmp;
21369 ++
21370 ++ *guser = g_tmp;
21371 ++ guser = &(g_tmp->next);
21372 ++ }
21373 ++
21374 ++ return 0;
21375 ++}
21376 ++
21377 ++static int
21378 ++copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
21379 ++ struct acl_role_label *role)
21380 ++{
21381 ++ struct acl_object_label *o_tmp;
21382 ++ unsigned int len;
21383 ++ int ret;
21384 ++ char *tmp;
21385 ++
21386 ++ while (userp) {
21387 ++ if ((o_tmp = (struct acl_object_label *)
21388 ++ acl_alloc(sizeof (struct acl_object_label))) == NULL)
21389 ++ return -ENOMEM;
21390 ++
21391 ++ if (copy_from_user(o_tmp, userp,
21392 ++ sizeof (struct acl_object_label)))
21393 ++ return -EFAULT;
21394 ++
21395 ++ userp = o_tmp->prev;
21396 ++
21397 ++ len = strnlen_user(o_tmp->filename, PATH_MAX);
21398 ++
21399 ++ if (!len || len >= PATH_MAX)
21400 ++ return -EINVAL;
21401 ++
21402 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
21403 ++ return -ENOMEM;
21404 ++
21405 ++ if (copy_from_user(tmp, o_tmp->filename, len))
21406 ++ return -EFAULT;
21407 ++
21408 ++ o_tmp->filename = tmp;
21409 ++
21410 ++ insert_acl_obj_label(o_tmp, subj);
21411 ++ if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
21412 ++ o_tmp->device, (o_tmp->mode & GR_DELETED) ? 1 : 0))
21413 ++ return -ENOMEM;
21414 ++
21415 ++ ret = copy_user_glob(o_tmp);
21416 ++ if (ret)
21417 ++ return ret;
21418 ++
21419 ++ if (o_tmp->nested) {
21420 ++ o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
21421 ++ if (IS_ERR(o_tmp->nested))
21422 ++ return PTR_ERR(o_tmp->nested);
21423 ++
21424 ++ /* insert into nested subject list */
21425 ++ o_tmp->nested->next = role->hash->first;
21426 ++ role->hash->first = o_tmp->nested;
21427 ++ }
21428 ++ }
21429 ++
21430 ++ return 0;
21431 ++}
21432 ++
21433 ++static __u32
21434 ++count_user_subjs(struct acl_subject_label *userp)
21435 ++{
21436 ++ struct acl_subject_label s_tmp;
21437 ++ __u32 num = 0;
21438 ++
21439 ++ while (userp) {
21440 ++ if (copy_from_user(&s_tmp, userp,
21441 ++ sizeof (struct acl_subject_label)))
21442 ++ break;
21443 ++
21444 ++ userp = s_tmp.prev;
21445 ++ /* do not count nested subjects against this count, since
21446 ++ they are not included in the hash table, but are
21447 ++ attached to objects. We have already counted
21448 ++ the subjects in userspace for the allocation
21449 ++ stack
21450 ++ */
21451 ++ if (!(s_tmp.mode & GR_NESTED))
21452 ++ num++;
21453 ++ }
21454 ++
21455 ++ return num;
21456 ++}
21457 ++
21458 ++static int
21459 ++copy_user_allowedips(struct acl_role_label *rolep)
21460 ++{
21461 ++ struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
21462 ++
21463 ++ ruserip = rolep->allowed_ips;
21464 ++
21465 ++ while (ruserip) {
21466 ++ rlast = rtmp;
21467 ++
21468 ++ if ((rtmp = (struct role_allowed_ip *)
21469 ++ acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
21470 ++ return -ENOMEM;
21471 ++
21472 ++ if (copy_from_user(rtmp, ruserip,
21473 ++ sizeof (struct role_allowed_ip)))
21474 ++ return -EFAULT;
21475 ++
21476 ++ ruserip = rtmp->prev;
21477 ++
21478 ++ if (!rlast) {
21479 ++ rtmp->prev = NULL;
21480 ++ rolep->allowed_ips = rtmp;
21481 ++ } else {
21482 ++ rlast->next = rtmp;
21483 ++ rtmp->prev = rlast;
21484 ++ }
21485 ++
21486 ++ if (!ruserip)
21487 ++ rtmp->next = NULL;
21488 ++ }
21489 ++
21490 ++ return 0;
21491 ++}
21492 ++
21493 ++static int
21494 ++copy_user_transitions(struct acl_role_label *rolep)
21495 ++{
21496 ++ struct role_transition *rusertp, *rtmp = NULL, *rlast;
21497 ++
21498 ++ unsigned int len;
21499 ++ char *tmp;
21500 ++
21501 ++ rusertp = rolep->transitions;
21502 ++
21503 ++ while (rusertp) {
21504 ++ rlast = rtmp;
21505 ++
21506 ++ if ((rtmp = (struct role_transition *)
21507 ++ acl_alloc(sizeof (struct role_transition))) == NULL)
21508 ++ return -ENOMEM;
21509 ++
21510 ++ if (copy_from_user(rtmp, rusertp,
21511 ++ sizeof (struct role_transition)))
21512 ++ return -EFAULT;
21513 ++
21514 ++ rusertp = rtmp->prev;
21515 ++
21516 ++ len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
21517 ++
21518 ++ if (!len || len >= GR_SPROLE_LEN)
21519 ++ return -EINVAL;
21520 ++
21521 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
21522 ++ return -ENOMEM;
21523 ++
21524 ++ if (copy_from_user(tmp, rtmp->rolename, len))
21525 ++ return -EFAULT;
21526 ++
21527 ++ rtmp->rolename = tmp;
21528 ++
21529 ++ if (!rlast) {
21530 ++ rtmp->prev = NULL;
21531 ++ rolep->transitions = rtmp;
21532 ++ } else {
21533 ++ rlast->next = rtmp;
21534 ++ rtmp->prev = rlast;
21535 ++ }
21536 ++
21537 ++ if (!rusertp)
21538 ++ rtmp->next = NULL;
21539 ++ }
21540 ++
21541 ++ return 0;
21542 ++}
21543 ++
21544 ++static struct acl_subject_label *
21545 ++do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
21546 ++{
21547 ++ struct acl_subject_label *s_tmp = NULL, *s_tmp2;
21548 ++ unsigned int len;
21549 ++ char *tmp;
21550 ++ __u32 num_objs;
21551 ++ struct acl_ip_label **i_tmp, *i_utmp2;
21552 ++ struct gr_hash_struct ghash;
21553 ++ struct subject_map *subjmap;
21554 ++ unsigned int i_num;
21555 ++ int err;
21556 ++
21557 ++ s_tmp = lookup_subject_map(userp);
21558 ++
21559 ++ /* we've already copied this subject into the kernel, just return
21560 ++ the reference to it, and don't copy it over again
21561 ++ */
21562 ++ if (s_tmp)
21563 ++ return(s_tmp);
21564 ++
21565 ++ if ((s_tmp = (struct acl_subject_label *)
21566 ++ acl_alloc(sizeof (struct acl_subject_label))) == NULL)
21567 ++ return ERR_PTR(-ENOMEM);
21568 ++
21569 ++ subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
21570 ++ if (subjmap == NULL)
21571 ++ return ERR_PTR(-ENOMEM);
21572 ++
21573 ++ subjmap->user = userp;
21574 ++ subjmap->kernel = s_tmp;
21575 ++ insert_subj_map_entry(subjmap);
21576 ++
21577 ++ if (copy_from_user(s_tmp, userp,
21578 ++ sizeof (struct acl_subject_label)))
21579 ++ return ERR_PTR(-EFAULT);
21580 ++
21581 ++ len = strnlen_user(s_tmp->filename, PATH_MAX);
21582 ++
21583 ++ if (!len || len >= PATH_MAX)
21584 ++ return ERR_PTR(-EINVAL);
21585 ++
21586 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
21587 ++ return ERR_PTR(-ENOMEM);
21588 ++
21589 ++ if (copy_from_user(tmp, s_tmp->filename, len))
21590 ++ return ERR_PTR(-EFAULT);
21591 ++
21592 ++ s_tmp->filename = tmp;
21593 ++
21594 ++ if (!strcmp(s_tmp->filename, "/"))
21595 ++ role->root_label = s_tmp;
21596 ++
21597 ++ if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
21598 ++ return ERR_PTR(-EFAULT);
21599 ++
21600 ++ /* copy user and group transition tables */
21601 ++
21602 ++ if (s_tmp->user_trans_num) {
21603 ++ uid_t *uidlist;
21604 ++
21605 ++ uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
21606 ++ if (uidlist == NULL)
21607 ++ return ERR_PTR(-ENOMEM);
21608 ++ if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
21609 ++ return ERR_PTR(-EFAULT);
21610 ++
21611 ++ s_tmp->user_transitions = uidlist;
21612 ++ }
21613 ++
21614 ++ if (s_tmp->group_trans_num) {
21615 ++ gid_t *gidlist;
21616 ++
21617 ++ gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
21618 ++ if (gidlist == NULL)
21619 ++ return ERR_PTR(-ENOMEM);
21620 ++ if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
21621 ++ return ERR_PTR(-EFAULT);
21622 ++
21623 ++ s_tmp->group_transitions = gidlist;
21624 ++ }
21625 ++
21626 ++ /* set up object hash table */
21627 ++ num_objs = count_user_objs(ghash.first);
21628 ++
21629 ++ s_tmp->obj_hash_size = num_objs;
21630 ++ s_tmp->obj_hash =
21631 ++ (struct acl_object_label **)
21632 ++ create_table(&(s_tmp->obj_hash_size), sizeof(void *));
21633 ++
21634 ++ if (!s_tmp->obj_hash)
21635 ++ return ERR_PTR(-ENOMEM);
21636 ++
21637 ++ memset(s_tmp->obj_hash, 0,
21638 ++ s_tmp->obj_hash_size *
21639 ++ sizeof (struct acl_object_label *));
21640 ++
21641 ++ /* add in objects */
21642 ++ err = copy_user_objs(ghash.first, s_tmp, role);
21643 ++
21644 ++ if (err)
21645 ++ return ERR_PTR(err);
21646 ++
21647 ++ /* set pointer for parent subject */
21648 ++ if (s_tmp->parent_subject) {
21649 ++ s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
21650 ++
21651 ++ if (IS_ERR(s_tmp2))
21652 ++ return s_tmp2;
21653 ++
21654 ++ s_tmp->parent_subject = s_tmp2;
21655 ++ }
21656 ++
21657 ++ /* add in ip acls */
21658 ++
21659 ++ if (!s_tmp->ip_num) {
21660 ++ s_tmp->ips = NULL;
21661 ++ goto insert;
21662 ++ }
21663 ++
21664 ++ i_tmp =
21665 ++ (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
21666 ++ sizeof (struct
21667 ++ acl_ip_label *));
21668 ++
21669 ++ if (!i_tmp)
21670 ++ return ERR_PTR(-ENOMEM);
21671 ++
21672 ++ for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
21673 ++ *(i_tmp + i_num) =
21674 ++ (struct acl_ip_label *)
21675 ++ acl_alloc(sizeof (struct acl_ip_label));
21676 ++ if (!*(i_tmp + i_num))
21677 ++ return ERR_PTR(-ENOMEM);
21678 ++
21679 ++ if (copy_from_user
21680 ++ (&i_utmp2, s_tmp->ips + i_num,
21681 ++ sizeof (struct acl_ip_label *)))
21682 ++ return ERR_PTR(-EFAULT);
21683 ++
21684 ++ if (copy_from_user
21685 ++ (*(i_tmp + i_num), i_utmp2,
21686 ++ sizeof (struct acl_ip_label)))
21687 ++ return ERR_PTR(-EFAULT);
21688 ++
21689 ++ if ((*(i_tmp + i_num))->iface == NULL)
21690 ++ continue;
21691 ++
21692 ++ len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
21693 ++ if (!len || len >= IFNAMSIZ)
21694 ++ return ERR_PTR(-EINVAL);
21695 ++ tmp = acl_alloc(len);
21696 ++ if (tmp == NULL)
21697 ++ return ERR_PTR(-ENOMEM);
21698 ++ if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
21699 ++ return ERR_PTR(-EFAULT);
21700 ++ (*(i_tmp + i_num))->iface = tmp;
21701 ++ }
21702 ++
21703 ++ s_tmp->ips = i_tmp;
21704 ++
21705 ++insert:
21706 ++ if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
21707 ++ s_tmp->device, (s_tmp->mode & GR_DELETED) ? 1 : 0))
21708 ++ return ERR_PTR(-ENOMEM);
21709 ++
21710 ++ return s_tmp;
21711 ++}
21712 ++
21713 ++static int
21714 ++copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
21715 ++{
21716 ++ struct acl_subject_label s_pre;
21717 ++ struct acl_subject_label * ret;
21718 ++ int err;
21719 ++
21720 ++ while (userp) {
21721 ++ if (copy_from_user(&s_pre, userp,
21722 ++ sizeof (struct acl_subject_label)))
21723 ++ return -EFAULT;
21724 ++
21725 ++ /* do not add nested subjects here, add
21726 ++ while parsing objects
21727 ++ */
21728 ++
21729 ++ if (s_pre.mode & GR_NESTED) {
21730 ++ userp = s_pre.prev;
21731 ++ continue;
21732 ++ }
21733 ++
21734 ++ ret = do_copy_user_subj(userp, role);
21735 ++
21736 ++ err = PTR_ERR(ret);
21737 ++ if (IS_ERR(ret))
21738 ++ return err;
21739 ++
21740 ++ insert_acl_subj_label(ret, role);
21741 ++
21742 ++ userp = s_pre.prev;
21743 ++ }
21744 ++
21745 ++ return 0;
21746 ++}
21747 ++
21748 ++static int
21749 ++copy_user_acl(struct gr_arg *arg)
21750 ++{
21751 ++ struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
21752 ++ struct sprole_pw *sptmp;
21753 ++ struct gr_hash_struct *ghash;
21754 ++ uid_t *domainlist;
21755 ++ unsigned int r_num;
21756 ++ unsigned int len;
21757 ++ char *tmp;
21758 ++ int err = 0;
21759 ++ __u16 i;
21760 ++ __u32 num_subjs;
21761 ++
21762 ++ /* we need a default and kernel role */
21763 ++ if (arg->role_db.num_roles < 2)
21764 ++ return -EINVAL;
21765 ++
21766 ++ /* copy special role authentication info from userspace */
21767 ++
21768 ++ num_sprole_pws = arg->num_sprole_pws;
21769 ++ acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
21770 ++
21771 ++ if (!acl_special_roles) {
21772 ++ err = -ENOMEM;
21773 ++ goto cleanup;
21774 ++ }
21775 ++
21776 ++ for (i = 0; i < num_sprole_pws; i++) {
21777 ++ sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
21778 ++ if (!sptmp) {
21779 ++ err = -ENOMEM;
21780 ++ goto cleanup;
21781 ++ }
21782 ++ if (copy_from_user(sptmp, arg->sprole_pws + i,
21783 ++ sizeof (struct sprole_pw))) {
21784 ++ err = -EFAULT;
21785 ++ goto cleanup;
21786 ++ }
21787 ++
21788 ++ len =
21789 ++ strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
21790 ++
21791 ++ if (!len || len >= GR_SPROLE_LEN) {
21792 ++ err = -EINVAL;
21793 ++ goto cleanup;
21794 ++ }
21795 ++
21796 ++ if ((tmp = (char *) acl_alloc(len)) == NULL) {
21797 ++ err = -ENOMEM;
21798 ++ goto cleanup;
21799 ++ }
21800 ++
21801 ++ if (copy_from_user(tmp, sptmp->rolename, len)) {
21802 ++ err = -EFAULT;
21803 ++ goto cleanup;
21804 ++ }
21805 ++
21806 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
21807 ++ printk(KERN_ALERT "Copying special role %s\n", tmp);
21808 ++#endif
21809 ++ sptmp->rolename = tmp;
21810 ++ acl_special_roles[i] = sptmp;
21811 ++ }
21812 ++
21813 ++ r_utmp = (struct acl_role_label **) arg->role_db.r_table;
21814 ++
21815 ++ for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
21816 ++ r_tmp = acl_alloc(sizeof (struct acl_role_label));
21817 ++
21818 ++ if (!r_tmp) {
21819 ++ err = -ENOMEM;
21820 ++ goto cleanup;
21821 ++ }
21822 ++
21823 ++ if (copy_from_user(&r_utmp2, r_utmp + r_num,
21824 ++ sizeof (struct acl_role_label *))) {
21825 ++ err = -EFAULT;
21826 ++ goto cleanup;
21827 ++ }
21828 ++
21829 ++ if (copy_from_user(r_tmp, r_utmp2,
21830 ++ sizeof (struct acl_role_label))) {
21831 ++ err = -EFAULT;
21832 ++ goto cleanup;
21833 ++ }
21834 ++
21835 ++ len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
21836 ++
21837 ++ if (!len || len >= PATH_MAX) {
21838 ++ err = -EINVAL;
21839 ++ goto cleanup;
21840 ++ }
21841 ++
21842 ++ if ((tmp = (char *) acl_alloc(len)) == NULL) {
21843 ++ err = -ENOMEM;
21844 ++ goto cleanup;
21845 ++ }
21846 ++ if (copy_from_user(tmp, r_tmp->rolename, len)) {
21847 ++ err = -EFAULT;
21848 ++ goto cleanup;
21849 ++ }
21850 ++ r_tmp->rolename = tmp;
21851 ++
21852 ++ if (!strcmp(r_tmp->rolename, "default")
21853 ++ && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
21854 ++ default_role = r_tmp;
21855 ++ } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
21856 ++ kernel_role = r_tmp;
21857 ++ }
21858 ++
21859 ++ if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
21860 ++ err = -ENOMEM;
21861 ++ goto cleanup;
21862 ++ }
21863 ++ if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
21864 ++ err = -EFAULT;
21865 ++ goto cleanup;
21866 ++ }
21867 ++
21868 ++ r_tmp->hash = ghash;
21869 ++
21870 ++ num_subjs = count_user_subjs(r_tmp->hash->first);
21871 ++
21872 ++ r_tmp->subj_hash_size = num_subjs;
21873 ++ r_tmp->subj_hash =
21874 ++ (struct acl_subject_label **)
21875 ++ create_table(&(r_tmp->subj_hash_size), sizeof(void *));
21876 ++
21877 ++ if (!r_tmp->subj_hash) {
21878 ++ err = -ENOMEM;
21879 ++ goto cleanup;
21880 ++ }
21881 ++
21882 ++ err = copy_user_allowedips(r_tmp);
21883 ++ if (err)
21884 ++ goto cleanup;
21885 ++
21886 ++ /* copy domain info */
21887 ++ if (r_tmp->domain_children != NULL) {
21888 ++ domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
21889 ++ if (domainlist == NULL) {
21890 ++ err = -ENOMEM;
21891 ++ goto cleanup;
21892 ++ }
21893 ++ if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
21894 ++ err = -EFAULT;
21895 ++ goto cleanup;
21896 ++ }
21897 ++ r_tmp->domain_children = domainlist;
21898 ++ }
21899 ++
21900 ++ err = copy_user_transitions(r_tmp);
21901 ++ if (err)
21902 ++ goto cleanup;
21903 ++
21904 ++ memset(r_tmp->subj_hash, 0,
21905 ++ r_tmp->subj_hash_size *
21906 ++ sizeof (struct acl_subject_label *));
21907 ++
21908 ++ err = copy_user_subjs(r_tmp->hash->first, r_tmp);
21909 ++
21910 ++ if (err)
21911 ++ goto cleanup;
21912 ++
21913 ++ /* set nested subject list to null */
21914 ++ r_tmp->hash->first = NULL;
21915 ++
21916 ++ insert_acl_role_label(r_tmp);
21917 ++ }
21918 ++
21919 ++ goto return_err;
21920 ++ cleanup:
21921 ++ free_variables();
21922 ++ return_err:
21923 ++ return err;
21924 ++
21925 ++}
21926 ++
21927 ++static int
21928 ++gracl_init(struct gr_arg *args)
21929 ++{
21930 ++ int error = 0;
21931 ++
21932 ++ memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
21933 ++ memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
21934 ++
21935 ++ if (init_variables(args)) {
21936 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
21937 ++ error = -ENOMEM;
21938 ++ free_variables();
21939 ++ goto out;
21940 ++ }
21941 ++
21942 ++ error = copy_user_acl(args);
21943 ++ free_init_variables();
21944 ++ if (error) {
21945 ++ free_variables();
21946 ++ goto out;
21947 ++ }
21948 ++
21949 ++ if ((error = gr_set_acls(0))) {
21950 ++ free_variables();
21951 ++ goto out;
21952 ++ }
21953 ++
21954 ++ gr_status |= GR_READY;
21955 ++ out:
21956 ++ return error;
21957 ++}
21958 ++
21959 ++/* derived from glibc fnmatch() 0: match, 1: no match*/
21960 ++
21961 ++static int
21962 ++glob_match(const char *p, const char *n)
21963 ++{
21964 ++ char c;
21965 ++
21966 ++ while ((c = *p++) != '\0') {
21967 ++ switch (c) {
21968 ++ case '?':
21969 ++ if (*n == '\0')
21970 ++ return 1;
21971 ++ else if (*n == '/')
21972 ++ return 1;
21973 ++ break;
21974 ++ case '\\':
21975 ++ if (*n != c)
21976 ++ return 1;
21977 ++ break;
21978 ++ case '*':
21979 ++ for (c = *p++; c == '?' || c == '*'; c = *p++) {
21980 ++ if (*n == '/')
21981 ++ return 1;
21982 ++ else if (c == '?') {
21983 ++ if (*n == '\0')
21984 ++ return 1;
21985 ++ else
21986 ++ ++n;
21987 ++ }
21988 ++ }
21989 ++ if (c == '\0') {
21990 ++ return 0;
21991 ++ } else {
21992 ++ const char *endp;
21993 ++
21994 ++ if ((endp = strchr(n, '/')) == NULL)
21995 ++ endp = n + strlen(n);
21996 ++
21997 ++ if (c == '[') {
21998 ++ for (--p; n < endp; ++n)
21999 ++ if (!glob_match(p, n))
22000 ++ return 0;
22001 ++ } else if (c == '/') {
22002 ++ while (*n != '\0' && *n != '/')
22003 ++ ++n;
22004 ++ if (*n == '/' && !glob_match(p, n + 1))
22005 ++ return 0;
22006 ++ } else {
22007 ++ for (--p; n < endp; ++n)
22008 ++ if (*n == c && !glob_match(p, n))
22009 ++ return 0;
22010 ++ }
22011 ++
22012 ++ return 1;
22013 ++ }
22014 ++ case '[':
22015 ++ {
22016 ++ int not;
22017 ++ char cold;
22018 ++
22019 ++ if (*n == '\0' || *n == '/')
22020 ++ return 1;
22021 ++
22022 ++ not = (*p == '!' || *p == '^');
22023 ++ if (not)
22024 ++ ++p;
22025 ++
22026 ++ c = *p++;
22027 ++ for (;;) {
22028 ++ unsigned char fn = (unsigned char)*n;
22029 ++
22030 ++ if (c == '\0')
22031 ++ return 1;
22032 ++ else {
22033 ++ if (c == fn)
22034 ++ goto matched;
22035 ++ cold = c;
22036 ++ c = *p++;
22037 ++
22038 ++ if (c == '-' && *p != ']') {
22039 ++ unsigned char cend = *p++;
22040 ++
22041 ++ if (cend == '\0')
22042 ++ return 1;
22043 ++
22044 ++ if (cold <= fn && fn <= cend)
22045 ++ goto matched;
22046 ++
22047 ++ c = *p++;
22048 ++ }
22049 ++ }
22050 ++
22051 ++ if (c == ']')
22052 ++ break;
22053 ++ }
22054 ++ if (!not)
22055 ++ return 1;
22056 ++ break;
22057 ++ matched:
22058 ++ while (c != ']') {
22059 ++ if (c == '\0')
22060 ++ return 1;
22061 ++
22062 ++ c = *p++;
22063 ++ }
22064 ++ if (not)
22065 ++ return 1;
22066 ++ }
22067 ++ break;
22068 ++ default:
22069 ++ if (c != *n)
22070 ++ return 1;
22071 ++ }
22072 ++
22073 ++ ++n;
22074 ++ }
22075 ++
22076 ++ if (*n == '\0')
22077 ++ return 0;
22078 ++
22079 ++ if (*n == '/')
22080 ++ return 0;
22081 ++
22082 ++ return 1;
22083 ++}
22084 ++
22085 ++static struct acl_object_label *
22086 ++chk_glob_label(struct acl_object_label *globbed,
22087 ++ struct dentry *dentry, struct vfsmount *mnt, char **path)
22088 ++{
22089 ++ struct acl_object_label *tmp;
22090 ++
22091 ++ if (*path == NULL)
22092 ++ *path = gr_to_filename_nolock(dentry, mnt);
22093 ++
22094 ++ tmp = globbed;
22095 ++
22096 ++ while (tmp) {
22097 ++ if (!glob_match(tmp->filename, *path))
22098 ++ return tmp;
22099 ++ tmp = tmp->next;
22100 ++ }
22101 ++
22102 ++ return NULL;
22103 ++}
22104 ++
22105 ++static struct acl_object_label *
22106 ++__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
22107 ++ const ino_t curr_ino, const dev_t curr_dev,
22108 ++ const struct acl_subject_label *subj, char **path)
22109 ++{
22110 ++ struct acl_subject_label *tmpsubj;
22111 ++ struct acl_object_label *retval;
22112 ++ struct acl_object_label *retval2;
22113 ++
22114 ++ tmpsubj = (struct acl_subject_label *) subj;
22115 ++ read_lock(&gr_inode_lock);
22116 ++ do {
22117 ++ retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
22118 ++ if (retval) {
22119 ++ if (retval->globbed) {
22120 ++ retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
22121 ++ (struct vfsmount *)orig_mnt, path);
22122 ++ if (retval2)
22123 ++ retval = retval2;
22124 ++ }
22125 ++ break;
22126 ++ }
22127 ++ } while ((tmpsubj = tmpsubj->parent_subject));
22128 ++ read_unlock(&gr_inode_lock);
22129 ++
22130 ++ return retval;
22131 ++}
22132 ++
22133 ++static __inline__ struct acl_object_label *
22134 ++full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
22135 ++ const struct dentry *curr_dentry,
22136 ++ const struct acl_subject_label *subj, char **path)
22137 ++{
22138 ++ return __full_lookup(orig_dentry, orig_mnt,
22139 ++ curr_dentry->d_inode->i_ino,
22140 ++ curr_dentry->d_inode->i_sb->s_dev, subj, path);
22141 ++}
22142 ++
22143 ++static struct acl_object_label *
22144 ++__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
22145 ++ const struct acl_subject_label *subj, char *path)
22146 ++{
22147 ++ struct dentry *dentry = (struct dentry *) l_dentry;
22148 ++ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
22149 ++ struct acl_object_label *retval;
22150 ++
22151 ++ spin_lock(&dcache_lock);
22152 ++
22153 ++ if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt ||
22154 ++ /* ignore Eric Biederman */
22155 ++ IS_PRIVATE(l_dentry->d_inode))) {
22156 ++ retval = fakefs_obj;
22157 ++ goto out;
22158 ++ }
22159 ++
22160 ++ for (;;) {
22161 ++ if (dentry == real_root && mnt == real_root_mnt)
22162 ++ break;
22163 ++
22164 ++ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
22165 ++ if (mnt->mnt_parent == mnt)
22166 ++ break;
22167 ++
22168 ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
22169 ++ if (retval != NULL)
22170 ++ goto out;
22171 ++
22172 ++ dentry = mnt->mnt_mountpoint;
22173 ++ mnt = mnt->mnt_parent;
22174 ++ continue;
22175 ++ }
22176 ++
22177 ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
22178 ++ if (retval != NULL)
22179 ++ goto out;
22180 ++
22181 ++ dentry = dentry->d_parent;
22182 ++ }
22183 ++
22184 ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
22185 ++
22186 ++ if (retval == NULL)
22187 ++ retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
22188 ++out:
22189 ++ spin_unlock(&dcache_lock);
22190 ++ return retval;
22191 ++}
22192 ++
22193 ++static __inline__ struct acl_object_label *
22194 ++chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
22195 ++ const struct acl_subject_label *subj)
22196 ++{
22197 ++ char *path = NULL;
22198 ++ return __chk_obj_label(l_dentry, l_mnt, subj, path);
22199 ++}
22200 ++
22201 ++static __inline__ struct acl_object_label *
22202 ++chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
22203 ++ const struct acl_subject_label *subj, char *path)
22204 ++{
22205 ++ return __chk_obj_label(l_dentry, l_mnt, subj, path);
22206 ++}
22207 ++
22208 ++static struct acl_subject_label *
22209 ++chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
22210 ++ const struct acl_role_label *role)
22211 ++{
22212 ++ struct dentry *dentry = (struct dentry *) l_dentry;
22213 ++ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
22214 ++ struct acl_subject_label *retval;
22215 ++
22216 ++ spin_lock(&dcache_lock);
22217 ++
22218 ++ for (;;) {
22219 ++ if (dentry == real_root && mnt == real_root_mnt)
22220 ++ break;
22221 ++ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
22222 ++ if (mnt->mnt_parent == mnt)
22223 ++ break;
22224 ++
22225 ++ read_lock(&gr_inode_lock);
22226 ++ retval =
22227 ++ lookup_acl_subj_label(dentry->d_inode->i_ino,
22228 ++ dentry->d_inode->i_sb->s_dev, role);
22229 ++ read_unlock(&gr_inode_lock);
22230 ++ if (retval != NULL)
22231 ++ goto out;
22232 ++
22233 ++ dentry = mnt->mnt_mountpoint;
22234 ++ mnt = mnt->mnt_parent;
22235 ++ continue;
22236 ++ }
22237 ++
22238 ++ read_lock(&gr_inode_lock);
22239 ++ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
22240 ++ dentry->d_inode->i_sb->s_dev, role);
22241 ++ read_unlock(&gr_inode_lock);
22242 ++ if (retval != NULL)
22243 ++ goto out;
22244 ++
22245 ++ dentry = dentry->d_parent;
22246 ++ }
22247 ++
22248 ++ read_lock(&gr_inode_lock);
22249 ++ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
22250 ++ dentry->d_inode->i_sb->s_dev, role);
22251 ++ read_unlock(&gr_inode_lock);
22252 ++
22253 ++ if (unlikely(retval == NULL)) {
22254 ++ read_lock(&gr_inode_lock);
22255 ++ retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
22256 ++ real_root->d_inode->i_sb->s_dev, role);
22257 ++ read_unlock(&gr_inode_lock);
22258 ++ }
22259 ++out:
22260 ++ spin_unlock(&dcache_lock);
22261 ++
22262 ++ return retval;
22263 ++}
22264 ++
22265 ++static void
22266 ++gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
22267 ++{
22268 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
22269 ++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
22270 ++ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
22271 ++ 1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
22272 ++
22273 ++ return;
22274 ++}
22275 ++
22276 ++static void
22277 ++gr_log_learn_sysctl(const struct task_struct *task, const char *path, const __u32 mode)
22278 ++{
22279 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
22280 ++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
22281 ++ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
22282 ++ 1, 1, path, (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
22283 ++
22284 ++ return;
22285 ++}
22286 ++
22287 ++static void
22288 ++gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real,
22289 ++ const unsigned int effective, const unsigned int fs)
22290 ++{
22291 ++ security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
22292 ++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
22293 ++ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
22294 ++ type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
22295 ++
22296 ++ return;
22297 ++}
22298 ++
22299 ++__u32
22300 ++gr_check_link(const struct dentry * new_dentry,
22301 ++ const struct dentry * parent_dentry,
22302 ++ const struct vfsmount * parent_mnt,
22303 ++ const struct dentry * old_dentry, const struct vfsmount * old_mnt)
22304 ++{
22305 ++ struct acl_object_label *obj;
22306 ++ __u32 oldmode, newmode;
22307 ++ __u32 needmode;
22308 ++
22309 ++ if (unlikely(!(gr_status & GR_READY)))
22310 ++ return (GR_CREATE | GR_LINK);
22311 ++
22312 ++ obj = chk_obj_label(old_dentry, old_mnt, current->acl);
22313 ++ oldmode = obj->mode;
22314 ++
22315 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
22316 ++ oldmode |= (GR_CREATE | GR_LINK);
22317 ++
22318 ++ needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
22319 ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
22320 ++ needmode |= GR_SETID | GR_AUDIT_SETID;
22321 ++
22322 ++ newmode =
22323 ++ gr_check_create(new_dentry, parent_dentry, parent_mnt,
22324 ++ oldmode | needmode);
22325 ++
22326 ++ needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
22327 ++ GR_SETID | GR_READ | GR_FIND | GR_DELETE |
22328 ++ GR_INHERIT | GR_AUDIT_INHERIT);
22329 ++
22330 ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
22331 ++ goto bad;
22332 ++
22333 ++ if ((oldmode & needmode) != needmode)
22334 ++ goto bad;
22335 ++
22336 ++ needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
22337 ++ if ((newmode & needmode) != needmode)
22338 ++ goto bad;
22339 ++
22340 ++ if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
22341 ++ return newmode;
22342 ++bad:
22343 ++ needmode = oldmode;
22344 ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
22345 ++ needmode |= GR_SETID;
22346 ++
22347 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
22348 ++ gr_log_learn(current, old_dentry, old_mnt, needmode);
22349 ++ return (GR_CREATE | GR_LINK);
22350 ++ } else if (newmode & GR_SUPPRESS)
22351 ++ return GR_SUPPRESS;
22352 ++ else
22353 ++ return 0;
22354 ++}
22355 ++
22356 ++__u32
22357 ++gr_search_file(const struct dentry * dentry, const __u32 mode,
22358 ++ const struct vfsmount * mnt)
22359 ++{
22360 ++ __u32 retval = mode;
22361 ++ struct acl_subject_label *curracl;
22362 ++ struct acl_object_label *currobj;
22363 ++
22364 ++ if (unlikely(!(gr_status & GR_READY)))
22365 ++ return (mode & ~GR_AUDITS);
22366 ++
22367 ++ curracl = current->acl;
22368 ++
22369 ++ currobj = chk_obj_label(dentry, mnt, curracl);
22370 ++ retval = currobj->mode & mode;
22371 ++
22372 ++ if (unlikely
22373 ++ ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
22374 ++ && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
22375 ++ __u32 new_mode = mode;
22376 ++
22377 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
22378 ++
22379 ++ retval = new_mode;
22380 ++
22381 ++ if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
22382 ++ new_mode |= GR_INHERIT;
22383 ++
22384 ++ if (!(mode & GR_NOLEARN))
22385 ++ gr_log_learn(current, dentry, mnt, new_mode);
22386 ++ }
22387 ++
22388 ++ return retval;
22389 ++}
22390 ++
22391 ++__u32
22392 ++gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
22393 ++ const struct vfsmount * mnt, const __u32 mode)
22394 ++{
22395 ++ struct name_entry *match;
22396 ++ struct acl_object_label *matchpo;
22397 ++ struct acl_subject_label *curracl;
22398 ++ char *path;
22399 ++ __u32 retval;
22400 ++
22401 ++ if (unlikely(!(gr_status & GR_READY)))
22402 ++ return (mode & ~GR_AUDITS);
22403 ++
22404 ++ preempt_disable();
22405 ++ path = gr_to_filename_rbac(new_dentry, mnt);
22406 ++ match = lookup_name_entry_create(path);
22407 ++
22408 ++ if (!match)
22409 ++ goto check_parent;
22410 ++
22411 ++ curracl = current->acl;
22412 ++
22413 ++ read_lock(&gr_inode_lock);
22414 ++ matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
22415 ++ read_unlock(&gr_inode_lock);
22416 ++
22417 ++ if (matchpo) {
22418 ++ if ((matchpo->mode & mode) !=
22419 ++ (mode & ~(GR_AUDITS | GR_SUPPRESS))
22420 ++ && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
22421 ++ __u32 new_mode = mode;
22422 ++
22423 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
22424 ++
22425 ++ gr_log_learn(current, new_dentry, mnt, new_mode);
22426 ++
22427 ++ preempt_enable();
22428 ++ return new_mode;
22429 ++ }
22430 ++ preempt_enable();
22431 ++ return (matchpo->mode & mode);
22432 ++ }
22433 ++
22434 ++ check_parent:
22435 ++ curracl = current->acl;
22436 ++
22437 ++ matchpo = chk_obj_create_label(parent, mnt, curracl, path);
22438 ++ retval = matchpo->mode & mode;
22439 ++
22440 ++ if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
22441 ++ && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
22442 ++ __u32 new_mode = mode;
22443 ++
22444 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
22445 ++
22446 ++ gr_log_learn(current, new_dentry, mnt, new_mode);
22447 ++ preempt_enable();
22448 ++ return new_mode;
22449 ++ }
22450 ++
22451 ++ preempt_enable();
22452 ++ return retval;
22453 ++}
22454 ++
22455 ++int
22456 ++gr_check_hidden_task(const struct task_struct *task)
22457 ++{
22458 ++ if (unlikely(!(gr_status & GR_READY)))
22459 ++ return 0;
22460 ++
22461 ++ if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
22462 ++ return 1;
22463 ++
22464 ++ return 0;
22465 ++}
22466 ++
22467 ++int
22468 ++gr_check_protected_task(const struct task_struct *task)
22469 ++{
22470 ++ if (unlikely(!(gr_status & GR_READY) || !task))
22471 ++ return 0;
22472 ++
22473 ++ if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
22474 ++ task->acl != current->acl)
22475 ++ return 1;
22476 ++
22477 ++ return 0;
22478 ++}
22479 ++
22480 ++void
22481 ++gr_copy_label(struct task_struct *tsk)
22482 ++{
22483 ++ tsk->signal->used_accept = 0;
22484 ++ tsk->acl_sp_role = 0;
22485 ++ tsk->acl_role_id = current->acl_role_id;
22486 ++ tsk->acl = current->acl;
22487 ++ tsk->role = current->role;
22488 ++ tsk->signal->curr_ip = current->signal->curr_ip;
22489 ++ if (current->exec_file)
22490 ++ get_file(current->exec_file);
22491 ++ tsk->exec_file = current->exec_file;
22492 ++ tsk->is_writable = current->is_writable;
22493 ++ if (unlikely(current->signal->used_accept))
22494 ++ current->signal->curr_ip = 0;
22495 ++
22496 ++ return;
22497 ++}
22498 ++
22499 ++static void
22500 ++gr_set_proc_res(struct task_struct *task)
22501 ++{
22502 ++ struct acl_subject_label *proc;
22503 ++ unsigned short i;
22504 ++
22505 ++ proc = task->acl;
22506 ++
22507 ++ if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
22508 ++ return;
22509 ++
22510 ++ for (i = 0; i < (GR_NLIMITS - 1); i++) {
22511 ++ if (!(proc->resmask & (1 << i)))
22512 ++ continue;
22513 ++
22514 ++ task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
22515 ++ task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
22516 ++ }
22517 ++
22518 ++ return;
22519 ++}
22520 ++
22521 ++int
22522 ++gr_check_user_change(int real, int effective, int fs)
22523 ++{
22524 ++ unsigned int i;
22525 ++ __u16 num;
22526 ++ uid_t *uidlist;
22527 ++ int curuid;
22528 ++ int realok = 0;
22529 ++ int effectiveok = 0;
22530 ++ int fsok = 0;
22531 ++
22532 ++ if (unlikely(!(gr_status & GR_READY)))
22533 ++ return 0;
22534 ++
22535 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
22536 ++ gr_log_learn_id_change(current, 'u', real, effective, fs);
22537 ++
22538 ++ num = current->acl->user_trans_num;
22539 ++ uidlist = current->acl->user_transitions;
22540 ++
22541 ++ if (uidlist == NULL)
22542 ++ return 0;
22543 ++
22544 ++ if (real == -1)
22545 ++ realok = 1;
22546 ++ if (effective == -1)
22547 ++ effectiveok = 1;
22548 ++ if (fs == -1)
22549 ++ fsok = 1;
22550 ++
22551 ++ if (current->acl->user_trans_type & GR_ID_ALLOW) {
22552 ++ for (i = 0; i < num; i++) {
22553 ++ curuid = (int)uidlist[i];
22554 ++ if (real == curuid)
22555 ++ realok = 1;
22556 ++ if (effective == curuid)
22557 ++ effectiveok = 1;
22558 ++ if (fs == curuid)
22559 ++ fsok = 1;
22560 ++ }
22561 ++ } else if (current->acl->user_trans_type & GR_ID_DENY) {
22562 ++ for (i = 0; i < num; i++) {
22563 ++ curuid = (int)uidlist[i];
22564 ++ if (real == curuid)
22565 ++ break;
22566 ++ if (effective == curuid)
22567 ++ break;
22568 ++ if (fs == curuid)
22569 ++ break;
22570 ++ }
22571 ++ /* not in deny list */
22572 ++ if (i == num) {
22573 ++ realok = 1;
22574 ++ effectiveok = 1;
22575 ++ fsok = 1;
22576 ++ }
22577 ++ }
22578 ++
22579 ++ if (realok && effectiveok && fsok)
22580 ++ return 0;
22581 ++ else {
22582 ++ gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
22583 ++ return 1;
22584 ++ }
22585 ++}
22586 ++
22587 ++int
22588 ++gr_check_group_change(int real, int effective, int fs)
22589 ++{
22590 ++ unsigned int i;
22591 ++ __u16 num;
22592 ++ gid_t *gidlist;
22593 ++ int curgid;
22594 ++ int realok = 0;
22595 ++ int effectiveok = 0;
22596 ++ int fsok = 0;
22597 ++
22598 ++ if (unlikely(!(gr_status & GR_READY)))
22599 ++ return 0;
22600 ++
22601 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
22602 ++ gr_log_learn_id_change(current, 'g', real, effective, fs);
22603 ++
22604 ++ num = current->acl->group_trans_num;
22605 ++ gidlist = current->acl->group_transitions;
22606 ++
22607 ++ if (gidlist == NULL)
22608 ++ return 0;
22609 ++
22610 ++ if (real == -1)
22611 ++ realok = 1;
22612 ++ if (effective == -1)
22613 ++ effectiveok = 1;
22614 ++ if (fs == -1)
22615 ++ fsok = 1;
22616 ++
22617 ++ if (current->acl->group_trans_type & GR_ID_ALLOW) {
22618 ++ for (i = 0; i < num; i++) {
22619 ++ curgid = (int)gidlist[i];
22620 ++ if (real == curgid)
22621 ++ realok = 1;
22622 ++ if (effective == curgid)
22623 ++ effectiveok = 1;
22624 ++ if (fs == curgid)
22625 ++ fsok = 1;
22626 ++ }
22627 ++ } else if (current->acl->group_trans_type & GR_ID_DENY) {
22628 ++ for (i = 0; i < num; i++) {
22629 ++ curgid = (int)gidlist[i];
22630 ++ if (real == curgid)
22631 ++ break;
22632 ++ if (effective == curgid)
22633 ++ break;
22634 ++ if (fs == curgid)
22635 ++ break;
22636 ++ }
22637 ++ /* not in deny list */
22638 ++ if (i == num) {
22639 ++ realok = 1;
22640 ++ effectiveok = 1;
22641 ++ fsok = 1;
22642 ++ }
22643 ++ }
22644 ++
22645 ++ if (realok && effectiveok && fsok)
22646 ++ return 0;
22647 ++ else {
22648 ++ gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
22649 ++ return 1;
22650 ++ }
22651 ++}
22652 ++
22653 ++void
22654 ++gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
22655 ++{
22656 ++ struct acl_role_label *role = task->role;
22657 ++ struct acl_subject_label *subj = NULL;
22658 ++ struct acl_object_label *obj;
22659 ++ struct file *filp;
22660 ++
22661 ++ if (unlikely(!(gr_status & GR_READY)))
22662 ++ return;
22663 ++
22664 ++ filp = task->exec_file;
22665 ++
22666 ++ /* kernel process, we'll give them the kernel role */
22667 ++ if (unlikely(!filp)) {
22668 ++ task->role = kernel_role;
22669 ++ task->acl = kernel_role->root_label;
22670 ++ return;
22671 ++ } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
22672 ++ role = lookup_acl_role_label(task, uid, gid);
22673 ++
22674 ++ /* perform subject lookup in possibly new role
22675 ++ we can use this result below in the case where role == task->role
22676 ++ */
22677 ++ subj = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, role);
22678 ++
22679 ++ /* if we changed uid/gid, but result in the same role
22680 ++ and are using inheritance, don't lose the inherited subject
22681 ++ if current subject is other than what normal lookup
22682 ++ would result in, we arrived via inheritance, don't
22683 ++ lose subject
22684 ++ */
22685 ++ if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
22686 ++ (subj == task->acl)))
22687 ++ task->acl = subj;
22688 ++
22689 ++ task->role = role;
22690 ++
22691 ++ task->is_writable = 0;
22692 ++
22693 ++ /* ignore additional mmap checks for processes that are writable
22694 ++ by the default ACL */
22695 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
22696 ++ if (unlikely(obj->mode & GR_WRITE))
22697 ++ task->is_writable = 1;
22698 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
22699 ++ if (unlikely(obj->mode & GR_WRITE))
22700 ++ task->is_writable = 1;
22701 ++
22702 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
22703 ++ printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
22704 ++#endif
22705 ++
22706 ++ gr_set_proc_res(task);
22707 ++
22708 ++ return;
22709 ++}
22710 ++
22711 ++int
22712 ++gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
22713 ++{
22714 ++ struct task_struct *task = current;
22715 ++ struct acl_subject_label *newacl;
22716 ++ struct acl_object_label *obj;
22717 ++ __u32 retmode;
22718 ++
22719 ++ if (unlikely(!(gr_status & GR_READY)))
22720 ++ return 0;
22721 ++
22722 ++ newacl = chk_subj_label(dentry, mnt, task->role);
22723 ++
22724 ++ task_lock(task);
22725 ++ if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
22726 ++ GR_POVERRIDE) && (task->acl != newacl) &&
22727 ++ !(task->role->roletype & GR_ROLE_GOD) &&
22728 ++ !gr_search_file(dentry, GR_PTRACERD, mnt) &&
22729 ++ !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
22730 ++ (atomic_read(&task->fs->count) > 1 ||
22731 ++ atomic_read(&task->files->count) > 1 ||
22732 ++ atomic_read(&task->sighand->count) > 1)) {
22733 ++ task_unlock(task);
22734 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
22735 ++ return -EACCES;
22736 ++ }
22737 ++ task_unlock(task);
22738 ++
22739 ++ obj = chk_obj_label(dentry, mnt, task->acl);
22740 ++ retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
22741 ++
22742 ++ if (!(task->acl->mode & GR_INHERITLEARN) &&
22743 ++ ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
22744 ++ if (obj->nested)
22745 ++ task->acl = obj->nested;
22746 ++ else
22747 ++ task->acl = newacl;
22748 ++ } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
22749 ++ gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
22750 ++
22751 ++ task->is_writable = 0;
22752 ++
22753 ++ /* ignore additional mmap checks for processes that are writable
22754 ++ by the default ACL */
22755 ++ obj = chk_obj_label(dentry, mnt, default_role->root_label);
22756 ++ if (unlikely(obj->mode & GR_WRITE))
22757 ++ task->is_writable = 1;
22758 ++ obj = chk_obj_label(dentry, mnt, task->role->root_label);
22759 ++ if (unlikely(obj->mode & GR_WRITE))
22760 ++ task->is_writable = 1;
22761 ++
22762 ++ gr_set_proc_res(task);
22763 ++
22764 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
22765 ++ printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
22766 ++#endif
22767 ++ return 0;
22768 ++}
22769 ++
22770 ++/* always called with valid inodev ptr */
22771 ++static void
22772 ++do_handle_delete(struct inodev_entry *inodev, const ino_t ino, const dev_t dev)
22773 ++{
22774 ++ struct acl_object_label *matchpo;
22775 ++ struct acl_subject_label *matchps;
22776 ++ struct acl_subject_label *subj;
22777 ++ struct acl_role_label *role;
22778 ++ unsigned int i, x;
22779 ++
22780 ++ FOR_EACH_ROLE_START(role, i)
22781 ++ FOR_EACH_SUBJECT_START(role, subj, x)
22782 ++ if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
22783 ++ matchpo->mode |= GR_DELETED;
22784 ++ FOR_EACH_SUBJECT_END(subj,x)
22785 ++ FOR_EACH_NESTED_SUBJECT_START(role, subj)
22786 ++ if (subj->inode == ino && subj->device == dev)
22787 ++ subj->mode |= GR_DELETED;
22788 ++ FOR_EACH_NESTED_SUBJECT_END(subj)
22789 ++ if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
22790 ++ matchps->mode |= GR_DELETED;
22791 ++ FOR_EACH_ROLE_END(role,i)
22792 ++
22793 ++ inodev->nentry->deleted = 1;
22794 ++
22795 ++ return;
22796 ++}
22797 ++
22798 ++void
22799 ++gr_handle_delete(const ino_t ino, const dev_t dev)
22800 ++{
22801 ++ struct inodev_entry *inodev;
22802 ++
22803 ++ if (unlikely(!(gr_status & GR_READY)))
22804 ++ return;
22805 ++
22806 ++ write_lock(&gr_inode_lock);
22807 ++ inodev = lookup_inodev_entry(ino, dev);
22808 ++ if (inodev != NULL)
22809 ++ do_handle_delete(inodev, ino, dev);
22810 ++ write_unlock(&gr_inode_lock);
22811 ++
22812 ++ return;
22813 ++}
22814 ++
22815 ++static void
22816 ++update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
22817 ++ const ino_t newinode, const dev_t newdevice,
22818 ++ struct acl_subject_label *subj)
22819 ++{
22820 ++ unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
22821 ++ struct acl_object_label *match;
22822 ++
22823 ++ match = subj->obj_hash[index];
22824 ++
22825 ++ while (match && (match->inode != oldinode ||
22826 ++ match->device != olddevice ||
22827 ++ !(match->mode & GR_DELETED)))
22828 ++ match = match->next;
22829 ++
22830 ++ if (match && (match->inode == oldinode)
22831 ++ && (match->device == olddevice)
22832 ++ && (match->mode & GR_DELETED)) {
22833 ++ if (match->prev == NULL) {
22834 ++ subj->obj_hash[index] = match->next;
22835 ++ if (match->next != NULL)
22836 ++ match->next->prev = NULL;
22837 ++ } else {
22838 ++ match->prev->next = match->next;
22839 ++ if (match->next != NULL)
22840 ++ match->next->prev = match->prev;
22841 ++ }
22842 ++ match->prev = NULL;
22843 ++ match->next = NULL;
22844 ++ match->inode = newinode;
22845 ++ match->device = newdevice;
22846 ++ match->mode &= ~GR_DELETED;
22847 ++
22848 ++ insert_acl_obj_label(match, subj);
22849 ++ }
22850 ++
22851 ++ return;
22852 ++}
22853 ++
22854 ++static void
22855 ++update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
22856 ++ const ino_t newinode, const dev_t newdevice,
22857 ++ struct acl_role_label *role)
22858 ++{
22859 ++ unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
22860 ++ struct acl_subject_label *match;
22861 ++
22862 ++ match = role->subj_hash[index];
22863 ++
22864 ++ while (match && (match->inode != oldinode ||
22865 ++ match->device != olddevice ||
22866 ++ !(match->mode & GR_DELETED)))
22867 ++ match = match->next;
22868 ++
22869 ++ if (match && (match->inode == oldinode)
22870 ++ && (match->device == olddevice)
22871 ++ && (match->mode & GR_DELETED)) {
22872 ++ if (match->prev == NULL) {
22873 ++ role->subj_hash[index] = match->next;
22874 ++ if (match->next != NULL)
22875 ++ match->next->prev = NULL;
22876 ++ } else {
22877 ++ match->prev->next = match->next;
22878 ++ if (match->next != NULL)
22879 ++ match->next->prev = match->prev;
22880 ++ }
22881 ++ match->prev = NULL;
22882 ++ match->next = NULL;
22883 ++ match->inode = newinode;
22884 ++ match->device = newdevice;
22885 ++ match->mode &= ~GR_DELETED;
22886 ++
22887 ++ insert_acl_subj_label(match, role);
22888 ++ }
22889 ++
22890 ++ return;
22891 ++}
22892 ++
22893 ++static void
22894 ++update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
22895 ++ const ino_t newinode, const dev_t newdevice)
22896 ++{
22897 ++ unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
22898 ++ struct inodev_entry *match;
22899 ++
22900 ++ match = inodev_set.i_hash[index];
22901 ++
22902 ++ while (match && (match->nentry->inode != oldinode ||
22903 ++ match->nentry->device != olddevice || !match->nentry->deleted))
22904 ++ match = match->next;
22905 ++
22906 ++ if (match && (match->nentry->inode == oldinode)
22907 ++ && (match->nentry->device == olddevice) &&
22908 ++ match->nentry->deleted) {
22909 ++ if (match->prev == NULL) {
22910 ++ inodev_set.i_hash[index] = match->next;
22911 ++ if (match->next != NULL)
22912 ++ match->next->prev = NULL;
22913 ++ } else {
22914 ++ match->prev->next = match->next;
22915 ++ if (match->next != NULL)
22916 ++ match->next->prev = match->prev;
22917 ++ }
22918 ++ match->prev = NULL;
22919 ++ match->next = NULL;
22920 ++ match->nentry->inode = newinode;
22921 ++ match->nentry->device = newdevice;
22922 ++ match->nentry->deleted = 0;
22923 ++
22924 ++ insert_inodev_entry(match);
22925 ++ }
22926 ++
22927 ++ return;
22928 ++}
22929 ++
22930 ++static void
22931 ++do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
22932 ++ const struct vfsmount *mnt)
22933 ++{
22934 ++ struct acl_subject_label *subj;
22935 ++ struct acl_role_label *role;
22936 ++ unsigned int i, x;
22937 ++
22938 ++ FOR_EACH_ROLE_START(role, i)
22939 ++ update_acl_subj_label(matchn->inode, matchn->device,
22940 ++ dentry->d_inode->i_ino,
22941 ++ dentry->d_inode->i_sb->s_dev, role);
22942 ++
22943 ++ FOR_EACH_NESTED_SUBJECT_START(role, subj)
22944 ++ if ((subj->inode == dentry->d_inode->i_ino) &&
22945 ++ (subj->device == dentry->d_inode->i_sb->s_dev)) {
22946 ++ subj->inode = dentry->d_inode->i_ino;
22947 ++ subj->device = dentry->d_inode->i_sb->s_dev;
22948 ++ }
22949 ++ FOR_EACH_NESTED_SUBJECT_END(subj)
22950 ++ FOR_EACH_SUBJECT_START(role, subj, x)
22951 ++ update_acl_obj_label(matchn->inode, matchn->device,
22952 ++ dentry->d_inode->i_ino,
22953 ++ dentry->d_inode->i_sb->s_dev, subj);
22954 ++ FOR_EACH_SUBJECT_END(subj,x)
22955 ++ FOR_EACH_ROLE_END(role,i)
22956 ++
22957 ++ update_inodev_entry(matchn->inode, matchn->device,
22958 ++ dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
22959 ++
22960 ++ return;
22961 ++}
22962 ++
22963 ++void
22964 ++gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
22965 ++{
22966 ++ struct name_entry *matchn;
22967 ++
22968 ++ if (unlikely(!(gr_status & GR_READY)))
22969 ++ return;
22970 ++
22971 ++ preempt_disable();
22972 ++ matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
22973 ++
22974 ++ if (unlikely((unsigned long)matchn)) {
22975 ++ write_lock(&gr_inode_lock);
22976 ++ do_handle_create(matchn, dentry, mnt);
22977 ++ write_unlock(&gr_inode_lock);
22978 ++ }
22979 ++ preempt_enable();
22980 ++
22981 ++ return;
22982 ++}
22983 ++
22984 ++void
22985 ++gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
22986 ++ struct dentry *old_dentry,
22987 ++ struct dentry *new_dentry,
22988 ++ struct vfsmount *mnt, const __u8 replace)
22989 ++{
22990 ++ struct name_entry *matchn;
22991 ++ struct inodev_entry *inodev;
22992 ++
22993 ++ /* vfs_rename swaps the name and parent link for old_dentry and
22994 ++ new_dentry
22995 ++ at this point, old_dentry has the new name, parent link, and inode
22996 ++ for the renamed file
22997 ++ if a file is being replaced by a rename, new_dentry has the inode
22998 ++ and name for the replaced file
22999 ++ */
23000 ++
23001 ++ if (unlikely(!(gr_status & GR_READY)))
23002 ++ return;
23003 ++
23004 ++ preempt_disable();
23005 ++ matchn = lookup_name_entry(gr_to_filename_rbac(old_dentry, mnt));
23006 ++
23007 ++ /* we wouldn't have to check d_inode if it weren't for
23008 ++ NFS silly-renaming
23009 ++ */
23010 ++
23011 ++ write_lock(&gr_inode_lock);
23012 ++ if (unlikely(replace && new_dentry->d_inode)) {
23013 ++ inodev = lookup_inodev_entry(new_dentry->d_inode->i_ino,
23014 ++ new_dentry->d_inode->i_sb->s_dev);
23015 ++ if (inodev != NULL && (new_dentry->d_inode->i_nlink <= 1))
23016 ++ do_handle_delete(inodev, new_dentry->d_inode->i_ino,
23017 ++ new_dentry->d_inode->i_sb->s_dev);
23018 ++ }
23019 ++
23020 ++ inodev = lookup_inodev_entry(old_dentry->d_inode->i_ino,
23021 ++ old_dentry->d_inode->i_sb->s_dev);
23022 ++ if (inodev != NULL && (old_dentry->d_inode->i_nlink <= 1))
23023 ++ do_handle_delete(inodev, old_dentry->d_inode->i_ino,
23024 ++ old_dentry->d_inode->i_sb->s_dev);
23025 ++
23026 ++ if (unlikely((unsigned long)matchn))
23027 ++ do_handle_create(matchn, old_dentry, mnt);
23028 ++
23029 ++ write_unlock(&gr_inode_lock);
23030 ++ preempt_enable();
23031 ++
23032 ++ return;
23033 ++}
23034 ++
23035 ++static int
23036 ++lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
23037 ++ unsigned char **sum)
23038 ++{
23039 ++ struct acl_role_label *r;
23040 ++ struct role_allowed_ip *ipp;
23041 ++ struct role_transition *trans;
23042 ++ unsigned int i;
23043 ++ int found = 0;
23044 ++
23045 ++ /* check transition table */
23046 ++
23047 ++ for (trans = current->role->transitions; trans; trans = trans->next) {
23048 ++ if (!strcmp(rolename, trans->rolename)) {
23049 ++ found = 1;
23050 ++ break;
23051 ++ }
23052 ++ }
23053 ++
23054 ++ if (!found)
23055 ++ return 0;
23056 ++
23057 ++ /* handle special roles that do not require authentication
23058 ++ and check ip */
23059 ++
23060 ++ FOR_EACH_ROLE_START(r, i)
23061 ++ if (!strcmp(rolename, r->rolename) &&
23062 ++ (r->roletype & GR_ROLE_SPECIAL)) {
23063 ++ found = 0;
23064 ++ if (r->allowed_ips != NULL) {
23065 ++ for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
23066 ++ if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
23067 ++ (ntohl(ipp->addr) & ipp->netmask))
23068 ++ found = 1;
23069 ++ }
23070 ++ } else
23071 ++ found = 2;
23072 ++ if (!found)
23073 ++ return 0;
23074 ++
23075 ++ if (((mode == GR_SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
23076 ++ ((mode == GR_SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
23077 ++ *salt = NULL;
23078 ++ *sum = NULL;
23079 ++ return 1;
23080 ++ }
23081 ++ }
23082 ++ FOR_EACH_ROLE_END(r,i)
23083 ++
23084 ++ for (i = 0; i < num_sprole_pws; i++) {
23085 ++ if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
23086 ++ *salt = acl_special_roles[i]->salt;
23087 ++ *sum = acl_special_roles[i]->sum;
23088 ++ return 1;
23089 ++ }
23090 ++ }
23091 ++
23092 ++ return 0;
23093 ++}
23094 ++
23095 ++static void
23096 ++assign_special_role(char *rolename)
23097 ++{
23098 ++ struct acl_object_label *obj;
23099 ++ struct acl_role_label *r;
23100 ++ struct acl_role_label *assigned = NULL;
23101 ++ struct task_struct *tsk;
23102 ++ struct file *filp;
23103 ++ unsigned int i;
23104 ++
23105 ++ FOR_EACH_ROLE_START(r, i)
23106 ++ if (!strcmp(rolename, r->rolename) &&
23107 ++ (r->roletype & GR_ROLE_SPECIAL))
23108 ++ assigned = r;
23109 ++ FOR_EACH_ROLE_END(r,i)
23110 ++
23111 ++ if (!assigned)
23112 ++ return;
23113 ++
23114 ++ read_lock(&tasklist_lock);
23115 ++ read_lock(&grsec_exec_file_lock);
23116 ++
23117 ++ tsk = current->parent;
23118 ++ if (tsk == NULL)
23119 ++ goto out_unlock;
23120 ++
23121 ++ filp = tsk->exec_file;
23122 ++ if (filp == NULL)
23123 ++ goto out_unlock;
23124 ++
23125 ++ tsk->is_writable = 0;
23126 ++
23127 ++ tsk->acl_sp_role = 1;
23128 ++ tsk->acl_role_id = ++acl_sp_role_value;
23129 ++ tsk->role = assigned;
23130 ++ tsk->acl = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role);
23131 ++
23132 ++ /* ignore additional mmap checks for processes that are writable
23133 ++ by the default ACL */
23134 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
23135 ++ if (unlikely(obj->mode & GR_WRITE))
23136 ++ tsk->is_writable = 1;
23137 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role->root_label);
23138 ++ if (unlikely(obj->mode & GR_WRITE))
23139 ++ tsk->is_writable = 1;
23140 ++
23141 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
23142 ++ printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
23143 ++#endif
23144 ++
23145 ++out_unlock:
23146 ++ read_unlock(&grsec_exec_file_lock);
23147 ++ read_unlock(&tasklist_lock);
23148 ++ return;
23149 ++}
23150 ++
23151 ++int gr_check_secure_terminal(struct task_struct *task)
23152 ++{
23153 ++ struct task_struct *p, *p2, *p3;
23154 ++ struct files_struct *files;
23155 ++ struct fdtable *fdt;
23156 ++ struct file *our_file = NULL, *file;
23157 ++ int i;
23158 ++
23159 ++ if (task->signal->tty == NULL)
23160 ++ return 1;
23161 ++
23162 ++ files = get_files_struct(task);
23163 ++ if (files != NULL) {
23164 ++ rcu_read_lock();
23165 ++ fdt = files_fdtable(files);
23166 ++ for (i=0; i < fdt->max_fds; i++) {
23167 ++ file = fcheck_files(files, i);
23168 ++ if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
23169 ++ get_file(file);
23170 ++ our_file = file;
23171 ++ }
23172 ++ }
23173 ++ rcu_read_unlock();
23174 ++ put_files_struct(files);
23175 ++ }
23176 ++
23177 ++ if (our_file == NULL)
23178 ++ return 1;
23179 ++
23180 ++ read_lock(&tasklist_lock);
23181 ++ do_each_thread(p2, p) {
23182 ++ files = get_files_struct(p);
23183 ++ if (files == NULL ||
23184 ++ (p->signal && p->signal->tty == task->signal->tty)) {
23185 ++ if (files != NULL)
23186 ++ put_files_struct(files);
23187 ++ continue;
23188 ++ }
23189 ++ rcu_read_lock();
23190 ++ fdt = files_fdtable(files);
23191 ++ for (i=0; i < fdt->max_fds; i++) {
23192 ++ file = fcheck_files(files, i);
23193 ++ if (file && S_ISCHR(file->f_path.dentry->d_inode->i_mode) &&
23194 ++ file->f_path.dentry->d_inode->i_rdev == our_file->f_path.dentry->d_inode->i_rdev) {
23195 ++ p3 = task;
23196 ++ while (p3->pid > 0) {
23197 ++ if (p3 == p)
23198 ++ break;
23199 ++ p3 = p3->parent;
23200 ++ }
23201 ++ if (p3 == p)
23202 ++ break;
23203 ++ gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
23204 ++ gr_handle_alertkill(p);
23205 ++ rcu_read_unlock();
23206 ++ put_files_struct(files);
23207 ++ read_unlock(&tasklist_lock);
23208 ++ fput(our_file);
23209 ++ return 0;
23210 ++ }
23211 ++ }
23212 ++ rcu_read_unlock();
23213 ++ put_files_struct(files);
23214 ++ } while_each_thread(p2, p);
23215 ++ read_unlock(&tasklist_lock);
23216 ++
23217 ++ fput(our_file);
23218 ++ return 1;
23219 ++}
23220 ++
23221 ++ssize_t
23222 ++write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
23223 ++{
23224 ++ struct gr_arg_wrapper uwrap;
23225 ++ unsigned char *sprole_salt;
23226 ++ unsigned char *sprole_sum;
23227 ++ int error = sizeof (struct gr_arg_wrapper);
23228 ++ int error2 = 0;
23229 ++
23230 ++ down(&gr_dev_sem);
23231 ++
23232 ++ if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
23233 ++ error = -EPERM;
23234 ++ goto out;
23235 ++ }
23236 ++
23237 ++ if (count != sizeof (struct gr_arg_wrapper)) {
23238 ++ gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
23239 ++ error = -EINVAL;
23240 ++ goto out;
23241 ++ }
23242 ++
23243 ++
23244 ++ if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
23245 ++ gr_auth_expires = 0;
23246 ++ gr_auth_attempts = 0;
23247 ++ }
23248 ++
23249 ++ if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
23250 ++ error = -EFAULT;
23251 ++ goto out;
23252 ++ }
23253 ++
23254 ++ if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
23255 ++ error = -EINVAL;
23256 ++ goto out;
23257 ++ }
23258 ++
23259 ++ if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
23260 ++ error = -EFAULT;
23261 ++ goto out;
23262 ++ }
23263 ++
23264 ++ if (gr_usermode->mode != GR_SPROLE && gr_usermode->mode != GR_SPROLEPAM &&
23265 ++ gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
23266 ++ time_after(gr_auth_expires, get_seconds())) {
23267 ++ error = -EBUSY;
23268 ++ goto out;
23269 ++ }
23270 ++
23271 ++ /* if non-root trying to do anything other than use a special role,
23272 ++ do not attempt authentication, do not count towards authentication
23273 ++ locking
23274 ++ */
23275 ++
23276 ++ if (gr_usermode->mode != GR_SPROLE && gr_usermode->mode != GR_STATUS &&
23277 ++ gr_usermode->mode != GR_UNSPROLE && gr_usermode->mode != GR_SPROLEPAM &&
23278 ++ current->uid) {
23279 ++ error = -EPERM;
23280 ++ goto out;
23281 ++ }
23282 ++
23283 ++ /* ensure pw and special role name are null terminated */
23284 ++
23285 ++ gr_usermode->pw[GR_PW_LEN - 1] = '\0';
23286 ++ gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
23287 ++
23288 ++ /* Okay.
23289 ++ * We have our enough of the argument structure..(we have yet
23290 ++ * to copy_from_user the tables themselves) . Copy the tables
23291 ++ * only if we need them, i.e. for loading operations. */
23292 ++
23293 ++ switch (gr_usermode->mode) {
23294 ++ case GR_STATUS:
23295 ++ if (gr_status & GR_READY) {
23296 ++ error = 1;
23297 ++ if (!gr_check_secure_terminal(current))
23298 ++ error = 3;
23299 ++ } else
23300 ++ error = 2;
23301 ++ goto out;
23302 ++ case GR_SHUTDOWN:
23303 ++ if ((gr_status & GR_READY)
23304 ++ && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
23305 ++ gr_status &= ~GR_READY;
23306 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
23307 ++ free_variables();
23308 ++ memset(gr_usermode, 0, sizeof (struct gr_arg));
23309 ++ memset(gr_system_salt, 0, GR_SALT_LEN);
23310 ++ memset(gr_system_sum, 0, GR_SHA_LEN);
23311 ++ } else if (gr_status & GR_READY) {
23312 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
23313 ++ error = -EPERM;
23314 ++ } else {
23315 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
23316 ++ error = -EAGAIN;
23317 ++ }
23318 ++ break;
23319 ++ case GR_ENABLE:
23320 ++ if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
23321 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
23322 ++ else {
23323 ++ if (gr_status & GR_READY)
23324 ++ error = -EAGAIN;
23325 ++ else
23326 ++ error = error2;
23327 ++ gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
23328 ++ }
23329 ++ break;
23330 ++ case GR_RELOAD:
23331 ++ if (!(gr_status & GR_READY)) {
23332 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
23333 ++ error = -EAGAIN;
23334 ++ } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
23335 ++ lock_kernel();
23336 ++ gr_status &= ~GR_READY;
23337 ++ free_variables();
23338 ++ if (!(error2 = gracl_init(gr_usermode))) {
23339 ++ unlock_kernel();
23340 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
23341 ++ } else {
23342 ++ unlock_kernel();
23343 ++ error = error2;
23344 ++ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
23345 ++ }
23346 ++ } else {
23347 ++ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
23348 ++ error = -EPERM;
23349 ++ }
23350 ++ break;
23351 ++ case GR_SEGVMOD:
23352 ++ if (unlikely(!(gr_status & GR_READY))) {
23353 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
23354 ++ error = -EAGAIN;
23355 ++ break;
23356 ++ }
23357 ++
23358 ++ if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
23359 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
23360 ++ if (gr_usermode->segv_device && gr_usermode->segv_inode) {
23361 ++ struct acl_subject_label *segvacl;
23362 ++ segvacl =
23363 ++ lookup_acl_subj_label(gr_usermode->segv_inode,
23364 ++ gr_usermode->segv_device,
23365 ++ current->role);
23366 ++ if (segvacl) {
23367 ++ segvacl->crashes = 0;
23368 ++ segvacl->expires = 0;
23369 ++ }
23370 ++ } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
23371 ++ gr_remove_uid(gr_usermode->segv_uid);
23372 ++ }
23373 ++ } else {
23374 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
23375 ++ error = -EPERM;
23376 ++ }
23377 ++ break;
23378 ++ case GR_SPROLE:
23379 ++ case GR_SPROLEPAM:
23380 ++ if (unlikely(!(gr_status & GR_READY))) {
23381 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
23382 ++ error = -EAGAIN;
23383 ++ break;
23384 ++ }
23385 ++
23386 ++ if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
23387 ++ current->role->expires = 0;
23388 ++ current->role->auth_attempts = 0;
23389 ++ }
23390 ++
23391 ++ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
23392 ++ time_after(current->role->expires, get_seconds())) {
23393 ++ error = -EBUSY;
23394 ++ goto out;
23395 ++ }
23396 ++
23397 ++ if (lookup_special_role_auth
23398 ++ (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
23399 ++ && ((!sprole_salt && !sprole_sum)
23400 ++ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
23401 ++ char *p = "";
23402 ++ assign_special_role(gr_usermode->sp_role);
23403 ++ read_lock(&tasklist_lock);
23404 ++ if (current->parent)
23405 ++ p = current->parent->role->rolename;
23406 ++ read_unlock(&tasklist_lock);
23407 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
23408 ++ p, acl_sp_role_value);
23409 ++ } else {
23410 ++ gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
23411 ++ error = -EPERM;
23412 ++ if(!(current->role->auth_attempts++))
23413 ++ current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
23414 ++
23415 ++ goto out;
23416 ++ }
23417 ++ break;
23418 ++ case GR_UNSPROLE:
23419 ++ if (unlikely(!(gr_status & GR_READY))) {
23420 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
23421 ++ error = -EAGAIN;
23422 ++ break;
23423 ++ }
23424 ++
23425 ++ if (current->role->roletype & GR_ROLE_SPECIAL) {
23426 ++ char *p = "";
23427 ++ int i = 0;
23428 ++
23429 ++ read_lock(&tasklist_lock);
23430 ++ if (current->parent) {
23431 ++ p = current->parent->role->rolename;
23432 ++ i = current->parent->acl_role_id;
23433 ++ }
23434 ++ read_unlock(&tasklist_lock);
23435 ++
23436 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
23437 ++ gr_set_acls(1);
23438 ++ } else {
23439 ++ gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
23440 ++ error = -EPERM;
23441 ++ goto out;
23442 ++ }
23443 ++ break;
23444 ++ default:
23445 ++ gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
23446 ++ error = -EINVAL;
23447 ++ break;
23448 ++ }
23449 ++
23450 ++ if (error != -EPERM)
23451 ++ goto out;
23452 ++
23453 ++ if(!(gr_auth_attempts++))
23454 ++ gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
23455 ++
23456 ++ out:
23457 ++ up(&gr_dev_sem);
23458 ++ return error;
23459 ++}
23460 ++
23461 ++int
23462 ++gr_set_acls(const int type)
23463 ++{
23464 ++ struct acl_object_label *obj;
23465 ++ struct task_struct *task, *task2;
23466 ++ struct file *filp;
23467 ++ struct acl_role_label *role = current->role;
23468 ++ __u16 acl_role_id = current->acl_role_id;
23469 ++
23470 ++ read_lock(&tasklist_lock);
23471 ++ read_lock(&grsec_exec_file_lock);
23472 ++ do_each_thread(task2, task) {
23473 ++ /* check to see if we're called from the exit handler,
23474 ++ if so, only replace ACLs that have inherited the admin
23475 ++ ACL */
23476 ++
23477 ++ if (type && (task->role != role ||
23478 ++ task->acl_role_id != acl_role_id))
23479 ++ continue;
23480 ++
23481 ++ task->acl_role_id = 0;
23482 ++ task->acl_sp_role = 0;
23483 ++
23484 ++ if ((filp = task->exec_file)) {
23485 ++ task->role = lookup_acl_role_label(task, task->uid, task->gid);
23486 ++
23487 ++ task->acl =
23488 ++ chk_subj_label(filp->f_path.dentry, filp->f_path.mnt,
23489 ++ task->role);
23490 ++ if (task->acl) {
23491 ++ struct acl_subject_label *curr;
23492 ++ curr = task->acl;
23493 ++
23494 ++ task->is_writable = 0;
23495 ++ /* ignore additional mmap checks for processes that are writable
23496 ++ by the default ACL */
23497 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
23498 ++ if (unlikely(obj->mode & GR_WRITE))
23499 ++ task->is_writable = 1;
23500 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
23501 ++ if (unlikely(obj->mode & GR_WRITE))
23502 ++ task->is_writable = 1;
23503 ++
23504 ++ gr_set_proc_res(task);
23505 ++
23506 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
23507 ++ printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
23508 ++#endif
23509 ++ } else {
23510 ++ read_unlock(&grsec_exec_file_lock);
23511 ++ read_unlock(&tasklist_lock);
23512 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
23513 ++ return 1;
23514 ++ }
23515 ++ } else {
23516 ++ // it's a kernel process
23517 ++ task->role = kernel_role;
23518 ++ task->acl = kernel_role->root_label;
23519 ++#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
23520 ++ task->acl->mode &= ~GR_PROCFIND;
23521 ++#endif
23522 ++ }
23523 ++ } while_each_thread(task2, task);
23524 ++ read_unlock(&grsec_exec_file_lock);
23525 ++ read_unlock(&tasklist_lock);
23526 ++ return 0;
23527 ++}
23528 ++
23529 ++void
23530 ++gr_learn_resource(const struct task_struct *task,
23531 ++ const int res, const unsigned long wanted, const int gt)
23532 ++{
23533 ++ struct acl_subject_label *acl;
23534 ++
23535 ++ if (unlikely((gr_status & GR_READY) &&
23536 ++ task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
23537 ++ goto skip_reslog;
23538 ++
23539 ++#ifdef CONFIG_GRKERNSEC_RESLOG
23540 ++ gr_log_resource(task, res, wanted, gt);
23541 ++#endif
23542 ++ skip_reslog:
23543 ++
23544 ++ if (unlikely(!(gr_status & GR_READY) || !wanted))
23545 ++ return;
23546 ++
23547 ++ acl = task->acl;
23548 ++
23549 ++ if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
23550 ++ !(acl->resmask & (1 << (unsigned short) res))))
23551 ++ return;
23552 ++
23553 ++ if (wanted >= acl->res[res].rlim_cur) {
23554 ++ unsigned long res_add;
23555 ++
23556 ++ res_add = wanted;
23557 ++ switch (res) {
23558 ++ case RLIMIT_CPU:
23559 ++ res_add += GR_RLIM_CPU_BUMP;
23560 ++ break;
23561 ++ case RLIMIT_FSIZE:
23562 ++ res_add += GR_RLIM_FSIZE_BUMP;
23563 ++ break;
23564 ++ case RLIMIT_DATA:
23565 ++ res_add += GR_RLIM_DATA_BUMP;
23566 ++ break;
23567 ++ case RLIMIT_STACK:
23568 ++ res_add += GR_RLIM_STACK_BUMP;
23569 ++ break;
23570 ++ case RLIMIT_CORE:
23571 ++ res_add += GR_RLIM_CORE_BUMP;
23572 ++ break;
23573 ++ case RLIMIT_RSS:
23574 ++ res_add += GR_RLIM_RSS_BUMP;
23575 ++ break;
23576 ++ case RLIMIT_NPROC:
23577 ++ res_add += GR_RLIM_NPROC_BUMP;
23578 ++ break;
23579 ++ case RLIMIT_NOFILE:
23580 ++ res_add += GR_RLIM_NOFILE_BUMP;
23581 ++ break;
23582 ++ case RLIMIT_MEMLOCK:
23583 ++ res_add += GR_RLIM_MEMLOCK_BUMP;
23584 ++ break;
23585 ++ case RLIMIT_AS:
23586 ++ res_add += GR_RLIM_AS_BUMP;
23587 ++ break;
23588 ++ case RLIMIT_LOCKS:
23589 ++ res_add += GR_RLIM_LOCKS_BUMP;
23590 ++ break;
23591 ++ }
23592 ++
23593 ++ acl->res[res].rlim_cur = res_add;
23594 ++
23595 ++ if (wanted > acl->res[res].rlim_max)
23596 ++ acl->res[res].rlim_max = res_add;
23597 ++
23598 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
23599 ++ task->role->roletype, acl->filename,
23600 ++ acl->res[res].rlim_cur, acl->res[res].rlim_max,
23601 ++ "", (unsigned long) res);
23602 ++ }
23603 ++
23604 ++ return;
23605 ++}
23606 ++
23607 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
23608 ++void
23609 ++pax_set_initial_flags(struct linux_binprm *bprm)
23610 ++{
23611 ++ struct task_struct *task = current;
23612 ++ struct acl_subject_label *proc;
23613 ++ unsigned long flags;
23614 ++
23615 ++ if (unlikely(!(gr_status & GR_READY)))
23616 ++ return;
23617 ++
23618 ++ flags = pax_get_flags(task);
23619 ++
23620 ++ proc = task->acl;
23621 ++
23622 ++ if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
23623 ++ flags &= ~MF_PAX_PAGEEXEC;
23624 ++ if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
23625 ++ flags &= ~MF_PAX_SEGMEXEC;
23626 ++ if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
23627 ++ flags &= ~MF_PAX_RANDMMAP;
23628 ++ if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
23629 ++ flags &= ~MF_PAX_EMUTRAMP;
23630 ++ if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
23631 ++ flags &= ~MF_PAX_MPROTECT;
23632 ++
23633 ++ if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
23634 ++ flags |= MF_PAX_PAGEEXEC;
23635 ++ if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
23636 ++ flags |= MF_PAX_SEGMEXEC;
23637 ++ if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
23638 ++ flags |= MF_PAX_RANDMMAP;
23639 ++ if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
23640 ++ flags |= MF_PAX_EMUTRAMP;
23641 ++ if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
23642 ++ flags |= MF_PAX_MPROTECT;
23643 ++
23644 ++ pax_set_flags(task, flags);
23645 ++
23646 ++ return;
23647 ++}
23648 ++#endif
23649 ++
23650 ++#ifdef CONFIG_SYSCTL
23651 ++/* Eric Biederman likes breaking userland ABI and every inode-based security
23652 ++ system to save 35kb of memory */
23653 ++
23654 ++/* we modify the passed in filename, but adjust it back before returning */
23655 ++static struct acl_object_label *gr_lookup_by_name(char *name, unsigned int len)
23656 ++{
23657 ++ struct name_entry *nmatch;
23658 ++ char *p, *lastp = NULL;
23659 ++ struct acl_object_label *obj = NULL, *tmp;
23660 ++ struct acl_subject_label *tmpsubj;
23661 ++ char c = '\0';
23662 ++
23663 ++ read_lock(&gr_inode_lock);
23664 ++
23665 ++ p = name + len - 1;
23666 ++ do {
23667 ++ nmatch = lookup_name_entry(name);
23668 ++ if (lastp != NULL)
23669 ++ *lastp = c;
23670 ++
23671 ++ if (nmatch == NULL)
23672 ++ goto next_component;
23673 ++ tmpsubj = current->acl;
23674 ++ do {
23675 ++ obj = lookup_acl_obj_label(nmatch->inode, nmatch->device, tmpsubj);
23676 ++ if (obj != NULL) {
23677 ++ tmp = obj->globbed;
23678 ++ while (tmp) {
23679 ++ if (!glob_match(tmp->filename, name)) {
23680 ++ obj = tmp;
23681 ++ goto found_obj;
23682 ++ }
23683 ++ tmp = tmp->next;
23684 ++ }
23685 ++ goto found_obj;
23686 ++ }
23687 ++ } while ((tmpsubj = tmpsubj->parent_subject));
23688 ++next_component:
23689 ++ /* end case */
23690 ++ if (p == name)
23691 ++ break;
23692 ++
23693 ++ while (*p != '/')
23694 ++ p--;
23695 ++ if (p == name)
23696 ++ lastp = p + 1;
23697 ++ else {
23698 ++ lastp = p;
23699 ++ p--;
23700 ++ }
23701 ++ c = *lastp;
23702 ++ *lastp = '\0';
23703 ++ } while (1);
23704 ++found_obj:
23705 ++ read_unlock(&gr_inode_lock);
23706 ++ /* obj returned will always be non-null */
23707 ++ return obj;
23708 ++}
23709 ++
23710 ++/* returns 0 when allowing, non-zero on error
23711 ++ op of 0 is used for readdir, so we don't log the names of hidden files
23712 ++*/
23713 ++__u32
23714 ++gr_handle_sysctl(const struct ctl_table *table, const int op)
23715 ++{
23716 ++ ctl_table *tmp;
23717 ++ const char *proc_sys = "/proc/sys";
23718 ++ char *path;
23719 ++ struct acl_object_label *obj;
23720 ++ unsigned short len = 0, pos = 0, depth = 0, i;
23721 ++ __u32 err = 0;
23722 ++ __u32 mode = 0;
23723 ++
23724 ++ if (unlikely(!(gr_status & GR_READY)))
23725 ++ return 0;
23726 ++
23727 ++ /* for now, ignore operations on non-sysctl entries if it's not a
23728 ++ readdir*/
23729 ++ if (table->child != NULL && op != 0)
23730 ++ return 0;
23731 ++
23732 ++ mode |= GR_FIND;
23733 ++ /* it's only a read if it's an entry, read on dirs is for readdir */
23734 ++ if (op & MAY_READ)
23735 ++ mode |= GR_READ;
23736 ++ if (op & MAY_WRITE)
23737 ++ mode |= GR_WRITE;
23738 ++
23739 ++ preempt_disable();
23740 ++
23741 ++ path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
23742 ++
23743 ++ /* it's only a read/write if it's an actual entry, not a dir
23744 ++ (which are opened for readdir)
23745 ++ */
23746 ++
23747 ++ /* convert the requested sysctl entry into a pathname */
23748 ++
23749 ++ for (tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
23750 ++ len += strlen(tmp->procname);
23751 ++ len++;
23752 ++ depth++;
23753 ++ }
23754 ++
23755 ++ if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE) {
23756 ++ /* deny */
23757 ++ goto out;
23758 ++ }
23759 ++
23760 ++ memset(path, 0, PAGE_SIZE);
23761 ++
23762 ++ memcpy(path, proc_sys, strlen(proc_sys));
23763 ++
23764 ++ pos += strlen(proc_sys);
23765 ++
23766 ++ for (; depth > 0; depth--) {
23767 ++ path[pos] = '/';
23768 ++ pos++;
23769 ++ for (i = 1, tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
23770 ++ if (depth == i) {
23771 ++ memcpy(path + pos, tmp->procname,
23772 ++ strlen(tmp->procname));
23773 ++ pos += strlen(tmp->procname);
23774 ++ }
23775 ++ i++;
23776 ++ }
23777 ++ }
23778 ++
23779 ++ obj = gr_lookup_by_name(path, pos);
23780 ++ err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
23781 ++
23782 ++ if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
23783 ++ ((err & mode) != mode))) {
23784 ++ __u32 new_mode = mode;
23785 ++
23786 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
23787 ++
23788 ++ err = 0;
23789 ++ gr_log_learn_sysctl(current, path, new_mode);
23790 ++ } else if (!(err & GR_FIND) && !(err & GR_SUPPRESS) && op != 0) {
23791 ++ gr_log_hidden_sysctl(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, path);
23792 ++ err = -ENOENT;
23793 ++ } else if (!(err & GR_FIND)) {
23794 ++ err = -ENOENT;
23795 ++ } else if (((err & mode) & ~GR_FIND) != (mode & ~GR_FIND) && !(err & GR_SUPPRESS)) {
23796 ++ gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
23797 ++ path, (mode & GR_READ) ? " reading" : "",
23798 ++ (mode & GR_WRITE) ? " writing" : "");
23799 ++ err = -EACCES;
23800 ++ } else if ((err & mode) != mode) {
23801 ++ err = -EACCES;
23802 ++ } else if ((((err & mode) & ~GR_FIND) == (mode & ~GR_FIND)) && (err & GR_AUDITS)) {
23803 ++ gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
23804 ++ path, (mode & GR_READ) ? " reading" : "",
23805 ++ (mode & GR_WRITE) ? " writing" : "");
23806 ++ err = 0;
23807 ++ } else
23808 ++ err = 0;
23809 ++
23810 ++ out:
23811 ++ preempt_enable();
23812 ++
23813 ++ return err;
23814 ++}
23815 ++#endif
23816 ++
23817 ++int
23818 ++gr_handle_proc_ptrace(struct task_struct *task)
23819 ++{
23820 ++ struct file *filp;
23821 ++ struct task_struct *tmp = task;
23822 ++ struct task_struct *curtemp = current;
23823 ++ __u32 retmode;
23824 ++
23825 ++ if (unlikely(!(gr_status & GR_READY)))
23826 ++ return 0;
23827 ++
23828 ++ read_lock(&tasklist_lock);
23829 ++ read_lock(&grsec_exec_file_lock);
23830 ++ filp = task->exec_file;
23831 ++
23832 ++ while (tmp->pid > 0) {
23833 ++ if (tmp == curtemp)
23834 ++ break;
23835 ++ tmp = tmp->parent;
23836 ++ }
23837 ++
23838 ++ if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
23839 ++ read_unlock(&grsec_exec_file_lock);
23840 ++ read_unlock(&tasklist_lock);
23841 ++ return 1;
23842 ++ }
23843 ++
23844 ++ retmode = gr_search_file(filp->f_path.dentry, GR_NOPTRACE, filp->f_path.mnt);
23845 ++ read_unlock(&grsec_exec_file_lock);
23846 ++ read_unlock(&tasklist_lock);
23847 ++
23848 ++ if (retmode & GR_NOPTRACE)
23849 ++ return 1;
23850 ++
23851 ++ if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
23852 ++ && (current->acl != task->acl || (current->acl != current->role->root_label
23853 ++ && current->pid != task->pid)))
23854 ++ return 1;
23855 ++
23856 ++ return 0;
23857 ++}
23858 ++
23859 ++int
23860 ++gr_handle_ptrace(struct task_struct *task, const long request)
23861 ++{
23862 ++ struct task_struct *tmp = task;
23863 ++ struct task_struct *curtemp = current;
23864 ++ __u32 retmode;
23865 ++
23866 ++ if (unlikely(!(gr_status & GR_READY)))
23867 ++ return 0;
23868 ++
23869 ++ read_lock(&tasklist_lock);
23870 ++ while (tmp->pid > 0) {
23871 ++ if (tmp == curtemp)
23872 ++ break;
23873 ++ tmp = tmp->parent;
23874 ++ }
23875 ++
23876 ++ if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
23877 ++ read_unlock(&tasklist_lock);
23878 ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
23879 ++ return 1;
23880 ++ }
23881 ++ read_unlock(&tasklist_lock);
23882 ++
23883 ++ read_lock(&grsec_exec_file_lock);
23884 ++ if (unlikely(!task->exec_file)) {
23885 ++ read_unlock(&grsec_exec_file_lock);
23886 ++ return 0;
23887 ++ }
23888 ++
23889 ++ retmode = gr_search_file(task->exec_file->f_path.dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_path.mnt);
23890 ++ read_unlock(&grsec_exec_file_lock);
23891 ++
23892 ++ if (retmode & GR_NOPTRACE) {
23893 ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
23894 ++ return 1;
23895 ++ }
23896 ++
23897 ++ if (retmode & GR_PTRACERD) {
23898 ++ switch (request) {
23899 ++ case PTRACE_POKETEXT:
23900 ++ case PTRACE_POKEDATA:
23901 ++ case PTRACE_POKEUSR:
23902 ++#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
23903 ++ case PTRACE_SETREGS:
23904 ++ case PTRACE_SETFPREGS:
23905 ++#endif
23906 ++#ifdef CONFIG_X86
23907 ++ case PTRACE_SETFPXREGS:
23908 ++#endif
23909 ++#ifdef CONFIG_ALTIVEC
23910 ++ case PTRACE_SETVRREGS:
23911 ++#endif
23912 ++ return 1;
23913 ++ default:
23914 ++ return 0;
23915 ++ }
23916 ++ } else if (!(current->acl->mode & GR_POVERRIDE) &&
23917 ++ !(current->role->roletype & GR_ROLE_GOD) &&
23918 ++ (current->acl != task->acl)) {
23919 ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
23920 ++ return 1;
23921 ++ }
23922 ++
23923 ++ return 0;
23924 ++}
23925 ++
23926 ++static int is_writable_mmap(const struct file *filp)
23927 ++{
23928 ++ struct task_struct *task = current;
23929 ++ struct acl_object_label *obj, *obj2;
23930 ++
23931 ++ if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
23932 ++ !task->is_writable && S_ISREG(filp->f_path.dentry->d_inode->i_mode)) {
23933 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
23934 ++ obj2 = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt,
23935 ++ task->role->root_label);
23936 ++ if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
23937 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_path.dentry, filp->f_path.mnt);
23938 ++ return 1;
23939 ++ }
23940 ++ }
23941 ++ return 0;
23942 ++}
23943 ++
23944 ++int
23945 ++gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
23946 ++{
23947 ++ __u32 mode;
23948 ++
23949 ++ if (unlikely(!file || !(prot & PROT_EXEC)))
23950 ++ return 1;
23951 ++
23952 ++ if (is_writable_mmap(file))
23953 ++ return 0;
23954 ++
23955 ++ mode =
23956 ++ gr_search_file(file->f_path.dentry,
23957 ++ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
23958 ++ file->f_path.mnt);
23959 ++
23960 ++ if (!gr_tpe_allow(file))
23961 ++ return 0;
23962 ++
23963 ++ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
23964 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
23965 ++ return 0;
23966 ++ } else if (unlikely(!(mode & GR_EXEC))) {
23967 ++ return 0;
23968 ++ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
23969 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
23970 ++ return 1;
23971 ++ }
23972 ++
23973 ++ return 1;
23974 ++}
23975 ++
23976 ++int
23977 ++gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
23978 ++{
23979 ++ __u32 mode;
23980 ++
23981 ++ if (unlikely(!file || !(prot & PROT_EXEC)))
23982 ++ return 1;
23983 ++
23984 ++ if (is_writable_mmap(file))
23985 ++ return 0;
23986 ++
23987 ++ mode =
23988 ++ gr_search_file(file->f_path.dentry,
23989 ++ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
23990 ++ file->f_path.mnt);
23991 ++
23992 ++ if (!gr_tpe_allow(file))
23993 ++ return 0;
23994 ++
23995 ++ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
23996 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
23997 ++ return 0;
23998 ++ } else if (unlikely(!(mode & GR_EXEC))) {
23999 ++ return 0;
24000 ++ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
24001 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
24002 ++ return 1;
24003 ++ }
24004 ++
24005 ++ return 1;
24006 ++}
24007 ++
24008 ++void
24009 ++gr_acl_handle_psacct(struct task_struct *task, const long code)
24010 ++{
24011 ++ unsigned long runtime;
24012 ++ unsigned long cputime;
24013 ++ unsigned int wday, cday;
24014 ++ __u8 whr, chr;
24015 ++ __u8 wmin, cmin;
24016 ++ __u8 wsec, csec;
24017 ++ struct timespec timeval;
24018 ++
24019 ++ if (unlikely(!(gr_status & GR_READY) || !task->acl ||
24020 ++ !(task->acl->mode & GR_PROCACCT)))
24021 ++ return;
24022 ++
24023 ++ do_posix_clock_monotonic_gettime(&timeval);
24024 ++ runtime = timeval.tv_sec - task->start_time.tv_sec;
24025 ++ wday = runtime / (3600 * 24);
24026 ++ runtime -= wday * (3600 * 24);
24027 ++ whr = runtime / 3600;
24028 ++ runtime -= whr * 3600;
24029 ++ wmin = runtime / 60;
24030 ++ runtime -= wmin * 60;
24031 ++ wsec = runtime;
24032 ++
24033 ++ cputime = (task->utime + task->stime) / HZ;
24034 ++ cday = cputime / (3600 * 24);
24035 ++ cputime -= cday * (3600 * 24);
24036 ++ chr = cputime / 3600;
24037 ++ cputime -= chr * 3600;
24038 ++ cmin = cputime / 60;
24039 ++ cputime -= cmin * 60;
24040 ++ csec = cputime;
24041 ++
24042 ++ gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
24043 ++
24044 ++ return;
24045 ++}
24046 ++
24047 ++void gr_set_kernel_label(struct task_struct *task)
24048 ++{
24049 ++ if (gr_status & GR_READY) {
24050 ++ task->role = kernel_role;
24051 ++ task->acl = kernel_role->root_label;
24052 ++ }
24053 ++ return;
24054 ++}
24055 ++
24056 ++int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
24057 ++{
24058 ++ struct task_struct *task = current;
24059 ++ struct dentry *dentry = file->f_path.dentry;
24060 ++ struct vfsmount *mnt = file->f_path.mnt;
24061 ++ struct acl_object_label *obj, *tmp;
24062 ++ struct acl_subject_label *subj;
24063 ++ unsigned int bufsize;
24064 ++ int is_not_root;
24065 ++ char *path;
24066 ++
24067 ++ if (unlikely(!(gr_status & GR_READY)))
24068 ++ return 1;
24069 ++
24070 ++ if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
24071 ++ return 1;
24072 ++
24073 ++ /* ignore Eric Biederman */
24074 ++ if (IS_PRIVATE(dentry->d_inode))
24075 ++ return 1;
24076 ++
24077 ++ subj = task->acl;
24078 ++ do {
24079 ++ obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
24080 ++ if (obj != NULL)
24081 ++ return (obj->mode & GR_FIND) ? 1 : 0;
24082 ++ } while ((subj = subj->parent_subject));
24083 ++
24084 ++ obj = chk_obj_label(dentry, mnt, task->acl);
24085 ++ if (obj->globbed == NULL)
24086 ++ return (obj->mode & GR_FIND) ? 1 : 0;
24087 ++
24088 ++ is_not_root = ((obj->filename[0] == '/') &&
24089 ++ (obj->filename[1] == '\0')) ? 0 : 1;
24090 ++ bufsize = PAGE_SIZE - namelen - is_not_root;
24091 ++
24092 ++ /* check bufsize > PAGE_SIZE || bufsize == 0 */
24093 ++ if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
24094 ++ return 1;
24095 ++
24096 ++ preempt_disable();
24097 ++ path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
24098 ++ bufsize);
24099 ++
24100 ++ bufsize = strlen(path);
24101 ++
24102 ++ /* if base is "/", don't append an additional slash */
24103 ++ if (is_not_root)
24104 ++ *(path + bufsize) = '/';
24105 ++ memcpy(path + bufsize + is_not_root, name, namelen);
24106 ++ *(path + bufsize + namelen + is_not_root) = '\0';
24107 ++
24108 ++ tmp = obj->globbed;
24109 ++ while (tmp) {
24110 ++ if (!glob_match(tmp->filename, path)) {
24111 ++ preempt_enable();
24112 ++ return (tmp->mode & GR_FIND) ? 1 : 0;
24113 ++ }
24114 ++ tmp = tmp->next;
24115 ++ }
24116 ++ preempt_enable();
24117 ++ return (obj->mode & GR_FIND) ? 1 : 0;
24118 ++}
24119 ++
24120 ++EXPORT_SYMBOL(gr_learn_resource);
24121 ++EXPORT_SYMBOL(gr_set_kernel_label);
24122 ++#ifdef CONFIG_SECURITY
24123 ++EXPORT_SYMBOL(gr_check_user_change);
24124 ++EXPORT_SYMBOL(gr_check_group_change);
24125 ++#endif
24126 ++
24127 +diff -urNp linux-2.6.28.8/grsecurity/gracl_cap.c linux-2.6.28.8/grsecurity/gracl_cap.c
24128 +--- linux-2.6.28.8/grsecurity/gracl_cap.c 1969-12-31 19:00:00.000000000 -0500
24129 ++++ linux-2.6.28.8/grsecurity/gracl_cap.c 2009-02-21 09:37:49.000000000 -0500
24130 +@@ -0,0 +1,129 @@
24131 ++#include <linux/kernel.h>
24132 ++#include <linux/module.h>
24133 ++#include <linux/sched.h>
24134 ++#include <linux/gracl.h>
24135 ++#include <linux/grsecurity.h>
24136 ++#include <linux/grinternal.h>
24137 ++
24138 ++static const char *captab_log[] = {
24139 ++ "CAP_CHOWN",
24140 ++ "CAP_DAC_OVERRIDE",
24141 ++ "CAP_DAC_READ_SEARCH",
24142 ++ "CAP_FOWNER",
24143 ++ "CAP_FSETID",
24144 ++ "CAP_KILL",
24145 ++ "CAP_SETGID",
24146 ++ "CAP_SETUID",
24147 ++ "CAP_SETPCAP",
24148 ++ "CAP_LINUX_IMMUTABLE",
24149 ++ "CAP_NET_BIND_SERVICE",
24150 ++ "CAP_NET_BROADCAST",
24151 ++ "CAP_NET_ADMIN",
24152 ++ "CAP_NET_RAW",
24153 ++ "CAP_IPC_LOCK",
24154 ++ "CAP_IPC_OWNER",
24155 ++ "CAP_SYS_MODULE",
24156 ++ "CAP_SYS_RAWIO",
24157 ++ "CAP_SYS_CHROOT",
24158 ++ "CAP_SYS_PTRACE",
24159 ++ "CAP_SYS_PACCT",
24160 ++ "CAP_SYS_ADMIN",
24161 ++ "CAP_SYS_BOOT",
24162 ++ "CAP_SYS_NICE",
24163 ++ "CAP_SYS_RESOURCE",
24164 ++ "CAP_SYS_TIME",
24165 ++ "CAP_SYS_TTY_CONFIG",
24166 ++ "CAP_MKNOD",
24167 ++ "CAP_LEASE",
24168 ++ "CAP_AUDIT_WRITE",
24169 ++ "CAP_AUDIT_CONTROL",
24170 ++ "CAP_SETFCAP",
24171 ++ "CAP_MAC_OVERRIDE",
24172 ++ "CAP_MAC_ADMIN"
24173 ++};
24174 ++
24175 ++EXPORT_SYMBOL(gr_task_is_capable);
24176 ++EXPORT_SYMBOL(gr_is_capable_nolog);
24177 ++
24178 ++int
24179 ++gr_task_is_capable(struct task_struct *task, const int cap)
24180 ++{
24181 ++ struct acl_subject_label *curracl;
24182 ++ kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
24183 ++
24184 ++ if (!gr_acl_is_enabled())
24185 ++ return 1;
24186 ++
24187 ++ curracl = task->acl;
24188 ++
24189 ++ cap_drop = curracl->cap_lower;
24190 ++ cap_mask = curracl->cap_mask;
24191 ++
24192 ++ while ((curracl = curracl->parent_subject)) {
24193 ++ /* if the cap isn't specified in the current computed mask but is specified in the
24194 ++ current level subject, and is lowered in the current level subject, then add
24195 ++ it to the set of dropped capabilities
24196 ++ otherwise, add the current level subject's mask to the current computed mask
24197 ++ */
24198 ++ if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
24199 ++ cap_raise(cap_mask, cap);
24200 ++ if (cap_raised(curracl->cap_lower, cap))
24201 ++ cap_raise(cap_drop, cap);
24202 ++ }
24203 ++ }
24204 ++
24205 ++ if (!cap_raised(cap_drop, cap))
24206 ++ return 1;
24207 ++
24208 ++ curracl = task->acl;
24209 ++
24210 ++ if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
24211 ++ && cap_raised(task->cap_effective, cap)) {
24212 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
24213 ++ task->role->roletype, task->uid,
24214 ++ task->gid, task->exec_file ?
24215 ++ gr_to_filename(task->exec_file->f_path.dentry,
24216 ++ task->exec_file->f_path.mnt) : curracl->filename,
24217 ++ curracl->filename, 0UL,
24218 ++ 0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
24219 ++ return 1;
24220 ++ }
24221 ++
24222 ++ if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap))
24223 ++ gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
24224 ++ return 0;
24225 ++}
24226 ++
24227 ++int
24228 ++gr_is_capable_nolog(const int cap)
24229 ++{
24230 ++ struct acl_subject_label *curracl;
24231 ++ kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
24232 ++
24233 ++ if (!gr_acl_is_enabled())
24234 ++ return 1;
24235 ++
24236 ++ curracl = current->acl;
24237 ++
24238 ++ cap_drop = curracl->cap_lower;
24239 ++ cap_mask = curracl->cap_mask;
24240 ++
24241 ++ while ((curracl = curracl->parent_subject)) {
24242 ++ /* if the cap isn't specified in the current computed mask but is specified in the
24243 ++ current level subject, and is lowered in the current level subject, then add
24244 ++ it to the set of dropped capabilities
24245 ++ otherwise, add the current level subject's mask to the current computed mask
24246 ++ */
24247 ++ if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
24248 ++ cap_raise(cap_mask, cap);
24249 ++ if (cap_raised(curracl->cap_lower, cap))
24250 ++ cap_raise(cap_drop, cap);
24251 ++ }
24252 ++ }
24253 ++
24254 ++ if (!cap_raised(cap_drop, cap))
24255 ++ return 1;
24256 ++
24257 ++ return 0;
24258 ++}
24259 ++
24260 +diff -urNp linux-2.6.28.8/grsecurity/gracl_fs.c linux-2.6.28.8/grsecurity/gracl_fs.c
24261 +--- linux-2.6.28.8/grsecurity/gracl_fs.c 1969-12-31 19:00:00.000000000 -0500
24262 ++++ linux-2.6.28.8/grsecurity/gracl_fs.c 2009-02-21 09:37:49.000000000 -0500
24263 +@@ -0,0 +1,423 @@
24264 ++#include <linux/kernel.h>
24265 ++#include <linux/sched.h>
24266 ++#include <linux/types.h>
24267 ++#include <linux/fs.h>
24268 ++#include <linux/file.h>
24269 ++#include <linux/stat.h>
24270 ++#include <linux/grsecurity.h>
24271 ++#include <linux/grinternal.h>
24272 ++#include <linux/gracl.h>
24273 ++
24274 ++__u32
24275 ++gr_acl_handle_hidden_file(const struct dentry * dentry,
24276 ++ const struct vfsmount * mnt)
24277 ++{
24278 ++ __u32 mode;
24279 ++
24280 ++ if (unlikely(!dentry->d_inode))
24281 ++ return GR_FIND;
24282 ++
24283 ++ mode =
24284 ++ gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
24285 ++
24286 ++ if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
24287 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
24288 ++ return mode;
24289 ++ } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
24290 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
24291 ++ return 0;
24292 ++ } else if (unlikely(!(mode & GR_FIND)))
24293 ++ return 0;
24294 ++
24295 ++ return GR_FIND;
24296 ++}
24297 ++
24298 ++__u32
24299 ++gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
24300 ++ const int fmode)
24301 ++{
24302 ++ __u32 reqmode = GR_FIND;
24303 ++ __u32 mode;
24304 ++
24305 ++ if (unlikely(!dentry->d_inode))
24306 ++ return reqmode;
24307 ++
24308 ++ if (unlikely(fmode & O_APPEND))
24309 ++ reqmode |= GR_APPEND;
24310 ++ else if (unlikely(fmode & FMODE_WRITE))
24311 ++ reqmode |= GR_WRITE;
24312 ++ if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
24313 ++ reqmode |= GR_READ;
24314 ++
24315 ++ mode =
24316 ++ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
24317 ++ mnt);
24318 ++
24319 ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
24320 ++ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
24321 ++ reqmode & GR_READ ? " reading" : "",
24322 ++ reqmode & GR_WRITE ? " writing" : reqmode &
24323 ++ GR_APPEND ? " appending" : "");
24324 ++ return reqmode;
24325 ++ } else
24326 ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
24327 ++ {
24328 ++ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
24329 ++ reqmode & GR_READ ? " reading" : "",
24330 ++ reqmode & GR_WRITE ? " writing" : reqmode &
24331 ++ GR_APPEND ? " appending" : "");
24332 ++ return 0;
24333 ++ } else if (unlikely((mode & reqmode) != reqmode))
24334 ++ return 0;
24335 ++
24336 ++ return reqmode;
24337 ++}
24338 ++
24339 ++__u32
24340 ++gr_acl_handle_creat(const struct dentry * dentry,
24341 ++ const struct dentry * p_dentry,
24342 ++ const struct vfsmount * p_mnt, const int fmode,
24343 ++ const int imode)
24344 ++{
24345 ++ __u32 reqmode = GR_WRITE | GR_CREATE;
24346 ++ __u32 mode;
24347 ++
24348 ++ if (unlikely(fmode & O_APPEND))
24349 ++ reqmode |= GR_APPEND;
24350 ++ if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
24351 ++ reqmode |= GR_READ;
24352 ++ if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
24353 ++ reqmode |= GR_SETID;
24354 ++
24355 ++ mode =
24356 ++ gr_check_create(dentry, p_dentry, p_mnt,
24357 ++ reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
24358 ++
24359 ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
24360 ++ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
24361 ++ reqmode & GR_READ ? " reading" : "",
24362 ++ reqmode & GR_WRITE ? " writing" : reqmode &
24363 ++ GR_APPEND ? " appending" : "");
24364 ++ return reqmode;
24365 ++ } else
24366 ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
24367 ++ {
24368 ++ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
24369 ++ reqmode & GR_READ ? " reading" : "",
24370 ++ reqmode & GR_WRITE ? " writing" : reqmode &
24371 ++ GR_APPEND ? " appending" : "");
24372 ++ return 0;
24373 ++ } else if (unlikely((mode & reqmode) != reqmode))
24374 ++ return 0;
24375 ++
24376 ++ return reqmode;
24377 ++}
24378 ++
24379 ++__u32
24380 ++gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
24381 ++ const int fmode)
24382 ++{
24383 ++ __u32 mode, reqmode = GR_FIND;
24384 ++
24385 ++ if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
24386 ++ reqmode |= GR_EXEC;
24387 ++ if (fmode & S_IWOTH)
24388 ++ reqmode |= GR_WRITE;
24389 ++ if (fmode & S_IROTH)
24390 ++ reqmode |= GR_READ;
24391 ++
24392 ++ mode =
24393 ++ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
24394 ++ mnt);
24395 ++
24396 ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
24397 ++ gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
24398 ++ reqmode & GR_READ ? " reading" : "",
24399 ++ reqmode & GR_WRITE ? " writing" : "",
24400 ++ reqmode & GR_EXEC ? " executing" : "");
24401 ++ return reqmode;
24402 ++ } else
24403 ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
24404 ++ {
24405 ++ gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
24406 ++ reqmode & GR_READ ? " reading" : "",
24407 ++ reqmode & GR_WRITE ? " writing" : "",
24408 ++ reqmode & GR_EXEC ? " executing" : "");
24409 ++ return 0;
24410 ++ } else if (unlikely((mode & reqmode) != reqmode))
24411 ++ return 0;
24412 ++
24413 ++ return reqmode;
24414 ++}
24415 ++
24416 ++static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
24417 ++{
24418 ++ __u32 mode;
24419 ++
24420 ++ mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
24421 ++
24422 ++ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
24423 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
24424 ++ return mode;
24425 ++ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
24426 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
24427 ++ return 0;
24428 ++ } else if (unlikely((mode & (reqmode)) != (reqmode)))
24429 ++ return 0;
24430 ++
24431 ++ return (reqmode);
24432 ++}
24433 ++
24434 ++__u32
24435 ++gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
24436 ++{
24437 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
24438 ++}
24439 ++
24440 ++__u32
24441 ++gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
24442 ++{
24443 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
24444 ++}
24445 ++
24446 ++__u32
24447 ++gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
24448 ++{
24449 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
24450 ++}
24451 ++
24452 ++__u32
24453 ++gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
24454 ++{
24455 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
24456 ++}
24457 ++
24458 ++__u32
24459 ++gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
24460 ++ mode_t mode)
24461 ++{
24462 ++ if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
24463 ++ return 1;
24464 ++
24465 ++ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
24466 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
24467 ++ GR_FCHMOD_ACL_MSG);
24468 ++ } else {
24469 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
24470 ++ }
24471 ++}
24472 ++
24473 ++__u32
24474 ++gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
24475 ++ mode_t mode)
24476 ++{
24477 ++ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
24478 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
24479 ++ GR_CHMOD_ACL_MSG);
24480 ++ } else {
24481 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
24482 ++ }
24483 ++}
24484 ++
24485 ++__u32
24486 ++gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
24487 ++{
24488 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
24489 ++}
24490 ++
24491 ++__u32
24492 ++gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
24493 ++{
24494 ++ return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
24495 ++}
24496 ++
24497 ++__u32
24498 ++gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
24499 ++{
24500 ++ return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
24501 ++ GR_UNIXCONNECT_ACL_MSG);
24502 ++}
24503 ++
24504 ++/* hardlinks require at minimum create permission,
24505 ++ any additional privilege required is based on the
24506 ++ privilege of the file being linked to
24507 ++*/
24508 ++__u32
24509 ++gr_acl_handle_link(const struct dentry * new_dentry,
24510 ++ const struct dentry * parent_dentry,
24511 ++ const struct vfsmount * parent_mnt,
24512 ++ const struct dentry * old_dentry,
24513 ++ const struct vfsmount * old_mnt, const char *to)
24514 ++{
24515 ++ __u32 mode;
24516 ++ __u32 needmode = GR_CREATE | GR_LINK;
24517 ++ __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
24518 ++
24519 ++ mode =
24520 ++ gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
24521 ++ old_mnt);
24522 ++
24523 ++ if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
24524 ++ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
24525 ++ return mode;
24526 ++ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
24527 ++ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
24528 ++ return 0;
24529 ++ } else if (unlikely((mode & needmode) != needmode))
24530 ++ return 0;
24531 ++
24532 ++ return 1;
24533 ++}
24534 ++
24535 ++__u32
24536 ++gr_acl_handle_symlink(const struct dentry * new_dentry,
24537 ++ const struct dentry * parent_dentry,
24538 ++ const struct vfsmount * parent_mnt, const char *from)
24539 ++{
24540 ++ __u32 needmode = GR_WRITE | GR_CREATE;
24541 ++ __u32 mode;
24542 ++
24543 ++ mode =
24544 ++ gr_check_create(new_dentry, parent_dentry, parent_mnt,
24545 ++ GR_CREATE | GR_AUDIT_CREATE |
24546 ++ GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
24547 ++
24548 ++ if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
24549 ++ gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
24550 ++ return mode;
24551 ++ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
24552 ++ gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
24553 ++ return 0;
24554 ++ } else if (unlikely((mode & needmode) != needmode))
24555 ++ return 0;
24556 ++
24557 ++ return (GR_WRITE | GR_CREATE);
24558 ++}
24559 ++
24560 ++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)
24561 ++{
24562 ++ __u32 mode;
24563 ++
24564 ++ mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
24565 ++
24566 ++ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
24567 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
24568 ++ return mode;
24569 ++ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
24570 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
24571 ++ return 0;
24572 ++ } else if (unlikely((mode & (reqmode)) != (reqmode)))
24573 ++ return 0;
24574 ++
24575 ++ return (reqmode);
24576 ++}
24577 ++
24578 ++__u32
24579 ++gr_acl_handle_mknod(const struct dentry * new_dentry,
24580 ++ const struct dentry * parent_dentry,
24581 ++ const struct vfsmount * parent_mnt,
24582 ++ const int mode)
24583 ++{
24584 ++ __u32 reqmode = GR_WRITE | GR_CREATE;
24585 ++ if (unlikely(mode & (S_ISUID | S_ISGID)))
24586 ++ reqmode |= GR_SETID;
24587 ++
24588 ++ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
24589 ++ reqmode, GR_MKNOD_ACL_MSG);
24590 ++}
24591 ++
24592 ++__u32
24593 ++gr_acl_handle_mkdir(const struct dentry *new_dentry,
24594 ++ const struct dentry *parent_dentry,
24595 ++ const struct vfsmount *parent_mnt)
24596 ++{
24597 ++ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
24598 ++ GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
24599 ++}
24600 ++
24601 ++#define RENAME_CHECK_SUCCESS(old, new) \
24602 ++ (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
24603 ++ ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
24604 ++
24605 ++int
24606 ++gr_acl_handle_rename(struct dentry *new_dentry,
24607 ++ struct dentry *parent_dentry,
24608 ++ const struct vfsmount *parent_mnt,
24609 ++ struct dentry *old_dentry,
24610 ++ struct inode *old_parent_inode,
24611 ++ struct vfsmount *old_mnt, const char *newname)
24612 ++{
24613 ++ __u32 comp1, comp2;
24614 ++ int error = 0;
24615 ++
24616 ++ if (unlikely(!gr_acl_is_enabled()))
24617 ++ return 0;
24618 ++
24619 ++ if (!new_dentry->d_inode) {
24620 ++ comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
24621 ++ GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
24622 ++ GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
24623 ++ comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
24624 ++ GR_DELETE | GR_AUDIT_DELETE |
24625 ++ GR_AUDIT_READ | GR_AUDIT_WRITE |
24626 ++ GR_SUPPRESS, old_mnt);
24627 ++ } else {
24628 ++ comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
24629 ++ GR_CREATE | GR_DELETE |
24630 ++ GR_AUDIT_CREATE | GR_AUDIT_DELETE |
24631 ++ GR_AUDIT_READ | GR_AUDIT_WRITE |
24632 ++ GR_SUPPRESS, parent_mnt);
24633 ++ comp2 =
24634 ++ gr_search_file(old_dentry,
24635 ++ GR_READ | GR_WRITE | GR_AUDIT_READ |
24636 ++ GR_DELETE | GR_AUDIT_DELETE |
24637 ++ GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
24638 ++ }
24639 ++
24640 ++ if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
24641 ++ ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
24642 ++ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
24643 ++ else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
24644 ++ && !(comp2 & GR_SUPPRESS)) {
24645 ++ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
24646 ++ error = -EACCES;
24647 ++ } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
24648 ++ error = -EACCES;
24649 ++
24650 ++ return error;
24651 ++}
24652 ++
24653 ++void
24654 ++gr_acl_handle_exit(void)
24655 ++{
24656 ++ u16 id;
24657 ++ char *rolename;
24658 ++ struct file *exec_file;
24659 ++
24660 ++ if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
24661 ++ id = current->acl_role_id;
24662 ++ rolename = current->role->rolename;
24663 ++ gr_set_acls(1);
24664 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
24665 ++ }
24666 ++
24667 ++ write_lock(&grsec_exec_file_lock);
24668 ++ exec_file = current->exec_file;
24669 ++ current->exec_file = NULL;
24670 ++ write_unlock(&grsec_exec_file_lock);
24671 ++
24672 ++ if (exec_file)
24673 ++ fput(exec_file);
24674 ++}
24675 ++
24676 ++int
24677 ++gr_acl_handle_procpidmem(const struct task_struct *task)
24678 ++{
24679 ++ if (unlikely(!gr_acl_is_enabled()))
24680 ++ return 0;
24681 ++
24682 ++ if (task != current && task->acl->mode & GR_PROTPROCFD)
24683 ++ return -EACCES;
24684 ++
24685 ++ return 0;
24686 ++}
24687 +diff -urNp linux-2.6.28.8/grsecurity/gracl_ip.c linux-2.6.28.8/grsecurity/gracl_ip.c
24688 +--- linux-2.6.28.8/grsecurity/gracl_ip.c 1969-12-31 19:00:00.000000000 -0500
24689 ++++ linux-2.6.28.8/grsecurity/gracl_ip.c 2009-02-21 09:37:49.000000000 -0500
24690 +@@ -0,0 +1,338 @@
24691 ++#include <linux/kernel.h>
24692 ++#include <asm/uaccess.h>
24693 ++#include <asm/errno.h>
24694 ++#include <net/sock.h>
24695 ++#include <linux/file.h>
24696 ++#include <linux/fs.h>
24697 ++#include <linux/net.h>
24698 ++#include <linux/in.h>
24699 ++#include <linux/skbuff.h>
24700 ++#include <linux/ip.h>
24701 ++#include <linux/udp.h>
24702 ++#include <linux/smp_lock.h>
24703 ++#include <linux/types.h>
24704 ++#include <linux/sched.h>
24705 ++#include <linux/netdevice.h>
24706 ++#include <linux/inetdevice.h>
24707 ++#include <linux/gracl.h>
24708 ++#include <linux/grsecurity.h>
24709 ++#include <linux/grinternal.h>
24710 ++
24711 ++#define GR_BIND 0x01
24712 ++#define GR_CONNECT 0x02
24713 ++#define GR_INVERT 0x04
24714 ++#define GR_BINDOVERRIDE 0x08
24715 ++#define GR_CONNECTOVERRIDE 0x10
24716 ++
24717 ++static const char * gr_protocols[256] = {
24718 ++ "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
24719 ++ "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
24720 ++ "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
24721 ++ "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
24722 ++ "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
24723 ++ "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
24724 ++ "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
24725 ++ "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
24726 ++ "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
24727 ++ "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
24728 ++ "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
24729 ++ "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
24730 ++ "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
24731 ++ "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
24732 ++ "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
24733 ++ "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
24734 ++ "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
24735 ++ "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
24736 ++ "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
24737 ++ "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
24738 ++ "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
24739 ++ "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
24740 ++ "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
24741 ++ "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
24742 ++ "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
24743 ++ "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
24744 ++ "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
24745 ++ "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
24746 ++ "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
24747 ++ "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
24748 ++ "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
24749 ++ "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
24750 ++ };
24751 ++
24752 ++static const char * gr_socktypes[11] = {
24753 ++ "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
24754 ++ "unknown:7", "unknown:8", "unknown:9", "packet"
24755 ++ };
24756 ++
24757 ++const char *
24758 ++gr_proto_to_name(unsigned char proto)
24759 ++{
24760 ++ return gr_protocols[proto];
24761 ++}
24762 ++
24763 ++const char *
24764 ++gr_socktype_to_name(unsigned char type)
24765 ++{
24766 ++ return gr_socktypes[type];
24767 ++}
24768 ++
24769 ++int
24770 ++gr_search_socket(const int domain, const int type, const int protocol)
24771 ++{
24772 ++ struct acl_subject_label *curr;
24773 ++
24774 ++ if (unlikely(!gr_acl_is_enabled()))
24775 ++ goto exit;
24776 ++
24777 ++ if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
24778 ++ || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
24779 ++ goto exit; // let the kernel handle it
24780 ++
24781 ++ curr = current->acl;
24782 ++
24783 ++ if (!curr->ips)
24784 ++ goto exit;
24785 ++
24786 ++ if ((curr->ip_type & (1 << type)) &&
24787 ++ (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
24788 ++ goto exit;
24789 ++
24790 ++ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
24791 ++ /* we don't place acls on raw sockets , and sometimes
24792 ++ dgram/ip sockets are opened for ioctl and not
24793 ++ bind/connect, so we'll fake a bind learn log */
24794 ++ if (type == SOCK_RAW || type == SOCK_PACKET) {
24795 ++ __u32 fakeip = 0;
24796 ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
24797 ++ current->role->roletype, current->uid,
24798 ++ current->gid, current->exec_file ?
24799 ++ gr_to_filename(current->exec_file->f_path.dentry,
24800 ++ current->exec_file->f_path.mnt) :
24801 ++ curr->filename, curr->filename,
24802 ++ NIPQUAD(fakeip), 0, type,
24803 ++ protocol, GR_CONNECT,
24804 ++NIPQUAD(current->signal->curr_ip));
24805 ++ } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
24806 ++ __u32 fakeip = 0;
24807 ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
24808 ++ current->role->roletype, current->uid,
24809 ++ current->gid, current->exec_file ?
24810 ++ gr_to_filename(current->exec_file->f_path.dentry,
24811 ++ current->exec_file->f_path.mnt) :
24812 ++ curr->filename, curr->filename,
24813 ++ NIPQUAD(fakeip), 0, type,
24814 ++ protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
24815 ++ }
24816 ++ /* we'll log when they use connect or bind */
24817 ++ goto exit;
24818 ++ }
24819 ++
24820 ++ gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet",
24821 ++ gr_socktype_to_name(type), gr_proto_to_name(protocol));
24822 ++
24823 ++ return 0;
24824 ++ exit:
24825 ++ return 1;
24826 ++}
24827 ++
24828 ++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)
24829 ++{
24830 ++ if ((ip->mode & mode) &&
24831 ++ (ip_port >= ip->low) &&
24832 ++ (ip_port <= ip->high) &&
24833 ++ ((ntohl(ip_addr) & our_netmask) ==
24834 ++ (ntohl(our_addr) & our_netmask))
24835 ++ && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
24836 ++ && (ip->type & (1 << type))) {
24837 ++ if (ip->mode & GR_INVERT)
24838 ++ return 2; // specifically denied
24839 ++ else
24840 ++ return 1; // allowed
24841 ++ }
24842 ++
24843 ++ return 0; // not specifically allowed, may continue parsing
24844 ++}
24845 ++
24846 ++static int
24847 ++gr_search_connectbind(const int full_mode, struct sock *sk,
24848 ++ struct sockaddr_in *addr, const int type)
24849 ++{
24850 ++ char iface[IFNAMSIZ] = {0};
24851 ++ struct acl_subject_label *curr;
24852 ++ struct acl_ip_label *ip;
24853 ++ struct inet_sock *isk;
24854 ++ struct net_device *dev;
24855 ++ struct in_device *idev;
24856 ++ unsigned long i;
24857 ++ int ret;
24858 ++ int mode = full_mode & (GR_BIND | GR_CONNECT);
24859 ++ __u32 ip_addr = 0;
24860 ++ __u32 our_addr;
24861 ++ __u32 our_netmask;
24862 ++ char *p;
24863 ++ __u16 ip_port = 0;
24864 ++
24865 ++ if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
24866 ++ return 0;
24867 ++
24868 ++ curr = current->acl;
24869 ++ isk = inet_sk(sk);
24870 ++
24871 ++ /* INADDR_ANY overriding for binds, inaddr_any_override is already in network order */
24872 ++ if ((full_mode & GR_BINDOVERRIDE) && addr->sin_addr.s_addr == htonl(INADDR_ANY) && curr->inaddr_any_override != 0)
24873 ++ addr->sin_addr.s_addr = curr->inaddr_any_override;
24874 ++ if ((full_mode & GR_CONNECT) && isk->saddr == htonl(INADDR_ANY) && curr->inaddr_any_override != 0) {
24875 ++ struct sockaddr_in saddr;
24876 ++ int err;
24877 ++
24878 ++ saddr.sin_family = AF_INET;
24879 ++ saddr.sin_addr.s_addr = curr->inaddr_any_override;
24880 ++ saddr.sin_port = isk->sport;
24881 ++
24882 ++ err = security_socket_bind(sk->sk_socket, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
24883 ++ if (err)
24884 ++ return err;
24885 ++
24886 ++ err = sk->sk_socket->ops->bind(sk->sk_socket, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
24887 ++ if (err)
24888 ++ return err;
24889 ++ }
24890 ++
24891 ++ if (!curr->ips)
24892 ++ return 0;
24893 ++
24894 ++ ip_addr = addr->sin_addr.s_addr;
24895 ++ ip_port = ntohs(addr->sin_port);
24896 ++
24897 ++ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
24898 ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
24899 ++ current->role->roletype, current->uid,
24900 ++ current->gid, current->exec_file ?
24901 ++ gr_to_filename(current->exec_file->f_path.dentry,
24902 ++ current->exec_file->f_path.mnt) :
24903 ++ curr->filename, curr->filename,
24904 ++ NIPQUAD(ip_addr), ip_port, type,
24905 ++ sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
24906 ++ return 0;
24907 ++ }
24908 ++
24909 ++ for (i = 0; i < curr->ip_num; i++) {
24910 ++ ip = *(curr->ips + i);
24911 ++ if (ip->iface != NULL) {
24912 ++ strncpy(iface, ip->iface, IFNAMSIZ - 1);
24913 ++ p = strchr(iface, ':');
24914 ++ if (p != NULL)
24915 ++ *p = '\0';
24916 ++ dev = dev_get_by_name(sock_net(sk), iface);
24917 ++ if (dev == NULL)
24918 ++ continue;
24919 ++ idev = in_dev_get(dev);
24920 ++ if (idev == NULL) {
24921 ++ dev_put(dev);
24922 ++ continue;
24923 ++ }
24924 ++ rcu_read_lock();
24925 ++ for_ifa(idev) {
24926 ++ if (!strcmp(ip->iface, ifa->ifa_label)) {
24927 ++ our_addr = ifa->ifa_address;
24928 ++ our_netmask = 0xffffffff;
24929 ++ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
24930 ++ if (ret == 1) {
24931 ++ rcu_read_unlock();
24932 ++ in_dev_put(idev);
24933 ++ dev_put(dev);
24934 ++ return 0;
24935 ++ } else if (ret == 2) {
24936 ++ rcu_read_unlock();
24937 ++ in_dev_put(idev);
24938 ++ dev_put(dev);
24939 ++ goto denied;
24940 ++ }
24941 ++ }
24942 ++ } endfor_ifa(idev);
24943 ++ rcu_read_unlock();
24944 ++ in_dev_put(idev);
24945 ++ dev_put(dev);
24946 ++ } else {
24947 ++ our_addr = ip->addr;
24948 ++ our_netmask = ip->netmask;
24949 ++ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
24950 ++ if (ret == 1)
24951 ++ return 0;
24952 ++ else if (ret == 2)
24953 ++ goto denied;
24954 ++ }
24955 ++ }
24956 ++
24957 ++denied:
24958 ++ if (mode == GR_BIND)
24959 ++ 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));
24960 ++ else if (mode == GR_CONNECT)
24961 ++ 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));
24962 ++
24963 ++ return -EACCES;
24964 ++}
24965 ++
24966 ++int
24967 ++gr_search_connect(struct socket *sock, struct sockaddr_in *addr)
24968 ++{
24969 ++ return gr_search_connectbind(GR_CONNECT | GR_CONNECTOVERRIDE, sock->sk, addr, sock->type);
24970 ++}
24971 ++
24972 ++int
24973 ++gr_search_bind(struct socket *sock, struct sockaddr_in *addr)
24974 ++{
24975 ++ return gr_search_connectbind(GR_BIND | GR_BINDOVERRIDE, sock->sk, addr, sock->type);
24976 ++}
24977 ++
24978 ++int gr_search_listen(struct socket *sock)
24979 ++{
24980 ++ struct sock *sk = sock->sk;
24981 ++ struct sockaddr_in addr;
24982 ++
24983 ++ addr.sin_addr.s_addr = inet_sk(sk)->saddr;
24984 ++ addr.sin_port = inet_sk(sk)->sport;
24985 ++
24986 ++ return gr_search_connectbind(GR_BIND | GR_CONNECTOVERRIDE, sock->sk, &addr, sock->type);
24987 ++}
24988 ++
24989 ++int gr_search_accept(struct socket *sock)
24990 ++{
24991 ++ struct sock *sk = sock->sk;
24992 ++ struct sockaddr_in addr;
24993 ++
24994 ++ addr.sin_addr.s_addr = inet_sk(sk)->saddr;
24995 ++ addr.sin_port = inet_sk(sk)->sport;
24996 ++
24997 ++ return gr_search_connectbind(GR_BIND | GR_CONNECTOVERRIDE, sock->sk, &addr, sock->type);
24998 ++}
24999 ++
25000 ++int
25001 ++gr_search_udp_sendmsg(struct sock *sk, struct sockaddr_in *addr)
25002 ++{
25003 ++ if (addr)
25004 ++ return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
25005 ++ else {
25006 ++ struct sockaddr_in sin;
25007 ++ const struct inet_sock *inet = inet_sk(sk);
25008 ++
25009 ++ sin.sin_addr.s_addr = inet->daddr;
25010 ++ sin.sin_port = inet->dport;
25011 ++
25012 ++ return gr_search_connectbind(GR_CONNECT | GR_CONNECTOVERRIDE, sk, &sin, SOCK_DGRAM);
25013 ++ }
25014 ++}
25015 ++
25016 ++int
25017 ++gr_search_udp_recvmsg(struct sock *sk, const struct sk_buff *skb)
25018 ++{
25019 ++ struct sockaddr_in sin;
25020 ++
25021 ++ if (unlikely(skb->len < sizeof (struct udphdr)))
25022 ++ return 0; // skip this packet
25023 ++
25024 ++ sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
25025 ++ sin.sin_port = udp_hdr(skb)->source;
25026 ++
25027 ++ return gr_search_connectbind(GR_CONNECT | GR_CONNECTOVERRIDE, sk, &sin, SOCK_DGRAM);
25028 ++}
25029 +diff -urNp linux-2.6.28.8/grsecurity/gracl_learn.c linux-2.6.28.8/grsecurity/gracl_learn.c
25030 +--- linux-2.6.28.8/grsecurity/gracl_learn.c 1969-12-31 19:00:00.000000000 -0500
25031 ++++ linux-2.6.28.8/grsecurity/gracl_learn.c 2009-02-21 09:37:49.000000000 -0500
25032 +@@ -0,0 +1,211 @@
25033 ++#include <linux/kernel.h>
25034 ++#include <linux/mm.h>
25035 ++#include <linux/sched.h>
25036 ++#include <linux/poll.h>
25037 ++#include <linux/smp_lock.h>
25038 ++#include <linux/string.h>
25039 ++#include <linux/file.h>
25040 ++#include <linux/types.h>
25041 ++#include <linux/vmalloc.h>
25042 ++#include <linux/grinternal.h>
25043 ++
25044 ++extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
25045 ++ size_t count, loff_t *ppos);
25046 ++extern int gr_acl_is_enabled(void);
25047 ++
25048 ++static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
25049 ++static int gr_learn_attached;
25050 ++
25051 ++/* use a 512k buffer */
25052 ++#define LEARN_BUFFER_SIZE (512 * 1024)
25053 ++
25054 ++static DEFINE_SPINLOCK(gr_learn_lock);
25055 ++static DECLARE_MUTEX(gr_learn_user_sem);
25056 ++
25057 ++/* we need to maintain two buffers, so that the kernel context of grlearn
25058 ++ uses a semaphore around the userspace copying, and the other kernel contexts
25059 ++ use a spinlock when copying into the buffer, since they cannot sleep
25060 ++*/
25061 ++static char *learn_buffer;
25062 ++static char *learn_buffer_user;
25063 ++static int learn_buffer_len;
25064 ++static int learn_buffer_user_len;
25065 ++
25066 ++static ssize_t
25067 ++read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
25068 ++{
25069 ++ DECLARE_WAITQUEUE(wait, current);
25070 ++ ssize_t retval = 0;
25071 ++
25072 ++ add_wait_queue(&learn_wait, &wait);
25073 ++ set_current_state(TASK_INTERRUPTIBLE);
25074 ++ do {
25075 ++ down(&gr_learn_user_sem);
25076 ++ spin_lock(&gr_learn_lock);
25077 ++ if (learn_buffer_len)
25078 ++ break;
25079 ++ spin_unlock(&gr_learn_lock);
25080 ++ up(&gr_learn_user_sem);
25081 ++ if (file->f_flags & O_NONBLOCK) {
25082 ++ retval = -EAGAIN;
25083 ++ goto out;
25084 ++ }
25085 ++ if (signal_pending(current)) {
25086 ++ retval = -ERESTARTSYS;
25087 ++ goto out;
25088 ++ }
25089 ++
25090 ++ schedule();
25091 ++ } while (1);
25092 ++
25093 ++ memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
25094 ++ learn_buffer_user_len = learn_buffer_len;
25095 ++ retval = learn_buffer_len;
25096 ++ learn_buffer_len = 0;
25097 ++
25098 ++ spin_unlock(&gr_learn_lock);
25099 ++
25100 ++ if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
25101 ++ retval = -EFAULT;
25102 ++
25103 ++ up(&gr_learn_user_sem);
25104 ++out:
25105 ++ set_current_state(TASK_RUNNING);
25106 ++ remove_wait_queue(&learn_wait, &wait);
25107 ++ return retval;
25108 ++}
25109 ++
25110 ++static unsigned int
25111 ++poll_learn(struct file * file, poll_table * wait)
25112 ++{
25113 ++ poll_wait(file, &learn_wait, wait);
25114 ++
25115 ++ if (learn_buffer_len)
25116 ++ return (POLLIN | POLLRDNORM);
25117 ++
25118 ++ return 0;
25119 ++}
25120 ++
25121 ++void
25122 ++gr_clear_learn_entries(void)
25123 ++{
25124 ++ char *tmp;
25125 ++
25126 ++ down(&gr_learn_user_sem);
25127 ++ if (learn_buffer != NULL) {
25128 ++ spin_lock(&gr_learn_lock);
25129 ++ tmp = learn_buffer;
25130 ++ learn_buffer = NULL;
25131 ++ spin_unlock(&gr_learn_lock);
25132 ++ vfree(learn_buffer);
25133 ++ }
25134 ++ if (learn_buffer_user != NULL) {
25135 ++ vfree(learn_buffer_user);
25136 ++ learn_buffer_user = NULL;
25137 ++ }
25138 ++ learn_buffer_len = 0;
25139 ++ up(&gr_learn_user_sem);
25140 ++
25141 ++ return;
25142 ++}
25143 ++
25144 ++void
25145 ++gr_add_learn_entry(const char *fmt, ...)
25146 ++{
25147 ++ va_list args;
25148 ++ unsigned int len;
25149 ++
25150 ++ if (!gr_learn_attached)
25151 ++ return;
25152 ++
25153 ++ spin_lock(&gr_learn_lock);
25154 ++
25155 ++ /* leave a gap at the end so we know when it's "full" but don't have to
25156 ++ compute the exact length of the string we're trying to append
25157 ++ */
25158 ++ if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
25159 ++ spin_unlock(&gr_learn_lock);
25160 ++ wake_up_interruptible(&learn_wait);
25161 ++ return;
25162 ++ }
25163 ++ if (learn_buffer == NULL) {
25164 ++ spin_unlock(&gr_learn_lock);
25165 ++ return;
25166 ++ }
25167 ++
25168 ++ va_start(args, fmt);
25169 ++ len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
25170 ++ va_end(args);
25171 ++
25172 ++ learn_buffer_len += len + 1;
25173 ++
25174 ++ spin_unlock(&gr_learn_lock);
25175 ++ wake_up_interruptible(&learn_wait);
25176 ++
25177 ++ return;
25178 ++}
25179 ++
25180 ++static int
25181 ++open_learn(struct inode *inode, struct file *file)
25182 ++{
25183 ++ if (file->f_mode & FMODE_READ && gr_learn_attached)
25184 ++ return -EBUSY;
25185 ++ if (file->f_mode & FMODE_READ) {
25186 ++ int retval = 0;
25187 ++ down(&gr_learn_user_sem);
25188 ++ if (learn_buffer == NULL)
25189 ++ learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
25190 ++ if (learn_buffer_user == NULL)
25191 ++ learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
25192 ++ if (learn_buffer == NULL) {
25193 ++ retval = -ENOMEM;
25194 ++ goto out_error;
25195 ++ }
25196 ++ if (learn_buffer_user == NULL) {
25197 ++ retval = -ENOMEM;
25198 ++ goto out_error;
25199 ++ }
25200 ++ learn_buffer_len = 0;
25201 ++ learn_buffer_user_len = 0;
25202 ++ gr_learn_attached = 1;
25203 ++out_error:
25204 ++ up(&gr_learn_user_sem);
25205 ++ return retval;
25206 ++ }
25207 ++ return 0;
25208 ++}
25209 ++
25210 ++static int
25211 ++close_learn(struct inode *inode, struct file *file)
25212 ++{
25213 ++ char *tmp;
25214 ++
25215 ++ if (file->f_mode & FMODE_READ) {
25216 ++ down(&gr_learn_user_sem);
25217 ++ if (learn_buffer != NULL) {
25218 ++ spin_lock(&gr_learn_lock);
25219 ++ tmp = learn_buffer;
25220 ++ learn_buffer = NULL;
25221 ++ spin_unlock(&gr_learn_lock);
25222 ++ vfree(tmp);
25223 ++ }
25224 ++ if (learn_buffer_user != NULL) {
25225 ++ vfree(learn_buffer_user);
25226 ++ learn_buffer_user = NULL;
25227 ++ }
25228 ++ learn_buffer_len = 0;
25229 ++ learn_buffer_user_len = 0;
25230 ++ gr_learn_attached = 0;
25231 ++ up(&gr_learn_user_sem);
25232 ++ }
25233 ++
25234 ++ return 0;
25235 ++}
25236 ++
25237 ++struct file_operations grsec_fops = {
25238 ++ .read = read_learn,
25239 ++ .write = write_grsec_handler,
25240 ++ .open = open_learn,
25241 ++ .release = close_learn,
25242 ++ .poll = poll_learn,
25243 ++};
25244 +diff -urNp linux-2.6.28.8/grsecurity/gracl_res.c linux-2.6.28.8/grsecurity/gracl_res.c
25245 +--- linux-2.6.28.8/grsecurity/gracl_res.c 1969-12-31 19:00:00.000000000 -0500
25246 ++++ linux-2.6.28.8/grsecurity/gracl_res.c 2009-02-21 09:37:49.000000000 -0500
25247 +@@ -0,0 +1,45 @@
25248 ++#include <linux/kernel.h>
25249 ++#include <linux/sched.h>
25250 ++#include <linux/gracl.h>
25251 ++#include <linux/grinternal.h>
25252 ++
25253 ++static const char *restab_log[] = {
25254 ++ [RLIMIT_CPU] = "RLIMIT_CPU",
25255 ++ [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
25256 ++ [RLIMIT_DATA] = "RLIMIT_DATA",
25257 ++ [RLIMIT_STACK] = "RLIMIT_STACK",
25258 ++ [RLIMIT_CORE] = "RLIMIT_CORE",
25259 ++ [RLIMIT_RSS] = "RLIMIT_RSS",
25260 ++ [RLIMIT_NPROC] = "RLIMIT_NPROC",
25261 ++ [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
25262 ++ [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
25263 ++ [RLIMIT_AS] = "RLIMIT_AS",
25264 ++ [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
25265 ++ [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH"
25266 ++};
25267 ++
25268 ++void
25269 ++gr_log_resource(const struct task_struct *task,
25270 ++ const int res, const unsigned long wanted, const int gt)
25271 ++{
25272 ++ if (res == RLIMIT_NPROC &&
25273 ++ (cap_raised(task->cap_effective, CAP_SYS_ADMIN) ||
25274 ++ cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
25275 ++ return;
25276 ++ else if (res == RLIMIT_MEMLOCK &&
25277 ++ cap_raised(task->cap_effective, CAP_IPC_LOCK))
25278 ++ return;
25279 ++
25280 ++ if (!gr_acl_is_enabled() && !grsec_resource_logging)
25281 ++ return;
25282 ++
25283 ++ preempt_disable();
25284 ++
25285 ++ if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
25286 ++ (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
25287 ++ task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
25288 ++ gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
25289 ++ preempt_enable_no_resched();
25290 ++
25291 ++ return;
25292 ++}
25293 +diff -urNp linux-2.6.28.8/grsecurity/gracl_segv.c linux-2.6.28.8/grsecurity/gracl_segv.c
25294 +--- linux-2.6.28.8/grsecurity/gracl_segv.c 1969-12-31 19:00:00.000000000 -0500
25295 ++++ linux-2.6.28.8/grsecurity/gracl_segv.c 2009-02-21 09:37:49.000000000 -0500
25296 +@@ -0,0 +1,304 @@
25297 ++#include <linux/kernel.h>
25298 ++#include <linux/mm.h>
25299 ++#include <asm/uaccess.h>
25300 ++#include <asm/errno.h>
25301 ++#include <asm/mman.h>
25302 ++#include <net/sock.h>
25303 ++#include <linux/file.h>
25304 ++#include <linux/fs.h>
25305 ++#include <linux/net.h>
25306 ++#include <linux/in.h>
25307 ++#include <linux/smp_lock.h>
25308 ++#include <linux/slab.h>
25309 ++#include <linux/types.h>
25310 ++#include <linux/sched.h>
25311 ++#include <linux/timer.h>
25312 ++#include <linux/gracl.h>
25313 ++#include <linux/grsecurity.h>
25314 ++#include <linux/grinternal.h>
25315 ++
25316 ++static struct crash_uid *uid_set;
25317 ++static unsigned short uid_used;
25318 ++static DEFINE_SPINLOCK(gr_uid_lock);
25319 ++extern rwlock_t gr_inode_lock;
25320 ++extern struct acl_subject_label *
25321 ++ lookup_acl_subj_label(const ino_t inode, const dev_t dev,
25322 ++ struct acl_role_label *role);
25323 ++extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
25324 ++
25325 ++int
25326 ++gr_init_uidset(void)
25327 ++{
25328 ++ uid_set =
25329 ++ kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
25330 ++ uid_used = 0;
25331 ++
25332 ++ return uid_set ? 1 : 0;
25333 ++}
25334 ++
25335 ++void
25336 ++gr_free_uidset(void)
25337 ++{
25338 ++ if (uid_set)
25339 ++ kfree(uid_set);
25340 ++
25341 ++ return;
25342 ++}
25343 ++
25344 ++int
25345 ++gr_find_uid(const uid_t uid)
25346 ++{
25347 ++ struct crash_uid *tmp = uid_set;
25348 ++ uid_t buid;
25349 ++ int low = 0, high = uid_used - 1, mid;
25350 ++
25351 ++ while (high >= low) {
25352 ++ mid = (low + high) >> 1;
25353 ++ buid = tmp[mid].uid;
25354 ++ if (buid == uid)
25355 ++ return mid;
25356 ++ if (buid > uid)
25357 ++ high = mid - 1;
25358 ++ if (buid < uid)
25359 ++ low = mid + 1;
25360 ++ }
25361 ++
25362 ++ return -1;
25363 ++}
25364 ++
25365 ++static __inline__ void
25366 ++gr_insertsort(void)
25367 ++{
25368 ++ unsigned short i, j;
25369 ++ struct crash_uid index;
25370 ++
25371 ++ for (i = 1; i < uid_used; i++) {
25372 ++ index = uid_set[i];
25373 ++ j = i;
25374 ++ while ((j > 0) && uid_set[j - 1].uid > index.uid) {
25375 ++ uid_set[j] = uid_set[j - 1];
25376 ++ j--;
25377 ++ }
25378 ++ uid_set[j] = index;
25379 ++ }
25380 ++
25381 ++ return;
25382 ++}
25383 ++
25384 ++static __inline__ void
25385 ++gr_insert_uid(const uid_t uid, const unsigned long expires)
25386 ++{
25387 ++ int loc;
25388 ++
25389 ++ if (uid_used == GR_UIDTABLE_MAX)
25390 ++ return;
25391 ++
25392 ++ loc = gr_find_uid(uid);
25393 ++
25394 ++ if (loc >= 0) {
25395 ++ uid_set[loc].expires = expires;
25396 ++ return;
25397 ++ }
25398 ++
25399 ++ uid_set[uid_used].uid = uid;
25400 ++ uid_set[uid_used].expires = expires;
25401 ++ uid_used++;
25402 ++
25403 ++ gr_insertsort();
25404 ++
25405 ++ return;
25406 ++}
25407 ++
25408 ++void
25409 ++gr_remove_uid(const unsigned short loc)
25410 ++{
25411 ++ unsigned short i;
25412 ++
25413 ++ for (i = loc + 1; i < uid_used; i++)
25414 ++ uid_set[i - 1] = uid_set[i];
25415 ++
25416 ++ uid_used--;
25417 ++
25418 ++ return;
25419 ++}
25420 ++
25421 ++int
25422 ++gr_check_crash_uid(const uid_t uid)
25423 ++{
25424 ++ int loc;
25425 ++ int ret = 0;
25426 ++
25427 ++ if (unlikely(!gr_acl_is_enabled()))
25428 ++ return 0;
25429 ++
25430 ++ spin_lock(&gr_uid_lock);
25431 ++ loc = gr_find_uid(uid);
25432 ++
25433 ++ if (loc < 0)
25434 ++ goto out_unlock;
25435 ++
25436 ++ if (time_before_eq(uid_set[loc].expires, get_seconds()))
25437 ++ gr_remove_uid(loc);
25438 ++ else
25439 ++ ret = 1;
25440 ++
25441 ++out_unlock:
25442 ++ spin_unlock(&gr_uid_lock);
25443 ++ return ret;
25444 ++}
25445 ++
25446 ++static __inline__ int
25447 ++proc_is_setxid(const struct task_struct *task)
25448 ++{
25449 ++ if (task->uid != task->euid || task->uid != task->suid ||
25450 ++ task->uid != task->fsuid)
25451 ++ return 1;
25452 ++ if (task->gid != task->egid || task->gid != task->sgid ||
25453 ++ task->gid != task->fsgid)
25454 ++ return 1;
25455 ++
25456 ++ return 0;
25457 ++}
25458 ++static __inline__ int
25459 ++gr_fake_force_sig(int sig, struct task_struct *t)
25460 ++{
25461 ++ unsigned long int flags;
25462 ++ int ret, blocked, ignored;
25463 ++ struct k_sigaction *action;
25464 ++
25465 ++ spin_lock_irqsave(&t->sighand->siglock, flags);
25466 ++ action = &t->sighand->action[sig-1];
25467 ++ ignored = action->sa.sa_handler == SIG_IGN;
25468 ++ blocked = sigismember(&t->blocked, sig);
25469 ++ if (blocked || ignored) {
25470 ++ action->sa.sa_handler = SIG_DFL;
25471 ++ if (blocked) {
25472 ++ sigdelset(&t->blocked, sig);
25473 ++ recalc_sigpending_and_wake(t);
25474 ++ }
25475 ++ }
25476 ++ if (action->sa.sa_handler == SIG_DFL)
25477 ++ t->signal->flags &= ~SIGNAL_UNKILLABLE;
25478 ++ ret = specific_send_sig_info(sig, SEND_SIG_PRIV, t);
25479 ++
25480 ++ spin_unlock_irqrestore(&t->sighand->siglock, flags);
25481 ++
25482 ++ return ret;
25483 ++}
25484 ++
25485 ++void
25486 ++gr_handle_crash(struct task_struct *task, const int sig)
25487 ++{
25488 ++ struct acl_subject_label *curr;
25489 ++ struct acl_subject_label *curr2;
25490 ++ struct task_struct *tsk, *tsk2;
25491 ++
25492 ++ if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
25493 ++ return;
25494 ++
25495 ++ if (unlikely(!gr_acl_is_enabled()))
25496 ++ return;
25497 ++
25498 ++ curr = task->acl;
25499 ++
25500 ++ if (!(curr->resmask & (1 << GR_CRASH_RES)))
25501 ++ return;
25502 ++
25503 ++ if (time_before_eq(curr->expires, get_seconds())) {
25504 ++ curr->expires = 0;
25505 ++ curr->crashes = 0;
25506 ++ }
25507 ++
25508 ++ curr->crashes++;
25509 ++
25510 ++ if (!curr->expires)
25511 ++ curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
25512 ++
25513 ++ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
25514 ++ time_after(curr->expires, get_seconds())) {
25515 ++ if (task->uid && proc_is_setxid(task)) {
25516 ++ gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
25517 ++ spin_lock(&gr_uid_lock);
25518 ++ gr_insert_uid(task->uid, curr->expires);
25519 ++ spin_unlock(&gr_uid_lock);
25520 ++ curr->expires = 0;
25521 ++ curr->crashes = 0;
25522 ++ read_lock(&tasklist_lock);
25523 ++ do_each_thread(tsk2, tsk) {
25524 ++ if (tsk != task && tsk->uid == task->uid)
25525 ++ gr_fake_force_sig(SIGKILL, tsk);
25526 ++ } while_each_thread(tsk2, tsk);
25527 ++ read_unlock(&tasklist_lock);
25528 ++ } else {
25529 ++ gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
25530 ++ read_lock(&tasklist_lock);
25531 ++ do_each_thread(tsk2, tsk) {
25532 ++ if (likely(tsk != task)) {
25533 ++ curr2 = tsk->acl;
25534 ++
25535 ++ if (curr2->device == curr->device &&
25536 ++ curr2->inode == curr->inode)
25537 ++ gr_fake_force_sig(SIGKILL, tsk);
25538 ++ }
25539 ++ } while_each_thread(tsk2, tsk);
25540 ++ read_unlock(&tasklist_lock);
25541 ++ }
25542 ++ }
25543 ++
25544 ++ return;
25545 ++}
25546 ++
25547 ++int
25548 ++gr_check_crash_exec(const struct file *filp)
25549 ++{
25550 ++ struct acl_subject_label *curr;
25551 ++
25552 ++ if (unlikely(!gr_acl_is_enabled()))
25553 ++ return 0;
25554 ++
25555 ++ read_lock(&gr_inode_lock);
25556 ++ curr = lookup_acl_subj_label(filp->f_path.dentry->d_inode->i_ino,
25557 ++ filp->f_path.dentry->d_inode->i_sb->s_dev,
25558 ++ current->role);
25559 ++ read_unlock(&gr_inode_lock);
25560 ++
25561 ++ if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
25562 ++ (!curr->crashes && !curr->expires))
25563 ++ return 0;
25564 ++
25565 ++ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
25566 ++ time_after(curr->expires, get_seconds()))
25567 ++ return 1;
25568 ++ else if (time_before_eq(curr->expires, get_seconds())) {
25569 ++ curr->crashes = 0;
25570 ++ curr->expires = 0;
25571 ++ }
25572 ++
25573 ++ return 0;
25574 ++}
25575 ++
25576 ++void
25577 ++gr_handle_alertkill(struct task_struct *task)
25578 ++{
25579 ++ struct acl_subject_label *curracl;
25580 ++ __u32 curr_ip;
25581 ++ struct task_struct *p, *p2;
25582 ++
25583 ++ if (unlikely(!gr_acl_is_enabled()))
25584 ++ return;
25585 ++
25586 ++ curracl = task->acl;
25587 ++ curr_ip = task->signal->curr_ip;
25588 ++
25589 ++ if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
25590 ++ read_lock(&tasklist_lock);
25591 ++ do_each_thread(p2, p) {
25592 ++ if (p->signal->curr_ip == curr_ip)
25593 ++ gr_fake_force_sig(SIGKILL, p);
25594 ++ } while_each_thread(p2, p);
25595 ++ read_unlock(&tasklist_lock);
25596 ++ } else if (curracl->mode & GR_KILLPROC)
25597 ++ gr_fake_force_sig(SIGKILL, task);
25598 ++
25599 ++ return;
25600 ++}
25601 +diff -urNp linux-2.6.28.8/grsecurity/gracl_shm.c linux-2.6.28.8/grsecurity/gracl_shm.c
25602 +--- linux-2.6.28.8/grsecurity/gracl_shm.c 1969-12-31 19:00:00.000000000 -0500
25603 ++++ linux-2.6.28.8/grsecurity/gracl_shm.c 2009-02-21 09:37:49.000000000 -0500
25604 +@@ -0,0 +1,33 @@
25605 ++#include <linux/kernel.h>
25606 ++#include <linux/mm.h>
25607 ++#include <linux/sched.h>
25608 ++#include <linux/file.h>
25609 ++#include <linux/ipc.h>
25610 ++#include <linux/gracl.h>
25611 ++#include <linux/grsecurity.h>
25612 ++#include <linux/grinternal.h>
25613 ++
25614 ++int
25615 ++gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
25616 ++ const time_t shm_createtime, const uid_t cuid, const int shmid)
25617 ++{
25618 ++ struct task_struct *task;
25619 ++
25620 ++ if (!gr_acl_is_enabled())
25621 ++ return 1;
25622 ++
25623 ++ task = find_task_by_vpid(shm_cprid);
25624 ++
25625 ++ if (unlikely(!task))
25626 ++ task = find_task_by_vpid(shm_lapid);
25627 ++
25628 ++ if (unlikely(task && (time_before_eq((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
25629 ++ (task->pid == shm_lapid)) &&
25630 ++ (task->acl->mode & GR_PROTSHM) &&
25631 ++ (task->acl != current->acl))) {
25632 ++ gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
25633 ++ return 0;
25634 ++ }
25635 ++
25636 ++ return 1;
25637 ++}
25638 +diff -urNp linux-2.6.28.8/grsecurity/grsec_chdir.c linux-2.6.28.8/grsecurity/grsec_chdir.c
25639 +--- linux-2.6.28.8/grsecurity/grsec_chdir.c 1969-12-31 19:00:00.000000000 -0500
25640 ++++ linux-2.6.28.8/grsecurity/grsec_chdir.c 2009-02-21 09:37:49.000000000 -0500
25641 +@@ -0,0 +1,19 @@
25642 ++#include <linux/kernel.h>
25643 ++#include <linux/sched.h>
25644 ++#include <linux/fs.h>
25645 ++#include <linux/file.h>
25646 ++#include <linux/grsecurity.h>
25647 ++#include <linux/grinternal.h>
25648 ++
25649 ++void
25650 ++gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
25651 ++{
25652 ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
25653 ++ if ((grsec_enable_chdir && grsec_enable_group &&
25654 ++ in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
25655 ++ !grsec_enable_group)) {
25656 ++ gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
25657 ++ }
25658 ++#endif
25659 ++ return;
25660 ++}
25661 +diff -urNp linux-2.6.28.8/grsecurity/grsec_chroot.c linux-2.6.28.8/grsecurity/grsec_chroot.c
25662 +--- linux-2.6.28.8/grsecurity/grsec_chroot.c 1969-12-31 19:00:00.000000000 -0500
25663 ++++ linux-2.6.28.8/grsecurity/grsec_chroot.c 2009-02-21 09:37:49.000000000 -0500
25664 +@@ -0,0 +1,336 @@
25665 ++#include <linux/kernel.h>
25666 ++#include <linux/module.h>
25667 ++#include <linux/sched.h>
25668 ++#include <linux/file.h>
25669 ++#include <linux/fs.h>
25670 ++#include <linux/mount.h>
25671 ++#include <linux/types.h>
25672 ++#include <linux/pid_namespace.h>
25673 ++#include <linux/grsecurity.h>
25674 ++#include <linux/grinternal.h>
25675 ++
25676 ++int
25677 ++gr_handle_chroot_unix(const pid_t pid)
25678 ++{
25679 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
25680 ++ struct pid *spid = NULL;
25681 ++
25682 ++ if (unlikely(!grsec_enable_chroot_unix))
25683 ++ return 1;
25684 ++
25685 ++ if (likely(!proc_is_chrooted(current)))
25686 ++ return 1;
25687 ++
25688 ++ read_lock(&tasklist_lock);
25689 ++
25690 ++ spid = find_vpid(pid);
25691 ++ if (spid) {
25692 ++ struct task_struct *p;
25693 ++ p = pid_task(spid, PIDTYPE_PID);
25694 ++ task_lock(p);
25695 ++ if (unlikely(!have_same_root(current, p))) {
25696 ++ task_unlock(p);
25697 ++ read_unlock(&tasklist_lock);
25698 ++ gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
25699 ++ return 0;
25700 ++ }
25701 ++ task_unlock(p);
25702 ++ }
25703 ++ read_unlock(&tasklist_lock);
25704 ++#endif
25705 ++ return 1;
25706 ++}
25707 ++
25708 ++int
25709 ++gr_handle_chroot_nice(void)
25710 ++{
25711 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
25712 ++ if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
25713 ++ gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
25714 ++ return -EPERM;
25715 ++ }
25716 ++#endif
25717 ++ return 0;
25718 ++}
25719 ++
25720 ++int
25721 ++gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
25722 ++{
25723 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
25724 ++ if (grsec_enable_chroot_nice && (niceval < task_nice(p))
25725 ++ && proc_is_chrooted(current)) {
25726 ++ gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
25727 ++ return -EACCES;
25728 ++ }
25729 ++#endif
25730 ++ return 0;
25731 ++}
25732 ++
25733 ++int
25734 ++gr_handle_chroot_rawio(const struct inode *inode)
25735 ++{
25736 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
25737 ++ if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
25738 ++ inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
25739 ++ return 1;
25740 ++#endif
25741 ++ return 0;
25742 ++}
25743 ++
25744 ++int
25745 ++gr_pid_is_chrooted(struct task_struct *p)
25746 ++{
25747 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
25748 ++ if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL)
25749 ++ return 0;
25750 ++
25751 ++ task_lock(p);
25752 ++ if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
25753 ++ !have_same_root(current, p)) {
25754 ++ task_unlock(p);
25755 ++ return 1;
25756 ++ }
25757 ++ task_unlock(p);
25758 ++#endif
25759 ++ return 0;
25760 ++}
25761 ++
25762 ++EXPORT_SYMBOL(gr_pid_is_chrooted);
25763 ++
25764 ++#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
25765 ++int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
25766 ++{
25767 ++ struct dentry *dentry = (struct dentry *)u_dentry;
25768 ++ struct vfsmount *mnt = (struct vfsmount *)u_mnt;
25769 ++ struct dentry *realroot;
25770 ++ struct vfsmount *realrootmnt;
25771 ++ struct dentry *currentroot;
25772 ++ struct vfsmount *currentmnt;
25773 ++ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
25774 ++ int ret = 1;
25775 ++
25776 ++ read_lock(&reaper->fs->lock);
25777 ++ realrootmnt = mntget(reaper->fs->root.mnt);
25778 ++ realroot = dget(reaper->fs->root.dentry);
25779 ++ read_unlock(&reaper->fs->lock);
25780 ++
25781 ++ read_lock(&current->fs->lock);
25782 ++ currentmnt = mntget(current->fs->root.mnt);
25783 ++ currentroot = dget(current->fs->root.dentry);
25784 ++ read_unlock(&current->fs->lock);
25785 ++
25786 ++ spin_lock(&dcache_lock);
25787 ++ for (;;) {
25788 ++ if (unlikely((dentry == realroot && mnt == realrootmnt)
25789 ++ || (dentry == currentroot && mnt == currentmnt)))
25790 ++ break;
25791 ++ if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
25792 ++ if (mnt->mnt_parent == mnt)
25793 ++ break;
25794 ++ dentry = mnt->mnt_mountpoint;
25795 ++ mnt = mnt->mnt_parent;
25796 ++ continue;
25797 ++ }
25798 ++ dentry = dentry->d_parent;
25799 ++ }
25800 ++ spin_unlock(&dcache_lock);
25801 ++
25802 ++ dput(currentroot);
25803 ++ mntput(currentmnt);
25804 ++
25805 ++ /* access is outside of chroot */
25806 ++ if (dentry == realroot && mnt == realrootmnt)
25807 ++ ret = 0;
25808 ++
25809 ++ dput(realroot);
25810 ++ mntput(realrootmnt);
25811 ++ return ret;
25812 ++}
25813 ++#endif
25814 ++
25815 ++int
25816 ++gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
25817 ++{
25818 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
25819 ++ if (!grsec_enable_chroot_fchdir)
25820 ++ return 1;
25821 ++
25822 ++ if (!proc_is_chrooted(current))
25823 ++ return 1;
25824 ++ else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
25825 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
25826 ++ return 0;
25827 ++ }
25828 ++#endif
25829 ++ return 1;
25830 ++}
25831 ++
25832 ++int
25833 ++gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
25834 ++ const time_t shm_createtime)
25835 ++{
25836 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
25837 ++ struct pid *pid = NULL;
25838 ++ time_t starttime;
25839 ++
25840 ++ if (unlikely(!grsec_enable_chroot_shmat))
25841 ++ return 1;
25842 ++
25843 ++ if (likely(!proc_is_chrooted(current)))
25844 ++ return 1;
25845 ++
25846 ++ read_lock(&tasklist_lock);
25847 ++
25848 ++ pid = find_vpid(shm_cprid);
25849 ++ if (pid) {
25850 ++ struct task_struct *p;
25851 ++ p = pid_task(pid, PIDTYPE_PID);
25852 ++ task_lock(p);
25853 ++ starttime = p->start_time.tv_sec;
25854 ++ if (unlikely(!have_same_root(current, p) &&
25855 ++ time_before_eq((unsigned long)starttime, (unsigned long)shm_createtime))) {
25856 ++ task_unlock(p);
25857 ++ read_unlock(&tasklist_lock);
25858 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
25859 ++ return 0;
25860 ++ }
25861 ++ task_unlock(p);
25862 ++ } else {
25863 ++ pid = find_vpid(shm_lapid);
25864 ++ if (pid) {
25865 ++ struct task_struct *p;
25866 ++ p = pid_task(pid, PIDTYPE_PID);
25867 ++ task_lock(p);
25868 ++ if (unlikely(!have_same_root(current, p))) {
25869 ++ task_unlock(p);
25870 ++ read_unlock(&tasklist_lock);
25871 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
25872 ++ return 0;
25873 ++ }
25874 ++ task_unlock(p);
25875 ++ }
25876 ++ }
25877 ++
25878 ++ read_unlock(&tasklist_lock);
25879 ++#endif
25880 ++ return 1;
25881 ++}
25882 ++
25883 ++void
25884 ++gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
25885 ++{
25886 ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
25887 ++ if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
25888 ++ gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
25889 ++#endif
25890 ++ return;
25891 ++}
25892 ++
25893 ++int
25894 ++gr_handle_chroot_mknod(const struct dentry *dentry,
25895 ++ const struct vfsmount *mnt, const int mode)
25896 ++{
25897 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
25898 ++ if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) &&
25899 ++ proc_is_chrooted(current)) {
25900 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
25901 ++ return -EPERM;
25902 ++ }
25903 ++#endif
25904 ++ return 0;
25905 ++}
25906 ++
25907 ++int
25908 ++gr_handle_chroot_mount(const struct dentry *dentry,
25909 ++ const struct vfsmount *mnt, const char *dev_name)
25910 ++{
25911 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
25912 ++ if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
25913 ++ gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
25914 ++ return -EPERM;
25915 ++ }
25916 ++#endif
25917 ++ return 0;
25918 ++}
25919 ++
25920 ++int
25921 ++gr_handle_chroot_pivot(void)
25922 ++{
25923 ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
25924 ++ if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
25925 ++ gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
25926 ++ return -EPERM;
25927 ++ }
25928 ++#endif
25929 ++ return 0;
25930 ++}
25931 ++
25932 ++int
25933 ++gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
25934 ++{
25935 ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
25936 ++ if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
25937 ++ !gr_is_outside_chroot(dentry, mnt)) {
25938 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
25939 ++ return -EPERM;
25940 ++ }
25941 ++#endif
25942 ++ return 0;
25943 ++}
25944 ++
25945 ++void
25946 ++gr_handle_chroot_caps(struct task_struct *task)
25947 ++{
25948 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
25949 ++ if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
25950 ++ kernel_cap_t chroot_caps = GR_CHROOT_CAPS;
25951 ++ task->cap_permitted =
25952 ++ cap_drop(task->cap_permitted, chroot_caps);
25953 ++ task->cap_inheritable =
25954 ++ cap_drop(task->cap_inheritable, chroot_caps);
25955 ++ task->cap_effective =
25956 ++ cap_drop(task->cap_effective, chroot_caps);
25957 ++ }
25958 ++#endif
25959 ++ return;
25960 ++}
25961 ++
25962 ++int
25963 ++gr_handle_chroot_sysctl(const int op)
25964 ++{
25965 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
25966 ++ if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
25967 ++ && (op & MAY_WRITE))
25968 ++ return -EACCES;
25969 ++#endif
25970 ++ return 0;
25971 ++}
25972 ++
25973 ++void
25974 ++gr_handle_chroot_chdir(struct path *path)
25975 ++{
25976 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
25977 ++ if (grsec_enable_chroot_chdir)
25978 ++ set_fs_pwd(current->fs, path);
25979 ++#endif
25980 ++ return;
25981 ++}
25982 ++
25983 ++int
25984 ++gr_handle_chroot_chmod(const struct dentry *dentry,
25985 ++ const struct vfsmount *mnt, const int mode)
25986 ++{
25987 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
25988 ++ if (grsec_enable_chroot_chmod &&
25989 ++ ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
25990 ++ proc_is_chrooted(current)) {
25991 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
25992 ++ return -EPERM;
25993 ++ }
25994 ++#endif
25995 ++ return 0;
25996 ++}
25997 ++
25998 ++#ifdef CONFIG_SECURITY
25999 ++EXPORT_SYMBOL(gr_handle_chroot_caps);
26000 ++#endif
26001 +diff -urNp linux-2.6.28.8/grsecurity/grsec_disabled.c linux-2.6.28.8/grsecurity/grsec_disabled.c
26002 +--- linux-2.6.28.8/grsecurity/grsec_disabled.c 1969-12-31 19:00:00.000000000 -0500
26003 ++++ linux-2.6.28.8/grsecurity/grsec_disabled.c 2009-03-07 14:23:04.000000000 -0500
26004 +@@ -0,0 +1,418 @@
26005 ++#include <linux/kernel.h>
26006 ++#include <linux/module.h>
26007 ++#include <linux/sched.h>
26008 ++#include <linux/file.h>
26009 ++#include <linux/fs.h>
26010 ++#include <linux/kdev_t.h>
26011 ++#include <linux/net.h>
26012 ++#include <linux/in.h>
26013 ++#include <linux/ip.h>
26014 ++#include <linux/skbuff.h>
26015 ++#include <linux/sysctl.h>
26016 ++
26017 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
26018 ++void
26019 ++pax_set_initial_flags(struct linux_binprm *bprm)
26020 ++{
26021 ++ return;
26022 ++}
26023 ++#endif
26024 ++
26025 ++#ifdef CONFIG_SYSCTL
26026 ++__u32
26027 ++gr_handle_sysctl(const struct ctl_table * table, const int op)
26028 ++{
26029 ++ return 0;
26030 ++}
26031 ++#endif
26032 ++
26033 ++int
26034 ++gr_acl_is_enabled(void)
26035 ++{
26036 ++ return 0;
26037 ++}
26038 ++
26039 ++int
26040 ++gr_handle_rawio(const struct inode *inode)
26041 ++{
26042 ++ return 0;
26043 ++}
26044 ++
26045 ++void
26046 ++gr_acl_handle_psacct(struct task_struct *task, const long code)
26047 ++{
26048 ++ return;
26049 ++}
26050 ++
26051 ++int
26052 ++gr_handle_ptrace(struct task_struct *task, const long request)
26053 ++{
26054 ++ return 0;
26055 ++}
26056 ++
26057 ++int
26058 ++gr_handle_proc_ptrace(struct task_struct *task)
26059 ++{
26060 ++ return 0;
26061 ++}
26062 ++
26063 ++void
26064 ++gr_learn_resource(const struct task_struct *task,
26065 ++ const int res, const unsigned long wanted, const int gt)
26066 ++{
26067 ++ return;
26068 ++}
26069 ++
26070 ++int
26071 ++gr_set_acls(const int type)
26072 ++{
26073 ++ return 0;
26074 ++}
26075 ++
26076 ++int
26077 ++gr_check_hidden_task(const struct task_struct *tsk)
26078 ++{
26079 ++ return 0;
26080 ++}
26081 ++
26082 ++int
26083 ++gr_check_protected_task(const struct task_struct *task)
26084 ++{
26085 ++ return 0;
26086 ++}
26087 ++
26088 ++void
26089 ++gr_copy_label(struct task_struct *tsk)
26090 ++{
26091 ++ return;
26092 ++}
26093 ++
26094 ++void
26095 ++gr_set_pax_flags(struct task_struct *task)
26096 ++{
26097 ++ return;
26098 ++}
26099 ++
26100 ++int
26101 ++gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
26102 ++{
26103 ++ return 0;
26104 ++}
26105 ++
26106 ++void
26107 ++gr_handle_delete(const ino_t ino, const dev_t dev)
26108 ++{
26109 ++ return;
26110 ++}
26111 ++
26112 ++void
26113 ++gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
26114 ++{
26115 ++ return;
26116 ++}
26117 ++
26118 ++void
26119 ++gr_handle_crash(struct task_struct *task, const int sig)
26120 ++{
26121 ++ return;
26122 ++}
26123 ++
26124 ++int
26125 ++gr_check_crash_exec(const struct file *filp)
26126 ++{
26127 ++ return 0;
26128 ++}
26129 ++
26130 ++int
26131 ++gr_check_crash_uid(const uid_t uid)
26132 ++{
26133 ++ return 0;
26134 ++}
26135 ++
26136 ++void
26137 ++gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
26138 ++ struct dentry *old_dentry,
26139 ++ struct dentry *new_dentry,
26140 ++ struct vfsmount *mnt, const __u8 replace)
26141 ++{
26142 ++ return;
26143 ++}
26144 ++
26145 ++int
26146 ++gr_search_socket(const int family, const int type, const int protocol)
26147 ++{
26148 ++ return 1;
26149 ++}
26150 ++
26151 ++int
26152 ++gr_search_connectbind(const int mode, const struct socket *sock,
26153 ++ const struct sockaddr_in *addr)
26154 ++{
26155 ++ return 0;
26156 ++}
26157 ++
26158 ++int
26159 ++gr_task_is_capable(struct task_struct *task, const int cap)
26160 ++{
26161 ++ return 1;
26162 ++}
26163 ++
26164 ++int
26165 ++gr_is_capable_nolog(const int cap)
26166 ++{
26167 ++ return 1;
26168 ++}
26169 ++
26170 ++void
26171 ++gr_handle_alertkill(struct task_struct *task)
26172 ++{
26173 ++ return;
26174 ++}
26175 ++
26176 ++__u32
26177 ++gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
26178 ++{
26179 ++ return 1;
26180 ++}
26181 ++
26182 ++__u32
26183 ++gr_acl_handle_hidden_file(const struct dentry * dentry,
26184 ++ const struct vfsmount * mnt)
26185 ++{
26186 ++ return 1;
26187 ++}
26188 ++
26189 ++__u32
26190 ++gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
26191 ++ const int fmode)
26192 ++{
26193 ++ return 1;
26194 ++}
26195 ++
26196 ++__u32
26197 ++gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
26198 ++{
26199 ++ return 1;
26200 ++}
26201 ++
26202 ++__u32
26203 ++gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
26204 ++{
26205 ++ return 1;
26206 ++}
26207 ++
26208 ++int
26209 ++gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
26210 ++ unsigned int *vm_flags)
26211 ++{
26212 ++ return 1;
26213 ++}
26214 ++
26215 ++__u32
26216 ++gr_acl_handle_truncate(const struct dentry * dentry,
26217 ++ const struct vfsmount * mnt)
26218 ++{
26219 ++ return 1;
26220 ++}
26221 ++
26222 ++__u32
26223 ++gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
26224 ++{
26225 ++ return 1;
26226 ++}
26227 ++
26228 ++__u32
26229 ++gr_acl_handle_access(const struct dentry * dentry,
26230 ++ const struct vfsmount * mnt, const int fmode)
26231 ++{
26232 ++ return 1;
26233 ++}
26234 ++
26235 ++__u32
26236 ++gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
26237 ++ mode_t mode)
26238 ++{
26239 ++ return 1;
26240 ++}
26241 ++
26242 ++__u32
26243 ++gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
26244 ++ mode_t mode)
26245 ++{
26246 ++ return 1;
26247 ++}
26248 ++
26249 ++__u32
26250 ++gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
26251 ++{
26252 ++ return 1;
26253 ++}
26254 ++
26255 ++void
26256 ++grsecurity_init(void)
26257 ++{
26258 ++ return;
26259 ++}
26260 ++
26261 ++__u32
26262 ++gr_acl_handle_mknod(const struct dentry * new_dentry,
26263 ++ const struct dentry * parent_dentry,
26264 ++ const struct vfsmount * parent_mnt,
26265 ++ const int mode)
26266 ++{
26267 ++ return 1;
26268 ++}
26269 ++
26270 ++__u32
26271 ++gr_acl_handle_mkdir(const struct dentry * new_dentry,
26272 ++ const struct dentry * parent_dentry,
26273 ++ const struct vfsmount * parent_mnt)
26274 ++{
26275 ++ return 1;
26276 ++}
26277 ++
26278 ++__u32
26279 ++gr_acl_handle_symlink(const struct dentry * new_dentry,
26280 ++ const struct dentry * parent_dentry,
26281 ++ const struct vfsmount * parent_mnt, const char *from)
26282 ++{
26283 ++ return 1;
26284 ++}
26285 ++
26286 ++__u32
26287 ++gr_acl_handle_link(const struct dentry * new_dentry,
26288 ++ const struct dentry * parent_dentry,
26289 ++ const struct vfsmount * parent_mnt,
26290 ++ const struct dentry * old_dentry,
26291 ++ const struct vfsmount * old_mnt, const char *to)
26292 ++{
26293 ++ return 1;
26294 ++}
26295 ++
26296 ++int
26297 ++gr_acl_handle_rename(const struct dentry *new_dentry,
26298 ++ const struct dentry *parent_dentry,
26299 ++ const struct vfsmount *parent_mnt,
26300 ++ const struct dentry *old_dentry,
26301 ++ const struct inode *old_parent_inode,
26302 ++ const struct vfsmount *old_mnt, const char *newname)
26303 ++{
26304 ++ return 0;
26305 ++}
26306 ++
26307 ++int
26308 ++gr_acl_handle_filldir(const struct file *file, const char *name,
26309 ++ const int namelen, const ino_t ino)
26310 ++{
26311 ++ return 1;
26312 ++}
26313 ++
26314 ++int
26315 ++gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
26316 ++ const time_t shm_createtime, const uid_t cuid, const int shmid)
26317 ++{
26318 ++ return 1;
26319 ++}
26320 ++
26321 ++int
26322 ++gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
26323 ++{
26324 ++ return 0;
26325 ++}
26326 ++
26327 ++int
26328 ++gr_search_accept(const struct socket *sock)
26329 ++{
26330 ++ return 0;
26331 ++}
26332 ++
26333 ++int
26334 ++gr_search_listen(const struct socket *sock)
26335 ++{
26336 ++ return 0;
26337 ++}
26338 ++
26339 ++int
26340 ++gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
26341 ++{
26342 ++ return 0;
26343 ++}
26344 ++
26345 ++__u32
26346 ++gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
26347 ++{
26348 ++ return 1;
26349 ++}
26350 ++
26351 ++__u32
26352 ++gr_acl_handle_creat(const struct dentry * dentry,
26353 ++ const struct dentry * p_dentry,
26354 ++ const struct vfsmount * p_mnt, const int fmode,
26355 ++ const int imode)
26356 ++{
26357 ++ return 1;
26358 ++}
26359 ++
26360 ++void
26361 ++gr_acl_handle_exit(void)
26362 ++{
26363 ++ return;
26364 ++}
26365 ++
26366 ++int
26367 ++gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
26368 ++{
26369 ++ return 1;
26370 ++}
26371 ++
26372 ++void
26373 ++gr_set_role_label(const uid_t uid, const gid_t gid)
26374 ++{
26375 ++ return;
26376 ++}
26377 ++
26378 ++int
26379 ++gr_acl_handle_procpidmem(const struct task_struct *task)
26380 ++{
26381 ++ return 0;
26382 ++}
26383 ++
26384 ++int
26385 ++gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
26386 ++{
26387 ++ return 0;
26388 ++}
26389 ++
26390 ++int
26391 ++gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
26392 ++{
26393 ++ return 0;
26394 ++}
26395 ++
26396 ++void
26397 ++gr_set_kernel_label(struct task_struct *task)
26398 ++{
26399 ++ return;
26400 ++}
26401 ++
26402 ++int
26403 ++gr_check_user_change(int real, int effective, int fs)
26404 ++{
26405 ++ return 0;
26406 ++}
26407 ++
26408 ++int
26409 ++gr_check_group_change(int real, int effective, int fs)
26410 ++{
26411 ++ return 0;
26412 ++}
26413 ++
26414 ++
26415 ++EXPORT_SYMBOL(gr_task_is_capable);
26416 ++EXPORT_SYMBOL(gr_is_capable_nolog);
26417 ++EXPORT_SYMBOL(gr_learn_resource);
26418 ++EXPORT_SYMBOL(gr_set_kernel_label);
26419 ++#ifdef CONFIG_SECURITY
26420 ++EXPORT_SYMBOL(gr_check_user_change);
26421 ++EXPORT_SYMBOL(gr_check_group_change);
26422 ++#endif
26423 +diff -urNp linux-2.6.28.8/grsecurity/grsec_exec.c linux-2.6.28.8/grsecurity/grsec_exec.c
26424 +--- linux-2.6.28.8/grsecurity/grsec_exec.c 1969-12-31 19:00:00.000000000 -0500
26425 ++++ linux-2.6.28.8/grsecurity/grsec_exec.c 2009-02-21 09:37:49.000000000 -0500
26426 +@@ -0,0 +1,88 @@
26427 ++#include <linux/kernel.h>
26428 ++#include <linux/sched.h>
26429 ++#include <linux/file.h>
26430 ++#include <linux/binfmts.h>
26431 ++#include <linux/smp_lock.h>
26432 ++#include <linux/fs.h>
26433 ++#include <linux/types.h>
26434 ++#include <linux/grdefs.h>
26435 ++#include <linux/grinternal.h>
26436 ++#include <linux/capability.h>
26437 ++
26438 ++#include <asm/uaccess.h>
26439 ++
26440 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
26441 ++static char gr_exec_arg_buf[132];
26442 ++static DECLARE_MUTEX(gr_exec_arg_sem);
26443 ++#endif
26444 ++
26445 ++int
26446 ++gr_handle_nproc(void)
26447 ++{
26448 ++#ifdef CONFIG_GRKERNSEC_EXECVE
26449 ++ if (grsec_enable_execve && current->user &&
26450 ++ (atomic_read(&current->user->processes) >
26451 ++ current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
26452 ++ !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
26453 ++ gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
26454 ++ return -EAGAIN;
26455 ++ }
26456 ++#endif
26457 ++ return 0;
26458 ++}
26459 ++
26460 ++void
26461 ++gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
26462 ++{
26463 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
26464 ++ char *grarg = gr_exec_arg_buf;
26465 ++ unsigned int i, x, execlen = 0;
26466 ++ char c;
26467 ++
26468 ++ if (!((grsec_enable_execlog && grsec_enable_group &&
26469 ++ in_group_p(grsec_audit_gid))
26470 ++ || (grsec_enable_execlog && !grsec_enable_group)))
26471 ++ return;
26472 ++
26473 ++ down(&gr_exec_arg_sem);
26474 ++ memset(grarg, 0, sizeof(gr_exec_arg_buf));
26475 ++
26476 ++ if (unlikely(argv == NULL))
26477 ++ goto log;
26478 ++
26479 ++ for (i = 0; i < bprm->argc && execlen < 128; i++) {
26480 ++ const char __user *p;
26481 ++ unsigned int len;
26482 ++
26483 ++ if (copy_from_user(&p, argv + i, sizeof(p)))
26484 ++ goto log;
26485 ++ if (!p)
26486 ++ goto log;
26487 ++ len = strnlen_user(p, 128 - execlen);
26488 ++ if (len > 128 - execlen)
26489 ++ len = 128 - execlen;
26490 ++ else if (len > 0)
26491 ++ len--;
26492 ++ if (copy_from_user(grarg + execlen, p, len))
26493 ++ goto log;
26494 ++
26495 ++ /* rewrite unprintable characters */
26496 ++ for (x = 0; x < len; x++) {
26497 ++ c = *(grarg + execlen + x);
26498 ++ if (c < 32 || c > 126)
26499 ++ *(grarg + execlen + x) = ' ';
26500 ++ }
26501 ++
26502 ++ execlen += len;
26503 ++ *(grarg + execlen) = ' ';
26504 ++ *(grarg + execlen + 1) = '\0';
26505 ++ execlen++;
26506 ++ }
26507 ++
26508 ++ log:
26509 ++ gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_path.dentry,
26510 ++ bprm->file->f_path.mnt, grarg);
26511 ++ up(&gr_exec_arg_sem);
26512 ++#endif
26513 ++ return;
26514 ++}
26515 +diff -urNp linux-2.6.28.8/grsecurity/grsec_fifo.c linux-2.6.28.8/grsecurity/grsec_fifo.c
26516 +--- linux-2.6.28.8/grsecurity/grsec_fifo.c 1969-12-31 19:00:00.000000000 -0500
26517 ++++ linux-2.6.28.8/grsecurity/grsec_fifo.c 2009-02-21 09:37:49.000000000 -0500
26518 +@@ -0,0 +1,22 @@
26519 ++#include <linux/kernel.h>
26520 ++#include <linux/sched.h>
26521 ++#include <linux/fs.h>
26522 ++#include <linux/file.h>
26523 ++#include <linux/grinternal.h>
26524 ++
26525 ++int
26526 ++gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
26527 ++ const struct dentry *dir, const int flag, const int acc_mode)
26528 ++{
26529 ++#ifdef CONFIG_GRKERNSEC_FIFO
26530 ++ if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
26531 ++ !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
26532 ++ (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
26533 ++ (current->fsuid != dentry->d_inode->i_uid)) {
26534 ++ if (!generic_permission(dentry->d_inode, acc_mode, NULL))
26535 ++ gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
26536 ++ return -EACCES;
26537 ++ }
26538 ++#endif
26539 ++ return 0;
26540 ++}
26541 +diff -urNp linux-2.6.28.8/grsecurity/grsec_fork.c linux-2.6.28.8/grsecurity/grsec_fork.c
26542 +--- linux-2.6.28.8/grsecurity/grsec_fork.c 1969-12-31 19:00:00.000000000 -0500
26543 ++++ linux-2.6.28.8/grsecurity/grsec_fork.c 2009-02-21 09:37:49.000000000 -0500
26544 +@@ -0,0 +1,15 @@
26545 ++#include <linux/kernel.h>
26546 ++#include <linux/sched.h>
26547 ++#include <linux/grsecurity.h>
26548 ++#include <linux/grinternal.h>
26549 ++#include <linux/errno.h>
26550 ++
26551 ++void
26552 ++gr_log_forkfail(const int retval)
26553 ++{
26554 ++#ifdef CONFIG_GRKERNSEC_FORKFAIL
26555 ++ if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
26556 ++ gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
26557 ++#endif
26558 ++ return;
26559 ++}
26560 +diff -urNp linux-2.6.28.8/grsecurity/grsec_init.c linux-2.6.28.8/grsecurity/grsec_init.c
26561 +--- linux-2.6.28.8/grsecurity/grsec_init.c 1969-12-31 19:00:00.000000000 -0500
26562 ++++ linux-2.6.28.8/grsecurity/grsec_init.c 2009-02-21 09:37:49.000000000 -0500
26563 +@@ -0,0 +1,230 @@
26564 ++#include <linux/kernel.h>
26565 ++#include <linux/sched.h>
26566 ++#include <linux/mm.h>
26567 ++#include <linux/smp_lock.h>
26568 ++#include <linux/gracl.h>
26569 ++#include <linux/slab.h>
26570 ++#include <linux/vmalloc.h>
26571 ++#include <linux/percpu.h>
26572 ++
26573 ++int grsec_enable_link;
26574 ++int grsec_enable_dmesg;
26575 ++int grsec_enable_fifo;
26576 ++int grsec_enable_execve;
26577 ++int grsec_enable_execlog;
26578 ++int grsec_enable_signal;
26579 ++int grsec_enable_forkfail;
26580 ++int grsec_enable_time;
26581 ++int grsec_enable_audit_textrel;
26582 ++int grsec_enable_group;
26583 ++int grsec_audit_gid;
26584 ++int grsec_enable_chdir;
26585 ++int grsec_enable_audit_ipc;
26586 ++int grsec_enable_mount;
26587 ++int grsec_enable_chroot_findtask;
26588 ++int grsec_enable_chroot_mount;
26589 ++int grsec_enable_chroot_shmat;
26590 ++int grsec_enable_chroot_fchdir;
26591 ++int grsec_enable_chroot_double;
26592 ++int grsec_enable_chroot_pivot;
26593 ++int grsec_enable_chroot_chdir;
26594 ++int grsec_enable_chroot_chmod;
26595 ++int grsec_enable_chroot_mknod;
26596 ++int grsec_enable_chroot_nice;
26597 ++int grsec_enable_chroot_execlog;
26598 ++int grsec_enable_chroot_caps;
26599 ++int grsec_enable_chroot_sysctl;
26600 ++int grsec_enable_chroot_unix;
26601 ++int grsec_enable_tpe;
26602 ++int grsec_tpe_gid;
26603 ++int grsec_enable_tpe_all;
26604 ++int grsec_enable_socket_all;
26605 ++int grsec_socket_all_gid;
26606 ++int grsec_enable_socket_client;
26607 ++int grsec_socket_client_gid;
26608 ++int grsec_enable_socket_server;
26609 ++int grsec_socket_server_gid;
26610 ++int grsec_resource_logging;
26611 ++int grsec_lock;
26612 ++
26613 ++DEFINE_SPINLOCK(grsec_alert_lock);
26614 ++unsigned long grsec_alert_wtime = 0;
26615 ++unsigned long grsec_alert_fyet = 0;
26616 ++
26617 ++DEFINE_SPINLOCK(grsec_audit_lock);
26618 ++
26619 ++DEFINE_RWLOCK(grsec_exec_file_lock);
26620 ++
26621 ++char *gr_shared_page[4];
26622 ++
26623 ++char *gr_alert_log_fmt;
26624 ++char *gr_audit_log_fmt;
26625 ++char *gr_alert_log_buf;
26626 ++char *gr_audit_log_buf;
26627 ++
26628 ++extern struct gr_arg *gr_usermode;
26629 ++extern unsigned char *gr_system_salt;
26630 ++extern unsigned char *gr_system_sum;
26631 ++
26632 ++void
26633 ++grsecurity_init(void)
26634 ++{
26635 ++ int j;
26636 ++ /* create the per-cpu shared pages */
26637 ++
26638 ++#ifdef CONFIG_X86
26639 ++ memset((char *)(0x41a + PAGE_OFFSET), 0, 36);
26640 ++#endif
26641 ++
26642 ++ for (j = 0; j < 4; j++) {
26643 ++ gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
26644 ++ if (gr_shared_page[j] == NULL) {
26645 ++ panic("Unable to allocate grsecurity shared page");
26646 ++ return;
26647 ++ }
26648 ++ }
26649 ++
26650 ++ /* allocate log buffers */
26651 ++ gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
26652 ++ if (!gr_alert_log_fmt) {
26653 ++ panic("Unable to allocate grsecurity alert log format buffer");
26654 ++ return;
26655 ++ }
26656 ++ gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
26657 ++ if (!gr_audit_log_fmt) {
26658 ++ panic("Unable to allocate grsecurity audit log format buffer");
26659 ++ return;
26660 ++ }
26661 ++ gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
26662 ++ if (!gr_alert_log_buf) {
26663 ++ panic("Unable to allocate grsecurity alert log buffer");
26664 ++ return;
26665 ++ }
26666 ++ gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
26667 ++ if (!gr_audit_log_buf) {
26668 ++ panic("Unable to allocate grsecurity audit log buffer");
26669 ++ return;
26670 ++ }
26671 ++
26672 ++ /* allocate memory for authentication structure */
26673 ++ gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
26674 ++ gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
26675 ++ gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
26676 ++
26677 ++ if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
26678 ++ panic("Unable to allocate grsecurity authentication structure");
26679 ++ return;
26680 ++ }
26681 ++
26682 ++#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
26683 ++#ifndef CONFIG_GRKERNSEC_SYSCTL
26684 ++ grsec_lock = 1;
26685 ++#endif
26686 ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
26687 ++ grsec_enable_audit_textrel = 1;
26688 ++#endif
26689 ++#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
26690 ++ grsec_enable_group = 1;
26691 ++ grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
26692 ++#endif
26693 ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
26694 ++ grsec_enable_chdir = 1;
26695 ++#endif
26696 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26697 ++ grsec_enable_audit_ipc = 1;
26698 ++#endif
26699 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
26700 ++ grsec_enable_mount = 1;
26701 ++#endif
26702 ++#ifdef CONFIG_GRKERNSEC_LINK
26703 ++ grsec_enable_link = 1;
26704 ++#endif
26705 ++#ifdef CONFIG_GRKERNSEC_DMESG
26706 ++ grsec_enable_dmesg = 1;
26707 ++#endif
26708 ++#ifdef CONFIG_GRKERNSEC_FIFO
26709 ++ grsec_enable_fifo = 1;
26710 ++#endif
26711 ++#ifdef CONFIG_GRKERNSEC_EXECVE
26712 ++ grsec_enable_execve = 1;
26713 ++#endif
26714 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
26715 ++ grsec_enable_execlog = 1;
26716 ++#endif
26717 ++#ifdef CONFIG_GRKERNSEC_SIGNAL
26718 ++ grsec_enable_signal = 1;
26719 ++#endif
26720 ++#ifdef CONFIG_GRKERNSEC_FORKFAIL
26721 ++ grsec_enable_forkfail = 1;
26722 ++#endif
26723 ++#ifdef CONFIG_GRKERNSEC_TIME
26724 ++ grsec_enable_time = 1;
26725 ++#endif
26726 ++#ifdef CONFIG_GRKERNSEC_RESLOG
26727 ++ grsec_resource_logging = 1;
26728 ++#endif
26729 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
26730 ++ grsec_enable_chroot_findtask = 1;
26731 ++#endif
26732 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
26733 ++ grsec_enable_chroot_unix = 1;
26734 ++#endif
26735 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
26736 ++ grsec_enable_chroot_mount = 1;
26737 ++#endif
26738 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
26739 ++ grsec_enable_chroot_fchdir = 1;
26740 ++#endif
26741 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
26742 ++ grsec_enable_chroot_shmat = 1;
26743 ++#endif
26744 ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
26745 ++ grsec_enable_chroot_double = 1;
26746 ++#endif
26747 ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
26748 ++ grsec_enable_chroot_pivot = 1;
26749 ++#endif
26750 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
26751 ++ grsec_enable_chroot_chdir = 1;
26752 ++#endif
26753 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
26754 ++ grsec_enable_chroot_chmod = 1;
26755 ++#endif
26756 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
26757 ++ grsec_enable_chroot_mknod = 1;
26758 ++#endif
26759 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
26760 ++ grsec_enable_chroot_nice = 1;
26761 ++#endif
26762 ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
26763 ++ grsec_enable_chroot_execlog = 1;
26764 ++#endif
26765 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
26766 ++ grsec_enable_chroot_caps = 1;
26767 ++#endif
26768 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
26769 ++ grsec_enable_chroot_sysctl = 1;
26770 ++#endif
26771 ++#ifdef CONFIG_GRKERNSEC_TPE
26772 ++ grsec_enable_tpe = 1;
26773 ++ grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
26774 ++#ifdef CONFIG_GRKERNSEC_TPE_ALL
26775 ++ grsec_enable_tpe_all = 1;
26776 ++#endif
26777 ++#endif
26778 ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
26779 ++ grsec_enable_socket_all = 1;
26780 ++ grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
26781 ++#endif
26782 ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
26783 ++ grsec_enable_socket_client = 1;
26784 ++ grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
26785 ++#endif
26786 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
26787 ++ grsec_enable_socket_server = 1;
26788 ++ grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
26789 ++#endif
26790 ++#endif
26791 ++
26792 ++ return;
26793 ++}
26794 +diff -urNp linux-2.6.28.8/grsecurity/grsec_ipc.c linux-2.6.28.8/grsecurity/grsec_ipc.c
26795 +--- linux-2.6.28.8/grsecurity/grsec_ipc.c 1969-12-31 19:00:00.000000000 -0500
26796 ++++ linux-2.6.28.8/grsecurity/grsec_ipc.c 2009-02-21 09:37:49.000000000 -0500
26797 +@@ -0,0 +1,81 @@
26798 ++#include <linux/kernel.h>
26799 ++#include <linux/sched.h>
26800 ++#include <linux/types.h>
26801 ++#include <linux/ipc.h>
26802 ++#include <linux/grsecurity.h>
26803 ++#include <linux/grinternal.h>
26804 ++
26805 ++void
26806 ++gr_log_msgget(const int ret, const int msgflg)
26807 ++{
26808 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26809 ++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
26810 ++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
26811 ++ !grsec_enable_group)) && (ret >= 0)
26812 ++ && (msgflg & IPC_CREAT))
26813 ++ gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
26814 ++#endif
26815 ++ return;
26816 ++}
26817 ++
26818 ++void
26819 ++gr_log_msgrm(const uid_t uid, const uid_t cuid)
26820 ++{
26821 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26822 ++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
26823 ++ grsec_enable_audit_ipc) ||
26824 ++ (grsec_enable_audit_ipc && !grsec_enable_group))
26825 ++ gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
26826 ++#endif
26827 ++ return;
26828 ++}
26829 ++
26830 ++void
26831 ++gr_log_semget(const int err, const int semflg)
26832 ++{
26833 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26834 ++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
26835 ++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
26836 ++ !grsec_enable_group)) && (err >= 0)
26837 ++ && (semflg & IPC_CREAT))
26838 ++ gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
26839 ++#endif
26840 ++ return;
26841 ++}
26842 ++
26843 ++void
26844 ++gr_log_semrm(const uid_t uid, const uid_t cuid)
26845 ++{
26846 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26847 ++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
26848 ++ grsec_enable_audit_ipc) ||
26849 ++ (grsec_enable_audit_ipc && !grsec_enable_group))
26850 ++ gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
26851 ++#endif
26852 ++ return;
26853 ++}
26854 ++
26855 ++void
26856 ++gr_log_shmget(const int err, const int shmflg, const size_t size)
26857 ++{
26858 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26859 ++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
26860 ++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
26861 ++ !grsec_enable_group)) && (err >= 0)
26862 ++ && (shmflg & IPC_CREAT))
26863 ++ gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
26864 ++#endif
26865 ++ return;
26866 ++}
26867 ++
26868 ++void
26869 ++gr_log_shmrm(const uid_t uid, const uid_t cuid)
26870 ++{
26871 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26872 ++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
26873 ++ grsec_enable_audit_ipc) ||
26874 ++ (grsec_enable_audit_ipc && !grsec_enable_group))
26875 ++ gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
26876 ++#endif
26877 ++ return;
26878 ++}
26879 +diff -urNp linux-2.6.28.8/grsecurity/grsec_link.c linux-2.6.28.8/grsecurity/grsec_link.c
26880 +--- linux-2.6.28.8/grsecurity/grsec_link.c 1969-12-31 19:00:00.000000000 -0500
26881 ++++ linux-2.6.28.8/grsecurity/grsec_link.c 2009-02-21 09:37:49.000000000 -0500
26882 +@@ -0,0 +1,39 @@
26883 ++#include <linux/kernel.h>
26884 ++#include <linux/sched.h>
26885 ++#include <linux/fs.h>
26886 ++#include <linux/file.h>
26887 ++#include <linux/grinternal.h>
26888 ++
26889 ++int
26890 ++gr_handle_follow_link(const struct inode *parent,
26891 ++ const struct inode *inode,
26892 ++ const struct dentry *dentry, const struct vfsmount *mnt)
26893 ++{
26894 ++#ifdef CONFIG_GRKERNSEC_LINK
26895 ++ if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
26896 ++ (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
26897 ++ (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
26898 ++ gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
26899 ++ return -EACCES;
26900 ++ }
26901 ++#endif
26902 ++ return 0;
26903 ++}
26904 ++
26905 ++int
26906 ++gr_handle_hardlink(const struct dentry *dentry,
26907 ++ const struct vfsmount *mnt,
26908 ++ struct inode *inode, const int mode, const char *to)
26909 ++{
26910 ++#ifdef CONFIG_GRKERNSEC_LINK
26911 ++ if (grsec_enable_link && current->fsuid != inode->i_uid &&
26912 ++ (!S_ISREG(mode) || (mode & S_ISUID) ||
26913 ++ ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
26914 ++ (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
26915 ++ !capable(CAP_FOWNER) && current->uid) {
26916 ++ gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
26917 ++ return -EPERM;
26918 ++ }
26919 ++#endif
26920 ++ return 0;
26921 ++}
26922 +diff -urNp linux-2.6.28.8/grsecurity/grsec_log.c linux-2.6.28.8/grsecurity/grsec_log.c
26923 +--- linux-2.6.28.8/grsecurity/grsec_log.c 1969-12-31 19:00:00.000000000 -0500
26924 ++++ linux-2.6.28.8/grsecurity/grsec_log.c 2009-02-21 09:37:49.000000000 -0500
26925 +@@ -0,0 +1,269 @@
26926 ++#include <linux/kernel.h>
26927 ++#include <linux/sched.h>
26928 ++#include <linux/file.h>
26929 ++#include <linux/tty.h>
26930 ++#include <linux/fs.h>
26931 ++#include <linux/grinternal.h>
26932 ++
26933 ++#define BEGIN_LOCKS(x) \
26934 ++ read_lock(&tasklist_lock); \
26935 ++ read_lock(&grsec_exec_file_lock); \
26936 ++ if (x != GR_DO_AUDIT) \
26937 ++ spin_lock(&grsec_alert_lock); \
26938 ++ else \
26939 ++ spin_lock(&grsec_audit_lock)
26940 ++
26941 ++#define END_LOCKS(x) \
26942 ++ if (x != GR_DO_AUDIT) \
26943 ++ spin_unlock(&grsec_alert_lock); \
26944 ++ else \
26945 ++ spin_unlock(&grsec_audit_lock); \
26946 ++ read_unlock(&grsec_exec_file_lock); \
26947 ++ read_unlock(&tasklist_lock); \
26948 ++ if (x == GR_DONT_AUDIT) \
26949 ++ gr_handle_alertkill(current)
26950 ++
26951 ++enum {
26952 ++ FLOODING,
26953 ++ NO_FLOODING
26954 ++};
26955 ++
26956 ++extern char *gr_alert_log_fmt;
26957 ++extern char *gr_audit_log_fmt;
26958 ++extern char *gr_alert_log_buf;
26959 ++extern char *gr_audit_log_buf;
26960 ++
26961 ++static int gr_log_start(int audit)
26962 ++{
26963 ++ char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
26964 ++ char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
26965 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
26966 ++
26967 ++ if (audit == GR_DO_AUDIT)
26968 ++ goto set_fmt;
26969 ++
26970 ++ if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
26971 ++ grsec_alert_wtime = jiffies;
26972 ++ grsec_alert_fyet = 0;
26973 ++ } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
26974 ++ grsec_alert_fyet++;
26975 ++ } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
26976 ++ grsec_alert_wtime = jiffies;
26977 ++ grsec_alert_fyet++;
26978 ++ printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
26979 ++ return FLOODING;
26980 ++ } else return FLOODING;
26981 ++
26982 ++set_fmt:
26983 ++ memset(buf, 0, PAGE_SIZE);
26984 ++ if (current->signal->curr_ip && gr_acl_is_enabled()) {
26985 ++ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
26986 ++ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
26987 ++ } else if (current->signal->curr_ip) {
26988 ++ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
26989 ++ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
26990 ++ } else if (gr_acl_is_enabled()) {
26991 ++ sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
26992 ++ snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
26993 ++ } else {
26994 ++ sprintf(fmt, "%s%s", loglevel, "grsec: ");
26995 ++ strcpy(buf, fmt);
26996 ++ }
26997 ++
26998 ++ return NO_FLOODING;
26999 ++}
27000 ++
27001 ++static void gr_log_middle(int audit, const char *msg, va_list ap)
27002 ++{
27003 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
27004 ++ unsigned int len = strlen(buf);
27005 ++
27006 ++ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
27007 ++
27008 ++ return;
27009 ++}
27010 ++
27011 ++static void gr_log_middle_varargs(int audit, const char *msg, ...)
27012 ++{
27013 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
27014 ++ unsigned int len = strlen(buf);
27015 ++ va_list ap;
27016 ++
27017 ++ va_start(ap, msg);
27018 ++ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
27019 ++ va_end(ap);
27020 ++
27021 ++ return;
27022 ++}
27023 ++
27024 ++static void gr_log_end(int audit)
27025 ++{
27026 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
27027 ++ unsigned int len = strlen(buf);
27028 ++
27029 ++ snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
27030 ++ printk("%s\n", buf);
27031 ++
27032 ++ return;
27033 ++}
27034 ++
27035 ++void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
27036 ++{
27037 ++ int logtype;
27038 ++ char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
27039 ++ char *str1, *str2, *str3;
27040 ++ int num1, num2;
27041 ++ unsigned long ulong1, ulong2;
27042 ++ struct dentry *dentry;
27043 ++ struct vfsmount *mnt;
27044 ++ struct file *file;
27045 ++ struct task_struct *task;
27046 ++ va_list ap;
27047 ++
27048 ++ BEGIN_LOCKS(audit);
27049 ++ logtype = gr_log_start(audit);
27050 ++ if (logtype == FLOODING) {
27051 ++ END_LOCKS(audit);
27052 ++ return;
27053 ++ }
27054 ++ va_start(ap, argtypes);
27055 ++ switch (argtypes) {
27056 ++ case GR_TTYSNIFF:
27057 ++ task = va_arg(ap, struct task_struct *);
27058 ++ 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);
27059 ++ break;
27060 ++ case GR_SYSCTL_HIDDEN:
27061 ++ str1 = va_arg(ap, char *);
27062 ++ gr_log_middle_varargs(audit, msg, result, str1);
27063 ++ break;
27064 ++ case GR_RBAC:
27065 ++ dentry = va_arg(ap, struct dentry *);
27066 ++ mnt = va_arg(ap, struct vfsmount *);
27067 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
27068 ++ break;
27069 ++ case GR_RBAC_STR:
27070 ++ dentry = va_arg(ap, struct dentry *);
27071 ++ mnt = va_arg(ap, struct vfsmount *);
27072 ++ str1 = va_arg(ap, char *);
27073 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
27074 ++ break;
27075 ++ case GR_STR_RBAC:
27076 ++ str1 = va_arg(ap, char *);
27077 ++ dentry = va_arg(ap, struct dentry *);
27078 ++ mnt = va_arg(ap, struct vfsmount *);
27079 ++ gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
27080 ++ break;
27081 ++ case GR_RBAC_MODE2:
27082 ++ dentry = va_arg(ap, struct dentry *);
27083 ++ mnt = va_arg(ap, struct vfsmount *);
27084 ++ str1 = va_arg(ap, char *);
27085 ++ str2 = va_arg(ap, char *);
27086 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
27087 ++ break;
27088 ++ case GR_RBAC_MODE3:
27089 ++ dentry = va_arg(ap, struct dentry *);
27090 ++ mnt = va_arg(ap, struct vfsmount *);
27091 ++ str1 = va_arg(ap, char *);
27092 ++ str2 = va_arg(ap, char *);
27093 ++ str3 = va_arg(ap, char *);
27094 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
27095 ++ break;
27096 ++ case GR_FILENAME:
27097 ++ dentry = va_arg(ap, struct dentry *);
27098 ++ mnt = va_arg(ap, struct vfsmount *);
27099 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
27100 ++ break;
27101 ++ case GR_STR_FILENAME:
27102 ++ str1 = va_arg(ap, char *);
27103 ++ dentry = va_arg(ap, struct dentry *);
27104 ++ mnt = va_arg(ap, struct vfsmount *);
27105 ++ gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
27106 ++ break;
27107 ++ case GR_FILENAME_STR:
27108 ++ dentry = va_arg(ap, struct dentry *);
27109 ++ mnt = va_arg(ap, struct vfsmount *);
27110 ++ str1 = va_arg(ap, char *);
27111 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
27112 ++ break;
27113 ++ case GR_FILENAME_TWO_INT:
27114 ++ dentry = va_arg(ap, struct dentry *);
27115 ++ mnt = va_arg(ap, struct vfsmount *);
27116 ++ num1 = va_arg(ap, int);
27117 ++ num2 = va_arg(ap, int);
27118 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
27119 ++ break;
27120 ++ case GR_FILENAME_TWO_INT_STR:
27121 ++ dentry = va_arg(ap, struct dentry *);
27122 ++ mnt = va_arg(ap, struct vfsmount *);
27123 ++ num1 = va_arg(ap, int);
27124 ++ num2 = va_arg(ap, int);
27125 ++ str1 = va_arg(ap, char *);
27126 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
27127 ++ break;
27128 ++ case GR_TEXTREL:
27129 ++ file = va_arg(ap, struct file *);
27130 ++ ulong1 = va_arg(ap, unsigned long);
27131 ++ ulong2 = va_arg(ap, unsigned long);
27132 ++ gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_path.dentry, file->f_path.mnt) : "<anonymous mapping>", ulong1, ulong2);
27133 ++ break;
27134 ++ case GR_PTRACE:
27135 ++ task = va_arg(ap, struct task_struct *);
27136 ++ 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);
27137 ++ break;
27138 ++ case GR_RESOURCE:
27139 ++ task = va_arg(ap, struct task_struct *);
27140 ++ ulong1 = va_arg(ap, unsigned long);
27141 ++ str1 = va_arg(ap, char *);
27142 ++ ulong2 = va_arg(ap, unsigned long);
27143 ++ 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);
27144 ++ break;
27145 ++ case GR_CAP:
27146 ++ task = va_arg(ap, struct task_struct *);
27147 ++ str1 = va_arg(ap, char *);
27148 ++ 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);
27149 ++ break;
27150 ++ case GR_SIG:
27151 ++ task = va_arg(ap, struct task_struct *);
27152 ++ num1 = va_arg(ap, int);
27153 ++ 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);
27154 ++ break;
27155 ++ case GR_CRASH1:
27156 ++ task = va_arg(ap, struct task_struct *);
27157 ++ ulong1 = va_arg(ap, unsigned long);
27158 ++ 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);
27159 ++ break;
27160 ++ case GR_CRASH2:
27161 ++ task = va_arg(ap, struct task_struct *);
27162 ++ ulong1 = va_arg(ap, unsigned long);
27163 ++ 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);
27164 ++ break;
27165 ++ case GR_PSACCT:
27166 ++ {
27167 ++ unsigned int wday, cday;
27168 ++ __u8 whr, chr;
27169 ++ __u8 wmin, cmin;
27170 ++ __u8 wsec, csec;
27171 ++ char cur_tty[64] = { 0 };
27172 ++ char parent_tty[64] = { 0 };
27173 ++
27174 ++ task = va_arg(ap, struct task_struct *);
27175 ++ wday = va_arg(ap, unsigned int);
27176 ++ cday = va_arg(ap, unsigned int);
27177 ++ whr = va_arg(ap, int);
27178 ++ chr = va_arg(ap, int);
27179 ++ wmin = va_arg(ap, int);
27180 ++ cmin = va_arg(ap, int);
27181 ++ wsec = va_arg(ap, int);
27182 ++ csec = va_arg(ap, int);
27183 ++ ulong1 = va_arg(ap, unsigned long);
27184 ++
27185 ++ 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);
27186 ++ }
27187 ++ break;
27188 ++ default:
27189 ++ gr_log_middle(audit, msg, ap);
27190 ++ }
27191 ++ va_end(ap);
27192 ++ gr_log_end(audit);
27193 ++ END_LOCKS(audit);
27194 ++}
27195 +diff -urNp linux-2.6.28.8/grsecurity/grsec_mem.c linux-2.6.28.8/grsecurity/grsec_mem.c
27196 +--- linux-2.6.28.8/grsecurity/grsec_mem.c 1969-12-31 19:00:00.000000000 -0500
27197 ++++ linux-2.6.28.8/grsecurity/grsec_mem.c 2009-02-21 09:37:49.000000000 -0500
27198 +@@ -0,0 +1,71 @@
27199 ++#include <linux/kernel.h>
27200 ++#include <linux/sched.h>
27201 ++#include <linux/mm.h>
27202 ++#include <linux/mman.h>
27203 ++#include <linux/grinternal.h>
27204 ++
27205 ++void
27206 ++gr_handle_ioperm(void)
27207 ++{
27208 ++ gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
27209 ++ return;
27210 ++}
27211 ++
27212 ++void
27213 ++gr_handle_iopl(void)
27214 ++{
27215 ++ gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
27216 ++ return;
27217 ++}
27218 ++
27219 ++void
27220 ++gr_handle_mem_write(void)
27221 ++{
27222 ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
27223 ++ return;
27224 ++}
27225 ++
27226 ++void
27227 ++gr_handle_kmem_write(void)
27228 ++{
27229 ++ gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
27230 ++ return;
27231 ++}
27232 ++
27233 ++void
27234 ++gr_handle_open_port(void)
27235 ++{
27236 ++ gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
27237 ++ return;
27238 ++}
27239 ++
27240 ++int
27241 ++gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
27242 ++{
27243 ++ unsigned long start, end;
27244 ++
27245 ++ start = offset;
27246 ++ end = start + vma->vm_end - vma->vm_start;
27247 ++
27248 ++ if (start > end) {
27249 ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
27250 ++ return -EPERM;
27251 ++ }
27252 ++
27253 ++ /* allowed ranges : ISA I/O BIOS */
27254 ++ if ((start >= __pa(high_memory))
27255 ++#ifdef CONFIG_X86
27256 ++ || (start >= 0x000a0000 && end <= 0x00100000)
27257 ++ || (start >= 0x00000000 && end <= 0x00001000)
27258 ++#endif
27259 ++ )
27260 ++ return 0;
27261 ++
27262 ++ if (vma->vm_flags & VM_WRITE) {
27263 ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
27264 ++ return -EPERM;
27265 ++ } else
27266 ++ vma->vm_flags &= ~VM_MAYWRITE;
27267 ++
27268 ++ return 0;
27269 ++}
27270 +diff -urNp linux-2.6.28.8/grsecurity/grsec_mount.c linux-2.6.28.8/grsecurity/grsec_mount.c
27271 +--- linux-2.6.28.8/grsecurity/grsec_mount.c 1969-12-31 19:00:00.000000000 -0500
27272 ++++ linux-2.6.28.8/grsecurity/grsec_mount.c 2009-02-21 09:37:49.000000000 -0500
27273 +@@ -0,0 +1,34 @@
27274 ++#include <linux/kernel.h>
27275 ++#include <linux/sched.h>
27276 ++#include <linux/grsecurity.h>
27277 ++#include <linux/grinternal.h>
27278 ++
27279 ++void
27280 ++gr_log_remount(const char *devname, const int retval)
27281 ++{
27282 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
27283 ++ if (grsec_enable_mount && (retval >= 0))
27284 ++ gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
27285 ++#endif
27286 ++ return;
27287 ++}
27288 ++
27289 ++void
27290 ++gr_log_unmount(const char *devname, const int retval)
27291 ++{
27292 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
27293 ++ if (grsec_enable_mount && (retval >= 0))
27294 ++ gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
27295 ++#endif
27296 ++ return;
27297 ++}
27298 ++
27299 ++void
27300 ++gr_log_mount(const char *from, const char *to, const int retval)
27301 ++{
27302 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
27303 ++ if (grsec_enable_mount && (retval >= 0))
27304 ++ gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
27305 ++#endif
27306 ++ return;
27307 ++}
27308 +diff -urNp linux-2.6.28.8/grsecurity/grsec_sig.c linux-2.6.28.8/grsecurity/grsec_sig.c
27309 +--- linux-2.6.28.8/grsecurity/grsec_sig.c 1969-12-31 19:00:00.000000000 -0500
27310 ++++ linux-2.6.28.8/grsecurity/grsec_sig.c 2009-02-21 09:37:49.000000000 -0500
27311 +@@ -0,0 +1,58 @@
27312 ++#include <linux/kernel.h>
27313 ++#include <linux/sched.h>
27314 ++#include <linux/delay.h>
27315 ++#include <linux/grsecurity.h>
27316 ++#include <linux/grinternal.h>
27317 ++
27318 ++void
27319 ++gr_log_signal(const int sig, const struct task_struct *t)
27320 ++{
27321 ++#ifdef CONFIG_GRKERNSEC_SIGNAL
27322 ++ if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
27323 ++ (sig == SIGABRT) || (sig == SIGBUS))) {
27324 ++ if (t->pid == current->pid) {
27325 ++ gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
27326 ++ } else {
27327 ++ gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
27328 ++ }
27329 ++ }
27330 ++#endif
27331 ++ return;
27332 ++}
27333 ++
27334 ++int
27335 ++gr_handle_signal(const struct task_struct *p, const int sig)
27336 ++{
27337 ++#ifdef CONFIG_GRKERNSEC
27338 ++ if (current->pid > 1 && gr_check_protected_task(p)) {
27339 ++ gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
27340 ++ return -EPERM;
27341 ++ } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
27342 ++ return -EPERM;
27343 ++ }
27344 ++#endif
27345 ++ return 0;
27346 ++}
27347 ++
27348 ++void gr_handle_brute_attach(struct task_struct *p)
27349 ++{
27350 ++#ifdef CONFIG_GRKERNSEC_BRUTE
27351 ++ read_lock(&tasklist_lock);
27352 ++ read_lock(&grsec_exec_file_lock);
27353 ++ if (p->parent && p->parent->exec_file == p->exec_file)
27354 ++ p->parent->brute = 1;
27355 ++ read_unlock(&grsec_exec_file_lock);
27356 ++ read_unlock(&tasklist_lock);
27357 ++#endif
27358 ++ return;
27359 ++}
27360 ++
27361 ++void gr_handle_brute_check(void)
27362 ++{
27363 ++#ifdef CONFIG_GRKERNSEC_BRUTE
27364 ++ if (current->brute)
27365 ++ msleep(30 * 1000);
27366 ++#endif
27367 ++ return;
27368 ++}
27369 ++
27370 +diff -urNp linux-2.6.28.8/grsecurity/grsec_sock.c linux-2.6.28.8/grsecurity/grsec_sock.c
27371 +--- linux-2.6.28.8/grsecurity/grsec_sock.c 1969-12-31 19:00:00.000000000 -0500
27372 ++++ linux-2.6.28.8/grsecurity/grsec_sock.c 2009-02-21 09:37:49.000000000 -0500
27373 +@@ -0,0 +1,274 @@
27374 ++#include <linux/kernel.h>
27375 ++#include <linux/module.h>
27376 ++#include <linux/sched.h>
27377 ++#include <linux/file.h>
27378 ++#include <linux/net.h>
27379 ++#include <linux/in.h>
27380 ++#include <linux/ip.h>
27381 ++#include <net/sock.h>
27382 ++#include <net/inet_sock.h>
27383 ++#include <linux/grsecurity.h>
27384 ++#include <linux/grinternal.h>
27385 ++#include <linux/gracl.h>
27386 ++
27387 ++#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
27388 ++extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
27389 ++EXPORT_SYMBOL(udp_v4_lookup);
27390 ++#endif
27391 ++
27392 ++kernel_cap_t gr_cap_rtnetlink(struct sock *sock);
27393 ++EXPORT_SYMBOL(gr_cap_rtnetlink);
27394 ++
27395 ++extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
27396 ++extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
27397 ++
27398 ++EXPORT_SYMBOL(gr_search_udp_recvmsg);
27399 ++EXPORT_SYMBOL(gr_search_udp_sendmsg);
27400 ++
27401 ++#ifdef CONFIG_UNIX_MODULE
27402 ++EXPORT_SYMBOL(gr_acl_handle_unix);
27403 ++EXPORT_SYMBOL(gr_acl_handle_mknod);
27404 ++EXPORT_SYMBOL(gr_handle_chroot_unix);
27405 ++EXPORT_SYMBOL(gr_handle_create);
27406 ++#endif
27407 ++
27408 ++#ifdef CONFIG_GRKERNSEC
27409 ++#define gr_conn_table_size 32749
27410 ++struct conn_table_entry {
27411 ++ struct conn_table_entry *next;
27412 ++ struct signal_struct *sig;
27413 ++};
27414 ++
27415 ++struct conn_table_entry *gr_conn_table[gr_conn_table_size];
27416 ++DEFINE_SPINLOCK(gr_conn_table_lock);
27417 ++
27418 ++extern const char * gr_socktype_to_name(unsigned char type);
27419 ++extern const char * gr_proto_to_name(unsigned char proto);
27420 ++
27421 ++static __inline__ int
27422 ++conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
27423 ++{
27424 ++ return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
27425 ++}
27426 ++
27427 ++static __inline__ int
27428 ++conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr,
27429 ++ __u16 sport, __u16 dport)
27430 ++{
27431 ++ if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
27432 ++ sig->gr_sport == sport && sig->gr_dport == dport))
27433 ++ return 1;
27434 ++ else
27435 ++ return 0;
27436 ++}
27437 ++
27438 ++static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
27439 ++{
27440 ++ struct conn_table_entry **match;
27441 ++ unsigned int index;
27442 ++
27443 ++ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
27444 ++ sig->gr_sport, sig->gr_dport,
27445 ++ gr_conn_table_size);
27446 ++
27447 ++ newent->sig = sig;
27448 ++
27449 ++ match = &gr_conn_table[index];
27450 ++ newent->next = *match;
27451 ++ *match = newent;
27452 ++
27453 ++ return;
27454 ++}
27455 ++
27456 ++static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
27457 ++{
27458 ++ struct conn_table_entry *match, *last = NULL;
27459 ++ unsigned int index;
27460 ++
27461 ++ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
27462 ++ sig->gr_sport, sig->gr_dport,
27463 ++ gr_conn_table_size);
27464 ++
27465 ++ match = gr_conn_table[index];
27466 ++ while (match && !conn_match(match->sig,
27467 ++ sig->gr_saddr, sig->gr_daddr, sig->gr_sport,
27468 ++ sig->gr_dport)) {
27469 ++ last = match;
27470 ++ match = match->next;
27471 ++ }
27472 ++
27473 ++ if (match) {
27474 ++ if (last)
27475 ++ last->next = match->next;
27476 ++ else
27477 ++ gr_conn_table[index] = NULL;
27478 ++ kfree(match);
27479 ++ }
27480 ++
27481 ++ return;
27482 ++}
27483 ++
27484 ++static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
27485 ++ __u16 sport, __u16 dport)
27486 ++{
27487 ++ struct conn_table_entry *match;
27488 ++ unsigned int index;
27489 ++
27490 ++ index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
27491 ++
27492 ++ match = gr_conn_table[index];
27493 ++ while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
27494 ++ match = match->next;
27495 ++
27496 ++ if (match)
27497 ++ return match->sig;
27498 ++ else
27499 ++ return NULL;
27500 ++}
27501 ++
27502 ++#endif
27503 ++
27504 ++void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
27505 ++{
27506 ++#ifdef CONFIG_GRKERNSEC
27507 ++ struct signal_struct *sig = task->signal;
27508 ++ struct conn_table_entry *newent;
27509 ++
27510 ++ newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
27511 ++ if (newent == NULL)
27512 ++ return;
27513 ++ /* no bh lock needed since we are called with bh disabled */
27514 ++ spin_lock(&gr_conn_table_lock);
27515 ++ gr_del_task_from_ip_table_nolock(sig);
27516 ++ sig->gr_saddr = inet->rcv_saddr;
27517 ++ sig->gr_daddr = inet->daddr;
27518 ++ sig->gr_sport = inet->sport;
27519 ++ sig->gr_dport = inet->dport;
27520 ++ gr_add_to_task_ip_table_nolock(sig, newent);
27521 ++ spin_unlock(&gr_conn_table_lock);
27522 ++#endif
27523 ++ return;
27524 ++}
27525 ++
27526 ++void gr_del_task_from_ip_table(struct task_struct *task)
27527 ++{
27528 ++#ifdef CONFIG_GRKERNSEC
27529 ++ spin_lock_bh(&gr_conn_table_lock);
27530 ++ gr_del_task_from_ip_table_nolock(task->signal);
27531 ++ spin_unlock_bh(&gr_conn_table_lock);
27532 ++#endif
27533 ++ return;
27534 ++}
27535 ++
27536 ++void
27537 ++gr_attach_curr_ip(const struct sock *sk)
27538 ++{
27539 ++#ifdef CONFIG_GRKERNSEC
27540 ++ struct signal_struct *p, *set;
27541 ++ const struct inet_sock *inet = inet_sk(sk);
27542 ++
27543 ++ if (unlikely(sk->sk_protocol != IPPROTO_TCP))
27544 ++ return;
27545 ++
27546 ++ set = current->signal;
27547 ++
27548 ++ spin_lock_bh(&gr_conn_table_lock);
27549 ++ p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
27550 ++ inet->dport, inet->sport);
27551 ++ if (unlikely(p != NULL)) {
27552 ++ set->curr_ip = p->curr_ip;
27553 ++ set->used_accept = 1;
27554 ++ gr_del_task_from_ip_table_nolock(p);
27555 ++ spin_unlock_bh(&gr_conn_table_lock);
27556 ++ return;
27557 ++ }
27558 ++ spin_unlock_bh(&gr_conn_table_lock);
27559 ++
27560 ++ set->curr_ip = inet->daddr;
27561 ++ set->used_accept = 1;
27562 ++#endif
27563 ++ return;
27564 ++}
27565 ++
27566 ++int
27567 ++gr_handle_sock_all(const int family, const int type, const int protocol)
27568 ++{
27569 ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
27570 ++ if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
27571 ++ (family != AF_UNIX) && (family != AF_LOCAL)) {
27572 ++ gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
27573 ++ return -EACCES;
27574 ++ }
27575 ++#endif
27576 ++ return 0;
27577 ++}
27578 ++
27579 ++int
27580 ++gr_handle_sock_server(const struct sockaddr *sck)
27581 ++{
27582 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
27583 ++ if (grsec_enable_socket_server &&
27584 ++ in_group_p(grsec_socket_server_gid) &&
27585 ++ sck && (sck->sa_family != AF_UNIX) &&
27586 ++ (sck->sa_family != AF_LOCAL)) {
27587 ++ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
27588 ++ return -EACCES;
27589 ++ }
27590 ++#endif
27591 ++ return 0;
27592 ++}
27593 ++
27594 ++int
27595 ++gr_handle_sock_server_other(const struct sock *sck)
27596 ++{
27597 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
27598 ++ if (grsec_enable_socket_server &&
27599 ++ in_group_p(grsec_socket_server_gid) &&
27600 ++ sck && (sck->sk_family != AF_UNIX) &&
27601 ++ (sck->sk_family != AF_LOCAL)) {
27602 ++ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
27603 ++ return -EACCES;
27604 ++ }
27605 ++#endif
27606 ++ return 0;
27607 ++}
27608 ++
27609 ++int
27610 ++gr_handle_sock_client(const struct sockaddr *sck)
27611 ++{
27612 ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
27613 ++ if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
27614 ++ sck && (sck->sa_family != AF_UNIX) &&
27615 ++ (sck->sa_family != AF_LOCAL)) {
27616 ++ gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
27617 ++ return -EACCES;
27618 ++ }
27619 ++#endif
27620 ++ return 0;
27621 ++}
27622 ++
27623 ++kernel_cap_t
27624 ++gr_cap_rtnetlink(struct sock *sock)
27625 ++{
27626 ++#ifdef CONFIG_GRKERNSEC
27627 ++ if (!gr_acl_is_enabled())
27628 ++ return current->cap_effective;
27629 ++ else if (sock->sk_protocol == NETLINK_ISCSI &&
27630 ++ cap_raised(current->cap_effective, CAP_SYS_ADMIN) &&
27631 ++ gr_task_is_capable(current, CAP_SYS_ADMIN))
27632 ++ return current->cap_effective;
27633 ++ else if (sock->sk_protocol == NETLINK_AUDIT &&
27634 ++ cap_raised(current->cap_effective, CAP_AUDIT_WRITE) &&
27635 ++ gr_task_is_capable(current, CAP_AUDIT_WRITE) &&
27636 ++ cap_raised(current->cap_effective, CAP_AUDIT_CONTROL) &&
27637 ++ gr_task_is_capable(current, CAP_AUDIT_CONTROL))
27638 ++ return current->cap_effective;
27639 ++ else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
27640 ++ gr_task_is_capable(current, CAP_NET_ADMIN))
27641 ++ return current->cap_effective;
27642 ++ else
27643 ++ return __cap_empty_set;
27644 ++#else
27645 ++ return current->cap_effective;
27646 ++#endif
27647 ++}
27648 +diff -urNp linux-2.6.28.8/grsecurity/grsec_sysctl.c linux-2.6.28.8/grsecurity/grsec_sysctl.c
27649 +--- linux-2.6.28.8/grsecurity/grsec_sysctl.c 1969-12-31 19:00:00.000000000 -0500
27650 ++++ linux-2.6.28.8/grsecurity/grsec_sysctl.c 2009-02-21 09:37:49.000000000 -0500
27651 +@@ -0,0 +1,435 @@
27652 ++#include <linux/kernel.h>
27653 ++#include <linux/sched.h>
27654 ++#include <linux/sysctl.h>
27655 ++#include <linux/grsecurity.h>
27656 ++#include <linux/grinternal.h>
27657 ++
27658 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
27659 ++int grsec_modstop;
27660 ++#endif
27661 ++
27662 ++int
27663 ++gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
27664 ++{
27665 ++#ifdef CONFIG_GRKERNSEC_SYSCTL
27666 ++ if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & MAY_WRITE)) {
27667 ++ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
27668 ++ return -EACCES;
27669 ++ }
27670 ++#endif
27671 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
27672 ++ if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
27673 ++ grsec_modstop && (op & MAY_WRITE)) {
27674 ++ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
27675 ++ return -EACCES;
27676 ++ }
27677 ++#endif
27678 ++ return 0;
27679 ++}
27680 ++
27681 ++#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
27682 ++ctl_table grsecurity_table[] = {
27683 ++#ifdef CONFIG_GRKERNSEC_SYSCTL
27684 ++#ifdef CONFIG_GRKERNSEC_LINK
27685 ++ {
27686 ++ .ctl_name = CTL_UNNUMBERED,
27687 ++ .procname = "linking_restrictions",
27688 ++ .data = &grsec_enable_link,
27689 ++ .maxlen = sizeof(int),
27690 ++ .mode = 0600,
27691 ++ .proc_handler = &proc_dointvec,
27692 ++ },
27693 ++#endif
27694 ++#ifdef CONFIG_GRKERNSEC_FIFO
27695 ++ {
27696 ++ .ctl_name = CTL_UNNUMBERED,
27697 ++ .procname = "fifo_restrictions",
27698 ++ .data = &grsec_enable_fifo,
27699 ++ .maxlen = sizeof(int),
27700 ++ .mode = 0600,
27701 ++ .proc_handler = &proc_dointvec,
27702 ++ },
27703 ++#endif
27704 ++#ifdef CONFIG_GRKERNSEC_EXECVE
27705 ++ {
27706 ++ .ctl_name = CTL_UNNUMBERED,
27707 ++ .procname = "execve_limiting",
27708 ++ .data = &grsec_enable_execve,
27709 ++ .maxlen = sizeof(int),
27710 ++ .mode = 0600,
27711 ++ .proc_handler = &proc_dointvec,
27712 ++ },
27713 ++#endif
27714 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
27715 ++ {
27716 ++ .ctl_name = CTL_UNNUMBERED,
27717 ++ .procname = "exec_logging",
27718 ++ .data = &grsec_enable_execlog,
27719 ++ .maxlen = sizeof(int),
27720 ++ .mode = 0600,
27721 ++ .proc_handler = &proc_dointvec,
27722 ++ },
27723 ++#endif
27724 ++#ifdef CONFIG_GRKERNSEC_SIGNAL
27725 ++ {
27726 ++ .ctl_name = CTL_UNNUMBERED,
27727 ++ .procname = "signal_logging",
27728 ++ .data = &grsec_enable_signal,
27729 ++ .maxlen = sizeof(int),
27730 ++ .mode = 0600,
27731 ++ .proc_handler = &proc_dointvec,
27732 ++ },
27733 ++#endif
27734 ++#ifdef CONFIG_GRKERNSEC_FORKFAIL
27735 ++ {
27736 ++ .ctl_name = CTL_UNNUMBERED,
27737 ++ .procname = "forkfail_logging",
27738 ++ .data = &grsec_enable_forkfail,
27739 ++ .maxlen = sizeof(int),
27740 ++ .mode = 0600,
27741 ++ .proc_handler = &proc_dointvec,
27742 ++ },
27743 ++#endif
27744 ++#ifdef CONFIG_GRKERNSEC_TIME
27745 ++ {
27746 ++ .ctl_name = CTL_UNNUMBERED,
27747 ++ .procname = "timechange_logging",
27748 ++ .data = &grsec_enable_time,
27749 ++ .maxlen = sizeof(int),
27750 ++ .mode = 0600,
27751 ++ .proc_handler = &proc_dointvec,
27752 ++ },
27753 ++#endif
27754 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
27755 ++ {
27756 ++ .ctl_name = CTL_UNNUMBERED,
27757 ++ .procname = "chroot_deny_shmat",
27758 ++ .data = &grsec_enable_chroot_shmat,
27759 ++ .maxlen = sizeof(int),
27760 ++ .mode = 0600,
27761 ++ .proc_handler = &proc_dointvec,
27762 ++ },
27763 ++#endif
27764 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
27765 ++ {
27766 ++ .ctl_name = CTL_UNNUMBERED,
27767 ++ .procname = "chroot_deny_unix",
27768 ++ .data = &grsec_enable_chroot_unix,
27769 ++ .maxlen = sizeof(int),
27770 ++ .mode = 0600,
27771 ++ .proc_handler = &proc_dointvec,
27772 ++ },
27773 ++#endif
27774 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
27775 ++ {
27776 ++ .ctl_name = CTL_UNNUMBERED,
27777 ++ .procname = "chroot_deny_mount",
27778 ++ .data = &grsec_enable_chroot_mount,
27779 ++ .maxlen = sizeof(int),
27780 ++ .mode = 0600,
27781 ++ .proc_handler = &proc_dointvec,
27782 ++ },
27783 ++#endif
27784 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
27785 ++ {
27786 ++ .ctl_name = CTL_UNNUMBERED,
27787 ++ .procname = "chroot_deny_fchdir",
27788 ++ .data = &grsec_enable_chroot_fchdir,
27789 ++ .maxlen = sizeof(int),
27790 ++ .mode = 0600,
27791 ++ .proc_handler = &proc_dointvec,
27792 ++ },
27793 ++#endif
27794 ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
27795 ++ {
27796 ++ .ctl_name = CTL_UNNUMBERED,
27797 ++ .procname = "chroot_deny_chroot",
27798 ++ .data = &grsec_enable_chroot_double,
27799 ++ .maxlen = sizeof(int),
27800 ++ .mode = 0600,
27801 ++ .proc_handler = &proc_dointvec,
27802 ++ },
27803 ++#endif
27804 ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
27805 ++ {
27806 ++ .ctl_name = CTL_UNNUMBERED,
27807 ++ .procname = "chroot_deny_pivot",
27808 ++ .data = &grsec_enable_chroot_pivot,
27809 ++ .maxlen = sizeof(int),
27810 ++ .mode = 0600,
27811 ++ .proc_handler = &proc_dointvec,
27812 ++ },
27813 ++#endif
27814 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
27815 ++ {
27816 ++ .ctl_name = CTL_UNNUMBERED,
27817 ++ .procname = "chroot_enforce_chdir",
27818 ++ .data = &grsec_enable_chroot_chdir,
27819 ++ .maxlen = sizeof(int),
27820 ++ .mode = 0600,
27821 ++ .proc_handler = &proc_dointvec,
27822 ++ },
27823 ++#endif
27824 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
27825 ++ {
27826 ++ .ctl_name = CTL_UNNUMBERED,
27827 ++ .procname = "chroot_deny_chmod",
27828 ++ .data = &grsec_enable_chroot_chmod,
27829 ++ .maxlen = sizeof(int),
27830 ++ .mode = 0600,
27831 ++ .proc_handler = &proc_dointvec,
27832 ++ },
27833 ++#endif
27834 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
27835 ++ {
27836 ++ .ctl_name = CTL_UNNUMBERED,
27837 ++ .procname = "chroot_deny_mknod",
27838 ++ .data = &grsec_enable_chroot_mknod,
27839 ++ .maxlen = sizeof(int),
27840 ++ .mode = 0600,
27841 ++ .proc_handler = &proc_dointvec,
27842 ++ },
27843 ++#endif
27844 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
27845 ++ {
27846 ++ .ctl_name = CTL_UNNUMBERED,
27847 ++ .procname = "chroot_restrict_nice",
27848 ++ .data = &grsec_enable_chroot_nice,
27849 ++ .maxlen = sizeof(int),
27850 ++ .mode = 0600,
27851 ++ .proc_handler = &proc_dointvec,
27852 ++ },
27853 ++#endif
27854 ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
27855 ++ {
27856 ++ .ctl_name = CTL_UNNUMBERED,
27857 ++ .procname = "chroot_execlog",
27858 ++ .data = &grsec_enable_chroot_execlog,
27859 ++ .maxlen = sizeof(int),
27860 ++ .mode = 0600,
27861 ++ .proc_handler = &proc_dointvec,
27862 ++ },
27863 ++#endif
27864 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
27865 ++ {
27866 ++ .ctl_name = CTL_UNNUMBERED,
27867 ++ .procname = "chroot_caps",
27868 ++ .data = &grsec_enable_chroot_caps,
27869 ++ .maxlen = sizeof(int),
27870 ++ .mode = 0600,
27871 ++ .proc_handler = &proc_dointvec,
27872 ++ },
27873 ++#endif
27874 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
27875 ++ {
27876 ++ .ctl_name = CTL_UNNUMBERED,
27877 ++ .procname = "chroot_deny_sysctl",
27878 ++ .data = &grsec_enable_chroot_sysctl,
27879 ++ .maxlen = sizeof(int),
27880 ++ .mode = 0600,
27881 ++ .proc_handler = &proc_dointvec,
27882 ++ },
27883 ++#endif
27884 ++#ifdef CONFIG_GRKERNSEC_TPE
27885 ++ {
27886 ++ .ctl_name = CTL_UNNUMBERED,
27887 ++ .procname = "tpe",
27888 ++ .data = &grsec_enable_tpe,
27889 ++ .maxlen = sizeof(int),
27890 ++ .mode = 0600,
27891 ++ .proc_handler = &proc_dointvec,
27892 ++ },
27893 ++ {
27894 ++ .ctl_name = CTL_UNNUMBERED,
27895 ++ .procname = "tpe_gid",
27896 ++ .data = &grsec_tpe_gid,
27897 ++ .maxlen = sizeof(int),
27898 ++ .mode = 0600,
27899 ++ .proc_handler = &proc_dointvec,
27900 ++ },
27901 ++#endif
27902 ++#ifdef CONFIG_GRKERNSEC_TPE_ALL
27903 ++ {
27904 ++ .ctl_name = CTL_UNNUMBERED,
27905 ++ .procname = "tpe_restrict_all",
27906 ++ .data = &grsec_enable_tpe_all,
27907 ++ .maxlen = sizeof(int),
27908 ++ .mode = 0600,
27909 ++ .proc_handler = &proc_dointvec,
27910 ++ },
27911 ++#endif
27912 ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
27913 ++ {
27914 ++ .ctl_name = CTL_UNNUMBERED,
27915 ++ .procname = "socket_all",
27916 ++ .data = &grsec_enable_socket_all,
27917 ++ .maxlen = sizeof(int),
27918 ++ .mode = 0600,
27919 ++ .proc_handler = &proc_dointvec,
27920 ++ },
27921 ++ {
27922 ++ .ctl_name = CTL_UNNUMBERED,
27923 ++ .procname = "socket_all_gid",
27924 ++ .data = &grsec_socket_all_gid,
27925 ++ .maxlen = sizeof(int),
27926 ++ .mode = 0600,
27927 ++ .proc_handler = &proc_dointvec,
27928 ++ },
27929 ++#endif
27930 ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
27931 ++ {
27932 ++ .ctl_name = CTL_UNNUMBERED,
27933 ++ .procname = "socket_client",
27934 ++ .data = &grsec_enable_socket_client,
27935 ++ .maxlen = sizeof(int),
27936 ++ .mode = 0600,
27937 ++ .proc_handler = &proc_dointvec,
27938 ++ },
27939 ++ {
27940 ++ .ctl_name = CTL_UNNUMBERED,
27941 ++ .procname = "socket_client_gid",
27942 ++ .data = &grsec_socket_client_gid,
27943 ++ .maxlen = sizeof(int),
27944 ++ .mode = 0600,
27945 ++ .proc_handler = &proc_dointvec,
27946 ++ },
27947 ++#endif
27948 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
27949 ++ {
27950 ++ .ctl_name = CTL_UNNUMBERED,
27951 ++ .procname = "socket_server",
27952 ++ .data = &grsec_enable_socket_server,
27953 ++ .maxlen = sizeof(int),
27954 ++ .mode = 0600,
27955 ++ .proc_handler = &proc_dointvec,
27956 ++ },
27957 ++ {
27958 ++ .ctl_name = CTL_UNNUMBERED,
27959 ++ .procname = "socket_server_gid",
27960 ++ .data = &grsec_socket_server_gid,
27961 ++ .maxlen = sizeof(int),
27962 ++ .mode = 0600,
27963 ++ .proc_handler = &proc_dointvec,
27964 ++ },
27965 ++#endif
27966 ++#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
27967 ++ {
27968 ++ .ctl_name = CTL_UNNUMBERED,
27969 ++ .procname = "audit_group",
27970 ++ .data = &grsec_enable_group,
27971 ++ .maxlen = sizeof(int),
27972 ++ .mode = 0600,
27973 ++ .proc_handler = &proc_dointvec,
27974 ++ },
27975 ++ {
27976 ++ .ctl_name = CTL_UNNUMBERED,
27977 ++ .procname = "audit_gid",
27978 ++ .data = &grsec_audit_gid,
27979 ++ .maxlen = sizeof(int),
27980 ++ .mode = 0600,
27981 ++ .proc_handler = &proc_dointvec,
27982 ++ },
27983 ++#endif
27984 ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
27985 ++ {
27986 ++ .ctl_name = CTL_UNNUMBERED,
27987 ++ .procname = "audit_chdir",
27988 ++ .data = &grsec_enable_chdir,
27989 ++ .maxlen = sizeof(int),
27990 ++ .mode = 0600,
27991 ++ .proc_handler = &proc_dointvec,
27992 ++ },
27993 ++#endif
27994 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
27995 ++ {
27996 ++ .ctl_name = CTL_UNNUMBERED,
27997 ++ .procname = "audit_mount",
27998 ++ .data = &grsec_enable_mount,
27999 ++ .maxlen = sizeof(int),
28000 ++ .mode = 0600,
28001 ++ .proc_handler = &proc_dointvec,
28002 ++ },
28003 ++#endif
28004 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
28005 ++ {
28006 ++ .ctl_name = CTL_UNNUMBERED,
28007 ++ .procname = "audit_ipc",
28008 ++ .data = &grsec_enable_audit_ipc,
28009 ++ .maxlen = sizeof(int),
28010 ++ .mode = 0600,
28011 ++ .proc_handler = &proc_dointvec,
28012 ++ },
28013 ++#endif
28014 ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
28015 ++ {
28016 ++ .ctl_name = CTL_UNNUMBERED,
28017 ++ .procname = "audit_textrel",
28018 ++ .data = &grsec_enable_audit_textrel,
28019 ++ .maxlen = sizeof(int),
28020 ++ .mode = 0600,
28021 ++ .proc_handler = &proc_dointvec,
28022 ++ },
28023 ++#endif
28024 ++#ifdef CONFIG_GRKERNSEC_DMESG
28025 ++ {
28026 ++ .ctl_name = CTL_UNNUMBERED,
28027 ++ .procname = "dmesg",
28028 ++ .data = &grsec_enable_dmesg,
28029 ++ .maxlen = sizeof(int),
28030 ++ .mode = 0600,
28031 ++ .proc_handler = &proc_dointvec,
28032 ++ },
28033 ++#endif
28034 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
28035 ++ {
28036 ++ .ctl_name = CTL_UNNUMBERED,
28037 ++ .procname = "chroot_findtask",
28038 ++ .data = &grsec_enable_chroot_findtask,
28039 ++ .maxlen = sizeof(int),
28040 ++ .mode = 0600,
28041 ++ .proc_handler = &proc_dointvec,
28042 ++ },
28043 ++#endif
28044 ++#ifdef CONFIG_GRKERNSEC_RESLOG
28045 ++ {
28046 ++ .ctl_name = CTL_UNNUMBERED,
28047 ++ .procname = "resource_logging",
28048 ++ .data = &grsec_resource_logging,
28049 ++ .maxlen = sizeof(int),
28050 ++ .mode = 0600,
28051 ++ .proc_handler = &proc_dointvec,
28052 ++ },
28053 ++#endif
28054 ++ {
28055 ++ .ctl_name = CTL_UNNUMBERED,
28056 ++ .procname = "grsec_lock",
28057 ++ .data = &grsec_lock,
28058 ++ .maxlen = sizeof(int),
28059 ++ .mode = 0600,
28060 ++ .proc_handler = &proc_dointvec,
28061 ++ },
28062 ++#endif
28063 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
28064 ++ {
28065 ++ .ctl_name = CTL_UNNUMBERED,
28066 ++ .procname = "disable_modules",
28067 ++ .data = &grsec_modstop,
28068 ++ .maxlen = sizeof(int),
28069 ++ .mode = 0600,
28070 ++ .proc_handler = &proc_dointvec,
28071 ++ },
28072 ++#endif
28073 ++ { .ctl_name = 0 }
28074 ++};
28075 ++#endif
28076 ++
28077 ++int gr_check_modstop(void)
28078 ++{
28079 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
28080 ++ if (grsec_modstop == 1) {
28081 ++ gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
28082 ++ return 1;
28083 ++ }
28084 ++#endif
28085 ++ return 0;
28086 ++}
28087 +diff -urNp linux-2.6.28.8/grsecurity/grsec_textrel.c linux-2.6.28.8/grsecurity/grsec_textrel.c
28088 +--- linux-2.6.28.8/grsecurity/grsec_textrel.c 1969-12-31 19:00:00.000000000 -0500
28089 ++++ linux-2.6.28.8/grsecurity/grsec_textrel.c 2009-02-21 09:37:49.000000000 -0500
28090 +@@ -0,0 +1,16 @@
28091 ++#include <linux/kernel.h>
28092 ++#include <linux/sched.h>
28093 ++#include <linux/mm.h>
28094 ++#include <linux/file.h>
28095 ++#include <linux/grinternal.h>
28096 ++#include <linux/grsecurity.h>
28097 ++
28098 ++void
28099 ++gr_log_textrel(struct vm_area_struct * vma)
28100 ++{
28101 ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
28102 ++ if (grsec_enable_audit_textrel)
28103 ++ gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
28104 ++#endif
28105 ++ return;
28106 ++}
28107 +diff -urNp linux-2.6.28.8/grsecurity/grsec_time.c linux-2.6.28.8/grsecurity/grsec_time.c
28108 +--- linux-2.6.28.8/grsecurity/grsec_time.c 1969-12-31 19:00:00.000000000 -0500
28109 ++++ linux-2.6.28.8/grsecurity/grsec_time.c 2009-02-21 09:37:49.000000000 -0500
28110 +@@ -0,0 +1,13 @@
28111 ++#include <linux/kernel.h>
28112 ++#include <linux/sched.h>
28113 ++#include <linux/grinternal.h>
28114 ++
28115 ++void
28116 ++gr_log_timechange(void)
28117 ++{
28118 ++#ifdef CONFIG_GRKERNSEC_TIME
28119 ++ if (grsec_enable_time)
28120 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
28121 ++#endif
28122 ++ return;
28123 ++}
28124 +diff -urNp linux-2.6.28.8/grsecurity/grsec_tpe.c linux-2.6.28.8/grsecurity/grsec_tpe.c
28125 +--- linux-2.6.28.8/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500
28126 ++++ linux-2.6.28.8/grsecurity/grsec_tpe.c 2009-02-21 09:37:49.000000000 -0500
28127 +@@ -0,0 +1,37 @@
28128 ++#include <linux/kernel.h>
28129 ++#include <linux/sched.h>
28130 ++#include <linux/file.h>
28131 ++#include <linux/fs.h>
28132 ++#include <linux/grinternal.h>
28133 ++
28134 ++extern int gr_acl_tpe_check(void);
28135 ++
28136 ++int
28137 ++gr_tpe_allow(const struct file *file)
28138 ++{
28139 ++#ifdef CONFIG_GRKERNSEC
28140 ++ struct inode *inode = file->f_path.dentry->d_parent->d_inode;
28141 ++
28142 ++ if (current->uid && ((grsec_enable_tpe &&
28143 ++#ifdef CONFIG_GRKERNSEC_TPE_INVERT
28144 ++ !in_group_p(grsec_tpe_gid)
28145 ++#else
28146 ++ in_group_p(grsec_tpe_gid)
28147 ++#endif
28148 ++ ) || gr_acl_tpe_check()) &&
28149 ++ (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
28150 ++ (inode->i_mode & S_IWOTH))))) {
28151 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
28152 ++ return 0;
28153 ++ }
28154 ++#ifdef CONFIG_GRKERNSEC_TPE_ALL
28155 ++ if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
28156 ++ ((inode->i_uid && (inode->i_uid != current->uid)) ||
28157 ++ (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
28158 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
28159 ++ return 0;
28160 ++ }
28161 ++#endif
28162 ++#endif
28163 ++ return 1;
28164 ++}
28165 +diff -urNp linux-2.6.28.8/grsecurity/grsum.c linux-2.6.28.8/grsecurity/grsum.c
28166 +--- linux-2.6.28.8/grsecurity/grsum.c 1969-12-31 19:00:00.000000000 -0500
28167 ++++ linux-2.6.28.8/grsecurity/grsum.c 2009-02-21 09:37:49.000000000 -0500
28168 +@@ -0,0 +1,59 @@
28169 ++#include <linux/err.h>
28170 ++#include <linux/kernel.h>
28171 ++#include <linux/sched.h>
28172 ++#include <linux/mm.h>
28173 ++#include <linux/scatterlist.h>
28174 ++#include <linux/crypto.h>
28175 ++#include <linux/gracl.h>
28176 ++
28177 ++
28178 ++#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
28179 ++#error "crypto and sha256 must be built into the kernel"
28180 ++#endif
28181 ++
28182 ++int
28183 ++chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
28184 ++{
28185 ++ char *p;
28186 ++ struct crypto_hash *tfm;
28187 ++ struct hash_desc desc;
28188 ++ struct scatterlist sg;
28189 ++ unsigned char temp_sum[GR_SHA_LEN];
28190 ++ volatile int retval = 0;
28191 ++ volatile int dummy = 0;
28192 ++ unsigned int i;
28193 ++
28194 ++ tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
28195 ++ if (IS_ERR(tfm)) {
28196 ++ /* should never happen, since sha256 should be built in */
28197 ++ return 1;
28198 ++ }
28199 ++
28200 ++ desc.tfm = tfm;
28201 ++ desc.flags = 0;
28202 ++
28203 ++ crypto_hash_init(&desc);
28204 ++
28205 ++ p = salt;
28206 ++ sg_set_buf(&sg, p, GR_SALT_LEN);
28207 ++ crypto_hash_update(&desc, &sg, sg.length);
28208 ++
28209 ++ p = entry->pw;
28210 ++ sg_set_buf(&sg, p, strlen(p));
28211 ++
28212 ++ crypto_hash_update(&desc, &sg, sg.length);
28213 ++
28214 ++ crypto_hash_final(&desc, temp_sum);
28215 ++
28216 ++ memset(entry->pw, 0, GR_PW_LEN);
28217 ++
28218 ++ for (i = 0; i < GR_SHA_LEN; i++)
28219 ++ if (sum[i] != temp_sum[i])
28220 ++ retval = 1;
28221 ++ else
28222 ++ dummy = 1; // waste a cycle
28223 ++
28224 ++ crypto_free_hash(tfm);
28225 ++
28226 ++ return retval;
28227 ++}
28228 +diff -urNp linux-2.6.28.8/grsecurity/Kconfig linux-2.6.28.8/grsecurity/Kconfig
28229 +--- linux-2.6.28.8/grsecurity/Kconfig 1969-12-31 19:00:00.000000000 -0500
28230 ++++ linux-2.6.28.8/grsecurity/Kconfig 2009-03-07 14:50:21.000000000 -0500
28231 +@@ -0,0 +1,868 @@
28232 ++#
28233 ++# grecurity configuration
28234 ++#
28235 ++
28236 ++menu "Grsecurity"
28237 ++
28238 ++config GRKERNSEC
28239 ++ bool "Grsecurity"
28240 ++ select CRYPTO
28241 ++ select CRYPTO_SHA256
28242 ++ select SECURITY
28243 ++ select SECURITY_CAPABILITIES
28244 ++ help
28245 ++ If you say Y here, you will be able to configure many features
28246 ++ that will enhance the security of your system. It is highly
28247 ++ recommended that you say Y here and read through the help
28248 ++ for each option so that you fully understand the features and
28249 ++ can evaluate their usefulness for your machine.
28250 ++
28251 ++choice
28252 ++ prompt "Security Level"
28253 ++ depends on GRKERNSEC
28254 ++ default GRKERNSEC_CUSTOM
28255 ++
28256 ++config GRKERNSEC_LOW
28257 ++ bool "Low"
28258 ++ select GRKERNSEC_LINK
28259 ++ select GRKERNSEC_FIFO
28260 ++ select GRKERNSEC_EXECVE
28261 ++ select GRKERNSEC_RANDNET
28262 ++ select GRKERNSEC_DMESG
28263 ++ select GRKERNSEC_CHROOT
28264 ++ select GRKERNSEC_CHROOT_CHDIR
28265 ++ select GRKERNSEC_MODSTOP if (MODULES)
28266 ++
28267 ++ help
28268 ++ If you choose this option, several of the grsecurity options will
28269 ++ be enabled that will give you greater protection against a number
28270 ++ of attacks, while assuring that none of your software will have any
28271 ++ conflicts with the additional security measures. If you run a lot
28272 ++ of unusual software, or you are having problems with the higher
28273 ++ security levels, you should say Y here. With this option, the
28274 ++ following features are enabled:
28275 ++
28276 ++ - Linking restrictions
28277 ++ - FIFO restrictions
28278 ++ - Enforcing RLIMIT_NPROC on execve
28279 ++ - Restricted dmesg
28280 ++ - Enforced chdir("/") on chroot
28281 ++ - Runtime module disabling
28282 ++
28283 ++config GRKERNSEC_MEDIUM
28284 ++ bool "Medium"
28285 ++ select PAX
28286 ++ select PAX_EI_PAX
28287 ++ select PAX_PT_PAX_FLAGS
28288 ++ select PAX_HAVE_ACL_FLAGS
28289 ++ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
28290 ++ select GRKERNSEC_CHROOT
28291 ++ select GRKERNSEC_CHROOT_SYSCTL
28292 ++ select GRKERNSEC_LINK
28293 ++ select GRKERNSEC_FIFO
28294 ++ select GRKERNSEC_EXECVE
28295 ++ select GRKERNSEC_DMESG
28296 ++ select GRKERNSEC_RANDNET
28297 ++ select GRKERNSEC_FORKFAIL
28298 ++ select GRKERNSEC_TIME
28299 ++ select GRKERNSEC_SIGNAL
28300 ++ select GRKERNSEC_CHROOT
28301 ++ select GRKERNSEC_CHROOT_UNIX
28302 ++ select GRKERNSEC_CHROOT_MOUNT
28303 ++ select GRKERNSEC_CHROOT_PIVOT
28304 ++ select GRKERNSEC_CHROOT_DOUBLE
28305 ++ select GRKERNSEC_CHROOT_CHDIR
28306 ++ select GRKERNSEC_CHROOT_MKNOD
28307 ++ select GRKERNSEC_PROC
28308 ++ select GRKERNSEC_PROC_USERGROUP
28309 ++ select GRKERNSEC_MODSTOP if (MODULES)
28310 ++ select PAX_RANDUSTACK
28311 ++ select PAX_ASLR
28312 ++ select PAX_RANDMMAP
28313 ++ select PAX_REFCOUNT if (X86)
28314 ++
28315 ++ help
28316 ++ If you say Y here, several features in addition to those included
28317 ++ in the low additional security level will be enabled. These
28318 ++ features provide even more security to your system, though in rare
28319 ++ cases they may be incompatible with very old or poorly written
28320 ++ software. If you enable this option, make sure that your auth
28321 ++ service (identd) is running as gid 1001. With this option,
28322 ++ the following features (in addition to those provided in the
28323 ++ low additional security level) will be enabled:
28324 ++
28325 ++ - Failed fork logging
28326 ++ - Time change logging
28327 ++ - Signal logging
28328 ++ - Deny mounts in chroot
28329 ++ - Deny double chrooting
28330 ++ - Deny sysctl writes in chroot
28331 ++ - Deny mknod in chroot
28332 ++ - Deny access to abstract AF_UNIX sockets out of chroot
28333 ++ - Deny pivot_root in chroot
28334 ++ - Denied writes of /dev/kmem, /dev/mem, and /dev/port
28335 ++ - /proc restrictions with special GID set to 10 (usually wheel)
28336 ++ - Address Space Layout Randomization (ASLR)
28337 ++ - Prevent exploitation of most refcount overflows
28338 ++
28339 ++config GRKERNSEC_HIGH
28340 ++ bool "High"
28341 ++ select GRKERNSEC_LINK
28342 ++ select GRKERNSEC_FIFO
28343 ++ select GRKERNSEC_EXECVE
28344 ++ select GRKERNSEC_DMESG
28345 ++ select GRKERNSEC_FORKFAIL
28346 ++ select GRKERNSEC_TIME
28347 ++ select GRKERNSEC_SIGNAL
28348 ++ select GRKERNSEC_CHROOT
28349 ++ select GRKERNSEC_CHROOT_SHMAT
28350 ++ select GRKERNSEC_CHROOT_UNIX
28351 ++ select GRKERNSEC_CHROOT_MOUNT
28352 ++ select GRKERNSEC_CHROOT_FCHDIR
28353 ++ select GRKERNSEC_CHROOT_PIVOT
28354 ++ select GRKERNSEC_CHROOT_DOUBLE
28355 ++ select GRKERNSEC_CHROOT_CHDIR
28356 ++ select GRKERNSEC_CHROOT_MKNOD
28357 ++ select GRKERNSEC_CHROOT_CAPS
28358 ++ select GRKERNSEC_CHROOT_SYSCTL
28359 ++ select GRKERNSEC_CHROOT_FINDTASK
28360 ++ select GRKERNSEC_PROC
28361 ++ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
28362 ++ select GRKERNSEC_HIDESYM
28363 ++ select GRKERNSEC_BRUTE
28364 ++ select GRKERNSEC_PROC_USERGROUP
28365 ++ select GRKERNSEC_KMEM
28366 ++ select GRKERNSEC_RESLOG
28367 ++ select GRKERNSEC_RANDNET
28368 ++ select GRKERNSEC_PROC_ADD
28369 ++ select GRKERNSEC_CHROOT_CHMOD
28370 ++ select GRKERNSEC_CHROOT_NICE
28371 ++ select GRKERNSEC_AUDIT_MOUNT
28372 ++ select GRKERNSEC_MODSTOP if (MODULES)
28373 ++ select PAX
28374 ++ select PAX_RANDUSTACK
28375 ++ select PAX_ASLR
28376 ++ select PAX_RANDMMAP
28377 ++ select PAX_NOEXEC
28378 ++ select PAX_MPROTECT
28379 ++ select PAX_EI_PAX
28380 ++ select PAX_PT_PAX_FLAGS
28381 ++ select PAX_HAVE_ACL_FLAGS
28382 ++ select PAX_KERNEXEC if (X86 && !EFI && !COMPAT_VDSO && !PARAVIRT && (!X86_32 || X86_WP_WORKS_OK))
28383 ++ select PAX_MEMORY_UDEREF if (!X86_64 && !COMPAT_VDSO)
28384 ++ select PAX_RANDKSTACK if (X86_TSC && !X86_64)
28385 ++ select PAX_SEGMEXEC if (X86 && !X86_64)
28386 ++ select PAX_PAGEEXEC if (!X86)
28387 ++ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
28388 ++ select PAX_DLRESOLVE if (SPARC32 || SPARC64)
28389 ++ select PAX_SYSCALL if (PPC32)
28390 ++ select PAX_EMUTRAMP if (PARISC)
28391 ++ select PAX_EMUSIGRT if (PARISC)
28392 ++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
28393 ++ select PAX_REFCOUNT if (X86)
28394 ++ help
28395 ++ If you say Y here, many of the features of grsecurity will be
28396 ++ enabled, which will protect you against many kinds of attacks
28397 ++ against your system. The heightened security comes at a cost
28398 ++ of an increased chance of incompatibilities with rare software
28399 ++ on your machine. Since this security level enables PaX, you should
28400 ++ view <http://pax.grsecurity.net> and read about the PaX
28401 ++ project. While you are there, download chpax and run it on
28402 ++ binaries that cause problems with PaX. Also remember that
28403 ++ since the /proc restrictions are enabled, you must run your
28404 ++ identd as gid 1001. This security level enables the following
28405 ++ features in addition to those listed in the low and medium
28406 ++ security levels:
28407 ++
28408 ++ - Additional /proc restrictions
28409 ++ - Chmod restrictions in chroot
28410 ++ - No signals, ptrace, or viewing of processes outside of chroot
28411 ++ - Capability restrictions in chroot
28412 ++ - Deny fchdir out of chroot
28413 ++ - Priority restrictions in chroot
28414 ++ - Segmentation-based implementation of PaX
28415 ++ - Mprotect restrictions
28416 ++ - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
28417 ++ - Kernel stack randomization
28418 ++ - Mount/unmount/remount logging
28419 ++ - Kernel symbol hiding
28420 ++ - Prevention of memory exhaustion-based exploits
28421 ++config GRKERNSEC_CUSTOM
28422 ++ bool "Custom"
28423 ++ help
28424 ++ If you say Y here, you will be able to configure every grsecurity
28425 ++ option, which allows you to enable many more features that aren't
28426 ++ covered in the basic security levels. These additional features
28427 ++ include TPE, socket restrictions, and the sysctl system for
28428 ++ grsecurity. It is advised that you read through the help for
28429 ++ each option to determine its usefulness in your situation.
28430 ++
28431 ++endchoice
28432 ++
28433 ++menu "Address Space Protection"
28434 ++depends on GRKERNSEC
28435 ++
28436 ++config GRKERNSEC_KMEM
28437 ++ bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
28438 ++ help
28439 ++ If you say Y here, /dev/kmem and /dev/mem won't be allowed to
28440 ++ be written to via mmap or otherwise to modify the running kernel.
28441 ++ /dev/port will also not be allowed to be opened. If you have module
28442 ++ support disabled, enabling this will close up four ways that are
28443 ++ currently used to insert malicious code into the running kernel.
28444 ++ Even with all these features enabled, we still highly recommend that
28445 ++ you use the RBAC system, as it is still possible for an attacker to
28446 ++ modify the running kernel through privileged I/O granted by ioperm/iopl.
28447 ++ If you are not using XFree86, you may be able to stop this additional
28448 ++ case by enabling the 'Disable privileged I/O' option. Though nothing
28449 ++ legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
28450 ++ but only to video memory, which is the only writing we allow in this
28451 ++ case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
28452 ++ not be allowed to mprotect it with PROT_WRITE later.
28453 ++ It is highly recommended that you say Y here if you meet all the
28454 ++ conditions above.
28455 ++
28456 ++config GRKERNSEC_IO
28457 ++ bool "Disable privileged I/O"
28458 ++ depends on X86
28459 ++ select RTC_CLASS
28460 ++ select RTC_INTF_DEV
28461 ++ help
28462 ++ If you say Y here, all ioperm and iopl calls will return an error.
28463 ++ Ioperm and iopl can be used to modify the running kernel.
28464 ++ Unfortunately, some programs need this access to operate properly,
28465 ++ the most notable of which are XFree86 and hwclock. hwclock can be
28466 ++ remedied by having RTC support in the kernel, so real-time
28467 ++ clock support is enabled if this option is enabled, to ensure
28468 ++ that hwclock operates correctly. XFree86 still will not
28469 ++ operate correctly with this option enabled, so DO NOT CHOOSE Y
28470 ++ IF YOU USE XFree86. If you use XFree86 and you still want to
28471 ++ protect your kernel against modification, use the RBAC system.
28472 ++
28473 ++config GRKERNSEC_PROC_MEMMAP
28474 ++ bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
28475 ++ depends on PAX_NOEXEC || PAX_ASLR
28476 ++ help
28477 ++ If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
28478 ++ give no information about the addresses of its mappings if
28479 ++ PaX features that rely on random addresses are enabled on the task.
28480 ++ If you use PaX it is greatly recommended that you say Y here as it
28481 ++ closes up a hole that makes the full ASLR useless for suid
28482 ++ binaries.
28483 ++
28484 ++config GRKERNSEC_BRUTE
28485 ++ bool "Deter exploit bruteforcing"
28486 ++ help
28487 ++ If you say Y here, attempts to bruteforce exploits against forking
28488 ++ daemons such as apache or sshd will be deterred. When a child of a
28489 ++ forking daemon is killed by PaX or crashes due to an illegal
28490 ++ instruction, the parent process will be delayed 30 seconds upon every
28491 ++ subsequent fork until the administrator is able to assess the
28492 ++ situation and restart the daemon. It is recommended that you also
28493 ++ enable signal logging in the auditing section so that logs are
28494 ++ generated when a process performs an illegal instruction.
28495 ++
28496 ++config GRKERNSEC_MODSTOP
28497 ++ bool "Runtime module disabling"
28498 ++ depends on MODULES
28499 ++ help
28500 ++ If you say Y here, you will be able to disable the ability to (un)load
28501 ++ modules at runtime. This feature is useful if you need the ability
28502 ++ to load kernel modules at boot time, but do not want to allow an
28503 ++ attacker to load a rootkit kernel module into the system, or to remove
28504 ++ a loaded kernel module important to system functioning. You should
28505 ++ enable the /dev/mem protection feature as well, since rootkits can be
28506 ++ inserted into the kernel via other methods than kernel modules. Since
28507 ++ an untrusted module could still be loaded by modifying init scripts and
28508 ++ rebooting the system, it is also recommended that you enable the RBAC
28509 ++ system. If you enable this option, a sysctl option with name
28510 ++ "disable_modules" will be created. Setting this option to "1" disables
28511 ++ module loading. After this option is set, no further writes to it are
28512 ++ allowed until the system is rebooted.
28513 ++
28514 ++config GRKERNSEC_HIDESYM
28515 ++ bool "Hide kernel symbols"
28516 ++ help
28517 ++ If you say Y here, getting information on loaded modules, and
28518 ++ displaying all kernel symbols through a syscall will be restricted
28519 ++ to users with CAP_SYS_MODULE. This option is only effective
28520 ++ provided the following conditions are met:
28521 ++ 1) The kernel using grsecurity is not precompiled by some distribution
28522 ++ 2) You are using the RBAC system and hiding other files such as your
28523 ++ kernel image and System.map
28524 ++ 3) You have the additional /proc restrictions enabled, which removes
28525 ++ /proc/kcore
28526 ++ If the above conditions are met, this option will aid to provide a
28527 ++ useful protection against local and remote kernel exploitation of
28528 ++ overflows and arbitrary read/write vulnerabilities.
28529 ++
28530 ++endmenu
28531 ++menu "Role Based Access Control Options"
28532 ++depends on GRKERNSEC
28533 ++
28534 ++config GRKERNSEC_ACL_HIDEKERN
28535 ++ bool "Hide kernel processes"
28536 ++ help
28537 ++ If you say Y here, all kernel threads will be hidden to all
28538 ++ processes but those whose subject has the "view hidden processes"
28539 ++ flag.
28540 ++
28541 ++config GRKERNSEC_ACL_MAXTRIES
28542 ++ int "Maximum tries before password lockout"
28543 ++ default 3
28544 ++ help
28545 ++ This option enforces the maximum number of times a user can attempt
28546 ++ to authorize themselves with the grsecurity RBAC system before being
28547 ++ denied the ability to attempt authorization again for a specified time.
28548 ++ The lower the number, the harder it will be to brute-force a password.
28549 ++
28550 ++config GRKERNSEC_ACL_TIMEOUT
28551 ++ int "Time to wait after max password tries, in seconds"
28552 ++ default 30
28553 ++ help
28554 ++ This option specifies the time the user must wait after attempting to
28555 ++ authorize to the RBAC system with the maximum number of invalid
28556 ++ passwords. The higher the number, the harder it will be to brute-force
28557 ++ a password.
28558 ++
28559 ++endmenu
28560 ++menu "Filesystem Protections"
28561 ++depends on GRKERNSEC
28562 ++
28563 ++config GRKERNSEC_PROC
28564 ++ bool "Proc restrictions"
28565 ++ help
28566 ++ If you say Y here, the permissions of the /proc filesystem
28567 ++ will be altered to enhance system security and privacy. You MUST
28568 ++ choose either a user only restriction or a user and group restriction.
28569 ++ Depending upon the option you choose, you can either restrict users to
28570 ++ see only the processes they themselves run, or choose a group that can
28571 ++ view all processes and files normally restricted to root if you choose
28572 ++ the "restrict to user only" option. NOTE: If you're running identd as
28573 ++ a non-root user, you will have to run it as the group you specify here.
28574 ++
28575 ++config GRKERNSEC_PROC_USER
28576 ++ bool "Restrict /proc to user only"
28577 ++ depends on GRKERNSEC_PROC
28578 ++ help
28579 ++ If you say Y here, non-root users will only be able to view their own
28580 ++ processes, and restricts them from viewing network-related information,
28581 ++ and viewing kernel symbol and module information.
28582 ++
28583 ++config GRKERNSEC_PROC_USERGROUP
28584 ++ bool "Allow special group"
28585 ++ depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
28586 ++ help
28587 ++ If you say Y here, you will be able to select a group that will be
28588 ++ able to view all processes, network-related information, and
28589 ++ kernel and symbol information. This option is useful if you want
28590 ++ to run identd as a non-root user.
28591 ++
28592 ++config GRKERNSEC_PROC_GID
28593 ++ int "GID for special group"
28594 ++ depends on GRKERNSEC_PROC_USERGROUP
28595 ++ default 1001
28596 ++
28597 ++config GRKERNSEC_PROC_ADD
28598 ++ bool "Additional restrictions"
28599 ++ depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
28600 ++ help
28601 ++ If you say Y here, additional restrictions will be placed on
28602 ++ /proc that keep normal users from viewing device information and
28603 ++ slabinfo information that could be useful for exploits.
28604 ++
28605 ++config GRKERNSEC_LINK
28606 ++ bool "Linking restrictions"
28607 ++ help
28608 ++ If you say Y here, /tmp race exploits will be prevented, since users
28609 ++ will no longer be able to follow symlinks owned by other users in
28610 ++ world-writable +t directories (i.e. /tmp), unless the owner of the
28611 ++ symlink is the owner of the directory. users will also not be
28612 ++ able to hardlink to files they do not own. If the sysctl option is
28613 ++ enabled, a sysctl option with name "linking_restrictions" is created.
28614 ++
28615 ++config GRKERNSEC_FIFO
28616 ++ bool "FIFO restrictions"
28617 ++ help
28618 ++ If you say Y here, users will not be able to write to FIFOs they don't
28619 ++ own in world-writable +t directories (i.e. /tmp), unless the owner of
28620 ++ the FIFO is the same owner of the directory it's held in. If the sysctl
28621 ++ option is enabled, a sysctl option with name "fifo_restrictions" is
28622 ++ created.
28623 ++
28624 ++config GRKERNSEC_CHROOT
28625 ++ bool "Chroot jail restrictions"
28626 ++ help
28627 ++ If you say Y here, you will be able to choose several options that will
28628 ++ make breaking out of a chrooted jail much more difficult. If you
28629 ++ encounter no software incompatibilities with the following options, it
28630 ++ is recommended that you enable each one.
28631 ++
28632 ++config GRKERNSEC_CHROOT_MOUNT
28633 ++ bool "Deny mounts"
28634 ++ depends on GRKERNSEC_CHROOT
28635 ++ help
28636 ++ If you say Y here, processes inside a chroot will not be able to
28637 ++ mount or remount filesystems. If the sysctl option is enabled, a
28638 ++ sysctl option with name "chroot_deny_mount" is created.
28639 ++
28640 ++config GRKERNSEC_CHROOT_DOUBLE
28641 ++ bool "Deny double-chroots"
28642 ++ depends on GRKERNSEC_CHROOT
28643 ++ help
28644 ++ If you say Y here, processes inside a chroot will not be able to chroot
28645 ++ again outside the chroot. This is a widely used method of breaking
28646 ++ out of a chroot jail and should not be allowed. If the sysctl
28647 ++ option is enabled, a sysctl option with name
28648 ++ "chroot_deny_chroot" is created.
28649 ++
28650 ++config GRKERNSEC_CHROOT_PIVOT
28651 ++ bool "Deny pivot_root in chroot"
28652 ++ depends on GRKERNSEC_CHROOT
28653 ++ help
28654 ++ If you say Y here, processes inside a chroot will not be able to use
28655 ++ a function called pivot_root() that was introduced in Linux 2.3.41. It
28656 ++ works similar to chroot in that it changes the root filesystem. This
28657 ++ function could be misused in a chrooted process to attempt to break out
28658 ++ of the chroot, and therefore should not be allowed. If the sysctl
28659 ++ option is enabled, a sysctl option with name "chroot_deny_pivot" is
28660 ++ created.
28661 ++
28662 ++config GRKERNSEC_CHROOT_CHDIR
28663 ++ bool "Enforce chdir(\"/\") on all chroots"
28664 ++ depends on GRKERNSEC_CHROOT
28665 ++ help
28666 ++ If you say Y here, the current working directory of all newly-chrooted
28667 ++ applications will be set to the the root directory of the chroot.
28668 ++ The man page on chroot(2) states:
28669 ++ Note that this call does not change the current working
28670 ++ directory, so that `.' can be outside the tree rooted at
28671 ++ `/'. In particular, the super-user can escape from a
28672 ++ `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
28673 ++
28674 ++ It is recommended that you say Y here, since it's not known to break
28675 ++ any software. If the sysctl option is enabled, a sysctl option with
28676 ++ name "chroot_enforce_chdir" is created.
28677 ++
28678 ++config GRKERNSEC_CHROOT_CHMOD
28679 ++ bool "Deny (f)chmod +s"
28680 ++ depends on GRKERNSEC_CHROOT
28681 ++ help
28682 ++ If you say Y here, processes inside a chroot will not be able to chmod
28683 ++ or fchmod files to make them have suid or sgid bits. This protects
28684 ++ against another published method of breaking a chroot. If the sysctl
28685 ++ option is enabled, a sysctl option with name "chroot_deny_chmod" is
28686 ++ created.
28687 ++
28688 ++config GRKERNSEC_CHROOT_FCHDIR
28689 ++ bool "Deny fchdir out of chroot"
28690 ++ depends on GRKERNSEC_CHROOT
28691 ++ help
28692 ++ If you say Y here, a well-known method of breaking chroots by fchdir'ing
28693 ++ to a file descriptor of the chrooting process that points to a directory
28694 ++ outside the filesystem will be stopped. If the sysctl option
28695 ++ is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
28696 ++
28697 ++config GRKERNSEC_CHROOT_MKNOD
28698 ++ bool "Deny mknod"
28699 ++ depends on GRKERNSEC_CHROOT
28700 ++ help
28701 ++ If you say Y here, processes inside a chroot will not be allowed to
28702 ++ mknod. The problem with using mknod inside a chroot is that it
28703 ++ would allow an attacker to create a device entry that is the same
28704 ++ as one on the physical root of your system, which could range from
28705 ++ anything from the console device to a device for your harddrive (which
28706 ++ they could then use to wipe the drive or steal data). It is recommended
28707 ++ that you say Y here, unless you run into software incompatibilities.
28708 ++ If the sysctl option is enabled, a sysctl option with name
28709 ++ "chroot_deny_mknod" is created.
28710 ++
28711 ++config GRKERNSEC_CHROOT_SHMAT
28712 ++ bool "Deny shmat() out of chroot"
28713 ++ depends on GRKERNSEC_CHROOT
28714 ++ help
28715 ++ If you say Y here, processes inside a chroot will not be able to attach
28716 ++ to shared memory segments that were created outside of the chroot jail.
28717 ++ It is recommended that you say Y here. If the sysctl option is enabled,
28718 ++ a sysctl option with name "chroot_deny_shmat" is created.
28719 ++
28720 ++config GRKERNSEC_CHROOT_UNIX
28721 ++ bool "Deny access to abstract AF_UNIX sockets out of chroot"
28722 ++ depends on GRKERNSEC_CHROOT
28723 ++ help
28724 ++ If you say Y here, processes inside a chroot will not be able to
28725 ++ connect to abstract (meaning not belonging to a filesystem) Unix
28726 ++ domain sockets that were bound outside of a chroot. It is recommended
28727 ++ that you say Y here. If the sysctl option is enabled, a sysctl option
28728 ++ with name "chroot_deny_unix" is created.
28729 ++
28730 ++config GRKERNSEC_CHROOT_FINDTASK
28731 ++ bool "Protect outside processes"
28732 ++ depends on GRKERNSEC_CHROOT
28733 ++ help
28734 ++ If you say Y here, processes inside a chroot will not be able to
28735 ++ kill, send signals with fcntl, ptrace, capget, getpgid, getsid,
28736 ++ or view any process outside of the chroot. If the sysctl
28737 ++ option is enabled, a sysctl option with name "chroot_findtask" is
28738 ++ created.
28739 ++
28740 ++config GRKERNSEC_CHROOT_NICE
28741 ++ bool "Restrict priority changes"
28742 ++ depends on GRKERNSEC_CHROOT
28743 ++ help
28744 ++ If you say Y here, processes inside a chroot will not be able to raise
28745 ++ the priority of processes in the chroot, or alter the priority of
28746 ++ processes outside the chroot. This provides more security than simply
28747 ++ removing CAP_SYS_NICE from the process' capability set. If the
28748 ++ sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
28749 ++ is created.
28750 ++
28751 ++config GRKERNSEC_CHROOT_SYSCTL
28752 ++ bool "Deny sysctl writes"
28753 ++ depends on GRKERNSEC_CHROOT
28754 ++ help
28755 ++ If you say Y here, an attacker in a chroot will not be able to
28756 ++ write to sysctl entries, either by sysctl(2) or through a /proc
28757 ++ interface. It is strongly recommended that you say Y here. If the
28758 ++ sysctl option is enabled, a sysctl option with name
28759 ++ "chroot_deny_sysctl" is created.
28760 ++
28761 ++config GRKERNSEC_CHROOT_CAPS
28762 ++ bool "Capability restrictions"
28763 ++ depends on GRKERNSEC_CHROOT
28764 ++ help
28765 ++ If you say Y here, the capabilities on all root processes within a
28766 ++ chroot jail will be lowered to stop module insertion, raw i/o,
28767 ++ system and net admin tasks, rebooting the system, modifying immutable
28768 ++ files, modifying IPC owned by another, and changing the system time.
28769 ++ This is left an option because it can break some apps. Disable this
28770 ++ if your chrooted apps are having problems performing those kinds of
28771 ++ tasks. If the sysctl option is enabled, a sysctl option with
28772 ++ name "chroot_caps" is created.
28773 ++
28774 ++endmenu
28775 ++menu "Kernel Auditing"
28776 ++depends on GRKERNSEC
28777 ++
28778 ++config GRKERNSEC_AUDIT_GROUP
28779 ++ bool "Single group for auditing"
28780 ++ help
28781 ++ If you say Y here, the exec, chdir, (un)mount, and ipc logging features
28782 ++ will only operate on a group you specify. This option is recommended
28783 ++ if you only want to watch certain users instead of having a large
28784 ++ amount of logs from the entire system. If the sysctl option is enabled,
28785 ++ a sysctl option with name "audit_group" is created.
28786 ++
28787 ++config GRKERNSEC_AUDIT_GID
28788 ++ int "GID for auditing"
28789 ++ depends on GRKERNSEC_AUDIT_GROUP
28790 ++ default 1007
28791 ++
28792 ++config GRKERNSEC_EXECLOG
28793 ++ bool "Exec logging"
28794 ++ help
28795 ++ If you say Y here, all execve() calls will be logged (since the
28796 ++ other exec*() calls are frontends to execve(), all execution
28797 ++ will be logged). Useful for shell-servers that like to keep track
28798 ++ of their users. If the sysctl option is enabled, a sysctl option with
28799 ++ name "exec_logging" is created.
28800 ++ WARNING: This option when enabled will produce a LOT of logs, especially
28801 ++ on an active system.
28802 ++
28803 ++config GRKERNSEC_RESLOG
28804 ++ bool "Resource logging"
28805 ++ help
28806 ++ If you say Y here, all attempts to overstep resource limits will
28807 ++ be logged with the resource name, the requested size, and the current
28808 ++ limit. It is highly recommended that you say Y here. If the sysctl
28809 ++ option is enabled, a sysctl option with name "resource_logging" is
28810 ++ created. If the RBAC system is enabled, the sysctl value is ignored.
28811 ++
28812 ++config GRKERNSEC_CHROOT_EXECLOG
28813 ++ bool "Log execs within chroot"
28814 ++ help
28815 ++ If you say Y here, all executions inside a chroot jail will be logged
28816 ++ to syslog. This can cause a large amount of logs if certain
28817 ++ applications (eg. djb's daemontools) are installed on the system, and
28818 ++ is therefore left as an option. If the sysctl option is enabled, a
28819 ++ sysctl option with name "chroot_execlog" is created.
28820 ++
28821 ++config GRKERNSEC_AUDIT_CHDIR
28822 ++ bool "Chdir logging"
28823 ++ help
28824 ++ If you say Y here, all chdir() calls will be logged. If the sysctl
28825 ++ option is enabled, a sysctl option with name "audit_chdir" is created.
28826 ++
28827 ++config GRKERNSEC_AUDIT_MOUNT
28828 ++ bool "(Un)Mount logging"
28829 ++ help
28830 ++ If you say Y here, all mounts and unmounts will be logged. If the
28831 ++ sysctl option is enabled, a sysctl option with name "audit_mount" is
28832 ++ created.
28833 ++
28834 ++config GRKERNSEC_AUDIT_IPC
28835 ++ bool "IPC logging"
28836 ++ help
28837 ++ If you say Y here, creation and removal of message queues, semaphores,
28838 ++ and shared memory will be logged. If the sysctl option is enabled, a
28839 ++ sysctl option with name "audit_ipc" is created.
28840 ++
28841 ++config GRKERNSEC_SIGNAL
28842 ++ bool "Signal logging"
28843 ++ help
28844 ++ If you say Y here, certain important signals will be logged, such as
28845 ++ SIGSEGV, which will as a result inform you of when a error in a program
28846 ++ occurred, which in some cases could mean a possible exploit attempt.
28847 ++ If the sysctl option is enabled, a sysctl option with name
28848 ++ "signal_logging" is created.
28849 ++
28850 ++config GRKERNSEC_FORKFAIL
28851 ++ bool "Fork failure logging"
28852 ++ help
28853 ++ If you say Y here, all failed fork() attempts will be logged.
28854 ++ This could suggest a fork bomb, or someone attempting to overstep
28855 ++ their process limit. If the sysctl option is enabled, a sysctl option
28856 ++ with name "forkfail_logging" is created.
28857 ++
28858 ++config GRKERNSEC_TIME
28859 ++ bool "Time change logging"
28860 ++ help
28861 ++ If you say Y here, any changes of the system clock will be logged.
28862 ++ If the sysctl option is enabled, a sysctl option with name
28863 ++ "timechange_logging" is created.
28864 ++
28865 ++config GRKERNSEC_PROC_IPADDR
28866 ++ bool "/proc/<pid>/ipaddr support"
28867 ++ help
28868 ++ If you say Y here, a new entry will be added to each /proc/<pid>
28869 ++ directory that contains the IP address of the person using the task.
28870 ++ The IP is carried across local TCP and AF_UNIX stream sockets.
28871 ++ This information can be useful for IDS/IPSes to perform remote response
28872 ++ to a local attack. The entry is readable by only the owner of the
28873 ++ process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
28874 ++ the RBAC system), and thus does not create privacy concerns.
28875 ++
28876 ++config GRKERNSEC_AUDIT_TEXTREL
28877 ++ bool 'ELF text relocations logging (READ HELP)'
28878 ++ depends on PAX_MPROTECT
28879 ++ help
28880 ++ If you say Y here, text relocations will be logged with the filename
28881 ++ of the offending library or binary. The purpose of the feature is
28882 ++ to help Linux distribution developers get rid of libraries and
28883 ++ binaries that need text relocations which hinder the future progress
28884 ++ of PaX. Only Linux distribution developers should say Y here, and
28885 ++ never on a production machine, as this option creates an information
28886 ++ leak that could aid an attacker in defeating the randomization of
28887 ++ a single memory region. If the sysctl option is enabled, a sysctl
28888 ++ option with name "audit_textrel" is created.
28889 ++
28890 ++endmenu
28891 ++
28892 ++menu "Executable Protections"
28893 ++depends on GRKERNSEC
28894 ++
28895 ++config GRKERNSEC_EXECVE
28896 ++ bool "Enforce RLIMIT_NPROC on execs"
28897 ++ help
28898 ++ If you say Y here, users with a resource limit on processes will
28899 ++ have the value checked during execve() calls. The current system
28900 ++ only checks the system limit during fork() calls. If the sysctl option
28901 ++ is enabled, a sysctl option with name "execve_limiting" is created.
28902 ++
28903 ++config GRKERNSEC_DMESG
28904 ++ bool "Dmesg(8) restriction"
28905 ++ help
28906 ++ If you say Y here, non-root users will not be able to use dmesg(8)
28907 ++ to view up to the last 4kb of messages in the kernel's log buffer.
28908 ++ If the sysctl option is enabled, a sysctl option with name "dmesg" is
28909 ++ created.
28910 ++
28911 ++config GRKERNSEC_TPE
28912 ++ bool "Trusted Path Execution (TPE)"
28913 ++ help
28914 ++ If you say Y here, you will be able to choose a gid to add to the
28915 ++ supplementary groups of users you want to mark as "untrusted."
28916 ++ These users will not be able to execute any files that are not in
28917 ++ root-owned directories writable only by root. If the sysctl option
28918 ++ is enabled, a sysctl option with name "tpe" is created.
28919 ++
28920 ++config GRKERNSEC_TPE_ALL
28921 ++ bool "Partially restrict non-root users"
28922 ++ depends on GRKERNSEC_TPE
28923 ++ help
28924 ++ If you say Y here, All non-root users other than the ones in the
28925 ++ group specified in the main TPE option will only be allowed to
28926 ++ execute files in directories they own that are not group or
28927 ++ world-writable, or in directories owned by root and writable only by
28928 ++ root. If the sysctl option is enabled, a sysctl option with name
28929 ++ "tpe_restrict_all" is created.
28930 ++
28931 ++config GRKERNSEC_TPE_INVERT
28932 ++ bool "Invert GID option"
28933 ++ depends on GRKERNSEC_TPE
28934 ++ help
28935 ++ If you say Y here, the group you specify in the TPE configuration will
28936 ++ decide what group TPE restrictions will be *disabled* for. This
28937 ++ option is useful if you want TPE restrictions to be applied to most
28938 ++ users on the system.
28939 ++
28940 ++config GRKERNSEC_TPE_GID
28941 ++ int "GID for untrusted users"
28942 ++ depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
28943 ++ default 1005
28944 ++ help
28945 ++ If you have selected the "Invert GID option" above, setting this
28946 ++ GID determines what group TPE restrictions will be *disabled* for.
28947 ++ If you have not selected the "Invert GID option" above, setting this
28948 ++ GID determines what group TPE restrictions will be *enabled* for.
28949 ++ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
28950 ++ is created.
28951 ++
28952 ++config GRKERNSEC_TPE_GID
28953 ++ int "GID for trusted users"
28954 ++ depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
28955 ++ default 1005
28956 ++ help
28957 ++ If you have selected the "Invert GID option" above, setting this
28958 ++ GID determines what group TPE restrictions will be *disabled* for.
28959 ++ If you have not selected the "Invert GID option" above, setting this
28960 ++ GID determines what group TPE restrictions will be *enabled* for.
28961 ++ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
28962 ++ is created.
28963 ++
28964 ++endmenu
28965 ++menu "Network Protections"
28966 ++depends on GRKERNSEC
28967 ++
28968 ++config GRKERNSEC_RANDNET
28969 ++ bool "Larger entropy pools"
28970 ++ help
28971 ++ If you say Y here, the entropy pools used for many features of Linux
28972 ++ and grsecurity will be doubled in size. Since several grsecurity
28973 ++ features use additional randomness, it is recommended that you say Y
28974 ++ here. Saying Y here has a similar effect as modifying
28975 ++ /proc/sys/kernel/random/poolsize.
28976 ++
28977 ++config GRKERNSEC_SOCKET
28978 ++ bool "Socket restrictions"
28979 ++ help
28980 ++ If you say Y here, you will be able to choose from several options.
28981 ++ If you assign a GID on your system and add it to the supplementary
28982 ++ groups of users you want to restrict socket access to, this patch
28983 ++ will perform up to three things, based on the option(s) you choose.
28984 ++
28985 ++config GRKERNSEC_SOCKET_ALL
28986 ++ bool "Deny any sockets to group"
28987 ++ depends on GRKERNSEC_SOCKET
28988 ++ help
28989 ++ If you say Y here, you will be able to choose a GID of whose users will
28990 ++ be unable to connect to other hosts from your machine or run server
28991 ++ applications from your machine. If the sysctl option is enabled, a
28992 ++ sysctl option with name "socket_all" is created.
28993 ++
28994 ++config GRKERNSEC_SOCKET_ALL_GID
28995 ++ int "GID to deny all sockets for"
28996 ++ depends on GRKERNSEC_SOCKET_ALL
28997 ++ default 1004
28998 ++ help
28999 ++ Here you can choose the GID to disable socket access for. Remember to
29000 ++ add the users you want socket access disabled for to the GID
29001 ++ specified here. If the sysctl option is enabled, a sysctl option
29002 ++ with name "socket_all_gid" is created.
29003 ++
29004 ++config GRKERNSEC_SOCKET_CLIENT
29005 ++ bool "Deny client sockets to group"
29006 ++ depends on GRKERNSEC_SOCKET
29007 ++ help
29008 ++ If you say Y here, you will be able to choose a GID of whose users will
29009 ++ be unable to connect to other hosts from your machine, but will be
29010 ++ able to run servers. If this option is enabled, all users in the group
29011 ++ you specify will have to use passive mode when initiating ftp transfers
29012 ++ from the shell on your machine. If the sysctl option is enabled, a
29013 ++ sysctl option with name "socket_client" is created.
29014 ++
29015 ++config GRKERNSEC_SOCKET_CLIENT_GID
29016 ++ int "GID to deny client sockets for"
29017 ++ depends on GRKERNSEC_SOCKET_CLIENT
29018 ++ default 1003
29019 ++ help
29020 ++ Here you can choose the GID to disable client socket access for.
29021 ++ Remember to add the users you want client socket access disabled for to
29022 ++ the GID specified here. If the sysctl option is enabled, a sysctl
29023 ++ option with name "socket_client_gid" is created.
29024 ++
29025 ++config GRKERNSEC_SOCKET_SERVER
29026 ++ bool "Deny server sockets to group"
29027 ++ depends on GRKERNSEC_SOCKET
29028 ++ help
29029 ++ If you say Y here, you will be able to choose a GID of whose users will
29030 ++ be unable to run server applications from your machine. If the sysctl
29031 ++ option is enabled, a sysctl option with name "socket_server" is created.
29032 ++
29033 ++config GRKERNSEC_SOCKET_SERVER_GID
29034 ++ int "GID to deny server sockets for"
29035 ++ depends on GRKERNSEC_SOCKET_SERVER
29036 ++ default 1002
29037 ++ help
29038 ++ Here you can choose the GID to disable server socket access for.
29039 ++ Remember to add the users you want server socket access disabled for to
29040 ++ the GID specified here. If the sysctl option is enabled, a sysctl
29041 ++ option with name "socket_server_gid" is created.
29042 ++
29043 ++endmenu
29044 ++menu "Sysctl support"
29045 ++depends on GRKERNSEC && SYSCTL
29046 ++
29047 ++config GRKERNSEC_SYSCTL
29048 ++ bool "Sysctl support"
29049 ++ help
29050 ++ If you say Y here, you will be able to change the options that
29051 ++ grsecurity runs with at bootup, without having to recompile your
29052 ++ kernel. You can echo values to files in /proc/sys/kernel/grsecurity
29053 ++ to enable (1) or disable (0) various features. All the sysctl entries
29054 ++ are mutable until the "grsec_lock" entry is set to a non-zero value.
29055 ++ All features enabled in the kernel configuration are disabled at boot
29056 ++ if you do not say Y to the "Turn on features by default" option.
29057 ++ All options should be set at startup, and the grsec_lock entry should
29058 ++ be set to a non-zero value after all the options are set.
29059 ++ *THIS IS EXTREMELY IMPORTANT*
29060 ++
29061 ++config GRKERNSEC_SYSCTL_ON
29062 ++ bool "Turn on features by default"
29063 ++ depends on GRKERNSEC_SYSCTL
29064 ++ help
29065 ++ If you say Y here, instead of having all features enabled in the
29066 ++ kernel configuration disabled at boot time, the features will be
29067 ++ enabled at boot time. It is recommended you say Y here unless
29068 ++ there is some reason you would want all sysctl-tunable features to
29069 ++ be disabled by default. As mentioned elsewhere, it is important
29070 ++ to enable the grsec_lock entry once you have finished modifying
29071 ++ the sysctl entries.
29072 ++
29073 ++endmenu
29074 ++menu "Logging Options"
29075 ++depends on GRKERNSEC
29076 ++
29077 ++config GRKERNSEC_FLOODTIME
29078 ++ int "Seconds in between log messages (minimum)"
29079 ++ default 10
29080 ++ help
29081 ++ This option allows you to enforce the number of seconds between
29082 ++ grsecurity log messages. The default should be suitable for most
29083 ++ people, however, if you choose to change it, choose a value small enough
29084 ++ to allow informative logs to be produced, but large enough to
29085 ++ prevent flooding.
29086 ++
29087 ++config GRKERNSEC_FLOODBURST
29088 ++ int "Number of messages in a burst (maximum)"
29089 ++ default 4
29090 ++ help
29091 ++ This option allows you to choose the maximum number of messages allowed
29092 ++ within the flood time interval you chose in a separate option. The
29093 ++ default should be suitable for most people, however if you find that
29094 ++ many of your logs are being interpreted as flooding, you may want to
29095 ++ raise this value.
29096 ++
29097 ++endmenu
29098 ++
29099 ++endmenu
29100 +diff -urNp linux-2.6.28.8/grsecurity/Makefile linux-2.6.28.8/grsecurity/Makefile
29101 +--- linux-2.6.28.8/grsecurity/Makefile 1969-12-31 19:00:00.000000000 -0500
29102 ++++ linux-2.6.28.8/grsecurity/Makefile 2009-02-21 09:37:49.000000000 -0500
29103 +@@ -0,0 +1,20 @@
29104 ++# grsecurity's ACL system was originally written in 2001 by Michael Dalton
29105 ++# during 2001-2005 it has been completely redesigned by Brad Spengler
29106 ++# into an RBAC system
29107 ++#
29108 ++# All code in this directory and various hooks inserted throughout the kernel
29109 ++# are copyright Brad Spengler, and released under the GPL v2 or higher
29110 ++
29111 ++obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
29112 ++ grsec_mount.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
29113 ++ grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
29114 ++
29115 ++obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
29116 ++ gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
29117 ++ gracl_learn.o grsec_log.o
29118 ++obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
29119 ++
29120 ++ifndef CONFIG_GRKERNSEC
29121 ++obj-y += grsec_disabled.o
29122 ++endif
29123 ++
29124 +diff -urNp linux-2.6.28.8/include/asm-frv/kmap_types.h linux-2.6.28.8/include/asm-frv/kmap_types.h
29125 +--- linux-2.6.28.8/include/asm-frv/kmap_types.h 2009-02-06 16:47:45.000000000 -0500
29126 ++++ linux-2.6.28.8/include/asm-frv/kmap_types.h 2009-02-21 09:37:49.000000000 -0500
29127 +@@ -23,6 +23,7 @@ enum km_type {
29128 + KM_IRQ1,
29129 + KM_SOFTIRQ0,
29130 + KM_SOFTIRQ1,
29131 ++ KM_CLEARPAGE,
29132 + KM_TYPE_NR
29133 + };
29134 +
29135 +diff -urNp linux-2.6.28.8/include/asm-generic/futex.h linux-2.6.28.8/include/asm-generic/futex.h
29136 +--- linux-2.6.28.8/include/asm-generic/futex.h 2009-02-06 16:47:45.000000000 -0500
29137 ++++ linux-2.6.28.8/include/asm-generic/futex.h 2009-02-21 09:37:49.000000000 -0500
29138 +@@ -6,7 +6,7 @@
29139 + #include <asm/errno.h>
29140 +
29141 + static inline int
29142 +-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
29143 ++futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
29144 + {
29145 + int op = (encoded_op >> 28) & 7;
29146 + int cmp = (encoded_op >> 24) & 15;
29147 +@@ -48,7 +48,7 @@ futex_atomic_op_inuser (int encoded_op,
29148 + }
29149 +
29150 + static inline int
29151 +-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
29152 ++futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
29153 + {
29154 + return -ENOSYS;
29155 + }
29156 +diff -urNp linux-2.6.28.8/include/asm-generic/vmlinux.lds.h linux-2.6.28.8/include/asm-generic/vmlinux.lds.h
29157 +--- linux-2.6.28.8/include/asm-generic/vmlinux.lds.h 2009-02-06 16:47:45.000000000 -0500
29158 ++++ linux-2.6.28.8/include/asm-generic/vmlinux.lds.h 2009-02-21 09:37:49.000000000 -0500
29159 +@@ -69,6 +69,7 @@
29160 + .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
29161 + VMLINUX_SYMBOL(__start_rodata) = .; \
29162 + *(.rodata) *(.rodata.*) \
29163 ++ *(.data.read_only) \
29164 + *(__vermagic) /* Kernel version magic */ \
29165 + *(__markers_strings) /* Markers: strings */ \
29166 + *(__tracepoints_strings)/* Tracepoints: strings */ \
29167 +diff -urNp linux-2.6.28.8/include/asm-m32r/kmap_types.h linux-2.6.28.8/include/asm-m32r/kmap_types.h
29168 +--- linux-2.6.28.8/include/asm-m32r/kmap_types.h 2009-02-06 16:47:45.000000000 -0500
29169 ++++ linux-2.6.28.8/include/asm-m32r/kmap_types.h 2009-02-21 09:37:49.000000000 -0500
29170 +@@ -21,7 +21,8 @@ D(9) KM_IRQ0,
29171 + D(10) KM_IRQ1,
29172 + D(11) KM_SOFTIRQ0,
29173 + D(12) KM_SOFTIRQ1,
29174 +-D(13) KM_TYPE_NR
29175 ++D(13) KM_CLEARPAGE,
29176 ++D(14) KM_TYPE_NR
29177 + };
29178 +
29179 + #undef D
29180 +diff -urNp linux-2.6.28.8/include/asm-m68k/kmap_types.h linux-2.6.28.8/include/asm-m68k/kmap_types.h
29181 +--- linux-2.6.28.8/include/asm-m68k/kmap_types.h 2009-02-06 16:47:45.000000000 -0500
29182 ++++ linux-2.6.28.8/include/asm-m68k/kmap_types.h 2009-02-21 09:37:49.000000000 -0500
29183 +@@ -15,6 +15,7 @@ enum km_type {
29184 + KM_IRQ1,
29185 + KM_SOFTIRQ0,
29186 + KM_SOFTIRQ1,
29187 ++ KM_CLEARPAGE,
29188 + KM_TYPE_NR
29189 + };
29190 +
29191 +diff -urNp linux-2.6.28.8/include/asm-mn10300/kmap_types.h linux-2.6.28.8/include/asm-mn10300/kmap_types.h
29192 +--- linux-2.6.28.8/include/asm-mn10300/kmap_types.h 2009-02-06 16:47:45.000000000 -0500
29193 ++++ linux-2.6.28.8/include/asm-mn10300/kmap_types.h 2009-02-21 09:37:49.000000000 -0500
29194 +@@ -25,6 +25,7 @@ enum km_type {
29195 + KM_IRQ1,
29196 + KM_SOFTIRQ0,
29197 + KM_SOFTIRQ1,
29198 ++ KM_CLEARPAGE,
29199 + KM_TYPE_NR
29200 + };
29201 +
29202 +diff -urNp linux-2.6.28.8/include/asm-xtensa/kmap_types.h linux-2.6.28.8/include/asm-xtensa/kmap_types.h
29203 +--- linux-2.6.28.8/include/asm-xtensa/kmap_types.h 2009-02-06 16:47:45.000000000 -0500
29204 ++++ linux-2.6.28.8/include/asm-xtensa/kmap_types.h 2009-02-21 09:37:49.000000000 -0500
29205 +@@ -25,6 +25,7 @@ enum km_type {
29206 + KM_IRQ1,
29207 + KM_SOFTIRQ0,
29208 + KM_SOFTIRQ1,
29209 ++ KM_CLEARPAGE,
29210 + KM_TYPE_NR
29211 + };
29212 +
29213 +diff -urNp linux-2.6.28.8/include/drm/drm_pciids.h linux-2.6.28.8/include/drm/drm_pciids.h
29214 +--- linux-2.6.28.8/include/drm/drm_pciids.h 2009-02-06 16:47:45.000000000 -0500
29215 ++++ linux-2.6.28.8/include/drm/drm_pciids.h 2009-02-21 09:37:49.000000000 -0500
29216 +@@ -243,7 +243,7 @@
29217 + {0x1002, 0x796d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
29218 + {0x1002, 0x796e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
29219 + {0x1002, 0x796f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
29220 +- {0, 0, 0}
29221 ++ {0, 0, 0, 0, 0, 0}
29222 +
29223 + #define r128_PCI_IDS \
29224 + {0x1002, 0x4c45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29225 +@@ -283,14 +283,14 @@
29226 + {0x1002, 0x5446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29227 + {0x1002, 0x544C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29228 + {0x1002, 0x5452, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29229 +- {0, 0, 0}
29230 ++ {0, 0, 0, 0, 0, 0}
29231 +
29232 + #define mga_PCI_IDS \
29233 + {0x102b, 0x0520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \
29234 + {0x102b, 0x0521, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \
29235 + {0x102b, 0x0525, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G400}, \
29236 + {0x102b, 0x2527, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G550}, \
29237 +- {0, 0, 0}
29238 ++ {0, 0, 0, 0, 0, 0}
29239 +
29240 + #define mach64_PCI_IDS \
29241 + {0x1002, 0x4749, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29242 +@@ -313,7 +313,7 @@
29243 + {0x1002, 0x4c53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29244 + {0x1002, 0x4c4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29245 + {0x1002, 0x4c4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29246 +- {0, 0, 0}
29247 ++ {0, 0, 0, 0, 0, 0}
29248 +
29249 + #define sisdrv_PCI_IDS \
29250 + {0x1039, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29251 +@@ -324,7 +324,7 @@
29252 + {0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29253 + {0x18CA, 0x0040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
29254 + {0x18CA, 0x0042, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
29255 +- {0, 0, 0}
29256 ++ {0, 0, 0, 0, 0, 0}
29257 +
29258 + #define tdfx_PCI_IDS \
29259 + {0x121a, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29260 +@@ -333,7 +333,7 @@
29261 + {0x121a, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29262 + {0x121a, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29263 + {0x121a, 0x000b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29264 +- {0, 0, 0}
29265 ++ {0, 0, 0, 0, 0, 0}
29266 +
29267 + #define viadrv_PCI_IDS \
29268 + {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29269 +@@ -345,25 +345,25 @@
29270 + {0x1106, 0x3343, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29271 + {0x1106, 0x3230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_DX9_0}, \
29272 + {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \
29273 +- {0, 0, 0}
29274 ++ {0, 0, 0, 0, 0, 0}
29275 +
29276 + #define i810_PCI_IDS \
29277 + {0x8086, 0x7121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29278 + {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29279 + {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29280 + {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29281 +- {0, 0, 0}
29282 ++ {0, 0, 0, 0, 0, 0}
29283 +
29284 + #define i830_PCI_IDS \
29285 + {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29286 + {0x8086, 0x2562, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29287 + {0x8086, 0x3582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29288 + {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29289 +- {0, 0, 0}
29290 ++ {0, 0, 0, 0, 0, 0}
29291 +
29292 + #define gamma_PCI_IDS \
29293 + {0x3d3d, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29294 +- {0, 0, 0}
29295 ++ {0, 0, 0, 0, 0, 0}
29296 +
29297 + #define savage_PCI_IDS \
29298 + {0x5333, 0x8a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \
29299 +@@ -389,10 +389,10 @@
29300 + {0x5333, 0x8d02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_TWISTER}, \
29301 + {0x5333, 0x8d03, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \
29302 + {0x5333, 0x8d04, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \
29303 +- {0, 0, 0}
29304 ++ {0, 0, 0, 0, 0, 0}
29305 +
29306 + #define ffb_PCI_IDS \
29307 +- {0, 0, 0}
29308 ++ {0, 0, 0, 0, 0, 0}
29309 +
29310 + #define i915_PCI_IDS \
29311 + {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
29312 +@@ -418,4 +418,4 @@
29313 + {0x8086, 0x2e02, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
29314 + {0x8086, 0x2e12, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
29315 + {0x8086, 0x2e22, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
29316 +- {0, 0, 0}
29317 ++ {0, 0, 0, 0, 0, 0}
29318 +diff -urNp linux-2.6.28.8/include/linux/a.out.h linux-2.6.28.8/include/linux/a.out.h
29319 +--- linux-2.6.28.8/include/linux/a.out.h 2009-02-06 16:47:45.000000000 -0500
29320 ++++ linux-2.6.28.8/include/linux/a.out.h 2009-02-21 09:37:49.000000000 -0500
29321 +@@ -39,6 +39,14 @@ enum machine_type {
29322 + M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
29323 + };
29324 +
29325 ++/* Constants for the N_FLAGS field */
29326 ++#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
29327 ++#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
29328 ++#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
29329 ++#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
29330 ++/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
29331 ++#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
29332 ++
29333 + #if !defined (N_MAGIC)
29334 + #define N_MAGIC(exec) ((exec).a_info & 0xffff)
29335 + #endif
29336 +diff -urNp linux-2.6.28.8/include/linux/binfmts.h linux-2.6.28.8/include/linux/binfmts.h
29337 +--- linux-2.6.28.8/include/linux/binfmts.h 2009-02-06 16:47:45.000000000 -0500
29338 ++++ linux-2.6.28.8/include/linux/binfmts.h 2009-02-21 09:37:49.000000000 -0500
29339 +@@ -74,6 +74,7 @@ struct linux_binfmt {
29340 + int (*load_binary)(struct linux_binprm *, struct pt_regs * regs);
29341 + int (*load_shlib)(struct file *);
29342 + int (*core_dump)(long signr, struct pt_regs *regs, struct file *file, unsigned long limit);
29343 ++ void (*handle_mprotect)(struct vm_area_struct *vma, unsigned long newflags);
29344 + unsigned long min_coredump; /* minimal dump size */
29345 + int hasvdso;
29346 + };
29347 +diff -urNp linux-2.6.28.8/include/linux/cache.h linux-2.6.28.8/include/linux/cache.h
29348 +--- linux-2.6.28.8/include/linux/cache.h 2009-02-06 16:47:45.000000000 -0500
29349 ++++ linux-2.6.28.8/include/linux/cache.h 2009-02-21 09:37:49.000000000 -0500
29350 +@@ -16,6 +16,10 @@
29351 + #define __read_mostly
29352 + #endif
29353 +
29354 ++#ifndef __read_only
29355 ++#define __read_only __read_mostly
29356 ++#endif
29357 ++
29358 + #ifndef ____cacheline_aligned
29359 + #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
29360 + #endif
29361 +diff -urNp linux-2.6.28.8/include/linux/capability.h linux-2.6.28.8/include/linux/capability.h
29362 +--- linux-2.6.28.8/include/linux/capability.h 2009-02-06 16:47:45.000000000 -0500
29363 ++++ linux-2.6.28.8/include/linux/capability.h 2009-02-21 09:37:49.000000000 -0500
29364 +@@ -516,6 +516,7 @@ kernel_cap_t cap_set_effective(const ker
29365 + #define has_capability(t, cap) (security_capable((t), (cap)) == 0)
29366 +
29367 + extern int capable(int cap);
29368 ++int capable_nolog(int cap);
29369 +
29370 + #endif /* __KERNEL__ */
29371 +
29372 +diff -urNp linux-2.6.28.8/include/linux/cpumask.h linux-2.6.28.8/include/linux/cpumask.h
29373 +--- linux-2.6.28.8/include/linux/cpumask.h 2009-02-06 16:47:45.000000000 -0500
29374 ++++ linux-2.6.28.8/include/linux/cpumask.h 2009-02-21 09:37:49.000000000 -0500
29375 +@@ -142,7 +142,6 @@
29376 + #include <linux/bitmap.h>
29377 +
29378 + typedef struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;
29379 +-extern cpumask_t _unused_cpumask_arg_;
29380 +
29381 + #define cpu_set(cpu, dst) __cpu_set((cpu), &(dst))
29382 + static inline void __cpu_set(int cpu, volatile cpumask_t *dstp)
29383 +diff -urNp linux-2.6.28.8/include/linux/elf.h linux-2.6.28.8/include/linux/elf.h
29384 +--- linux-2.6.28.8/include/linux/elf.h 2009-02-06 16:47:45.000000000 -0500
29385 ++++ linux-2.6.28.8/include/linux/elf.h 2009-02-21 09:37:49.000000000 -0500
29386 +@@ -49,6 +49,17 @@ typedef __s64 Elf64_Sxword;
29387 + #define PT_GNU_EH_FRAME 0x6474e550
29388 +
29389 + #define PT_GNU_STACK (PT_LOOS + 0x474e551)
29390 ++#define PT_GNU_RELRO (PT_LOOS + 0x474e552)
29391 ++
29392 ++#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
29393 ++
29394 ++/* Constants for the e_flags field */
29395 ++#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
29396 ++#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
29397 ++#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
29398 ++#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
29399 ++/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
29400 ++#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
29401 +
29402 + /* These constants define the different elf file types */
29403 + #define ET_NONE 0
29404 +@@ -84,6 +95,8 @@ typedef __s64 Elf64_Sxword;
29405 + #define DT_DEBUG 21
29406 + #define DT_TEXTREL 22
29407 + #define DT_JMPREL 23
29408 ++#define DT_FLAGS 30
29409 ++ #define DF_TEXTREL 0x00000004
29410 + #define DT_ENCODING 32
29411 + #define OLD_DT_LOOS 0x60000000
29412 + #define DT_LOOS 0x6000000d
29413 +@@ -230,6 +243,19 @@ typedef struct elf64_hdr {
29414 + #define PF_W 0x2
29415 + #define PF_X 0x1
29416 +
29417 ++#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */
29418 ++#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */
29419 ++#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */
29420 ++#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */
29421 ++#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */
29422 ++#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */
29423 ++/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */
29424 ++/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */
29425 ++#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */
29426 ++#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */
29427 ++#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */
29428 ++#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */
29429 ++
29430 + typedef struct elf32_phdr{
29431 + Elf32_Word p_type;
29432 + Elf32_Off p_offset;
29433 +@@ -322,6 +348,8 @@ typedef struct elf64_shdr {
29434 + #define EI_OSABI 7
29435 + #define EI_PAD 8
29436 +
29437 ++#define EI_PAX 14
29438 ++
29439 + #define ELFMAG0 0x7f /* EI_MAG */
29440 + #define ELFMAG1 'E'
29441 + #define ELFMAG2 'L'
29442 +@@ -384,6 +412,7 @@ extern Elf32_Dyn _DYNAMIC [];
29443 + #define elf_phdr elf32_phdr
29444 + #define elf_note elf32_note
29445 + #define elf_addr_t Elf32_Off
29446 ++#define elf_dyn Elf32_Dyn
29447 +
29448 + #else
29449 +
29450 +@@ -392,6 +421,7 @@ extern Elf64_Dyn _DYNAMIC [];
29451 + #define elf_phdr elf64_phdr
29452 + #define elf_note elf64_note
29453 + #define elf_addr_t Elf64_Off
29454 ++#define elf_dyn Elf64_Dyn
29455 +
29456 + #endif
29457 +
29458 +diff -urNp linux-2.6.28.8/include/linux/gracl.h linux-2.6.28.8/include/linux/gracl.h
29459 +--- linux-2.6.28.8/include/linux/gracl.h 1969-12-31 19:00:00.000000000 -0500
29460 ++++ linux-2.6.28.8/include/linux/gracl.h 2009-02-21 09:37:49.000000000 -0500
29461 +@@ -0,0 +1,318 @@
29462 ++#ifndef GR_ACL_H
29463 ++#define GR_ACL_H
29464 ++
29465 ++#include <linux/grdefs.h>
29466 ++#include <linux/resource.h>
29467 ++#include <linux/capability.h>
29468 ++#include <linux/dcache.h>
29469 ++#include <asm/resource.h>
29470 ++
29471 ++/* Major status information */
29472 ++
29473 ++#define GR_VERSION "grsecurity 2.1.13"
29474 ++#define GRSECURITY_VERSION 0x2113
29475 ++
29476 ++enum {
29477 ++ GR_SHUTDOWN = 0,
29478 ++ GR_ENABLE = 1,
29479 ++ GR_SPROLE = 2,
29480 ++ GR_RELOAD = 3,
29481 ++ GR_SEGVMOD = 4,
29482 ++ GR_STATUS = 5,
29483 ++ GR_UNSPROLE = 6,
29484 ++ GR_PASSSET = 7,
29485 ++ GR_SPROLEPAM = 8,
29486 ++};
29487 ++
29488 ++/* Password setup definitions
29489 ++ * kernel/grhash.c */
29490 ++enum {
29491 ++ GR_PW_LEN = 128,
29492 ++ GR_SALT_LEN = 16,
29493 ++ GR_SHA_LEN = 32,
29494 ++};
29495 ++
29496 ++enum {
29497 ++ GR_SPROLE_LEN = 64,
29498 ++};
29499 ++
29500 ++#define GR_NLIMITS (RLIMIT_LOCKS + 2)
29501 ++
29502 ++/* Begin Data Structures */
29503 ++
29504 ++struct sprole_pw {
29505 ++ unsigned char *rolename;
29506 ++ unsigned char salt[GR_SALT_LEN];
29507 ++ unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
29508 ++};
29509 ++
29510 ++struct name_entry {
29511 ++ __u32 key;
29512 ++ ino_t inode;
29513 ++ dev_t device;
29514 ++ char *name;
29515 ++ __u16 len;
29516 ++ __u8 deleted;
29517 ++ struct name_entry *prev;
29518 ++ struct name_entry *next;
29519 ++};
29520 ++
29521 ++struct inodev_entry {
29522 ++ struct name_entry *nentry;
29523 ++ struct inodev_entry *prev;
29524 ++ struct inodev_entry *next;
29525 ++};
29526 ++
29527 ++struct acl_role_db {
29528 ++ struct acl_role_label **r_hash;
29529 ++ __u32 r_size;
29530 ++};
29531 ++
29532 ++struct inodev_db {
29533 ++ struct inodev_entry **i_hash;
29534 ++ __u32 i_size;
29535 ++};
29536 ++
29537 ++struct name_db {
29538 ++ struct name_entry **n_hash;
29539 ++ __u32 n_size;
29540 ++};
29541 ++
29542 ++struct crash_uid {
29543 ++ uid_t uid;
29544 ++ unsigned long expires;
29545 ++};
29546 ++
29547 ++struct gr_hash_struct {
29548 ++ void **table;
29549 ++ void **nametable;
29550 ++ void *first;
29551 ++ __u32 table_size;
29552 ++ __u32 used_size;
29553 ++ int type;
29554 ++};
29555 ++
29556 ++/* Userspace Grsecurity ACL data structures */
29557 ++
29558 ++struct acl_subject_label {
29559 ++ char *filename;
29560 ++ ino_t inode;
29561 ++ dev_t device;
29562 ++ __u32 mode;
29563 ++ kernel_cap_t cap_mask;
29564 ++ kernel_cap_t cap_lower;
29565 ++
29566 ++ struct rlimit res[GR_NLIMITS];
29567 ++ __u16 resmask;
29568 ++
29569 ++ __u8 user_trans_type;
29570 ++ __u8 group_trans_type;
29571 ++ uid_t *user_transitions;
29572 ++ gid_t *group_transitions;
29573 ++ __u16 user_trans_num;
29574 ++ __u16 group_trans_num;
29575 ++
29576 ++ __u32 ip_proto[8];
29577 ++ __u32 ip_type;
29578 ++ struct acl_ip_label **ips;
29579 ++ __u32 ip_num;
29580 ++ __u32 inaddr_any_override;
29581 ++
29582 ++ __u32 crashes;
29583 ++ unsigned long expires;
29584 ++
29585 ++ struct acl_subject_label *parent_subject;
29586 ++ struct gr_hash_struct *hash;
29587 ++ struct acl_subject_label *prev;
29588 ++ struct acl_subject_label *next;
29589 ++
29590 ++ struct acl_object_label **obj_hash;
29591 ++ __u32 obj_hash_size;
29592 ++ __u16 pax_flags;
29593 ++};
29594 ++
29595 ++struct role_allowed_ip {
29596 ++ __u32 addr;
29597 ++ __u32 netmask;
29598 ++
29599 ++ struct role_allowed_ip *prev;
29600 ++ struct role_allowed_ip *next;
29601 ++};
29602 ++
29603 ++struct role_transition {
29604 ++ char *rolename;
29605 ++
29606 ++ struct role_transition *prev;
29607 ++ struct role_transition *next;
29608 ++};
29609 ++
29610 ++struct acl_role_label {
29611 ++ char *rolename;
29612 ++ uid_t uidgid;
29613 ++ __u16 roletype;
29614 ++
29615 ++ __u16 auth_attempts;
29616 ++ unsigned long expires;
29617 ++
29618 ++ struct acl_subject_label *root_label;
29619 ++ struct gr_hash_struct *hash;
29620 ++
29621 ++ struct acl_role_label *prev;
29622 ++ struct acl_role_label *next;
29623 ++
29624 ++ struct role_transition *transitions;
29625 ++ struct role_allowed_ip *allowed_ips;
29626 ++ uid_t *domain_children;
29627 ++ __u16 domain_child_num;
29628 ++
29629 ++ struct acl_subject_label **subj_hash;
29630 ++ __u32 subj_hash_size;
29631 ++};
29632 ++
29633 ++struct user_acl_role_db {
29634 ++ struct acl_role_label **r_table;
29635 ++ __u32 num_pointers; /* Number of allocations to track */
29636 ++ __u32 num_roles; /* Number of roles */
29637 ++ __u32 num_domain_children; /* Number of domain children */
29638 ++ __u32 num_subjects; /* Number of subjects */
29639 ++ __u32 num_objects; /* Number of objects */
29640 ++};
29641 ++
29642 ++struct acl_object_label {
29643 ++ char *filename;
29644 ++ ino_t inode;
29645 ++ dev_t device;
29646 ++ __u32 mode;
29647 ++
29648 ++ struct acl_subject_label *nested;
29649 ++ struct acl_object_label *globbed;
29650 ++
29651 ++ /* next two structures not used */
29652 ++
29653 ++ struct acl_object_label *prev;
29654 ++ struct acl_object_label *next;
29655 ++};
29656 ++
29657 ++struct acl_ip_label {
29658 ++ char *iface;
29659 ++ __u32 addr;
29660 ++ __u32 netmask;
29661 ++ __u16 low, high;
29662 ++ __u8 mode;
29663 ++ __u32 type;
29664 ++ __u32 proto[8];
29665 ++
29666 ++ /* next two structures not used */
29667 ++
29668 ++ struct acl_ip_label *prev;
29669 ++ struct acl_ip_label *next;
29670 ++};
29671 ++
29672 ++struct gr_arg {
29673 ++ struct user_acl_role_db role_db;
29674 ++ unsigned char pw[GR_PW_LEN];
29675 ++ unsigned char salt[GR_SALT_LEN];
29676 ++ unsigned char sum[GR_SHA_LEN];
29677 ++ unsigned char sp_role[GR_SPROLE_LEN];
29678 ++ struct sprole_pw *sprole_pws;
29679 ++ dev_t segv_device;
29680 ++ ino_t segv_inode;
29681 ++ uid_t segv_uid;
29682 ++ __u16 num_sprole_pws;
29683 ++ __u16 mode;
29684 ++};
29685 ++
29686 ++struct gr_arg_wrapper {
29687 ++ struct gr_arg *arg;
29688 ++ __u32 version;
29689 ++ __u32 size;
29690 ++};
29691 ++
29692 ++struct subject_map {
29693 ++ struct acl_subject_label *user;
29694 ++ struct acl_subject_label *kernel;
29695 ++ struct subject_map *prev;
29696 ++ struct subject_map *next;
29697 ++};
29698 ++
29699 ++struct acl_subj_map_db {
29700 ++ struct subject_map **s_hash;
29701 ++ __u32 s_size;
29702 ++};
29703 ++
29704 ++/* End Data Structures Section */
29705 ++
29706 ++/* Hash functions generated by empirical testing by Brad Spengler
29707 ++ Makes good use of the low bits of the inode. Generally 0-1 times
29708 ++ in loop for successful match. 0-3 for unsuccessful match.
29709 ++ Shift/add algorithm with modulus of table size and an XOR*/
29710 ++
29711 ++static __inline__ unsigned int
29712 ++rhash(const uid_t uid, const __u16 type, const unsigned int sz)
29713 ++{
29714 ++ return (((uid << type) + (uid ^ type)) % sz);
29715 ++}
29716 ++
29717 ++ static __inline__ unsigned int
29718 ++shash(const struct acl_subject_label *userp, const unsigned int sz)
29719 ++{
29720 ++ return ((const unsigned long)userp % sz);
29721 ++}
29722 ++
29723 ++static __inline__ unsigned int
29724 ++fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
29725 ++{
29726 ++ return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
29727 ++}
29728 ++
29729 ++static __inline__ unsigned int
29730 ++nhash(const char *name, const __u16 len, const unsigned int sz)
29731 ++{
29732 ++ return full_name_hash(name, len) % sz;
29733 ++}
29734 ++
29735 ++#define FOR_EACH_ROLE_START(role,iter) \
29736 ++ role = NULL; \
29737 ++ iter = 0; \
29738 ++ while (iter < acl_role_set.r_size) { \
29739 ++ if (role == NULL) \
29740 ++ role = acl_role_set.r_hash[iter]; \
29741 ++ if (role == NULL) { \
29742 ++ iter++; \
29743 ++ continue; \
29744 ++ }
29745 ++
29746 ++#define FOR_EACH_ROLE_END(role,iter) \
29747 ++ role = role->next; \
29748 ++ if (role == NULL) \
29749 ++ iter++; \
29750 ++ }
29751 ++
29752 ++#define FOR_EACH_SUBJECT_START(role,subj,iter) \
29753 ++ subj = NULL; \
29754 ++ iter = 0; \
29755 ++ while (iter < role->subj_hash_size) { \
29756 ++ if (subj == NULL) \
29757 ++ subj = role->subj_hash[iter]; \
29758 ++ if (subj == NULL) { \
29759 ++ iter++; \
29760 ++ continue; \
29761 ++ }
29762 ++
29763 ++#define FOR_EACH_SUBJECT_END(subj,iter) \
29764 ++ subj = subj->next; \
29765 ++ if (subj == NULL) \
29766 ++ iter++; \
29767 ++ }
29768 ++
29769 ++
29770 ++#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
29771 ++ subj = role->hash->first; \
29772 ++ while (subj != NULL) {
29773 ++
29774 ++#define FOR_EACH_NESTED_SUBJECT_END(subj) \
29775 ++ subj = subj->next; \
29776 ++ }
29777 ++
29778 ++#endif
29779 ++
29780 +diff -urNp linux-2.6.28.8/include/linux/gralloc.h linux-2.6.28.8/include/linux/gralloc.h
29781 +--- linux-2.6.28.8/include/linux/gralloc.h 1969-12-31 19:00:00.000000000 -0500
29782 ++++ linux-2.6.28.8/include/linux/gralloc.h 2009-02-21 09:37:49.000000000 -0500
29783 +@@ -0,0 +1,8 @@
29784 ++#ifndef __GRALLOC_H
29785 ++#define __GRALLOC_H
29786 ++
29787 ++void acl_free_all(void);
29788 ++int acl_alloc_stack_init(unsigned long size);
29789 ++void *acl_alloc(unsigned long len);
29790 ++
29791 ++#endif
29792 +diff -urNp linux-2.6.28.8/include/linux/grdefs.h linux-2.6.28.8/include/linux/grdefs.h
29793 +--- linux-2.6.28.8/include/linux/grdefs.h 1969-12-31 19:00:00.000000000 -0500
29794 ++++ linux-2.6.28.8/include/linux/grdefs.h 2009-02-21 09:37:49.000000000 -0500
29795 +@@ -0,0 +1,131 @@
29796 ++#ifndef GRDEFS_H
29797 ++#define GRDEFS_H
29798 ++
29799 ++/* Begin grsecurity status declarations */
29800 ++
29801 ++enum {
29802 ++ GR_READY = 0x01,
29803 ++ GR_STATUS_INIT = 0x00 // disabled state
29804 ++};
29805 ++
29806 ++/* Begin ACL declarations */
29807 ++
29808 ++/* Role flags */
29809 ++
29810 ++enum {
29811 ++ GR_ROLE_USER = 0x0001,
29812 ++ GR_ROLE_GROUP = 0x0002,
29813 ++ GR_ROLE_DEFAULT = 0x0004,
29814 ++ GR_ROLE_SPECIAL = 0x0008,
29815 ++ GR_ROLE_AUTH = 0x0010,
29816 ++ GR_ROLE_NOPW = 0x0020,
29817 ++ GR_ROLE_GOD = 0x0040,
29818 ++ GR_ROLE_LEARN = 0x0080,
29819 ++ GR_ROLE_TPE = 0x0100,
29820 ++ GR_ROLE_DOMAIN = 0x0200,
29821 ++ GR_ROLE_PAM = 0x0400
29822 ++};
29823 ++
29824 ++/* ACL Subject and Object mode flags */
29825 ++enum {
29826 ++ GR_DELETED = 0x80000000
29827 ++};
29828 ++
29829 ++/* ACL Object-only mode flags */
29830 ++enum {
29831 ++ GR_READ = 0x00000001,
29832 ++ GR_APPEND = 0x00000002,
29833 ++ GR_WRITE = 0x00000004,
29834 ++ GR_EXEC = 0x00000008,
29835 ++ GR_FIND = 0x00000010,
29836 ++ GR_INHERIT = 0x00000020,
29837 ++ GR_SETID = 0x00000040,
29838 ++ GR_CREATE = 0x00000080,
29839 ++ GR_DELETE = 0x00000100,
29840 ++ GR_LINK = 0x00000200,
29841 ++ GR_AUDIT_READ = 0x00000400,
29842 ++ GR_AUDIT_APPEND = 0x00000800,
29843 ++ GR_AUDIT_WRITE = 0x00001000,
29844 ++ GR_AUDIT_EXEC = 0x00002000,
29845 ++ GR_AUDIT_FIND = 0x00004000,
29846 ++ GR_AUDIT_INHERIT= 0x00008000,
29847 ++ GR_AUDIT_SETID = 0x00010000,
29848 ++ GR_AUDIT_CREATE = 0x00020000,
29849 ++ GR_AUDIT_DELETE = 0x00040000,
29850 ++ GR_AUDIT_LINK = 0x00080000,
29851 ++ GR_PTRACERD = 0x00100000,
29852 ++ GR_NOPTRACE = 0x00200000,
29853 ++ GR_SUPPRESS = 0x00400000,
29854 ++ GR_NOLEARN = 0x00800000
29855 ++};
29856 ++
29857 ++#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
29858 ++ GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
29859 ++ GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
29860 ++
29861 ++/* ACL subject-only mode flags */
29862 ++enum {
29863 ++ GR_KILL = 0x00000001,
29864 ++ GR_VIEW = 0x00000002,
29865 ++ GR_PROTECTED = 0x00000004,
29866 ++ GR_LEARN = 0x00000008,
29867 ++ GR_OVERRIDE = 0x00000010,
29868 ++ /* just a placeholder, this mode is only used in userspace */
29869 ++ GR_DUMMY = 0x00000020,
29870 ++ GR_PROTSHM = 0x00000040,
29871 ++ GR_KILLPROC = 0x00000080,
29872 ++ GR_KILLIPPROC = 0x00000100,
29873 ++ /* just a placeholder, this mode is only used in userspace */
29874 ++ GR_NOTROJAN = 0x00000200,
29875 ++ GR_PROTPROCFD = 0x00000400,
29876 ++ GR_PROCACCT = 0x00000800,
29877 ++ GR_RELAXPTRACE = 0x00001000,
29878 ++ GR_NESTED = 0x00002000,
29879 ++ GR_INHERITLEARN = 0x00004000,
29880 ++ GR_PROCFIND = 0x00008000,
29881 ++ GR_POVERRIDE = 0x00010000,
29882 ++ GR_KERNELAUTH = 0x00020000,
29883 ++};
29884 ++
29885 ++enum {
29886 ++ GR_PAX_ENABLE_SEGMEXEC = 0x0001,
29887 ++ GR_PAX_ENABLE_PAGEEXEC = 0x0002,
29888 ++ GR_PAX_ENABLE_MPROTECT = 0x0004,
29889 ++ GR_PAX_ENABLE_RANDMMAP = 0x0008,
29890 ++ GR_PAX_ENABLE_EMUTRAMP = 0x0010,
29891 ++ GR_PAX_DISABLE_SEGMEXEC = 0x0100,
29892 ++ GR_PAX_DISABLE_PAGEEXEC = 0x0200,
29893 ++ GR_PAX_DISABLE_MPROTECT = 0x0400,
29894 ++ GR_PAX_DISABLE_RANDMMAP = 0x0800,
29895 ++ GR_PAX_DISABLE_EMUTRAMP = 0x1000,
29896 ++};
29897 ++
29898 ++enum {
29899 ++ GR_ID_USER = 0x01,
29900 ++ GR_ID_GROUP = 0x02,
29901 ++};
29902 ++
29903 ++enum {
29904 ++ GR_ID_ALLOW = 0x01,
29905 ++ GR_ID_DENY = 0x02,
29906 ++};
29907 ++
29908 ++#define GR_CRASH_RES 11
29909 ++#define GR_UIDTABLE_MAX 500
29910 ++
29911 ++/* begin resource learning section */
29912 ++enum {
29913 ++ GR_RLIM_CPU_BUMP = 60,
29914 ++ GR_RLIM_FSIZE_BUMP = 50000,
29915 ++ GR_RLIM_DATA_BUMP = 10000,
29916 ++ GR_RLIM_STACK_BUMP = 1000,
29917 ++ GR_RLIM_CORE_BUMP = 10000,
29918 ++ GR_RLIM_RSS_BUMP = 500000,
29919 ++ GR_RLIM_NPROC_BUMP = 1,
29920 ++ GR_RLIM_NOFILE_BUMP = 5,
29921 ++ GR_RLIM_MEMLOCK_BUMP = 50000,
29922 ++ GR_RLIM_AS_BUMP = 500000,
29923 ++ GR_RLIM_LOCKS_BUMP = 2
29924 ++};
29925 ++
29926 ++#endif
29927 +diff -urNp linux-2.6.28.8/include/linux/grinternal.h linux-2.6.28.8/include/linux/grinternal.h
29928 +--- linux-2.6.28.8/include/linux/grinternal.h 1969-12-31 19:00:00.000000000 -0500
29929 ++++ linux-2.6.28.8/include/linux/grinternal.h 2009-02-21 09:37:49.000000000 -0500
29930 +@@ -0,0 +1,210 @@
29931 ++#ifndef __GRINTERNAL_H
29932 ++#define __GRINTERNAL_H
29933 ++
29934 ++#ifdef CONFIG_GRKERNSEC
29935 ++
29936 ++#include <linux/fs.h>
29937 ++#include <linux/gracl.h>
29938 ++#include <linux/grdefs.h>
29939 ++#include <linux/grmsg.h>
29940 ++
29941 ++void gr_add_learn_entry(const char *fmt, ...);
29942 ++__u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
29943 ++ const struct vfsmount *mnt);
29944 ++__u32 gr_check_create(const struct dentry *new_dentry,
29945 ++ const struct dentry *parent,
29946 ++ const struct vfsmount *mnt, const __u32 mode);
29947 ++int gr_check_protected_task(const struct task_struct *task);
29948 ++__u32 to_gr_audit(const __u32 reqmode);
29949 ++int gr_set_acls(const int type);
29950 ++
29951 ++int gr_acl_is_enabled(void);
29952 ++char gr_roletype_to_char(void);
29953 ++
29954 ++void gr_handle_alertkill(struct task_struct *task);
29955 ++char *gr_to_filename(const struct dentry *dentry,
29956 ++ const struct vfsmount *mnt);
29957 ++char *gr_to_filename1(const struct dentry *dentry,
29958 ++ const struct vfsmount *mnt);
29959 ++char *gr_to_filename2(const struct dentry *dentry,
29960 ++ const struct vfsmount *mnt);
29961 ++char *gr_to_filename3(const struct dentry *dentry,
29962 ++ const struct vfsmount *mnt);
29963 ++
29964 ++extern int grsec_enable_link;
29965 ++extern int grsec_enable_fifo;
29966 ++extern int grsec_enable_execve;
29967 ++extern int grsec_enable_shm;
29968 ++extern int grsec_enable_execlog;
29969 ++extern int grsec_enable_signal;
29970 ++extern int grsec_enable_forkfail;
29971 ++extern int grsec_enable_time;
29972 ++extern int grsec_enable_chroot_shmat;
29973 ++extern int grsec_enable_chroot_findtask;
29974 ++extern int grsec_enable_chroot_mount;
29975 ++extern int grsec_enable_chroot_double;
29976 ++extern int grsec_enable_chroot_pivot;
29977 ++extern int grsec_enable_chroot_chdir;
29978 ++extern int grsec_enable_chroot_chmod;
29979 ++extern int grsec_enable_chroot_mknod;
29980 ++extern int grsec_enable_chroot_fchdir;
29981 ++extern int grsec_enable_chroot_nice;
29982 ++extern int grsec_enable_chroot_execlog;
29983 ++extern int grsec_enable_chroot_caps;
29984 ++extern int grsec_enable_chroot_sysctl;
29985 ++extern int grsec_enable_chroot_unix;
29986 ++extern int grsec_enable_tpe;
29987 ++extern int grsec_tpe_gid;
29988 ++extern int grsec_enable_tpe_all;
29989 ++extern int grsec_enable_sidcaps;
29990 ++extern int grsec_enable_socket_all;
29991 ++extern int grsec_socket_all_gid;
29992 ++extern int grsec_enable_socket_client;
29993 ++extern int grsec_socket_client_gid;
29994 ++extern int grsec_enable_socket_server;
29995 ++extern int grsec_socket_server_gid;
29996 ++extern int grsec_audit_gid;
29997 ++extern int grsec_enable_group;
29998 ++extern int grsec_enable_audit_ipc;
29999 ++extern int grsec_enable_audit_textrel;
30000 ++extern int grsec_enable_mount;
30001 ++extern int grsec_enable_chdir;
30002 ++extern int grsec_resource_logging;
30003 ++extern int grsec_lock;
30004 ++
30005 ++extern spinlock_t grsec_alert_lock;
30006 ++extern unsigned long grsec_alert_wtime;
30007 ++extern unsigned long grsec_alert_fyet;
30008 ++
30009 ++extern spinlock_t grsec_audit_lock;
30010 ++
30011 ++extern rwlock_t grsec_exec_file_lock;
30012 ++
30013 ++#define gr_task_fullpath(tsk) (tsk->exec_file ? \
30014 ++ gr_to_filename2(tsk->exec_file->f_path.dentry, \
30015 ++ tsk->exec_file->f_vfsmnt) : "/")
30016 ++
30017 ++#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
30018 ++ gr_to_filename3(tsk->parent->exec_file->f_path.dentry, \
30019 ++ tsk->parent->exec_file->f_vfsmnt) : "/")
30020 ++
30021 ++#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
30022 ++ gr_to_filename(tsk->exec_file->f_path.dentry, \
30023 ++ tsk->exec_file->f_vfsmnt) : "/")
30024 ++
30025 ++#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
30026 ++ gr_to_filename1(tsk->parent->exec_file->f_path.dentry, \
30027 ++ tsk->parent->exec_file->f_vfsmnt) : "/")
30028 ++
30029 ++#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
30030 ++ ((tsk_a->fs->root.dentry->d_inode->i_sb->s_dev != \
30031 ++ tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_sb->s_dev) || \
30032 ++ (tsk_a->fs->root.dentry->d_inode->i_ino != \
30033 ++ tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_ino)))
30034 ++
30035 ++#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
30036 ++ (tsk_a->fs->root.dentry->d_inode->i_sb->s_dev == \
30037 ++ tsk_b->fs->root.dentry->d_inode->i_sb->s_dev) && \
30038 ++ (tsk_a->fs->root.dentry->d_inode->i_ino == \
30039 ++ tsk_b->fs->root.dentry->d_inode->i_ino))
30040 ++
30041 ++#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
30042 ++ task->pid, task->uid, \
30043 ++ task->euid, task->gid, task->egid, \
30044 ++ gr_parent_task_fullpath(task), \
30045 ++ task->parent->comm, task->parent->pid, \
30046 ++ task->parent->uid, task->parent->euid, \
30047 ++ task->parent->gid, task->parent->egid
30048 ++
30049 ++#define GR_CHROOT_CAPS {{ \
30050 ++ CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
30051 ++ CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
30052 ++ CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
30053 ++ CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
30054 ++ CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
30055 ++ CAP_TO_MASK(CAP_IPC_OWNER) , 0 }}
30056 ++
30057 ++#define security_learn(normal_msg,args...) \
30058 ++({ \
30059 ++ read_lock(&grsec_exec_file_lock); \
30060 ++ gr_add_learn_entry(normal_msg "\n", ## args); \
30061 ++ read_unlock(&grsec_exec_file_lock); \
30062 ++})
30063 ++
30064 ++enum {
30065 ++ GR_DO_AUDIT,
30066 ++ GR_DONT_AUDIT,
30067 ++ GR_DONT_AUDIT_GOOD
30068 ++};
30069 ++
30070 ++enum {
30071 ++ GR_TTYSNIFF,
30072 ++ GR_RBAC,
30073 ++ GR_RBAC_STR,
30074 ++ GR_STR_RBAC,
30075 ++ GR_RBAC_MODE2,
30076 ++ GR_RBAC_MODE3,
30077 ++ GR_FILENAME,
30078 ++ GR_SYSCTL_HIDDEN,
30079 ++ GR_NOARGS,
30080 ++ GR_ONE_INT,
30081 ++ GR_ONE_INT_TWO_STR,
30082 ++ GR_ONE_STR,
30083 ++ GR_STR_INT,
30084 ++ GR_TWO_INT,
30085 ++ GR_THREE_INT,
30086 ++ GR_FIVE_INT_TWO_STR,
30087 ++ GR_TWO_STR,
30088 ++ GR_THREE_STR,
30089 ++ GR_FOUR_STR,
30090 ++ GR_STR_FILENAME,
30091 ++ GR_FILENAME_STR,
30092 ++ GR_FILENAME_TWO_INT,
30093 ++ GR_FILENAME_TWO_INT_STR,
30094 ++ GR_TEXTREL,
30095 ++ GR_PTRACE,
30096 ++ GR_RESOURCE,
30097 ++ GR_CAP,
30098 ++ GR_SIG,
30099 ++ GR_CRASH1,
30100 ++ GR_CRASH2,
30101 ++ GR_PSACCT
30102 ++};
30103 ++
30104 ++#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str)
30105 ++#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
30106 ++#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
30107 ++#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
30108 ++#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
30109 ++#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
30110 ++#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)
30111 ++#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
30112 ++#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
30113 ++#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
30114 ++#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
30115 ++#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
30116 ++#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
30117 ++#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
30118 ++#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
30119 ++#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)
30120 ++#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
30121 ++#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
30122 ++#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
30123 ++#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
30124 ++#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
30125 ++#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
30126 ++#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)
30127 ++#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
30128 ++#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
30129 ++#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
30130 ++#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
30131 ++#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
30132 ++#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
30133 ++#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
30134 ++#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)
30135 ++
30136 ++void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
30137 ++
30138 ++#endif
30139 ++
30140 ++#endif
30141 +diff -urNp linux-2.6.28.8/include/linux/grmsg.h linux-2.6.28.8/include/linux/grmsg.h
30142 +--- linux-2.6.28.8/include/linux/grmsg.h 1969-12-31 19:00:00.000000000 -0500
30143 ++++ linux-2.6.28.8/include/linux/grmsg.h 2009-02-21 09:37:49.000000000 -0500
30144 +@@ -0,0 +1,108 @@
30145 ++#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"
30146 ++#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"
30147 ++#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
30148 ++#define GR_STOPMOD_MSG "denied modification of module state by "
30149 ++#define GR_IOPERM_MSG "denied use of ioperm() by "
30150 ++#define GR_IOPL_MSG "denied use of iopl() by "
30151 ++#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
30152 ++#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
30153 ++#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
30154 ++#define GR_KMEM_MSG "denied write of /dev/kmem by "
30155 ++#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
30156 ++#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
30157 ++#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
30158 ++#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
30159 ++#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"
30160 ++#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"
30161 ++#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
30162 ++#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
30163 ++#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
30164 ++#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
30165 ++#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
30166 ++#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
30167 ++#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
30168 ++#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
30169 ++#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
30170 ++#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
30171 ++#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
30172 ++#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
30173 ++#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
30174 ++#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
30175 ++#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
30176 ++#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
30177 ++#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
30178 ++#define GR_NPROC_MSG "denied overstep of process limit by "
30179 ++#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
30180 ++#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
30181 ++#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
30182 ++#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
30183 ++#define GR_MOUNT_CHROOT_MSG "denied mount of %.256s as %.930s from chroot by "
30184 ++#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
30185 ++#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
30186 ++#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
30187 ++#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
30188 ++#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
30189 ++#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
30190 ++#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
30191 ++#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
30192 ++#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
30193 ++#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
30194 ++#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
30195 ++#define GR_INITF_ACL_MSG "init_variables() failed %s by "
30196 ++#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"
30197 ++#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
30198 ++#define GR_SHUTS_ACL_MSG "shutdown auth success for "
30199 ++#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
30200 ++#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
30201 ++#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
30202 ++#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
30203 ++#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
30204 ++#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
30205 ++#define GR_ENABLEF_ACL_MSG "unable to load %s for "
30206 ++#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
30207 ++#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
30208 ++#define GR_RELOADF_ACL_MSG "failed reload of %s for "
30209 ++#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
30210 ++#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
30211 ++#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
30212 ++#define GR_SPROLEF_ACL_MSG "special role %s failure for "
30213 ++#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
30214 ++#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
30215 ++#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
30216 ++#define GR_INVMODE_ACL_MSG "invalid mode %d by "
30217 ++#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
30218 ++#define GR_FAILFORK_MSG "failed fork with errno %d by "
30219 ++#define GR_NICE_CHROOT_MSG "denied priority change by "
30220 ++#define GR_UNISIGLOG_MSG "signal %d sent to "
30221 ++#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
30222 ++#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
30223 ++#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
30224 ++#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
30225 ++#define GR_TIME_MSG "time set by "
30226 ++#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
30227 ++#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
30228 ++#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
30229 ++#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
30230 ++#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
30231 ++#define GR_BIND_MSG "denied bind() by "
30232 ++#define GR_CONNECT_MSG "denied connect() by "
30233 ++#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
30234 ++#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
30235 ++#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"
30236 ++#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
30237 ++#define GR_CAP_ACL_MSG "use of %s denied for "
30238 ++#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
30239 ++#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
30240 ++#define GR_REMOUNT_AUDIT_MSG "remount of %.256s by "
30241 ++#define GR_UNMOUNT_AUDIT_MSG "unmount of %.256s by "
30242 ++#define GR_MOUNT_AUDIT_MSG "mount of %.256s to %.256s by "
30243 ++#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
30244 ++#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
30245 ++#define GR_MSGQ_AUDIT_MSG "message queue created by "
30246 ++#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
30247 ++#define GR_SEM_AUDIT_MSG "semaphore created by "
30248 ++#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
30249 ++#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
30250 ++#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
30251 ++#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
30252 ++#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
30253 +diff -urNp linux-2.6.28.8/include/linux/grsecurity.h linux-2.6.28.8/include/linux/grsecurity.h
30254 +--- linux-2.6.28.8/include/linux/grsecurity.h 1969-12-31 19:00:00.000000000 -0500
30255 ++++ linux-2.6.28.8/include/linux/grsecurity.h 2009-02-21 09:37:49.000000000 -0500
30256 +@@ -0,0 +1,200 @@
30257 ++#ifndef GR_SECURITY_H
30258 ++#define GR_SECURITY_H
30259 ++#include <linux/fs.h>
30260 ++#include <linux/binfmts.h>
30261 ++#include <linux/gracl.h>
30262 ++
30263 ++/* notify of brain-dead configs */
30264 ++#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC)
30265 ++#error "CONFIG_PAX_NOEXEC enabled, but PAGEEXEC, SEGMEXEC, and KERNEXEC are disabled."
30266 ++#endif
30267 ++#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
30268 ++#error "CONFIG_PAX_NOEXEC enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
30269 ++#endif
30270 ++#if defined(CONFIG_PAX_ASLR) && (defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
30271 ++#error "CONFIG_PAX_ASLR enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
30272 ++#endif
30273 ++#if defined(CONFIG_PAX_ASLR) && !defined(CONFIG_PAX_RANDKSTACK) && !defined(CONFIG_PAX_RANDUSTACK) && !defined(CONFIG_PAX_RANDMMAP)
30274 ++#error "CONFIG_PAX_ASLR enabled, but RANDKSTACK, RANDUSTACK, and RANDMMAP are disabled."
30275 ++#endif
30276 ++#if defined(CONFIG_PAX) && !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_ASLR)
30277 ++#error "CONFIG_PAX enabled, but no PaX options are enabled."
30278 ++#endif
30279 ++
30280 ++void gr_handle_brute_attach(struct task_struct *p);
30281 ++void gr_handle_brute_check(void);
30282 ++
30283 ++char gr_roletype_to_char(void);
30284 ++
30285 ++int gr_check_user_change(int real, int effective, int fs);
30286 ++int gr_check_group_change(int real, int effective, int fs);
30287 ++
30288 ++void gr_del_task_from_ip_table(struct task_struct *p);
30289 ++
30290 ++int gr_pid_is_chrooted(struct task_struct *p);
30291 ++int gr_handle_chroot_nice(void);
30292 ++int gr_handle_chroot_sysctl(const int op);
30293 ++int gr_handle_chroot_setpriority(struct task_struct *p,
30294 ++ const int niceval);
30295 ++int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
30296 ++int gr_handle_chroot_chroot(const struct dentry *dentry,
30297 ++ const struct vfsmount *mnt);
30298 ++void gr_handle_chroot_caps(struct task_struct *task);
30299 ++void gr_handle_chroot_chdir(struct path *path);
30300 ++int gr_handle_chroot_chmod(const struct dentry *dentry,
30301 ++ const struct vfsmount *mnt, const int mode);
30302 ++int gr_handle_chroot_mknod(const struct dentry *dentry,
30303 ++ const struct vfsmount *mnt, const int mode);
30304 ++int gr_handle_chroot_mount(const struct dentry *dentry,
30305 ++ const struct vfsmount *mnt,
30306 ++ const char *dev_name);
30307 ++int gr_handle_chroot_pivot(void);
30308 ++int gr_handle_chroot_unix(const pid_t pid);
30309 ++
30310 ++int gr_handle_rawio(const struct inode *inode);
30311 ++int gr_handle_nproc(void);
30312 ++
30313 ++void gr_handle_ioperm(void);
30314 ++void gr_handle_iopl(void);
30315 ++
30316 ++int gr_tpe_allow(const struct file *file);
30317 ++
30318 ++int gr_random_pid(void);
30319 ++
30320 ++void gr_log_forkfail(const int retval);
30321 ++void gr_log_timechange(void);
30322 ++void gr_log_signal(const int sig, const struct task_struct *t);
30323 ++void gr_log_chdir(const struct dentry *dentry,
30324 ++ const struct vfsmount *mnt);
30325 ++void gr_log_chroot_exec(const struct dentry *dentry,
30326 ++ const struct vfsmount *mnt);
30327 ++void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
30328 ++void gr_log_remount(const char *devname, const int retval);
30329 ++void gr_log_unmount(const char *devname, const int retval);
30330 ++void gr_log_mount(const char *from, const char *to, const int retval);
30331 ++void gr_log_msgget(const int ret, const int msgflg);
30332 ++void gr_log_msgrm(const uid_t uid, const uid_t cuid);
30333 ++void gr_log_semget(const int err, const int semflg);
30334 ++void gr_log_semrm(const uid_t uid, const uid_t cuid);
30335 ++void gr_log_shmget(const int err, const int shmflg, const size_t size);
30336 ++void gr_log_shmrm(const uid_t uid, const uid_t cuid);
30337 ++void gr_log_textrel(struct vm_area_struct *vma);
30338 ++
30339 ++int gr_handle_follow_link(const struct inode *parent,
30340 ++ const struct inode *inode,
30341 ++ const struct dentry *dentry,
30342 ++ const struct vfsmount *mnt);
30343 ++int gr_handle_fifo(const struct dentry *dentry,
30344 ++ const struct vfsmount *mnt,
30345 ++ const struct dentry *dir, const int flag,
30346 ++ const int acc_mode);
30347 ++int gr_handle_hardlink(const struct dentry *dentry,
30348 ++ const struct vfsmount *mnt,
30349 ++ struct inode *inode,
30350 ++ const int mode, const char *to);
30351 ++
30352 ++int gr_task_is_capable(struct task_struct *task, const int cap);
30353 ++int gr_is_capable_nolog(const int cap);
30354 ++void gr_learn_resource(const struct task_struct *task, const int limit,
30355 ++ const unsigned long wanted, const int gt);
30356 ++void gr_copy_label(struct task_struct *tsk);
30357 ++void gr_handle_crash(struct task_struct *task, const int sig);
30358 ++int gr_handle_signal(const struct task_struct *p, const int sig);
30359 ++int gr_check_crash_uid(const uid_t uid);
30360 ++int gr_check_protected_task(const struct task_struct *task);
30361 ++int gr_acl_handle_mmap(const struct file *file,
30362 ++ const unsigned long prot);
30363 ++int gr_acl_handle_mprotect(const struct file *file,
30364 ++ const unsigned long prot);
30365 ++int gr_check_hidden_task(const struct task_struct *tsk);
30366 ++__u32 gr_acl_handle_truncate(const struct dentry *dentry,
30367 ++ const struct vfsmount *mnt);
30368 ++__u32 gr_acl_handle_utime(const struct dentry *dentry,
30369 ++ const struct vfsmount *mnt);
30370 ++__u32 gr_acl_handle_access(const struct dentry *dentry,
30371 ++ const struct vfsmount *mnt, const int fmode);
30372 ++__u32 gr_acl_handle_fchmod(const struct dentry *dentry,
30373 ++ const struct vfsmount *mnt, mode_t mode);
30374 ++__u32 gr_acl_handle_chmod(const struct dentry *dentry,
30375 ++ const struct vfsmount *mnt, mode_t mode);
30376 ++__u32 gr_acl_handle_chown(const struct dentry *dentry,
30377 ++ const struct vfsmount *mnt);
30378 ++int gr_handle_ptrace(struct task_struct *task, const long request);
30379 ++int gr_handle_proc_ptrace(struct task_struct *task);
30380 ++__u32 gr_acl_handle_execve(const struct dentry *dentry,
30381 ++ const struct vfsmount *mnt);
30382 ++int gr_check_crash_exec(const struct file *filp);
30383 ++int gr_acl_is_enabled(void);
30384 ++void gr_set_kernel_label(struct task_struct *task);
30385 ++void gr_set_role_label(struct task_struct *task, const uid_t uid,
30386 ++ const gid_t gid);
30387 ++int gr_set_proc_label(const struct dentry *dentry,
30388 ++ const struct vfsmount *mnt);
30389 ++__u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
30390 ++ const struct vfsmount *mnt);
30391 ++__u32 gr_acl_handle_open(const struct dentry *dentry,
30392 ++ const struct vfsmount *mnt, const int fmode);
30393 ++__u32 gr_acl_handle_creat(const struct dentry *dentry,
30394 ++ const struct dentry *p_dentry,
30395 ++ const struct vfsmount *p_mnt, const int fmode,
30396 ++ const int imode);
30397 ++void gr_handle_create(const struct dentry *dentry,
30398 ++ const struct vfsmount *mnt);
30399 ++__u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
30400 ++ const struct dentry *parent_dentry,
30401 ++ const struct vfsmount *parent_mnt,
30402 ++ const int mode);
30403 ++__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
30404 ++ const struct dentry *parent_dentry,
30405 ++ const struct vfsmount *parent_mnt);
30406 ++__u32 gr_acl_handle_rmdir(const struct dentry *dentry,
30407 ++ const struct vfsmount *mnt);
30408 ++void gr_handle_delete(const ino_t ino, const dev_t dev);
30409 ++__u32 gr_acl_handle_unlink(const struct dentry *dentry,
30410 ++ const struct vfsmount *mnt);
30411 ++__u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
30412 ++ const struct dentry *parent_dentry,
30413 ++ const struct vfsmount *parent_mnt,
30414 ++ const char *from);
30415 ++__u32 gr_acl_handle_link(const struct dentry *new_dentry,
30416 ++ const struct dentry *parent_dentry,
30417 ++ const struct vfsmount *parent_mnt,
30418 ++ const struct dentry *old_dentry,
30419 ++ const struct vfsmount *old_mnt, const char *to);
30420 ++int gr_acl_handle_rename(struct dentry *new_dentry,
30421 ++ struct dentry *parent_dentry,
30422 ++ const struct vfsmount *parent_mnt,
30423 ++ struct dentry *old_dentry,
30424 ++ struct inode *old_parent_inode,
30425 ++ struct vfsmount *old_mnt, const char *newname);
30426 ++void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
30427 ++ struct dentry *old_dentry,
30428 ++ struct dentry *new_dentry,
30429 ++ struct vfsmount *mnt, const __u8 replace);
30430 ++__u32 gr_check_link(const struct dentry *new_dentry,
30431 ++ const struct dentry *parent_dentry,
30432 ++ const struct vfsmount *parent_mnt,
30433 ++ const struct dentry *old_dentry,
30434 ++ const struct vfsmount *old_mnt);
30435 ++int gr_acl_handle_filldir(const struct file *file, const char *name,
30436 ++ const unsigned int namelen, const ino_t ino);
30437 ++
30438 ++__u32 gr_acl_handle_unix(const struct dentry *dentry,
30439 ++ const struct vfsmount *mnt);
30440 ++void gr_acl_handle_exit(void);
30441 ++void gr_acl_handle_psacct(struct task_struct *task, const long code);
30442 ++int gr_acl_handle_procpidmem(const struct task_struct *task);
30443 ++
30444 ++#ifdef CONFIG_GRKERNSEC
30445 ++void gr_handle_mem_write(void);
30446 ++void gr_handle_kmem_write(void);
30447 ++void gr_handle_open_port(void);
30448 ++int gr_handle_mem_mmap(const unsigned long offset,
30449 ++ struct vm_area_struct *vma);
30450 ++
30451 ++extern int grsec_enable_dmesg;
30452 ++extern int grsec_enable_randsrc;
30453 ++extern int grsec_enable_shm;
30454 ++#endif
30455 ++
30456 ++#endif
30457 +diff -urNp linux-2.6.28.8/include/linux/highmem.h linux-2.6.28.8/include/linux/highmem.h
30458 +--- linux-2.6.28.8/include/linux/highmem.h 2009-02-06 16:47:45.000000000 -0500
30459 ++++ linux-2.6.28.8/include/linux/highmem.h 2009-03-07 10:35:39.000000000 -0500
30460 +@@ -124,6 +124,18 @@ static inline void clear_highpage(struct
30461 + kunmap_atomic(kaddr, KM_USER0);
30462 + }
30463 +
30464 ++static inline void sanitize_highpage(struct page *page)
30465 ++{
30466 ++ void *kaddr;
30467 ++ unsigned long flags;
30468 ++
30469 ++ local_irq_save(flags);
30470 ++ kaddr = kmap_atomic(page, KM_CLEARPAGE);
30471 ++ clear_page(kaddr);
30472 ++ kunmap_atomic(kaddr, KM_CLEARPAGE);
30473 ++ local_irq_restore(flags);
30474 ++}
30475 ++
30476 + static inline void zero_user_segments(struct page *page,
30477 + unsigned start1, unsigned end1,
30478 + unsigned start2, unsigned end2)
30479 +diff -urNp linux-2.6.28.8/include/linux/jbd2.h linux-2.6.28.8/include/linux/jbd2.h
30480 +--- linux-2.6.28.8/include/linux/jbd2.h 2009-03-07 10:24:49.000000000 -0500
30481 ++++ linux-2.6.28.8/include/linux/jbd2.h 2009-03-07 10:29:51.000000000 -0500
30482 +@@ -66,7 +66,7 @@ extern u8 jbd2_journal_enable_debug;
30483 + } \
30484 + } while (0)
30485 + #else
30486 +-#define jbd_debug(f, a...) /**/
30487 ++#define jbd_debug(f, a...) do {} while (0)
30488 + #endif
30489 +
30490 + static inline void *jbd2_alloc(size_t size, gfp_t flags)
30491 +diff -urNp linux-2.6.28.8/include/linux/jbd.h linux-2.6.28.8/include/linux/jbd.h
30492 +--- linux-2.6.28.8/include/linux/jbd.h 2009-02-06 16:47:45.000000000 -0500
30493 ++++ linux-2.6.28.8/include/linux/jbd.h 2009-02-21 09:37:49.000000000 -0500
30494 +@@ -66,7 +66,7 @@ extern u8 journal_enable_debug;
30495 + } \
30496 + } while (0)
30497 + #else
30498 +-#define jbd_debug(f, a...) /**/
30499 ++#define jbd_debug(f, a...) do {} while (0)
30500 + #endif
30501 +
30502 + static inline void *jbd_alloc(size_t size, gfp_t flags)
30503 +diff -urNp linux-2.6.28.8/include/linux/kvm_host.h linux-2.6.28.8/include/linux/kvm_host.h
30504 +--- linux-2.6.28.8/include/linux/kvm_host.h 2009-02-06 16:47:45.000000000 -0500
30505 ++++ linux-2.6.28.8/include/linux/kvm_host.h 2009-02-21 09:37:49.000000000 -0500
30506 +@@ -150,7 +150,7 @@ void kvm_vcpu_uninit(struct kvm_vcpu *vc
30507 + void vcpu_load(struct kvm_vcpu *vcpu);
30508 + void vcpu_put(struct kvm_vcpu *vcpu);
30509 +
30510 +-int kvm_init(void *opaque, unsigned int vcpu_size,
30511 ++int kvm_init(const void *opaque, unsigned int vcpu_size,
30512 + struct module *module);
30513 + void kvm_exit(void);
30514 +
30515 +@@ -258,7 +258,7 @@ int kvm_arch_vcpu_ioctl_debug_guest(stru
30516 + struct kvm_debug_guest *dbg);
30517 + int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run);
30518 +
30519 +-int kvm_arch_init(void *opaque);
30520 ++int kvm_arch_init(const void *opaque);
30521 + void kvm_arch_exit(void);
30522 +
30523 + int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu);
30524 +diff -urNp linux-2.6.28.8/include/linux/libata.h linux-2.6.28.8/include/linux/libata.h
30525 +--- linux-2.6.28.8/include/linux/libata.h 2009-02-06 16:47:45.000000000 -0500
30526 ++++ linux-2.6.28.8/include/linux/libata.h 2009-02-21 09:37:49.000000000 -0500
30527 +@@ -64,11 +64,11 @@
30528 + #ifdef ATA_VERBOSE_DEBUG
30529 + #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args)
30530 + #else
30531 +-#define VPRINTK(fmt, args...)
30532 ++#define VPRINTK(fmt, args...) do {} while (0)
30533 + #endif /* ATA_VERBOSE_DEBUG */
30534 + #else
30535 +-#define DPRINTK(fmt, args...)
30536 +-#define VPRINTK(fmt, args...)
30537 ++#define DPRINTK(fmt, args...) do {} while (0)
30538 ++#define VPRINTK(fmt, args...) do {} while (0)
30539 + #endif /* ATA_DEBUG */
30540 +
30541 + #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __func__, ## args)
30542 +diff -urNp linux-2.6.28.8/include/linux/mm.h linux-2.6.28.8/include/linux/mm.h
30543 +--- linux-2.6.28.8/include/linux/mm.h 2009-03-07 10:24:49.000000000 -0500
30544 ++++ linux-2.6.28.8/include/linux/mm.h 2009-03-07 10:29:51.000000000 -0500
30545 +@@ -39,6 +39,7 @@ extern unsigned long mmap_min_addr;
30546 + #include <asm/page.h>
30547 + #include <asm/pgtable.h>
30548 + #include <asm/processor.h>
30549 ++#include <asm/mman.h>
30550 +
30551 + #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
30552 +
30553 +@@ -115,6 +116,10 @@ extern unsigned int kobjsize(const void
30554 + #define VM_MIXEDMAP 0x10000000 /* Can contain "struct page" and pure PFN pages */
30555 + #define VM_SAO 0x20000000 /* Strong Access Ordering (powerpc) */
30556 +
30557 ++#ifdef CONFIG_PAX_PAGEEXEC
30558 ++#define VM_PAGEEXEC 0x40000000 /* vma->vm_page_prot needs special handling */
30559 ++#endif
30560 ++
30561 + #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
30562 + #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
30563 + #endif
30564 +@@ -873,6 +878,8 @@ struct shrinker {
30565 + extern void register_shrinker(struct shrinker *);
30566 + extern void unregister_shrinker(struct shrinker *);
30567 +
30568 ++pgprot_t vm_get_page_prot(unsigned long vm_flags);
30569 ++
30570 + int vma_wants_writenotify(struct vm_area_struct *vma);
30571 +
30572 + extern pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl);
30573 +@@ -1141,6 +1148,7 @@ out:
30574 + }
30575 +
30576 + extern int do_munmap(struct mm_struct *, unsigned long, size_t);
30577 ++extern int __do_munmap(struct mm_struct *, unsigned long, size_t);
30578 +
30579 + extern unsigned long do_brk(unsigned long, unsigned long);
30580 +
30581 +@@ -1193,6 +1201,10 @@ extern struct vm_area_struct * find_vma(
30582 + extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
30583 + struct vm_area_struct **pprev);
30584 +
30585 ++extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma);
30586 ++extern void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma);
30587 ++extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl);
30588 ++
30589 + /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
30590 + NULL if none. Assume start_addr < end_addr. */
30591 + static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
30592 +@@ -1209,7 +1221,6 @@ static inline unsigned long vma_pages(st
30593 + return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
30594 + }
30595 +
30596 +-pgprot_t vm_get_page_prot(unsigned long vm_flags);
30597 + struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
30598 + int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
30599 + unsigned long pfn, unsigned long size, pgprot_t);
30600 +@@ -1298,5 +1309,11 @@ int vmemmap_populate_basepages(struct pa
30601 + int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
30602 + void vmemmap_populate_print_last(void);
30603 +
30604 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
30605 ++extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
30606 ++#else
30607 ++static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
30608 ++#endif
30609 ++
30610 + #endif /* __KERNEL__ */
30611 + #endif /* _LINUX_MM_H */
30612 +diff -urNp linux-2.6.28.8/include/linux/mm_types.h linux-2.6.28.8/include/linux/mm_types.h
30613 +--- linux-2.6.28.8/include/linux/mm_types.h 2009-02-06 16:47:45.000000000 -0500
30614 ++++ linux-2.6.28.8/include/linux/mm_types.h 2009-02-21 09:37:49.000000000 -0500
30615 +@@ -157,6 +157,8 @@ struct vm_area_struct {
30616 + #ifdef CONFIG_NUMA
30617 + struct mempolicy *vm_policy; /* NUMA policy for the VMA */
30618 + #endif
30619 ++
30620 ++ struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */
30621 + };
30622 +
30623 + struct core_thread {
30624 +@@ -256,6 +258,24 @@ struct mm_struct {
30625 + #ifdef CONFIG_MMU_NOTIFIER
30626 + struct mmu_notifier_mm *mmu_notifier_mm;
30627 + #endif
30628 ++
30629 ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
30630 ++ unsigned long pax_flags;
30631 ++#endif
30632 ++
30633 ++#ifdef CONFIG_PAX_DLRESOLVE
30634 ++ unsigned long call_dl_resolve;
30635 ++#endif
30636 ++
30637 ++#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
30638 ++ unsigned long call_syscall;
30639 ++#endif
30640 ++
30641 ++#ifdef CONFIG_PAX_ASLR
30642 ++ unsigned long delta_mmap; /* randomized offset */
30643 ++ unsigned long delta_stack; /* randomized offset */
30644 ++#endif
30645 ++
30646 + };
30647 +
30648 + #endif /* _LINUX_MM_TYPES_H */
30649 +diff -urNp linux-2.6.28.8/include/linux/module.h linux-2.6.28.8/include/linux/module.h
30650 +--- linux-2.6.28.8/include/linux/module.h 2009-02-07 16:10:45.000000000 -0500
30651 ++++ linux-2.6.28.8/include/linux/module.h 2009-02-21 09:37:49.000000000 -0500
30652 +@@ -283,16 +283,16 @@ struct module
30653 + int (*init)(void);
30654 +
30655 + /* If this is non-NULL, vfree after init() returns */
30656 +- void *module_init;
30657 ++ void *module_init_rx, *module_init_rw;
30658 +
30659 + /* Here is the actual code + data, vfree'd on unload. */
30660 +- void *module_core;
30661 ++ void *module_core_rx, *module_core_rw;
30662 +
30663 + /* Here are the sizes of the init and core sections */
30664 +- unsigned int init_size, core_size;
30665 ++ unsigned int init_size_rw, core_size_rw;
30666 +
30667 + /* The size of the executable code in each section. */
30668 +- unsigned int init_text_size, core_text_size;
30669 ++ unsigned int init_size_rx, core_size_rx;
30670 +
30671 + /* The handle returned from unwind_add_table. */
30672 + void *unwind_info;
30673 +diff -urNp linux-2.6.28.8/include/linux/moduleloader.h linux-2.6.28.8/include/linux/moduleloader.h
30674 +--- linux-2.6.28.8/include/linux/moduleloader.h 2009-02-06 16:47:45.000000000 -0500
30675 ++++ linux-2.6.28.8/include/linux/moduleloader.h 2009-02-21 09:37:49.000000000 -0500
30676 +@@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
30677 + sections. Returns NULL on failure. */
30678 + void *module_alloc(unsigned long size);
30679 +
30680 ++#ifdef CONFIG_PAX_KERNEXEC
30681 ++void *module_alloc_exec(unsigned long size);
30682 ++#else
30683 ++#define module_alloc_exec(x) module_alloc(x)
30684 ++#endif
30685 ++
30686 + /* Free memory returned from module_alloc. */
30687 + void module_free(struct module *mod, void *module_region);
30688 +
30689 ++#ifdef CONFIG_PAX_KERNEXEC
30690 ++void module_free_exec(struct module *mod, void *module_region);
30691 ++#else
30692 ++#define module_free_exec(x, y) module_free(x, y)
30693 ++#endif
30694 ++
30695 + /* Apply the given relocation to the (simplified) ELF. Return -error
30696 + or 0. */
30697 + int apply_relocate(Elf_Shdr *sechdrs,
30698 +diff -urNp linux-2.6.28.8/include/linux/namei.h linux-2.6.28.8/include/linux/namei.h
30699 +--- linux-2.6.28.8/include/linux/namei.h 2009-02-06 16:47:45.000000000 -0500
30700 ++++ linux-2.6.28.8/include/linux/namei.h 2009-02-21 09:37:49.000000000 -0500
30701 +@@ -21,7 +21,7 @@ struct nameidata {
30702 + unsigned int flags;
30703 + int last_type;
30704 + unsigned depth;
30705 +- char *saved_names[MAX_NESTED_LINKS + 1];
30706 ++ const char *saved_names[MAX_NESTED_LINKS + 1];
30707 +
30708 + /* Intent data */
30709 + union {
30710 +@@ -84,12 +84,12 @@ extern int follow_up(struct vfsmount **,
30711 + extern struct dentry *lock_rename(struct dentry *, struct dentry *);
30712 + extern void unlock_rename(struct dentry *, struct dentry *);
30713 +
30714 +-static inline void nd_set_link(struct nameidata *nd, char *path)
30715 ++static inline void nd_set_link(struct nameidata *nd, const char *path)
30716 + {
30717 + nd->saved_names[nd->depth] = path;
30718 + }
30719 +
30720 +-static inline char *nd_get_link(struct nameidata *nd)
30721 ++static inline const char *nd_get_link(struct nameidata *nd)
30722 + {
30723 + return nd->saved_names[nd->depth];
30724 + }
30725 +diff -urNp linux-2.6.28.8/include/linux/nodemask.h linux-2.6.28.8/include/linux/nodemask.h
30726 +--- linux-2.6.28.8/include/linux/nodemask.h 2009-02-06 16:47:45.000000000 -0500
30727 ++++ linux-2.6.28.8/include/linux/nodemask.h 2009-02-21 09:37:49.000000000 -0500
30728 +@@ -442,11 +442,11 @@ static inline int num_node_state(enum no
30729 +
30730 + #define any_online_node(mask) \
30731 + ({ \
30732 +- int node; \
30733 +- for_each_node_mask(node, (mask)) \
30734 +- if (node_online(node)) \
30735 ++ int __node; \
30736 ++ for_each_node_mask(__node, (mask)) \
30737 ++ if (node_online(__node)) \
30738 + break; \
30739 +- node; \
30740 ++ __node; \
30741 + })
30742 +
30743 + #define num_online_nodes() num_node_state(N_ONLINE)
30744 +diff -urNp linux-2.6.28.8/include/linux/percpu.h linux-2.6.28.8/include/linux/percpu.h
30745 +--- linux-2.6.28.8/include/linux/percpu.h 2009-02-06 16:47:45.000000000 -0500
30746 ++++ linux-2.6.28.8/include/linux/percpu.h 2009-02-21 09:37:49.000000000 -0500
30747 +@@ -50,7 +50,7 @@
30748 + #endif
30749 +
30750 + #define PERCPU_ENOUGH_ROOM \
30751 +- (__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE)
30752 ++ ((unsigned long)(__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE))
30753 + #endif /* PERCPU_ENOUGH_ROOM */
30754 +
30755 + /*
30756 +diff -urNp linux-2.6.28.8/include/linux/poison.h linux-2.6.28.8/include/linux/poison.h
30757 +--- linux-2.6.28.8/include/linux/poison.h 2009-02-06 16:47:45.000000000 -0500
30758 ++++ linux-2.6.28.8/include/linux/poison.h 2009-02-21 09:37:49.000000000 -0500
30759 +@@ -7,8 +7,8 @@
30760 + * under normal circumstances, used to verify that nobody uses
30761 + * non-initialized list entries.
30762 + */
30763 +-#define LIST_POISON1 ((void *) 0x00100100)
30764 +-#define LIST_POISON2 ((void *) 0x00200200)
30765 ++#define LIST_POISON1 ((void *) 0xFF1001FFFF1001FFULL)
30766 ++#define LIST_POISON2 ((void *) 0xFF2002FFFF2002FFULL)
30767 +
30768 + /********** include/linux/timer.h **********/
30769 + /*
30770 +diff -urNp linux-2.6.28.8/include/linux/proc_fs.h linux-2.6.28.8/include/linux/proc_fs.h
30771 +--- linux-2.6.28.8/include/linux/proc_fs.h 2009-02-06 16:47:45.000000000 -0500
30772 ++++ linux-2.6.28.8/include/linux/proc_fs.h 2009-02-21 09:37:49.000000000 -0500
30773 +@@ -174,6 +174,19 @@ static inline struct proc_dir_entry *pro
30774 + return proc_create_data(name, mode, parent, proc_fops, NULL);
30775 + }
30776 +
30777 ++static inline struct proc_dir_entry *proc_create_grsec(const char *name, mode_t mode,
30778 ++ struct proc_dir_entry *parent, const struct file_operations *proc_fops)
30779 ++{
30780 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
30781 ++ return proc_create_data(name, S_IRUSR, parent, proc_fops, NULL);
30782 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
30783 ++ return proc_create_data(name, S_IRUSR | S_IRGRP, parent, proc_fops, NULL);
30784 ++#else
30785 ++ return proc_create_data(name, mode, parent, proc_fops, NULL);
30786 ++#endif
30787 ++}
30788 ++
30789 ++
30790 + static inline struct proc_dir_entry *create_proc_read_entry(const char *name,
30791 + mode_t mode, struct proc_dir_entry *base,
30792 + read_proc_t *read_proc, void * data)
30793 +diff -urNp linux-2.6.28.8/include/linux/random.h linux-2.6.28.8/include/linux/random.h
30794 +--- linux-2.6.28.8/include/linux/random.h 2009-02-06 16:47:45.000000000 -0500
30795 ++++ linux-2.6.28.8/include/linux/random.h 2009-02-21 09:37:49.000000000 -0500
30796 +@@ -72,6 +72,11 @@ unsigned long randomize_range(unsigned l
30797 + u32 random32(void);
30798 + void srandom32(u32 seed);
30799 +
30800 ++static inline unsigned long pax_get_random_long(void)
30801 ++{
30802 ++ return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0);
30803 ++}
30804 ++
30805 + #endif /* __KERNEL___ */
30806 +
30807 + #endif /* _LINUX_RANDOM_H */
30808 +diff -urNp linux-2.6.28.8/include/linux/sched.h linux-2.6.28.8/include/linux/sched.h
30809 +--- linux-2.6.28.8/include/linux/sched.h 2009-02-06 16:47:45.000000000 -0500
30810 ++++ linux-2.6.28.8/include/linux/sched.h 2009-02-21 09:37:49.000000000 -0500
30811 +@@ -96,6 +96,7 @@ struct exec_domain;
30812 + struct futex_pi_state;
30813 + struct robust_list_head;
30814 + struct bio;
30815 ++struct linux_binprm;
30816 +
30817 + /*
30818 + * List of flags we want to share for kernel threads,
30819 +@@ -588,6 +589,15 @@ struct signal_struct {
30820 + unsigned audit_tty;
30821 + struct tty_audit_buf *tty_audit_buf;
30822 + #endif
30823 ++
30824 ++#ifdef CONFIG_GRKERNSEC
30825 ++ u32 curr_ip;
30826 ++ u32 gr_saddr;
30827 ++ u32 gr_daddr;
30828 ++ u16 gr_sport;
30829 ++ u16 gr_dport;
30830 ++ u8 used_accept:1;
30831 ++#endif
30832 + };
30833 +
30834 + /* Context switch must be unlocked if interrupts are to be enabled */
30835 +@@ -1073,7 +1083,7 @@ struct sched_rt_entity {
30836 +
30837 + struct task_struct {
30838 + volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
30839 +- void *stack;
30840 ++ struct thread_info *stack;
30841 + atomic_t usage;
30842 + unsigned int flags; /* per process flags, defined below */
30843 + unsigned int ptrace;
30844 +@@ -1138,10 +1148,9 @@ struct task_struct {
30845 + pid_t pid;
30846 + pid_t tgid;
30847 +
30848 +-#ifdef CONFIG_CC_STACKPROTECTOR
30849 + /* Canary value for the -fstack-protector gcc feature */
30850 + unsigned long stack_canary;
30851 +-#endif
30852 ++
30853 + /*
30854 + * pointers to (original) parent process, youngest child, younger sibling,
30855 + * older sibling, respectively. (p->father can be replaced with
30856 +@@ -1169,8 +1178,8 @@ struct task_struct {
30857 + struct list_head thread_group;
30858 +
30859 + struct completion *vfork_done; /* for vfork() */
30860 +- int __user *set_child_tid; /* CLONE_CHILD_SETTID */
30861 +- int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
30862 ++ pid_t __user *set_child_tid; /* CLONE_CHILD_SETTID */
30863 ++ pid_t __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
30864 +
30865 + cputime_t utime, stime, utimescaled, stimescaled;
30866 + cputime_t gtime;
30867 +@@ -1355,8 +1364,64 @@ struct task_struct {
30868 + unsigned long default_timer_slack_ns;
30869 +
30870 + struct list_head *scm_work_list;
30871 ++
30872 ++#ifdef CONFIG_GRKERNSEC
30873 ++ /* grsecurity */
30874 ++ struct acl_subject_label *acl;
30875 ++ struct acl_role_label *role;
30876 ++ struct file *exec_file;
30877 ++ u16 acl_role_id;
30878 ++ u8 acl_sp_role;
30879 ++ u8 is_writable;
30880 ++ u8 brute;
30881 ++#endif
30882 ++
30883 + };
30884 +
30885 ++#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
30886 ++#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
30887 ++#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
30888 ++#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
30889 ++/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */
30890 ++#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
30891 ++
30892 ++#ifdef CONFIG_PAX_SOFTMODE
30893 ++extern unsigned int pax_softmode;
30894 ++#endif
30895 ++
30896 ++extern int pax_check_flags(unsigned long *);
30897 ++
30898 ++/* if tsk != current then task_lock must be held on it */
30899 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
30900 ++static inline unsigned long pax_get_flags(struct task_struct *tsk)
30901 ++{
30902 ++ if (likely(tsk->mm))
30903 ++ return tsk->mm->pax_flags;
30904 ++ else
30905 ++ return 0UL;
30906 ++}
30907 ++
30908 ++/* if tsk != current then task_lock must be held on it */
30909 ++static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
30910 ++{
30911 ++ if (likely(tsk->mm)) {
30912 ++ tsk->mm->pax_flags = flags;
30913 ++ return 0;
30914 ++ }
30915 ++ return -EINVAL;
30916 ++}
30917 ++#endif
30918 ++
30919 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
30920 ++extern void pax_set_initial_flags(struct linux_binprm *bprm);
30921 ++#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
30922 ++extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
30923 ++#endif
30924 ++
30925 ++void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
30926 ++void pax_report_insns(void *pc, void *sp);
30927 ++void pax_report_refcount_overflow(struct pt_regs *regs);
30928 ++
30929 + /*
30930 + * Priority of a process goes from 0..MAX_PRIO-1, valid RT
30931 + * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
30932 +@@ -1899,7 +1964,7 @@ extern void __cleanup_sighand(struct sig
30933 + extern void exit_itimers(struct signal_struct *);
30934 + extern void flush_itimer_signals(void);
30935 +
30936 +-extern NORET_TYPE void do_group_exit(int);
30937 ++extern NORET_TYPE void do_group_exit(int) ATTRIB_NORET;
30938 +
30939 + extern void daemonize(const char *, ...);
30940 + extern int allow_signal(int);
30941 +@@ -2002,8 +2067,8 @@ static inline void unlock_task_sighand(s
30942 +
30943 + #ifndef __HAVE_THREAD_FUNCTIONS
30944 +
30945 +-#define task_thread_info(task) ((struct thread_info *)(task)->stack)
30946 +-#define task_stack_page(task) ((task)->stack)
30947 ++#define task_thread_info(task) ((task)->stack)
30948 ++#define task_stack_page(task) ((void *)(task)->stack)
30949 +
30950 + static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
30951 + {
30952 +diff -urNp linux-2.6.28.8/include/linux/screen_info.h linux-2.6.28.8/include/linux/screen_info.h
30953 +--- linux-2.6.28.8/include/linux/screen_info.h 2009-02-06 16:47:45.000000000 -0500
30954 ++++ linux-2.6.28.8/include/linux/screen_info.h 2009-02-21 09:37:49.000000000 -0500
30955 +@@ -42,7 +42,8 @@ struct screen_info {
30956 + __u16 pages; /* 0x32 */
30957 + __u16 vesa_attributes; /* 0x34 */
30958 + __u32 capabilities; /* 0x36 */
30959 +- __u8 _reserved[6]; /* 0x3a */
30960 ++ __u16 vesapm_size; /* 0x3a */
30961 ++ __u8 _reserved[4]; /* 0x3c */
30962 + } __attribute__((packed));
30963 +
30964 + #define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
30965 +diff -urNp linux-2.6.28.8/include/linux/security.h linux-2.6.28.8/include/linux/security.h
30966 +--- linux-2.6.28.8/include/linux/security.h 2009-02-06 16:47:45.000000000 -0500
30967 ++++ linux-2.6.28.8/include/linux/security.h 2009-02-21 09:37:49.000000000 -0500
30968 +@@ -32,6 +32,7 @@
30969 + #include <linux/sched.h>
30970 + #include <linux/key.h>
30971 + #include <linux/xfrm.h>
30972 ++#include <linux/grsecurity.h>
30973 + #include <net/flow.h>
30974 +
30975 + /* Maximum number of letters for an LSM name string */
30976 +diff -urNp linux-2.6.28.8/include/linux/shm.h linux-2.6.28.8/include/linux/shm.h
30977 +--- linux-2.6.28.8/include/linux/shm.h 2009-02-06 16:47:45.000000000 -0500
30978 ++++ linux-2.6.28.8/include/linux/shm.h 2009-02-21 09:37:49.000000000 -0500
30979 +@@ -95,6 +95,10 @@ struct shmid_kernel /* private to the ke
30980 + pid_t shm_cprid;
30981 + pid_t shm_lprid;
30982 + struct user_struct *mlock_user;
30983 ++#ifdef CONFIG_GRKERNSEC
30984 ++ time_t shm_createtime;
30985 ++ pid_t shm_lapid;
30986 ++#endif
30987 + };
30988 +
30989 + /* shm_mode upper byte flags */
30990 +diff -urNp linux-2.6.28.8/include/linux/slab.h linux-2.6.28.8/include/linux/slab.h
30991 +--- linux-2.6.28.8/include/linux/slab.h 2009-02-06 16:47:45.000000000 -0500
30992 ++++ linux-2.6.28.8/include/linux/slab.h 2009-02-21 09:37:49.000000000 -0500
30993 +@@ -73,10 +73,9 @@
30994 + * ZERO_SIZE_PTR can be passed to kfree though in the same way that NULL can.
30995 + * Both make kfree a no-op.
30996 + */
30997 +-#define ZERO_SIZE_PTR ((void *)16)
30998 ++#define ZERO_SIZE_PTR ((void *)-1024L)
30999 +
31000 +-#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= \
31001 +- (unsigned long)ZERO_SIZE_PTR)
31002 ++#define ZERO_OR_NULL_PTR(x) (!(x) || (x) == ZERO_SIZE_PTR)
31003 +
31004 + /*
31005 + * struct kmem_cache related prototypes
31006 +diff -urNp linux-2.6.28.8/include/linux/sysctl.h linux-2.6.28.8/include/linux/sysctl.h
31007 +--- linux-2.6.28.8/include/linux/sysctl.h 2009-02-06 16:47:45.000000000 -0500
31008 ++++ linux-2.6.28.8/include/linux/sysctl.h 2009-02-21 09:37:49.000000000 -0500
31009 +@@ -165,7 +165,11 @@ enum
31010 + KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
31011 + };
31012 +
31013 +-
31014 ++#ifdef CONFIG_PAX_SOFTMODE
31015 ++enum {
31016 ++ PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */
31017 ++};
31018 ++#endif
31019 +
31020 + /* CTL_VM names: */
31021 + enum
31022 +diff -urNp linux-2.6.28.8/include/linux/thread_info.h linux-2.6.28.8/include/linux/thread_info.h
31023 +--- linux-2.6.28.8/include/linux/thread_info.h 2009-02-06 16:47:45.000000000 -0500
31024 ++++ linux-2.6.28.8/include/linux/thread_info.h 2009-02-21 09:37:49.000000000 -0500
31025 +@@ -23,7 +23,7 @@ struct restart_block {
31026 + };
31027 + /* For futex_wait */
31028 + struct {
31029 +- u32 *uaddr;
31030 ++ u32 __user *uaddr;
31031 + u32 val;
31032 + u32 flags;
31033 + u32 bitset;
31034 +diff -urNp linux-2.6.28.8/include/linux/uaccess.h linux-2.6.28.8/include/linux/uaccess.h
31035 +--- linux-2.6.28.8/include/linux/uaccess.h 2009-02-06 16:47:45.000000000 -0500
31036 ++++ linux-2.6.28.8/include/linux/uaccess.h 2009-02-21 09:37:49.000000000 -0500
31037 +@@ -76,11 +76,11 @@ static inline unsigned long __copy_from_
31038 + long ret; \
31039 + mm_segment_t old_fs = get_fs(); \
31040 + \
31041 +- set_fs(KERNEL_DS); \
31042 + pagefault_disable(); \
31043 ++ set_fs(KERNEL_DS); \
31044 + ret = __get_user(retval, (__force typeof(retval) __user *)(addr)); \
31045 +- pagefault_enable(); \
31046 + set_fs(old_fs); \
31047 ++ pagefault_enable(); \
31048 + ret; \
31049 + })
31050 +
31051 +diff -urNp linux-2.6.28.8/include/linux/vmalloc.h linux-2.6.28.8/include/linux/vmalloc.h
31052 +--- linux-2.6.28.8/include/linux/vmalloc.h 2009-02-06 16:47:45.000000000 -0500
31053 ++++ linux-2.6.28.8/include/linux/vmalloc.h 2009-02-21 09:37:49.000000000 -0500
31054 +@@ -13,6 +13,11 @@ struct vm_area_struct; /* vma defining
31055 + #define VM_MAP 0x00000004 /* vmap()ed pages */
31056 + #define VM_USERMAP 0x00000008 /* suitable for remap_vmalloc_range */
31057 + #define VM_VPAGES 0x00000010 /* buffer for pages was vmalloc'ed */
31058 ++
31059 ++#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
31060 ++#define VM_KERNEXEC 0x00000020 /* allocate from executable kernel memory range */
31061 ++#endif
31062 ++
31063 + /* bits [20..32] reserved for arch specific ioremap internals */
31064 +
31065 + /*
31066 +diff -urNp linux-2.6.28.8/include/net/sctp/sctp.h linux-2.6.28.8/include/net/sctp/sctp.h
31067 +--- linux-2.6.28.8/include/net/sctp/sctp.h 2009-02-06 16:47:45.000000000 -0500
31068 ++++ linux-2.6.28.8/include/net/sctp/sctp.h 2009-02-21 09:37:49.000000000 -0500
31069 +@@ -309,8 +309,8 @@ extern int sctp_debug_flag;
31070 +
31071 + #else /* SCTP_DEBUG */
31072 +
31073 +-#define SCTP_DEBUG_PRINTK(whatever...)
31074 +-#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
31075 ++#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
31076 ++#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
31077 + #define SCTP_ENABLE_DEBUG
31078 + #define SCTP_DISABLE_DEBUG
31079 + #define SCTP_ASSERT(expr, str, func)
31080 +diff -urNp linux-2.6.28.8/include/sound/core.h linux-2.6.28.8/include/sound/core.h
31081 +--- linux-2.6.28.8/include/sound/core.h 2009-02-06 16:47:45.000000000 -0500
31082 ++++ linux-2.6.28.8/include/sound/core.h 2009-02-21 09:37:49.000000000 -0500
31083 +@@ -405,7 +405,7 @@ static inline int __snd_bug_on(void)
31084 + */
31085 + #define snd_printdd(format, args...) snd_printk(format, ##args)
31086 + #else
31087 +-#define snd_printdd(format, args...) /* nothing */
31088 ++#define snd_printdd(format, args...) do {} while (0)
31089 + #endif
31090 +
31091 +
31092 +diff -urNp linux-2.6.28.8/include/video/uvesafb.h linux-2.6.28.8/include/video/uvesafb.h
31093 +--- linux-2.6.28.8/include/video/uvesafb.h 2009-02-06 16:47:45.000000000 -0500
31094 ++++ linux-2.6.28.8/include/video/uvesafb.h 2009-02-21 09:37:49.000000000 -0500
31095 +@@ -175,6 +175,7 @@ struct uvesafb_par {
31096 + u8 ypan; /* 0 - nothing, 1 - ypan, 2 - ywrap */
31097 + u8 pmi_setpal; /* PMI for palette changes */
31098 + u16 *pmi_base; /* protected mode interface location */
31099 ++ u8 *pmi_code; /* protected mode code location */
31100 + void *pmi_start;
31101 + void *pmi_pal;
31102 + u8 *vbe_state_orig; /*
31103 +diff -urNp linux-2.6.28.8/init/do_mounts.c linux-2.6.28.8/init/do_mounts.c
31104 +--- linux-2.6.28.8/init/do_mounts.c 2009-02-06 16:47:45.000000000 -0500
31105 ++++ linux-2.6.28.8/init/do_mounts.c 2009-02-21 09:37:49.000000000 -0500
31106 +@@ -214,11 +214,11 @@ static void __init get_fs_names(char *pa
31107 +
31108 + static int __init do_mount_root(char *name, char *fs, int flags, void *data)
31109 + {
31110 +- int err = sys_mount(name, "/root", fs, flags, data);
31111 ++ int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data);
31112 + if (err)
31113 + return err;
31114 +
31115 +- sys_chdir("/root");
31116 ++ sys_chdir((char __user *)"/root");
31117 + ROOT_DEV = current->fs->pwd.mnt->mnt_sb->s_dev;
31118 + printk("VFS: Mounted root (%s filesystem)%s.\n",
31119 + current->fs->pwd.mnt->mnt_sb->s_type->name,
31120 +@@ -308,18 +308,18 @@ void __init change_floppy(char *fmt, ...
31121 + va_start(args, fmt);
31122 + vsprintf(buf, fmt, args);
31123 + va_end(args);
31124 +- fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
31125 ++ fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
31126 + if (fd >= 0) {
31127 + sys_ioctl(fd, FDEJECT, 0);
31128 + sys_close(fd);
31129 + }
31130 + printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
31131 +- fd = sys_open("/dev/console", O_RDWR, 0);
31132 ++ fd = sys_open((char __user *)"/dev/console", O_RDWR, 0);
31133 + if (fd >= 0) {
31134 + sys_ioctl(fd, TCGETS, (long)&termios);
31135 + termios.c_lflag &= ~ICANON;
31136 + sys_ioctl(fd, TCSETSF, (long)&termios);
31137 +- sys_read(fd, &c, 1);
31138 ++ sys_read(fd, (char __user *)&c, 1);
31139 + termios.c_lflag |= ICANON;
31140 + sys_ioctl(fd, TCSETSF, (long)&termios);
31141 + sys_close(fd);
31142 +@@ -406,7 +406,7 @@ void __init prepare_namespace(void)
31143 +
31144 + mount_root();
31145 + out:
31146 +- sys_mount(".", "/", NULL, MS_MOVE, NULL);
31147 +- sys_chroot(".");
31148 ++ sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
31149 ++ sys_chroot((char __user *)".");
31150 + }
31151 +
31152 +diff -urNp linux-2.6.28.8/init/do_mounts.h linux-2.6.28.8/init/do_mounts.h
31153 +--- linux-2.6.28.8/init/do_mounts.h 2009-02-06 16:47:45.000000000 -0500
31154 ++++ linux-2.6.28.8/init/do_mounts.h 2009-02-21 09:37:49.000000000 -0500
31155 +@@ -14,15 +14,15 @@ extern int root_mountflags;
31156 +
31157 + static inline int create_dev(char *name, dev_t dev)
31158 + {
31159 +- sys_unlink(name);
31160 +- return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
31161 ++ sys_unlink((char __user *)name);
31162 ++ return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
31163 + }
31164 +
31165 + #if BITS_PER_LONG == 32
31166 + static inline u32 bstat(char *name)
31167 + {
31168 + struct stat64 stat;
31169 +- if (sys_stat64(name, &stat) != 0)
31170 ++ if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0)
31171 + return 0;
31172 + if (!S_ISBLK(stat.st_mode))
31173 + return 0;
31174 +diff -urNp linux-2.6.28.8/init/do_mounts_initrd.c linux-2.6.28.8/init/do_mounts_initrd.c
31175 +--- linux-2.6.28.8/init/do_mounts_initrd.c 2009-02-06 16:47:45.000000000 -0500
31176 ++++ linux-2.6.28.8/init/do_mounts_initrd.c 2009-02-21 09:37:49.000000000 -0500
31177 +@@ -32,7 +32,7 @@ static int __init do_linuxrc(void * shel
31178 + sys_close(old_fd);sys_close(root_fd);
31179 + sys_close(0);sys_close(1);sys_close(2);
31180 + sys_setsid();
31181 +- (void) sys_open("/dev/console",O_RDWR,0);
31182 ++ (void) sys_open((const char __user *)"/dev/console",O_RDWR,0);
31183 + (void) sys_dup(0);
31184 + (void) sys_dup(0);
31185 + return kernel_execve(shell, argv, envp_init);
31186 +@@ -47,13 +47,13 @@ static void __init handle_initrd(void)
31187 + create_dev("/dev/root.old", Root_RAM0);
31188 + /* mount initrd on rootfs' /root */
31189 + mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
31190 +- sys_mkdir("/old", 0700);
31191 +- root_fd = sys_open("/", 0, 0);
31192 +- old_fd = sys_open("/old", 0, 0);
31193 ++ sys_mkdir((const char __user *)"/old", 0700);
31194 ++ root_fd = sys_open((const char __user *)"/", 0, 0);
31195 ++ old_fd = sys_open((const char __user *)"/old", 0, 0);
31196 + /* move initrd over / and chdir/chroot in initrd root */
31197 +- sys_chdir("/root");
31198 +- sys_mount(".", "/", NULL, MS_MOVE, NULL);
31199 +- sys_chroot(".");
31200 ++ sys_chdir((const char __user *)"/root");
31201 ++ sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
31202 ++ sys_chroot((const char __user *)".");
31203 +
31204 + /*
31205 + * In case that a resume from disk is carried out by linuxrc or one of
31206 +@@ -70,15 +70,15 @@ static void __init handle_initrd(void)
31207 +
31208 + /* move initrd to rootfs' /old */
31209 + sys_fchdir(old_fd);
31210 +- sys_mount("/", ".", NULL, MS_MOVE, NULL);
31211 ++ sys_mount((char __user *)"/", (char __user *)".", NULL, MS_MOVE, NULL);
31212 + /* switch root and cwd back to / of rootfs */
31213 + sys_fchdir(root_fd);
31214 +- sys_chroot(".");
31215 ++ sys_chroot((const char __user *)".");
31216 + sys_close(old_fd);
31217 + sys_close(root_fd);
31218 +
31219 + if (new_decode_dev(real_root_dev) == Root_RAM0) {
31220 +- sys_chdir("/old");
31221 ++ sys_chdir((const char __user *)"/old");
31222 + return;
31223 + }
31224 +
31225 +@@ -86,17 +86,17 @@ static void __init handle_initrd(void)
31226 + mount_root();
31227 +
31228 + printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
31229 +- error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
31230 ++ error = sys_mount((char __user *)"/old", (char __user *)"/root/initrd", NULL, MS_MOVE, NULL);
31231 + if (!error)
31232 + printk("okay\n");
31233 + else {
31234 +- int fd = sys_open("/dev/root.old", O_RDWR, 0);
31235 ++ int fd = sys_open((const char __user *)"/dev/root.old", O_RDWR, 0);
31236 + if (error == -ENOENT)
31237 + printk("/initrd does not exist. Ignored.\n");
31238 + else
31239 + printk("failed\n");
31240 + printk(KERN_NOTICE "Unmounting old root\n");
31241 +- sys_umount("/old", MNT_DETACH);
31242 ++ sys_umount((char __user *)"/old", MNT_DETACH);
31243 + printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
31244 + if (fd < 0) {
31245 + error = fd;
31246 +@@ -119,11 +119,11 @@ int __init initrd_load(void)
31247 + * mounted in the normal path.
31248 + */
31249 + if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) {
31250 +- sys_unlink("/initrd.image");
31251 ++ sys_unlink((const char __user *)"/initrd.image");
31252 + handle_initrd();
31253 + return 1;
31254 + }
31255 + }
31256 +- sys_unlink("/initrd.image");
31257 ++ sys_unlink((const char __user *)"/initrd.image");
31258 + return 0;
31259 + }
31260 +diff -urNp linux-2.6.28.8/init/do_mounts_md.c linux-2.6.28.8/init/do_mounts_md.c
31261 +--- linux-2.6.28.8/init/do_mounts_md.c 2009-02-06 16:47:45.000000000 -0500
31262 ++++ linux-2.6.28.8/init/do_mounts_md.c 2009-02-21 09:37:49.000000000 -0500
31263 +@@ -171,7 +171,7 @@ static void __init md_setup_drive(void)
31264 + partitioned ? "_d" : "", minor,
31265 + md_setup_args[ent].device_names);
31266 +
31267 +- fd = sys_open(name, 0, 0);
31268 ++ fd = sys_open((char __user *)name, 0, 0);
31269 + if (fd < 0) {
31270 + printk(KERN_ERR "md: open failed - cannot start "
31271 + "array %s\n", name);
31272 +@@ -234,7 +234,7 @@ static void __init md_setup_drive(void)
31273 + * array without it
31274 + */
31275 + sys_close(fd);
31276 +- fd = sys_open(name, 0, 0);
31277 ++ fd = sys_open((char __user *)name, 0, 0);
31278 + sys_ioctl(fd, BLKRRPART, 0);
31279 + }
31280 + sys_close(fd);
31281 +@@ -283,7 +283,7 @@ static void autodetect_raid(void)
31282 + printk(KERN_INFO "md: If you don't use raid, use raid=noautodetect\n");
31283 + while (driver_probe_done() < 0)
31284 + msleep(100);
31285 +- fd = sys_open("/dev/md0", 0, 0);
31286 ++ fd = sys_open((char __user *)"/dev/md0", 0, 0);
31287 + if (fd >= 0) {
31288 + sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
31289 + sys_close(fd);
31290 +diff -urNp linux-2.6.28.8/init/initramfs.c linux-2.6.28.8/init/initramfs.c
31291 +--- linux-2.6.28.8/init/initramfs.c 2009-02-06 16:47:45.000000000 -0500
31292 ++++ linux-2.6.28.8/init/initramfs.c 2009-02-21 09:37:49.000000000 -0500
31293 +@@ -276,7 +276,7 @@ static int __init maybe_link(void)
31294 + if (nlink >= 2) {
31295 + char *old = find_link(major, minor, ino, mode, collected);
31296 + if (old)
31297 +- return (sys_link(old, collected) < 0) ? -1 : 1;
31298 ++ return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1;
31299 + }
31300 + return 0;
31301 + }
31302 +@@ -285,11 +285,11 @@ static void __init clean_path(char *path
31303 + {
31304 + struct stat st;
31305 +
31306 +- if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
31307 ++ if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
31308 + if (S_ISDIR(st.st_mode))
31309 +- sys_rmdir(path);
31310 ++ sys_rmdir((char __user *)path);
31311 + else
31312 +- sys_unlink(path);
31313 ++ sys_unlink((char __user *)path);
31314 + }
31315 + }
31316 +
31317 +@@ -312,7 +312,7 @@ static int __init do_name(void)
31318 + int openflags = O_WRONLY|O_CREAT;
31319 + if (ml != 1)
31320 + openflags |= O_TRUNC;
31321 +- wfd = sys_open(collected, openflags, mode);
31322 ++ wfd = sys_open((char __user *)collected, openflags, mode);
31323 +
31324 + if (wfd >= 0) {
31325 + sys_fchown(wfd, uid, gid);
31326 +@@ -322,16 +322,16 @@ static int __init do_name(void)
31327 + }
31328 + }
31329 + } else if (S_ISDIR(mode)) {
31330 +- sys_mkdir(collected, mode);
31331 +- sys_chown(collected, uid, gid);
31332 +- sys_chmod(collected, mode);
31333 ++ sys_mkdir((char __user *)collected, mode);
31334 ++ sys_chown((char __user *)collected, uid, gid);
31335 ++ sys_chmod((char __user *)collected, mode);
31336 + dir_add(collected, mtime);
31337 + } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
31338 + S_ISFIFO(mode) || S_ISSOCK(mode)) {
31339 + if (maybe_link() == 0) {
31340 +- sys_mknod(collected, mode, rdev);
31341 +- sys_chown(collected, uid, gid);
31342 +- sys_chmod(collected, mode);
31343 ++ sys_mknod((char __user *)collected, mode, rdev);
31344 ++ sys_chown((char __user *)collected, uid, gid);
31345 ++ sys_chmod((char __user *)collected, mode);
31346 + do_utime(collected, mtime);
31347 + }
31348 + }
31349 +@@ -341,7 +341,7 @@ static int __init do_name(void)
31350 + static int __init do_copy(void)
31351 + {
31352 + if (count >= body_len) {
31353 +- sys_write(wfd, victim, body_len);
31354 ++ sys_write(wfd, (char __user *)victim, body_len);
31355 + sys_close(wfd);
31356 + do_utime(vcollected, mtime);
31357 + kfree(vcollected);
31358 +@@ -349,7 +349,7 @@ static int __init do_copy(void)
31359 + state = SkipIt;
31360 + return 0;
31361 + } else {
31362 +- sys_write(wfd, victim, count);
31363 ++ sys_write(wfd, (char __user *)victim, count);
31364 + body_len -= count;
31365 + eat(count);
31366 + return 1;
31367 +@@ -360,8 +360,8 @@ static int __init do_symlink(void)
31368 + {
31369 + collected[N_ALIGN(name_len) + body_len] = '\0';
31370 + clean_path(collected, 0);
31371 +- sys_symlink(collected + N_ALIGN(name_len), collected);
31372 +- sys_lchown(collected, uid, gid);
31373 ++ sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected);
31374 ++ sys_lchown((char __user *)collected, uid, gid);
31375 + do_utime(collected, mtime);
31376 + state = SkipIt;
31377 + next_state = Reset;
31378 +diff -urNp linux-2.6.28.8/init/Kconfig linux-2.6.28.8/init/Kconfig
31379 +--- linux-2.6.28.8/init/Kconfig 2009-02-06 16:47:45.000000000 -0500
31380 ++++ linux-2.6.28.8/init/Kconfig 2009-02-21 09:37:49.000000000 -0500
31381 +@@ -572,6 +572,7 @@ config SYSCTL_SYSCALL
31382 + config KALLSYMS
31383 + bool "Load all symbols for debugging/ksymoops" if EMBEDDED
31384 + default y
31385 ++ depends on !GRKERNSEC_HIDESYM
31386 + help
31387 + Say Y here to let the kernel print out symbolic crash information and
31388 + symbolic stack backtraces. This increases the size of the kernel
31389 +@@ -822,9 +823,9 @@ config HAVE_GENERIC_DMA_COHERENT
31390 +
31391 + config SLABINFO
31392 + bool
31393 +- depends on PROC_FS
31394 ++ depends on PROC_FS && !GRKERNSEC_PROC_ADD
31395 + depends on SLAB || SLUB_DEBUG
31396 +- default y
31397 ++ default n
31398 +
31399 + config RT_MUTEXES
31400 + boolean
31401 +diff -urNp linux-2.6.28.8/init/main.c linux-2.6.28.8/init/main.c
31402 +--- linux-2.6.28.8/init/main.c 2009-02-06 16:47:45.000000000 -0500
31403 ++++ linux-2.6.28.8/init/main.c 2009-02-21 09:37:49.000000000 -0500
31404 +@@ -104,6 +104,7 @@ static inline void mark_rodata_ro(void)
31405 + #ifdef CONFIG_TC
31406 + extern void tc_init(void);
31407 + #endif
31408 ++extern void grsecurity_init(void);
31409 +
31410 + enum system_states system_state;
31411 + EXPORT_SYMBOL(system_state);
31412 +@@ -190,6 +191,40 @@ static int __init set_reset_devices(char
31413 +
31414 + __setup("reset_devices", set_reset_devices);
31415 +
31416 ++#if defined(CONFIG_PAX_MEMORY_UDEREF) && defined(CONFIG_X86_32)
31417 ++static int __init setup_pax_nouderef(char *str)
31418 ++{
31419 ++ unsigned int cpu;
31420 ++
31421 ++#ifdef CONFIG_PAX_KERNEXEC
31422 ++ unsigned long cr0;
31423 ++
31424 ++ pax_open_kernel(cr0);
31425 ++#endif
31426 ++
31427 ++ for (cpu = 0; cpu < NR_CPUS; cpu++)
31428 ++ get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_DS].b = 0x00cf9300;
31429 ++
31430 ++#ifdef CONFIG_PAX_KERNEXEC
31431 ++ pax_close_kernel(cr0);
31432 ++#endif
31433 ++
31434 ++ return 1;
31435 ++}
31436 ++__setup("pax_nouderef", setup_pax_nouderef);
31437 ++#endif
31438 ++
31439 ++#ifdef CONFIG_PAX_SOFTMODE
31440 ++unsigned int pax_softmode;
31441 ++
31442 ++static int __init setup_pax_softmode(char *str)
31443 ++{
31444 ++ get_option(&str, &pax_softmode);
31445 ++ return 1;
31446 ++}
31447 ++__setup("pax_softmode=", setup_pax_softmode);
31448 ++#endif
31449 ++
31450 + static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
31451 + char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
31452 + static const char *panic_later, *panic_param;
31453 +@@ -388,7 +423,7 @@ static void __init setup_nr_cpu_ids(void
31454 + }
31455 +
31456 + #ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
31457 +-unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
31458 ++unsigned long __per_cpu_offset[NR_CPUS] __read_only;
31459 +
31460 + EXPORT_SYMBOL(__per_cpu_offset);
31461 +
31462 +@@ -704,6 +739,7 @@ int do_one_initcall(initcall_t fn)
31463 + {
31464 + int count = preempt_count();
31465 + ktime_t delta;
31466 ++ const char *msg1 = "", *msg2 = "";
31467 + char msgbuf[64];
31468 + struct boot_trace it;
31469 +
31470 +@@ -730,15 +766,15 @@ int do_one_initcall(initcall_t fn)
31471 + sprintf(msgbuf, "error code %d ", it.result);
31472 +
31473 + if (preempt_count() != count) {
31474 +- strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf));
31475 ++ msg1 = " preemption imbalance";
31476 + preempt_count() = count;
31477 + }
31478 + if (irqs_disabled()) {
31479 +- strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf));
31480 ++ msg2 = " disabled interrupts";
31481 + local_irq_enable();
31482 + }
31483 +- if (msgbuf[0]) {
31484 +- printk("initcall %pF returned with %s\n", fn, msgbuf);
31485 ++ if (msgbuf[0] || *msg1 || *msg2) {
31486 ++ printk("initcall %pF returned with %s%s%s\n", fn, msgbuf, msg1, msg2);
31487 + }
31488 +
31489 + return it.result;
31490 +@@ -877,6 +913,8 @@ static int __init kernel_init(void * unu
31491 + prepare_namespace();
31492 + }
31493 +
31494 ++ grsecurity_init();
31495 ++
31496 + /*
31497 + * Ok, we have completed the initial bootup, and
31498 + * we're essentially up and running. Get rid of the
31499 +diff -urNp linux-2.6.28.8/init/noinitramfs.c linux-2.6.28.8/init/noinitramfs.c
31500 +--- linux-2.6.28.8/init/noinitramfs.c 2009-02-06 16:47:45.000000000 -0500
31501 ++++ linux-2.6.28.8/init/noinitramfs.c 2009-02-21 09:37:49.000000000 -0500
31502 +@@ -29,7 +29,7 @@ static int __init default_rootfs(void)
31503 + {
31504 + int err;
31505 +
31506 +- err = sys_mkdir("/dev", 0755);
31507 ++ err = sys_mkdir((const char __user *)"/dev", 0755);
31508 + if (err < 0)
31509 + goto out;
31510 +
31511 +@@ -39,7 +39,7 @@ static int __init default_rootfs(void)
31512 + if (err < 0)
31513 + goto out;
31514 +
31515 +- err = sys_mkdir("/root", 0700);
31516 ++ err = sys_mkdir((const char __user *)"/root", 0700);
31517 + if (err < 0)
31518 + goto out;
31519 +
31520 +diff -urNp linux-2.6.28.8/ipc/ipc_sysctl.c linux-2.6.28.8/ipc/ipc_sysctl.c
31521 +--- linux-2.6.28.8/ipc/ipc_sysctl.c 2009-02-06 16:47:45.000000000 -0500
31522 ++++ linux-2.6.28.8/ipc/ipc_sysctl.c 2009-02-21 09:37:49.000000000 -0500
31523 +@@ -267,7 +267,7 @@ static struct ctl_table ipc_kern_table[]
31524 + .extra1 = &zero,
31525 + .extra2 = &one,
31526 + },
31527 +- {}
31528 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
31529 + };
31530 +
31531 + static struct ctl_table ipc_root_table[] = {
31532 +@@ -277,7 +277,7 @@ static struct ctl_table ipc_root_table[]
31533 + .mode = 0555,
31534 + .child = ipc_kern_table,
31535 + },
31536 +- {}
31537 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
31538 + };
31539 +
31540 + static int __init ipc_sysctl_init(void)
31541 +diff -urNp linux-2.6.28.8/ipc/msg.c linux-2.6.28.8/ipc/msg.c
31542 +--- linux-2.6.28.8/ipc/msg.c 2009-02-06 16:47:45.000000000 -0500
31543 ++++ linux-2.6.28.8/ipc/msg.c 2009-02-21 09:37:49.000000000 -0500
31544 +@@ -314,6 +314,7 @@ SYSCALL_DEFINE2(msgget, key_t, key, int,
31545 + struct ipc_namespace *ns;
31546 + struct ipc_ops msg_ops;
31547 + struct ipc_params msg_params;
31548 ++ long err;
31549 +
31550 + ns = current->nsproxy->ipc_ns;
31551 +
31552 +@@ -324,7 +325,11 @@ SYSCALL_DEFINE2(msgget, key_t, key, int,
31553 + msg_params.key = key;
31554 + msg_params.flg = msgflg;
31555 +
31556 +- return ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
31557 ++ err = ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
31558 ++
31559 ++ gr_log_msgget(err, msgflg);
31560 ++
31561 ++ return err;
31562 + }
31563 +
31564 + static inline unsigned long
31565 +@@ -434,6 +439,7 @@ static int msgctl_down(struct ipc_namesp
31566 +
31567 + switch (cmd) {
31568 + case IPC_RMID:
31569 ++ gr_log_msgrm(ipcp->uid, ipcp->cuid);
31570 + freeque(ns, ipcp);
31571 + goto out_up;
31572 + case IPC_SET:
31573 +diff -urNp linux-2.6.28.8/ipc/sem.c linux-2.6.28.8/ipc/sem.c
31574 +--- linux-2.6.28.8/ipc/sem.c 2009-02-06 16:47:45.000000000 -0500
31575 ++++ linux-2.6.28.8/ipc/sem.c 2009-02-21 09:37:49.000000000 -0500
31576 +@@ -313,6 +313,7 @@ SYSCALL_DEFINE3(semget, key_t, key, int,
31577 + struct ipc_namespace *ns;
31578 + struct ipc_ops sem_ops;
31579 + struct ipc_params sem_params;
31580 ++ long err;
31581 +
31582 + ns = current->nsproxy->ipc_ns;
31583 +
31584 +@@ -327,7 +328,11 @@ SYSCALL_DEFINE3(semget, key_t, key, int,
31585 + sem_params.flg = semflg;
31586 + sem_params.u.nsems = nsems;
31587 +
31588 +- return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
31589 ++ err = ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
31590 ++
31591 ++ gr_log_semget(err, semflg);
31592 ++
31593 ++ return err;
31594 + }
31595 +
31596 + /*
31597 +@@ -870,6 +875,7 @@ static int semctl_down(struct ipc_namesp
31598 +
31599 + switch(cmd){
31600 + case IPC_RMID:
31601 ++ gr_log_semrm(ipcp->uid, ipcp->cuid);
31602 + freeary(ns, ipcp);
31603 + goto out_up;
31604 + case IPC_SET:
31605 +diff -urNp linux-2.6.28.8/ipc/shm.c linux-2.6.28.8/ipc/shm.c
31606 +--- linux-2.6.28.8/ipc/shm.c 2009-02-07 16:10:45.000000000 -0500
31607 ++++ linux-2.6.28.8/ipc/shm.c 2009-02-21 09:37:49.000000000 -0500
31608 +@@ -69,6 +69,14 @@ static void shm_destroy (struct ipc_name
31609 + static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
31610 + #endif
31611 +
31612 ++#ifdef CONFIG_GRKERNSEC
31613 ++extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
31614 ++ const time_t shm_createtime, const uid_t cuid,
31615 ++ const int shmid);
31616 ++extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
31617 ++ const time_t shm_createtime);
31618 ++#endif
31619 ++
31620 + void shm_init_ns(struct ipc_namespace *ns)
31621 + {
31622 + ns->shm_ctlmax = SHMMAX;
31623 +@@ -87,6 +95,8 @@ static void do_shm_rmid(struct ipc_names
31624 + struct shmid_kernel *shp;
31625 + shp = container_of(ipcp, struct shmid_kernel, shm_perm);
31626 +
31627 ++ gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
31628 ++
31629 + if (shp->shm_nattch){
31630 + shp->shm_perm.mode |= SHM_DEST;
31631 + /* Do not find it any more */
31632 +@@ -392,6 +402,14 @@ static int newseg(struct ipc_namespace *
31633 + shp->shm_lprid = 0;
31634 + shp->shm_atim = shp->shm_dtim = 0;
31635 + shp->shm_ctim = get_seconds();
31636 ++#ifdef CONFIG_GRKERNSEC
31637 ++ {
31638 ++ struct timespec timeval;
31639 ++ do_posix_clock_monotonic_gettime(&timeval);
31640 ++
31641 ++ shp->shm_createtime = timeval.tv_sec;
31642 ++ }
31643 ++#endif
31644 + shp->shm_segsz = size;
31645 + shp->shm_nattch = 0;
31646 + shp->shm_file = file;
31647 +@@ -445,6 +463,7 @@ SYSCALL_DEFINE3(shmget, key_t, key, size
31648 + struct ipc_namespace *ns;
31649 + struct ipc_ops shm_ops;
31650 + struct ipc_params shm_params;
31651 ++ long err;
31652 +
31653 + ns = current->nsproxy->ipc_ns;
31654 +
31655 +@@ -456,7 +475,11 @@ SYSCALL_DEFINE3(shmget, key_t, key, size
31656 + shm_params.flg = shmflg;
31657 + shm_params.u.size = size;
31658 +
31659 +- return ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
31660 ++ err = ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
31661 ++
31662 ++ gr_log_shmget(err, shmflg, size);
31663 ++
31664 ++ return err;
31665 + }
31666 +
31667 + static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version)
31668 +@@ -877,9 +900,21 @@ long do_shmat(int shmid, char __user *sh
31669 + if (err)
31670 + goto out_unlock;
31671 +
31672 ++#ifdef CONFIG_GRKERNSEC
31673 ++ if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
31674 ++ shp->shm_perm.cuid, shmid) ||
31675 ++ !gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
31676 ++ err = -EACCES;
31677 ++ goto out_unlock;
31678 ++ }
31679 ++#endif
31680 ++
31681 + path.dentry = dget(shp->shm_file->f_path.dentry);
31682 + path.mnt = shp->shm_file->f_path.mnt;
31683 + shp->shm_nattch++;
31684 ++#ifdef CONFIG_GRKERNSEC
31685 ++ shp->shm_lapid = current->pid;
31686 ++#endif
31687 + size = i_size_read(path.dentry->d_inode);
31688 + shm_unlock(shp);
31689 +
31690 +diff -urNp linux-2.6.28.8/kernel/acct.c linux-2.6.28.8/kernel/acct.c
31691 +--- linux-2.6.28.8/kernel/acct.c 2009-02-06 16:47:45.000000000 -0500
31692 ++++ linux-2.6.28.8/kernel/acct.c 2009-02-21 09:37:49.000000000 -0500
31693 +@@ -573,7 +573,7 @@ static void do_acct_process(struct bsd_a
31694 + */
31695 + flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
31696 + current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
31697 +- file->f_op->write(file, (char *)&ac,
31698 ++ file->f_op->write(file, (char __user *)&ac,
31699 + sizeof(acct_t), &file->f_pos);
31700 + current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
31701 + set_fs(fs);
31702 +diff -urNp linux-2.6.28.8/kernel/capability.c linux-2.6.28.8/kernel/capability.c
31703 +--- linux-2.6.28.8/kernel/capability.c 2009-02-06 16:47:45.000000000 -0500
31704 ++++ linux-2.6.28.8/kernel/capability.c 2009-02-21 09:37:49.000000000 -0500
31705 +@@ -498,10 +498,21 @@ SYSCALL_DEFINE2(capset, cap_user_header_
31706 + */
31707 + int capable(int cap)
31708 + {
31709 +- if (has_capability(current, cap)) {
31710 ++ if (has_capability(current, cap) && gr_task_is_capable(current, cap)) {
31711 + current->flags |= PF_SUPERPRIV;
31712 + return 1;
31713 + }
31714 + return 0;
31715 + }
31716 ++
31717 ++int capable_nolog(int cap)
31718 ++{
31719 ++ if (has_capability(current, cap) && gr_is_capable_nolog(cap)) {
31720 ++ current->flags |= PF_SUPERPRIV;
31721 ++ return 1;
31722 ++ }
31723 ++ return 0;
31724 ++}
31725 ++
31726 + EXPORT_SYMBOL(capable);
31727 ++EXPORT_SYMBOL(capable_nolog);
31728 +diff -urNp linux-2.6.28.8/kernel/configs.c linux-2.6.28.8/kernel/configs.c
31729 +--- linux-2.6.28.8/kernel/configs.c 2009-02-06 16:47:45.000000000 -0500
31730 ++++ linux-2.6.28.8/kernel/configs.c 2009-02-21 09:37:49.000000000 -0500
31731 +@@ -73,8 +73,19 @@ static int __init ikconfig_init(void)
31732 + struct proc_dir_entry *entry;
31733 +
31734 + /* create the current config file */
31735 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
31736 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
31737 ++ entry = proc_create("config.gz", S_IFREG | S_IRUSR, NULL,
31738 ++ &ikconfig_file_ops);
31739 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
31740 ++ entry = proc_create("config.gz", S_IFREG | S_IRUSR | S_IRGRP, NULL,
31741 ++ &ikconfig_file_ops);
31742 ++#endif
31743 ++#else
31744 + entry = proc_create("config.gz", S_IFREG | S_IRUGO, NULL,
31745 + &ikconfig_file_ops);
31746 ++#endif
31747 ++
31748 + if (!entry)
31749 + return -ENOMEM;
31750 +
31751 +diff -urNp linux-2.6.28.8/kernel/cpu.c linux-2.6.28.8/kernel/cpu.c
31752 +--- linux-2.6.28.8/kernel/cpu.c 2009-02-06 16:47:45.000000000 -0500
31753 ++++ linux-2.6.28.8/kernel/cpu.c 2009-02-21 09:37:49.000000000 -0500
31754 +@@ -40,7 +40,7 @@ EXPORT_SYMBOL(cpu_possible_map);
31755 + /* Serializes the updates to cpu_online_map, cpu_present_map */
31756 + static DEFINE_MUTEX(cpu_add_remove_lock);
31757 +
31758 +-static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain);
31759 ++static RAW_NOTIFIER_HEAD(cpu_chain);
31760 +
31761 + /* If set, cpu_up and cpu_down will return -EBUSY and do nothing.
31762 + * Should always be manipulated under cpu_add_remove_lock
31763 +diff -urNp linux-2.6.28.8/kernel/exit.c linux-2.6.28.8/kernel/exit.c
31764 +--- linux-2.6.28.8/kernel/exit.c 2009-02-06 16:47:45.000000000 -0500
31765 ++++ linux-2.6.28.8/kernel/exit.c 2009-03-07 04:29:14.000000000 -0500
31766 +@@ -53,6 +53,10 @@
31767 + #include <asm/pgtable.h>
31768 + #include <asm/mmu_context.h>
31769 +
31770 ++#ifdef CONFIG_GRKERNSEC
31771 ++extern rwlock_t grsec_exec_file_lock;
31772 ++#endif
31773 ++
31774 + static void exit_mm(struct task_struct * tsk);
31775 +
31776 + static inline int task_detached(struct task_struct *p)
31777 +@@ -163,6 +167,8 @@ void release_task(struct task_struct * p
31778 + struct task_struct *leader;
31779 + int zap_leader;
31780 + repeat:
31781 ++ gr_del_task_from_ip_table(p);
31782 ++
31783 + tracehook_prepare_release_task(p);
31784 + atomic_dec(&p->user->processes);
31785 + proc_flush_task(p);
31786 +@@ -326,11 +332,22 @@ static void reparent_to_kthreadd(void)
31787 + {
31788 + write_lock_irq(&tasklist_lock);
31789 +
31790 ++#ifdef CONFIG_GRKERNSEC
31791 ++ write_lock(&grsec_exec_file_lock);
31792 ++ if (current->exec_file) {
31793 ++ fput(current->exec_file);
31794 ++ current->exec_file = NULL;
31795 ++ }
31796 ++ write_unlock(&grsec_exec_file_lock);
31797 ++#endif
31798 ++
31799 + ptrace_unlink(current);
31800 + /* Reparent to init */
31801 + current->real_parent = current->parent = kthreadd_task;
31802 + list_move_tail(&current->sibling, &current->real_parent->children);
31803 +
31804 ++ gr_set_kernel_label(current);
31805 ++
31806 + /* Set the exit signal to SIGCHLD so we signal init on exit */
31807 + current->exit_signal = SIGCHLD;
31808 +
31809 +@@ -424,6 +441,17 @@ void daemonize(const char *name, ...)
31810 + vsnprintf(current->comm, sizeof(current->comm), name, args);
31811 + va_end(args);
31812 +
31813 ++#ifdef CONFIG_GRKERNSEC
31814 ++ write_lock(&grsec_exec_file_lock);
31815 ++ if (current->exec_file) {
31816 ++ fput(current->exec_file);
31817 ++ current->exec_file = NULL;
31818 ++ }
31819 ++ write_unlock(&grsec_exec_file_lock);
31820 ++#endif
31821 ++
31822 ++ gr_set_kernel_label(current);
31823 ++
31824 + /*
31825 + * If we were started as result of loading a module, close all of the
31826 + * user space pages. We don't need them, and if we didn't close them
31827 +@@ -1066,6 +1094,9 @@ NORET_TYPE void do_exit(long code)
31828 + tsk->exit_code = code;
31829 + taskstats_exit(tsk, group_dead);
31830 +
31831 ++ gr_acl_handle_psacct(tsk, code);
31832 ++ gr_acl_handle_exit();
31833 ++
31834 + exit_mm(tsk);
31835 +
31836 + if (group_dead)
31837 +@@ -1272,7 +1303,7 @@ static int wait_task_zombie(struct task_
31838 + if (unlikely(options & WNOWAIT)) {
31839 + uid_t uid = p->uid;
31840 + int exit_code = p->exit_code;
31841 +- int why, status;
31842 ++ int why;
31843 +
31844 + get_task_struct(p);
31845 + read_unlock(&tasklist_lock);
31846 +diff -urNp linux-2.6.28.8/kernel/fork.c linux-2.6.28.8/kernel/fork.c
31847 +--- linux-2.6.28.8/kernel/fork.c 2009-03-07 10:24:49.000000000 -0500
31848 ++++ linux-2.6.28.8/kernel/fork.c 2009-03-07 10:29:51.000000000 -0500
31849 +@@ -236,7 +236,7 @@ static struct task_struct *dup_task_stru
31850 + setup_thread_stack(tsk, orig);
31851 +
31852 + #ifdef CONFIG_CC_STACKPROTECTOR
31853 +- tsk->stack_canary = get_random_int();
31854 ++ tsk->stack_canary = pax_get_random_long();
31855 + #endif
31856 +
31857 + /* One for us, one for whoever does the "release_task()" (usually parent) */
31858 +@@ -273,8 +273,8 @@ static int dup_mmap(struct mm_struct *mm
31859 + mm->locked_vm = 0;
31860 + mm->mmap = NULL;
31861 + mm->mmap_cache = NULL;
31862 +- mm->free_area_cache = oldmm->mmap_base;
31863 +- mm->cached_hole_size = ~0UL;
31864 ++ mm->free_area_cache = oldmm->free_area_cache;
31865 ++ mm->cached_hole_size = oldmm->cached_hole_size;
31866 + mm->map_count = 0;
31867 + cpus_clear(mm->cpu_vm_mask);
31868 + mm->mm_rb = RB_ROOT;
31869 +@@ -311,6 +311,7 @@ static int dup_mmap(struct mm_struct *mm
31870 + tmp->vm_flags &= ~VM_LOCKED;
31871 + tmp->vm_mm = mm;
31872 + tmp->vm_next = NULL;
31873 ++ tmp->vm_mirror = NULL;
31874 + anon_vma_link(tmp);
31875 + file = tmp->vm_file;
31876 + if (file) {
31877 +@@ -358,6 +359,31 @@ static int dup_mmap(struct mm_struct *mm
31878 + if (retval)
31879 + goto out;
31880 + }
31881 ++
31882 ++#ifdef CONFIG_PAX_SEGMEXEC
31883 ++ if (oldmm->pax_flags & MF_PAX_SEGMEXEC) {
31884 ++ struct vm_area_struct *mpnt_m;
31885 ++
31886 ++ for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) {
31887 ++ BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm);
31888 ++
31889 ++ if (!mpnt->vm_mirror)
31890 ++ continue;
31891 ++
31892 ++ if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) {
31893 ++ BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt);
31894 ++ mpnt->vm_mirror = mpnt_m;
31895 ++ } else {
31896 ++ BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm);
31897 ++ mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror;
31898 ++ mpnt_m->vm_mirror->vm_mirror = mpnt_m;
31899 ++ mpnt->vm_mirror->vm_mirror = mpnt;
31900 ++ }
31901 ++ }
31902 ++ BUG_ON(mpnt_m);
31903 ++ }
31904 ++#endif
31905 ++
31906 + /* a new mm has just been created */
31907 + arch_dup_mmap(oldmm, mm);
31908 + retval = 0;
31909 +@@ -527,9 +553,11 @@ void mm_release(struct task_struct *tsk,
31910 + #ifdef CONFIG_FUTEX
31911 + if (unlikely(tsk->robust_list))
31912 + exit_robust_list(tsk);
31913 ++ tsk->robust_list = NULL;
31914 + #ifdef CONFIG_COMPAT
31915 + if (unlikely(tsk->compat_robust_list))
31916 + compat_exit_robust_list(tsk);
31917 ++ tsk->compat_robust_list = NULL;
31918 + #endif
31919 + #endif
31920 +
31921 +@@ -551,7 +579,7 @@ void mm_release(struct task_struct *tsk,
31922 + if (tsk->clear_child_tid
31923 + && !(tsk->flags & PF_SIGNALED)
31924 + && atomic_read(&mm->mm_users) > 1) {
31925 +- u32 __user * tidptr = tsk->clear_child_tid;
31926 ++ pid_t __user * tidptr = tsk->clear_child_tid;
31927 + tsk->clear_child_tid = NULL;
31928 +
31929 + /*
31930 +@@ -559,7 +587,7 @@ void mm_release(struct task_struct *tsk,
31931 + * not set up a proper pointer then tough luck.
31932 + */
31933 + put_user(0, tidptr);
31934 +- sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
31935 ++ sys_futex((u32 __user *)tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
31936 + }
31937 + }
31938 +
31939 +@@ -984,6 +1012,9 @@ static struct task_struct *copy_process(
31940 + DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
31941 + #endif
31942 + retval = -EAGAIN;
31943 ++
31944 ++ gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
31945 ++
31946 + if (atomic_read(&p->user->processes) >=
31947 + p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
31948 + if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
31949 +@@ -1147,6 +1178,8 @@ static struct task_struct *copy_process(
31950 + goto bad_fork_free_pid;
31951 + }
31952 +
31953 ++ gr_copy_label(p);
31954 ++
31955 + p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
31956 + /*
31957 + * Clear TID on mm_release()?
31958 +@@ -1317,6 +1350,8 @@ bad_fork_cleanup_count:
31959 + bad_fork_free:
31960 + free_task(p);
31961 + fork_out:
31962 ++ gr_log_forkfail(retval);
31963 ++
31964 + return ERR_PTR(retval);
31965 + }
31966 +
31967 +@@ -1395,6 +1430,8 @@ long do_fork(unsigned long clone_flags,
31968 + if (clone_flags & CLONE_PARENT_SETTID)
31969 + put_user(nr, parent_tidptr);
31970 +
31971 ++ gr_handle_brute_check();
31972 ++
31973 + if (clone_flags & CLONE_VFORK) {
31974 + p->vfork_done = &vfork;
31975 + init_completion(&vfork);
31976 +diff -urNp linux-2.6.28.8/kernel/futex.c linux-2.6.28.8/kernel/futex.c
31977 +--- linux-2.6.28.8/kernel/futex.c 2009-02-06 16:47:45.000000000 -0500
31978 ++++ linux-2.6.28.8/kernel/futex.c 2009-02-21 09:37:49.000000000 -0500
31979 +@@ -188,6 +188,11 @@ static int get_futex_key(u32 __user *uad
31980 + struct page *page;
31981 + int err;
31982 +
31983 ++#ifdef CONFIG_PAX_SEGMEXEC
31984 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && address >= SEGMEXEC_TASK_SIZE)
31985 ++ return -EFAULT;
31986 ++#endif
31987 ++
31988 + /*
31989 + * The futex address must be "naturally" aligned.
31990 + */
31991 +@@ -214,8 +219,8 @@ static int get_futex_key(u32 __user *uad
31992 + * The futex is hashed differently depending on whether
31993 + * it's in a shared or private mapping. So check vma first.
31994 + */
31995 +- vma = find_extend_vma(mm, address);
31996 +- if (unlikely(!vma))
31997 ++ vma = find_vma(mm, address);
31998 ++ if (unlikely(!vma || address < vma->vm_start))
31999 + return -EFAULT;
32000 +
32001 + /*
32002 +@@ -1348,7 +1353,7 @@ static int futex_wait(u32 __user *uaddr,
32003 + struct restart_block *restart;
32004 + restart = &current_thread_info()->restart_block;
32005 + restart->fn = futex_wait_restart;
32006 +- restart->futex.uaddr = (u32 *)uaddr;
32007 ++ restart->futex.uaddr = uaddr;
32008 + restart->futex.val = val;
32009 + restart->futex.time = abs_time->tv64;
32010 + restart->futex.bitset = bitset;
32011 +@@ -1908,7 +1913,7 @@ retry:
32012 + */
32013 + static inline int fetch_robust_entry(struct robust_list __user **entry,
32014 + struct robust_list __user * __user *head,
32015 +- int *pi)
32016 ++ unsigned int *pi)
32017 + {
32018 + unsigned long uentry;
32019 +
32020 +diff -urNp linux-2.6.28.8/kernel/irq/handle.c linux-2.6.28.8/kernel/irq/handle.c
32021 +--- linux-2.6.28.8/kernel/irq/handle.c 2009-02-06 16:47:45.000000000 -0500
32022 ++++ linux-2.6.28.8/kernel/irq/handle.c 2009-02-21 09:37:49.000000000 -0500
32023 +@@ -57,7 +57,8 @@ struct irq_desc irq_desc[NR_IRQS] __cach
32024 + .depth = 1,
32025 + .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
32026 + #ifdef CONFIG_SMP
32027 +- .affinity = CPU_MASK_ALL
32028 ++ .affinity = CPU_MASK_ALL,
32029 ++ .cpu = 0,
32030 + #endif
32031 + }
32032 + };
32033 +diff -urNp linux-2.6.28.8/kernel/kallsyms.c linux-2.6.28.8/kernel/kallsyms.c
32034 +--- linux-2.6.28.8/kernel/kallsyms.c 2009-02-06 16:47:45.000000000 -0500
32035 ++++ linux-2.6.28.8/kernel/kallsyms.c 2009-02-21 09:37:49.000000000 -0500
32036 +@@ -62,6 +62,18 @@ static inline int is_kernel_text(unsigne
32037 +
32038 + static inline int is_kernel(unsigned long addr)
32039 + {
32040 ++
32041 ++#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_MODULES)
32042 ++ if ((unsigned long)MODULES_VADDR <= ktla_ktva(addr) &&
32043 ++ ktla_ktva(addr) < (unsigned long)MODULES_END)
32044 ++ return 0;
32045 ++#endif
32046 ++
32047 ++#ifdef CONFIG_X86_32
32048 ++ if (is_kernel_inittext(addr))
32049 ++ return 1;
32050 ++#endif
32051 ++
32052 + if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
32053 + return 1;
32054 + return in_gate_area_no_task(addr);
32055 +@@ -372,7 +384,6 @@ static unsigned long get_ksymbol_core(st
32056 +
32057 + static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
32058 + {
32059 +- iter->name[0] = '\0';
32060 + iter->nameoff = get_symbol_offset(new_pos);
32061 + iter->pos = new_pos;
32062 + }
32063 +@@ -456,7 +467,7 @@ static int kallsyms_open(struct inode *i
32064 + struct kallsym_iter *iter;
32065 + int ret;
32066 +
32067 +- iter = kmalloc(sizeof(*iter), GFP_KERNEL);
32068 ++ iter = kzalloc(sizeof(*iter), GFP_KERNEL);
32069 + if (!iter)
32070 + return -ENOMEM;
32071 + reset_iter(iter, 0);
32072 +@@ -478,7 +489,15 @@ static const struct file_operations kall
32073 +
32074 + static int __init kallsyms_init(void)
32075 + {
32076 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
32077 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
32078 ++ proc_create("kallsyms", S_IFREG | S_IRUSR, NULL, &kallsyms_operations);
32079 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
32080 ++ proc_create("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL, &kallsyms_operations);
32081 ++#endif
32082 ++#else
32083 + proc_create("kallsyms", 0444, NULL, &kallsyms_operations);
32084 ++#endif
32085 + return 0;
32086 + }
32087 + __initcall(kallsyms_init);
32088 +diff -urNp linux-2.6.28.8/kernel/kmod.c linux-2.6.28.8/kernel/kmod.c
32089 +--- linux-2.6.28.8/kernel/kmod.c 2009-02-06 16:47:45.000000000 -0500
32090 ++++ linux-2.6.28.8/kernel/kmod.c 2009-02-21 09:37:49.000000000 -0500
32091 +@@ -108,7 +108,7 @@ int request_module(const char *fmt, ...)
32092 + return -ENOMEM;
32093 + }
32094 +
32095 +- ret = call_usermodehelper(modprobe_path, argv, envp, 1);
32096 ++ ret = call_usermodehelper(modprobe_path, argv, envp, UMH_WAIT_PROC);
32097 + atomic_dec(&kmod_concurrent);
32098 + return ret;
32099 + }
32100 +diff -urNp linux-2.6.28.8/kernel/kprobes.c linux-2.6.28.8/kernel/kprobes.c
32101 +--- linux-2.6.28.8/kernel/kprobes.c 2009-02-06 16:47:45.000000000 -0500
32102 ++++ linux-2.6.28.8/kernel/kprobes.c 2009-02-21 09:37:49.000000000 -0500
32103 +@@ -182,7 +182,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
32104 + * kernel image and loaded module images reside. This is required
32105 + * so x86_64 can correctly handle the %rip-relative fixups.
32106 + */
32107 +- kip->insns = module_alloc(PAGE_SIZE);
32108 ++ kip->insns = module_alloc_exec(PAGE_SIZE);
32109 + if (!kip->insns) {
32110 + kfree(kip);
32111 + return NULL;
32112 +@@ -214,7 +214,7 @@ static int __kprobes collect_one_slot(st
32113 + hlist_add_head(&kip->hlist,
32114 + &kprobe_insn_pages);
32115 + } else {
32116 +- module_free(NULL, kip->insns);
32117 ++ module_free_exec(NULL, kip->insns);
32118 + kfree(kip);
32119 + }
32120 + return 1;
32121 +diff -urNp linux-2.6.28.8/kernel/lockdep.c linux-2.6.28.8/kernel/lockdep.c
32122 +--- linux-2.6.28.8/kernel/lockdep.c 2009-02-06 16:47:45.000000000 -0500
32123 ++++ linux-2.6.28.8/kernel/lockdep.c 2009-02-21 09:37:49.000000000 -0500
32124 +@@ -627,6 +627,10 @@ static int static_obj(void *obj)
32125 + int i;
32126 + #endif
32127 +
32128 ++#ifdef CONFIG_PAX_KERNEXEC
32129 ++ start = (unsigned long )&_data;
32130 ++#endif
32131 ++
32132 + /*
32133 + * static variable?
32134 + */
32135 +@@ -638,9 +642,12 @@ static int static_obj(void *obj)
32136 + * percpu var?
32137 + */
32138 + for_each_possible_cpu(i) {
32139 ++#ifdef CONFIG_X86_32
32140 ++ start = per_cpu_offset(i);
32141 ++#else
32142 + start = (unsigned long) &__per_cpu_start + per_cpu_offset(i);
32143 +- end = (unsigned long) &__per_cpu_start + PERCPU_ENOUGH_ROOM
32144 +- + per_cpu_offset(i);
32145 ++#endif
32146 ++ end = start + PERCPU_ENOUGH_ROOM;
32147 +
32148 + if ((addr >= start) && (addr < end))
32149 + return 1;
32150 +diff -urNp linux-2.6.28.8/kernel/module.c linux-2.6.28.8/kernel/module.c
32151 +--- linux-2.6.28.8/kernel/module.c 2009-02-06 16:47:45.000000000 -0500
32152 ++++ linux-2.6.28.8/kernel/module.c 2009-02-21 09:37:50.000000000 -0500
32153 +@@ -47,6 +47,11 @@
32154 + #include <linux/rculist.h>
32155 + #include <asm/uaccess.h>
32156 + #include <asm/cacheflush.h>
32157 ++
32158 ++#ifdef CONFIG_PAX_KERNEXEC
32159 ++#include <asm/desc.h>
32160 ++#endif
32161 ++
32162 + #include <linux/license.h>
32163 + #include <asm/sections.h>
32164 + #include <linux/tracepoint.h>
32165 +@@ -76,7 +81,10 @@ static DECLARE_WAIT_QUEUE_HEAD(module_wq
32166 + static BLOCKING_NOTIFIER_HEAD(module_notify_list);
32167 +
32168 + /* Bounds of module allocation, for speeding __module_text_address */
32169 +-static unsigned long module_addr_min = -1UL, module_addr_max = 0;
32170 ++static unsigned long module_addr_min_rw = -1UL, module_addr_max_rw = 0;
32171 ++static unsigned long module_addr_min_rx = -1UL, module_addr_max_rx = 0;
32172 ++
32173 ++extern int gr_check_modstop(void);
32174 +
32175 + int register_module_notifier(struct notifier_block * nb)
32176 + {
32177 +@@ -245,7 +253,7 @@ static bool each_symbol(bool (*fn)(const
32178 + return true;
32179 +
32180 + list_for_each_entry_rcu(mod, &modules, list) {
32181 +- struct symsearch arr[] = {
32182 ++ struct symsearch modarr[] = {
32183 + { mod->syms, mod->syms + mod->num_syms, mod->crcs,
32184 + NOT_GPL_ONLY, false },
32185 + { mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms,
32186 +@@ -267,7 +275,7 @@ static bool each_symbol(bool (*fn)(const
32187 + #endif
32188 + };
32189 +
32190 +- if (each_symbol_in_section(arr, ARRAY_SIZE(arr), mod, fn, data))
32191 ++ if (each_symbol_in_section(modarr, ARRAY_SIZE(modarr), mod, fn, data))
32192 + return true;
32193 + }
32194 + return false;
32195 +@@ -403,6 +411,8 @@ static inline unsigned int block_size(in
32196 + return val;
32197 + }
32198 +
32199 ++EXPORT_SYMBOL(__per_cpu_start);
32200 ++
32201 + static void *percpu_modalloc(unsigned long size, unsigned long align,
32202 + const char *name)
32203 + {
32204 +@@ -410,7 +420,7 @@ static void *percpu_modalloc(unsigned lo
32205 + unsigned int i;
32206 + void *ptr;
32207 +
32208 +- if (align > PAGE_SIZE) {
32209 ++ if (align-1 >= PAGE_SIZE) {
32210 + printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
32211 + name, align, PAGE_SIZE);
32212 + align = PAGE_SIZE;
32213 +@@ -492,7 +502,11 @@ static void percpu_modcopy(void *pcpudes
32214 + int cpu;
32215 +
32216 + for_each_possible_cpu(cpu)
32217 ++#ifdef CONFIG_X86_32
32218 ++ memcpy(pcpudest + __per_cpu_offset[cpu], from, size);
32219 ++#else
32220 + memcpy(pcpudest + per_cpu_offset(cpu), from, size);
32221 ++#endif
32222 + }
32223 +
32224 + static int percpu_modinit(void)
32225 +@@ -750,6 +764,9 @@ SYSCALL_DEFINE2(delete_module, const cha
32226 + char name[MODULE_NAME_LEN];
32227 + int ret, forced = 0;
32228 +
32229 ++ if (gr_check_modstop())
32230 ++ return -EPERM;
32231 ++
32232 + if (!capable(CAP_SYS_MODULE))
32233 + return -EPERM;
32234 +
32235 +@@ -1448,19 +1465,22 @@ static void free_module(struct module *m
32236 + module_unload_free(mod);
32237 +
32238 + /* release any pointers to mcount in this module */
32239 +- ftrace_release(mod->module_core, mod->core_size);
32240 ++ ftrace_release(mod->module_core_rx, mod->core_size_rx);
32241 +
32242 + /* This may be NULL, but that's OK */
32243 +- module_free(mod, mod->module_init);
32244 ++ module_free(mod, mod->module_init_rw);
32245 ++ module_free_exec(mod, mod->module_init_rx);
32246 + kfree(mod->args);
32247 + if (mod->percpu)
32248 + percpu_modfree(mod->percpu);
32249 +
32250 + /* Free lock-classes: */
32251 +- lockdep_free_key_range(mod->module_core, mod->core_size);
32252 ++ lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
32253 ++ lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
32254 +
32255 + /* Finally, free the core (containing the module structure) */
32256 +- module_free(mod, mod->module_core);
32257 ++ module_free_exec(mod, mod->module_core_rx);
32258 ++ module_free(mod, mod->module_core_rw);
32259 + }
32260 +
32261 + void *__symbol_get(const char *symbol)
32262 +@@ -1526,10 +1546,14 @@ static int simplify_symbols(Elf_Shdr *se
32263 + struct module *mod)
32264 + {
32265 + Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
32266 +- unsigned long secbase;
32267 ++ unsigned long secbase, symbol;
32268 + unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
32269 + int ret = 0;
32270 +
32271 ++#ifdef CONFIG_PAX_KERNEXEC
32272 ++ unsigned long cr0;
32273 ++#endif
32274 ++
32275 + for (i = 1; i < n; i++) {
32276 + switch (sym[i].st_shndx) {
32277 + case SHN_COMMON:
32278 +@@ -1548,10 +1572,19 @@ static int simplify_symbols(Elf_Shdr *se
32279 + break;
32280 +
32281 + case SHN_UNDEF:
32282 +- sym[i].st_value
32283 +- = resolve_symbol(sechdrs, versindex,
32284 ++ symbol = resolve_symbol(sechdrs, versindex,
32285 + strtab + sym[i].st_name, mod);
32286 +
32287 ++#ifdef CONFIG_PAX_KERNEXEC
32288 ++ pax_open_kernel(cr0);
32289 ++#endif
32290 ++
32291 ++ sym[i].st_value = symbol;
32292 ++
32293 ++#ifdef CONFIG_PAX_KERNEXEC
32294 ++ pax_close_kernel(cr0);
32295 ++#endif
32296 ++
32297 + /* Ok if resolved. */
32298 + if (!IS_ERR_VALUE(sym[i].st_value))
32299 + break;
32300 +@@ -1566,11 +1599,27 @@ static int simplify_symbols(Elf_Shdr *se
32301 +
32302 + default:
32303 + /* Divert to percpu allocation if a percpu var. */
32304 +- if (sym[i].st_shndx == pcpuindex)
32305 ++ if (sym[i].st_shndx == pcpuindex) {
32306 ++
32307 ++#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
32308 ++ secbase = (unsigned long)mod->percpu - (unsigned long)__per_cpu_start;
32309 ++#else
32310 + secbase = (unsigned long)mod->percpu;
32311 +- else
32312 ++#endif
32313 ++
32314 ++ } else
32315 + secbase = sechdrs[sym[i].st_shndx].sh_addr;
32316 ++
32317 ++#ifdef CONFIG_PAX_KERNEXEC
32318 ++ pax_open_kernel(cr0);
32319 ++#endif
32320 ++
32321 + sym[i].st_value += secbase;
32322 ++
32323 ++#ifdef CONFIG_PAX_KERNEXEC
32324 ++ pax_close_kernel(cr0);
32325 ++#endif
32326 ++
32327 + break;
32328 + }
32329 + }
32330 +@@ -1622,11 +1671,12 @@ static void layout_sections(struct modul
32331 + || strncmp(secstrings + s->sh_name,
32332 + ".init", 5) == 0)
32333 + continue;
32334 +- s->sh_entsize = get_offset(&mod->core_size, s);
32335 ++ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
32336 ++ s->sh_entsize = get_offset(&mod->core_size_rw, s);
32337 ++ else
32338 ++ s->sh_entsize = get_offset(&mod->core_size_rx, s);
32339 + DEBUGP("\t%s\n", secstrings + s->sh_name);
32340 + }
32341 +- if (m == 0)
32342 +- mod->core_text_size = mod->core_size;
32343 + }
32344 +
32345 + DEBUGP("Init section allocation order:\n");
32346 +@@ -1640,12 +1690,13 @@ static void layout_sections(struct modul
32347 + || strncmp(secstrings + s->sh_name,
32348 + ".init", 5) != 0)
32349 + continue;
32350 +- s->sh_entsize = (get_offset(&mod->init_size, s)
32351 +- | INIT_OFFSET_MASK);
32352 ++ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
32353 ++ s->sh_entsize = get_offset(&mod->init_size_rw, s);
32354 ++ else
32355 ++ s->sh_entsize = get_offset(&mod->init_size_rx, s);
32356 ++ s->sh_entsize |= INIT_OFFSET_MASK;
32357 + DEBUGP("\t%s\n", secstrings + s->sh_name);
32358 + }
32359 +- if (m == 0)
32360 +- mod->init_text_size = mod->init_size;
32361 + }
32362 + }
32363 +
32364 +@@ -1785,14 +1836,31 @@ static void add_kallsyms(struct module *
32365 + {
32366 + unsigned int i;
32367 +
32368 ++#ifdef CONFIG_PAX_KERNEXEC
32369 ++ unsigned long cr0;
32370 ++#endif
32371 ++
32372 + mod->symtab = (void *)sechdrs[symindex].sh_addr;
32373 + mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
32374 + mod->strtab = (void *)sechdrs[strindex].sh_addr;
32375 +
32376 + /* Set types up while we still have access to sections. */
32377 +- for (i = 0; i < mod->num_symtab; i++)
32378 +- mod->symtab[i].st_info
32379 +- = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
32380 ++
32381 ++ for (i = 0; i < mod->num_symtab; i++) {
32382 ++ char type = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
32383 ++
32384 ++#ifdef CONFIG_PAX_KERNEXEC
32385 ++ pax_open_kernel(cr0);
32386 ++#endif
32387 ++
32388 ++ mod->symtab[i].st_info = type;
32389 ++
32390 ++#ifdef CONFIG_PAX_KERNEXEC
32391 ++ pax_close_kernel(cr0);
32392 ++#endif
32393 ++
32394 ++ }
32395 ++
32396 + }
32397 + #else
32398 + static inline void add_kallsyms(struct module *mod,
32399 +@@ -1819,16 +1887,30 @@ static void dynamic_printk_setup(struct
32400 + #endif /* CONFIG_DYNAMIC_PRINTK_DEBUG */
32401 + }
32402 +
32403 +-static void *module_alloc_update_bounds(unsigned long size)
32404 ++static void *module_alloc_update_bounds_rw(unsigned long size)
32405 + {
32406 + void *ret = module_alloc(size);
32407 +
32408 + if (ret) {
32409 + /* Update module bounds. */
32410 +- if ((unsigned long)ret < module_addr_min)
32411 +- module_addr_min = (unsigned long)ret;
32412 +- if ((unsigned long)ret + size > module_addr_max)
32413 +- module_addr_max = (unsigned long)ret + size;
32414 ++ if ((unsigned long)ret < module_addr_min_rw)
32415 ++ module_addr_min_rw = (unsigned long)ret;
32416 ++ if ((unsigned long)ret + size > module_addr_max_rw)
32417 ++ module_addr_max_rw = (unsigned long)ret + size;
32418 ++ }
32419 ++ return ret;
32420 ++}
32421 ++
32422 ++static void *module_alloc_update_bounds_rx(unsigned long size)
32423 ++{
32424 ++ void *ret = module_alloc_exec(size);
32425 ++
32426 ++ if (ret) {
32427 ++ /* Update module bounds. */
32428 ++ if ((unsigned long)ret < module_addr_min_rx)
32429 ++ module_addr_min_rx = (unsigned long)ret;
32430 ++ if ((unsigned long)ret + size > module_addr_max_rx)
32431 ++ module_addr_max_rx = (unsigned long)ret + size;
32432 + }
32433 + return ret;
32434 + }
32435 +@@ -1856,6 +1938,10 @@ static noinline struct module *load_modu
32436 + unsigned long *mseg;
32437 + mm_segment_t old_fs;
32438 +
32439 ++#ifdef CONFIG_PAX_KERNEXEC
32440 ++ unsigned long cr0;
32441 ++#endif
32442 ++
32443 + DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
32444 + umod, len, uargs);
32445 + if (len < sizeof(*hdr))
32446 +@@ -2010,22 +2096,57 @@ static noinline struct module *load_modu
32447 + layout_sections(mod, hdr, sechdrs, secstrings);
32448 +
32449 + /* Do the allocs. */
32450 +- ptr = module_alloc_update_bounds(mod->core_size);
32451 ++ ptr = module_alloc_update_bounds_rw(mod->core_size_rw);
32452 + if (!ptr) {
32453 + err = -ENOMEM;
32454 + goto free_percpu;
32455 + }
32456 +- memset(ptr, 0, mod->core_size);
32457 +- mod->module_core = ptr;
32458 ++ memset(ptr, 0, mod->core_size_rw);
32459 ++ mod->module_core_rw = ptr;
32460 +
32461 +- ptr = module_alloc_update_bounds(mod->init_size);
32462 +- if (!ptr && mod->init_size) {
32463 ++ ptr = module_alloc_update_bounds_rw(mod->init_size_rw);
32464 ++ if (!ptr && mod->init_size_rw) {
32465 + err = -ENOMEM;
32466 +- goto free_core;
32467 ++ goto free_core_rw;
32468 + }
32469 +- memset(ptr, 0, mod->init_size);
32470 +- mod->module_init = ptr;
32471 ++ memset(ptr, 0, mod->init_size_rw);
32472 ++ mod->module_init_rw = ptr;
32473 ++
32474 ++ ptr = module_alloc_update_bounds_rx(mod->core_size_rx);
32475 ++ if (!ptr) {
32476 ++ err = -ENOMEM;
32477 ++ goto free_init_rw;
32478 ++ }
32479 ++
32480 ++#ifdef CONFIG_PAX_KERNEXEC
32481 ++ pax_open_kernel(cr0);
32482 ++#endif
32483 +
32484 ++ memset(ptr, 0, mod->core_size_rx);
32485 ++
32486 ++#ifdef CONFIG_PAX_KERNEXEC
32487 ++ pax_close_kernel(cr0);
32488 ++#endif
32489 ++
32490 ++ mod->module_core_rx = ptr;
32491 ++
32492 ++ ptr = module_alloc_update_bounds_rx(mod->init_size_rx);
32493 ++ if (!ptr && mod->init_size_rx) {
32494 ++ err = -ENOMEM;
32495 ++ goto free_core_rx;
32496 ++ }
32497 ++
32498 ++#ifdef CONFIG_PAX_KERNEXEC
32499 ++ pax_open_kernel(cr0);
32500 ++#endif
32501 ++
32502 ++ memset(ptr, 0, mod->init_size_rx);
32503 ++
32504 ++#ifdef CONFIG_PAX_KERNEXEC
32505 ++ pax_close_kernel(cr0);
32506 ++#endif
32507 ++
32508 ++ mod->module_init_rx = ptr;
32509 + /* Transfer each section which specifies SHF_ALLOC */
32510 + DEBUGP("final section addresses:\n");
32511 + for (i = 0; i < hdr->e_shnum; i++) {
32512 +@@ -2034,17 +2155,41 @@ static noinline struct module *load_modu
32513 + if (!(sechdrs[i].sh_flags & SHF_ALLOC))
32514 + continue;
32515 +
32516 +- if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
32517 +- dest = mod->module_init
32518 +- + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
32519 +- else
32520 +- dest = mod->module_core + sechdrs[i].sh_entsize;
32521 ++ if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
32522 ++ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
32523 ++ dest = mod->module_init_rw
32524 ++ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
32525 ++ else
32526 ++ dest = mod->module_init_rx
32527 ++ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
32528 ++ } else {
32529 ++ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
32530 ++ dest = mod->module_core_rw + sechdrs[i].sh_entsize;
32531 ++ else
32532 ++ dest = mod->module_core_rx + sechdrs[i].sh_entsize;
32533 ++ }
32534 ++
32535 ++ if (sechdrs[i].sh_type != SHT_NOBITS) {
32536 +
32537 +- if (sechdrs[i].sh_type != SHT_NOBITS)
32538 +- memcpy(dest, (void *)sechdrs[i].sh_addr,
32539 +- sechdrs[i].sh_size);
32540 ++#ifdef CONFIG_PAX_KERNEXEC
32541 ++ if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC)) {
32542 ++ pax_open_kernel(cr0);
32543 ++ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
32544 ++ pax_close_kernel(cr0);
32545 ++ } else
32546 ++#endif
32547 ++
32548 ++ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
32549 ++ }
32550 + /* Update sh_addr to point to copy in image. */
32551 +- sechdrs[i].sh_addr = (unsigned long)dest;
32552 ++
32553 ++#ifdef CONFIG_PAX_KERNEXEC
32554 ++ if (sechdrs[i].sh_flags & SHF_EXECINSTR)
32555 ++ sechdrs[i].sh_addr = ktva_ktla((unsigned long)dest);
32556 ++ else
32557 ++#endif
32558 ++
32559 ++ sechdrs[i].sh_addr = (unsigned long)dest;
32560 + DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
32561 + }
32562 + /* Module has been moved. */
32563 +@@ -2144,8 +2289,8 @@ static noinline struct module *load_modu
32564 +
32565 + /* Now do relocations. */
32566 + for (i = 1; i < hdr->e_shnum; i++) {
32567 +- const char *strtab = (char *)sechdrs[strindex].sh_addr;
32568 + unsigned int info = sechdrs[i].sh_info;
32569 ++ strtab = (char *)sechdrs[strindex].sh_addr;
32570 +
32571 + /* Not a valid relocation section? */
32572 + if (info >= hdr->e_shnum)
32573 +@@ -2216,12 +2361,12 @@ static noinline struct module *load_modu
32574 + * Do it before processing of module parameters, so the module
32575 + * can provide parameter accessor functions of its own.
32576 + */
32577 +- if (mod->module_init)
32578 +- flush_icache_range((unsigned long)mod->module_init,
32579 +- (unsigned long)mod->module_init
32580 +- + mod->init_size);
32581 +- flush_icache_range((unsigned long)mod->module_core,
32582 +- (unsigned long)mod->module_core + mod->core_size);
32583 ++ if (mod->module_init_rx)
32584 ++ flush_icache_range((unsigned long)mod->module_init_rx,
32585 ++ (unsigned long)mod->module_init_rx
32586 ++ + mod->init_size_rx);
32587 ++ flush_icache_range((unsigned long)mod->module_core_rx,
32588 ++ (unsigned long)mod->module_core_rx + mod->core_size_rx);
32589 +
32590 + set_fs(old_fs);
32591 +
32592 +@@ -2266,12 +2411,16 @@ static noinline struct module *load_modu
32593 + cleanup:
32594 + kobject_del(&mod->mkobj.kobj);
32595 + kobject_put(&mod->mkobj.kobj);
32596 +- ftrace_release(mod->module_core, mod->core_size);
32597 ++ ftrace_release(mod->module_core_rx, mod->core_size_rx);
32598 + free_unload:
32599 + module_unload_free(mod);
32600 +- module_free(mod, mod->module_init);
32601 +- free_core:
32602 +- module_free(mod, mod->module_core);
32603 ++ module_free_exec(mod, mod->module_init_rx);
32604 ++ free_core_rx:
32605 ++ module_free_exec(mod, mod->module_core_rx);
32606 ++ free_init_rw:
32607 ++ module_free(mod, mod->module_init_rw);
32608 ++ free_core_rw:
32609 ++ module_free(mod, mod->module_core_rw);
32610 + free_percpu:
32611 + if (percpu)
32612 + percpu_modfree(percpu);
32613 +@@ -2294,6 +2443,9 @@ SYSCALL_DEFINE3(init_module, void __user
32614 + struct module *mod;
32615 + int ret = 0;
32616 +
32617 ++ if (gr_check_modstop())
32618 ++ return -EPERM;
32619 ++
32620 + /* Must have permission */
32621 + if (!capable(CAP_SYS_MODULE))
32622 + return -EPERM;
32623 +@@ -2349,10 +2501,12 @@ SYSCALL_DEFINE3(init_module, void __user
32624 + /* Drop initial reference. */
32625 + module_put(mod);
32626 + unwind_remove_table(mod->unwind_info, 1);
32627 +- module_free(mod, mod->module_init);
32628 +- mod->module_init = NULL;
32629 +- mod->init_size = 0;
32630 +- mod->init_text_size = 0;
32631 ++ module_free(mod, mod->module_init_rw);
32632 ++ module_free_exec(mod, mod->module_init_rx);
32633 ++ mod->module_init_rw = NULL;
32634 ++ mod->module_init_rx = NULL;
32635 ++ mod->init_size_rw = 0;
32636 ++ mod->init_size_rx = 0;
32637 + mutex_unlock(&module_mutex);
32638 +
32639 + return 0;
32640 +@@ -2360,6 +2514,13 @@ SYSCALL_DEFINE3(init_module, void __user
32641 +
32642 + static inline int within(unsigned long addr, void *start, unsigned long size)
32643 + {
32644 ++
32645 ++#ifdef CONFIG_PAX_KERNEXEC
32646 ++ if (ktla_ktva(addr) >= (unsigned long)start &&
32647 ++ ktla_ktva(addr) < (unsigned long)start + size)
32648 ++ return 1;
32649 ++#endif
32650 ++
32651 + return ((void *)addr >= start && (void *)addr < start + size);
32652 + }
32653 +
32654 +@@ -2383,10 +2544,14 @@ static const char *get_ksymbol(struct mo
32655 + unsigned long nextval;
32656 +
32657 + /* At worse, next value is at end of module */
32658 +- if (within(addr, mod->module_init, mod->init_size))
32659 +- nextval = (unsigned long)mod->module_init+mod->init_text_size;
32660 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx))
32661 ++ nextval = (unsigned long)mod->module_init_rx+mod->init_size_rx;
32662 ++ else if (within(addr, mod->module_init_rw, mod->init_size_rw))
32663 ++ nextval = (unsigned long)mod->module_init_rw+mod->init_size_rw;
32664 ++ else if (within(addr, mod->module_core_rx, mod->core_size_rx))
32665 ++ nextval = (unsigned long)mod->module_core_rx+mod->core_size_rx;
32666 + else
32667 +- nextval = (unsigned long)mod->module_core+mod->core_text_size;
32668 ++ nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
32669 +
32670 + /* Scan for closest preceeding symbol, and next symbol. (ELF
32671 + starts real symbols at 1). */
32672 +@@ -2431,8 +2596,10 @@ const char *module_address_lookup(unsign
32673 +
32674 + preempt_disable();
32675 + list_for_each_entry_rcu(mod, &modules, list) {
32676 +- if (within(addr, mod->module_init, mod->init_size)
32677 +- || within(addr, mod->module_core, mod->core_size)) {
32678 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
32679 ++ within(addr, mod->module_init_rw, mod->init_size_rw) ||
32680 ++ within(addr, mod->module_core_rx, mod->core_size_rx) ||
32681 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
32682 + if (modname)
32683 + *modname = mod->name;
32684 + ret = get_ksymbol(mod, addr, size, offset);
32685 +@@ -2454,8 +2621,10 @@ int lookup_module_symbol_name(unsigned l
32686 +
32687 + preempt_disable();
32688 + list_for_each_entry_rcu(mod, &modules, list) {
32689 +- if (within(addr, mod->module_init, mod->init_size) ||
32690 +- within(addr, mod->module_core, mod->core_size)) {
32691 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
32692 ++ within(addr, mod->module_init_rw, mod->init_size_rw) ||
32693 ++ within(addr, mod->module_core_rx, mod->core_size_rx) ||
32694 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
32695 + const char *sym;
32696 +
32697 + sym = get_ksymbol(mod, addr, NULL, NULL);
32698 +@@ -2478,8 +2647,10 @@ int lookup_module_symbol_attrs(unsigned
32699 +
32700 + preempt_disable();
32701 + list_for_each_entry_rcu(mod, &modules, list) {
32702 +- if (within(addr, mod->module_init, mod->init_size) ||
32703 +- within(addr, mod->module_core, mod->core_size)) {
32704 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
32705 ++ within(addr, mod->module_init_rw, mod->init_size_rw) ||
32706 ++ within(addr, mod->module_core_rx, mod->core_size_rx) ||
32707 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
32708 + const char *sym;
32709 +
32710 + sym = get_ksymbol(mod, addr, size, offset);
32711 +@@ -2613,7 +2784,7 @@ static int m_show(struct seq_file *m, vo
32712 + char buf[8];
32713 +
32714 + seq_printf(m, "%s %u",
32715 +- mod->name, mod->init_size + mod->core_size);
32716 ++ mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
32717 + print_unload_info(m, mod);
32718 +
32719 + /* Informative for users. */
32720 +@@ -2622,7 +2793,7 @@ static int m_show(struct seq_file *m, vo
32721 + mod->state == MODULE_STATE_COMING ? "Loading":
32722 + "Live");
32723 + /* Used by oprofile and other similar tools. */
32724 +- seq_printf(m, " 0x%p", mod->module_core);
32725 ++ seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
32726 +
32727 + /* Taints info */
32728 + if (mod->taints)
32729 +@@ -2698,8 +2869,8 @@ int is_module_address(unsigned long addr
32730 + preempt_disable();
32731 +
32732 + list_for_each_entry_rcu(mod, &modules, list) {
32733 +- if (within(addr, mod->module_core, mod->core_size)) {
32734 +- preempt_enable();
32735 ++ if (within(addr, mod->module_core_rx, mod->core_size_rx) ||
32736 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
32737 + return 1;
32738 + }
32739 + }
32740 +@@ -2715,12 +2886,16 @@ struct module *__module_text_address(uns
32741 + {
32742 + struct module *mod;
32743 +
32744 +- if (addr < module_addr_min || addr > module_addr_max)
32745 ++#ifdef CONFIG_X86_32
32746 ++ addr = ktla_ktva(addr);
32747 ++#endif
32748 ++
32749 ++ if (addr < module_addr_min_rx || addr > module_addr_max_rx)
32750 + return NULL;
32751 +
32752 + list_for_each_entry_rcu(mod, &modules, list)
32753 +- if (within(addr, mod->module_init, mod->init_text_size)
32754 +- || within(addr, mod->module_core, mod->core_text_size))
32755 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx)
32756 ++ || within(addr, mod->module_core_rx, mod->core_size_rx))
32757 + return mod;
32758 + return NULL;
32759 + }
32760 +diff -urNp linux-2.6.28.8/kernel/mutex.c linux-2.6.28.8/kernel/mutex.c
32761 +--- linux-2.6.28.8/kernel/mutex.c 2009-02-06 16:47:45.000000000 -0500
32762 ++++ linux-2.6.28.8/kernel/mutex.c 2009-02-21 09:37:50.000000000 -0500
32763 +@@ -83,7 +83,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou
32764 + *
32765 + * This function is similar to (but not equivalent to) down().
32766 + */
32767 +-void inline __sched mutex_lock(struct mutex *lock)
32768 ++inline void __sched mutex_lock(struct mutex *lock)
32769 + {
32770 + might_sleep();
32771 + /*
32772 +diff -urNp linux-2.6.28.8/kernel/panic.c linux-2.6.28.8/kernel/panic.c
32773 +--- linux-2.6.28.8/kernel/panic.c 2009-02-06 16:47:45.000000000 -0500
32774 ++++ linux-2.6.28.8/kernel/panic.c 2009-02-21 09:37:50.000000000 -0500
32775 +@@ -367,6 +367,8 @@ EXPORT_SYMBOL(warn_slowpath);
32776 + */
32777 + void __stack_chk_fail(void)
32778 + {
32779 ++ print_symbol("stack corrupted in: %s\n", (unsigned long)__builtin_return_address(0));
32780 ++ dump_stack();
32781 + panic("stack-protector: Kernel stack is corrupted");
32782 + }
32783 + EXPORT_SYMBOL(__stack_chk_fail);
32784 +diff -urNp linux-2.6.28.8/kernel/pid.c linux-2.6.28.8/kernel/pid.c
32785 +--- linux-2.6.28.8/kernel/pid.c 2009-02-06 16:47:45.000000000 -0500
32786 ++++ linux-2.6.28.8/kernel/pid.c 2009-02-21 09:37:50.000000000 -0500
32787 +@@ -33,6 +33,7 @@
32788 + #include <linux/rculist.h>
32789 + #include <linux/bootmem.h>
32790 + #include <linux/hash.h>
32791 ++#include <linux/security.h>
32792 + #include <linux/pid_namespace.h>
32793 + #include <linux/init_task.h>
32794 + #include <linux/syscalls.h>
32795 +@@ -45,7 +46,7 @@ struct pid init_struct_pid = INIT_STRUCT
32796 +
32797 + int pid_max = PID_MAX_DEFAULT;
32798 +
32799 +-#define RESERVED_PIDS 300
32800 ++#define RESERVED_PIDS 500
32801 +
32802 + int pid_max_min = RESERVED_PIDS + 1;
32803 + int pid_max_max = PID_MAX_LIMIT;
32804 +@@ -381,7 +382,14 @@ EXPORT_SYMBOL(pid_task);
32805 + struct task_struct *find_task_by_pid_type_ns(int type, int nr,
32806 + struct pid_namespace *ns)
32807 + {
32808 +- return pid_task(find_pid_ns(nr, ns), type);
32809 ++ struct task_struct *task;
32810 ++
32811 ++ task = pid_task(find_pid_ns(nr, ns), type);
32812 ++
32813 ++ if (gr_pid_is_chrooted(task))
32814 ++ return NULL;
32815 ++
32816 ++ return task;
32817 + }
32818 +
32819 + EXPORT_SYMBOL(find_task_by_pid_type_ns);
32820 +diff -urNp linux-2.6.28.8/kernel/posix-cpu-timers.c linux-2.6.28.8/kernel/posix-cpu-timers.c
32821 +--- linux-2.6.28.8/kernel/posix-cpu-timers.c 2009-02-06 16:47:45.000000000 -0500
32822 ++++ linux-2.6.28.8/kernel/posix-cpu-timers.c 2009-02-21 09:37:50.000000000 -0500
32823 +@@ -6,6 +6,7 @@
32824 + #include <linux/posix-timers.h>
32825 + #include <linux/errno.h>
32826 + #include <linux/math64.h>
32827 ++#include <linux/security.h>
32828 + #include <asm/uaccess.h>
32829 + #include <linux/kernel_stat.h>
32830 +
32831 +@@ -1157,6 +1158,7 @@ static void check_process_timers(struct
32832 + __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
32833 + return;
32834 + }
32835 ++ gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1);
32836 + if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
32837 + /*
32838 + * At the soft limit, send a SIGXCPU every second.
32839 +@@ -1381,17 +1383,17 @@ void run_posix_cpu_timers(struct task_st
32840 + * timer call will interfere.
32841 + */
32842 + list_for_each_entry_safe(timer, next, &firing, it.cpu.entry) {
32843 +- int firing;
32844 ++ int __firing;
32845 + spin_lock(&timer->it_lock);
32846 + list_del_init(&timer->it.cpu.entry);
32847 +- firing = timer->it.cpu.firing;
32848 ++ __firing = timer->it.cpu.firing;
32849 + timer->it.cpu.firing = 0;
32850 + /*
32851 + * The firing flag is -1 if we collided with a reset
32852 + * of the timer, which already reported this
32853 + * almost-firing as an overrun. So don't generate an event.
32854 + */
32855 +- if (likely(firing >= 0)) {
32856 ++ if (likely(__firing >= 0)) {
32857 + cpu_timer_fire(timer);
32858 + }
32859 + spin_unlock(&timer->it_lock);
32860 +diff -urNp linux-2.6.28.8/kernel/power/poweroff.c linux-2.6.28.8/kernel/power/poweroff.c
32861 +--- linux-2.6.28.8/kernel/power/poweroff.c 2009-02-06 16:47:45.000000000 -0500
32862 ++++ linux-2.6.28.8/kernel/power/poweroff.c 2009-02-21 09:37:50.000000000 -0500
32863 +@@ -37,7 +37,7 @@ static struct sysrq_key_op sysrq_powerof
32864 + .enable_mask = SYSRQ_ENABLE_BOOT,
32865 + };
32866 +
32867 +-static int pm_sysrq_init(void)
32868 ++static int __init pm_sysrq_init(void)
32869 + {
32870 + register_sysrq_key('o', &sysrq_poweroff_op);
32871 + return 0;
32872 +diff -urNp linux-2.6.28.8/kernel/printk.c linux-2.6.28.8/kernel/printk.c
32873 +--- linux-2.6.28.8/kernel/printk.c 2009-02-06 16:47:45.000000000 -0500
32874 ++++ linux-2.6.28.8/kernel/printk.c 2009-02-21 09:37:50.000000000 -0500
32875 +@@ -254,6 +254,11 @@ int do_syslog(int type, char __user *buf
32876 + char c;
32877 + int error = 0;
32878 +
32879 ++#ifdef CONFIG_GRKERNSEC_DMESG
32880 ++ if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
32881 ++ return -EPERM;
32882 ++#endif
32883 ++
32884 + error = security_syslog(type);
32885 + if (error)
32886 + return error;
32887 +diff -urNp linux-2.6.28.8/kernel/ptrace.c linux-2.6.28.8/kernel/ptrace.c
32888 +--- linux-2.6.28.8/kernel/ptrace.c 2009-02-06 16:47:45.000000000 -0500
32889 ++++ linux-2.6.28.8/kernel/ptrace.c 2009-02-21 09:37:50.000000000 -0500
32890 +@@ -132,12 +132,12 @@ int __ptrace_may_access(struct task_stru
32891 + (current->uid != task->uid) ||
32892 + (current->gid != task->egid) ||
32893 + (current->gid != task->sgid) ||
32894 +- (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
32895 ++ (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
32896 + return -EPERM;
32897 + smp_rmb();
32898 + if (task->mm)
32899 + dumpable = get_dumpable(task->mm);
32900 +- if (!dumpable && !capable(CAP_SYS_PTRACE))
32901 ++ if (!dumpable && !capable_nolog(CAP_SYS_PTRACE))
32902 + return -EPERM;
32903 +
32904 + return security_ptrace_may_access(task, mode);
32905 +@@ -193,7 +193,7 @@ repeat:
32906 +
32907 + /* Go */
32908 + task->ptrace |= PT_PTRACED;
32909 +- if (capable(CAP_SYS_PTRACE))
32910 ++ if (capable_nolog(CAP_SYS_PTRACE))
32911 + task->ptrace |= PT_PTRACE_CAP;
32912 +
32913 + __ptrace_link(task, current);
32914 +@@ -582,6 +582,11 @@ SYSCALL_DEFINE4(ptrace, long, request, l
32915 + if (ret < 0)
32916 + goto out_put_task_struct;
32917 +
32918 ++ if (gr_handle_ptrace(child, request)) {
32919 ++ ret = -EPERM;
32920 ++ goto out_put_task_struct;
32921 ++ }
32922 ++
32923 + ret = arch_ptrace(child, request, addr, data);
32924 + if (ret < 0)
32925 + goto out_put_task_struct;
32926 +diff -urNp linux-2.6.28.8/kernel/relay.c linux-2.6.28.8/kernel/relay.c
32927 +--- linux-2.6.28.8/kernel/relay.c 2009-02-06 16:47:45.000000000 -0500
32928 ++++ linux-2.6.28.8/kernel/relay.c 2009-02-21 09:37:50.000000000 -0500
32929 +@@ -1292,7 +1292,7 @@ static int subbuf_splice_actor(struct fi
32930 + return 0;
32931 +
32932 + ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
32933 +- if (ret < 0 || ret < total_len)
32934 ++ if ((int)ret < 0 || ret < total_len)
32935 + return ret;
32936 +
32937 + if (read_start + ret == nonpad_end)
32938 +diff -urNp linux-2.6.28.8/kernel/resource.c linux-2.6.28.8/kernel/resource.c
32939 +--- linux-2.6.28.8/kernel/resource.c 2009-02-06 16:47:45.000000000 -0500
32940 ++++ linux-2.6.28.8/kernel/resource.c 2009-02-21 09:37:50.000000000 -0500
32941 +@@ -132,8 +132,18 @@ static const struct file_operations proc
32942 +
32943 + static int __init ioresources_init(void)
32944 + {
32945 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
32946 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
32947 ++ proc_create("ioports", S_IRUSR, NULL, &proc_ioports_operations);
32948 ++ proc_create("iomem", S_IRUSR, NULL, &proc_iomem_operations);
32949 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
32950 ++ proc_create("ioports", S_IRUSR | S_IRGRP, NULL, &proc_ioports_operations);
32951 ++ proc_create("iomem", S_IRUSR | S_IRGRP, NULL, &proc_iomem_operations);
32952 ++#endif
32953 ++#else
32954 + proc_create("ioports", 0, NULL, &proc_ioports_operations);
32955 + proc_create("iomem", 0, NULL, &proc_iomem_operations);
32956 ++#endif
32957 + return 0;
32958 + }
32959 + __initcall(ioresources_init);
32960 +diff -urNp linux-2.6.28.8/kernel/sched.c linux-2.6.28.8/kernel/sched.c
32961 +--- linux-2.6.28.8/kernel/sched.c 2009-02-07 16:10:45.000000000 -0500
32962 ++++ linux-2.6.28.8/kernel/sched.c 2009-02-21 09:37:50.000000000 -0500
32963 +@@ -5045,7 +5045,8 @@ SYSCALL_DEFINE1(nice, int, increment)
32964 + if (nice > 19)
32965 + nice = 19;
32966 +
32967 +- if (increment < 0 && !can_nice(current, nice))
32968 ++ if (increment < 0 && (!can_nice(current, nice) ||
32969 ++ gr_handle_chroot_nice()))
32970 + return -EPERM;
32971 +
32972 + retval = security_task_setnice(current, nice);
32973 +@@ -6310,7 +6311,7 @@ static struct ctl_table sd_ctl_dir[] = {
32974 + .procname = "sched_domain",
32975 + .mode = 0555,
32976 + },
32977 +- {0, },
32978 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
32979 + };
32980 +
32981 + static struct ctl_table sd_ctl_root[] = {
32982 +@@ -6320,7 +6321,7 @@ static struct ctl_table sd_ctl_root[] =
32983 + .mode = 0555,
32984 + .child = sd_ctl_dir,
32985 + },
32986 +- {0, },
32987 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
32988 + };
32989 +
32990 + static struct ctl_table *sd_alloc_ctl_entry(int n)
32991 +diff -urNp linux-2.6.28.8/kernel/signal.c linux-2.6.28.8/kernel/signal.c
32992 +--- linux-2.6.28.8/kernel/signal.c 2009-02-06 16:47:45.000000000 -0500
32993 ++++ linux-2.6.28.8/kernel/signal.c 2009-03-07 14:17:22.000000000 -0500
32994 +@@ -596,6 +596,9 @@ static int check_kill_permission(int sig
32995 + }
32996 + }
32997 +
32998 ++ if (gr_handle_signal(t, sig))
32999 ++ return -EPERM;
33000 ++
33001 + return security_task_kill(t, info, sig, 0);
33002 + }
33003 +
33004 +@@ -887,8 +890,8 @@ static void print_fatal_signal(struct pt
33005 + for (i = 0; i < 16; i++) {
33006 + unsigned char insn;
33007 +
33008 +- __get_user(insn, (unsigned char *)(regs->ip + i));
33009 +- printk("%02x ", insn);
33010 ++ if (!get_user(insn, (unsigned char __user *)(regs->ip + i)))
33011 ++ printk("%02x ", insn);
33012 + }
33013 + }
33014 + #endif
33015 +@@ -911,7 +914,7 @@ __group_send_sig_info(int sig, struct si
33016 + return send_signal(sig, info, p, 1);
33017 + }
33018 +
33019 +-static int
33020 ++int
33021 + specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
33022 + {
33023 + return send_signal(sig, info, t, 0);
33024 +@@ -951,6 +954,9 @@ force_sig_info(int sig, struct siginfo *
33025 + ret = specific_send_sig_info(sig, info, t);
33026 + spin_unlock_irqrestore(&t->sighand->siglock, flags);
33027 +
33028 ++ gr_log_signal(sig, t);
33029 ++ gr_handle_crash(t, sig);
33030 ++
33031 + return ret;
33032 + }
33033 +
33034 +@@ -1021,6 +1027,8 @@ int group_send_sig_info(int sig, struct
33035 + ret = __group_send_sig_info(sig, info, p);
33036 + unlock_task_sighand(p, &flags);
33037 + }
33038 ++ if (!ret)
33039 ++ gr_log_signal(sig, p);
33040 + }
33041 +
33042 + return ret;
33043 +diff -urNp linux-2.6.28.8/kernel/softirq.c linux-2.6.28.8/kernel/softirq.c
33044 +--- linux-2.6.28.8/kernel/softirq.c 2009-02-06 16:47:45.000000000 -0500
33045 ++++ linux-2.6.28.8/kernel/softirq.c 2009-02-21 09:37:50.000000000 -0500
33046 +@@ -463,9 +463,9 @@ void tasklet_kill(struct tasklet_struct
33047 + printk("Attempt to kill tasklet from interrupt\n");
33048 +
33049 + while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
33050 +- do
33051 ++ do {
33052 + yield();
33053 +- while (test_bit(TASKLET_STATE_SCHED, &t->state));
33054 ++ } while (test_bit(TASKLET_STATE_SCHED, &t->state));
33055 + }
33056 + tasklet_unlock_wait(t);
33057 + clear_bit(TASKLET_STATE_SCHED, &t->state);
33058 +diff -urNp linux-2.6.28.8/kernel/sys.c linux-2.6.28.8/kernel/sys.c
33059 +--- linux-2.6.28.8/kernel/sys.c 2009-02-07 16:10:45.000000000 -0500
33060 ++++ linux-2.6.28.8/kernel/sys.c 2009-02-21 09:37:50.000000000 -0500
33061 +@@ -125,6 +125,12 @@ static int set_one_prio(struct task_stru
33062 + error = -EACCES;
33063 + goto out;
33064 + }
33065 ++
33066 ++ if (gr_handle_chroot_setpriority(p, niceval)) {
33067 ++ error = -EACCES;
33068 ++ goto out;
33069 ++ }
33070 ++
33071 + no_nice = security_task_setnice(p, niceval);
33072 + if (no_nice) {
33073 + error = no_nice;
33074 +@@ -181,10 +187,10 @@ SYSCALL_DEFINE3(setpriority, int, which,
33075 + if ((who != current->uid) && !(user = find_user(who)))
33076 + goto out_unlock; /* No processes for this user */
33077 +
33078 +- do_each_thread(g, p)
33079 ++ do_each_thread(g, p) {
33080 + if (p->uid == who)
33081 + error = set_one_prio(p, niceval, error);
33082 +- while_each_thread(g, p);
33083 ++ } while_each_thread(g, p);
33084 + if (who != current->uid)
33085 + free_uid(user); /* For find_user() */
33086 + break;
33087 +@@ -243,13 +249,13 @@ SYSCALL_DEFINE2(getpriority, int, which,
33088 + if ((who != current->uid) && !(user = find_user(who)))
33089 + goto out_unlock; /* No processes for this user */
33090 +
33091 +- do_each_thread(g, p)
33092 ++ do_each_thread(g, p) {
33093 + if (p->uid == who) {
33094 + niceval = 20 - task_nice(p);
33095 + if (niceval > retval)
33096 + retval = niceval;
33097 + }
33098 +- while_each_thread(g, p);
33099 ++ } while_each_thread(g, p);
33100 + if (who != current->uid)
33101 + free_uid(user); /* for find_user() */
33102 + break;
33103 +@@ -500,6 +506,10 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, g
33104 + else
33105 + return -EPERM;
33106 + }
33107 ++
33108 ++ if (gr_check_group_change(new_rgid, new_egid, -1))
33109 ++ return -EPERM;
33110 ++
33111 + if (new_egid != old_egid) {
33112 + set_dumpable(current->mm, suid_dumpable);
33113 + smp_wmb();
33114 +@@ -507,6 +517,9 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, g
33115 + if (rgid != (gid_t) -1 ||
33116 + (egid != (gid_t) -1 && egid != old_rgid))
33117 + current->sgid = new_egid;
33118 ++
33119 ++ gr_set_role_label(current, current->uid, new_rgid);
33120 ++
33121 + current->fsgid = new_egid;
33122 + current->egid = new_egid;
33123 + current->gid = new_rgid;
33124 +@@ -529,11 +542,17 @@ SYSCALL_DEFINE1(setgid, gid_t, gid)
33125 + if (retval)
33126 + return retval;
33127 +
33128 ++ if (gr_check_group_change(gid, gid, gid))
33129 ++ return -EPERM;
33130 ++
33131 + if (capable(CAP_SETGID)) {
33132 + if (old_egid != gid) {
33133 + set_dumpable(current->mm, suid_dumpable);
33134 + smp_wmb();
33135 + }
33136 ++
33137 ++ gr_set_role_label(current, current->uid, gid);
33138 ++
33139 + current->gid = current->egid = current->sgid = current->fsgid = gid;
33140 + } else if ((gid == current->gid) || (gid == current->sgid)) {
33141 + if (old_egid != gid) {
33142 +@@ -571,6 +590,9 @@ static int set_user(uid_t new_ruid, int
33143 + set_dumpable(current->mm, suid_dumpable);
33144 + smp_wmb();
33145 + }
33146 ++
33147 ++ gr_set_role_label(current, new_ruid, current->gid);
33148 ++
33149 + current->uid = new_ruid;
33150 + return 0;
33151 + }
33152 +@@ -620,6 +642,9 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, u
33153 + return -EPERM;
33154 + }
33155 +
33156 ++ if (gr_check_user_change(new_ruid, new_euid, -1))
33157 ++ return -EPERM;
33158 ++
33159 + if (new_ruid != old_ruid && set_user(new_ruid, new_euid != old_euid) < 0)
33160 + return -EAGAIN;
33161 +
33162 +@@ -666,6 +691,12 @@ SYSCALL_DEFINE1(setuid, uid_t, uid)
33163 + old_suid = current->suid;
33164 + new_suid = old_suid;
33165 +
33166 ++ if (gr_check_crash_uid(uid))
33167 ++ return -EPERM;
33168 ++
33169 ++ if (gr_check_user_change(uid, uid, uid))
33170 ++ return -EPERM;
33171 ++
33172 + if (capable(CAP_SETUID)) {
33173 + if (uid != old_ruid && set_user(uid, old_euid != uid) < 0)
33174 + return -EAGAIN;
33175 +@@ -713,6 +744,10 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid,
33176 + (suid != current->euid) && (suid != current->suid))
33177 + return -EPERM;
33178 + }
33179 ++
33180 ++ if (gr_check_user_change(ruid, euid, -1))
33181 ++ return -EPERM;
33182 ++
33183 + if (ruid != (uid_t) -1) {
33184 + if (ruid != current->uid && set_user(ruid, euid != current->euid) < 0)
33185 + return -EAGAIN;
33186 +@@ -767,6 +802,10 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid,
33187 + (sgid != current->egid) && (sgid != current->sgid))
33188 + return -EPERM;
33189 + }
33190 ++
33191 ++ if (gr_check_group_change(rgid, egid, -1))
33192 ++ return -EPERM;
33193 ++
33194 + if (egid != (gid_t) -1) {
33195 + if (egid != current->egid) {
33196 + set_dumpable(current->mm, suid_dumpable);
33197 +@@ -775,8 +814,10 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid,
33198 + current->egid = egid;
33199 + }
33200 + current->fsgid = current->egid;
33201 +- if (rgid != (gid_t) -1)
33202 ++ if (rgid != (gid_t) -1) {
33203 ++ gr_set_role_label(current, current->uid, rgid);
33204 + current->gid = rgid;
33205 ++ }
33206 + if (sgid != (gid_t) -1)
33207 + current->sgid = sgid;
33208 +
33209 +@@ -811,6 +852,9 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
33210 + if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS))
33211 + return old_fsuid;
33212 +
33213 ++ if (gr_check_user_change(-1, -1, uid))
33214 ++ return old_fsuid;
33215 ++
33216 + if (uid == current->uid || uid == current->euid ||
33217 + uid == current->suid || uid == current->fsuid ||
33218 + capable(CAP_SETUID)) {
33219 +@@ -843,6 +887,9 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid)
33220 + if (gid == current->gid || gid == current->egid ||
33221 + gid == current->sgid || gid == current->fsgid ||
33222 + capable(CAP_SETGID)) {
33223 ++ if (gr_check_group_change(-1, -1, gid))
33224 ++ return old_fsgid;
33225 ++
33226 + if (gid != old_fsgid) {
33227 + set_dumpable(current->mm, suid_dumpable);
33228 + smp_wmb();
33229 +@@ -914,7 +961,10 @@ SYSCALL_DEFINE2(setpgid, pid_t, pid, pid
33230 + write_lock_irq(&tasklist_lock);
33231 +
33232 + err = -ESRCH;
33233 +- p = find_task_by_vpid(pid);
33234 ++ /* grsec: replaced find_task_by_vpid with equivalent call which
33235 ++ lacks the chroot restriction
33236 ++ */
33237 ++ p = pid_task(find_pid_ns(pid, current->nsproxy->pid_ns), PIDTYPE_PID);
33238 + if (!p)
33239 + goto out;
33240 +
33241 +@@ -1640,7 +1690,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsi
33242 + error = get_dumpable(current->mm);
33243 + break;
33244 + case PR_SET_DUMPABLE:
33245 +- if (arg2 < 0 || arg2 > 1) {
33246 ++ if (arg2 > 1) {
33247 + error = -EINVAL;
33248 + break;
33249 + }
33250 +diff -urNp linux-2.6.28.8/kernel/sysctl.c linux-2.6.28.8/kernel/sysctl.c
33251 +--- linux-2.6.28.8/kernel/sysctl.c 2009-02-06 16:47:45.000000000 -0500
33252 ++++ linux-2.6.28.8/kernel/sysctl.c 2009-03-07 04:29:14.000000000 -0500
33253 +@@ -61,6 +61,13 @@
33254 + static int deprecated_sysctl_warning(struct __sysctl_args *args);
33255 +
33256 + #if defined(CONFIG_SYSCTL)
33257 ++#include <linux/grsecurity.h>
33258 ++#include <linux/grinternal.h>
33259 ++
33260 ++extern __u32 gr_handle_sysctl(const ctl_table *table, const int op);
33261 ++extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
33262 ++ const int op);
33263 ++extern int gr_handle_chroot_sysctl(const int op);
33264 +
33265 + /* External variables not in a header file. */
33266 + extern int C_A_D;
33267 +@@ -152,6 +159,7 @@ static int proc_do_cad_pid(struct ctl_ta
33268 + static int proc_taint(struct ctl_table *table, int write, struct file *filp,
33269 + void __user *buffer, size_t *lenp, loff_t *ppos);
33270 + #endif
33271 ++extern ctl_table grsecurity_table[];
33272 +
33273 + static struct ctl_table root_table[];
33274 + static struct ctl_table_root sysctl_table_root;
33275 +@@ -184,6 +192,21 @@ extern struct ctl_table epoll_table[];
33276 + int sysctl_legacy_va_layout;
33277 + #endif
33278 +
33279 ++#ifdef CONFIG_PAX_SOFTMODE
33280 ++static ctl_table pax_table[] = {
33281 ++ {
33282 ++ .ctl_name = CTL_UNNUMBERED,
33283 ++ .procname = "softmode",
33284 ++ .data = &pax_softmode,
33285 ++ .maxlen = sizeof(unsigned int),
33286 ++ .mode = 0600,
33287 ++ .proc_handler = &proc_dointvec,
33288 ++ },
33289 ++
33290 ++ { .ctl_name = 0 }
33291 ++};
33292 ++#endif
33293 ++
33294 + extern int prove_locking;
33295 + extern int lock_stat;
33296 +
33297 +@@ -856,6 +879,25 @@ static struct ctl_table kern_table[] = {
33298 + .proc_handler = &scan_unevictable_handler,
33299 + },
33300 + #endif
33301 ++
33302 ++#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
33303 ++ {
33304 ++ .ctl_name = CTL_UNNUMBERED,
33305 ++ .procname = "grsecurity",
33306 ++ .mode = 0500,
33307 ++ .child = grsecurity_table,
33308 ++ },
33309 ++#endif
33310 ++
33311 ++#ifdef CONFIG_PAX_SOFTMODE
33312 ++ {
33313 ++ .ctl_name = CTL_UNNUMBERED,
33314 ++ .procname = "pax",
33315 ++ .mode = 0500,
33316 ++ .child = pax_table,
33317 ++ },
33318 ++#endif
33319 ++
33320 + /*
33321 + * NOTE: do not add new entries to this table unless you have read
33322 + * Documentation/sysctl/ctl_unnumbered.txt
33323 +@@ -1562,6 +1604,8 @@ static int do_sysctl_strategy(struct ctl
33324 + return 0;
33325 + }
33326 +
33327 ++static int sysctl_perm_nochk(struct ctl_table_root *root, struct ctl_table *table, int op);
33328 ++
33329 + static int parse_table(int __user *name, int nlen,
33330 + void __user *oldval, size_t __user *oldlenp,
33331 + void __user *newval, size_t newlen,
33332 +@@ -1580,7 +1624,7 @@ repeat:
33333 + if (n == table->ctl_name) {
33334 + int error;
33335 + if (table->child) {
33336 +- if (sysctl_perm(root, table, MAY_EXEC))
33337 ++ if (sysctl_perm_nochk(root, table, MAY_EXEC))
33338 + return -EPERM;
33339 + name++;
33340 + nlen--;
33341 +@@ -1665,6 +1709,33 @@ int sysctl_perm(struct ctl_table_root *r
33342 + int error;
33343 + int mode;
33344 +
33345 ++ if (table->parent != NULL && table->parent->procname != NULL &&
33346 ++ table->procname != NULL &&
33347 ++ gr_handle_sysctl_mod(table->parent->procname, table->procname, op))
33348 ++ return -EACCES;
33349 ++ if (gr_handle_chroot_sysctl(op))
33350 ++ return -EACCES;
33351 ++ error = gr_handle_sysctl(table, op);
33352 ++ if (error)
33353 ++ return error;
33354 ++
33355 ++ error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
33356 ++ if (error)
33357 ++ return error;
33358 ++
33359 ++ if (root->permissions)
33360 ++ mode = root->permissions(root, current->nsproxy, table);
33361 ++ else
33362 ++ mode = table->mode;
33363 ++
33364 ++ return test_perm(mode, op);
33365 ++}
33366 ++
33367 ++int sysctl_perm_nochk(struct ctl_table_root *root, struct ctl_table *table, int op)
33368 ++{
33369 ++ int error;
33370 ++ int mode;
33371 ++
33372 + error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
33373 + if (error)
33374 + return error;
33375 +diff -urNp linux-2.6.28.8/kernel/time/tick-broadcast.c linux-2.6.28.8/kernel/time/tick-broadcast.c
33376 +--- linux-2.6.28.8/kernel/time/tick-broadcast.c 2009-02-06 16:47:45.000000000 -0500
33377 ++++ linux-2.6.28.8/kernel/time/tick-broadcast.c 2009-02-21 09:37:50.000000000 -0500
33378 +@@ -114,7 +114,7 @@ int tick_device_uses_broadcast(struct cl
33379 + * then clear the broadcast bit.
33380 + */
33381 + if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) {
33382 +- int cpu = smp_processor_id();
33383 ++ cpu = smp_processor_id();
33384 +
33385 + cpu_clear(cpu, tick_broadcast_mask);
33386 + tick_broadcast_clear_oneshot(cpu);
33387 +diff -urNp linux-2.6.28.8/kernel/time.c linux-2.6.28.8/kernel/time.c
33388 +--- linux-2.6.28.8/kernel/time.c 2009-02-06 16:47:45.000000000 -0500
33389 ++++ linux-2.6.28.8/kernel/time.c 2009-02-21 09:37:50.000000000 -0500
33390 +@@ -92,6 +92,9 @@ SYSCALL_DEFINE1(stime, time_t __user *,
33391 + return err;
33392 +
33393 + do_settimeofday(&tv);
33394 ++
33395 ++ gr_log_timechange();
33396 ++
33397 + return 0;
33398 + }
33399 +
33400 +@@ -200,6 +203,8 @@ SYSCALL_DEFINE2(settimeofday, struct tim
33401 + return -EFAULT;
33402 + }
33403 +
33404 ++ gr_log_timechange();
33405 ++
33406 + return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
33407 + }
33408 +
33409 +@@ -238,7 +243,7 @@ EXPORT_SYMBOL(current_fs_time);
33410 + * Avoid unnecessary multiplications/divisions in the
33411 + * two most common HZ cases:
33412 + */
33413 +-unsigned int inline jiffies_to_msecs(const unsigned long j)
33414 ++inline unsigned int jiffies_to_msecs(const unsigned long j)
33415 + {
33416 + #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
33417 + return (MSEC_PER_SEC / HZ) * j;
33418 +@@ -254,7 +259,7 @@ unsigned int inline jiffies_to_msecs(con
33419 + }
33420 + EXPORT_SYMBOL(jiffies_to_msecs);
33421 +
33422 +-unsigned int inline jiffies_to_usecs(const unsigned long j)
33423 ++inline unsigned int jiffies_to_usecs(const unsigned long j)
33424 + {
33425 + #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
33426 + return (USEC_PER_SEC / HZ) * j;
33427 +diff -urNp linux-2.6.28.8/kernel/utsname_sysctl.c linux-2.6.28.8/kernel/utsname_sysctl.c
33428 +--- linux-2.6.28.8/kernel/utsname_sysctl.c 2009-02-06 16:47:45.000000000 -0500
33429 ++++ linux-2.6.28.8/kernel/utsname_sysctl.c 2009-02-21 09:37:50.000000000 -0500
33430 +@@ -123,7 +123,7 @@ static struct ctl_table uts_kern_table[]
33431 + .proc_handler = proc_do_uts_string,
33432 + .strategy = sysctl_uts_string,
33433 + },
33434 +- {}
33435 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
33436 + };
33437 +
33438 + static struct ctl_table uts_root_table[] = {
33439 +@@ -133,7 +133,7 @@ static struct ctl_table uts_root_table[]
33440 + .mode = 0555,
33441 + .child = uts_kern_table,
33442 + },
33443 +- {}
33444 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
33445 + };
33446 +
33447 + static int __init utsname_sysctl_init(void)
33448 +diff -urNp linux-2.6.28.8/lib/radix-tree.c linux-2.6.28.8/lib/radix-tree.c
33449 +--- linux-2.6.28.8/lib/radix-tree.c 2009-02-06 16:47:45.000000000 -0500
33450 ++++ linux-2.6.28.8/lib/radix-tree.c 2009-02-21 09:37:50.000000000 -0500
33451 +@@ -81,7 +81,7 @@ struct radix_tree_preload {
33452 + int nr;
33453 + struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
33454 + };
33455 +-DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
33456 ++DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads);
33457 +
33458 + static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
33459 + {
33460 +diff -urNp linux-2.6.28.8/localversion-grsec linux-2.6.28.8/localversion-grsec
33461 +--- linux-2.6.28.8/localversion-grsec 1969-12-31 19:00:00.000000000 -0500
33462 ++++ linux-2.6.28.8/localversion-grsec 2009-02-21 09:37:50.000000000 -0500
33463 +@@ -0,0 +1 @@
33464 ++-grsec
33465 +diff -urNp linux-2.6.28.8/Makefile linux-2.6.28.8/Makefile
33466 +--- linux-2.6.28.8/Makefile 2009-03-07 10:24:49.000000000 -0500
33467 ++++ linux-2.6.28.8/Makefile 2009-03-07 10:29:51.000000000 -0500
33468 +@@ -221,7 +221,7 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH"
33469 +
33470 + HOSTCC = gcc
33471 + HOSTCXX = g++
33472 +-HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
33473 ++HOSTCFLAGS = -Wall -W -Wno-unused -Wno-sign-compare -Wstrict-prototypes -O2 -fomit-frame-pointer
33474 + HOSTCXXFLAGS = -O2
33475 +
33476 + # Decide whether to build built-in, modular, or both.
33477 +@@ -619,7 +619,7 @@ export mod_strip_cmd
33478 +
33479 +
33480 + ifeq ($(KBUILD_EXTMOD),)
33481 +-core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
33482 ++core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
33483 +
33484 + vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
33485 + $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
33486 +diff -urNp linux-2.6.28.8/mm/filemap.c linux-2.6.28.8/mm/filemap.c
33487 +--- linux-2.6.28.8/mm/filemap.c 2009-02-06 16:47:45.000000000 -0500
33488 ++++ linux-2.6.28.8/mm/filemap.c 2009-02-21 09:37:50.000000000 -0500
33489 +@@ -1609,7 +1609,7 @@ int generic_file_mmap(struct file * file
33490 + struct address_space *mapping = file->f_mapping;
33491 +
33492 + if (!mapping->a_ops->readpage)
33493 +- return -ENOEXEC;
33494 ++ return -ENODEV;
33495 + file_accessed(file);
33496 + vma->vm_ops = &generic_file_vm_ops;
33497 + vma->vm_flags |= VM_CAN_NONLINEAR;
33498 +@@ -1970,6 +1970,7 @@ inline int generic_write_checks(struct f
33499 + *pos = i_size_read(inode);
33500 +
33501 + if (limit != RLIM_INFINITY) {
33502 ++ gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
33503 + if (*pos >= limit) {
33504 + send_sig(SIGXFSZ, current, 0);
33505 + return -EFBIG;
33506 +diff -urNp linux-2.6.28.8/mm/fremap.c linux-2.6.28.8/mm/fremap.c
33507 +--- linux-2.6.28.8/mm/fremap.c 2009-02-06 16:47:45.000000000 -0500
33508 ++++ linux-2.6.28.8/mm/fremap.c 2009-02-21 09:37:50.000000000 -0500
33509 +@@ -153,6 +153,13 @@ SYSCALL_DEFINE5(remap_file_pages, unsign
33510 + retry:
33511 + vma = find_vma(mm, start);
33512 +
33513 ++#ifdef CONFIG_PAX_SEGMEXEC
33514 ++ if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC)) {
33515 ++ up_read(&mm->mmap_sem);
33516 ++ return err;
33517 ++ }
33518 ++#endif
33519 ++
33520 + /*
33521 + * Make sure the vma is shared, that it supports prefaulting,
33522 + * and that the remapped range is valid and fully within
33523 +diff -urNp linux-2.6.28.8/mm/hugetlb.c linux-2.6.28.8/mm/hugetlb.c
33524 +--- linux-2.6.28.8/mm/hugetlb.c 2009-02-06 16:47:45.000000000 -0500
33525 ++++ linux-2.6.28.8/mm/hugetlb.c 2009-02-21 09:37:50.000000000 -0500
33526 +@@ -1832,6 +1832,26 @@ static int unmap_ref_private(struct mm_s
33527 + return 1;
33528 + }
33529 +
33530 ++#ifdef CONFIG_PAX_SEGMEXEC
33531 ++static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m)
33532 ++{
33533 ++ struct mm_struct *mm = vma->vm_mm;
33534 ++ struct vm_area_struct *vma_m;
33535 ++ unsigned long address_m;
33536 ++ pte_t *ptep_m;
33537 ++
33538 ++ vma_m = pax_find_mirror_vma(vma);
33539 ++ if (!vma_m)
33540 ++ return;
33541 ++
33542 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33543 ++ address_m = address + SEGMEXEC_TASK_SIZE;
33544 ++ ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK);
33545 ++ get_page(page_m);
33546 ++ set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0));
33547 ++}
33548 ++#endif
33549 ++
33550 + static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
33551 + unsigned long address, pte_t *ptep, pte_t pte,
33552 + struct page *pagecache_page)
33553 +@@ -1903,6 +1923,11 @@ retry_avoidcopy:
33554 + huge_ptep_clear_flush(vma, address, ptep);
33555 + set_huge_pte_at(mm, address, ptep,
33556 + make_huge_pte(vma, new_page, 1));
33557 ++
33558 ++#ifdef CONFIG_PAX_SEGMEXEC
33559 ++ pax_mirror_huge_pte(vma, address, new_page);
33560 ++#endif
33561 ++
33562 + /* Make the old page be freed below */
33563 + new_page = old_page;
33564 + }
33565 +@@ -2012,6 +2037,10 @@ retry:
33566 + && (vma->vm_flags & VM_SHARED)));
33567 + set_huge_pte_at(mm, address, ptep, new_pte);
33568 +
33569 ++#ifdef CONFIG_PAX_SEGMEXEC
33570 ++ pax_mirror_huge_pte(vma, address, page);
33571 ++#endif
33572 ++
33573 + if (write_access && !(vma->vm_flags & VM_SHARED)) {
33574 + /* Optimization, do the COW without a second fault */
33575 + ret = hugetlb_cow(mm, vma, address, ptep, new_pte, page);
33576 +@@ -2040,6 +2069,28 @@ int hugetlb_fault(struct mm_struct *mm,
33577 + static DEFINE_MUTEX(hugetlb_instantiation_mutex);
33578 + struct hstate *h = hstate_vma(vma);
33579 +
33580 ++#ifdef CONFIG_PAX_SEGMEXEC
33581 ++ struct vm_area_struct *vma_m;
33582 ++
33583 ++ vma_m = pax_find_mirror_vma(vma);
33584 ++ if (vma_m) {
33585 ++ unsigned long address_m;
33586 ++
33587 ++ if (vma->vm_start > vma_m->vm_start) {
33588 ++ address_m = address;
33589 ++ address -= SEGMEXEC_TASK_SIZE;
33590 ++ vma = vma_m;
33591 ++ h = hstate_vma(vma);
33592 ++ } else
33593 ++ address_m = address + SEGMEXEC_TASK_SIZE;
33594 ++
33595 ++ if (!huge_pte_alloc(mm, address_m, huge_page_size(h)))
33596 ++ return VM_FAULT_OOM;
33597 ++ address_m &= HPAGE_MASK;
33598 ++ unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE, NULL);
33599 ++ }
33600 ++#endif
33601 ++
33602 + ptep = huge_pte_alloc(mm, address, huge_page_size(h));
33603 + if (!ptep)
33604 + return VM_FAULT_OOM;
33605 +diff -urNp linux-2.6.28.8/mm/madvise.c linux-2.6.28.8/mm/madvise.c
33606 +--- linux-2.6.28.8/mm/madvise.c 2009-02-06 16:47:45.000000000 -0500
33607 ++++ linux-2.6.28.8/mm/madvise.c 2009-02-21 09:37:50.000000000 -0500
33608 +@@ -43,6 +43,10 @@ static long madvise_behavior(struct vm_a
33609 + pgoff_t pgoff;
33610 + int new_flags = vma->vm_flags;
33611 +
33612 ++#ifdef CONFIG_PAX_SEGMEXEC
33613 ++ struct vm_area_struct *vma_m;
33614 ++#endif
33615 ++
33616 + switch (behavior) {
33617 + case MADV_NORMAL:
33618 + new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
33619 +@@ -92,6 +96,13 @@ success:
33620 + /*
33621 + * vm_flags is protected by the mmap_sem held in write mode.
33622 + */
33623 ++
33624 ++#ifdef CONFIG_PAX_SEGMEXEC
33625 ++ vma_m = pax_find_mirror_vma(vma);
33626 ++ if (vma_m)
33627 ++ vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT);
33628 ++#endif
33629 ++
33630 + vma->vm_flags = new_flags;
33631 +
33632 + out:
33633 +@@ -236,6 +247,17 @@ madvise_vma(struct vm_area_struct *vma,
33634 +
33635 + case MADV_DONTNEED:
33636 + error = madvise_dontneed(vma, prev, start, end);
33637 ++
33638 ++#ifdef CONFIG_PAX_SEGMEXEC
33639 ++ if (!error) {
33640 ++ struct vm_area_struct *vma_m, *prev_m;
33641 ++
33642 ++ vma_m = pax_find_mirror_vma(vma);
33643 ++ if (vma_m)
33644 ++ error = madvise_dontneed(vma_m, &prev_m, start + SEGMEXEC_TASK_SIZE, end + SEGMEXEC_TASK_SIZE);
33645 ++ }
33646 ++#endif
33647 ++
33648 + break;
33649 +
33650 + default:
33651 +@@ -308,6 +330,16 @@ SYSCALL_DEFINE3(madvise, unsigned long,
33652 + if (end < start)
33653 + goto out;
33654 +
33655 ++#ifdef CONFIG_PAX_SEGMEXEC
33656 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
33657 ++ if (end > SEGMEXEC_TASK_SIZE)
33658 ++ goto out;
33659 ++ } else
33660 ++#endif
33661 ++
33662 ++ if (end > TASK_SIZE)
33663 ++ goto out;
33664 ++
33665 + error = 0;
33666 + if (end == start)
33667 + goto out;
33668 +diff -urNp linux-2.6.28.8/mm/memory.c linux-2.6.28.8/mm/memory.c
33669 +--- linux-2.6.28.8/mm/memory.c 2009-02-07 16:10:45.000000000 -0500
33670 ++++ linux-2.6.28.8/mm/memory.c 2009-02-21 09:37:50.000000000 -0500
33671 +@@ -47,6 +47,7 @@
33672 + #include <linux/pagemap.h>
33673 + #include <linux/rmap.h>
33674 + #include <linux/module.h>
33675 ++#include <linux/security.h>
33676 + #include <linux/delayacct.h>
33677 + #include <linux/init.h>
33678 + #include <linux/writeback.h>
33679 +@@ -1151,11 +1152,11 @@ int __get_user_pages(struct task_struct
33680 + vm_flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
33681 + i = 0;
33682 +
33683 +- do {
33684 ++ while (len) {
33685 + struct vm_area_struct *vma;
33686 + unsigned int foll_flags;
33687 +
33688 +- vma = find_extend_vma(mm, start);
33689 ++ vma = find_vma(mm, start);
33690 + if (!vma && in_gate_area(tsk, start)) {
33691 + unsigned long pg = start & PAGE_MASK;
33692 + struct vm_area_struct *gate_vma = get_gate_vma(tsk);
33693 +@@ -1197,7 +1198,7 @@ int __get_user_pages(struct task_struct
33694 + continue;
33695 + }
33696 +
33697 +- if (!vma ||
33698 ++ if (!vma || start < vma->vm_start ||
33699 + (vma->vm_flags & (VM_IO | VM_PFNMAP)) ||
33700 + (!ignore && !(vm_flags & vma->vm_flags)))
33701 + return i ? : -EFAULT;
33702 +@@ -1271,7 +1272,7 @@ int __get_user_pages(struct task_struct
33703 + start += PAGE_SIZE;
33704 + len--;
33705 + } while (len && start < vma->vm_end);
33706 +- } while (len);
33707 ++ }
33708 + return i;
33709 + }
33710 +
33711 +@@ -1760,6 +1761,186 @@ static inline void cow_user_page(struct
33712 + copy_user_highpage(dst, src, va, vma);
33713 + }
33714 +
33715 ++#ifdef CONFIG_PAX_SEGMEXEC
33716 ++static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd)
33717 ++{
33718 ++ struct mm_struct *mm = vma->vm_mm;
33719 ++ spinlock_t *ptl;
33720 ++ pte_t *pte, entry;
33721 ++
33722 ++ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
33723 ++ entry = *pte;
33724 ++ if (!pte_present(entry)) {
33725 ++ if (!pte_none(entry)) {
33726 ++ BUG_ON(pte_file(entry));
33727 ++ free_swap_and_cache(pte_to_swp_entry(entry));
33728 ++ pte_clear_not_present_full(mm, address, pte, 0);
33729 ++ }
33730 ++ } else {
33731 ++ struct page *page;
33732 ++
33733 ++ flush_cache_page(vma, address, pte_pfn(entry));
33734 ++ entry = ptep_clear_flush(vma, address, pte);
33735 ++ BUG_ON(pte_dirty(entry));
33736 ++ page = vm_normal_page(vma, address, entry);
33737 ++ if (page) {
33738 ++ update_hiwater_rss(mm);
33739 ++ if (PageAnon(page))
33740 ++ dec_mm_counter(mm, anon_rss);
33741 ++ else
33742 ++ dec_mm_counter(mm, file_rss);
33743 ++ page_remove_rmap(page, vma);
33744 ++ page_cache_release(page);
33745 ++ }
33746 ++ }
33747 ++ pte_unmap_unlock(pte, ptl);
33748 ++}
33749 ++
33750 ++/* PaX: if vma is mirrored, synchronize the mirror's PTE
33751 ++ *
33752 ++ * the ptl of the lower mapped page is held on entry and is not released on exit
33753 ++ * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
33754 ++ */
33755 ++static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
33756 ++{
33757 ++ struct mm_struct *mm = vma->vm_mm;
33758 ++ unsigned long address_m;
33759 ++ spinlock_t *ptl_m;
33760 ++ struct vm_area_struct *vma_m;
33761 ++ pmd_t *pmd_m;
33762 ++ pte_t *pte_m, entry_m;
33763 ++
33764 ++ BUG_ON(!page_m || !PageAnon(page_m));
33765 ++
33766 ++ vma_m = pax_find_mirror_vma(vma);
33767 ++ if (!vma_m)
33768 ++ return;
33769 ++
33770 ++ BUG_ON(!PageLocked(page_m));
33771 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33772 ++ address_m = address + SEGMEXEC_TASK_SIZE;
33773 ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
33774 ++ pte_m = pte_offset_map_nested(pmd_m, address_m);
33775 ++ ptl_m = pte_lockptr(mm, pmd_m);
33776 ++ if (ptl != ptl_m) {
33777 ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
33778 ++ if (!pte_none(*pte_m))
33779 ++ goto out;
33780 ++ }
33781 ++
33782 ++ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
33783 ++ page_cache_get(page_m);
33784 ++ page_add_anon_rmap(page_m, vma_m, address_m);
33785 ++ inc_mm_counter(mm, anon_rss);
33786 ++ set_pte_at(mm, address_m, pte_m, entry_m);
33787 ++ update_mmu_cache(vma_m, address_m, entry_m);
33788 ++out:
33789 ++ if (ptl != ptl_m)
33790 ++ spin_unlock(ptl_m);
33791 ++ pte_unmap_nested(pte_m);
33792 ++ unlock_page(page_m);
33793 ++}
33794 ++
33795 ++void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
33796 ++{
33797 ++ struct mm_struct *mm = vma->vm_mm;
33798 ++ unsigned long address_m;
33799 ++ spinlock_t *ptl_m;
33800 ++ struct vm_area_struct *vma_m;
33801 ++ pmd_t *pmd_m;
33802 ++ pte_t *pte_m, entry_m;
33803 ++
33804 ++ BUG_ON(!page_m || PageAnon(page_m));
33805 ++
33806 ++ vma_m = pax_find_mirror_vma(vma);
33807 ++ if (!vma_m)
33808 ++ return;
33809 ++
33810 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33811 ++ address_m = address + SEGMEXEC_TASK_SIZE;
33812 ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
33813 ++ pte_m = pte_offset_map_nested(pmd_m, address_m);
33814 ++ ptl_m = pte_lockptr(mm, pmd_m);
33815 ++ if (ptl != ptl_m) {
33816 ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
33817 ++ if (!pte_none(*pte_m))
33818 ++ goto out;
33819 ++ }
33820 ++
33821 ++ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
33822 ++ page_cache_get(page_m);
33823 ++ page_add_file_rmap(page_m);
33824 ++ inc_mm_counter(mm, file_rss);
33825 ++ set_pte_at(mm, address_m, pte_m, entry_m);
33826 ++ update_mmu_cache(vma_m, address_m, entry_m);
33827 ++out:
33828 ++ if (ptl != ptl_m)
33829 ++ spin_unlock(ptl_m);
33830 ++ pte_unmap_nested(pte_m);
33831 ++}
33832 ++
33833 ++static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl)
33834 ++{
33835 ++ struct mm_struct *mm = vma->vm_mm;
33836 ++ unsigned long address_m;
33837 ++ spinlock_t *ptl_m;
33838 ++ struct vm_area_struct *vma_m;
33839 ++ pmd_t *pmd_m;
33840 ++ pte_t *pte_m, entry_m;
33841 ++
33842 ++ vma_m = pax_find_mirror_vma(vma);
33843 ++ if (!vma_m)
33844 ++ return;
33845 ++
33846 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33847 ++ address_m = address + SEGMEXEC_TASK_SIZE;
33848 ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
33849 ++ pte_m = pte_offset_map_nested(pmd_m, address_m);
33850 ++ ptl_m = pte_lockptr(mm, pmd_m);
33851 ++ if (ptl != ptl_m) {
33852 ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
33853 ++ if (!pte_none(*pte_m))
33854 ++ goto out;
33855 ++ }
33856 ++
33857 ++ entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
33858 ++ set_pte_at(mm, address_m, pte_m, entry_m);
33859 ++out:
33860 ++ if (ptl != ptl_m)
33861 ++ spin_unlock(ptl_m);
33862 ++ pte_unmap_nested(pte_m);
33863 ++}
33864 ++
33865 ++static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, pmd_t *pmd, spinlock_t *ptl)
33866 ++{
33867 ++ struct page *page_m;
33868 ++ pte_t entry;
33869 ++
33870 ++ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC))
33871 ++ goto out;
33872 ++
33873 ++ entry = *pte;
33874 ++ page_m = vm_normal_page(vma, address, entry);
33875 ++ if (!page_m)
33876 ++ pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl);
33877 ++ else if (PageAnon(page_m)) {
33878 ++ if (pax_find_mirror_vma(vma)) {
33879 ++ pte_unmap_unlock(pte, ptl);
33880 ++ lock_page(page_m);
33881 ++ pte = pte_offset_map_lock(vma->vm_mm, pmd, address, &ptl);
33882 ++ if (pte_same(entry, *pte))
33883 ++ pax_mirror_anon_pte(vma, address, page_m, ptl);
33884 ++ else
33885 ++ unlock_page(page_m);
33886 ++ }
33887 ++ } else
33888 ++ pax_mirror_file_pte(vma, address, page_m, ptl);
33889 ++
33890 ++out:
33891 ++ pte_unmap_unlock(pte, ptl);
33892 ++}
33893 ++#endif
33894 ++
33895 + /*
33896 + * This routine handles present pages, when users try to write
33897 + * to a shared page. It is done by copying the page to a new address
33898 +@@ -1897,6 +2078,12 @@ gotten:
33899 + */
33900 + page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
33901 + if (likely(pte_same(*page_table, orig_pte))) {
33902 ++
33903 ++#ifdef CONFIG_PAX_SEGMEXEC
33904 ++ if (pax_find_mirror_vma(vma))
33905 ++ BUG_ON(!trylock_page(new_page));
33906 ++#endif
33907 ++
33908 + if (old_page) {
33909 + if (!PageAnon(old_page)) {
33910 + dec_mm_counter(mm, file_rss);
33911 +@@ -1947,6 +2134,10 @@ gotten:
33912 + page_remove_rmap(old_page, vma);
33913 + }
33914 +
33915 ++#ifdef CONFIG_PAX_SEGMEXEC
33916 ++ pax_mirror_anon_pte(vma, address, new_page, ptl);
33917 ++#endif
33918 ++
33919 + /* Free the old page.. */
33920 + new_page = old_page;
33921 + ret |= VM_FAULT_WRITE;
33922 +@@ -2206,6 +2397,7 @@ int vmtruncate(struct inode * inode, lof
33923 + unsigned long limit;
33924 +
33925 + limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
33926 ++ gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
33927 + if (limit != RLIM_INFINITY && offset > limit)
33928 + goto out_sig;
33929 + if (offset > inode->i_sb->s_maxbytes)
33930 +@@ -2357,6 +2549,11 @@ static int do_swap_page(struct mm_struct
33931 + swap_free(entry);
33932 + if (vm_swap_full() || (vma->vm_flags & VM_LOCKED) || PageMlocked(page))
33933 + remove_exclusive_swap_page(page);
33934 ++
33935 ++#ifdef CONFIG_PAX_SEGMEXEC
33936 ++ if (write_access || !pax_find_mirror_vma(vma))
33937 ++#endif
33938 ++
33939 + unlock_page(page);
33940 +
33941 + if (write_access) {
33942 +@@ -2368,6 +2565,11 @@ static int do_swap_page(struct mm_struct
33943 +
33944 + /* No need to invalidate - it was non-present before */
33945 + update_mmu_cache(vma, address, pte);
33946 ++
33947 ++#ifdef CONFIG_PAX_SEGMEXEC
33948 ++ pax_mirror_anon_pte(vma, address, page, ptl);
33949 ++#endif
33950 ++
33951 + unlock:
33952 + pte_unmap_unlock(page_table, ptl);
33953 + out:
33954 +@@ -2412,6 +2614,12 @@ static int do_anonymous_page(struct mm_s
33955 + page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
33956 + if (!pte_none(*page_table))
33957 + goto release;
33958 ++
33959 ++#ifdef CONFIG_PAX_SEGMEXEC
33960 ++ if (pax_find_mirror_vma(vma))
33961 ++ BUG_ON(!trylock_page(page));
33962 ++#endif
33963 ++
33964 + inc_mm_counter(mm, anon_rss);
33965 + SetPageSwapBacked(page);
33966 + lru_cache_add_active_or_unevictable(page, vma);
33967 +@@ -2420,6 +2628,11 @@ static int do_anonymous_page(struct mm_s
33968 +
33969 + /* No need to invalidate - it was non-present before */
33970 + update_mmu_cache(vma, address, entry);
33971 ++
33972 ++#ifdef CONFIG_PAX_SEGMEXEC
33973 ++ pax_mirror_anon_pte(vma, address, page, ptl);
33974 ++#endif
33975 ++
33976 + unlock:
33977 + pte_unmap_unlock(page_table, ptl);
33978 + return 0;
33979 +@@ -2556,6 +2769,12 @@ static int __do_fault(struct mm_struct *
33980 + */
33981 + /* Only go through if we didn't race with anybody else... */
33982 + if (likely(pte_same(*page_table, orig_pte))) {
33983 ++
33984 ++#ifdef CONFIG_PAX_SEGMEXEC
33985 ++ if (anon && pax_find_mirror_vma(vma))
33986 ++ BUG_ON(!trylock_page(page));
33987 ++#endif
33988 ++
33989 + flush_icache_page(vma, page);
33990 + entry = mk_pte(page, vma->vm_page_prot);
33991 + if (flags & FAULT_FLAG_WRITE)
33992 +@@ -2578,6 +2797,14 @@ static int __do_fault(struct mm_struct *
33993 +
33994 + /* no need to invalidate: a not-present page won't be cached */
33995 + update_mmu_cache(vma, address, entry);
33996 ++
33997 ++#ifdef CONFIG_PAX_SEGMEXEC
33998 ++ if (anon)
33999 ++ pax_mirror_anon_pte(vma, address, page, ptl);
34000 ++ else
34001 ++ pax_mirror_file_pte(vma, address, page, ptl);
34002 ++#endif
34003 ++
34004 + } else {
34005 + if (charged)
34006 + mem_cgroup_uncharge_page(page);
34007 +@@ -2711,6 +2938,12 @@ static inline int handle_pte_fault(struc
34008 + if (write_access)
34009 + flush_tlb_page(vma, address);
34010 + }
34011 ++
34012 ++#ifdef CONFIG_PAX_SEGMEXEC
34013 ++ pax_mirror_pte(vma, address, pte, pmd, ptl);
34014 ++ return 0;
34015 ++#endif
34016 ++
34017 + unlock:
34018 + pte_unmap_unlock(pte, ptl);
34019 + return 0;
34020 +@@ -2727,6 +2960,10 @@ int handle_mm_fault(struct mm_struct *mm
34021 + pmd_t *pmd;
34022 + pte_t *pte;
34023 +
34024 ++#ifdef CONFIG_PAX_SEGMEXEC
34025 ++ struct vm_area_struct *vma_m;
34026 ++#endif
34027 ++
34028 + __set_current_state(TASK_RUNNING);
34029 +
34030 + count_vm_event(PGFAULT);
34031 +@@ -2734,6 +2971,34 @@ int handle_mm_fault(struct mm_struct *mm
34032 + if (unlikely(is_vm_hugetlb_page(vma)))
34033 + return hugetlb_fault(mm, vma, address, write_access);
34034 +
34035 ++#ifdef CONFIG_PAX_SEGMEXEC
34036 ++ vma_m = pax_find_mirror_vma(vma);
34037 ++ if (vma_m) {
34038 ++ unsigned long address_m;
34039 ++ pgd_t *pgd_m;
34040 ++ pud_t *pud_m;
34041 ++ pmd_t *pmd_m;
34042 ++
34043 ++ if (vma->vm_start > vma_m->vm_start) {
34044 ++ address_m = address;
34045 ++ address -= SEGMEXEC_TASK_SIZE;
34046 ++ vma = vma_m;
34047 ++ } else
34048 ++ address_m = address + SEGMEXEC_TASK_SIZE;
34049 ++
34050 ++ pgd_m = pgd_offset(mm, address_m);
34051 ++ pud_m = pud_alloc(mm, pgd_m, address_m);
34052 ++ if (!pud_m)
34053 ++ return VM_FAULT_OOM;
34054 ++ pmd_m = pmd_alloc(mm, pud_m, address_m);
34055 ++ if (!pmd_m)
34056 ++ return VM_FAULT_OOM;
34057 ++ if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
34058 ++ return VM_FAULT_OOM;
34059 ++ pax_unmap_mirror_pte(vma_m, address_m, pmd_m);
34060 ++ }
34061 ++#endif
34062 ++
34063 + pgd = pgd_offset(mm, address);
34064 + pud = pud_alloc(mm, pgd, address);
34065 + if (!pud)
34066 +@@ -2831,7 +3096,7 @@ static int __init gate_vma_init(void)
34067 + gate_vma.vm_start = FIXADDR_USER_START;
34068 + gate_vma.vm_end = FIXADDR_USER_END;
34069 + gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
34070 +- gate_vma.vm_page_prot = __P101;
34071 ++ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
34072 + /*
34073 + * Make sure the vDSO gets into every core dump.
34074 + * Dumping its contents makes post-mortem fully interpretable later
34075 +diff -urNp linux-2.6.28.8/mm/mempolicy.c linux-2.6.28.8/mm/mempolicy.c
34076 +--- linux-2.6.28.8/mm/mempolicy.c 2009-02-06 16:47:45.000000000 -0500
34077 ++++ linux-2.6.28.8/mm/mempolicy.c 2009-02-21 09:37:50.000000000 -0500
34078 +@@ -551,6 +551,10 @@ static int mbind_range(struct vm_area_st
34079 + struct vm_area_struct *next;
34080 + int err;
34081 +
34082 ++#ifdef CONFIG_PAX_SEGMEXEC
34083 ++ struct vm_area_struct *vma_m;
34084 ++#endif
34085 ++
34086 + err = 0;
34087 + for (; vma && vma->vm_start < end; vma = next) {
34088 + next = vma->vm_next;
34089 +@@ -562,6 +566,16 @@ static int mbind_range(struct vm_area_st
34090 + err = policy_vma(vma, new);
34091 + if (err)
34092 + break;
34093 ++
34094 ++#ifdef CONFIG_PAX_SEGMEXEC
34095 ++ vma_m = pax_find_mirror_vma(vma);
34096 ++ if (vma_m) {
34097 ++ err = policy_vma(vma_m, new);
34098 ++ if (err)
34099 ++ break;
34100 ++ }
34101 ++#endif
34102 ++
34103 + }
34104 + return err;
34105 + }
34106 +@@ -954,6 +968,17 @@ static long do_mbind(unsigned long start
34107 +
34108 + if (end < start)
34109 + return -EINVAL;
34110 ++
34111 ++#ifdef CONFIG_PAX_SEGMEXEC
34112 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC) {
34113 ++ if (end > SEGMEXEC_TASK_SIZE)
34114 ++ return -EINVAL;
34115 ++ } else
34116 ++#endif
34117 ++
34118 ++ if (end > TASK_SIZE)
34119 ++ return -EINVAL;
34120 ++
34121 + if (end == start)
34122 + return 0;
34123 +
34124 +diff -urNp linux-2.6.28.8/mm/migrate.c linux-2.6.28.8/mm/migrate.c
34125 +--- linux-2.6.28.8/mm/migrate.c 2009-02-06 16:47:45.000000000 -0500
34126 ++++ linux-2.6.28.8/mm/migrate.c 2009-02-21 09:37:50.000000000 -0500
34127 +@@ -1139,7 +1139,7 @@ int migrate_vmas(struct mm_struct *mm, c
34128 + struct vm_area_struct *vma;
34129 + int err = 0;
34130 +
34131 +- for(vma = mm->mmap; vma->vm_next && !err; vma = vma->vm_next) {
34132 ++ for(vma = mm->mmap; vma && !err; vma = vma->vm_next) {
34133 + if (vma->vm_ops && vma->vm_ops->migrate) {
34134 + err = vma->vm_ops->migrate(vma, to, from, flags);
34135 + if (err)
34136 +diff -urNp linux-2.6.28.8/mm/mlock.c linux-2.6.28.8/mm/mlock.c
34137 +--- linux-2.6.28.8/mm/mlock.c 2009-02-07 16:10:45.000000000 -0500
34138 ++++ linux-2.6.28.8/mm/mlock.c 2009-02-21 09:37:50.000000000 -0500
34139 +@@ -13,6 +13,7 @@
34140 + #include <linux/pagemap.h>
34141 + #include <linux/mempolicy.h>
34142 + #include <linux/syscalls.h>
34143 ++#include <linux/security.h>
34144 + #include <linux/sched.h>
34145 + #include <linux/module.h>
34146 + #include <linux/rmap.h>
34147 +@@ -452,6 +453,17 @@ static int do_mlock(unsigned long start,
34148 + return -EINVAL;
34149 + if (end == start)
34150 + return 0;
34151 ++
34152 ++#ifdef CONFIG_PAX_SEGMEXEC
34153 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
34154 ++ if (end > SEGMEXEC_TASK_SIZE)
34155 ++ return -EINVAL;
34156 ++ } else
34157 ++#endif
34158 ++
34159 ++ if (end > TASK_SIZE)
34160 ++ return -EINVAL;
34161 ++
34162 + vma = find_vma_prev(current->mm, start, &prev);
34163 + if (!vma || vma->vm_start > start)
34164 + return -ENOMEM;
34165 +@@ -511,6 +523,7 @@ SYSCALL_DEFINE2(mlock, unsigned long, st
34166 + lock_limit >>= PAGE_SHIFT;
34167 +
34168 + /* check against resource limits */
34169 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
34170 + if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
34171 + error = do_mlock(start, len, 1);
34172 + up_write(&current->mm->mmap_sem);
34173 +@@ -532,10 +545,10 @@ SYSCALL_DEFINE2(munlock, unsigned long,
34174 + static int do_mlockall(int flags)
34175 + {
34176 + struct vm_area_struct * vma, * prev = NULL;
34177 +- unsigned int def_flags = 0;
34178 ++ unsigned int def_flags = current->mm->def_flags & ~VM_LOCKED;
34179 +
34180 + if (flags & MCL_FUTURE)
34181 +- def_flags = VM_LOCKED;
34182 ++ def_flags |= VM_LOCKED;
34183 + current->mm->def_flags = def_flags;
34184 + if (flags == MCL_FUTURE)
34185 + goto out;
34186 +@@ -543,6 +556,12 @@ static int do_mlockall(int flags)
34187 + for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
34188 + unsigned int newflags;
34189 +
34190 ++#ifdef CONFIG_PAX_SEGMEXEC
34191 ++ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
34192 ++ break;
34193 ++#endif
34194 ++
34195 ++ BUG_ON(vma->vm_end > TASK_SIZE);
34196 + newflags = vma->vm_flags | VM_LOCKED;
34197 + if (!(flags & MCL_CURRENT))
34198 + newflags &= ~VM_LOCKED;
34199 +@@ -574,6 +593,7 @@ SYSCALL_DEFINE1(mlockall, int, flags)
34200 + lock_limit >>= PAGE_SHIFT;
34201 +
34202 + ret = -ENOMEM;
34203 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
34204 + if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
34205 + capable(CAP_IPC_LOCK))
34206 + ret = do_mlockall(flags);
34207 +diff -urNp linux-2.6.28.8/mm/mmap.c linux-2.6.28.8/mm/mmap.c
34208 +--- linux-2.6.28.8/mm/mmap.c 2009-02-08 00:54:27.000000000 -0500
34209 ++++ linux-2.6.28.8/mm/mmap.c 2009-02-21 09:37:50.000000000 -0500
34210 +@@ -43,6 +43,16 @@
34211 + #define arch_rebalance_pgtables(addr, len) (addr)
34212 + #endif
34213 +
34214 ++static inline void verify_mm_writelocked(struct mm_struct *mm)
34215 ++{
34216 ++#if defined(CONFIG_DEBUG_VM) || defined(CONFIG_PAX)
34217 ++ if (unlikely(down_read_trylock(&mm->mmap_sem))) {
34218 ++ up_read(&mm->mmap_sem);
34219 ++ BUG();
34220 ++ }
34221 ++#endif
34222 ++}
34223 ++
34224 + static void unmap_region(struct mm_struct *mm,
34225 + struct vm_area_struct *vma, struct vm_area_struct *prev,
34226 + unsigned long start, unsigned long end);
34227 +@@ -68,16 +78,25 @@ static void unmap_region(struct mm_struc
34228 + * x: (no) no x: (no) yes x: (no) yes x: (yes) yes
34229 + *
34230 + */
34231 +-pgprot_t protection_map[16] = {
34232 ++pgprot_t protection_map[16] __read_only = {
34233 + __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
34234 + __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
34235 + };
34236 +
34237 + pgprot_t vm_get_page_prot(unsigned long vm_flags)
34238 + {
34239 +- return __pgprot(pgprot_val(protection_map[vm_flags &
34240 ++ pgprot_t prot = __pgprot(pgprot_val(protection_map[vm_flags &
34241 + (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]) |
34242 + pgprot_val(arch_vm_get_page_prot(vm_flags)));
34243 ++
34244 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
34245 ++ if (!nx_enabled &&
34246 ++ (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC &&
34247 ++ (vm_flags & (VM_READ | VM_WRITE)))
34248 ++ prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot)))));
34249 ++#endif
34250 ++
34251 ++ return prot;
34252 + }
34253 + EXPORT_SYMBOL(vm_get_page_prot);
34254 +
34255 +@@ -233,6 +252,7 @@ static struct vm_area_struct *remove_vma
34256 + struct vm_area_struct *next = vma->vm_next;
34257 +
34258 + might_sleep();
34259 ++ BUG_ON(vma->vm_mirror);
34260 + if (vma->vm_ops && vma->vm_ops->close)
34261 + vma->vm_ops->close(vma);
34262 + if (vma->vm_file) {
34263 +@@ -269,6 +289,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
34264 + * not page aligned -Ram Gupta
34265 + */
34266 + rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
34267 ++ gr_learn_resource(current, RLIMIT_DATA, (brk - mm->start_brk) + (mm->end_data - mm->start_data), 1);
34268 + if (rlim < RLIM_INFINITY && (brk - mm->start_brk) +
34269 + (mm->end_data - mm->start_data) > rlim)
34270 + goto out;
34271 +@@ -696,6 +717,12 @@ static int
34272 + can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
34273 + struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
34274 + {
34275 ++
34276 ++#ifdef CONFIG_PAX_SEGMEXEC
34277 ++ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE)
34278 ++ return 0;
34279 ++#endif
34280 ++
34281 + if (is_mergeable_vma(vma, file, vm_flags) &&
34282 + is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
34283 + if (vma->vm_pgoff == vm_pgoff)
34284 +@@ -715,6 +742,12 @@ static int
34285 + can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
34286 + struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
34287 + {
34288 ++
34289 ++#ifdef CONFIG_PAX_SEGMEXEC
34290 ++ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE)
34291 ++ return 0;
34292 ++#endif
34293 ++
34294 + if (is_mergeable_vma(vma, file, vm_flags) &&
34295 + is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
34296 + pgoff_t vm_pglen;
34297 +@@ -757,12 +790,19 @@ can_vma_merge_after(struct vm_area_struc
34298 + struct vm_area_struct *vma_merge(struct mm_struct *mm,
34299 + struct vm_area_struct *prev, unsigned long addr,
34300 + unsigned long end, unsigned long vm_flags,
34301 +- struct anon_vma *anon_vma, struct file *file,
34302 ++ struct anon_vma *anon_vma, struct file *file,
34303 + pgoff_t pgoff, struct mempolicy *policy)
34304 + {
34305 + pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
34306 + struct vm_area_struct *area, *next;
34307 +
34308 ++#ifdef CONFIG_PAX_SEGMEXEC
34309 ++ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE;
34310 ++ struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL;
34311 ++
34312 ++ BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end);
34313 ++#endif
34314 ++
34315 + /*
34316 + * We later require that vma->vm_flags == vm_flags,
34317 + * so this tests vma->vm_flags & VM_SPECIAL, too.
34318 +@@ -778,6 +818,15 @@ struct vm_area_struct *vma_merge(struct
34319 + if (next && next->vm_end == end) /* cases 6, 7, 8 */
34320 + next = next->vm_next;
34321 +
34322 ++#ifdef CONFIG_PAX_SEGMEXEC
34323 ++ if (prev)
34324 ++ prev_m = pax_find_mirror_vma(prev);
34325 ++ if (area)
34326 ++ area_m = pax_find_mirror_vma(area);
34327 ++ if (next)
34328 ++ next_m = pax_find_mirror_vma(next);
34329 ++#endif
34330 ++
34331 + /*
34332 + * Can it merge with the predecessor?
34333 + */
34334 +@@ -797,9 +846,24 @@ struct vm_area_struct *vma_merge(struct
34335 + /* cases 1, 6 */
34336 + vma_adjust(prev, prev->vm_start,
34337 + next->vm_end, prev->vm_pgoff, NULL);
34338 +- } else /* cases 2, 5, 7 */
34339 ++
34340 ++#ifdef CONFIG_PAX_SEGMEXEC
34341 ++ if (prev_m)
34342 ++ vma_adjust(prev_m, prev_m->vm_start,
34343 ++ next_m->vm_end, prev_m->vm_pgoff, NULL);
34344 ++#endif
34345 ++
34346 ++ } else { /* cases 2, 5, 7 */
34347 + vma_adjust(prev, prev->vm_start,
34348 + end, prev->vm_pgoff, NULL);
34349 ++
34350 ++#ifdef CONFIG_PAX_SEGMEXEC
34351 ++ if (prev_m)
34352 ++ vma_adjust(prev_m, prev_m->vm_start,
34353 ++ end_m, prev_m->vm_pgoff, NULL);
34354 ++#endif
34355 ++
34356 ++ }
34357 + return prev;
34358 + }
34359 +
34360 +@@ -810,12 +874,27 @@ struct vm_area_struct *vma_merge(struct
34361 + mpol_equal(policy, vma_policy(next)) &&
34362 + can_vma_merge_before(next, vm_flags,
34363 + anon_vma, file, pgoff+pglen)) {
34364 +- if (prev && addr < prev->vm_end) /* case 4 */
34365 ++ if (prev && addr < prev->vm_end) { /* case 4 */
34366 + vma_adjust(prev, prev->vm_start,
34367 + addr, prev->vm_pgoff, NULL);
34368 +- else /* cases 3, 8 */
34369 ++
34370 ++#ifdef CONFIG_PAX_SEGMEXEC
34371 ++ if (prev_m)
34372 ++ vma_adjust(prev_m, prev_m->vm_start,
34373 ++ addr_m, prev_m->vm_pgoff, NULL);
34374 ++#endif
34375 ++
34376 ++ } else { /* cases 3, 8 */
34377 + vma_adjust(area, addr, next->vm_end,
34378 + next->vm_pgoff - pglen, NULL);
34379 ++
34380 ++#ifdef CONFIG_PAX_SEGMEXEC
34381 ++ if (area_m)
34382 ++ vma_adjust(area_m, addr_m, next_m->vm_end,
34383 ++ next_m->vm_pgoff - pglen, NULL);
34384 ++#endif
34385 ++
34386 ++ }
34387 + return area;
34388 + }
34389 +
34390 +@@ -890,14 +969,11 @@ none:
34391 + void vm_stat_account(struct mm_struct *mm, unsigned long flags,
34392 + struct file *file, long pages)
34393 + {
34394 +- const unsigned long stack_flags
34395 +- = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
34396 +-
34397 + if (file) {
34398 + mm->shared_vm += pages;
34399 + if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
34400 + mm->exec_vm += pages;
34401 +- } else if (flags & stack_flags)
34402 ++ } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
34403 + mm->stack_vm += pages;
34404 + if (flags & (VM_RESERVED|VM_IO))
34405 + mm->reserved_vm += pages;
34406 +@@ -925,7 +1001,7 @@ unsigned long do_mmap_pgoff(struct file
34407 + * (the exception is when the underlying filesystem is noexec
34408 + * mounted, in which case we dont add PROT_EXEC.)
34409 + */
34410 +- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
34411 ++ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
34412 + if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
34413 + prot |= PROT_EXEC;
34414 +
34415 +@@ -935,15 +1011,15 @@ unsigned long do_mmap_pgoff(struct file
34416 + if (!(flags & MAP_FIXED))
34417 + addr = round_hint_to_min(addr);
34418 +
34419 +- error = arch_mmap_check(addr, len, flags);
34420 +- if (error)
34421 +- return error;
34422 +-
34423 + /* Careful about overflows.. */
34424 + len = PAGE_ALIGN(len);
34425 + if (!len || len > TASK_SIZE)
34426 + return -ENOMEM;
34427 +
34428 ++ error = arch_mmap_check(addr, len, flags);
34429 ++ if (error)
34430 ++ return error;
34431 ++
34432 + /* offset overflow? */
34433 + if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
34434 + return -EOVERFLOW;
34435 +@@ -955,7 +1031,7 @@ unsigned long do_mmap_pgoff(struct file
34436 + /* Obtain the address to map to. we verify (or select) it and ensure
34437 + * that it represents a valid section of the address space.
34438 + */
34439 +- addr = get_unmapped_area(file, addr, len, pgoff, flags);
34440 ++ addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
34441 + if (addr & ~PAGE_MASK)
34442 + return addr;
34443 +
34444 +@@ -966,6 +1042,26 @@ unsigned long do_mmap_pgoff(struct file
34445 + vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
34446 + mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
34447 +
34448 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
34449 ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
34450 ++
34451 ++#ifdef CONFIG_PAX_MPROTECT
34452 ++ if (mm->pax_flags & MF_PAX_MPROTECT) {
34453 ++ if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
34454 ++ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
34455 ++ else
34456 ++ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
34457 ++ }
34458 ++#endif
34459 ++
34460 ++ }
34461 ++#endif
34462 ++
34463 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
34464 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file)
34465 ++ vm_flags &= ~VM_PAGEEXEC;
34466 ++#endif
34467 ++
34468 + if (flags & MAP_LOCKED) {
34469 + if (!can_do_mlock())
34470 + return -EPERM;
34471 +@@ -979,6 +1075,7 @@ unsigned long do_mmap_pgoff(struct file
34472 + locked += mm->locked_vm;
34473 + lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
34474 + lock_limit >>= PAGE_SHIFT;
34475 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
34476 + if (locked > lock_limit && !capable(CAP_IPC_LOCK))
34477 + return -EAGAIN;
34478 + }
34479 +@@ -1051,6 +1148,9 @@ unsigned long do_mmap_pgoff(struct file
34480 + if (error)
34481 + return error;
34482 +
34483 ++ if (!gr_acl_handle_mmap(file, prot))
34484 ++ return -EACCES;
34485 ++
34486 + return mmap_region(file, addr, len, flags, vm_flags, pgoff,
34487 + accountable);
34488 + }
34489 +@@ -1064,10 +1164,10 @@ EXPORT_SYMBOL(do_mmap_pgoff);
34490 + */
34491 + int vma_wants_writenotify(struct vm_area_struct *vma)
34492 + {
34493 +- unsigned int vm_flags = vma->vm_flags;
34494 ++ unsigned long vm_flags = vma->vm_flags;
34495 +
34496 + /* If it was private or non-writable, the write bit is already clear */
34497 +- if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED)))
34498 ++ if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED))
34499 + return 0;
34500 +
34501 + /* The backer wishes to know when pages are first written to? */
34502 +@@ -1102,14 +1202,24 @@ unsigned long mmap_region(struct file *f
34503 + unsigned long charged = 0;
34504 + struct inode *inode = file ? file->f_path.dentry->d_inode : NULL;
34505 +
34506 ++#ifdef CONFIG_PAX_SEGMEXEC
34507 ++ struct vm_area_struct *vma_m = NULL;
34508 ++#endif
34509 ++
34510 ++ /*
34511 ++ * mm->mmap_sem is required to protect against another thread
34512 ++ * changing the mappings in case we sleep.
34513 ++ */
34514 ++ verify_mm_writelocked(mm);
34515 ++
34516 + /* Clear old maps */
34517 + error = -ENOMEM;
34518 +-munmap_back:
34519 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
34520 + if (vma && vma->vm_start < addr + len) {
34521 + if (do_munmap(mm, addr, len))
34522 + return -ENOMEM;
34523 +- goto munmap_back;
34524 ++ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
34525 ++ BUG_ON(vma && vma->vm_start < addr + len);
34526 + }
34527 +
34528 + /* Check against address space limit. */
34529 +@@ -1158,6 +1268,16 @@ munmap_back:
34530 + goto unacct_error;
34531 + }
34532 +
34533 ++#ifdef CONFIG_PAX_SEGMEXEC
34534 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) {
34535 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
34536 ++ if (!vma_m) {
34537 ++ error = -ENOMEM;
34538 ++ goto free_vma;
34539 ++ }
34540 ++ }
34541 ++#endif
34542 ++
34543 + vma->vm_mm = mm;
34544 + vma->vm_start = addr;
34545 + vma->vm_end = addr + len;
34546 +@@ -1180,6 +1300,19 @@ munmap_back:
34547 + error = file->f_op->mmap(file, vma);
34548 + if (error)
34549 + goto unmap_and_free_vma;
34550 ++
34551 ++#ifdef CONFIG_PAX_SEGMEXEC
34552 ++ if (vma_m && (vm_flags & VM_EXECUTABLE))
34553 ++ added_exe_file_vma(mm);
34554 ++#endif
34555 ++
34556 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
34557 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) {
34558 ++ vma->vm_flags |= VM_PAGEEXEC;
34559 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
34560 ++ }
34561 ++#endif
34562 ++
34563 + if (vm_flags & VM_EXECUTABLE)
34564 + added_exe_file_vma(mm);
34565 + } else if (vm_flags & VM_SHARED) {
34566 +@@ -1215,13 +1348,30 @@ munmap_back:
34567 + if (merged_vma) {
34568 + mpol_put(vma_policy(vma));
34569 + kmem_cache_free(vm_area_cachep, vma);
34570 ++ vma = NULL;
34571 + fput(file);
34572 ++
34573 ++#ifdef CONFIG_PAX_SEGMEXEC
34574 ++ if (vma_m) {
34575 ++ kmem_cache_free(vm_area_cachep, vma_m);
34576 ++
34577 ++ if (vm_flags & VM_EXECUTABLE)
34578 ++ removed_exe_file_vma(mm);
34579 ++ }
34580 ++#endif
34581 ++
34582 + if (vm_flags & VM_EXECUTABLE)
34583 + removed_exe_file_vma(mm);
34584 + vma = merged_vma;
34585 + } else {
34586 + vma_link(mm, vma, prev, rb_link, rb_parent);
34587 + file = vma->vm_file;
34588 ++
34589 ++#ifdef CONFIG_PAX_SEGMEXEC
34590 ++ if (vma_m)
34591 ++ pax_mirror_vma(vma_m, vma);
34592 ++#endif
34593 ++
34594 + }
34595 +
34596 + /* Once vma denies write, undo our temporary denial count */
34597 +@@ -1230,6 +1380,7 @@ munmap_back:
34598 + out:
34599 + mm->total_vm += len >> PAGE_SHIFT;
34600 + vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
34601 ++ track_exec_limit(mm, addr, addr + len, vm_flags);
34602 + if (vm_flags & VM_LOCKED) {
34603 + /*
34604 + * makes pages present; downgrades, drops, reacquires mmap_sem
34605 +@@ -1252,6 +1403,12 @@ unmap_and_free_vma:
34606 + unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
34607 + charged = 0;
34608 + free_vma:
34609 ++
34610 ++#ifdef CONFIG_PAX_SEGMEXEC
34611 ++ if (vma_m)
34612 ++ kmem_cache_free(vm_area_cachep, vma_m);
34613 ++#endif
34614 ++
34615 + kmem_cache_free(vm_area_cachep, vma);
34616 + unacct_error:
34617 + if (charged)
34618 +@@ -1285,6 +1442,10 @@ arch_get_unmapped_area(struct file *filp
34619 + if (flags & MAP_FIXED)
34620 + return addr;
34621 +
34622 ++#ifdef CONFIG_PAX_RANDMMAP
34623 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
34624 ++#endif
34625 ++
34626 + if (addr) {
34627 + addr = PAGE_ALIGN(addr);
34628 + vma = find_vma(mm, addr);
34629 +@@ -1293,10 +1454,10 @@ arch_get_unmapped_area(struct file *filp
34630 + return addr;
34631 + }
34632 + if (len > mm->cached_hole_size) {
34633 +- start_addr = addr = mm->free_area_cache;
34634 ++ start_addr = addr = mm->free_area_cache;
34635 + } else {
34636 +- start_addr = addr = TASK_UNMAPPED_BASE;
34637 +- mm->cached_hole_size = 0;
34638 ++ start_addr = addr = mm->mmap_base;
34639 ++ mm->cached_hole_size = 0;
34640 + }
34641 +
34642 + full_search:
34643 +@@ -1307,9 +1468,8 @@ full_search:
34644 + * Start a new search - just in case we missed
34645 + * some holes.
34646 + */
34647 +- if (start_addr != TASK_UNMAPPED_BASE) {
34648 +- addr = TASK_UNMAPPED_BASE;
34649 +- start_addr = addr;
34650 ++ if (start_addr != mm->mmap_base) {
34651 ++ start_addr = addr = mm->mmap_base;
34652 + mm->cached_hole_size = 0;
34653 + goto full_search;
34654 + }
34655 +@@ -1331,10 +1491,16 @@ full_search:
34656 +
34657 + void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
34658 + {
34659 ++
34660 ++#ifdef CONFIG_PAX_SEGMEXEC
34661 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
34662 ++ return;
34663 ++#endif
34664 ++
34665 + /*
34666 + * Is this a new hole at the lowest possible address?
34667 + */
34668 +- if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
34669 ++ if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
34670 + mm->free_area_cache = addr;
34671 + mm->cached_hole_size = ~0UL;
34672 + }
34673 +@@ -1352,7 +1518,7 @@ arch_get_unmapped_area_topdown(struct fi
34674 + {
34675 + struct vm_area_struct *vma;
34676 + struct mm_struct *mm = current->mm;
34677 +- unsigned long addr = addr0;
34678 ++ unsigned long base = mm->mmap_base, addr = addr0;
34679 +
34680 + /* requested length too big for entire address space */
34681 + if (len > TASK_SIZE)
34682 +@@ -1361,6 +1527,10 @@ arch_get_unmapped_area_topdown(struct fi
34683 + if (flags & MAP_FIXED)
34684 + return addr;
34685 +
34686 ++#ifdef CONFIG_PAX_RANDMMAP
34687 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
34688 ++#endif
34689 ++
34690 + /* requesting a specific address */
34691 + if (addr) {
34692 + addr = PAGE_ALIGN(addr);
34693 +@@ -1418,13 +1588,21 @@ bottomup:
34694 + * can happen with large stack limits and large mmap()
34695 + * allocations.
34696 + */
34697 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
34698 ++
34699 ++#ifdef CONFIG_PAX_RANDMMAP
34700 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
34701 ++ mm->mmap_base += mm->delta_mmap;
34702 ++#endif
34703 ++
34704 ++ mm->free_area_cache = mm->mmap_base;
34705 + mm->cached_hole_size = ~0UL;
34706 +- mm->free_area_cache = TASK_UNMAPPED_BASE;
34707 + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
34708 + /*
34709 + * Restore the topdown base:
34710 + */
34711 +- mm->free_area_cache = mm->mmap_base;
34712 ++ mm->mmap_base = base;
34713 ++ mm->free_area_cache = base;
34714 + mm->cached_hole_size = ~0UL;
34715 +
34716 + return addr;
34717 +@@ -1433,6 +1611,12 @@ bottomup:
34718 +
34719 + void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
34720 + {
34721 ++
34722 ++#ifdef CONFIG_PAX_SEGMEXEC
34723 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
34724 ++ return;
34725 ++#endif
34726 ++
34727 + /*
34728 + * Is this a new hole at the highest possible address?
34729 + */
34730 +@@ -1440,8 +1624,10 @@ void arch_unmap_area_topdown(struct mm_s
34731 + mm->free_area_cache = addr;
34732 +
34733 + /* dont allow allocations above current base */
34734 +- if (mm->free_area_cache > mm->mmap_base)
34735 ++ if (mm->free_area_cache > mm->mmap_base) {
34736 + mm->free_area_cache = mm->mmap_base;
34737 ++ mm->cached_hole_size = ~0UL;
34738 ++ }
34739 + }
34740 +
34741 + unsigned long
34742 +@@ -1541,6 +1727,27 @@ out:
34743 + return prev ? prev->vm_next : vma;
34744 + }
34745 +
34746 ++#ifdef CONFIG_PAX_SEGMEXEC
34747 ++struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
34748 ++{
34749 ++ struct vm_area_struct *vma_m;
34750 ++
34751 ++ BUG_ON(!vma || vma->vm_start >= vma->vm_end);
34752 ++ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) {
34753 ++ BUG_ON(vma->vm_mirror);
34754 ++ return NULL;
34755 ++ }
34756 ++ BUG_ON(vma->vm_start < SEGMEXEC_TASK_SIZE && SEGMEXEC_TASK_SIZE < vma->vm_end);
34757 ++ vma_m = vma->vm_mirror;
34758 ++ BUG_ON(!vma_m || vma_m->vm_mirror != vma);
34759 ++ BUG_ON(vma->vm_file != vma_m->vm_file);
34760 ++ BUG_ON(vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start);
34761 ++ BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff || vma->anon_vma != vma_m->anon_vma);
34762 ++ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED));
34763 ++ return vma_m;
34764 ++}
34765 ++#endif
34766 ++
34767 + /*
34768 + * Verify that the stack growth is acceptable and
34769 + * update accounting. This is shared with both the
34770 +@@ -1557,6 +1764,7 @@ static int acct_stack_growth(struct vm_a
34771 + return -ENOMEM;
34772 +
34773 + /* Stack limit test */
34774 ++ gr_learn_resource(current, RLIMIT_STACK, size, 1);
34775 + if (size > rlim[RLIMIT_STACK].rlim_cur)
34776 + return -ENOMEM;
34777 +
34778 +@@ -1566,6 +1774,7 @@ static int acct_stack_growth(struct vm_a
34779 + unsigned long limit;
34780 + locked = mm->locked_vm + grow;
34781 + limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
34782 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
34783 + if (locked > limit && !capable(CAP_IPC_LOCK))
34784 + return -ENOMEM;
34785 + }
34786 +@@ -1580,7 +1789,7 @@ static int acct_stack_growth(struct vm_a
34787 + * Overcommit.. This must be the final test, as it will
34788 + * update security statistics.
34789 + */
34790 +- if (security_vm_enough_memory(grow))
34791 ++ if (security_vm_enough_memory_mm(mm, grow))
34792 + return -ENOMEM;
34793 +
34794 + /* Ok, everything looks good - let it rip */
34795 +@@ -1601,35 +1810,40 @@ static
34796 + #endif
34797 + int expand_upwards(struct vm_area_struct *vma, unsigned long address)
34798 + {
34799 +- int error;
34800 ++ int error, locknext;
34801 +
34802 + if (!(vma->vm_flags & VM_GROWSUP))
34803 + return -EFAULT;
34804 +
34805 ++ /* Also guard against wrapping around to address 0. */
34806 ++ if (address < PAGE_ALIGN(address+1))
34807 ++ address = PAGE_ALIGN(address+1);
34808 ++ else
34809 ++ return -ENOMEM;
34810 ++
34811 + /*
34812 + * We must make sure the anon_vma is allocated
34813 + * so that the anon_vma locking is not a noop.
34814 + */
34815 + if (unlikely(anon_vma_prepare(vma)))
34816 + return -ENOMEM;
34817 ++ locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN);
34818 ++ if (locknext && unlikely(anon_vma_prepare(vma->vm_next)))
34819 ++ return -ENOMEM;
34820 + anon_vma_lock(vma);
34821 ++ if (locknext)
34822 ++ anon_vma_lock(vma->vm_next);
34823 +
34824 + /*
34825 + * vma->vm_start/vm_end cannot change under us because the caller
34826 + * is required to hold the mmap_sem in read mode. We need the
34827 +- * anon_vma lock to serialize against concurrent expand_stacks.
34828 +- * Also guard against wrapping around to address 0.
34829 ++ * anon_vma locks to serialize against concurrent expand_stacks
34830 ++ * and expand_upwards.
34831 + */
34832 +- if (address < PAGE_ALIGN(address+4))
34833 +- address = PAGE_ALIGN(address+4);
34834 +- else {
34835 +- anon_vma_unlock(vma);
34836 +- return -ENOMEM;
34837 +- }
34838 + error = 0;
34839 +
34840 + /* Somebody else might have raced and expanded it already */
34841 +- if (address > vma->vm_end) {
34842 ++ if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) {
34843 + unsigned long size, grow;
34844 +
34845 + size = address - vma->vm_start;
34846 +@@ -1639,6 +1853,8 @@ int expand_upwards(struct vm_area_struct
34847 + if (!error)
34848 + vma->vm_end = address;
34849 + }
34850 ++ if (locknext)
34851 ++ anon_vma_unlock(vma->vm_next);
34852 + anon_vma_unlock(vma);
34853 + return error;
34854 + }
34855 +@@ -1650,7 +1866,8 @@ int expand_upwards(struct vm_area_struct
34856 + static int expand_downwards(struct vm_area_struct *vma,
34857 + unsigned long address)
34858 + {
34859 +- int error;
34860 ++ int error, lockprev = 0;
34861 ++ struct vm_area_struct *prev = NULL;
34862 +
34863 + /*
34864 + * We must make sure the anon_vma is allocated
34865 +@@ -1664,6 +1881,15 @@ static int expand_downwards(struct vm_ar
34866 + if (error)
34867 + return error;
34868 +
34869 ++#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
34870 ++ find_vma_prev(vma->vm_mm, address, &prev);
34871 ++ lockprev = prev && (prev->vm_flags & VM_GROWSUP);
34872 ++#endif
34873 ++ if (lockprev && unlikely(anon_vma_prepare(prev)))
34874 ++ return -ENOMEM;
34875 ++ if (lockprev)
34876 ++ anon_vma_lock(prev);
34877 ++
34878 + anon_vma_lock(vma);
34879 +
34880 + /*
34881 +@@ -1673,9 +1899,15 @@ static int expand_downwards(struct vm_ar
34882 + */
34883 +
34884 + /* Somebody else might have raced and expanded it already */
34885 +- if (address < vma->vm_start) {
34886 ++ if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) {
34887 + unsigned long size, grow;
34888 +
34889 ++#ifdef CONFIG_PAX_SEGMEXEC
34890 ++ struct vm_area_struct *vma_m;
34891 ++
34892 ++ vma_m = pax_find_mirror_vma(vma);
34893 ++#endif
34894 ++
34895 + size = vma->vm_end - address;
34896 + grow = (vma->vm_start - address) >> PAGE_SHIFT;
34897 +
34898 +@@ -1683,9 +1915,20 @@ static int expand_downwards(struct vm_ar
34899 + if (!error) {
34900 + vma->vm_start = address;
34901 + vma->vm_pgoff -= grow;
34902 ++ track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
34903 ++
34904 ++#ifdef CONFIG_PAX_SEGMEXEC
34905 ++ if (vma_m) {
34906 ++ vma_m->vm_start -= grow << PAGE_SHIFT;
34907 ++ vma_m->vm_pgoff -= grow;
34908 ++ }
34909 ++#endif
34910 ++
34911 + }
34912 + }
34913 + anon_vma_unlock(vma);
34914 ++ if (lockprev)
34915 ++ anon_vma_unlock(prev);
34916 + return error;
34917 + }
34918 +
34919 +@@ -1761,6 +2004,13 @@ static void remove_vma_list(struct mm_st
34920 + do {
34921 + long nrpages = vma_pages(vma);
34922 +
34923 ++#ifdef CONFIG_PAX_SEGMEXEC
34924 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) {
34925 ++ vma = remove_vma(vma);
34926 ++ continue;
34927 ++ }
34928 ++#endif
34929 ++
34930 + mm->total_vm -= nrpages;
34931 + vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages);
34932 + vma = remove_vma(vma);
34933 +@@ -1805,6 +2055,16 @@ detach_vmas_to_be_unmapped(struct mm_str
34934 +
34935 + insertion_point = (prev ? &prev->vm_next : &mm->mmap);
34936 + do {
34937 ++
34938 ++#ifdef CONFIG_PAX_SEGMEXEC
34939 ++ if (vma->vm_mirror) {
34940 ++ BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma);
34941 ++ vma->vm_mirror->vm_mirror = NULL;
34942 ++ vma->vm_mirror->vm_flags &= ~VM_EXEC;
34943 ++ vma->vm_mirror = NULL;
34944 ++ }
34945 ++#endif
34946 ++
34947 + rb_erase(&vma->vm_rb, &mm->mm_rb);
34948 + mm->map_count--;
34949 + tail_vma = vma;
34950 +@@ -1824,6 +2084,108 @@ detach_vmas_to_be_unmapped(struct mm_str
34951 + * Split a vma into two pieces at address 'addr', a new vma is allocated
34952 + * either for the first part or the tail.
34953 + */
34954 ++
34955 ++#ifdef CONFIG_PAX_SEGMEXEC
34956 ++int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
34957 ++ unsigned long addr, int new_below)
34958 ++{
34959 ++ struct mempolicy *pol;
34960 ++ struct vm_area_struct *new, *vma_m, *new_m = NULL;
34961 ++ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE;
34962 ++
34963 ++ if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK))
34964 ++ return -EINVAL;
34965 ++
34966 ++ vma_m = pax_find_mirror_vma(vma);
34967 ++ if (vma_m) {
34968 ++ BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE);
34969 ++ if (mm->map_count >= sysctl_max_map_count-1)
34970 ++ return -ENOMEM;
34971 ++ } else if (mm->map_count >= sysctl_max_map_count)
34972 ++ return -ENOMEM;
34973 ++
34974 ++ new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
34975 ++ if (!new)
34976 ++ return -ENOMEM;
34977 ++
34978 ++ if (vma_m) {
34979 ++ new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
34980 ++ if (!new_m) {
34981 ++ kmem_cache_free(vm_area_cachep, new);
34982 ++ return -ENOMEM;
34983 ++ }
34984 ++ }
34985 ++
34986 ++ /* most fields are the same, copy all, and then fixup */
34987 ++ *new = *vma;
34988 ++
34989 ++ if (new_below)
34990 ++ new->vm_end = addr;
34991 ++ else {
34992 ++ new->vm_start = addr;
34993 ++ new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
34994 ++ }
34995 ++
34996 ++ if (vma_m) {
34997 ++ *new_m = *vma_m;
34998 ++ new_m->vm_mirror = new;
34999 ++ new->vm_mirror = new_m;
35000 ++
35001 ++ if (new_below)
35002 ++ new_m->vm_end = addr_m;
35003 ++ else {
35004 ++ new_m->vm_start = addr_m;
35005 ++ new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT);
35006 ++ }
35007 ++ }
35008 ++
35009 ++ pol = mpol_dup(vma_policy(vma));
35010 ++ if (IS_ERR(pol)) {
35011 ++ if (new_m)
35012 ++ kmem_cache_free(vm_area_cachep, new_m);
35013 ++ kmem_cache_free(vm_area_cachep, new);
35014 ++ return PTR_ERR(pol);
35015 ++ }
35016 ++ vma_set_policy(new, pol);
35017 ++
35018 ++ if (new->vm_file) {
35019 ++ get_file(new->vm_file);
35020 ++ if (vma->vm_flags & VM_EXECUTABLE)
35021 ++ added_exe_file_vma(mm);
35022 ++ }
35023 ++
35024 ++ if (new->vm_ops && new->vm_ops->open)
35025 ++ new->vm_ops->open(new);
35026 ++
35027 ++ if (new_below)
35028 ++ vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
35029 ++ ((addr - new->vm_start) >> PAGE_SHIFT), new);
35030 ++ else
35031 ++ vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
35032 ++
35033 ++ if (vma_m) {
35034 ++ mpol_get(pol);
35035 ++ vma_set_policy(new_m, pol);
35036 ++
35037 ++ if (new_m->vm_file) {
35038 ++ get_file(new_m->vm_file);
35039 ++ if (vma_m->vm_flags & VM_EXECUTABLE)
35040 ++ added_exe_file_vma(mm);
35041 ++ }
35042 ++
35043 ++ if (new_m->vm_ops && new_m->vm_ops->open)
35044 ++ new_m->vm_ops->open(new_m);
35045 ++
35046 ++ if (new_below)
35047 ++ vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff +
35048 ++ ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m);
35049 ++ else
35050 ++ vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m);
35051 ++ }
35052 ++
35053 ++ return 0;
35054 ++}
35055 ++#else
35056 + int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
35057 + unsigned long addr, int new_below)
35058 + {
35059 +@@ -1875,17 +2237,37 @@ int split_vma(struct mm_struct * mm, str
35060 +
35061 + return 0;
35062 + }
35063 ++#endif
35064 +
35065 + /* Munmap is split into 2 main parts -- this part which finds
35066 + * what needs doing, and the areas themselves, which do the
35067 + * work. This now handles partial unmappings.
35068 + * Jeremy Fitzhardinge <jeremy@××××.org>
35069 + */
35070 ++#ifdef CONFIG_PAX_SEGMEXEC
35071 + int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
35072 + {
35073 ++ int ret = __do_munmap(mm, start, len);
35074 ++ if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC))
35075 ++ return ret;
35076 ++
35077 ++ return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
35078 ++}
35079 ++
35080 ++int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
35081 ++#else
35082 ++int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
35083 ++#endif
35084 ++{
35085 + unsigned long end;
35086 + struct vm_area_struct *vma, *prev, *last;
35087 +
35088 ++ /*
35089 ++ * mm->mmap_sem is required to protect against another thread
35090 ++ * changing the mappings in case we sleep.
35091 ++ */
35092 ++ verify_mm_writelocked(mm);
35093 ++
35094 + if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
35095 + return -EINVAL;
35096 +
35097 +@@ -1949,6 +2331,8 @@ int do_munmap(struct mm_struct *mm, unsi
35098 + /* Fix up all other VM information */
35099 + remove_vma_list(mm, vma);
35100 +
35101 ++ track_exec_limit(mm, start, end, 0UL);
35102 ++
35103 + return 0;
35104 + }
35105 +
35106 +@@ -1961,22 +2345,18 @@ SYSCALL_DEFINE2(munmap, unsigned long, a
35107 +
35108 + profile_munmap(addr);
35109 +
35110 ++#ifdef CONFIG_PAX_SEGMEXEC
35111 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
35112 ++ (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
35113 ++ return -EINVAL;
35114 ++#endif
35115 ++
35116 + down_write(&mm->mmap_sem);
35117 + ret = do_munmap(mm, addr, len);
35118 + up_write(&mm->mmap_sem);
35119 + return ret;
35120 + }
35121 +
35122 +-static inline void verify_mm_writelocked(struct mm_struct *mm)
35123 +-{
35124 +-#ifdef CONFIG_DEBUG_VM
35125 +- if (unlikely(down_read_trylock(&mm->mmap_sem))) {
35126 +- WARN_ON(1);
35127 +- up_read(&mm->mmap_sem);
35128 +- }
35129 +-#endif
35130 +-}
35131 +-
35132 + /*
35133 + * this is really a simplified "do_mmap". it only handles
35134 + * anonymous maps. eventually we may be able to do some
35135 +@@ -1990,6 +2370,11 @@ unsigned long do_brk(unsigned long addr,
35136 + struct rb_node ** rb_link, * rb_parent;
35137 + pgoff_t pgoff = addr >> PAGE_SHIFT;
35138 + int error;
35139 ++ unsigned long charged;
35140 ++
35141 ++#ifdef CONFIG_PAX_SEGMEXEC
35142 ++ struct vm_area_struct *vma_m = NULL;
35143 ++#endif
35144 +
35145 + len = PAGE_ALIGN(len);
35146 + if (!len)
35147 +@@ -2007,19 +2392,34 @@ unsigned long do_brk(unsigned long addr,
35148 +
35149 + flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
35150 +
35151 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
35152 ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
35153 ++ flags &= ~VM_EXEC;
35154 ++
35155 ++#ifdef CONFIG_PAX_MPROTECT
35156 ++ if (mm->pax_flags & MF_PAX_MPROTECT)
35157 ++ flags &= ~VM_MAYEXEC;
35158 ++#endif
35159 ++
35160 ++ }
35161 ++#endif
35162 ++
35163 + error = arch_mmap_check(addr, len, flags);
35164 + if (error)
35165 + return error;
35166 +
35167 ++ charged = len >> PAGE_SHIFT;
35168 ++
35169 + /*
35170 + * mlock MCL_FUTURE?
35171 + */
35172 + if (mm->def_flags & VM_LOCKED) {
35173 + unsigned long locked, lock_limit;
35174 +- locked = len >> PAGE_SHIFT;
35175 ++ locked = charged;
35176 + locked += mm->locked_vm;
35177 + lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
35178 + lock_limit >>= PAGE_SHIFT;
35179 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
35180 + if (locked > lock_limit && !capable(CAP_IPC_LOCK))
35181 + return -EAGAIN;
35182 + }
35183 +@@ -2033,22 +2433,22 @@ unsigned long do_brk(unsigned long addr,
35184 + /*
35185 + * Clear old maps. this also does some error checking for us
35186 + */
35187 +- munmap_back:
35188 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
35189 + if (vma && vma->vm_start < addr + len) {
35190 + if (do_munmap(mm, addr, len))
35191 + return -ENOMEM;
35192 +- goto munmap_back;
35193 ++ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
35194 ++ BUG_ON(vma && vma->vm_start < addr + len);
35195 + }
35196 +
35197 + /* Check against address space limits *after* clearing old maps... */
35198 +- if (!may_expand_vm(mm, len >> PAGE_SHIFT))
35199 ++ if (!may_expand_vm(mm, charged))
35200 + return -ENOMEM;
35201 +
35202 + if (mm->map_count > sysctl_max_map_count)
35203 + return -ENOMEM;
35204 +
35205 +- if (security_vm_enough_memory(len >> PAGE_SHIFT))
35206 ++ if (security_vm_enough_memory(charged))
35207 + return -ENOMEM;
35208 +
35209 + /* Can we just expand an old private anonymous mapping? */
35210 +@@ -2062,10 +2462,21 @@ unsigned long do_brk(unsigned long addr,
35211 + */
35212 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
35213 + if (!vma) {
35214 +- vm_unacct_memory(len >> PAGE_SHIFT);
35215 ++ vm_unacct_memory(charged);
35216 + return -ENOMEM;
35217 + }
35218 +
35219 ++#ifdef CONFIG_PAX_SEGMEXEC
35220 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (flags & VM_EXEC)) {
35221 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
35222 ++ if (!vma_m) {
35223 ++ kmem_cache_free(vm_area_cachep, vma);
35224 ++ vm_unacct_memory(charged);
35225 ++ return -ENOMEM;
35226 ++ }
35227 ++ }
35228 ++#endif
35229 ++
35230 + vma->vm_mm = mm;
35231 + vma->vm_start = addr;
35232 + vma->vm_end = addr + len;
35233 +@@ -2074,11 +2485,12 @@ unsigned long do_brk(unsigned long addr,
35234 + vma->vm_page_prot = vm_get_page_prot(flags);
35235 + vma_link(mm, vma, prev, rb_link, rb_parent);
35236 + out:
35237 +- mm->total_vm += len >> PAGE_SHIFT;
35238 ++ mm->total_vm += charged;
35239 + if (flags & VM_LOCKED) {
35240 + if (!mlock_vma_pages_range(vma, addr, addr + len))
35241 +- mm->locked_vm += (len >> PAGE_SHIFT);
35242 ++ mm->locked_vm += charged;
35243 + }
35244 ++ track_exec_limit(mm, addr, addr + len, flags);
35245 + return addr;
35246 + }
35247 +
35248 +@@ -2124,8 +2536,10 @@ void exit_mmap(struct mm_struct *mm)
35249 + * Walk the list again, actually closing and freeing it,
35250 + * with preemption enabled, without holding any MM locks.
35251 + */
35252 +- while (vma)
35253 ++ while (vma) {
35254 ++ vma->vm_mirror = NULL;
35255 + vma = remove_vma(vma);
35256 ++ }
35257 +
35258 + BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
35259 + }
35260 +@@ -2139,6 +2553,10 @@ int insert_vm_struct(struct mm_struct *
35261 + struct vm_area_struct * __vma, * prev;
35262 + struct rb_node ** rb_link, * rb_parent;
35263 +
35264 ++#ifdef CONFIG_PAX_SEGMEXEC
35265 ++ struct vm_area_struct *vma_m = NULL;
35266 ++#endif
35267 ++
35268 + /*
35269 + * The vm_pgoff of a purely anonymous vma should be irrelevant
35270 + * until its first write fault, when page's anon_vma and index
35271 +@@ -2161,7 +2579,22 @@ int insert_vm_struct(struct mm_struct *
35272 + if ((vma->vm_flags & VM_ACCOUNT) &&
35273 + security_vm_enough_memory_mm(mm, vma_pages(vma)))
35274 + return -ENOMEM;
35275 ++
35276 ++#ifdef CONFIG_PAX_SEGMEXEC
35277 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) {
35278 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
35279 ++ if (!vma_m)
35280 ++ return -ENOMEM;
35281 ++ }
35282 ++#endif
35283 ++
35284 + vma_link(mm, vma, prev, rb_link, rb_parent);
35285 ++
35286 ++#ifdef CONFIG_PAX_SEGMEXEC
35287 ++ if (vma_m)
35288 ++ pax_mirror_vma(vma_m, vma);
35289 ++#endif
35290 ++
35291 + return 0;
35292 + }
35293 +
35294 +@@ -2179,6 +2612,8 @@ struct vm_area_struct *copy_vma(struct v
35295 + struct rb_node **rb_link, *rb_parent;
35296 + struct mempolicy *pol;
35297 +
35298 ++ BUG_ON(vma->vm_mirror);
35299 ++
35300 + /*
35301 + * If anonymous vma has not yet been faulted, update new pgoff
35302 + * to match new location, to increase its chance of merging.
35303 +@@ -2222,6 +2657,35 @@ struct vm_area_struct *copy_vma(struct v
35304 + return new_vma;
35305 + }
35306 +
35307 ++#ifdef CONFIG_PAX_SEGMEXEC
35308 ++void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma)
35309 ++{
35310 ++ struct vm_area_struct *prev_m;
35311 ++ struct rb_node **rb_link_m, *rb_parent_m;
35312 ++ struct mempolicy *pol_m;
35313 ++
35314 ++ BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC));
35315 ++ BUG_ON(vma->vm_mirror || vma_m->vm_mirror);
35316 ++ BUG_ON(!mpol_equal(vma_policy(vma), vma_policy(vma_m)));
35317 ++ *vma_m = *vma;
35318 ++ pol_m = vma_policy(vma_m);
35319 ++ mpol_get(pol_m);
35320 ++ vma_set_policy(vma_m, pol_m);
35321 ++ vma_m->vm_start += SEGMEXEC_TASK_SIZE;
35322 ++ vma_m->vm_end += SEGMEXEC_TASK_SIZE;
35323 ++ vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED);
35324 ++ vma_m->vm_page_prot = vm_get_page_prot(vma_m->vm_flags);
35325 ++ if (vma_m->vm_file)
35326 ++ get_file(vma_m->vm_file);
35327 ++ if (vma_m->vm_ops && vma_m->vm_ops->open)
35328 ++ vma_m->vm_ops->open(vma_m);
35329 ++ find_vma_prepare(vma->vm_mm, vma_m->vm_start, &prev_m, &rb_link_m, &rb_parent_m);
35330 ++ vma_link(vma->vm_mm, vma_m, prev_m, rb_link_m, rb_parent_m);
35331 ++ vma_m->vm_mirror = vma;
35332 ++ vma->vm_mirror = vma_m;
35333 ++}
35334 ++#endif
35335 ++
35336 + /*
35337 + * Return true if the calling process may expand its vm space by the passed
35338 + * number of pages
35339 +@@ -2232,7 +2696,7 @@ int may_expand_vm(struct mm_struct *mm,
35340 + unsigned long lim;
35341 +
35342 + lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
35343 +-
35344 ++ gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
35345 + if (cur + npages > lim)
35346 + return 0;
35347 + return 1;
35348 +@@ -2301,6 +2765,15 @@ int install_special_mapping(struct mm_st
35349 + vma->vm_start = addr;
35350 + vma->vm_end = addr + len;
35351 +
35352 ++#ifdef CONFIG_PAX_MPROTECT
35353 ++ if (mm->pax_flags & MF_PAX_MPROTECT) {
35354 ++ if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC)
35355 ++ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
35356 ++ else
35357 ++ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
35358 ++ }
35359 ++#endif
35360 ++
35361 + vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
35362 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
35363 +
35364 +diff -urNp linux-2.6.28.8/mm/mprotect.c linux-2.6.28.8/mm/mprotect.c
35365 +--- linux-2.6.28.8/mm/mprotect.c 2009-02-06 16:47:45.000000000 -0500
35366 ++++ linux-2.6.28.8/mm/mprotect.c 2009-02-21 09:37:50.000000000 -0500
35367 +@@ -22,10 +22,16 @@
35368 + #include <linux/swap.h>
35369 + #include <linux/swapops.h>
35370 + #include <linux/mmu_notifier.h>
35371 ++
35372 ++#ifdef CONFIG_PAX_MPROTECT
35373 ++#include <linux/elf.h>
35374 ++#endif
35375 ++
35376 + #include <asm/uaccess.h>
35377 + #include <asm/pgtable.h>
35378 + #include <asm/cacheflush.h>
35379 + #include <asm/tlbflush.h>
35380 ++#include <asm/mmu_context.h>
35381 +
35382 + #ifndef pgprot_modify
35383 + static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
35384 +@@ -133,6 +139,48 @@ static void change_protection(struct vm_
35385 + flush_tlb_range(vma, start, end);
35386 + }
35387 +
35388 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
35389 ++/* called while holding the mmap semaphor for writing except stack expansion */
35390 ++void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
35391 ++{
35392 ++ unsigned long oldlimit, newlimit = 0UL;
35393 ++
35394 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || nx_enabled)
35395 ++ return;
35396 ++
35397 ++ spin_lock(&mm->page_table_lock);
35398 ++ oldlimit = mm->context.user_cs_limit;
35399 ++ if ((prot & VM_EXEC) && oldlimit < end)
35400 ++ /* USER_CS limit moved up */
35401 ++ newlimit = end;
35402 ++ else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
35403 ++ /* USER_CS limit moved down */
35404 ++ newlimit = start;
35405 ++
35406 ++ if (newlimit) {
35407 ++ mm->context.user_cs_limit = newlimit;
35408 ++
35409 ++#ifdef CONFIG_SMP
35410 ++ wmb();
35411 ++ cpus_clear(mm->context.cpu_user_cs_mask);
35412 ++ cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
35413 ++#endif
35414 ++
35415 ++ set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
35416 ++ }
35417 ++ spin_unlock(&mm->page_table_lock);
35418 ++ if (newlimit == end) {
35419 ++ struct vm_area_struct *vma = find_vma(mm, oldlimit);
35420 ++
35421 ++ for (; vma && vma->vm_start < end; vma = vma->vm_next)
35422 ++ if (is_vm_hugetlb_page(vma))
35423 ++ hugetlb_change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
35424 ++ else
35425 ++ change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
35426 ++ }
35427 ++}
35428 ++#endif
35429 ++
35430 + int
35431 + mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
35432 + unsigned long start, unsigned long end, unsigned long newflags)
35433 +@@ -145,6 +193,14 @@ mprotect_fixup(struct vm_area_struct *vm
35434 + int error;
35435 + int dirty_accountable = 0;
35436 +
35437 ++#ifdef CONFIG_PAX_SEGMEXEC
35438 ++ struct vm_area_struct *vma_m = NULL;
35439 ++ unsigned long start_m, end_m;
35440 ++
35441 ++ start_m = start + SEGMEXEC_TASK_SIZE;
35442 ++ end_m = end + SEGMEXEC_TASK_SIZE;
35443 ++#endif
35444 ++
35445 + if (newflags == oldflags) {
35446 + *pprev = vma;
35447 + return 0;
35448 +@@ -165,6 +221,38 @@ mprotect_fixup(struct vm_area_struct *vm
35449 + }
35450 + }
35451 +
35452 ++#ifdef CONFIG_PAX_SEGMEXEC
35453 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && ((oldflags ^ newflags) & VM_EXEC)) {
35454 ++ if (start != vma->vm_start) {
35455 ++ error = split_vma(mm, vma, start, 1);
35456 ++ if (error)
35457 ++ goto fail;
35458 ++ BUG_ON(!*pprev || (*pprev)->vm_next == vma);
35459 ++ *pprev = (*pprev)->vm_next;
35460 ++ }
35461 ++
35462 ++ if (end != vma->vm_end) {
35463 ++ error = split_vma(mm, vma, end, 0);
35464 ++ if (error)
35465 ++ goto fail;
35466 ++ }
35467 ++
35468 ++ if (pax_find_mirror_vma(vma)) {
35469 ++ error = __do_munmap(mm, start_m, end_m - start_m);
35470 ++ if (error)
35471 ++ goto fail;
35472 ++ } else {
35473 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
35474 ++ if (!vma_m) {
35475 ++ error = -ENOMEM;
35476 ++ goto fail;
35477 ++ }
35478 ++ vma->vm_flags = newflags;
35479 ++ pax_mirror_vma(vma_m, vma);
35480 ++ }
35481 ++ }
35482 ++#endif
35483 ++
35484 + /*
35485 + * First try to merge with previous and/or next vma.
35486 + */
35487 +@@ -196,8 +284,14 @@ success:
35488 + * held in write mode.
35489 + */
35490 + vma->vm_flags = newflags;
35491 ++
35492 ++#ifdef CONFIG_PAX_MPROTECT
35493 ++ if (current->binfmt && current->binfmt->handle_mprotect)
35494 ++ current->binfmt->handle_mprotect(vma, newflags);
35495 ++#endif
35496 ++
35497 + vma->vm_page_prot = pgprot_modify(vma->vm_page_prot,
35498 +- vm_get_page_prot(newflags));
35499 ++ vm_get_page_prot(vma->vm_flags));
35500 +
35501 + if (vma_wants_writenotify(vma)) {
35502 + vma->vm_page_prot = vm_get_page_prot(newflags & ~VM_SHARED);
35503 +@@ -238,6 +332,17 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
35504 + end = start + len;
35505 + if (end <= start)
35506 + return -ENOMEM;
35507 ++
35508 ++#ifdef CONFIG_PAX_SEGMEXEC
35509 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
35510 ++ if (end > SEGMEXEC_TASK_SIZE)
35511 ++ return -EINVAL;
35512 ++ } else
35513 ++#endif
35514 ++
35515 ++ if (end > TASK_SIZE)
35516 ++ return -EINVAL;
35517 ++
35518 + if (!arch_validate_prot(prot))
35519 + return -EINVAL;
35520 +
35521 +@@ -245,7 +350,7 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
35522 + /*
35523 + * Does the application expect PROT_READ to imply PROT_EXEC:
35524 + */
35525 +- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
35526 ++ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
35527 + prot |= PROT_EXEC;
35528 +
35529 + vm_flags = calc_vm_prot_bits(prot);
35530 +@@ -277,6 +382,16 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
35531 + if (start > vma->vm_start)
35532 + prev = vma;
35533 +
35534 ++ if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
35535 ++ error = -EACCES;
35536 ++ goto out;
35537 ++ }
35538 ++
35539 ++#ifdef CONFIG_PAX_MPROTECT
35540 ++ if (current->binfmt && current->binfmt->handle_mprotect)
35541 ++ current->binfmt->handle_mprotect(vma, vm_flags);
35542 ++#endif
35543 ++
35544 + for (nstart = start ; ; ) {
35545 + unsigned long newflags;
35546 +
35547 +@@ -300,6 +415,9 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
35548 + error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
35549 + if (error)
35550 + goto out;
35551 ++
35552 ++ track_exec_limit(current->mm, nstart, tmp, vm_flags);
35553 ++
35554 + nstart = tmp;
35555 +
35556 + if (nstart < prev->vm_end)
35557 +diff -urNp linux-2.6.28.8/mm/mremap.c linux-2.6.28.8/mm/mremap.c
35558 +--- linux-2.6.28.8/mm/mremap.c 2009-02-06 16:47:45.000000000 -0500
35559 ++++ linux-2.6.28.8/mm/mremap.c 2009-02-21 09:37:50.000000000 -0500
35560 +@@ -113,6 +113,12 @@ static void move_ptes(struct vm_area_str
35561 + continue;
35562 + pte = ptep_clear_flush(vma, old_addr, old_pte);
35563 + pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
35564 ++
35565 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
35566 ++ if (!nx_enabled && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC)
35567 ++ pte = pte_exprotect(pte);
35568 ++#endif
35569 ++
35570 + set_pte_at(mm, new_addr, new_pte, pte);
35571 + }
35572 +
35573 +@@ -262,6 +268,7 @@ unsigned long do_mremap(unsigned long ad
35574 + struct vm_area_struct *vma;
35575 + unsigned long ret = -EINVAL;
35576 + unsigned long charged = 0;
35577 ++ unsigned long pax_task_size = TASK_SIZE;
35578 +
35579 + if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
35580 + goto out;
35581 +@@ -280,6 +287,15 @@ unsigned long do_mremap(unsigned long ad
35582 + if (!new_len)
35583 + goto out;
35584 +
35585 ++#ifdef CONFIG_PAX_SEGMEXEC
35586 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
35587 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
35588 ++#endif
35589 ++
35590 ++ if (new_len > pax_task_size || addr > pax_task_size-new_len ||
35591 ++ old_len > pax_task_size || addr > pax_task_size-old_len)
35592 ++ goto out;
35593 ++
35594 + /* new_addr is only valid if MREMAP_FIXED is specified */
35595 + if (flags & MREMAP_FIXED) {
35596 + if (new_addr & ~PAGE_MASK)
35597 +@@ -287,16 +303,13 @@ unsigned long do_mremap(unsigned long ad
35598 + if (!(flags & MREMAP_MAYMOVE))
35599 + goto out;
35600 +
35601 +- if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
35602 ++ if (new_addr > pax_task_size - new_len)
35603 + goto out;
35604 +
35605 + /* Check if the location we're moving into overlaps the
35606 + * old location at all, and fail if it does.
35607 + */
35608 +- if ((new_addr <= addr) && (new_addr+new_len) > addr)
35609 +- goto out;
35610 +-
35611 +- if ((addr <= new_addr) && (addr+old_len) > new_addr)
35612 ++ if (addr + old_len > new_addr && new_addr + new_len > addr)
35613 + goto out;
35614 +
35615 + ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
35616 +@@ -334,6 +347,14 @@ unsigned long do_mremap(unsigned long ad
35617 + ret = -EINVAL;
35618 + goto out;
35619 + }
35620 ++
35621 ++#ifdef CONFIG_PAX_SEGMEXEC
35622 ++ if (pax_find_mirror_vma(vma)) {
35623 ++ ret = -EINVAL;
35624 ++ goto out;
35625 ++ }
35626 ++#endif
35627 ++
35628 + /* We can't remap across vm area boundaries */
35629 + if (old_len > vma->vm_end - addr)
35630 + goto out;
35631 +@@ -367,7 +388,7 @@ unsigned long do_mremap(unsigned long ad
35632 + if (old_len == vma->vm_end - addr &&
35633 + !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
35634 + (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
35635 +- unsigned long max_addr = TASK_SIZE;
35636 ++ unsigned long max_addr = pax_task_size;
35637 + if (vma->vm_next)
35638 + max_addr = vma->vm_next->vm_start;
35639 + /* can we just expand the current mapping? */
35640 +@@ -385,6 +406,7 @@ unsigned long do_mremap(unsigned long ad
35641 + addr + new_len);
35642 + }
35643 + ret = addr;
35644 ++ track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
35645 + goto out;
35646 + }
35647 + }
35648 +@@ -395,8 +417,8 @@ unsigned long do_mremap(unsigned long ad
35649 + */
35650 + ret = -ENOMEM;
35651 + if (flags & MREMAP_MAYMOVE) {
35652 ++ unsigned long map_flags = 0;
35653 + if (!(flags & MREMAP_FIXED)) {
35654 +- unsigned long map_flags = 0;
35655 + if (vma->vm_flags & VM_MAYSHARE)
35656 + map_flags |= MAP_SHARED;
35657 +
35658 +@@ -411,7 +433,12 @@ unsigned long do_mremap(unsigned long ad
35659 + if (ret)
35660 + goto out;
35661 + }
35662 ++ map_flags = vma->vm_flags;
35663 + ret = move_vma(vma, addr, old_len, new_len, new_addr);
35664 ++ if (!(ret & ~PAGE_MASK)) {
35665 ++ track_exec_limit(current->mm, addr, addr + old_len, 0UL);
35666 ++ track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
35667 ++ }
35668 + }
35669 + out:
35670 + if (ret & ~PAGE_MASK)
35671 +diff -urNp linux-2.6.28.8/mm/nommu.c linux-2.6.28.8/mm/nommu.c
35672 +--- linux-2.6.28.8/mm/nommu.c 2009-02-06 16:47:45.000000000 -0500
35673 ++++ linux-2.6.28.8/mm/nommu.c 2009-02-21 09:37:50.000000000 -0500
35674 +@@ -459,15 +459,6 @@ struct vm_area_struct *find_vma(struct m
35675 + }
35676 + EXPORT_SYMBOL(find_vma);
35677 +
35678 +-/*
35679 +- * find a VMA
35680 +- * - we don't extend stack VMAs under NOMMU conditions
35681 +- */
35682 +-struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
35683 +-{
35684 +- return find_vma(mm, addr);
35685 +-}
35686 +-
35687 + int expand_stack(struct vm_area_struct *vma, unsigned long address)
35688 + {
35689 + return -ENOMEM;
35690 +diff -urNp linux-2.6.28.8/mm/page_alloc.c linux-2.6.28.8/mm/page_alloc.c
35691 +--- linux-2.6.28.8/mm/page_alloc.c 2009-03-07 10:24:49.000000000 -0500
35692 ++++ linux-2.6.28.8/mm/page_alloc.c 2009-03-07 10:29:51.000000000 -0500
35693 +@@ -525,6 +525,10 @@ static void __free_pages_ok(struct page
35694 + int i;
35695 + int reserved = 0;
35696 +
35697 ++#ifdef CONFIG_PAX_MEMORY_SANITIZE
35698 ++ unsigned long index = 1UL << order;
35699 ++#endif
35700 ++
35701 + for (i = 0 ; i < (1 << order) ; ++i)
35702 + reserved += free_pages_check(page + i);
35703 + if (reserved)
35704 +@@ -535,6 +539,12 @@ static void __free_pages_ok(struct page
35705 + debug_check_no_obj_freed(page_address(page),
35706 + PAGE_SIZE << order);
35707 + }
35708 ++
35709 ++#ifdef CONFIG_PAX_MEMORY_SANITIZE
35710 ++ for (; index; --index)
35711 ++ sanitize_highpage(page + index - 1);
35712 ++#endif
35713 ++
35714 + arch_free_page(page, order);
35715 + kernel_map_pages(page, 1 << order, 0);
35716 +
35717 +@@ -635,8 +645,10 @@ static int prep_new_page(struct page *pa
35718 + arch_alloc_page(page, order);
35719 + kernel_map_pages(page, 1 << order, 1);
35720 +
35721 ++#ifndef CONFIG_PAX_MEMORY_SANITIZE
35722 + if (gfp_flags & __GFP_ZERO)
35723 + prep_zero_page(page, order, gfp_flags);
35724 ++#endif
35725 +
35726 + if (order && (gfp_flags & __GFP_COMP))
35727 + prep_compound_page(page, order);
35728 +@@ -997,6 +1009,11 @@ static void free_hot_cold_page(struct pa
35729 + debug_check_no_locks_freed(page_address(page), PAGE_SIZE);
35730 + debug_check_no_obj_freed(page_address(page), PAGE_SIZE);
35731 + }
35732 ++
35733 ++#ifdef CONFIG_PAX_MEMORY_SANITIZE
35734 ++ sanitize_highpage(page);
35735 ++#endif
35736 ++
35737 + arch_free_page(page, 0);
35738 + kernel_map_pages(page, 1, 0);
35739 +
35740 +diff -urNp linux-2.6.28.8/mm/rmap.c linux-2.6.28.8/mm/rmap.c
35741 +--- linux-2.6.28.8/mm/rmap.c 2009-02-06 16:47:45.000000000 -0500
35742 ++++ linux-2.6.28.8/mm/rmap.c 2009-02-21 09:37:50.000000000 -0500
35743 +@@ -103,6 +103,10 @@ int anon_vma_prepare(struct vm_area_stru
35744 + struct mm_struct *mm = vma->vm_mm;
35745 + struct anon_vma *allocated;
35746 +
35747 ++#ifdef CONFIG_PAX_SEGMEXEC
35748 ++ struct vm_area_struct *vma_m;
35749 ++#endif
35750 ++
35751 + anon_vma = find_mergeable_anon_vma(vma);
35752 + allocated = NULL;
35753 + if (!anon_vma) {
35754 +@@ -116,6 +120,15 @@ int anon_vma_prepare(struct vm_area_stru
35755 + /* page_table_lock to protect against threads */
35756 + spin_lock(&mm->page_table_lock);
35757 + if (likely(!vma->anon_vma)) {
35758 ++
35759 ++#ifdef CONFIG_PAX_SEGMEXEC
35760 ++ vma_m = pax_find_mirror_vma(vma);
35761 ++ if (vma_m) {
35762 ++ vma_m->anon_vma = anon_vma;
35763 ++ __anon_vma_link(vma_m);
35764 ++ }
35765 ++#endif
35766 ++
35767 + vma->anon_vma = anon_vma;
35768 + list_add_tail(&vma->anon_vma_node, &anon_vma->head);
35769 + allocated = NULL;
35770 +diff -urNp linux-2.6.28.8/mm/shmem.c linux-2.6.28.8/mm/shmem.c
35771 +--- linux-2.6.28.8/mm/shmem.c 2009-02-06 16:47:45.000000000 -0500
35772 ++++ linux-2.6.28.8/mm/shmem.c 2009-02-21 09:37:50.000000000 -0500
35773 +@@ -2486,7 +2486,7 @@ static struct file_system_type tmpfs_fs_
35774 + .get_sb = shmem_get_sb,
35775 + .kill_sb = kill_litter_super,
35776 + };
35777 +-static struct vfsmount *shm_mnt;
35778 ++struct vfsmount *shm_mnt;
35779 +
35780 + static int __init init_tmpfs(void)
35781 + {
35782 +diff -urNp linux-2.6.28.8/mm/slab.c linux-2.6.28.8/mm/slab.c
35783 +--- linux-2.6.28.8/mm/slab.c 2009-02-06 16:47:45.000000000 -0500
35784 ++++ linux-2.6.28.8/mm/slab.c 2009-02-21 09:37:50.000000000 -0500
35785 +@@ -305,7 +305,7 @@ struct kmem_list3 {
35786 + * Need this for bootstrapping a per node allocator.
35787 + */
35788 + #define NUM_INIT_LISTS (3 * MAX_NUMNODES)
35789 +-struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
35790 ++struct kmem_list3 initkmem_list3[NUM_INIT_LISTS];
35791 + #define CACHE_CACHE 0
35792 + #define SIZE_AC MAX_NUMNODES
35793 + #define SIZE_L3 (2 * MAX_NUMNODES)
35794 +@@ -654,14 +654,14 @@ struct cache_names {
35795 + static struct cache_names __initdata cache_names[] = {
35796 + #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
35797 + #include <linux/kmalloc_sizes.h>
35798 +- {NULL,}
35799 ++ {NULL, NULL}
35800 + #undef CACHE
35801 + };
35802 +
35803 + static struct arraycache_init initarray_cache __initdata =
35804 +- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
35805 ++ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
35806 + static struct arraycache_init initarray_generic =
35807 +- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
35808 ++ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
35809 +
35810 + /* internal cache of cache description objs */
35811 + static struct kmem_cache cache_cache = {
35812 +@@ -2997,7 +2997,7 @@ retry:
35813 + * there must be at least one object available for
35814 + * allocation.
35815 + */
35816 +- BUG_ON(slabp->inuse < 0 || slabp->inuse >= cachep->num);
35817 ++ BUG_ON(slabp->inuse >= cachep->num);
35818 +
35819 + while (slabp->inuse < cachep->num && batchcount--) {
35820 + STATS_INC_ALLOCED(cachep);
35821 +@@ -4491,10 +4491,12 @@ static const struct file_operations proc
35822 +
35823 + static int __init slab_proc_init(void)
35824 + {
35825 ++#if !defined(CONFIG_GRKERNSEC_PROC_ADD)
35826 + proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
35827 + #ifdef CONFIG_DEBUG_SLAB_LEAK
35828 + proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations);
35829 + #endif
35830 ++#endif
35831 + return 0;
35832 + }
35833 + module_init(slab_proc_init);
35834 +diff -urNp linux-2.6.28.8/mm/slub.c linux-2.6.28.8/mm/slub.c
35835 +--- linux-2.6.28.8/mm/slub.c 2009-02-06 16:47:45.000000000 -0500
35836 ++++ linux-2.6.28.8/mm/slub.c 2009-02-21 09:37:50.000000000 -0500
35837 +@@ -4508,7 +4508,9 @@ static const struct file_operations proc
35838 +
35839 + static int __init slab_proc_init(void)
35840 + {
35841 ++#if !defined(CONFIG_GRKERNSEC_PROC_ADD)
35842 + proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
35843 ++#endif
35844 + return 0;
35845 + }
35846 + module_init(slab_proc_init);
35847 +diff -urNp linux-2.6.28.8/mm/tiny-shmem.c linux-2.6.28.8/mm/tiny-shmem.c
35848 +--- linux-2.6.28.8/mm/tiny-shmem.c 2009-02-06 16:47:45.000000000 -0500
35849 ++++ linux-2.6.28.8/mm/tiny-shmem.c 2009-02-21 09:37:50.000000000 -0500
35850 +@@ -26,7 +26,7 @@ static struct file_system_type tmpfs_fs_
35851 + .kill_sb = kill_litter_super,
35852 + };
35853 +
35854 +-static struct vfsmount *shm_mnt;
35855 ++struct vfsmount *shm_mnt;
35856 +
35857 + static int __init init_tmpfs(void)
35858 + {
35859 +diff -urNp linux-2.6.28.8/mm/util.c linux-2.6.28.8/mm/util.c
35860 +--- linux-2.6.28.8/mm/util.c 2009-02-06 16:47:45.000000000 -0500
35861 ++++ linux-2.6.28.8/mm/util.c 2009-02-21 09:37:50.000000000 -0500
35862 +@@ -167,6 +167,12 @@ EXPORT_SYMBOL(strndup_user);
35863 + void arch_pick_mmap_layout(struct mm_struct *mm)
35864 + {
35865 + mm->mmap_base = TASK_UNMAPPED_BASE;
35866 ++
35867 ++#ifdef CONFIG_PAX_RANDMMAP
35868 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
35869 ++ mm->mmap_base += mm->delta_mmap;
35870 ++#endif
35871 ++
35872 + mm->get_unmapped_area = arch_get_unmapped_area;
35873 + mm->unmap_area = arch_unmap_area;
35874 + }
35875 +diff -urNp linux-2.6.28.8/mm/vmalloc.c linux-2.6.28.8/mm/vmalloc.c
35876 +--- linux-2.6.28.8/mm/vmalloc.c 2009-03-07 10:24:49.000000000 -0500
35877 ++++ linux-2.6.28.8/mm/vmalloc.c 2009-03-07 10:29:51.000000000 -0500
35878 +@@ -90,6 +90,11 @@ static int vmap_pte_range(pmd_t *pmd, un
35879 + unsigned long end, pgprot_t prot, struct page **pages, int *nr)
35880 + {
35881 + pte_t *pte;
35882 ++ int ret = -ENOMEM;
35883 ++
35884 ++#ifdef CONFIG_PAX_KERNEXEC
35885 ++ unsigned long cr0;
35886 ++#endif
35887 +
35888 + /*
35889 + * nr is a running index into the array which helps higher level
35890 +@@ -99,17 +104,33 @@ static int vmap_pte_range(pmd_t *pmd, un
35891 + pte = pte_alloc_kernel(pmd, addr);
35892 + if (!pte)
35893 + return -ENOMEM;
35894 ++
35895 ++#ifdef CONFIG_PAX_KERNEXEC
35896 ++ pax_open_kernel(cr0);
35897 ++#endif
35898 ++
35899 + do {
35900 + struct page *page = pages[*nr];
35901 +
35902 +- if (WARN_ON(!pte_none(*pte)))
35903 +- return -EBUSY;
35904 +- if (WARN_ON(!page))
35905 +- return -ENOMEM;
35906 ++ if (WARN_ON(!pte_none(*pte))) {
35907 ++ ret = -EBUSY;
35908 ++ goto out;
35909 ++ }
35910 ++ if (WARN_ON(!page)) {
35911 ++ ret = -ENOMEM;
35912 ++ goto out;
35913 ++ }
35914 + set_pte_at(&init_mm, addr, pte, mk_pte(page, prot));
35915 + (*nr)++;
35916 + } while (pte++, addr += PAGE_SIZE, addr != end);
35917 +- return 0;
35918 ++ ret = 0;
35919 ++out:
35920 ++
35921 ++#ifdef CONFIG_PAX_KERNEXEC
35922 ++ pax_close_kernel(cr0);
35923 ++#endif
35924 ++
35925 ++ return ret;
35926 + }
35927 +
35928 + static int vmap_pmd_range(pud_t *pud, unsigned long addr,
35929 +@@ -1033,6 +1054,16 @@ static struct vm_struct *__get_vm_area_n
35930 + unsigned long align = 1;
35931 +
35932 + BUG_ON(in_interrupt());
35933 ++
35934 ++#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
35935 ++ if (flags & VM_KERNEXEC) {
35936 ++ if (start != VMALLOC_START || end != VMALLOC_END)
35937 ++ return NULL;
35938 ++ start = (unsigned long)MODULES_VADDR;
35939 ++ end = (unsigned long)MODULES_END;
35940 ++ }
35941 ++#endif
35942 ++
35943 + if (flags & VM_IOREMAP) {
35944 + int bit = fls(size);
35945 +
35946 +@@ -1256,6 +1287,11 @@ void *vmap(struct page **pages, unsigned
35947 + if (count > num_physpages)
35948 + return NULL;
35949 +
35950 ++#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
35951 ++ if (!(pgprot_val(prot) & _PAGE_NX))
35952 ++ flags |= VM_KERNEXEC;
35953 ++#endif
35954 ++
35955 + area = get_vm_area_caller((count << PAGE_SHIFT), flags,
35956 + __builtin_return_address(0));
35957 + if (!area)
35958 +@@ -1352,6 +1388,13 @@ static void *__vmalloc_node(unsigned lon
35959 + if (!size || (size >> PAGE_SHIFT) > num_physpages)
35960 + return NULL;
35961 +
35962 ++#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
35963 ++ if (!(pgprot_val(prot) & _PAGE_NX))
35964 ++ area = __get_vm_area_node(size, VM_ALLOC | VM_KERNEXEC, VMALLOC_START, VMALLOC_END,
35965 ++ node, gfp_mask, caller);
35966 ++ else
35967 ++#endif
35968 ++
35969 + area = __get_vm_area_node(size, VM_ALLOC, VMALLOC_START, VMALLOC_END,
35970 + node, gfp_mask, caller);
35971 +
35972 +@@ -1441,7 +1484,7 @@ EXPORT_SYMBOL(vmalloc_node);
35973 +
35974 + void *vmalloc_exec(unsigned long size)
35975 + {
35976 +- return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC);
35977 ++ return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL_EXEC);
35978 + }
35979 +
35980 + #if defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA32)
35981 +diff -urNp linux-2.6.28.8/net/bridge/br_stp_if.c linux-2.6.28.8/net/bridge/br_stp_if.c
35982 +--- linux-2.6.28.8/net/bridge/br_stp_if.c 2009-02-06 16:47:45.000000000 -0500
35983 ++++ linux-2.6.28.8/net/bridge/br_stp_if.c 2009-02-21 09:37:50.000000000 -0500
35984 +@@ -146,7 +146,7 @@ static void br_stp_stop(struct net_bridg
35985 + char *envp[] = { NULL };
35986 +
35987 + if (br->stp_enabled == BR_USER_STP) {
35988 +- r = call_usermodehelper(BR_STP_PROG, argv, envp, 1);
35989 ++ r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
35990 + printk(KERN_INFO "%s: userspace STP stopped, return code %d\n",
35991 + br->dev->name, r);
35992 +
35993 +diff -urNp linux-2.6.28.8/net/core/flow.c linux-2.6.28.8/net/core/flow.c
35994 +--- linux-2.6.28.8/net/core/flow.c 2009-02-06 16:47:45.000000000 -0500
35995 ++++ linux-2.6.28.8/net/core/flow.c 2009-02-21 09:37:50.000000000 -0500
35996 +@@ -39,7 +39,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT(
35997 +
35998 + static u32 flow_hash_shift;
35999 + #define flow_hash_size (1 << flow_hash_shift)
36000 +-static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL };
36001 ++static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables);
36002 +
36003 + #define flow_table(cpu) (per_cpu(flow_tables, cpu))
36004 +
36005 +@@ -52,7 +52,7 @@ struct flow_percpu_info {
36006 + u32 hash_rnd;
36007 + int count;
36008 + };
36009 +-static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 };
36010 ++static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info);
36011 +
36012 + #define flow_hash_rnd_recalc(cpu) \
36013 + (per_cpu(flow_hash_info, cpu).hash_rnd_recalc)
36014 +@@ -69,7 +69,7 @@ struct flow_flush_info {
36015 + atomic_t cpuleft;
36016 + struct completion completion;
36017 + };
36018 +-static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL };
36019 ++static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets);
36020 +
36021 + #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu))
36022 +
36023 +diff -urNp linux-2.6.28.8/net/dccp/ccids/ccid3.c linux-2.6.28.8/net/dccp/ccids/ccid3.c
36024 +--- linux-2.6.28.8/net/dccp/ccids/ccid3.c 2009-02-06 16:47:45.000000000 -0500
36025 ++++ linux-2.6.28.8/net/dccp/ccids/ccid3.c 2009-02-21 09:37:50.000000000 -0500
36026 +@@ -43,7 +43,7 @@
36027 + static int ccid3_debug;
36028 + #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
36029 + #else
36030 +-#define ccid3_pr_debug(format, a...)
36031 ++#define ccid3_pr_debug(format, a...) do {} while (0)
36032 + #endif
36033 +
36034 + /*
36035 +diff -urNp linux-2.6.28.8/net/dccp/dccp.h linux-2.6.28.8/net/dccp/dccp.h
36036 +--- linux-2.6.28.8/net/dccp/dccp.h 2009-02-06 16:47:45.000000000 -0500
36037 ++++ linux-2.6.28.8/net/dccp/dccp.h 2009-02-21 09:37:50.000000000 -0500
36038 +@@ -43,8 +43,8 @@ extern int dccp_debug;
36039 + #define dccp_pr_debug(format, a...) DCCP_PR_DEBUG(dccp_debug, format, ##a)
36040 + #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a)
36041 + #else
36042 +-#define dccp_pr_debug(format, a...)
36043 +-#define dccp_pr_debug_cat(format, a...)
36044 ++#define dccp_pr_debug(format, a...) do {} while (0)
36045 ++#define dccp_pr_debug_cat(format, a...) do {} while (0)
36046 + #endif
36047 +
36048 + extern struct inet_hashinfo dccp_hashinfo;
36049 +diff -urNp linux-2.6.28.8/net/ipv4/inet_connection_sock.c linux-2.6.28.8/net/ipv4/inet_connection_sock.c
36050 +--- linux-2.6.28.8/net/ipv4/inet_connection_sock.c 2009-02-06 16:47:45.000000000 -0500
36051 ++++ linux-2.6.28.8/net/ipv4/inet_connection_sock.c 2009-02-21 09:37:50.000000000 -0500
36052 +@@ -15,6 +15,7 @@
36053 +
36054 + #include <linux/module.h>
36055 + #include <linux/jhash.h>
36056 ++#include <linux/security.h>
36057 +
36058 + #include <net/inet_connection_sock.h>
36059 + #include <net/inet_hashtables.h>
36060 +diff -urNp linux-2.6.28.8/net/ipv4/inet_hashtables.c linux-2.6.28.8/net/ipv4/inet_hashtables.c
36061 +--- linux-2.6.28.8/net/ipv4/inet_hashtables.c 2009-02-06 16:47:45.000000000 -0500
36062 ++++ linux-2.6.28.8/net/ipv4/inet_hashtables.c 2009-02-21 09:37:50.000000000 -0500
36063 +@@ -18,11 +18,14 @@
36064 + #include <linux/sched.h>
36065 + #include <linux/slab.h>
36066 + #include <linux/wait.h>
36067 ++#include <linux/security.h>
36068 +
36069 + #include <net/inet_connection_sock.h>
36070 + #include <net/inet_hashtables.h>
36071 + #include <net/ip.h>
36072 +
36073 ++extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
36074 ++
36075 + /*
36076 + * Allocate and initialize a new local port bind bucket.
36077 + * The bindhash mutex for snum's hash chain must be held here.
36078 +@@ -487,6 +490,8 @@ ok:
36079 + }
36080 + spin_unlock(&head->lock);
36081 +
36082 ++ gr_update_task_in_ip_table(current, inet_sk(sk));
36083 ++
36084 + if (tw) {
36085 + inet_twsk_deschedule(tw, death_row);
36086 + inet_twsk_put(tw);
36087 +diff -urNp linux-2.6.28.8/net/ipv4/netfilter/ipt_stealth.c linux-2.6.28.8/net/ipv4/netfilter/ipt_stealth.c
36088 +--- linux-2.6.28.8/net/ipv4/netfilter/ipt_stealth.c 1969-12-31 19:00:00.000000000 -0500
36089 ++++ linux-2.6.28.8/net/ipv4/netfilter/ipt_stealth.c 2009-02-21 09:37:50.000000000 -0500
36090 +@@ -0,0 +1,114 @@
36091 ++/* Kernel module to add stealth support.
36092 ++ *
36093 ++ * Copyright (C) 2002-2006 Brad Spengler <spender@××××××××××.net>
36094 ++ *
36095 ++ */
36096 ++
36097 ++#include <linux/kernel.h>
36098 ++#include <linux/module.h>
36099 ++#include <linux/skbuff.h>
36100 ++#include <linux/net.h>
36101 ++#include <linux/sched.h>
36102 ++#include <linux/inet.h>
36103 ++#include <linux/stddef.h>
36104 ++
36105 ++#include <net/ip.h>
36106 ++#include <net/sock.h>
36107 ++#include <net/tcp.h>
36108 ++#include <net/udp.h>
36109 ++#include <net/route.h>
36110 ++#include <net/inet_common.h>
36111 ++
36112 ++#include <linux/netfilter_ipv4/ip_tables.h>
36113 ++
36114 ++MODULE_LICENSE("GPL");
36115 ++
36116 ++extern struct sock *udp_v4_lookup(struct net *net, u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
36117 ++
36118 ++static bool
36119 ++match(const struct sk_buff *skb,
36120 ++ const struct net_device *in,
36121 ++ const struct net_device *out,
36122 ++ const struct xt_match *match,
36123 ++ const void *matchinfo,
36124 ++ int offset,
36125 ++ unsigned int protoff,
36126 ++ bool *hotdrop)
36127 ++{
36128 ++ struct iphdr *ip = ip_hdr(skb);
36129 ++ struct tcphdr th;
36130 ++ struct udphdr uh;
36131 ++ struct sock *sk = NULL;
36132 ++
36133 ++ if (!ip || offset) return false;
36134 ++
36135 ++ switch(ip->protocol) {
36136 ++ case IPPROTO_TCP:
36137 ++ if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &th, sizeof(th)) < 0) {
36138 ++ *hotdrop = true;
36139 ++ return false;
36140 ++ }
36141 ++ if (!(th.syn && !th.ack)) return false;
36142 ++ sk = inet_lookup_listener(dev_net(skb->dev), &tcp_hashinfo, ip->daddr, th.dest, inet_iif(skb));
36143 ++ break;
36144 ++ case IPPROTO_UDP:
36145 ++ if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &uh, sizeof(uh)) < 0) {
36146 ++ *hotdrop = true;
36147 ++ return false;
36148 ++ }
36149 ++ sk = udp_v4_lookup(dev_net(skb->dev), ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
36150 ++ break;
36151 ++ default:
36152 ++ return false;
36153 ++ }
36154 ++
36155 ++ if(!sk) // port is being listened on, match this
36156 ++ return true;
36157 ++ else {
36158 ++ sock_put(sk);
36159 ++ return false;
36160 ++ }
36161 ++}
36162 ++
36163 ++/* Called when user tries to insert an entry of this type. */
36164 ++static bool
36165 ++checkentry(const char *tablename,
36166 ++ const void *nip,
36167 ++ const struct xt_match *match,
36168 ++ void *matchinfo,
36169 ++ unsigned int hook_mask)
36170 ++{
36171 ++ const struct ipt_ip *ip = (const struct ipt_ip *)nip;
36172 ++
36173 ++ if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
36174 ++ ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
36175 ++ && (hook_mask & (1 << NF_INET_LOCAL_IN)))
36176 ++ return true;
36177 ++
36178 ++ printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
36179 ++
36180 ++ return false;
36181 ++}
36182 ++
36183 ++
36184 ++static struct xt_match stealth_match __read_mostly = {
36185 ++ .name = "stealth",
36186 ++ .family = AF_INET,
36187 ++ .match = match,
36188 ++ .checkentry = checkentry,
36189 ++ .destroy = NULL,
36190 ++ .me = THIS_MODULE
36191 ++};
36192 ++
36193 ++static int __init init(void)
36194 ++{
36195 ++ return xt_register_match(&stealth_match);
36196 ++}
36197 ++
36198 ++static void __exit fini(void)
36199 ++{
36200 ++ xt_unregister_match(&stealth_match);
36201 ++}
36202 ++
36203 ++module_init(init);
36204 ++module_exit(fini);
36205 +diff -urNp linux-2.6.28.8/net/ipv4/netfilter/Kconfig linux-2.6.28.8/net/ipv4/netfilter/Kconfig
36206 +--- linux-2.6.28.8/net/ipv4/netfilter/Kconfig 2009-02-06 16:47:45.000000000 -0500
36207 ++++ linux-2.6.28.8/net/ipv4/netfilter/Kconfig 2009-03-07 04:29:14.000000000 -0500
36208 +@@ -101,6 +101,21 @@ config IP_NF_MATCH_TTL
36209 +
36210 + To compile it as a module, choose M here. If unsure, say N.
36211 +
36212 ++config IP_NF_MATCH_STEALTH
36213 ++ tristate "stealth match support"
36214 ++ depends on IP_NF_IPTABLES
36215 ++ help
36216 ++ Enabling this option will drop all syn packets coming to unserved tcp
36217 ++ ports as well as all packets coming to unserved udp ports. If you
36218 ++ are using your system to route any type of packets (ie. via NAT)
36219 ++ you should put this module at the end of your ruleset, since it will
36220 ++ drop packets that aren't going to ports that are listening on your
36221 ++ machine itself, it doesn't take into account that the packet might be
36222 ++ destined for someone on your internal network if you're using NAT for
36223 ++ instance.
36224 ++
36225 ++ To compile it as a module, choose M here. If unsure, say N.
36226 ++
36227 + # `filter', generic and specific targets
36228 + config IP_NF_FILTER
36229 + tristate "Packet filtering"
36230 +diff -urNp linux-2.6.28.8/net/ipv4/netfilter/Makefile linux-2.6.28.8/net/ipv4/netfilter/Makefile
36231 +--- linux-2.6.28.8/net/ipv4/netfilter/Makefile 2009-02-06 16:47:45.000000000 -0500
36232 ++++ linux-2.6.28.8/net/ipv4/netfilter/Makefile 2009-02-21 09:37:50.000000000 -0500
36233 +@@ -61,6 +61,7 @@ obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) +=
36234 + obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
36235 + obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
36236 + obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
36237 ++obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
36238 + obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
36239 + obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
36240 +
36241 +diff -urNp linux-2.6.28.8/net/ipv4/tcp_ipv4.c linux-2.6.28.8/net/ipv4/tcp_ipv4.c
36242 +--- linux-2.6.28.8/net/ipv4/tcp_ipv4.c 2009-02-06 16:47:45.000000000 -0500
36243 ++++ linux-2.6.28.8/net/ipv4/tcp_ipv4.c 2009-02-21 09:37:50.000000000 -0500
36244 +@@ -55,6 +55,7 @@
36245 + #include <linux/fcntl.h>
36246 + #include <linux/module.h>
36247 + #include <linux/random.h>
36248 ++#include <linux/security.h>
36249 + #include <linux/cache.h>
36250 + #include <linux/jhash.h>
36251 + #include <linux/init.h>
36252 +diff -urNp linux-2.6.28.8/net/ipv4/udp.c linux-2.6.28.8/net/ipv4/udp.c
36253 +--- linux-2.6.28.8/net/ipv4/udp.c 2009-02-08 00:54:28.000000000 -0500
36254 ++++ linux-2.6.28.8/net/ipv4/udp.c 2009-02-21 09:37:50.000000000 -0500
36255 +@@ -84,6 +84,7 @@
36256 + #include <linux/types.h>
36257 + #include <linux/fcntl.h>
36258 + #include <linux/module.h>
36259 ++#include <linux/security.h>
36260 + #include <linux/socket.h>
36261 + #include <linux/sockios.h>
36262 + #include <linux/igmp.h>
36263 +@@ -104,6 +105,9 @@
36264 + #include <net/xfrm.h>
36265 + #include "udp_impl.h"
36266 +
36267 ++extern int gr_search_udp_recvmsg(struct sock *sk, const struct sk_buff *skb);
36268 ++extern int gr_search_udp_sendmsg(struct sock *sk, struct sockaddr_in *addr);
36269 ++
36270 + /*
36271 + * Snmp MIB for the UDP layer
36272 + */
36273 +@@ -284,6 +288,13 @@ struct sock *udp4_lib_lookup(struct net
36274 + }
36275 + EXPORT_SYMBOL_GPL(udp4_lib_lookup);
36276 +
36277 ++struct sock *udp_v4_lookup(struct net *net, __be32 saddr, __be16 sport,
36278 ++ __be32 daddr, __be16 dport, int dif)
36279 ++{
36280 ++ return __udp4_lib_lookup(net, saddr, sport, daddr, dport, dif, udp_hash);
36281 ++}
36282 ++
36283 ++
36284 + static inline struct sock *udp_v4_mcast_next(struct net *net, struct sock *sk,
36285 + __be16 loc_port, __be32 loc_addr,
36286 + __be16 rmt_port, __be32 rmt_addr,
36287 +@@ -574,9 +585,18 @@ int udp_sendmsg(struct kiocb *iocb, stru
36288 + dport = usin->sin_port;
36289 + if (dport == 0)
36290 + return -EINVAL;
36291 ++
36292 ++ err = gr_search_udp_sendmsg(sk, usin);
36293 ++ if (err)
36294 ++ return err;
36295 + } else {
36296 + if (sk->sk_state != TCP_ESTABLISHED)
36297 + return -EDESTADDRREQ;
36298 ++
36299 ++ err = gr_search_udp_sendmsg(sk, NULL);
36300 ++ if (err)
36301 ++ return err;
36302 ++
36303 + daddr = inet->daddr;
36304 + dport = inet->dport;
36305 + /* Open fast path for connected socket.
36306 +@@ -842,6 +862,10 @@ try_again:
36307 + if (!skb)
36308 + goto out;
36309 +
36310 ++ err = gr_search_udp_recvmsg(sk, skb);
36311 ++ if (err)
36312 ++ goto out_free;
36313 ++
36314 + ulen = skb->len - sizeof(struct udphdr);
36315 + copied = len;
36316 + if (copied > ulen)
36317 +diff -urNp linux-2.6.28.8/net/ipv6/exthdrs.c linux-2.6.28.8/net/ipv6/exthdrs.c
36318 +--- linux-2.6.28.8/net/ipv6/exthdrs.c 2009-02-06 16:47:45.000000000 -0500
36319 ++++ linux-2.6.28.8/net/ipv6/exthdrs.c 2009-02-21 09:37:50.000000000 -0500
36320 +@@ -630,7 +630,7 @@ static struct tlvtype_proc tlvprochopopt
36321 + .type = IPV6_TLV_JUMBO,
36322 + .func = ipv6_hop_jumbo,
36323 + },
36324 +- { -1, }
36325 ++ { -1, NULL }
36326 + };
36327 +
36328 + int ipv6_parse_hopopts(struct sk_buff *skb)
36329 +diff -urNp linux-2.6.28.8/net/ipv6/raw.c linux-2.6.28.8/net/ipv6/raw.c
36330 +--- linux-2.6.28.8/net/ipv6/raw.c 2009-02-06 16:47:45.000000000 -0500
36331 ++++ linux-2.6.28.8/net/ipv6/raw.c 2009-02-21 09:37:50.000000000 -0500
36332 +@@ -600,7 +600,7 @@ out:
36333 + return err;
36334 + }
36335 +
36336 +-static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
36337 ++static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
36338 + struct flowi *fl, struct rt6_info *rt,
36339 + unsigned int flags)
36340 + {
36341 +diff -urNp linux-2.6.28.8/net/irda/ircomm/ircomm_tty.c linux-2.6.28.8/net/irda/ircomm/ircomm_tty.c
36342 +--- linux-2.6.28.8/net/irda/ircomm/ircomm_tty.c 2009-02-06 16:47:45.000000000 -0500
36343 ++++ linux-2.6.28.8/net/irda/ircomm/ircomm_tty.c 2009-02-21 09:37:50.000000000 -0500
36344 +@@ -371,7 +371,7 @@ static int ircomm_tty_open(struct tty_st
36345 + IRDA_DEBUG(2, "%s()\n", __func__ );
36346 +
36347 + line = tty->index;
36348 +- if ((line < 0) || (line >= IRCOMM_TTY_PORTS)) {
36349 ++ if (line >= IRCOMM_TTY_PORTS) {
36350 + return -ENODEV;
36351 + }
36352 +
36353 +diff -urNp linux-2.6.28.8/net/sctp/socket.c linux-2.6.28.8/net/sctp/socket.c
36354 +--- linux-2.6.28.8/net/sctp/socket.c 2009-02-06 16:47:45.000000000 -0500
36355 ++++ linux-2.6.28.8/net/sctp/socket.c 2009-02-21 09:37:50.000000000 -0500
36356 +@@ -1434,7 +1434,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
36357 + struct sctp_sndrcvinfo *sinfo;
36358 + struct sctp_initmsg *sinit;
36359 + sctp_assoc_t associd = 0;
36360 +- sctp_cmsgs_t cmsgs = { NULL };
36361 ++ sctp_cmsgs_t cmsgs = { NULL, NULL };
36362 + int err;
36363 + sctp_scope_t scope;
36364 + long timeo;
36365 +@@ -5616,7 +5616,6 @@ pp_found:
36366 + */
36367 + int reuse = sk->sk_reuse;
36368 + struct sock *sk2;
36369 +- struct hlist_node *node;
36370 +
36371 + SCTP_DEBUG_PRINTK("sctp_get_port() found a possible match\n");
36372 + if (pp->fastreuse && sk->sk_reuse &&
36373 +diff -urNp linux-2.6.28.8/net/socket.c linux-2.6.28.8/net/socket.c
36374 +--- linux-2.6.28.8/net/socket.c 2009-02-06 16:47:45.000000000 -0500
36375 ++++ linux-2.6.28.8/net/socket.c 2009-03-07 04:29:14.000000000 -0500
36376 +@@ -87,6 +87,7 @@
36377 + #include <linux/audit.h>
36378 + #include <linux/wireless.h>
36379 + #include <linux/nsproxy.h>
36380 ++#include <linux/in.h>
36381 +
36382 + #include <asm/uaccess.h>
36383 + #include <asm/unistd.h>
36384 +@@ -97,6 +98,21 @@
36385 + #include <net/sock.h>
36386 + #include <linux/netfilter.h>
36387 +
36388 ++extern void gr_attach_curr_ip(const struct sock *sk);
36389 ++extern int gr_handle_sock_all(const int family, const int type,
36390 ++ const int protocol);
36391 ++extern int gr_handle_sock_server(const struct sockaddr *sck);
36392 ++extern int gr_handle_sock_server_other(const struct socket *sck);
36393 ++extern int gr_handle_sock_client(const struct sockaddr *sck);
36394 ++extern int gr_search_connect(struct socket * sock,
36395 ++ struct sockaddr_in * addr);
36396 ++extern int gr_search_bind(struct socket * sock,
36397 ++ struct sockaddr_in * addr);
36398 ++extern int gr_search_listen(struct socket * sock);
36399 ++extern int gr_search_accept(struct socket * sock);
36400 ++extern int gr_search_socket(const int domain, const int type,
36401 ++ const int protocol);
36402 ++
36403 + static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
36404 + static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
36405 + unsigned long nr_segs, loff_t pos);
36406 +@@ -300,7 +316,7 @@ static int sockfs_get_sb(struct file_sys
36407 + mnt);
36408 + }
36409 +
36410 +-static struct vfsmount *sock_mnt __read_mostly;
36411 ++struct vfsmount *sock_mnt __read_mostly;
36412 +
36413 + static struct file_system_type sock_fs_type = {
36414 + .name = "sockfs",
36415 +@@ -1235,6 +1251,16 @@ SYSCALL_DEFINE3(socket, int, family, int
36416 + if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
36417 + flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
36418 +
36419 ++ if(!gr_search_socket(family, type, protocol)) {
36420 ++ retval = -EACCES;
36421 ++ goto out;
36422 ++ }
36423 ++
36424 ++ if (gr_handle_sock_all(family, type, protocol)) {
36425 ++ retval = -EACCES;
36426 ++ goto out;
36427 ++ }
36428 ++
36429 + retval = sock_create(family, type, protocol, &sock);
36430 + if (retval < 0)
36431 + goto out;
36432 +@@ -1374,6 +1400,14 @@ SYSCALL_DEFINE3(bind, int, fd, struct so
36433 + if (sock) {
36434 + err = move_addr_to_kernel(umyaddr, addrlen, (struct sockaddr *)&address);
36435 + if (err >= 0) {
36436 ++ if (gr_handle_sock_server((struct sockaddr *)&address)) {
36437 ++ err = -EACCES;
36438 ++ goto error;
36439 ++ }
36440 ++ err = gr_search_bind(sock, (struct sockaddr_in *)&address);
36441 ++ if (err)
36442 ++ goto error;
36443 ++
36444 + err = security_socket_bind(sock,
36445 + (struct sockaddr *)&address,
36446 + addrlen);
36447 +@@ -1382,6 +1416,7 @@ SYSCALL_DEFINE3(bind, int, fd, struct so
36448 + (struct sockaddr *)
36449 + &address, addrlen);
36450 + }
36451 ++error:
36452 + fput_light(sock->file, fput_needed);
36453 + }
36454 + return err;
36455 +@@ -1405,10 +1440,20 @@ SYSCALL_DEFINE2(listen, int, fd, int, ba
36456 + if ((unsigned)backlog > somaxconn)
36457 + backlog = somaxconn;
36458 +
36459 ++ if (gr_handle_sock_server_other(sock)) {
36460 ++ err = -EPERM;
36461 ++ goto error;
36462 ++ }
36463 ++
36464 ++ err = gr_search_listen(sock);
36465 ++ if (err)
36466 ++ goto error;
36467 ++
36468 + err = security_socket_listen(sock, backlog);
36469 + if (!err)
36470 + err = sock->ops->listen(sock, backlog);
36471 +
36472 ++error:
36473 + fput_light(sock->file, fput_needed);
36474 + }
36475 + return err;
36476 +@@ -1451,6 +1496,18 @@ SYSCALL_DEFINE4(accept4, int, fd, struct
36477 + newsock->type = sock->type;
36478 + newsock->ops = sock->ops;
36479 +
36480 ++ if (gr_handle_sock_server_other(sock)) {
36481 ++ err = -EPERM;
36482 ++ sock_release(newsock);
36483 ++ goto out_put;
36484 ++ }
36485 ++
36486 ++ err = gr_search_accept(sock);
36487 ++ if (err) {
36488 ++ sock_release(newsock);
36489 ++ goto out_put;
36490 ++ }
36491 ++
36492 + /*
36493 + * We don't need try_module_get here, as the listening socket (sock)
36494 + * has the protocol module (sock->ops->owner) held.
36495 +@@ -1494,6 +1551,7 @@ SYSCALL_DEFINE4(accept4, int, fd, struct
36496 + err = newfd;
36497 +
36498 + security_socket_post_accept(sock, newsock);
36499 ++ gr_attach_curr_ip(newsock->sk);
36500 +
36501 + out_put:
36502 + fput_light(sock->file, fput_needed);
36503 +@@ -1532,6 +1590,7 @@ SYSCALL_DEFINE3(connect, int, fd, struct
36504 + int, addrlen)
36505 + {
36506 + struct socket *sock;
36507 ++ struct sockaddr *sck;
36508 + struct sockaddr_storage address;
36509 + int err, fput_needed;
36510 +
36511 +@@ -1542,6 +1601,17 @@ SYSCALL_DEFINE3(connect, int, fd, struct
36512 + if (err < 0)
36513 + goto out_put;
36514 +
36515 ++ sck = (struct sockaddr *)&address;
36516 ++
36517 ++ if (gr_handle_sock_client(sck)) {
36518 ++ err = -EACCES;
36519 ++ goto out_put;
36520 ++ }
36521 ++
36522 ++ err = gr_search_connect(sock, (struct sockaddr_in *)sck);
36523 ++ if (err)
36524 ++ goto out_put;
36525 ++
36526 + err =
36527 + security_socket_connect(sock, (struct sockaddr *)&address, addrlen);
36528 + if (err)
36529 +diff -urNp linux-2.6.28.8/net/unix/af_unix.c linux-2.6.28.8/net/unix/af_unix.c
36530 +--- linux-2.6.28.8/net/unix/af_unix.c 2009-02-06 16:47:45.000000000 -0500
36531 ++++ linux-2.6.28.8/net/unix/af_unix.c 2009-02-21 09:37:50.000000000 -0500
36532 +@@ -727,6 +727,12 @@ static struct sock *unix_find_other(stru
36533 + err = -ECONNREFUSED;
36534 + if (!S_ISSOCK(inode->i_mode))
36535 + goto put_fail;
36536 ++
36537 ++ if (!gr_acl_handle_unix(path.dentry, path.mnt)) {
36538 ++ err = -EACCES;
36539 ++ goto put_fail;
36540 ++ }
36541 ++
36542 + u = unix_find_socket_byinode(net, inode);
36543 + if (!u)
36544 + goto put_fail;
36545 +@@ -747,6 +753,13 @@ static struct sock *unix_find_other(stru
36546 + if (u) {
36547 + struct dentry *dentry;
36548 + dentry = unix_sk(u)->dentry;
36549 ++
36550 ++ if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
36551 ++ err = -EPERM;
36552 ++ sock_put(u);
36553 ++ goto fail;
36554 ++ }
36555 ++
36556 + if (dentry)
36557 + touch_atime(unix_sk(u)->mnt, dentry);
36558 + } else
36559 +@@ -829,10 +842,20 @@ static int unix_bind(struct socket *sock
36560 + err = mnt_want_write(nd.path.mnt);
36561 + if (err)
36562 + goto out_mknod_dput;
36563 ++
36564 ++ if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
36565 ++ err = -EACCES;
36566 ++ mnt_drop_write(nd.path.mnt);
36567 ++ goto out_mknod_dput;
36568 ++ }
36569 ++
36570 + err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0);
36571 + mnt_drop_write(nd.path.mnt);
36572 + if (err)
36573 + goto out_mknod_dput;
36574 ++
36575 ++ gr_handle_create(dentry, nd.path.mnt);
36576 ++
36577 + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
36578 + dput(nd.path.dentry);
36579 + nd.path.dentry = dentry;
36580 +@@ -850,6 +873,10 @@ static int unix_bind(struct socket *sock
36581 + goto out_unlock;
36582 + }
36583 +
36584 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
36585 ++ sk->sk_peercred.pid = current->pid;
36586 ++#endif
36587 ++
36588 + list = &unix_socket_table[addr->hash];
36589 + } else {
36590 + list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
36591 +diff -urNp linux-2.6.28.8/scripts/pnmtologo.c linux-2.6.28.8/scripts/pnmtologo.c
36592 +--- linux-2.6.28.8/scripts/pnmtologo.c 2009-02-06 16:47:45.000000000 -0500
36593 ++++ linux-2.6.28.8/scripts/pnmtologo.c 2009-02-21 09:37:50.000000000 -0500
36594 +@@ -237,14 +237,14 @@ static void write_header(void)
36595 + fprintf(out, " * Linux logo %s\n", logoname);
36596 + fputs(" */\n\n", out);
36597 + fputs("#include <linux/linux_logo.h>\n\n", out);
36598 +- fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
36599 ++ fprintf(out, "static unsigned char %s_data[] = {\n",
36600 + logoname);
36601 + }
36602 +
36603 + static void write_footer(void)
36604 + {
36605 + fputs("\n};\n\n", out);
36606 +- fprintf(out, "struct linux_logo %s __initdata = {\n", logoname);
36607 ++ fprintf(out, "struct linux_logo %s = {\n", logoname);
36608 + fprintf(out, " .type\t= %s,\n", logo_types[logo_type]);
36609 + fprintf(out, " .width\t= %d,\n", logo_width);
36610 + fprintf(out, " .height\t= %d,\n", logo_height);
36611 +@@ -374,7 +374,7 @@ static void write_logo_clut224(void)
36612 + fputs("\n};\n\n", out);
36613 +
36614 + /* write logo clut */
36615 +- fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
36616 ++ fprintf(out, "static unsigned char %s_clut[] = {\n",
36617 + logoname);
36618 + write_hex_cnt = 0;
36619 + for (i = 0; i < logo_clutsize; i++) {
36620 +diff -urNp linux-2.6.28.8/security/commoncap.c linux-2.6.28.8/security/commoncap.c
36621 +--- linux-2.6.28.8/security/commoncap.c 2009-02-06 16:47:45.000000000 -0500
36622 ++++ linux-2.6.28.8/security/commoncap.c 2009-03-07 04:29:14.000000000 -0500
36623 +@@ -27,9 +27,11 @@
36624 + #include <linux/prctl.h>
36625 + #include <linux/securebits.h>
36626 +
36627 ++extern kernel_cap_t gr_cap_rtnetlink(struct sock *sk);
36628 ++
36629 + int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
36630 + {
36631 +- NETLINK_CB(skb).eff_cap = current->cap_effective;
36632 ++ NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink(sk);
36633 + return 0;
36634 + }
36635 +
36636 +@@ -56,6 +58,14 @@ int cap_capable (struct task_struct *tsk
36637 + return -EPERM;
36638 + }
36639 +
36640 ++int cap_capable_nolog (struct task_struct *tsk, int cap)
36641 ++{
36642 ++ /* tsk = current for all callers */
36643 ++ if (cap_raised(tsk->cap_effective, cap) && gr_is_capable_nolog(cap))
36644 ++ return 0;
36645 ++ return -EPERM;
36646 ++}
36647 ++
36648 + int cap_settime(struct timespec *ts, struct timezone *tz)
36649 + {
36650 + if (!capable(CAP_SYS_TIME))
36651 +@@ -379,8 +389,11 @@ void cap_bprm_apply_creds (struct linux_
36652 + }
36653 + }
36654 +
36655 +- current->suid = current->euid = current->fsuid = bprm->e_uid;
36656 +- current->sgid = current->egid = current->fsgid = bprm->e_gid;
36657 ++ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
36658 ++ current->suid = current->euid = current->fsuid = bprm->e_uid;
36659 ++
36660 ++ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
36661 ++ current->sgid = current->egid = current->fsgid = bprm->e_gid;
36662 +
36663 + /* For init, we want to retain the capabilities set
36664 + * in the init_task struct. Thus we skip the usual
36665 +@@ -393,6 +406,8 @@ void cap_bprm_apply_creds (struct linux_
36666 + cap_clear(current->cap_effective);
36667 + }
36668 +
36669 ++ gr_handle_chroot_caps(current);
36670 ++
36671 + /* AUD: Audit candidate if current->cap_effective is set */
36672 +
36673 + current->securebits &= ~issecure_mask(SECURE_KEEP_CAPS);
36674 +@@ -705,7 +720,7 @@ int cap_vm_enough_memory(struct mm_struc
36675 + {
36676 + int cap_sys_admin = 0;
36677 +
36678 +- if (cap_capable(current, CAP_SYS_ADMIN) == 0)
36679 ++ if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
36680 + cap_sys_admin = 1;
36681 + return __vm_enough_memory(mm, pages, cap_sys_admin);
36682 + }
36683 +diff -urNp linux-2.6.28.8/security/Kconfig linux-2.6.28.8/security/Kconfig
36684 +--- linux-2.6.28.8/security/Kconfig 2009-02-06 16:47:45.000000000 -0500
36685 ++++ linux-2.6.28.8/security/Kconfig 2009-02-21 09:37:50.000000000 -0500
36686 +@@ -4,6 +4,447 @@
36687 +
36688 + menu "Security options"
36689 +
36690 ++source grsecurity/Kconfig
36691 ++
36692 ++menu "PaX"
36693 ++
36694 ++config PAX
36695 ++ bool "Enable various PaX features"
36696 ++ depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86)
36697 ++ help
36698 ++ This allows you to enable various PaX features. PaX adds
36699 ++ intrusion prevention mechanisms to the kernel that reduce
36700 ++ the risks posed by exploitable memory corruption bugs.
36701 ++
36702 ++menu "PaX Control"
36703 ++ depends on PAX
36704 ++
36705 ++config PAX_SOFTMODE
36706 ++ bool 'Support soft mode'
36707 ++ help
36708 ++ Enabling this option will allow you to run PaX in soft mode, that
36709 ++ is, PaX features will not be enforced by default, only on executables
36710 ++ marked explicitly. You must also enable PT_PAX_FLAGS support as it
36711 ++ is the only way to mark executables for soft mode use.
36712 ++
36713 ++ Soft mode can be activated by using the "pax_softmode=1" kernel command
36714 ++ line option on boot. Furthermore you can control various PaX features
36715 ++ at runtime via the entries in /proc/sys/kernel/pax.
36716 ++
36717 ++config PAX_EI_PAX
36718 ++ bool 'Use legacy ELF header marking'
36719 ++ help
36720 ++ Enabling this option will allow you to control PaX features on
36721 ++ a per executable basis via the 'chpax' utility available at
36722 ++ http://pax.grsecurity.net/. The control flags will be read from
36723 ++ an otherwise reserved part of the ELF header. This marking has
36724 ++ numerous drawbacks (no support for soft-mode, toolchain does not
36725 ++ know about the non-standard use of the ELF header) therefore it
36726 ++ has been deprecated in favour of PT_PAX_FLAGS support.
36727 ++
36728 ++ If you have applications not marked by the PT_PAX_FLAGS ELF
36729 ++ program header then you MUST enable this option otherwise they
36730 ++ will not get any protection.
36731 ++
36732 ++ Note that if you enable PT_PAX_FLAGS marking support as well,
36733 ++ the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
36734 ++
36735 ++config PAX_PT_PAX_FLAGS
36736 ++ bool 'Use ELF program header marking'
36737 ++ help
36738 ++ Enabling this option will allow you to control PaX features on
36739 ++ a per executable basis via the 'paxctl' utility available at
36740 ++ http://pax.grsecurity.net/. The control flags will be read from
36741 ++ a PaX specific ELF program header (PT_PAX_FLAGS). This marking
36742 ++ has the benefits of supporting both soft mode and being fully
36743 ++ integrated into the toolchain (the binutils patch is available
36744 ++ from http://pax.grsecurity.net).
36745 ++
36746 ++ If you have applications not marked by the PT_PAX_FLAGS ELF
36747 ++ program header then you MUST enable the EI_PAX marking support
36748 ++ otherwise they will not get any protection.
36749 ++
36750 ++ Note that if you enable the legacy EI_PAX marking support as well,
36751 ++ the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
36752 ++
36753 ++choice
36754 ++ prompt 'MAC system integration'
36755 ++ default PAX_HAVE_ACL_FLAGS
36756 ++ help
36757 ++ Mandatory Access Control systems have the option of controlling
36758 ++ PaX flags on a per executable basis, choose the method supported
36759 ++ by your particular system.
36760 ++
36761 ++ - "none": if your MAC system does not interact with PaX,
36762 ++ - "direct": if your MAC system defines pax_set_initial_flags() itself,
36763 ++ - "hook": if your MAC system uses the pax_set_initial_flags_func callback.
36764 ++
36765 ++ NOTE: this option is for developers/integrators only.
36766 ++
36767 ++ config PAX_NO_ACL_FLAGS
36768 ++ bool 'none'
36769 ++
36770 ++ config PAX_HAVE_ACL_FLAGS
36771 ++ bool 'direct'
36772 ++
36773 ++ config PAX_HOOK_ACL_FLAGS
36774 ++ bool 'hook'
36775 ++endchoice
36776 ++
36777 ++endmenu
36778 ++
36779 ++menu "Non-executable pages"
36780 ++ depends on PAX
36781 ++
36782 ++config PAX_NOEXEC
36783 ++ bool "Enforce non-executable pages"
36784 ++ 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)
36785 ++ help
36786 ++ By design some architectures do not allow for protecting memory
36787 ++ pages against execution or even if they do, Linux does not make
36788 ++ use of this feature. In practice this means that if a page is
36789 ++ readable (such as the stack or heap) it is also executable.
36790 ++
36791 ++ There is a well known exploit technique that makes use of this
36792 ++ fact and a common programming mistake where an attacker can
36793 ++ introduce code of his choice somewhere in the attacked program's
36794 ++ memory (typically the stack or the heap) and then execute it.
36795 ++
36796 ++ If the attacked program was running with different (typically
36797 ++ higher) privileges than that of the attacker, then he can elevate
36798 ++ his own privilege level (e.g. get a root shell, write to files for
36799 ++ which he does not have write access to, etc).
36800 ++
36801 ++ Enabling this option will let you choose from various features
36802 ++ that prevent the injection and execution of 'foreign' code in
36803 ++ a program.
36804 ++
36805 ++ This will also break programs that rely on the old behaviour and
36806 ++ expect that dynamically allocated memory via the malloc() family
36807 ++ of functions is executable (which it is not). Notable examples
36808 ++ are the XFree86 4.x server, the java runtime and wine.
36809 ++
36810 ++config PAX_PAGEEXEC
36811 ++ bool "Paging based non-executable pages"
36812 ++ 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)
36813 ++ help
36814 ++ This implementation is based on the paging feature of the CPU.
36815 ++ On i386 without hardware non-executable bit support there is a
36816 ++ variable but usually low performance impact, however on Intel's
36817 ++ P4 core based CPUs it is very high so you should not enable this
36818 ++ for kernels meant to be used on such CPUs.
36819 ++
36820 ++ On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386
36821 ++ with hardware non-executable bit support there is no performance
36822 ++ impact, on ppc the impact is negligible.
36823 ++
36824 ++ Note that several architectures require various emulations due to
36825 ++ badly designed userland ABIs, this will cause a performance impact
36826 ++ but will disappear as soon as userland is fixed (e.g., ppc users
36827 ++ can make use of the secure-plt feature found in binutils).
36828 ++
36829 ++config PAX_SEGMEXEC
36830 ++ bool "Segmentation based non-executable pages"
36831 ++ depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32
36832 ++ help
36833 ++ This implementation is based on the segmentation feature of the
36834 ++ CPU and has a very small performance impact, however applications
36835 ++ will be limited to a 1.5 GB address space instead of the normal
36836 ++ 3 GB.
36837 ++
36838 ++config PAX_EMUTRAMP
36839 ++ bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86)
36840 ++ default y if PARISC || PPC32
36841 ++ help
36842 ++ There are some programs and libraries that for one reason or
36843 ++ another attempt to execute special small code snippets from
36844 ++ non-executable memory pages. Most notable examples are the
36845 ++ signal handler return code generated by the kernel itself and
36846 ++ the GCC trampolines.
36847 ++
36848 ++ If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
36849 ++ such programs will no longer work under your kernel.
36850 ++
36851 ++ As a remedy you can say Y here and use the 'chpax' or 'paxctl'
36852 ++ utilities to enable trampoline emulation for the affected programs
36853 ++ yet still have the protection provided by the non-executable pages.
36854 ++
36855 ++ On parisc and ppc you MUST enable this option and EMUSIGRT as
36856 ++ well, otherwise your system will not even boot.
36857 ++
36858 ++ Alternatively you can say N here and use the 'chpax' or 'paxctl'
36859 ++ utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
36860 ++ for the affected files.
36861 ++
36862 ++ NOTE: enabling this feature *may* open up a loophole in the
36863 ++ protection provided by non-executable pages that an attacker
36864 ++ could abuse. Therefore the best solution is to not have any
36865 ++ files on your system that would require this option. This can
36866 ++ be achieved by not using libc5 (which relies on the kernel
36867 ++ signal handler return code) and not using or rewriting programs
36868 ++ that make use of the nested function implementation of GCC.
36869 ++ Skilled users can just fix GCC itself so that it implements
36870 ++ nested function calls in a way that does not interfere with PaX.
36871 ++
36872 ++config PAX_EMUSIGRT
36873 ++ bool "Automatically emulate sigreturn trampolines"
36874 ++ depends on PAX_EMUTRAMP && (PARISC || PPC32)
36875 ++ default y
36876 ++ help
36877 ++ Enabling this option will have the kernel automatically detect
36878 ++ and emulate signal return trampolines executing on the stack
36879 ++ that would otherwise lead to task termination.
36880 ++
36881 ++ This solution is intended as a temporary one for users with
36882 ++ legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
36883 ++ Modula-3 runtime, etc) or executables linked to such, basically
36884 ++ everything that does not specify its own SA_RESTORER function in
36885 ++ normal executable memory like glibc 2.1+ does.
36886 ++
36887 ++ On parisc and ppc you MUST enable this option, otherwise your
36888 ++ system will not even boot.
36889 ++
36890 ++ NOTE: this feature cannot be disabled on a per executable basis
36891 ++ and since it *does* open up a loophole in the protection provided
36892 ++ by non-executable pages, the best solution is to not have any
36893 ++ files on your system that would require this option.
36894 ++
36895 ++config PAX_MPROTECT
36896 ++ bool "Restrict mprotect()"
36897 ++ depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
36898 ++ help
36899 ++ Enabling this option will prevent programs from
36900 ++ - changing the executable status of memory pages that were
36901 ++ not originally created as executable,
36902 ++ - making read-only executable pages writable again,
36903 ++ - creating executable pages from anonymous memory.
36904 ++
36905 ++ You should say Y here to complete the protection provided by
36906 ++ the enforcement of non-executable pages.
36907 ++
36908 ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
36909 ++ this feature on a per file basis.
36910 ++
36911 ++config PAX_NOELFRELOCS
36912 ++ bool "Disallow ELF text relocations"
36913 ++ depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86)
36914 ++ help
36915 ++ Non-executable pages and mprotect() restrictions are effective
36916 ++ in preventing the introduction of new executable code into an
36917 ++ attacked task's address space. There remain only two venues
36918 ++ for this kind of attack: if the attacker can execute already
36919 ++ existing code in the attacked task then he can either have it
36920 ++ create and mmap() a file containing his code or have it mmap()
36921 ++ an already existing ELF library that does not have position
36922 ++ independent code in it and use mprotect() on it to make it
36923 ++ writable and copy his code there. While protecting against
36924 ++ the former approach is beyond PaX, the latter can be prevented
36925 ++ by having only PIC ELF libraries on one's system (which do not
36926 ++ need to relocate their code). If you are sure this is your case,
36927 ++ then enable this option otherwise be careful as you may not even
36928 ++ be able to boot or log on your system (for example, some PAM
36929 ++ modules are erroneously compiled as non-PIC by default).
36930 ++
36931 ++ NOTE: if you are using dynamic ELF executables (as suggested
36932 ++ when using ASLR) then you must have made sure that you linked
36933 ++ your files using the PIC version of crt1 (the et_dyn.tar.gz package
36934 ++ referenced there has already been updated to support this).
36935 ++
36936 ++config PAX_ETEXECRELOCS
36937 ++ bool "Allow ELF ET_EXEC text relocations"
36938 ++ depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
36939 ++ default y
36940 ++ help
36941 ++ On some architectures there are incorrectly created applications
36942 ++ that require text relocations and would not work without enabling
36943 ++ this option. If you are an alpha, ia64 or parisc user, you should
36944 ++ enable this option and disable it once you have made sure that
36945 ++ none of your applications need it.
36946 ++
36947 ++config PAX_EMUPLT
36948 ++ bool "Automatically emulate ELF PLT"
36949 ++ depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
36950 ++ default y
36951 ++ help
36952 ++ Enabling this option will have the kernel automatically detect
36953 ++ and emulate the Procedure Linkage Table entries in ELF files.
36954 ++ On some architectures such entries are in writable memory, and
36955 ++ become non-executable leading to task termination. Therefore
36956 ++ it is mandatory that you enable this option on alpha, parisc,
36957 ++ ppc (if secure-plt is not used throughout in userland), sparc
36958 ++ and sparc64, otherwise your system would not even boot.
36959 ++
36960 ++ NOTE: this feature *does* open up a loophole in the protection
36961 ++ provided by the non-executable pages, therefore the proper
36962 ++ solution is to modify the toolchain to produce a PLT that does
36963 ++ not need to be writable.
36964 ++
36965 ++config PAX_DLRESOLVE
36966 ++ bool
36967 ++ depends on PAX_EMUPLT && (SPARC32 || SPARC64)
36968 ++ default y
36969 ++
36970 ++config PAX_SYSCALL
36971 ++ bool
36972 ++ depends on PAX_PAGEEXEC && PPC32
36973 ++ default y
36974 ++
36975 ++config PAX_KERNEXEC
36976 ++ bool "Enforce non-executable kernel pages"
36977 ++ depends on PAX_NOEXEC && X86 && !EFI && !COMPAT_VDSO && (!X86_32 || X86_WP_WORKS_OK) && !PARAVIRT
36978 ++ help
36979 ++ This is the kernel land equivalent of PAGEEXEC and MPROTECT,
36980 ++ that is, enabling this option will make it harder to inject
36981 ++ and execute 'foreign' code in kernel memory itself.
36982 ++
36983 ++endmenu
36984 ++
36985 ++menu "Address Space Layout Randomization"
36986 ++ depends on PAX
36987 ++
36988 ++config PAX_ASLR
36989 ++ bool "Address Space Layout Randomization"
36990 ++ depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
36991 ++ help
36992 ++ Many if not most exploit techniques rely on the knowledge of
36993 ++ certain addresses in the attacked program. The following options
36994 ++ will allow the kernel to apply a certain amount of randomization
36995 ++ to specific parts of the program thereby forcing an attacker to
36996 ++ guess them in most cases. Any failed guess will most likely crash
36997 ++ the attacked program which allows the kernel to detect such attempts
36998 ++ and react on them. PaX itself provides no reaction mechanisms,
36999 ++ instead it is strongly encouraged that you make use of Nergal's
37000 ++ segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
37001 ++ (http://www.grsecurity.net/) built-in crash detection features or
37002 ++ develop one yourself.
37003 ++
37004 ++ By saying Y here you can choose to randomize the following areas:
37005 ++ - top of the task's kernel stack
37006 ++ - top of the task's userland stack
37007 ++ - base address for mmap() requests that do not specify one
37008 ++ (this includes all libraries)
37009 ++ - base address of the main executable
37010 ++
37011 ++ It is strongly recommended to say Y here as address space layout
37012 ++ randomization has negligible impact on performance yet it provides
37013 ++ a very effective protection.
37014 ++
37015 ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
37016 ++ this feature on a per file basis.
37017 ++
37018 ++config PAX_RANDKSTACK
37019 ++ bool "Randomize kernel stack base"
37020 ++ depends on PAX_ASLR && X86_TSC && X86_32
37021 ++ help
37022 ++ By saying Y here the kernel will randomize every task's kernel
37023 ++ stack on every system call. This will not only force an attacker
37024 ++ to guess it but also prevent him from making use of possible
37025 ++ leaked information about it.
37026 ++
37027 ++ Since the kernel stack is a rather scarce resource, randomization
37028 ++ may cause unexpected stack overflows, therefore you should very
37029 ++ carefully test your system. Note that once enabled in the kernel
37030 ++ configuration, this feature cannot be disabled on a per file basis.
37031 ++
37032 ++config PAX_RANDUSTACK
37033 ++ bool "Randomize user stack base"
37034 ++ depends on PAX_ASLR
37035 ++ help
37036 ++ By saying Y here the kernel will randomize every task's userland
37037 ++ stack. The randomization is done in two steps where the second
37038 ++ one may apply a big amount of shift to the top of the stack and
37039 ++ cause problems for programs that want to use lots of memory (more
37040 ++ than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
37041 ++ For this reason the second step can be controlled by 'chpax' or
37042 ++ 'paxctl' on a per file basis.
37043 ++
37044 ++config PAX_RANDMMAP
37045 ++ bool "Randomize mmap() base"
37046 ++ depends on PAX_ASLR
37047 ++ help
37048 ++ By saying Y here the kernel will use a randomized base address for
37049 ++ mmap() requests that do not specify one themselves. As a result
37050 ++ all dynamically loaded libraries will appear at random addresses
37051 ++ and therefore be harder to exploit by a technique where an attacker
37052 ++ attempts to execute library code for his purposes (e.g. spawn a
37053 ++ shell from an exploited program that is running at an elevated
37054 ++ privilege level).
37055 ++
37056 ++ Furthermore, if a program is relinked as a dynamic ELF file, its
37057 ++ base address will be randomized as well, completing the full
37058 ++ randomization of the address space layout. Attacking such programs
37059 ++ becomes a guess game. You can find an example of doing this at
37060 ++ http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
37061 ++ http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
37062 ++
37063 ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
37064 ++ feature on a per file basis.
37065 ++
37066 ++endmenu
37067 ++
37068 ++menu "Miscellaneous hardening features"
37069 ++
37070 ++config PAX_MEMORY_SANITIZE
37071 ++ bool "Sanitize all freed memory"
37072 ++ help
37073 ++ By saying Y here the kernel will erase memory pages as soon as they
37074 ++ are freed. This in turn reduces the lifetime of data stored in the
37075 ++ pages, making it less likely that sensitive information such as
37076 ++ passwords, cryptographic secrets, etc stay in memory for too long.
37077 ++
37078 ++ This is especially useful for programs whose runtime is short, long
37079 ++ lived processes and the kernel itself benefit from this as long as
37080 ++ they operate on whole memory pages and ensure timely freeing of pages
37081 ++ that may hold sensitive information.
37082 ++
37083 ++ The tradeoff is performance impact, on a single CPU system kernel
37084 ++ compilation sees a 3% slowdown, other systems and workloads may vary
37085 ++ and you are advised to test this feature on your expected workload
37086 ++ before deploying it.
37087 ++
37088 ++ Note that this feature does not protect data stored in live pages,
37089 ++ e.g., process memory swapped to disk may stay there for a long time.
37090 ++
37091 ++config PAX_MEMORY_UDEREF
37092 ++ bool "Prevent invalid userland pointer dereference"
37093 ++ depends on X86_32 && !COMPAT_VDSO && !UML_X86
37094 ++ help
37095 ++ By saying Y here the kernel will be prevented from dereferencing
37096 ++ userland pointers in contexts where the kernel expects only kernel
37097 ++ pointers. This is both a useful runtime debugging feature and a
37098 ++ security measure that prevents exploiting a class of kernel bugs.
37099 ++
37100 ++ The tradeoff is that some virtualization solutions may experience
37101 ++ a huge slowdown and therefore you should not enable this feature
37102 ++ for kernels meant to run in such environments. Whether a given VM
37103 ++ solution is affected or not is best determined by simply trying it
37104 ++ out, the performance impact will be obvious right on boot as this
37105 ++ mechanism engages from very early on. A good rule of thumb is that
37106 ++ VMs running on CPUs without hardware virtualization support (i.e.,
37107 ++ the majority of IA-32 CPUs) will likely experience the slowdown.
37108 ++
37109 ++config PAX_REFCOUNT
37110 ++ bool "Prevent various kernel object reference counter overflows"
37111 ++ depends on X86
37112 ++ help
37113 ++ By saying Y here the kernel will detect and prevent overflowing
37114 ++ various (but not all) kinds of object reference counters. Such
37115 ++ overflows can normally occur due to bugs only and are often, if
37116 ++ not always, exploitable.
37117 ++
37118 ++ The tradeoff is that data structures protected by an overflowed
37119 ++ refcount will never be freed and therefore will leak memory. Note
37120 ++ that this leak also happens even without this protection but in
37121 ++ that case the overflow can eventually trigger the freeing of the
37122 ++ data structure while it is still being used elsewhere, resulting
37123 ++ in the exploitable situation that this feature prevents.
37124 ++
37125 ++ Since this has a negligible performance impact, you should enable
37126 ++ this feature.
37127 ++endmenu
37128 ++
37129 ++endmenu
37130 ++
37131 + config KEYS
37132 + bool "Enable access key retention support"
37133 + help
37134 +diff -urNp linux-2.6.28.8/sound/core/oss/pcm_oss.c linux-2.6.28.8/sound/core/oss/pcm_oss.c
37135 +--- linux-2.6.28.8/sound/core/oss/pcm_oss.c 2009-02-06 16:47:45.000000000 -0500
37136 ++++ linux-2.6.28.8/sound/core/oss/pcm_oss.c 2009-02-21 09:37:50.000000000 -0500
37137 +@@ -2929,8 +2929,8 @@ static void snd_pcm_oss_proc_done(struct
37138 + }
37139 + }
37140 + #else /* !CONFIG_SND_VERBOSE_PROCFS */
37141 +-#define snd_pcm_oss_proc_init(pcm)
37142 +-#define snd_pcm_oss_proc_done(pcm)
37143 ++#define snd_pcm_oss_proc_init(pcm) do {} while (0)
37144 ++#define snd_pcm_oss_proc_done(pcm) do {} while (0)
37145 + #endif /* CONFIG_SND_VERBOSE_PROCFS */
37146 +
37147 + /*
37148 +diff -urNp linux-2.6.28.8/sound/core/seq/seq_lock.h linux-2.6.28.8/sound/core/seq/seq_lock.h
37149 +--- linux-2.6.28.8/sound/core/seq/seq_lock.h 2009-02-06 16:47:45.000000000 -0500
37150 ++++ linux-2.6.28.8/sound/core/seq/seq_lock.h 2009-02-21 09:37:50.000000000 -0500
37151 +@@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo
37152 + #else /* SMP || CONFIG_SND_DEBUG */
37153 +
37154 + typedef spinlock_t snd_use_lock_t; /* dummy */
37155 +-#define snd_use_lock_init(lockp) /**/
37156 +-#define snd_use_lock_use(lockp) /**/
37157 +-#define snd_use_lock_free(lockp) /**/
37158 +-#define snd_use_lock_sync(lockp) /**/
37159 ++#define snd_use_lock_init(lockp) do {} while (0)
37160 ++#define snd_use_lock_use(lockp) do {} while (0)
37161 ++#define snd_use_lock_free(lockp) do {} while (0)
37162 ++#define snd_use_lock_sync(lockp) do {} while (0)
37163 +
37164 + #endif /* SMP || CONFIG_SND_DEBUG */
37165 +
37166 +diff -urNp linux-2.6.28.8/sound/pci/ac97/ac97_patch.c linux-2.6.28.8/sound/pci/ac97/ac97_patch.c
37167 +--- linux-2.6.28.8/sound/pci/ac97/ac97_patch.c 2009-02-06 16:47:45.000000000 -0500
37168 ++++ linux-2.6.28.8/sound/pci/ac97/ac97_patch.c 2009-02-21 09:37:50.000000000 -0500
37169 +@@ -1498,7 +1498,7 @@ static const struct snd_ac97_res_table a
37170 + { AC97_VIDEO, 0x9f1f },
37171 + { AC97_AUX, 0x9f1f },
37172 + { AC97_PCM, 0x9f1f },
37173 +- { } /* terminator */
37174 ++ { 0, 0 } /* terminator */
37175 + };
37176 +
37177 + static int patch_ad1819(struct snd_ac97 * ac97)
37178 +@@ -3870,7 +3870,7 @@ static struct snd_ac97_res_table lm4550_
37179 + { AC97_AUX, 0x1f1f },
37180 + { AC97_PCM, 0x1f1f },
37181 + { AC97_REC_GAIN, 0x0f0f },
37182 +- { } /* terminator */
37183 ++ { 0, 0 } /* terminator */
37184 + };
37185 +
37186 + static int patch_lm4550(struct snd_ac97 *ac97)
37187 +diff -urNp linux-2.6.28.8/sound/pci/ens1370.c linux-2.6.28.8/sound/pci/ens1370.c
37188 +--- linux-2.6.28.8/sound/pci/ens1370.c 2009-02-06 16:47:45.000000000 -0500
37189 ++++ linux-2.6.28.8/sound/pci/ens1370.c 2009-02-21 09:37:50.000000000 -0500
37190 +@@ -452,7 +452,7 @@ static struct pci_device_id snd_audiopci
37191 + { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1373 - CT5880 */
37192 + { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ectiva EV1938 */
37193 + #endif
37194 +- { 0, }
37195 ++ { 0, 0, 0, 0, 0, 0, 0 }
37196 + };
37197 +
37198 + MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
37199 +diff -urNp linux-2.6.28.8/sound/pci/intel8x0.c linux-2.6.28.8/sound/pci/intel8x0.c
37200 +--- linux-2.6.28.8/sound/pci/intel8x0.c 2009-02-06 16:47:45.000000000 -0500
37201 ++++ linux-2.6.28.8/sound/pci/intel8x0.c 2009-02-21 09:37:50.000000000 -0500
37202 +@@ -443,7 +443,7 @@ static struct pci_device_id snd_intel8x0
37203 + { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
37204 + { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
37205 + { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
37206 +- { 0, }
37207 ++ { 0, 0, 0, 0, 0, 0, 0 }
37208 + };
37209 +
37210 + MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
37211 +@@ -2088,7 +2088,7 @@ static struct ac97_quirk ac97_quirks[] _
37212 + .type = AC97_TUNE_HP_ONLY
37213 + },
37214 + #endif
37215 +- { } /* terminator */
37216 ++ { 0, 0, 0, 0, NULL, 0 } /* terminator */
37217 + };
37218 +
37219 + static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
37220 +diff -urNp linux-2.6.28.8/sound/pci/intel8x0m.c linux-2.6.28.8/sound/pci/intel8x0m.c
37221 +--- linux-2.6.28.8/sound/pci/intel8x0m.c 2009-02-06 16:47:45.000000000 -0500
37222 ++++ linux-2.6.28.8/sound/pci/intel8x0m.c 2009-02-21 09:37:50.000000000 -0500
37223 +@@ -239,7 +239,7 @@ static struct pci_device_id snd_intel8x0
37224 + { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
37225 + { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
37226 + #endif
37227 +- { 0, }
37228 ++ { 0, 0, 0, 0, 0, 0, 0 }
37229 + };
37230 +
37231 + MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
37232 +@@ -1258,7 +1258,7 @@ static struct shortname_table {
37233 + { 0x5455, "ALi M5455" },
37234 + { 0x746d, "AMD AMD8111" },
37235 + #endif
37236 +- { 0 },
37237 ++ { 0, NULL },
37238 + };
37239 +
37240 + static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
37241 +diff -urNp linux-2.6.28.8/virt/kvm/kvm_main.c linux-2.6.28.8/virt/kvm/kvm_main.c
37242 +--- linux-2.6.28.8/virt/kvm/kvm_main.c 2009-02-06 16:47:45.000000000 -0500
37243 ++++ linux-2.6.28.8/virt/kvm/kvm_main.c 2009-02-21 09:37:50.000000000 -0500
37244 +@@ -1765,6 +1765,9 @@ static struct miscdevice kvm_dev = {
37245 + KVM_MINOR,
37246 + "kvm",
37247 + &kvm_chardev_ops,
37248 ++ {NULL, NULL},
37249 ++ NULL,
37250 ++ NULL
37251 + };
37252 +
37253 + static void hardware_enable(void *junk)
37254 +@@ -1996,7 +1999,7 @@ static void kvm_sched_out(struct preempt
37255 + kvm_arch_vcpu_put(vcpu);
37256 + }
37257 +
37258 +-int kvm_init(void *opaque, unsigned int vcpu_size,
37259 ++int kvm_init(const void *opaque, unsigned int vcpu_size,
37260 + struct module *module)
37261 + {
37262 + int r;
37263
37264 Added: hardened/2.6/tags/2.6.28-7/4421_grsec-remove-localversion-grsec.patch
37265 ===================================================================
37266 --- hardened/2.6/tags/2.6.28-7/4421_grsec-remove-localversion-grsec.patch (rev 0)
37267 +++ hardened/2.6/tags/2.6.28-7/4421_grsec-remove-localversion-grsec.patch 2009-03-21 10:58:14 UTC (rev 1529)
37268 @@ -0,0 +1,9 @@
37269 +From: Kerin Millar <kerframil@×××××.com>
37270 +
37271 +Remove grsecurity's localversion-grsec file as it is inconsistent with
37272 +Gentoo's kernel practices and naming scheme.
37273 +
37274 +--- a/localversion-grsec 2008-02-24 14:26:59.000000000 +0000
37275 ++++ b/localversion-grsec 1970-01-01 01:00:00.000000000 +0100
37276 +@@ -1 +0,0 @@
37277 +--grsec
37278
37279 Added: hardened/2.6/tags/2.6.28-7/4422_grsec-mute-warnings.patch
37280 ===================================================================
37281 --- hardened/2.6/tags/2.6.28-7/4422_grsec-mute-warnings.patch (rev 0)
37282 +++ hardened/2.6/tags/2.6.28-7/4422_grsec-mute-warnings.patch 2009-03-21 10:58:14 UTC (rev 1529)
37283 @@ -0,0 +1,28 @@
37284 +From: Gordon Malm <gengor@g.o>
37285 +
37286 +Updated patch for kernel series 2.6.24.
37287 +
37288 +The credits/description from the original version of this patch remain accurate
37289 +and are included below.
37290 +
37291 +---
37292 +From: Alexander Gabert <gaberta@××××××××.de>
37293 +
37294 +This patch removes the warnings introduced by grsec patch 2.1.9 and later.
37295 +It removes the -W options added by the patch and restores the original
37296 +warning flags of vanilla kernel versions.
37297 +
37298 +Acked-by: Christian Heim <phreak@g.o>
37299 +---
37300 +
37301 +--- a/Makefile
37302 ++++ b/Makefile
37303 +@@ -214,7 +214,7 @@
37304 +
37305 + HOSTCC = gcc
37306 + HOSTCXX = g++
37307 +-HOSTCFLAGS = -Wall -W -Wno-unused -Wno-sign-compare -Wstrict-prototypes -O2 -fomit-frame-pointer
37308 ++HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
37309 + HOSTCXXFLAGS = -O2
37310 +
37311 + # Decide whether to build built-in, modular, or both.
37312
37313 Added: hardened/2.6/tags/2.6.28-7/4425_grsec-pax-without-grsec.patch
37314 ===================================================================
37315 --- hardened/2.6/tags/2.6.28-7/4425_grsec-pax-without-grsec.patch (rev 0)
37316 +++ hardened/2.6/tags/2.6.28-7/4425_grsec-pax-without-grsec.patch 2009-03-21 10:58:14 UTC (rev 1529)
37317 @@ -0,0 +1,60 @@
37318 +From: Gordon Malm <gengor@g.o>
37319 +
37320 +Allow PaX options to be selected without first selecting CONFIG_GRKERNSEC.
37321 +
37322 +This patch has been updated to keep current with newer kernel versions.
37323 +The original version of this patch contained no credits/description.
37324 +
37325 +--- a/arch/x86/mm/fault.c
37326 ++++ b/arch/x86/mm/fault.c
37327 +@@ -431,10 +431,12 @@ static void show_fault_oops(struct pt_re
37328 + if (init_mm.start_code <= address && address < init_mm.end_code)
37329 + #endif
37330 + {
37331 ++#ifdef CONFIG_GRKERNSEC
37332 + if (current->signal->curr_ip)
37333 + printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
37334 + NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current->uid, current->euid);
37335 + else
37336 ++#endif
37337 + printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
37338 + current->comm, task_pid_nr(current), current->uid, current->euid);
37339 + }
37340 +--- a/fs/exec.c
37341 ++++ b/fs/exec.c
37342 +@@ -1693,9 +1693,11 @@ void pax_report_fault(struct pt_regs *re
37343 + }
37344 + up_read(&mm->mmap_sem);
37345 + }
37346 ++#ifdef CONFIG_GRKERNSEC
37347 + if (tsk->signal->curr_ip)
37348 + 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);
37349 + else
37350 ++#endif
37351 + printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
37352 + printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
37353 + "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
37354 +@@ -1710,10 +1712,12 @@ void pax_report_fault(struct pt_regs *re
37355 + #ifdef CONFIG_PAX_REFCOUNT
37356 + void pax_report_refcount_overflow(struct pt_regs *regs)
37357 + {
37358 ++#ifdef CONFIG_GRKERNSEC
37359 + if (current->signal->curr_ip)
37360 + printk(KERN_ERR "PAX: From %u.%u.%u.%u: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n",
37361 + NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current->uid, current->euid);
37362 + else
37363 ++#endif
37364 + printk(KERN_ERR "PAX: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n",
37365 + current->comm, task_pid_nr(current), current->uid, current->euid);
37366 + print_symbol(KERN_ERR "PAX: refcount overflow occured at: %s\n", instruction_pointer(regs));
37367 +--- a/security/Kconfig
37368 ++++ b/security/Kconfig
37369 +@@ -10,7 +10,7 @@ menu "PaX"
37370 +
37371 + config PAX
37372 + bool "Enable various PaX features"
37373 +- depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86)
37374 ++ depends on (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86)
37375 + help
37376 + This allows you to enable various PaX features. PaX adds
37377 + intrusion prevention mechanisms to the kernel that reduce
37378
37379 Added: hardened/2.6/tags/2.6.28-7/4430_grsec-kconfig-default-gids.patch
37380 ===================================================================
37381 --- hardened/2.6/tags/2.6.28-7/4430_grsec-kconfig-default-gids.patch (rev 0)
37382 +++ hardened/2.6/tags/2.6.28-7/4430_grsec-kconfig-default-gids.patch 2009-03-21 10:58:14 UTC (rev 1529)
37383 @@ -0,0 +1,76 @@
37384 +From: Kerin Millar <kerframil@×××××.com>
37385 +
37386 +grsecurity contains a number of options which allow certain protections
37387 +to be applied to or exempted from members of a given group. However, the
37388 +default GIDs specified in the upstream patch are entirely arbitrary and
37389 +there is no telling which (if any) groups the GIDs will correlate with
37390 +on an end-user's system. Because some users don't pay a great deal of
37391 +attention to the finer points of kernel configuration, it is probably
37392 +wise to specify some reasonable defaults so as to stop careless users
37393 +from shooting themselves in the foot.
37394 +
37395 +--- a/grsecurity/Kconfig
37396 ++++ b/grsecurity/Kconfig
37397 +@@ -352,7 +564,7 @@
37398 + config GRKERNSEC_PROC_GID
37399 + int "GID for special group"
37400 + depends on GRKERNSEC_PROC_USERGROUP
37401 +- default 1001
37402 ++ default 10
37403 +
37404 + config GRKERNSEC_PROC_ADD
37405 + bool "Additional restrictions"
37406 +@@ -547,7 +759,7 @@
37407 + config GRKERNSEC_AUDIT_GID
37408 + int "GID for auditing"
37409 + depends on GRKERNSEC_AUDIT_GROUP
37410 +- default 1007
37411 ++ default 100
37412 +
37413 + config GRKERNSEC_EXECLOG
37414 + bool "Exec logging"
37415 +@@ -700,7 +912,7 @@
37416 + config GRKERNSEC_TPE_GID
37417 + int "GID for untrusted users"
37418 + depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
37419 +- default 1005
37420 ++ default 100
37421 + help
37422 + If you have selected the "Invert GID option" above, setting this
37423 + GID determines what group TPE restrictions will be *disabled* for.
37424 +@@ -712,7 +924,7 @@
37425 + config GRKERNSEC_TPE_GID
37426 + int "GID for trusted users"
37427 + depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
37428 +- default 1005
37429 ++ default 10
37430 + help
37431 + If you have selected the "Invert GID option" above, setting this
37432 + GID determines what group TPE restrictions will be *disabled* for.
37433 +@@ -754,7 +966,7 @@
37434 + config GRKERNSEC_SOCKET_ALL_GID
37435 + int "GID to deny all sockets for"
37436 + depends on GRKERNSEC_SOCKET_ALL
37437 +- default 1004
37438 ++ default 65534
37439 + help
37440 + Here you can choose the GID to disable socket access for. Remember to
37441 + add the users you want socket access disabled for to the GID
37442 +@@ -775,7 +987,7 @@
37443 + config GRKERNSEC_SOCKET_CLIENT_GID
37444 + int "GID to deny client sockets for"
37445 + depends on GRKERNSEC_SOCKET_CLIENT
37446 +- default 1003
37447 ++ default 65534
37448 + help
37449 + Here you can choose the GID to disable client socket access for.
37450 + Remember to add the users you want client socket access disabled for to
37451 +@@ -793,7 +1005,7 @@
37452 + config GRKERNSEC_SOCKET_SERVER_GID
37453 + int "GID to deny server sockets for"
37454 + depends on GRKERNSEC_SOCKET_SERVER
37455 +- default 1002
37456 ++ default 65534
37457 + help
37458 + Here you can choose the GID to disable server socket access for.
37459 + Remember to add the users you want server socket access disabled for to
37460
37461 Added: hardened/2.6/tags/2.6.28-7/4435_grsec-kconfig-gentoo.patch
37462 ===================================================================
37463 --- hardened/2.6/tags/2.6.28-7/4435_grsec-kconfig-gentoo.patch (rev 0)
37464 +++ hardened/2.6/tags/2.6.28-7/4435_grsec-kconfig-gentoo.patch 2009-03-21 10:58:14 UTC (rev 1529)
37465 @@ -0,0 +1,243 @@
37466 +From: Gordon Malm <gengor@g.o>
37467 +From: Kerin Millar <kerframil@×××××.com>
37468 +
37469 +Add Hardened Gentoo [server/workstation] predefined grsecurity
37470 +levels. They're designed to provide a comparitively high level of
37471 +security while remaining generally suitable for as great a majority
37472 +of the userbase as possible (particularly new users).
37473 +
37474 +Make Hardened Gentoo [workstation] predefined grsecurity level the
37475 +default. The Hardened Gentoo [server] level is more restrictive
37476 +and conflicts with some software and thus would be less suitable.
37477 +
37478 +The original version of this patch was conceived and created by:
37479 +Ned Ludd <solar@g.o>
37480 +
37481 +--- a/grsecurity/Kconfig
37482 ++++ b/grsecurity/Kconfig
37483 +@@ -20,7 +20,7 @@ config GRKERNSEC
37484 + choice
37485 + prompt "Security Level"
37486 + depends on GRKERNSEC
37487 +- default GRKERNSEC_CUSTOM
37488 ++ default GRKERNSEC_HARDENED_WORKSTATION
37489 +
37490 + config GRKERNSEC_LOW
37491 + bool "Low"
37492 +@@ -183,6 +183,216 @@ config GRKERNSEC_HIGH
37493 + - Mount/unmount/remount logging
37494 + - Kernel symbol hiding
37495 + - Prevention of memory exhaustion-based exploits
37496 ++
37497 ++config GRKERNSEC_HARDENED_SERVER
37498 ++ bool "Hardened Gentoo [server]"
37499 ++ select GRKERNSEC_AUDIT_MOUNT
37500 ++ select GRKERNSEC_BRUTE
37501 ++ select GRKERNSEC_CHROOT
37502 ++ select GRKERNSEC_CHROOT_CAPS
37503 ++ select GRKERNSEC_CHROOT_CHDIR
37504 ++ select GRKERNSEC_CHROOT_CHMOD
37505 ++ select GRKERNSEC_CHROOT_DOUBLE
37506 ++ select GRKERNSEC_CHROOT_FCHDIR
37507 ++ select GRKERNSEC_CHROOT_FINDTASK
37508 ++ select GRKERNSEC_CHROOT_MKNOD
37509 ++ select GRKERNSEC_CHROOT_MOUNT
37510 ++ select GRKERNSEC_CHROOT_NICE
37511 ++ select GRKERNSEC_CHROOT_PIVOT
37512 ++ select GRKERNSEC_CHROOT_SHMAT
37513 ++ select GRKERNSEC_CHROOT_SYSCTL
37514 ++ select GRKERNSEC_CHROOT_UNIX
37515 ++ select GRKERNSEC_DMESG
37516 ++ select GRKERNSEC_EXECVE
37517 ++ select GRKERNSEC_FIFO
37518 ++ select GRKERNSEC_FORKFAIL
37519 ++ select GRKERNSEC_HIDESYM
37520 ++ select GRKERNSEC_IO if (X86)
37521 ++ select GRKERNSEC_KMEM
37522 ++ select GRKERNSEC_LINK
37523 ++ select GRKERNSEC_MODSTOP if (MODULES)
37524 ++ select GRKERNSEC_PROC
37525 ++ select GRKERNSEC_PROC_ADD
37526 ++ select GRKERNSEC_PROC_IPADDR
37527 ++ select GRKERNSEC_PROC_MEMMAP
37528 ++ select GRKERNSEC_PROC_USERGROUP
37529 ++ select GRKERNSEC_RANDNET
37530 ++ select GRKERNSEC_RESLOG
37531 ++ select GRKERNSEC_SIGNAL
37532 ++# select GRKERNSEC_SOCKET
37533 ++# select GRKERNSEC_SOCKET_SERVER
37534 ++ select GRKERNSEC_SYSCTL
37535 ++ select GRKERNSEC_SYSCTL_ON
37536 ++ select GRKERNSEC_TIME
37537 ++ select PAX
37538 ++ select PAX_ASLR
37539 ++ select PAX_DLRESOLVE if (SPARC32 || SPARC64)
37540 ++ select PAX_EI_PAX
37541 ++ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
37542 ++ select PAX_EMUSIGRT if (PARISC || PPC32)
37543 ++ select PAX_EMUTRAMP if (PARISC || PPC32)
37544 ++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
37545 ++ select PAX_KERNEXEC if (X86 && !EFI && !COMPAT_VDSO && !PARAVIRT && (!X86_32 || X86_WP_WORKS_OK))
37546 ++ select PAX_MEMORY_SANITIZE
37547 ++ select PAX_MEMORY_UDEREF if (X86_32 && !COMPAT_VDSO && !UML_X86)
37548 ++ select PAX_MPROTECT if (!PPC64)
37549 ++ select PAX_HAVE_ACL_FLAGS
37550 ++ select PAX_NOELFRELOCS if (X86)
37551 ++ select PAX_NOEXEC
37552 ++ select PAX_PAGEEXEC
37553 ++ select PAX_PT_PAX_FLAGS
37554 ++ select PAX_RANDKSTACK if (X86_32 && X86_TSC)
37555 ++ select PAX_RANDMMAP
37556 ++ select PAX_RANDUSTACK
37557 ++ select PAX_REFCOUNT if (X86)
37558 ++ select PAX_SEGMEXEC if (X86_32)
37559 ++ select PAX_SYSCALL if (PPC32)
37560 ++ help
37561 ++ If you say Y here, a configuration will be used that is endorsed by
37562 ++ the Hardened Gentoo project. Therefore, many of the protections
37563 ++ made available by grsecurity and PaX will be enabled.
37564 ++
37565 ++ Hardened Gentoo's pre-defined security levels are designed to provide
37566 ++ a high level of security while minimizing incompatibilities with the
37567 ++ majority of available software. For further information, please
37568 ++ view <http://www.grsecurity.net> and <http://pax.grsecurity.net> as
37569 ++ well as the Hardened Gentoo Primer at
37570 ++ <http://www.gentoo.org/proj/en/hardened/primer.xml>.
37571 ++
37572 ++ This Hardened Gentoo [server] level is identical to the
37573 ++ Hardened Gentoo [workstation] level, but with the GRKERNSEC_IO,
37574 ++ PAX_KERNEXEC and PAX_NOELFRELOCS security features enabled.
37575 ++ Accordingly, this is the preferred security level if the system will
37576 ++ not be utilizing software incompatible with the aforementioned
37577 ++ grsecurity/PaX features.
37578 ++
37579 ++ You may wish to emerge paxctl, a utility which allows you to toggle
37580 ++ PaX features on problematic binaries on an individual basis. Note that
37581 ++ this only works for ELF binaries that contain a PT_PAX_FLAGS header.
37582 ++ Translated, this means that if you wish to toggle PaX features on
37583 ++ binaries provided by applications that are distributed only in binary
37584 ++ format (rather than being built locally from sources), you will need to
37585 ++ run paxctl -C on the binaries beforehand so as to inject the missing
37586 ++ headers.
37587 ++
37588 ++ When this level is selected, some options cannot be changed. However,
37589 ++ you may opt to fully customize the options that are selected by
37590 ++ choosing "Custom" in the Security Level menu. You may find it helpful
37591 ++ to inherit the options selected by the "Hardened Gentoo [server]"
37592 ++ security level as a starting point for further configuration. To
37593 ++ accomplish this, select this security level then exit the menuconfig
37594 ++ interface, saving changes when prompted. Then, run make menuconfig
37595 ++ again and select the "Custom" level.
37596 ++
37597 ++ Note that this security level probably should not be used if the
37598 ++ target system is a 32bit x86 virtualized guest. If you intend to run
37599 ++ the kernel in a 32bit x86 virtualized guest you will likely need to
37600 ++ disable the PAX_MEMORY_UDEREF option in order to avoid an unacceptable
37601 ++ impact on performance.
37602 ++
37603 ++config GRKERNSEC_HARDENED_WORKSTATION
37604 ++ bool "Hardened Gentoo [workstation]"
37605 ++ select GRKERNSEC_AUDIT_MOUNT
37606 ++ select GRKERNSEC_BRUTE
37607 ++ select GRKERNSEC_CHROOT
37608 ++ select GRKERNSEC_CHROOT_CAPS
37609 ++ select GRKERNSEC_CHROOT_CHDIR
37610 ++ select GRKERNSEC_CHROOT_CHMOD
37611 ++ select GRKERNSEC_CHROOT_DOUBLE
37612 ++ select GRKERNSEC_CHROOT_FCHDIR
37613 ++ select GRKERNSEC_CHROOT_FINDTASK
37614 ++ select GRKERNSEC_CHROOT_MKNOD
37615 ++ select GRKERNSEC_CHROOT_MOUNT
37616 ++ select GRKERNSEC_CHROOT_NICE
37617 ++ select GRKERNSEC_CHROOT_PIVOT
37618 ++ select GRKERNSEC_CHROOT_SHMAT
37619 ++ select GRKERNSEC_CHROOT_SYSCTL
37620 ++ select GRKERNSEC_CHROOT_UNIX
37621 ++ select GRKERNSEC_DMESG
37622 ++ select GRKERNSEC_EXECVE
37623 ++ select GRKERNSEC_FIFO
37624 ++ select GRKERNSEC_FORKFAIL
37625 ++ select GRKERNSEC_HIDESYM
37626 ++ select GRKERNSEC_KMEM
37627 ++ select GRKERNSEC_LINK
37628 ++ select GRKERNSEC_MODSTOP if (MODULES)
37629 ++ select GRKERNSEC_PROC
37630 ++ select GRKERNSEC_PROC_ADD
37631 ++ select GRKERNSEC_PROC_IPADDR
37632 ++ select GRKERNSEC_PROC_MEMMAP
37633 ++ select GRKERNSEC_PROC_USERGROUP
37634 ++ select GRKERNSEC_RANDNET
37635 ++ select GRKERNSEC_RESLOG
37636 ++ select GRKERNSEC_SIGNAL
37637 ++# select GRKERNSEC_SOCKET
37638 ++# select GRKERNSEC_SOCKET_SERVER
37639 ++ select GRKERNSEC_SYSCTL
37640 ++ select GRKERNSEC_SYSCTL_ON
37641 ++ select GRKERNSEC_TIME
37642 ++ select PAX
37643 ++ select PAX_ASLR
37644 ++ select PAX_DLRESOLVE if (SPARC32 || SPARC64)
37645 ++ select PAX_EI_PAX
37646 ++ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
37647 ++ select PAX_EMUSIGRT if (PARISC || PPC32)
37648 ++ select PAX_EMUTRAMP if (PARISC || PPC32)
37649 ++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
37650 ++ select PAX_MEMORY_SANITIZE
37651 ++ select PAX_MEMORY_UDEREF if (X86_32 && !COMPAT_VDSO && !UML_X86)
37652 ++ select PAX_MPROTECT if (!PPC64)
37653 ++ select PAX_HAVE_ACL_FLAGS
37654 ++ select PAX_NOEXEC
37655 ++ select PAX_PAGEEXEC
37656 ++ select PAX_PT_PAX_FLAGS
37657 ++ select PAX_RANDKSTACK if (X86_32 && X86_TSC)
37658 ++ select PAX_RANDMMAP
37659 ++ select PAX_RANDUSTACK
37660 ++ select PAX_REFCOUNT if (X86)
37661 ++ select PAX_SEGMEXEC if (X86_32)
37662 ++ select PAX_SYSCALL if (PPC32)
37663 ++ help
37664 ++ If you say Y here, a configuration will be used that is endorsed by
37665 ++ the Hardened Gentoo project. Therefore, many of the protections
37666 ++ made available by grsecurity and PaX will be enabled.
37667 ++
37668 ++ Hardened Gentoo's pre-defined security levels are designed to provide
37669 ++ a high level of security while minimizing incompatibilities with the
37670 ++ majority of available software. For further information, please
37671 ++ view <http://www.grsecurity.net> and <http://pax.grsecurity.net> as
37672 ++ well as the Hardened Gentoo Primer at
37673 ++ <http://www.gentoo.org/proj/en/hardened/primer.xml>.
37674 ++
37675 ++ This Hardened Gentoo [workstation] level is designed for machines
37676 ++ which are intended to run software not compatible with the
37677 ++ GRKERNSEC_IO, PAX_KERNEXEC and PAX_NOELFRELOCS features of grsecurity.
37678 ++ Accordingly, this security level is suitable for use with the X server
37679 ++ "Xorg" and/or any system that will act as host OS to the virtualization
37680 ++ softwares vmware-server or virtualbox.
37681 ++
37682 ++ You may wish to emerge paxctl, a utility which allows you to toggle
37683 ++ PaX features on problematic binaries on an individual basis. Note that
37684 ++ this only works for ELF binaries that contain a PT_PAX_FLAGS header.
37685 ++ Translated, this means that if you wish to toggle PaX features on
37686 ++ binaries provided by applications that are distributed only in binary
37687 ++ format (rather than being built locally from sources), you will need to
37688 ++ run paxctl -C on the binaries beforehand so as to inject the missing
37689 ++ headers.
37690 ++
37691 ++ When this level is selected, some options cannot be changed. However,
37692 ++ you may opt to fully customize the options that are selected by
37693 ++ choosing "Custom" in the Security Level menu. You may find it helpful
37694 ++ to inherit the options selected by the "Hardened Gentoo [workstation]"
37695 ++ security level as a starting point for further configuration. To
37696 ++ accomplish this, select this security level then exit the menuconfig
37697 ++ interface, saving changes when prompted. Then, run make menuconfig
37698 ++ again and select the "Custom" level.
37699 ++
37700 ++ Note that this security level probably should not be used if the
37701 ++ target system is a 32bit x86 virtualized guest. If you intend to run
37702 ++ the kernel in a 32bit x86 virtualized guest you will likely need to
37703 ++ disable the PAX_MEMORY_UDEREF option in order to avoid an unacceptable
37704 ++ impact on performance.
37705 ++
37706 + config GRKERNSEC_CUSTOM
37707 + bool "Custom"
37708 + help
37709
37710 Added: hardened/2.6/tags/2.6.28-7/4440_selinux-avc_audit-log-curr_ip.patch
37711 ===================================================================
37712 --- hardened/2.6/tags/2.6.28-7/4440_selinux-avc_audit-log-curr_ip.patch (rev 0)
37713 +++ hardened/2.6/tags/2.6.28-7/4440_selinux-avc_audit-log-curr_ip.patch 2009-03-21 10:58:14 UTC (rev 1529)
37714 @@ -0,0 +1,65 @@
37715 +From: Gordon Malm <gengor@g.o>
37716 +
37717 +This is a reworked version of the original
37718 +*_selinux-avc_audit-log-curr_ip.patch carried in earlier releases of
37719 +hardened-sources.
37720 +
37721 +Dropping the patch, or simply fixing the #ifdef of the original patch
37722 +could break automated logging setups so this route was necessary.
37723 +
37724 +Suggestions for improving the help text are welcome.
37725 +
37726 +The original patch's description is still accurate and included below.
37727 +
37728 +---
37729 +Provides support for a new field ipaddr within the SELinux
37730 +AVC audit log, relying in task_struct->curr_ip (ipv4 only)
37731 +provided by grSecurity patch to be applied before.
37732 +
37733 +Signed-off-by: Lorenzo Hernandez Garcia-Hierro <lorenzo@×××.org>
37734 +---
37735 +
37736 +--- a/grsecurity/Kconfig
37737 ++++ b/grsecurity/Kconfig
37738 +@@ -1044,6 +1044,27 @@ endmenu
37739 + menu "Logging Options"
37740 + depends on GRKERNSEC
37741 +
37742 ++config GRKERNSEC_SELINUX_AVC_LOG_IPADDR
37743 ++ def_bool n
37744 ++ prompt "Add source IP address to SELinux AVC log messages"
37745 ++ depends on GRKERNSEC && SECURITY_SELINUX
37746 ++ help
37747 ++ If you say Y here, a new field "ipaddr=" will be added to many SELinux
37748 ++ AVC log messages. The value of this field in any given message
37749 ++ represents the source IP address of the remote machine/user that created
37750 ++ the offending process.
37751 ++
37752 ++ This information is sourced from task_struct->curr_ip provided by
37753 ++ grsecurity's GRKERNSEC top-level configuration option. One limitation
37754 ++ is that only IPv4 is supported.
37755 ++
37756 ++ In many instances SELinux AVC log messages already log a superior level
37757 ++ of information that also includes source port and destination ip/port.
37758 ++ Additionally, SELinux's AVC log code supports IPv6.
37759 ++
37760 ++ However, grsecurity's task_struct->curr_ip will sometimes (often?)
37761 ++ provide the offender's IP address where stock SELinux logging fails to.
37762 ++
37763 + config GRKERNSEC_FLOODTIME
37764 + int "Seconds in between log messages (minimum)"
37765 + default 10
37766 +--- a/security/selinux/avc.c
37767 ++++ b/security/selinux/avc.c
37768 +@@ -202,6 +202,11 @@ static void avc_dump_query(struct audit_
37769 + char *scontext;
37770 + u32 scontext_len;
37771 +
37772 ++#ifdef CONFIG_GRKERNSEC_SELINUX_AVC_LOG_IPADDR
37773 ++ if (current->signal->curr_ip)
37774 ++ audit_log_format(ab, "ipaddr=%u.%u.%u.%u ", NIPQUAD(current->signal->curr_ip));
37775 ++#endif
37776 ++
37777 + rc = security_sid_to_context(ssid, &scontext, &scontext_len);
37778 + if (rc)
37779 + audit_log_format(ab, "ssid=%d", ssid);
37780
37781 Added: hardened/2.6/tags/2.6.28-7/4445_disable-compat_vdso.patch
37782 ===================================================================
37783 --- hardened/2.6/tags/2.6.28-7/4445_disable-compat_vdso.patch (rev 0)
37784 +++ hardened/2.6/tags/2.6.28-7/4445_disable-compat_vdso.patch 2009-03-21 10:58:14 UTC (rev 1529)
37785 @@ -0,0 +1,74 @@
37786 +From: Gordon Malm <gengor@g.o>
37787 +From: Kerin Millar <kerframil@×××××.com>
37788 +
37789 +COMPAT_VDSO is inappropriate for any modern Hardened Gentoo system. It
37790 +conflicts with various parts of PaX, crashing the system if enabled
37791 +while PaX's NOEXEC or UDEREF features are active. Moreover, it prevents
37792 +a number of important PaX options from appearing in the configuration
37793 +menu, including all PaX NOEXEC implementations. Unfortunately, the
37794 +reason for the disappearance of these PaX configuration options is
37795 +often far from obvious to inexperienced users.
37796 +
37797 +Therefore, we disable the COMPAT_VDSO menu entry entirely. However,
37798 +COMPAT_VDSO operation can still be enabled via bootparam and sysctl
37799 +interfaces. Consequently, we must also disable the ability to select
37800 +COMPAT_VDSO operation at boot or runtime. Here we patch the kernel so
37801 +that selecting COMPAT_VDSO operation at boot/runtime has no effect if
37802 +conflicting PaX options are enabled, leaving VDSO_ENABLED operation
37803 +intact.
37804 +
37805 +Closes bug: http://bugs.gentoo.org/show_bug.cgi?id=210138
37806 +
37807 +--- a/arch/x86/Kconfig
37808 ++++ b/arch/x86/Kconfig
37809 +@@ -1215,16 +1215,7 @@ config HOTPLUG_CPU
37810 +
37811 + config COMPAT_VDSO
37812 + def_bool n
37813 +- prompt "Compat VDSO support"
37814 + depends on (X86_32 || IA32_EMULATION) && !PAX_NOEXEC
37815 +- help
37816 +- Map the 32-bit VDSO to the predictable old-style address too.
37817 +- ---help---
37818 +- Say N here if you are running a sufficiently recent glibc
37819 +- version (2.3.3 or later), to remove the high-mapped
37820 +- VDSO mapping and to exclusively use the randomized VDSO.
37821 +-
37822 +- If unsure, say Y.
37823 +
37824 + endmenu
37825 +
37826 +--- a/arch/x86/vdso/vdso32-setup.c
37827 ++++ b/arch/x86/vdso/vdso32-setup.c
37828 +@@ -333,17 +333,21 @@ int arch_setup_additional_pages(struct l
37829 +
37830 + map_compat_vdso(compat);
37831 +
37832 ++#if !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF)
37833 + if (compat)
37834 + addr = VDSO_HIGH_BASE;
37835 + else {
37836 ++#endif
37837 + addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
37838 + if (IS_ERR_VALUE(addr)) {
37839 + ret = addr;
37840 + goto up_fail;
37841 + }
37842 ++#if !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF)
37843 + }
37844 +
37845 + if (compat_uses_vma || !compat) {
37846 ++#endif
37847 + /*
37848 + * MAYWRITE to allow gdb to COW and set breakpoints
37849 + *
37850 +@@ -361,7 +365,9 @@ int arch_setup_additional_pages(struct l
37851 +
37852 + if (ret)
37853 + goto up_fail;
37854 ++#if !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF)
37855 + }
37856 ++#endif
37857 +
37858 + current->mm->context.vdso = addr;
37859 + current_thread_info()->sysenter_return =
37860
37861 Added: hardened/2.6/tags/2.6.28-7/4450_grsec-grkernsec_io-select-rtc-cmos.patch
37862 ===================================================================
37863 --- hardened/2.6/tags/2.6.28-7/4450_grsec-grkernsec_io-select-rtc-cmos.patch (rev 0)
37864 +++ hardened/2.6/tags/2.6.28-7/4450_grsec-grkernsec_io-select-rtc-cmos.patch 2009-03-21 10:58:14 UTC (rev 1529)
37865 @@ -0,0 +1,14 @@
37866 +From: Gordon Malm <gengor@g.o>
37867 +
37868 +Build rtc-cmos driver into the kernel when GRKERNSEC_IO is enabled.
37869 +
37870 +--- a/grsecurity/Kconfig
37871 ++++ b/grsecurity/Kconfig
37872 +@@ -437,6 +437,7 @@ config GRKERNSEC_IO
37873 + depends on X86
37874 + select RTC_CLASS
37875 + select RTC_INTF_DEV
37876 ++ select RTC_DRV_CMOS
37877 + help
37878 + If you say Y here, all ioperm and iopl calls will return an error.
37879 + Ioperm and iopl can be used to modify the running kernel.