Gentoo Archives: gentoo-commits

From: "Christian Heim (phreak)" <phreak@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] hardened r97 - in hardened-sources/2.6/tags: . 2.6.23-7
Date: Wed, 30 Apr 2008 11:49:26
Message-Id: E1JrAi6-0001JE-7V@stork.gentoo.org
1 Author: phreak
2 Date: 2008-04-30 11:42:53 +0000 (Wed, 30 Apr 2008)
3 New Revision: 97
4
5 Added:
6 hardened-sources/2.6/tags/2.6.23-7/
7 hardened-sources/2.6/tags/2.6.23-7/4405_alpha-sysctl-uac-for-hardened-extras.patch
8 hardened-sources/2.6/tags/2.6.23-7/4430_grsec-2.1.11-2.6.23.15-20080210.patch
9 hardened-sources/2.6/tags/2.6.23-7/4435_grsec-2.1.10-mute-warnings.patch
10 hardened-sources/2.6/tags/2.6.23-7/4440_grsec-2.1.10-pax_curr_ip-fixes.patch
11 hardened-sources/2.6/tags/2.6.23-7/4445_grsec-kconfig-gentoo.patch
12 hardened-sources/2.6/tags/2.6.23-7/4450_selinux-avc_audit-log-curr_ip.patch
13 hardened-sources/2.6/tags/2.6.23-7/4455_disable-compat_vdso.patch
14 hardened-sources/2.6/tags/2.6.23-7/4460_pax-hook-build-error.patch
15 hardened-sources/2.6/tags/2.6.23-7/4465_acct_stack_growth-null-deref.patch
16 hardened-sources/2.6/tags/2.6.23-7/4470_pax-vma-mirroring-fixes.patch
17 hardened-sources/2.6/tags/2.6.23-7/4475_vesafb-pmi-kernexec-fix.patch
18 hardened-sources/2.6/tags/2.6.23-7/4480_deselect-kernexec-on-unsupported-arches.patch
19 hardened-sources/2.6/tags/2.6.23-7/4485_ia64-modular-kernel-compile-fix.patch
20 hardened-sources/2.6/tags/2.6.23-7/4490_grsec-ptrace-recursive-lock-fix.patch
21 hardened-sources/2.6/tags/2.6.23-7/4495_grsec-netlink-security-fixes.patch
22 Log:
23 Importing patchset for 2.6.23-7 (from hardened-patches-2.6.23-7.extras.tar.bz2).
24
25 Added: hardened-sources/2.6/tags/2.6.23-7/4405_alpha-sysctl-uac-for-hardened-extras.patch
26 ===================================================================
27 --- hardened-sources/2.6/tags/2.6.23-7/4405_alpha-sysctl-uac-for-hardened-extras.patch (rev 0)
28 +++ hardened-sources/2.6/tags/2.6.23-7/4405_alpha-sysctl-uac-for-hardened-extras.patch 2008-04-30 11:42:53 UTC (rev 97)
29 @@ -0,0 +1,187 @@
30 +---
31 + arch/alpha/Kconfig | 26 ++++++++++++++++++++++++
32 + arch/alpha/kernel/traps.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++
33 + include/linux/sysctl.h | 14 +++++++++++++
34 + kernel/sysctl.c | 12 ++++++++++-
35 + 4 files changed, 100 insertions(+), 1 deletion(-)
36 +
37 +--- a/arch/alpha/Kconfig
38 ++++ b/arch/alpha/Kconfig
39 +@@ -616,6 +616,32 @@ config VERBOSE_MCHECK_ON
40 +
41 + Take the default (1) unless you want more control or more info.
42 +
43 ++config ALPHA_UAC_SYSCTL
44 ++ bool "Configure UAC policy via sysctl"
45 ++ depends on SYSCTL
46 ++ default y
47 ++ ---help---
48 ++ Configuring the UAC (unaligned access control) policy on a Linux
49 ++ system usually involves setting a compile time define. If you say
50 ++ Y here, you will be able to modify the UAC policy at runtime using
51 ++ the /proc interface.
52 ++
53 ++ The UAC policy defines the action Linux should take when an
54 ++ unaligned memory access occurs. The action can include printing a
55 ++ warning message (NOPRINT), sending a signal to the offending
56 ++ program to help developers debug their applications (SIGBUS), or
57 ++ disabling the transparent fixing (NOFIX).
58 ++
59 ++ The sysctls will be initialized to the compile-time defined UAC
60 ++ policy. You can change these manually, or with the sysctl(8)
61 ++ userspace utility.
62 ++
63 ++ To disable the warning messages at runtime, you would use
64 ++
65 ++ echo 1 > /proc/sys/kernel/uac/noprint
66 ++
67 ++ This is pretty harmless. Say Y if you're not sure.
68 ++
69 + source "drivers/pci/Kconfig"
70 + source "drivers/eisa/Kconfig"
71 +
72 +--- a/arch/alpha/kernel/traps.c
73 ++++ b/arch/alpha/kernel/traps.c
74 +@@ -14,6 +14,7 @@
75 + #include <linux/delay.h>
76 + #include <linux/smp_lock.h>
77 + #include <linux/module.h>
78 ++#include <linux/sysctl.h>
79 + #include <linux/init.h>
80 + #include <linux/kallsyms.h>
81 +
82 +@@ -102,6 +103,38 @@ static char * ireg_name[] = {"v0", "t0",
83 + "t10", "t11", "ra", "pv", "at", "gp", "sp", "zero"};
84 + #endif
85 +
86 ++#ifdef CONFIG_ALPHA_UAC_SYSCTL
87 ++static struct ctl_table_header *uac_sysctl_header;
88 ++
89 ++static int enabled_noprint = 0;
90 ++static int enabled_sigbus = 0;
91 ++static int enabled_nofix = 0;
92 ++
93 ++ctl_table uac_table[] = {
94 ++ {KERN_UAC_NOPRINT, "noprint", &enabled_noprint, sizeof (int), 0644, NULL, NULL, &proc_dointvec},
95 ++ {KERN_UAC_SIGBUS, "sigbus", &enabled_sigbus, sizeof (int), 0644, NULL, NULL, &proc_dointvec},
96 ++ {KERN_UAC_NOFIX, "nofix", &enabled_nofix, sizeof (int), 0644, NULL, NULL, &proc_dointvec},
97 ++ {0}
98 ++};
99 ++
100 ++static int __init init_uac_sysctl(void)
101 ++{
102 ++ /* Initialize sysctls with the #defined UAC policy */
103 ++ enabled_noprint = (test_thread_flag (TIF_UAC_NOPRINT)) ? 1 : 0;
104 ++ enabled_sigbus = (test_thread_flag (TIF_UAC_SIGBUS)) ? 1 : 0;
105 ++ enabled_nofix = (test_thread_flag (TIF_UAC_NOFIX)) ? 1 : 0;
106 ++
107 ++ /* save this for later so we can clean up */
108 ++ uac_sysctl_header = register_sysctl_table(uac_table);
109 ++ return 0;
110 ++}
111 ++
112 ++static void __exit exit_uac_sysctl(void)
113 ++{
114 ++ unregister_sysctl_table(uac_sysctl_header);
115 ++}
116 ++#endif
117 ++
118 + static void
119 + dik_show_code(unsigned int *pc)
120 + {
121 +@@ -780,7 +813,11 @@ do_entUnaUser(void __user * va, unsigned
122 + /* Check the UAC bits to decide what the user wants us to do
123 + with the unaliged access. */
124 +
125 ++#ifndef CONFIG_ALPHA_UAC_SYSCTL
126 + if (!test_thread_flag (TIF_UAC_NOPRINT)) {
127 ++#else /* CONFIG_ALPHA_UAC_SYSCTL */
128 ++ if (!(enabled_noprint)) {
129 ++#endif /* CONFIG_ALPHA_UAC_SYSCTL */
130 + if (cnt >= 5 && jiffies - last_time > 5*HZ) {
131 + cnt = 0;
132 + }
133 +@@ -791,10 +828,18 @@ do_entUnaUser(void __user * va, unsigned
134 + }
135 + last_time = jiffies;
136 + }
137 ++#ifndef CONFIG_ALPHA_UAC_SYSCTL
138 + if (test_thread_flag (TIF_UAC_SIGBUS))
139 ++#else /* CONFIG_ALPHA_UAC_SYSCTL */
140 ++ if (enabled_sigbus)
141 ++#endif /* CONFIG_ALPHA_UAC_SYSCTL */
142 + goto give_sigbus;
143 + /* Not sure why you'd want to use this, but... */
144 ++#ifndef CONFIG_ALPHA_UAC_SYSCTL
145 + if (test_thread_flag (TIF_UAC_NOFIX))
146 ++#else /* CONFIG_ALPHA_UAC_SYSCTL */
147 ++ if (enabled_nofix)
148 ++#endif /* CONFIG_ALPHA_UAC_SYSCTL */
149 + return;
150 +
151 + /* Don't bother reading ds in the access check since we already
152 +@@ -1089,3 +1134,7 @@ trap_init(void)
153 + wrent(entSys, 5);
154 + wrent(entDbg, 6);
155 + }
156 ++
157 ++#ifdef CONFIG_ALPHA_UAC_SYSCTL
158 ++__initcall(init_uac_sysctl);
159 ++#endif
160 +--- a/include/linux/sysctl.h
161 ++++ b/include/linux/sysctl.h
162 +@@ -165,6 +165,9 @@ enum
163 + KERN_MAX_LOCK_DEPTH=74,
164 + KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */
165 + KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
166 ++#ifdef CONFIG_ALPHA_UAC_SYSCTL
167 ++ KERN_UAC_POLICY=78, /* int: Alpha unaligned access control policy flags */
168 ++#endif /* CONFIG_ALPHA_UAC_SYSCTL */
169 + };
170 +
171 +
172 +@@ -258,6 +261,17 @@ enum
173 + PTY_NR=2
174 + };
175 +
176 ++#ifdef CONFIG_ALPHA_UAC_SYSCTL
177 ++/* /proc/sys/kernel/uac */
178 ++enum
179 ++{
180 ++ /* UAC policy on Alpha */
181 ++ KERN_UAC_NOPRINT=1, /* int: printk() on unaligned access */
182 ++ KERN_UAC_SIGBUS=2, /* int: send SIGBUS on unaligned access */
183 ++ KERN_UAC_NOFIX=3, /* int: don't fix the unaligned access */
184 ++};
185 ++#endif /* CONFIG_ALPHA_UAC_SYSCTL */
186 ++
187 + /* /proc/sys/bus/isa */
188 + enum
189 + {
190 +--- a/kernel/sysctl.c
191 ++++ b/kernel/sysctl.c
192 +@@ -155,6 +155,9 @@ extern ctl_table pty_table[];
193 + #ifdef CONFIG_INOTIFY_USER
194 + extern ctl_table inotify_table[];
195 + #endif
196 ++#ifdef CONFIG_ALPHA_UAC_SYSCTL
197 ++extern ctl_table uac_table[];
198 ++#endif
199 +
200 + #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
201 + int sysctl_legacy_va_layout;
202 +@@ -208,6 +211,14 @@ static ctl_table root_table[] = {
203 + * NOTE: do not add new entries to this table unless you have read
204 + * Documentation/sysctl/ctl_unnumbered.txt
205 + */
206 ++#ifdef CONFIG_ALPHA_UAC_SYSCTL
207 ++ {
208 ++ .ctl_name = KERN_UAC_POLICY,
209 ++ .procname = "uac",
210 ++ .mode = 0555,
211 ++ .child = uac_table,
212 ++ },
213 ++#endif /* CONFIG_ALPHA_UAC_SYSCTL */
214 + { .ctl_name = 0 }
215 + };
216 +
217
218 Added: hardened-sources/2.6/tags/2.6.23-7/4430_grsec-2.1.11-2.6.23.15-20080210.patch
219 ===================================================================
220 --- hardened-sources/2.6/tags/2.6.23-7/4430_grsec-2.1.11-2.6.23.15-20080210.patch (rev 0)
221 +++ hardened-sources/2.6/tags/2.6.23-7/4430_grsec-2.1.11-2.6.23.15-20080210.patch 2008-04-30 11:42:53 UTC (rev 97)
222 @@ -0,0 +1,35665 @@
223 +From: Kerin Millar <kerframil@×××××.com>
224 +
225 +grsecurity-2.1.11-2.6.23.14-200801231800 forward ported to 2.6.23.15 for
226 +the Hardened Gentoo project. Thanks to pipacs for some advice concerning
227 +mmap.c changes.
228 +
229 +diff -Nurp linux-2.6.23.15/Documentation/dontdiff linux-2.6.23.15-grsec/Documentation/dontdiff
230 +--- linux-2.6.23.15/Documentation/dontdiff 2007-10-09 21:31:38.000000000 +0100
231 ++++ linux-2.6.23.15-grsec/Documentation/dontdiff 2008-02-11 10:37:44.000000000 +0000
232 +@@ -176,14 +176,18 @@ times.h*
233 + tkparse
234 + trix_boot.h
235 + utsrelease.h*
236 ++vdso.lds
237 + version.h*
238 + vmlinux
239 + vmlinux-*
240 + vmlinux.aout
241 ++vmlinux.bin.all
242 + vmlinux.lds
243 ++vmlinux.relocs
244 + vsyscall.lds
245 + wanxlfw.inc
246 + uImage
247 + unifdef
248 ++utsrelease.h
249 + zImage*
250 + zconf.hash.c
251 +diff -Nurp linux-2.6.23.15/Makefile linux-2.6.23.15-grsec/Makefile
252 +--- linux-2.6.23.15/Makefile 2008-02-11 10:36:03.000000000 +0000
253 ++++ linux-2.6.23.15-grsec/Makefile 2008-02-11 10:37:44.000000000 +0000
254 +@@ -312,7 +312,7 @@ LINUXINCLUDE := -Iinclude \
255 +
256 + CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE)
257 +
258 +-CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
259 ++CFLAGS := -Wall -W -Wno-unused -Wno-sign-compare -Wundef -Wstrict-prototypes -Wno-trigraphs \
260 + -fno-strict-aliasing -fno-common \
261 + -Werror-implicit-function-declaration
262 + AFLAGS := -D__ASSEMBLY__
263 +@@ -560,7 +560,7 @@ export mod_strip_cmd
264 +
265 +
266 + ifeq ($(KBUILD_EXTMOD),)
267 +-core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
268 ++core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
269 +
270 + vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
271 + $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
272 +diff -Nurp linux-2.6.23.15/arch/alpha/kernel/module.c linux-2.6.23.15-grsec/arch/alpha/kernel/module.c
273 +--- linux-2.6.23.15/arch/alpha/kernel/module.c 2007-10-09 21:31:38.000000000 +0100
274 ++++ linux-2.6.23.15-grsec/arch/alpha/kernel/module.c 2008-02-11 10:37:44.000000000 +0000
275 +@@ -176,7 +176,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
276 +
277 + /* The small sections were sorted to the end of the segment.
278 + The following should definitely cover them. */
279 +- gp = (u64)me->module_core + me->core_size - 0x8000;
280 ++ gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
281 + got = sechdrs[me->arch.gotsecindex].sh_addr;
282 +
283 + for (i = 0; i < n; i++) {
284 +diff -Nurp linux-2.6.23.15/arch/alpha/kernel/osf_sys.c linux-2.6.23.15-grsec/arch/alpha/kernel/osf_sys.c
285 +--- linux-2.6.23.15/arch/alpha/kernel/osf_sys.c 2007-10-09 21:31:38.000000000 +0100
286 ++++ linux-2.6.23.15-grsec/arch/alpha/kernel/osf_sys.c 2008-02-11 10:37:44.000000000 +0000
287 +@@ -1288,6 +1288,10 @@ arch_get_unmapped_area(struct file *filp
288 + merely specific addresses, but regions of memory -- perhaps
289 + this feature should be incorporated into all ports? */
290 +
291 ++#ifdef CONFIG_PAX_RANDMMAP
292 ++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
293 ++#endif
294 ++
295 + if (addr) {
296 + addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
297 + if (addr != (unsigned long) -ENOMEM)
298 +@@ -1295,8 +1299,8 @@ arch_get_unmapped_area(struct file *filp
299 + }
300 +
301 + /* Next, try allocating at TASK_UNMAPPED_BASE. */
302 +- addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
303 +- len, limit);
304 ++ addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
305 ++
306 + if (addr != (unsigned long) -ENOMEM)
307 + return addr;
308 +
309 +diff -Nurp linux-2.6.23.15/arch/alpha/kernel/ptrace.c linux-2.6.23.15-grsec/arch/alpha/kernel/ptrace.c
310 +--- linux-2.6.23.15/arch/alpha/kernel/ptrace.c 2007-10-09 21:31:38.000000000 +0100
311 ++++ linux-2.6.23.15-grsec/arch/alpha/kernel/ptrace.c 2008-02-11 10:37:44.000000000 +0000
312 +@@ -15,6 +15,7 @@
313 + #include <linux/slab.h>
314 + #include <linux/security.h>
315 + #include <linux/signal.h>
316 ++#include <linux/grsecurity.h>
317 +
318 + #include <asm/uaccess.h>
319 + #include <asm/pgtable.h>
320 +@@ -283,6 +284,11 @@ do_sys_ptrace(long request, long pid, lo
321 + goto out_notsk;
322 + }
323 +
324 ++ if (gr_handle_ptrace(child, request)) {
325 ++ ret = -EPERM;
326 ++ goto out;
327 ++ }
328 ++
329 + if (request == PTRACE_ATTACH) {
330 + ret = ptrace_attach(child);
331 + goto out;
332 +diff -Nurp linux-2.6.23.15/arch/alpha/mm/fault.c linux-2.6.23.15-grsec/arch/alpha/mm/fault.c
333 +--- linux-2.6.23.15/arch/alpha/mm/fault.c 2007-10-09 21:31:38.000000000 +0100
334 ++++ linux-2.6.23.15-grsec/arch/alpha/mm/fault.c 2008-02-11 10:37:44.000000000 +0000
335 +@@ -23,6 +23,7 @@
336 + #include <linux/smp.h>
337 + #include <linux/interrupt.h>
338 + #include <linux/module.h>
339 ++#include <linux/binfmts.h>
340 +
341 + #include <asm/system.h>
342 + #include <asm/uaccess.h>
343 +@@ -54,6 +55,124 @@ __load_new_mm_context(struct mm_struct *
344 + __reload_thread(pcb);
345 + }
346 +
347 ++#ifdef CONFIG_PAX_PAGEEXEC
348 ++/*
349 ++ * PaX: decide what to do with offenders (regs->pc = fault address)
350 ++ *
351 ++ * returns 1 when task should be killed
352 ++ * 2 when patched PLT trampoline was detected
353 ++ * 3 when unpatched PLT trampoline was detected
354 ++ */
355 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
356 ++{
357 ++
358 ++#ifdef CONFIG_PAX_EMUPLT
359 ++ int err;
360 ++
361 ++ do { /* PaX: patched PLT emulation #1 */
362 ++ unsigned int ldah, ldq, jmp;
363 ++
364 ++ err = get_user(ldah, (unsigned int *)regs->pc);
365 ++ err |= get_user(ldq, (unsigned int *)(regs->pc+4));
366 ++ err |= get_user(jmp, (unsigned int *)(regs->pc+8));
367 ++
368 ++ if (err)
369 ++ break;
370 ++
371 ++ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
372 ++ (ldq & 0xFFFF0000U) == 0xA77B0000U &&
373 ++ jmp == 0x6BFB0000U)
374 ++ {
375 ++ unsigned long r27, addr;
376 ++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
377 ++ unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
378 ++
379 ++ addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
380 ++ err = get_user(r27, (unsigned long *)addr);
381 ++ if (err)
382 ++ break;
383 ++
384 ++ regs->r27 = r27;
385 ++ regs->pc = r27;
386 ++ return 2;
387 ++ }
388 ++ } while (0);
389 ++
390 ++ do { /* PaX: patched PLT emulation #2 */
391 ++ unsigned int ldah, lda, br;
392 ++
393 ++ err = get_user(ldah, (unsigned int *)regs->pc);
394 ++ err |= get_user(lda, (unsigned int *)(regs->pc+4));
395 ++ err |= get_user(br, (unsigned int *)(regs->pc+8));
396 ++
397 ++ if (err)
398 ++ break;
399 ++
400 ++ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
401 ++ (lda & 0xFFFF0000U) == 0xA77B0000U &&
402 ++ (br & 0xFFE00000U) == 0xC3E00000U)
403 ++ {
404 ++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
405 ++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
406 ++ unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
407 ++
408 ++ regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
409 ++ regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
410 ++ return 2;
411 ++ }
412 ++ } while (0);
413 ++
414 ++ do { /* PaX: unpatched PLT emulation */
415 ++ unsigned int br;
416 ++
417 ++ err = get_user(br, (unsigned int *)regs->pc);
418 ++
419 ++ if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
420 ++ unsigned int br2, ldq, nop, jmp;
421 ++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
422 ++
423 ++ addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
424 ++ err = get_user(br2, (unsigned int *)addr);
425 ++ err |= get_user(ldq, (unsigned int *)(addr+4));
426 ++ err |= get_user(nop, (unsigned int *)(addr+8));
427 ++ err |= get_user(jmp, (unsigned int *)(addr+12));
428 ++ err |= get_user(resolver, (unsigned long *)(addr+16));
429 ++
430 ++ if (err)
431 ++ break;
432 ++
433 ++ if (br2 == 0xC3600000U &&
434 ++ ldq == 0xA77B000CU &&
435 ++ nop == 0x47FF041FU &&
436 ++ jmp == 0x6B7B0000U)
437 ++ {
438 ++ regs->r28 = regs->pc+4;
439 ++ regs->r27 = addr+16;
440 ++ regs->pc = resolver;
441 ++ return 3;
442 ++ }
443 ++ }
444 ++ } while (0);
445 ++#endif
446 ++
447 ++ return 1;
448 ++}
449 ++
450 ++void pax_report_insns(void *pc, void *sp)
451 ++{
452 ++ unsigned long i;
453 ++
454 ++ printk(KERN_ERR "PAX: bytes at PC: ");
455 ++ for (i = 0; i < 5; i++) {
456 ++ unsigned int c;
457 ++ if (get_user(c, (unsigned int *)pc+i))
458 ++ printk("???????? ");
459 ++ else
460 ++ printk("%08x ", c);
461 ++ }
462 ++ printk("\n");
463 ++}
464 ++#endif
465 +
466 + /*
467 + * This routine handles page faults. It determines the address,
468 +@@ -131,8 +250,29 @@ do_page_fault(unsigned long address, uns
469 + good_area:
470 + si_code = SEGV_ACCERR;
471 + if (cause < 0) {
472 +- if (!(vma->vm_flags & VM_EXEC))
473 ++ if (!(vma->vm_flags & VM_EXEC)) {
474 ++
475 ++#ifdef CONFIG_PAX_PAGEEXEC
476 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
477 ++ goto bad_area;
478 ++
479 ++ up_read(&mm->mmap_sem);
480 ++ switch (pax_handle_fetch_fault(regs)) {
481 ++
482 ++#ifdef CONFIG_PAX_EMUPLT
483 ++ case 2:
484 ++ case 3:
485 ++ return;
486 ++#endif
487 ++
488 ++ }
489 ++ pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
490 ++ do_exit(SIGKILL);
491 ++#else
492 + goto bad_area;
493 ++#endif
494 ++
495 ++ }
496 + } else if (!cause) {
497 + /* Allow reads even for write-only mappings */
498 + if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
499 +diff -Nurp linux-2.6.23.15/arch/arm/mm/mmap.c linux-2.6.23.15-grsec/arch/arm/mm/mmap.c
500 +--- linux-2.6.23.15/arch/arm/mm/mmap.c 2007-10-09 21:31:38.000000000 +0100
501 ++++ linux-2.6.23.15-grsec/arch/arm/mm/mmap.c 2008-02-11 10:37:44.000000000 +0000
502 +@@ -60,6 +60,10 @@ arch_get_unmapped_area(struct file *filp
503 + if (len > TASK_SIZE)
504 + return -ENOMEM;
505 +
506 ++#ifdef CONFIG_PAX_RANDMMAP
507 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
508 ++#endif
509 ++
510 + if (addr) {
511 + if (do_align)
512 + addr = COLOUR_ALIGN(addr, pgoff);
513 +@@ -72,10 +76,10 @@ arch_get_unmapped_area(struct file *filp
514 + return addr;
515 + }
516 + if (len > mm->cached_hole_size) {
517 +- start_addr = addr = mm->free_area_cache;
518 ++ start_addr = addr = mm->free_area_cache;
519 + } else {
520 +- start_addr = addr = TASK_UNMAPPED_BASE;
521 +- mm->cached_hole_size = 0;
522 ++ start_addr = addr = mm->mmap_base;
523 ++ mm->cached_hole_size = 0;
524 + }
525 +
526 + full_search:
527 +@@ -91,8 +95,8 @@ full_search:
528 + * Start a new search - just in case we missed
529 + * some holes.
530 + */
531 +- if (start_addr != TASK_UNMAPPED_BASE) {
532 +- start_addr = addr = TASK_UNMAPPED_BASE;
533 ++ if (start_addr != mm->mmap_base) {
534 ++ start_addr = addr = mm->mmap_base;
535 + mm->cached_hole_size = 0;
536 + goto full_search;
537 + }
538 +diff -Nurp linux-2.6.23.15/arch/avr32/mm/fault.c linux-2.6.23.15-grsec/arch/avr32/mm/fault.c
539 +--- linux-2.6.23.15/arch/avr32/mm/fault.c 2007-10-09 21:31:38.000000000 +0100
540 ++++ linux-2.6.23.15-grsec/arch/avr32/mm/fault.c 2008-02-11 10:37:44.000000000 +0000
541 +@@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
542 +
543 + int exception_trace = 1;
544 +
545 ++#ifdef CONFIG_PAX_PAGEEXEC
546 ++void pax_report_insns(void *pc, void *sp)
547 ++{
548 ++ unsigned long i;
549 ++
550 ++ printk(KERN_ERR "PAX: bytes at PC: ");
551 ++ for (i = 0; i < 20; i++) {
552 ++ unsigned char c;
553 ++ if (get_user(c, (unsigned char *)pc+i))
554 ++ printk("???????? ");
555 ++ else
556 ++ printk("%02x ", c);
557 ++ }
558 ++ printk("\n");
559 ++}
560 ++#endif
561 ++
562 + /*
563 + * This routine handles page faults. It determines the address and the
564 + * problem, and then passes it off to one of the appropriate routines.
565 +@@ -157,6 +174,16 @@ bad_area:
566 + up_read(&mm->mmap_sem);
567 +
568 + if (user_mode(regs)) {
569 ++
570 ++#ifdef CONFIG_PAX_PAGEEXEC
571 ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
572 ++ if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
573 ++ pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
574 ++ do_exit(SIGKILL);
575 ++ }
576 ++ }
577 ++#endif
578 ++
579 + if (exception_trace && printk_ratelimit())
580 + printk("%s%s[%d]: segfault at %08lx pc %08lx "
581 + "sp %08lx ecr %lu\n",
582 +diff -Nurp linux-2.6.23.15/arch/i386/Kconfig linux-2.6.23.15-grsec/arch/i386/Kconfig
583 +--- linux-2.6.23.15/arch/i386/Kconfig 2007-10-09 21:31:38.000000000 +0100
584 ++++ linux-2.6.23.15-grsec/arch/i386/Kconfig 2008-02-11 10:37:44.000000000 +0000
585 +@@ -592,7 +592,7 @@ config PAGE_OFFSET
586 + hex
587 + default 0xB0000000 if VMSPLIT_3G_OPT
588 + default 0x80000000 if VMSPLIT_2G
589 +- default 0x78000000 if VMSPLIT_2G_OPT
590 ++ default 0x70000000 if VMSPLIT_2G_OPT
591 + default 0x40000000 if VMSPLIT_1G
592 + default 0xC0000000
593 +
594 +@@ -831,7 +831,7 @@ config CRASH_DUMP
595 + config PHYSICAL_START
596 + hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
597 + default "0x1000000" if X86_NUMAQ
598 +- default "0x100000"
599 ++ default "0x200000"
600 + help
601 + This gives the physical address where the kernel is loaded.
602 +
603 +@@ -916,7 +916,7 @@ config HOTPLUG_CPU
604 +
605 + config COMPAT_VDSO
606 + bool "Compat VDSO support"
607 +- default y
608 ++ default n
609 + help
610 + Map the VDSO to the predictable old-style address too.
611 + ---help---
612 +@@ -1092,7 +1092,7 @@ config PCI
613 + choice
614 + prompt "PCI access mode"
615 + depends on PCI && !X86_VISWS
616 +- default PCI_GOANY
617 ++ default PCI_GODIRECT
618 + ---help---
619 + On PCI systems, the BIOS can be used to detect the PCI devices and
620 + determine their configuration. However, some old PCI motherboards
621 +diff -Nurp linux-2.6.23.15/arch/i386/Kconfig.cpu linux-2.6.23.15-grsec/arch/i386/Kconfig.cpu
622 +--- linux-2.6.23.15/arch/i386/Kconfig.cpu 2007-10-09 21:31:38.000000000 +0100
623 ++++ linux-2.6.23.15-grsec/arch/i386/Kconfig.cpu 2008-02-11 10:37:44.000000000 +0000
624 +@@ -274,7 +274,7 @@ config X86_PPRO_FENCE
625 +
626 + config X86_F00F_BUG
627 + bool
628 +- depends on M586MMX || M586TSC || M586 || M486 || M386
629 ++ depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
630 + default y
631 +
632 + config X86_WP_WORKS_OK
633 +@@ -299,7 +299,7 @@ config X86_POPAD_OK
634 +
635 + config X86_ALIGNMENT_16
636 + bool
637 +- depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
638 ++ depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
639 + default y
640 +
641 + config X86_GOOD_APIC
642 +diff -Nurp linux-2.6.23.15/arch/i386/Kconfig.debug linux-2.6.23.15-grsec/arch/i386/Kconfig.debug
643 +--- linux-2.6.23.15/arch/i386/Kconfig.debug 2007-10-09 21:31:38.000000000 +0100
644 ++++ linux-2.6.23.15-grsec/arch/i386/Kconfig.debug 2008-02-11 10:37:44.000000000 +0000
645 +@@ -46,16 +46,6 @@ config DEBUG_PAGEALLOC
646 + This results in a large slowdown, but helps to find certain types
647 + of memory corruptions.
648 +
649 +-config DEBUG_RODATA
650 +- bool "Write protect kernel read-only data structures"
651 +- depends on DEBUG_KERNEL
652 +- help
653 +- Mark the kernel read-only data as write-protected in the pagetables,
654 +- in order to catch accidental (and incorrect) writes to such const
655 +- data. This option may have a slight performance impact because a
656 +- portion of the kernel code won't be covered by a 2MB TLB anymore.
657 +- If in doubt, say "N".
658 +-
659 + config 4KSTACKS
660 + bool "Use 4Kb for kernel stacks instead of 8Kb"
661 + depends on DEBUG_KERNEL
662 +diff -Nurp linux-2.6.23.15/arch/i386/boot/bitops.h linux-2.6.23.15-grsec/arch/i386/boot/bitops.h
663 +--- linux-2.6.23.15/arch/i386/boot/bitops.h 2007-10-09 21:31:38.000000000 +0100
664 ++++ linux-2.6.23.15-grsec/arch/i386/boot/bitops.h 2008-02-11 10:37:44.000000000 +0000
665 +@@ -28,7 +28,7 @@ static inline int variable_test_bit(int
666 + u8 v;
667 + const u32 *p = (const u32 *)addr;
668 +
669 +- asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
670 ++ asm volatile("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
671 + return v;
672 + }
673 +
674 +@@ -39,7 +39,7 @@ static inline int variable_test_bit(int
675 +
676 + static inline void set_bit(int nr, void *addr)
677 + {
678 +- asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
679 ++ asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
680 + }
681 +
682 + #endif /* BOOT_BITOPS_H */
683 +diff -Nurp linux-2.6.23.15/arch/i386/boot/boot.h linux-2.6.23.15-grsec/arch/i386/boot/boot.h
684 +--- linux-2.6.23.15/arch/i386/boot/boot.h 2008-02-11 10:36:03.000000000 +0000
685 ++++ linux-2.6.23.15-grsec/arch/i386/boot/boot.h 2008-02-11 10:37:44.000000000 +0000
686 +@@ -78,7 +78,7 @@ static inline void io_delay(void)
687 + static inline u16 ds(void)
688 + {
689 + u16 seg;
690 +- asm("movw %%ds,%0" : "=rm" (seg));
691 ++ asm volatile("movw %%ds,%0" : "=rm" (seg));
692 + return seg;
693 + }
694 +
695 +@@ -174,7 +174,7 @@ static inline void wrgs32(u32 v, addr_t
696 + static inline int memcmp(const void *s1, const void *s2, size_t len)
697 + {
698 + u8 diff;
699 +- asm("repe; cmpsb; setnz %0"
700 ++ asm volatile("repe; cmpsb; setnz %0"
701 + : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
702 + return diff;
703 + }
704 +diff -Nurp linux-2.6.23.15/arch/i386/boot/compressed/head.S linux-2.6.23.15-grsec/arch/i386/boot/compressed/head.S
705 +--- linux-2.6.23.15/arch/i386/boot/compressed/head.S 2007-10-09 21:31:38.000000000 +0100
706 ++++ linux-2.6.23.15-grsec/arch/i386/boot/compressed/head.S 2008-02-11 10:37:44.000000000 +0000
707 +@@ -159,9 +159,8 @@ relocated:
708 + */
709 +
710 + 1: subl $4, %edi
711 +- movl 0(%edi), %ecx
712 +- testl %ecx, %ecx
713 +- jz 2f
714 ++ movl (%edi), %ecx
715 ++ jecxz 2f
716 + addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
717 + jmp 1b
718 + 2:
719 +diff -Nurp linux-2.6.23.15/arch/i386/boot/compressed/relocs.c linux-2.6.23.15-grsec/arch/i386/boot/compressed/relocs.c
720 +--- linux-2.6.23.15/arch/i386/boot/compressed/relocs.c 2007-10-09 21:31:38.000000000 +0100
721 ++++ linux-2.6.23.15-grsec/arch/i386/boot/compressed/relocs.c 2008-02-11 10:37:44.000000000 +0000
722 +@@ -10,9 +10,13 @@
723 + #define USE_BSD
724 + #include <endian.h>
725 +
726 ++#include "../../../../include/linux/autoconf.h"
727 ++
728 ++#define MAX_PHDRS 100
729 + #define MAX_SHDRS 100
730 + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
731 + static Elf32_Ehdr ehdr;
732 ++static Elf32_Phdr phdr[MAX_PHDRS];
733 + static Elf32_Shdr shdr[MAX_SHDRS];
734 + static Elf32_Sym *symtab[MAX_SHDRS];
735 + static Elf32_Rel *reltab[MAX_SHDRS];
736 +@@ -246,6 +250,34 @@ static void read_ehdr(FILE *fp)
737 + }
738 + }
739 +
740 ++static void read_phdrs(FILE *fp)
741 ++{
742 ++ int i;
743 ++ if (ehdr.e_phnum > MAX_PHDRS) {
744 ++ die("%d program headers supported: %d\n",
745 ++ ehdr.e_phnum, MAX_PHDRS);
746 ++ }
747 ++ if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) {
748 ++ die("Seek to %d failed: %s\n",
749 ++ ehdr.e_phoff, strerror(errno));
750 ++ }
751 ++ if (fread(&phdr, sizeof(phdr[0]), ehdr.e_phnum, fp) != ehdr.e_phnum) {
752 ++ die("Cannot read ELF program headers: %s\n",
753 ++ strerror(errno));
754 ++ }
755 ++ for(i = 0; i < ehdr.e_phnum; i++) {
756 ++ phdr[i].p_type = elf32_to_cpu(phdr[i].p_type);
757 ++ phdr[i].p_offset = elf32_to_cpu(phdr[i].p_offset);
758 ++ phdr[i].p_vaddr = elf32_to_cpu(phdr[i].p_vaddr);
759 ++ phdr[i].p_paddr = elf32_to_cpu(phdr[i].p_paddr);
760 ++ phdr[i].p_filesz = elf32_to_cpu(phdr[i].p_filesz);
761 ++ phdr[i].p_memsz = elf32_to_cpu(phdr[i].p_memsz);
762 ++ phdr[i].p_flags = elf32_to_cpu(phdr[i].p_flags);
763 ++ phdr[i].p_align = elf32_to_cpu(phdr[i].p_align);
764 ++ }
765 ++
766 ++}
767 ++
768 + static void read_shdrs(FILE *fp)
769 + {
770 + int i;
771 +@@ -332,6 +364,8 @@ static void read_symtabs(FILE *fp)
772 + static void read_relocs(FILE *fp)
773 + {
774 + int i,j;
775 ++ uint32_t base;
776 ++
777 + for(i = 0; i < ehdr.e_shnum; i++) {
778 + if (shdr[i].sh_type != SHT_REL) {
779 + continue;
780 +@@ -349,8 +383,17 @@ static void read_relocs(FILE *fp)
781 + die("Cannot read symbol table: %s\n",
782 + strerror(errno));
783 + }
784 ++ base = 0;
785 ++ for (j = 0; j < ehdr.e_phnum; j++) {
786 ++ if (phdr[j].p_type != PT_LOAD )
787 ++ continue;
788 ++ if (shdr[shdr[i].sh_info].sh_offset < phdr[j].p_offset || shdr[shdr[i].sh_info].sh_offset > phdr[j].p_offset + phdr[j].p_filesz)
789 ++ continue;
790 ++ base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr;
791 ++ break;
792 ++ }
793 + for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) {
794 +- reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset);
795 ++ reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset) + base;
796 + reltab[i][j].r_info = elf32_to_cpu(reltab[i][j].r_info);
797 + }
798 + }
799 +@@ -487,6 +530,27 @@ static void walk_relocs(void (*visit)(El
800 + if (sym->st_shndx == SHN_ABS) {
801 + continue;
802 + }
803 ++ /* Don't relocate actual per-cpu variables, they are absolute indices, not addresses */
804 ++ if (!strcmp(sec_name(sym->st_shndx), ".data.percpu") && strncmp(sym_name(sym_strtab, sym), "__per_cpu_", 10)) {
805 ++ continue;
806 ++ }
807 ++#ifdef CONFIG_PAX_KERNEXEC
808 ++ /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */
809 ++ if (!strcmp(sec_name(sym->st_shndx), ".init.text")) {
810 ++ continue;
811 ++ }
812 ++ if (!strcmp(sec_name(sym->st_shndx), ".exit.text")) {
813 ++ continue;
814 ++ }
815 ++ if (!strcmp(sec_name(sym->st_shndx), ".text.head"))
816 ++ if (strcmp(sym_name(sym_strtab, sym), "__init_end") &&
817 ++ strcmp(sym_name(sym_strtab, sym), "KERNEL_TEXT_OFFSET")) {
818 ++ continue;
819 ++ }
820 ++ if (!strcmp(sec_name(sym->st_shndx), ".text")) {
821 ++ continue;
822 ++ }
823 ++#endif
824 + if (r_type == R_386_PC32) {
825 + /* PC relative relocations don't need to be adjusted */
826 + }
827 +@@ -614,6 +678,7 @@ int main(int argc, char **argv)
828 + fname, strerror(errno));
829 + }
830 + read_ehdr(fp);
831 ++ read_phdrs(fp);
832 + read_shdrs(fp);
833 + read_strtabs(fp);
834 + read_symtabs(fp);
835 +diff -Nurp linux-2.6.23.15/arch/i386/boot/cpucheck.c linux-2.6.23.15-grsec/arch/i386/boot/cpucheck.c
836 +--- linux-2.6.23.15/arch/i386/boot/cpucheck.c 2007-10-09 21:31:38.000000000 +0100
837 ++++ linux-2.6.23.15-grsec/arch/i386/boot/cpucheck.c 2008-02-11 10:37:44.000000000 +0000
838 +@@ -90,7 +90,7 @@ static int has_fpu(void)
839 + u16 fcw = -1, fsw = -1;
840 + u32 cr0;
841 +
842 +- asm("movl %%cr0,%0" : "=r" (cr0));
843 ++ asm volatile("movl %%cr0,%0" : "=r" (cr0));
844 + if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
845 + cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
846 + asm volatile("movl %0,%%cr0" : : "r" (cr0));
847 +@@ -106,7 +106,7 @@ static int has_eflag(u32 mask)
848 + {
849 + u32 f0, f1;
850 +
851 +- asm("pushfl ; "
852 ++ asm volatile("pushfl ; "
853 + "pushfl ; "
854 + "popl %0 ; "
855 + "movl %0,%1 ; "
856 +@@ -131,7 +131,7 @@ static void get_flags(void)
857 + set_bit(X86_FEATURE_FPU, cpu.flags);
858 +
859 + if (has_eflag(X86_EFLAGS_ID)) {
860 +- asm("cpuid"
861 ++ asm volatile("cpuid"
862 + : "=a" (max_intel_level),
863 + "=b" (cpu_vendor[0]),
864 + "=d" (cpu_vendor[1]),
865 +@@ -140,7 +140,7 @@ static void get_flags(void)
866 +
867 + if (max_intel_level >= 0x00000001 &&
868 + max_intel_level <= 0x0000ffff) {
869 +- asm("cpuid"
870 ++ asm volatile("cpuid"
871 + : "=a" (tfms),
872 + "=c" (cpu.flags[4]),
873 + "=d" (cpu.flags[0])
874 +@@ -152,7 +152,7 @@ static void get_flags(void)
875 + cpu.model += ((tfms >> 16) & 0xf) << 4;
876 + }
877 +
878 +- asm("cpuid"
879 ++ asm volatile("cpuid"
880 + : "=a" (max_amd_level)
881 + : "a" (0x80000000)
882 + : "ebx", "ecx", "edx");
883 +@@ -160,7 +160,7 @@ static void get_flags(void)
884 + if (max_amd_level >= 0x80000001 &&
885 + max_amd_level <= 0x8000ffff) {
886 + u32 eax = 0x80000001;
887 +- asm("cpuid"
888 ++ asm volatile("cpuid"
889 + : "+a" (eax),
890 + "=c" (cpu.flags[6]),
891 + "=d" (cpu.flags[1])
892 +@@ -219,9 +219,9 @@ int check_cpu(int *cpu_level_ptr, int *r
893 + u32 ecx = MSR_K7_HWCR;
894 + u32 eax, edx;
895 +
896 +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
897 ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
898 + eax &= ~(1 << 15);
899 +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
900 ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
901 +
902 + get_flags(); /* Make sure it really did something */
903 + err = check_flags();
904 +@@ -234,9 +234,9 @@ int check_cpu(int *cpu_level_ptr, int *r
905 + u32 ecx = MSR_VIA_FCR;
906 + u32 eax, edx;
907 +
908 +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
909 ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
910 + eax |= (1<<1)|(1<<7);
911 +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
912 ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
913 +
914 + set_bit(X86_FEATURE_CX8, cpu.flags);
915 + err = check_flags();
916 +@@ -247,12 +247,12 @@ int check_cpu(int *cpu_level_ptr, int *r
917 + u32 eax, edx;
918 + u32 level = 1;
919 +
920 +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
921 +- asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
922 +- asm("cpuid"
923 ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
924 ++ asm volatile("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
925 ++ asm volatile("cpuid"
926 + : "+a" (level), "=d" (cpu.flags[0])
927 + : : "ecx", "ebx");
928 +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
929 ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
930 +
931 + err = check_flags();
932 + }
933 +diff -Nurp linux-2.6.23.15/arch/i386/boot/edd.c linux-2.6.23.15-grsec/arch/i386/boot/edd.c
934 +--- linux-2.6.23.15/arch/i386/boot/edd.c 2007-10-09 21:31:38.000000000 +0100
935 ++++ linux-2.6.23.15-grsec/arch/i386/boot/edd.c 2008-02-11 10:37:44.000000000 +0000
936 +@@ -78,7 +78,7 @@ static int get_edd_info(u8 devno, struct
937 + ax = 0x4100;
938 + bx = EDDMAGIC1;
939 + dx = devno;
940 +- asm("pushfl; stc; int $0x13; setc %%al; popfl"
941 ++ asm volatile("pushfl; stc; int $0x13; setc %%al; popfl"
942 + : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
943 + : : "esi", "edi");
944 +
945 +@@ -97,7 +97,7 @@ static int get_edd_info(u8 devno, struct
946 + ei->params.length = sizeof(ei->params);
947 + ax = 0x4800;
948 + dx = devno;
949 +- asm("pushfl; int $0x13; popfl"
950 ++ asm volatile("pushfl; int $0x13; popfl"
951 + : "+a" (ax), "+d" (dx), "=m" (ei->params)
952 + : "S" (&ei->params)
953 + : "ebx", "ecx", "edi");
954 +@@ -108,7 +108,7 @@ static int get_edd_info(u8 devno, struct
955 + ax = 0x0800;
956 + dx = devno;
957 + di = 0;
958 +- asm("pushw %%es; "
959 ++ asm volatile("pushw %%es; "
960 + "movw %%di,%%es; "
961 + "pushfl; stc; int $0x13; setc %%al; popfl; "
962 + "popw %%es"
963 +diff -Nurp linux-2.6.23.15/arch/i386/boot/main.c linux-2.6.23.15-grsec/arch/i386/boot/main.c
964 +--- linux-2.6.23.15/arch/i386/boot/main.c 2007-10-09 21:31:38.000000000 +0100
965 ++++ linux-2.6.23.15-grsec/arch/i386/boot/main.c 2008-02-11 10:37:44.000000000 +0000
966 +@@ -77,7 +77,7 @@ static void keyboard_set_repeat(void)
967 + */
968 + static void query_ist(void)
969 + {
970 +- asm("int $0x15"
971 ++ asm volatile("int $0x15"
972 + : "=a" (boot_params.ist_info.signature),
973 + "=b" (boot_params.ist_info.command),
974 + "=c" (boot_params.ist_info.event),
975 +diff -Nurp linux-2.6.23.15/arch/i386/boot/mca.c linux-2.6.23.15-grsec/arch/i386/boot/mca.c
976 +--- linux-2.6.23.15/arch/i386/boot/mca.c 2007-10-09 21:31:38.000000000 +0100
977 ++++ linux-2.6.23.15-grsec/arch/i386/boot/mca.c 2008-02-11 10:37:44.000000000 +0000
978 +@@ -21,7 +21,7 @@ int query_mca(void)
979 + u8 err;
980 + u16 es, bx, len;
981 +
982 +- asm("pushw %%es ; "
983 ++ asm volatile("pushw %%es ; "
984 + "int $0x15 ; "
985 + "setc %0 ; "
986 + "movw %%es, %1 ; "
987 +diff -Nurp linux-2.6.23.15/arch/i386/boot/memory.c linux-2.6.23.15-grsec/arch/i386/boot/memory.c
988 +--- linux-2.6.23.15/arch/i386/boot/memory.c 2007-10-09 21:31:38.000000000 +0100
989 ++++ linux-2.6.23.15-grsec/arch/i386/boot/memory.c 2008-02-11 10:37:44.000000000 +0000
990 +@@ -32,7 +32,7 @@ static int detect_memory_e820(void)
991 + /* Important: %edx is clobbered by some BIOSes,
992 + so it must be either used for the error output
993 + or explicitly marked clobbered. */
994 +- asm("int $0x15; setc %0"
995 ++ asm volatile("int $0x15; setc %0"
996 + : "=d" (err), "+b" (next), "=a" (id), "+c" (size),
997 + "=m" (*desc)
998 + : "D" (desc), "d" (SMAP), "a" (0xe820));
999 +@@ -64,7 +64,7 @@ static int detect_memory_e801(void)
1000 +
1001 + bx = cx = dx = 0;
1002 + ax = 0xe801;
1003 +- asm("stc; int $0x15; setc %0"
1004 ++ asm volatile("stc; int $0x15; setc %0"
1005 + : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
1006 +
1007 + if (err)
1008 +@@ -94,7 +94,7 @@ static int detect_memory_88(void)
1009 + u8 err;
1010 +
1011 + ax = 0x8800;
1012 +- asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
1013 ++ asm volatile("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
1014 +
1015 + boot_params.screen_info.ext_mem_k = ax;
1016 +
1017 +diff -Nurp linux-2.6.23.15/arch/i386/boot/video-vesa.c linux-2.6.23.15-grsec/arch/i386/boot/video-vesa.c
1018 +--- linux-2.6.23.15/arch/i386/boot/video-vesa.c 2008-02-11 10:36:03.000000000 +0000
1019 ++++ linux-2.6.23.15-grsec/arch/i386/boot/video-vesa.c 2008-02-11 10:37:44.000000000 +0000
1020 +@@ -41,7 +41,7 @@ static int vesa_probe(void)
1021 +
1022 + ax = 0x4f00;
1023 + di = (size_t)&vginfo;
1024 +- asm(INT10
1025 ++ asm volatile(INT10
1026 + : "+a" (ax), "+D" (di), "=m" (vginfo)
1027 + : : "ebx", "ecx", "edx", "esi");
1028 +
1029 +@@ -68,7 +68,7 @@ static int vesa_probe(void)
1030 + ax = 0x4f01;
1031 + cx = mode;
1032 + di = (size_t)&vminfo;
1033 +- asm(INT10
1034 ++ asm volatile(INT10
1035 + : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
1036 + : : "ebx", "edx", "esi");
1037 +
1038 +@@ -115,7 +115,7 @@ static int vesa_set_mode(struct mode_inf
1039 + ax = 0x4f01;
1040 + cx = vesa_mode;
1041 + di = (size_t)&vminfo;
1042 +- asm(INT10
1043 ++ asm volatile(INT10
1044 + : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
1045 + : : "ebx", "edx", "esi");
1046 +
1047 +@@ -193,19 +193,20 @@ static void vesa_dac_set_8bits(void)
1048 + /* Save the VESA protected mode info */
1049 + static void vesa_store_pm_info(void)
1050 + {
1051 +- u16 ax, bx, di, es;
1052 ++ u16 ax, bx, cx, di, es;
1053 +
1054 + ax = 0x4f0a;
1055 +- bx = di = 0;
1056 +- asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
1057 +- : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
1058 +- : : "ecx", "esi");
1059 ++ bx = cx = di = 0;
1060 ++ asm volatile("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
1061 ++ : "=d" (es), "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di)
1062 ++ : : "esi");
1063 +
1064 + if (ax != 0x004f)
1065 + return;
1066 +
1067 + boot_params.screen_info.vesapm_seg = es;
1068 + boot_params.screen_info.vesapm_off = di;
1069 ++ boot_params.screen_info.vesapm_size = cx;
1070 + }
1071 +
1072 + /*
1073 +@@ -259,7 +260,7 @@ void vesa_store_edid(void)
1074 + /* Note: The VBE DDC spec is different from the main VESA spec;
1075 + we genuinely have to assume all registers are destroyed here. */
1076 +
1077 +- asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
1078 ++ asm volatile("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
1079 + : "+a" (ax), "+b" (bx)
1080 + : "c" (cx), "D" (di)
1081 + : "esi");
1082 +@@ -275,7 +276,7 @@ void vesa_store_edid(void)
1083 + cx = 0; /* Controller 0 */
1084 + dx = 0; /* EDID block number */
1085 + di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
1086 +- asm(INT10
1087 ++ asm volatile(INT10
1088 + : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info)
1089 + : "c" (cx), "D" (di)
1090 + : "esi");
1091 +diff -Nurp linux-2.6.23.15/arch/i386/boot/video-vga.c linux-2.6.23.15-grsec/arch/i386/boot/video-vga.c
1092 +--- linux-2.6.23.15/arch/i386/boot/video-vga.c 2007-10-09 21:31:38.000000000 +0100
1093 ++++ linux-2.6.23.15-grsec/arch/i386/boot/video-vga.c 2008-02-11 10:37:44.000000000 +0000
1094 +@@ -225,7 +225,7 @@ static int vga_probe(void)
1095 + };
1096 + u8 vga_flag;
1097 +
1098 +- asm(INT10
1099 ++ asm volatile(INT10
1100 + : "=b" (boot_params.screen_info.orig_video_ega_bx)
1101 + : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
1102 + : "ecx", "edx", "esi", "edi");
1103 +@@ -233,7 +233,7 @@ static int vga_probe(void)
1104 + /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
1105 + if ((u8)boot_params.screen_info.orig_video_ega_bx != 0x10) {
1106 + /* EGA/VGA */
1107 +- asm(INT10
1108 ++ asm volatile(INT10
1109 + : "=a" (vga_flag)
1110 + : "a" (0x1a00)
1111 + : "ebx", "ecx", "edx", "esi", "edi");
1112 +diff -Nurp linux-2.6.23.15/arch/i386/boot/video.c linux-2.6.23.15-grsec/arch/i386/boot/video.c
1113 +--- linux-2.6.23.15/arch/i386/boot/video.c 2008-02-11 10:36:03.000000000 +0000
1114 ++++ linux-2.6.23.15-grsec/arch/i386/boot/video.c 2008-02-11 10:37:44.000000000 +0000
1115 +@@ -40,7 +40,7 @@ static void store_cursor_position(void)
1116 +
1117 + ax = 0x0300;
1118 + bx = 0;
1119 +- asm(INT10
1120 ++ asm volatile(INT10
1121 + : "=d" (curpos), "+a" (ax), "+b" (bx)
1122 + : : "ecx", "esi", "edi");
1123 +
1124 +@@ -55,7 +55,7 @@ static void store_video_mode(void)
1125 + /* N.B.: the saving of the video page here is a bit silly,
1126 + since we pretty much assume page 0 everywhere. */
1127 + ax = 0x0f00;
1128 +- asm(INT10
1129 ++ asm volatile(INT10
1130 + : "+a" (ax), "=b" (page)
1131 + : : "ecx", "edx", "esi", "edi");
1132 +
1133 +diff -Nurp linux-2.6.23.15/arch/i386/boot/voyager.c linux-2.6.23.15-grsec/arch/i386/boot/voyager.c
1134 +--- linux-2.6.23.15/arch/i386/boot/voyager.c 2007-10-09 21:31:38.000000000 +0100
1135 ++++ linux-2.6.23.15-grsec/arch/i386/boot/voyager.c 2008-02-11 10:37:44.000000000 +0000
1136 +@@ -27,7 +27,7 @@ int query_voyager(void)
1137 +
1138 + data_ptr[0] = 0xff; /* Flag on config not found(?) */
1139 +
1140 +- asm("pushw %%es ; "
1141 ++ asm volatile("pushw %%es ; "
1142 + "int $0x15 ; "
1143 + "setc %0 ; "
1144 + "movw %%es, %1 ; "
1145 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/acpi/boot.c linux-2.6.23.15-grsec/arch/i386/kernel/acpi/boot.c
1146 +--- linux-2.6.23.15/arch/i386/kernel/acpi/boot.c 2007-10-09 21:31:38.000000000 +0100
1147 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/acpi/boot.c 2008-02-11 10:37:44.000000000 +0000
1148 +@@ -1123,7 +1123,7 @@ static struct dmi_system_id __initdata a
1149 + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
1150 + },
1151 + },
1152 +- {}
1153 ++ { NULL, NULL, {{0, NULL}}, NULL}
1154 + };
1155 +
1156 + #endif /* __i386__ */
1157 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/acpi/sleep.c linux-2.6.23.15-grsec/arch/i386/kernel/acpi/sleep.c
1158 +--- linux-2.6.23.15/arch/i386/kernel/acpi/sleep.c 2007-10-09 21:31:38.000000000 +0100
1159 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/acpi/sleep.c 2008-02-11 10:37:44.000000000 +0000
1160 +@@ -98,7 +98,7 @@ static __initdata struct dmi_system_id a
1161 + DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
1162 + },
1163 + },
1164 +- {}
1165 ++ { NULL, NULL, {{0, NULL}}, NULL}
1166 + };
1167 +
1168 + static int __init acpisleep_dmi_init(void)
1169 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/acpi/wakeup.S linux-2.6.23.15-grsec/arch/i386/kernel/acpi/wakeup.S
1170 +--- linux-2.6.23.15/arch/i386/kernel/acpi/wakeup.S 2007-10-09 21:31:38.000000000 +0100
1171 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/acpi/wakeup.S 2008-02-11 10:37:44.000000000 +0000
1172 +@@ -2,6 +2,7 @@
1173 + #include <linux/linkage.h>
1174 + #include <asm/segment.h>
1175 + #include <asm/page.h>
1176 ++#include <asm/msr-index.h>
1177 +
1178 + #
1179 + # wakeup_code runs in real mode, and at unknown address (determined at run-time).
1180 +@@ -84,7 +85,7 @@ wakeup_code:
1181 + # restore efer setting
1182 + movl real_save_efer_edx - wakeup_code, %edx
1183 + movl real_save_efer_eax - wakeup_code, %eax
1184 +- mov $0xc0000080, %ecx
1185 ++ mov $MSR_EFER, %ecx
1186 + wrmsr
1187 + 4:
1188 + # make sure %cr4 is set correctly (features, etc)
1189 +@@ -209,13 +210,11 @@ wakeup_pmode_return:
1190 + # and restore the stack ... but you need gdt for this to work
1191 + movl saved_context_esp, %esp
1192 +
1193 +- movl %cs:saved_magic, %eax
1194 +- cmpl $0x12345678, %eax
1195 ++ cmpl $0x12345678, saved_magic
1196 + jne bogus_magic
1197 +
1198 + # jump to place where we left off
1199 +- movl saved_eip,%eax
1200 +- jmp *%eax
1201 ++ jmp *(saved_eip)
1202 +
1203 + bogus_magic:
1204 + movw $0x0e00 + 'B', 0xb8018
1205 +@@ -247,7 +246,7 @@ ENTRY(acpi_copy_wakeup_routine)
1206 + # save efer setting
1207 + pushl %eax
1208 + movl %eax, %ebx
1209 +- mov $0xc0000080, %ecx
1210 ++ mov $MSR_EFER, %ecx
1211 + rdmsr
1212 + movl %edx, real_save_efer_edx - wakeup_start (%ebx)
1213 + movl %eax, real_save_efer_eax - wakeup_start (%ebx)
1214 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/alternative.c linux-2.6.23.15-grsec/arch/i386/kernel/alternative.c
1215 +--- linux-2.6.23.15/arch/i386/kernel/alternative.c 2007-10-09 21:31:38.000000000 +0100
1216 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/alternative.c 2008-02-11 10:37:44.000000000 +0000
1217 +@@ -443,7 +443,20 @@ void __init alternative_instructions(voi
1218 + */
1219 + void __kprobes text_poke(void *addr, unsigned char *opcode, int len)
1220 + {
1221 ++
1222 ++#ifdef CONFIG_PAX_KERNEXEC
1223 ++ unsigned long cr0;
1224 ++
1225 ++ pax_open_kernel(cr0);
1226 ++#endif
1227 ++
1228 ++ addr += __KERNEL_TEXT_OFFSET;
1229 + memcpy(addr, opcode, len);
1230 ++
1231 ++#ifdef CONFIG_PAX_KERNEXEC
1232 ++ pax_close_kernel(cr0);
1233 ++#endif
1234 ++
1235 + sync_core();
1236 + /* Could also do a CLFLUSH here to speed up CPU recovery; but
1237 + that causes hangs on some VIA CPUs. */
1238 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/apm.c linux-2.6.23.15-grsec/arch/i386/kernel/apm.c
1239 +--- linux-2.6.23.15/arch/i386/kernel/apm.c 2008-02-11 10:36:03.000000000 +0000
1240 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/apm.c 2008-02-11 10:37:44.000000000 +0000
1241 +@@ -407,7 +407,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitq
1242 + static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
1243 + static struct apm_user * user_list;
1244 + static DEFINE_SPINLOCK(user_list_lock);
1245 +-static const struct desc_struct bad_bios_desc = { 0, 0x00409200 };
1246 ++static const struct desc_struct bad_bios_desc = { 0, 0x00409300 };
1247 +
1248 + static const char driver_version[] = "1.16ac"; /* no spaces */
1249 +
1250 +@@ -601,19 +601,42 @@ static u8 apm_bios_call(u32 func, u32 eb
1251 + struct desc_struct save_desc_40;
1252 + struct desc_struct *gdt;
1253 +
1254 ++#ifdef CONFIG_PAX_KERNEXEC
1255 ++ unsigned long cr0;
1256 ++#endif
1257 ++
1258 + cpus = apm_save_cpus();
1259 +
1260 + cpu = get_cpu();
1261 + gdt = get_cpu_gdt_table(cpu);
1262 + save_desc_40 = gdt[0x40 / 8];
1263 ++
1264 ++#ifdef CONFIG_PAX_KERNEXEC
1265 ++ pax_open_kernel(cr0);
1266 ++#endif
1267 ++
1268 + gdt[0x40 / 8] = bad_bios_desc;
1269 +
1270 ++#ifdef CONFIG_PAX_KERNEXEC
1271 ++ pax_close_kernel(cr0);
1272 ++#endif
1273 ++
1274 + apm_irq_save(flags);
1275 + APM_DO_SAVE_SEGS;
1276 + apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
1277 + APM_DO_RESTORE_SEGS;
1278 + apm_irq_restore(flags);
1279 ++
1280 ++#ifdef CONFIG_PAX_KERNEXEC
1281 ++ pax_open_kernel(cr0);
1282 ++#endif
1283 ++
1284 + gdt[0x40 / 8] = save_desc_40;
1285 ++
1286 ++#ifdef CONFIG_PAX_KERNEXEC
1287 ++ pax_close_kernel(cr0);
1288 ++#endif
1289 ++
1290 + put_cpu();
1291 + apm_restore_cpus(cpus);
1292 +
1293 +@@ -644,19 +667,42 @@ static u8 apm_bios_call_simple(u32 func,
1294 + struct desc_struct save_desc_40;
1295 + struct desc_struct *gdt;
1296 +
1297 ++#ifdef CONFIG_PAX_KERNEXEC
1298 ++ unsigned long cr0;
1299 ++#endif
1300 ++
1301 + cpus = apm_save_cpus();
1302 +
1303 + cpu = get_cpu();
1304 + gdt = get_cpu_gdt_table(cpu);
1305 + save_desc_40 = gdt[0x40 / 8];
1306 ++
1307 ++#ifdef CONFIG_PAX_KERNEXEC
1308 ++ pax_open_kernel(cr0);
1309 ++#endif
1310 ++
1311 + gdt[0x40 / 8] = bad_bios_desc;
1312 +
1313 ++#ifdef CONFIG_PAX_KERNEXEC
1314 ++ pax_close_kernel(cr0);
1315 ++#endif
1316 ++
1317 + apm_irq_save(flags);
1318 + APM_DO_SAVE_SEGS;
1319 + error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
1320 + APM_DO_RESTORE_SEGS;
1321 + apm_irq_restore(flags);
1322 ++
1323 ++#ifdef CONFIG_PAX_KERNEXEC
1324 ++ pax_open_kernel(cr0);
1325 ++#endif
1326 ++
1327 + gdt[0x40 / 8] = save_desc_40;
1328 ++
1329 ++#ifdef CONFIG_PAX_KERNEXEC
1330 ++ pax_close_kernel(cr0);
1331 ++#endif
1332 ++
1333 + put_cpu();
1334 + apm_restore_cpus(cpus);
1335 + return error;
1336 +@@ -924,7 +970,7 @@ recalc:
1337 +
1338 + static void apm_power_off(void)
1339 + {
1340 +- unsigned char po_bios_call[] = {
1341 ++ const unsigned char po_bios_call[] = {
1342 + 0xb8, 0x00, 0x10, /* movw $0x1000,ax */
1343 + 0x8e, 0xd0, /* movw ax,ss */
1344 + 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */
1345 +@@ -1864,7 +1910,10 @@ static const struct file_operations apm_
1346 + static struct miscdevice apm_device = {
1347 + APM_MINOR_DEV,
1348 + "apm_bios",
1349 +- &apm_bios_fops
1350 ++ &apm_bios_fops,
1351 ++ {NULL, NULL},
1352 ++ NULL,
1353 ++ NULL
1354 + };
1355 +
1356 +
1357 +@@ -1974,210 +2023,210 @@ static struct dmi_system_id __initdata a
1358 + print_if_true,
1359 + KERN_WARNING "IBM T23 - BIOS 1.03b+ and controller firmware 1.02+ may be needed for Linux APM.",
1360 + { DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
1361 +- DMI_MATCH(DMI_BIOS_VERSION, "1AET38WW (1.01b)"), },
1362 ++ DMI_MATCH(DMI_BIOS_VERSION, "1AET38WW (1.01b)"), }, NULL
1363 + },
1364 + { /* Handle problems with APM on the C600 */
1365 + broken_ps2_resume, "Dell Latitude C600",
1366 + { DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
1367 +- DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C600"), },
1368 ++ DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C600"), }, NULL
1369 + },
1370 + { /* Allow interrupts during suspend on Dell Latitude laptops*/
1371 + set_apm_ints, "Dell Latitude",
1372 + { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
1373 +- DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C510"), }
1374 ++ DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C510"), }, NULL
1375 + },
1376 + { /* APM crashes */
1377 + apm_is_horked, "Dell Inspiron 2500",
1378 + { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
1379 + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"),
1380 + DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
1381 +- DMI_MATCH(DMI_BIOS_VERSION,"A11"), },
1382 ++ DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, NULL
1383 + },
1384 + { /* Allow interrupts during suspend on Dell Inspiron laptops*/
1385 + set_apm_ints, "Dell Inspiron", {
1386 + DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
1387 +- DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 4000"), },
1388 ++ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 4000"), }, NULL
1389 + },
1390 + { /* Handle problems with APM on Inspiron 5000e */
1391 + broken_apm_power, "Dell Inspiron 5000e",
1392 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
1393 + DMI_MATCH(DMI_BIOS_VERSION, "A04"),
1394 +- DMI_MATCH(DMI_BIOS_DATE, "08/24/2000"), },
1395 ++ DMI_MATCH(DMI_BIOS_DATE, "08/24/2000"), }, NULL
1396 + },
1397 + { /* Handle problems with APM on Inspiron 2500 */
1398 + broken_apm_power, "Dell Inspiron 2500",
1399 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
1400 + DMI_MATCH(DMI_BIOS_VERSION, "A12"),
1401 +- DMI_MATCH(DMI_BIOS_DATE, "02/04/2002"), },
1402 ++ DMI_MATCH(DMI_BIOS_DATE, "02/04/2002"), }, NULL
1403 + },
1404 + { /* APM crashes */
1405 + apm_is_horked, "Dell Dimension 4100",
1406 + { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
1407 + DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"),
1408 + DMI_MATCH(DMI_BIOS_VENDOR,"Intel Corp."),
1409 +- DMI_MATCH(DMI_BIOS_VERSION,"A11"), },
1410 ++ DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, NULL
1411 + },
1412 + { /* Allow interrupts during suspend on Compaq Laptops*/
1413 + set_apm_ints, "Compaq 12XL125",
1414 + { DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
1415 + DMI_MATCH(DMI_PRODUCT_NAME, "Compaq PC"),
1416 + DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
1417 +- DMI_MATCH(DMI_BIOS_VERSION,"4.06"), },
1418 ++ DMI_MATCH(DMI_BIOS_VERSION,"4.06"), }, NULL
1419 + },
1420 + { /* Allow interrupts during APM or the clock goes slow */
1421 + set_apm_ints, "ASUSTeK",
1422 + { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
1423 +- DMI_MATCH(DMI_PRODUCT_NAME, "L8400K series Notebook PC"), },
1424 ++ DMI_MATCH(DMI_PRODUCT_NAME, "L8400K series Notebook PC"), }, NULL
1425 + },
1426 + { /* APM blows on shutdown */
1427 + apm_is_horked, "ABIT KX7-333[R]",
1428 + { DMI_MATCH(DMI_BOARD_VENDOR, "ABIT"),
1429 +- DMI_MATCH(DMI_BOARD_NAME, "VT8367-8233A (KX7-333[R])"), },
1430 ++ DMI_MATCH(DMI_BOARD_NAME, "VT8367-8233A (KX7-333[R])"), }, NULL
1431 + },
1432 + { /* APM crashes */
1433 + apm_is_horked, "Trigem Delhi3",
1434 + { DMI_MATCH(DMI_SYS_VENDOR, "TriGem Computer, Inc"),
1435 +- DMI_MATCH(DMI_PRODUCT_NAME, "Delhi3"), },
1436 ++ DMI_MATCH(DMI_PRODUCT_NAME, "Delhi3"), }, NULL
1437 + },
1438 + { /* APM crashes */
1439 + apm_is_horked, "Fujitsu-Siemens",
1440 + { DMI_MATCH(DMI_BIOS_VENDOR, "hoenix/FUJITSU SIEMENS"),
1441 +- DMI_MATCH(DMI_BIOS_VERSION, "Version1.01"), },
1442 ++ DMI_MATCH(DMI_BIOS_VERSION, "Version1.01"), }, NULL
1443 + },
1444 + { /* APM crashes */
1445 + apm_is_horked_d850md, "Intel D850MD",
1446 + { DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
1447 +- DMI_MATCH(DMI_BIOS_VERSION, "MV85010A.86A.0016.P07.0201251536"), },
1448 ++ DMI_MATCH(DMI_BIOS_VERSION, "MV85010A.86A.0016.P07.0201251536"), }, NULL
1449 + },
1450 + { /* APM crashes */
1451 + apm_is_horked, "Intel D810EMO",
1452 + { DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
1453 +- DMI_MATCH(DMI_BIOS_VERSION, "MO81010A.86A.0008.P04.0004170800"), },
1454 ++ DMI_MATCH(DMI_BIOS_VERSION, "MO81010A.86A.0008.P04.0004170800"), }, NULL
1455 + },
1456 + { /* APM crashes */
1457 + apm_is_horked, "Dell XPS-Z",
1458 + { DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
1459 + DMI_MATCH(DMI_BIOS_VERSION, "A11"),
1460 +- DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"), },
1461 ++ DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"), }, NULL
1462 + },
1463 + { /* APM crashes */
1464 + apm_is_horked, "Sharp PC-PJ/AX",
1465 + { DMI_MATCH(DMI_SYS_VENDOR, "SHARP"),
1466 + DMI_MATCH(DMI_PRODUCT_NAME, "PC-PJ/AX"),
1467 + DMI_MATCH(DMI_BIOS_VENDOR,"SystemSoft"),
1468 +- DMI_MATCH(DMI_BIOS_VERSION,"Version R2.08"), },
1469 ++ DMI_MATCH(DMI_BIOS_VERSION,"Version R2.08"), }, NULL
1470 + },
1471 + { /* APM crashes */
1472 + apm_is_horked, "Dell Inspiron 2500",
1473 + { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
1474 + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"),
1475 + DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
1476 +- DMI_MATCH(DMI_BIOS_VERSION,"A11"), },
1477 ++ DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, NULL
1478 + },
1479 + { /* APM idle hangs */
1480 + apm_likes_to_melt, "Jabil AMD",
1481 + { DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
1482 +- DMI_MATCH(DMI_BIOS_VERSION, "0AASNP06"), },
1483 ++ DMI_MATCH(DMI_BIOS_VERSION, "0AASNP06"), }, NULL
1484 + },
1485 + { /* APM idle hangs */
1486 + apm_likes_to_melt, "AMI Bios",
1487 + { DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
1488 +- DMI_MATCH(DMI_BIOS_VERSION, "0AASNP05"), },
1489 ++ DMI_MATCH(DMI_BIOS_VERSION, "0AASNP05"), }, NULL
1490 + },
1491 + { /* Handle problems with APM on Sony Vaio PCG-N505X(DE) */
1492 + swab_apm_power_in_minutes, "Sony VAIO",
1493 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
1494 + DMI_MATCH(DMI_BIOS_VERSION, "R0206H"),
1495 +- DMI_MATCH(DMI_BIOS_DATE, "08/23/99"), },
1496 ++ DMI_MATCH(DMI_BIOS_DATE, "08/23/99"), }, NULL
1497 + },
1498 + { /* Handle problems with APM on Sony Vaio PCG-N505VX */
1499 + swab_apm_power_in_minutes, "Sony VAIO",
1500 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
1501 + DMI_MATCH(DMI_BIOS_VERSION, "W2K06H0"),
1502 +- DMI_MATCH(DMI_BIOS_DATE, "02/03/00"), },
1503 ++ DMI_MATCH(DMI_BIOS_DATE, "02/03/00"), }, NULL
1504 + },
1505 + { /* Handle problems with APM on Sony Vaio PCG-XG29 */
1506 + swab_apm_power_in_minutes, "Sony VAIO",
1507 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
1508 + DMI_MATCH(DMI_BIOS_VERSION, "R0117A0"),
1509 +- DMI_MATCH(DMI_BIOS_DATE, "04/25/00"), },
1510 ++ DMI_MATCH(DMI_BIOS_DATE, "04/25/00"), }, NULL
1511 + },
1512 + { /* Handle problems with APM on Sony Vaio PCG-Z600NE */
1513 + swab_apm_power_in_minutes, "Sony VAIO",
1514 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
1515 + DMI_MATCH(DMI_BIOS_VERSION, "R0121Z1"),
1516 +- DMI_MATCH(DMI_BIOS_DATE, "05/11/00"), },
1517 ++ DMI_MATCH(DMI_BIOS_DATE, "05/11/00"), }, NULL
1518 + },
1519 + { /* Handle problems with APM on Sony Vaio PCG-Z600NE */
1520 + swab_apm_power_in_minutes, "Sony VAIO",
1521 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
1522 + DMI_MATCH(DMI_BIOS_VERSION, "WME01Z1"),
1523 +- DMI_MATCH(DMI_BIOS_DATE, "08/11/00"), },
1524 ++ DMI_MATCH(DMI_BIOS_DATE, "08/11/00"), }, NULL
1525 + },
1526 + { /* Handle problems with APM on Sony Vaio PCG-Z600LEK(DE) */
1527 + swab_apm_power_in_minutes, "Sony VAIO",
1528 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
1529 + DMI_MATCH(DMI_BIOS_VERSION, "R0206Z3"),
1530 +- DMI_MATCH(DMI_BIOS_DATE, "12/25/00"), },
1531 ++ DMI_MATCH(DMI_BIOS_DATE, "12/25/00"), }, NULL
1532 + },
1533 + { /* Handle problems with APM on Sony Vaio PCG-Z505LS */
1534 + swab_apm_power_in_minutes, "Sony VAIO",
1535 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
1536 + DMI_MATCH(DMI_BIOS_VERSION, "R0203D0"),
1537 +- DMI_MATCH(DMI_BIOS_DATE, "05/12/00"), },
1538 ++ DMI_MATCH(DMI_BIOS_DATE, "05/12/00"), }, NULL
1539 + },
1540 + { /* Handle problems with APM on Sony Vaio PCG-Z505LS */
1541 + swab_apm_power_in_minutes, "Sony VAIO",
1542 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
1543 + DMI_MATCH(DMI_BIOS_VERSION, "R0203Z3"),
1544 +- DMI_MATCH(DMI_BIOS_DATE, "08/25/00"), },
1545 ++ DMI_MATCH(DMI_BIOS_DATE, "08/25/00"), }, NULL
1546 + },
1547 + { /* Handle problems with APM on Sony Vaio PCG-Z505LS (with updated BIOS) */
1548 + swab_apm_power_in_minutes, "Sony VAIO",
1549 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
1550 + DMI_MATCH(DMI_BIOS_VERSION, "R0209Z3"),
1551 +- DMI_MATCH(DMI_BIOS_DATE, "05/12/01"), },
1552 ++ DMI_MATCH(DMI_BIOS_DATE, "05/12/01"), }, NULL
1553 + },
1554 + { /* Handle problems with APM on Sony Vaio PCG-F104K */
1555 + swab_apm_power_in_minutes, "Sony VAIO",
1556 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
1557 + DMI_MATCH(DMI_BIOS_VERSION, "R0204K2"),
1558 +- DMI_MATCH(DMI_BIOS_DATE, "08/28/00"), },
1559 ++ DMI_MATCH(DMI_BIOS_DATE, "08/28/00"), }, NULL
1560 + },
1561 +
1562 + { /* Handle problems with APM on Sony Vaio PCG-C1VN/C1VE */
1563 + swab_apm_power_in_minutes, "Sony VAIO",
1564 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
1565 + DMI_MATCH(DMI_BIOS_VERSION, "R0208P1"),
1566 +- DMI_MATCH(DMI_BIOS_DATE, "11/09/00"), },
1567 ++ DMI_MATCH(DMI_BIOS_DATE, "11/09/00"), }, NULL
1568 + },
1569 + { /* Handle problems with APM on Sony Vaio PCG-C1VE */
1570 + swab_apm_power_in_minutes, "Sony VAIO",
1571 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
1572 + DMI_MATCH(DMI_BIOS_VERSION, "R0204P1"),
1573 +- DMI_MATCH(DMI_BIOS_DATE, "09/12/00"), },
1574 ++ DMI_MATCH(DMI_BIOS_DATE, "09/12/00"), }, NULL
1575 + },
1576 + { /* Handle problems with APM on Sony Vaio PCG-C1VE */
1577 + swab_apm_power_in_minutes, "Sony VAIO",
1578 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
1579 + DMI_MATCH(DMI_BIOS_VERSION, "WXPO1Z3"),
1580 +- DMI_MATCH(DMI_BIOS_DATE, "10/26/01"), },
1581 ++ DMI_MATCH(DMI_BIOS_DATE, "10/26/01"), }, NULL
1582 + },
1583 + { /* broken PM poweroff bios */
1584 + set_realmode_power_off, "Award Software v4.60 PGMA",
1585 + { DMI_MATCH(DMI_BIOS_VENDOR, "Award Software International, Inc."),
1586 + DMI_MATCH(DMI_BIOS_VERSION, "4.60 PGMA"),
1587 +- DMI_MATCH(DMI_BIOS_DATE, "134526184"), },
1588 ++ DMI_MATCH(DMI_BIOS_DATE, "134526184"), }, NULL
1589 + },
1590 +
1591 + /* Generic per vendor APM settings */
1592 +
1593 + { /* Allow interrupts during suspend on IBM laptops */
1594 + set_apm_ints, "IBM",
1595 +- { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
1596 ++ { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), }, NULL
1597 + },
1598 +
1599 +- { }
1600 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
1601 + };
1602 +
1603 + /*
1604 +@@ -2196,6 +2245,10 @@ static int __init apm_init(void)
1605 + struct desc_struct *gdt;
1606 + int err;
1607 +
1608 ++#ifdef CONFIG_PAX_KERNEXEC
1609 ++ unsigned long cr0;
1610 ++#endif
1611 ++
1612 + dmi_check_system(apm_dmi_table);
1613 +
1614 + if (apm_info.bios.version == 0 || paravirt_enabled()) {
1615 +@@ -2269,9 +2322,18 @@ static int __init apm_init(void)
1616 + * This is for buggy BIOS's that refer to (real mode) segment 0x40
1617 + * even though they are called in protected mode.
1618 + */
1619 ++
1620 ++#ifdef CONFIG_PAX_KERNEXEC
1621 ++ pax_open_kernel(cr0);
1622 ++#endif
1623 ++
1624 + set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
1625 + _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
1626 +
1627 ++#ifdef CONFIG_PAX_KERNEXEC
1628 ++ pax_close_kernel(cr0);
1629 ++#endif
1630 ++
1631 + /*
1632 + * Set up the long jump entry point to the APM BIOS, which is called
1633 + * from inline assembly.
1634 +@@ -2290,6 +2352,11 @@ static int __init apm_init(void)
1635 + * code to that CPU.
1636 + */
1637 + gdt = get_cpu_gdt_table(0);
1638 ++
1639 ++#ifdef CONFIG_PAX_KERNEXEC
1640 ++ pax_open_kernel(cr0);
1641 ++#endif
1642 ++
1643 + set_base(gdt[APM_CS >> 3],
1644 + __va((unsigned long)apm_info.bios.cseg << 4));
1645 + set_base(gdt[APM_CS_16 >> 3],
1646 +@@ -2297,6 +2364,10 @@ static int __init apm_init(void)
1647 + set_base(gdt[APM_DS >> 3],
1648 + __va((unsigned long)apm_info.bios.dseg << 4));
1649 +
1650 ++#ifdef CONFIG_PAX_KERNEXEC
1651 ++ pax_close_kernel(cr0);
1652 ++#endif
1653 ++
1654 + apm_proc = create_proc_entry("apm", 0, NULL);
1655 + if (apm_proc)
1656 + apm_proc->proc_fops = &apm_file_ops;
1657 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/asm-offsets.c linux-2.6.23.15-grsec/arch/i386/kernel/asm-offsets.c
1658 +--- linux-2.6.23.15/arch/i386/kernel/asm-offsets.c 2007-10-09 21:31:38.000000000 +0100
1659 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/asm-offsets.c 2008-02-11 10:37:44.000000000 +0000
1660 +@@ -109,6 +109,7 @@ void foo(void)
1661 + DEFINE(PTRS_PER_PTE, PTRS_PER_PTE);
1662 + DEFINE(PTRS_PER_PMD, PTRS_PER_PMD);
1663 + DEFINE(PTRS_PER_PGD, PTRS_PER_PGD);
1664 ++ DEFINE(PERCPU_MODULE_RESERVE, PERCPU_MODULE_RESERVE);
1665 +
1666 + DEFINE(VDSO_PRELINK_asm, VDSO_PRELINK);
1667 +
1668 +@@ -122,6 +123,7 @@ void foo(void)
1669 + OFFSET(PARAVIRT_irq_enable_sysexit, paravirt_ops, irq_enable_sysexit);
1670 + OFFSET(PARAVIRT_iret, paravirt_ops, iret);
1671 + OFFSET(PARAVIRT_read_cr0, paravirt_ops, read_cr0);
1672 ++ OFFSET(PARAVIRT_write_cr0, paravirt_ops, write_cr0);
1673 + #endif
1674 +
1675 + #ifdef CONFIG_XEN
1676 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/cpu/common.c linux-2.6.23.15-grsec/arch/i386/kernel/cpu/common.c
1677 +--- linux-2.6.23.15/arch/i386/kernel/cpu/common.c 2007-10-09 21:31:38.000000000 +0100
1678 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/cpu/common.c 2008-02-11 10:37:44.000000000 +0000
1679 +@@ -4,7 +4,6 @@
1680 + #include <linux/smp.h>
1681 + #include <linux/module.h>
1682 + #include <linux/percpu.h>
1683 +-#include <linux/bootmem.h>
1684 + #include <asm/semaphore.h>
1685 + #include <asm/processor.h>
1686 + #include <asm/i387.h>
1687 +@@ -21,39 +20,15 @@
1688 +
1689 + #include "cpu.h"
1690 +
1691 +-DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
1692 +- [GDT_ENTRY_KERNEL_CS] = { 0x0000ffff, 0x00cf9a00 },
1693 +- [GDT_ENTRY_KERNEL_DS] = { 0x0000ffff, 0x00cf9200 },
1694 +- [GDT_ENTRY_DEFAULT_USER_CS] = { 0x0000ffff, 0x00cffa00 },
1695 +- [GDT_ENTRY_DEFAULT_USER_DS] = { 0x0000ffff, 0x00cff200 },
1696 +- /*
1697 +- * Segments used for calling PnP BIOS have byte granularity.
1698 +- * They code segments and data segments have fixed 64k limits,
1699 +- * the transfer segment sizes are set at run time.
1700 +- */
1701 +- [GDT_ENTRY_PNPBIOS_CS32] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */
1702 +- [GDT_ENTRY_PNPBIOS_CS16] = { 0x0000ffff, 0x00009a00 },/* 16-bit code */
1703 +- [GDT_ENTRY_PNPBIOS_DS] = { 0x0000ffff, 0x00009200 }, /* 16-bit data */
1704 +- [GDT_ENTRY_PNPBIOS_TS1] = { 0x00000000, 0x00009200 },/* 16-bit data */
1705 +- [GDT_ENTRY_PNPBIOS_TS2] = { 0x00000000, 0x00009200 },/* 16-bit data */
1706 +- /*
1707 +- * The APM segments have byte granularity and their bases
1708 +- * are set at run time. All have 64k limits.
1709 +- */
1710 +- [GDT_ENTRY_APMBIOS_BASE] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */
1711 +- /* 16-bit code */
1712 +- [GDT_ENTRY_APMBIOS_BASE+1] = { 0x0000ffff, 0x00009a00 },
1713 +- [GDT_ENTRY_APMBIOS_BASE+2] = { 0x0000ffff, 0x00409200 }, /* data */
1714 +-
1715 +- [GDT_ENTRY_ESPFIX_SS] = { 0x00000000, 0x00c09200 },
1716 +- [GDT_ENTRY_PERCPU] = { 0x00000000, 0x00000000 },
1717 +-} };
1718 +-EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
1719 +-
1720 + static int cachesize_override __cpuinitdata = -1;
1721 + static int disable_x86_fxsr __cpuinitdata;
1722 + static int disable_x86_serial_nr __cpuinitdata = 1;
1723 +-static int disable_x86_sep __cpuinitdata;
1724 ++
1725 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
1726 ++int disable_x86_sep __cpuinitdata = 1;
1727 ++#else
1728 ++int disable_x86_sep __cpuinitdata;
1729 ++#endif
1730 +
1731 + struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
1732 +
1733 +@@ -261,10 +236,10 @@ static int __cpuinit have_cpuid_p(void)
1734 + void __init cpu_detect(struct cpuinfo_x86 *c)
1735 + {
1736 + /* Get vendor name */
1737 +- cpuid(0x00000000, &c->cpuid_level,
1738 +- (int *)&c->x86_vendor_id[0],
1739 +- (int *)&c->x86_vendor_id[8],
1740 +- (int *)&c->x86_vendor_id[4]);
1741 ++ cpuid(0x00000000, (unsigned int *)&c->cpuid_level,
1742 ++ (unsigned int *)&c->x86_vendor_id[0],
1743 ++ (unsigned int *)&c->x86_vendor_id[8],
1744 ++ (unsigned int *)&c->x86_vendor_id[4]);
1745 +
1746 + c->x86 = 4;
1747 + if (c->cpuid_level >= 0x00000001) {
1748 +@@ -304,15 +279,14 @@ static void __init early_cpu_detect(void
1749 +
1750 + static void __cpuinit generic_identify(struct cpuinfo_x86 * c)
1751 + {
1752 +- u32 tfms, xlvl;
1753 +- int ebx;
1754 ++ u32 tfms, xlvl, ebx;
1755 +
1756 + if (have_cpuid_p()) {
1757 + /* Get vendor name */
1758 +- cpuid(0x00000000, &c->cpuid_level,
1759 +- (int *)&c->x86_vendor_id[0],
1760 +- (int *)&c->x86_vendor_id[8],
1761 +- (int *)&c->x86_vendor_id[4]);
1762 ++ cpuid(0x00000000, (unsigned int *)&c->cpuid_level,
1763 ++ (unsigned int *)&c->x86_vendor_id[0],
1764 ++ (unsigned int *)&c->x86_vendor_id[8],
1765 ++ (unsigned int *)&c->x86_vendor_id[4]);
1766 +
1767 + get_cpu_vendor(c, 0);
1768 + /* Initialize the standard set of capabilities */
1769 +@@ -644,7 +618,7 @@ void switch_to_new_gdt(void)
1770 + {
1771 + struct Xgt_desc_struct gdt_descr;
1772 +
1773 +- gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
1774 ++ gdt_descr.address = get_cpu_gdt_table(smp_processor_id());
1775 + gdt_descr.size = GDT_SIZE - 1;
1776 + load_gdt(&gdt_descr);
1777 + asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory");
1778 +@@ -660,7 +634,7 @@ void __cpuinit cpu_init(void)
1779 + {
1780 + int cpu = smp_processor_id();
1781 + struct task_struct *curr = current;
1782 +- struct tss_struct * t = &per_cpu(init_tss, cpu);
1783 ++ struct tss_struct *t = init_tss + cpu;
1784 + struct thread_struct *thread = &curr->thread;
1785 +
1786 + if (cpu_test_and_set(cpu, cpu_initialized)) {
1787 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c linux-2.6.23.15-grsec/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
1788 +--- linux-2.6.23.15/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c 2007-10-09 21:31:38.000000000 +0100
1789 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-02-11 10:37:44.000000000 +0000
1790 +@@ -549,7 +549,7 @@ static struct dmi_system_id sw_any_bug_d
1791 + DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
1792 + },
1793 + },
1794 +- { }
1795 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
1796 + };
1797 + #endif
1798 +
1799 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c linux-2.6.23.15-grsec/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
1800 +--- linux-2.6.23.15/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c 2007-10-09 21:31:38.000000000 +0100
1801 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c 2008-02-11 10:37:44.000000000 +0000
1802 +@@ -223,7 +223,7 @@ static struct cpu_model models[] =
1803 + { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
1804 + { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
1805 +
1806 +- { NULL, }
1807 ++ { NULL, NULL, 0, NULL}
1808 + };
1809 + #undef _BANIAS
1810 + #undef BANIAS
1811 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/cpu/intel_cacheinfo.c linux-2.6.23.15-grsec/arch/i386/kernel/cpu/intel_cacheinfo.c
1812 +--- linux-2.6.23.15/arch/i386/kernel/cpu/intel_cacheinfo.c 2007-10-09 21:31:38.000000000 +0100
1813 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/cpu/intel_cacheinfo.c 2008-02-11 10:37:44.000000000 +0000
1814 +@@ -351,8 +351,8 @@ unsigned int __cpuinit init_intel_cachei
1815 + */
1816 + if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) {
1817 + /* supports eax=2 call */
1818 +- int i, j, n;
1819 +- int regs[4];
1820 ++ int j, n;
1821 ++ unsigned int regs[4];
1822 + unsigned char *dp = (unsigned char *)regs;
1823 + int only_trace = 0;
1824 +
1825 +@@ -367,7 +367,7 @@ unsigned int __cpuinit init_intel_cachei
1826 +
1827 + /* If bit 31 is set, this is an unknown format */
1828 + for ( j = 0 ; j < 3 ; j++ ) {
1829 +- if ( regs[j] < 0 ) regs[j] = 0;
1830 ++ if ( (int)regs[j] < 0 ) regs[j] = 0;
1831 + }
1832 +
1833 + /* Byte 0 is level count, not a descriptor */
1834 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/cpu/mcheck/therm_throt.c linux-2.6.23.15-grsec/arch/i386/kernel/cpu/mcheck/therm_throt.c
1835 +--- linux-2.6.23.15/arch/i386/kernel/cpu/mcheck/therm_throt.c 2007-10-09 21:31:38.000000000 +0100
1836 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/cpu/mcheck/therm_throt.c 2008-02-11 10:37:44.000000000 +0000
1837 +@@ -152,7 +152,7 @@ static __cpuinit int thermal_throttle_cp
1838 + return NOTIFY_OK;
1839 + }
1840 +
1841 +-static struct notifier_block thermal_throttle_cpu_notifier =
1842 ++static __cpuinitdata struct notifier_block thermal_throttle_cpu_notifier =
1843 + {
1844 + .notifier_call = thermal_throttle_cpu_callback,
1845 + };
1846 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/cpu/mtrr/generic.c linux-2.6.23.15-grsec/arch/i386/kernel/cpu/mtrr/generic.c
1847 +--- linux-2.6.23.15/arch/i386/kernel/cpu/mtrr/generic.c 2007-10-09 21:31:38.000000000 +0100
1848 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/cpu/mtrr/generic.c 2008-02-11 10:37:44.000000000 +0000
1849 +@@ -29,11 +29,11 @@ static struct fixed_range_block fixed_ra
1850 + { MTRRfix64K_00000_MSR, 1 }, /* one 64k MTRR */
1851 + { MTRRfix16K_80000_MSR, 2 }, /* two 16k MTRRs */
1852 + { MTRRfix4K_C0000_MSR, 8 }, /* eight 4k MTRRs */
1853 +- {}
1854 ++ { 0, 0 }
1855 + };
1856 +
1857 + static unsigned long smp_changes_mask;
1858 +-static struct mtrr_state mtrr_state = {};
1859 ++static struct mtrr_state mtrr_state;
1860 +
1861 + #undef MODULE_PARAM_PREFIX
1862 + #define MODULE_PARAM_PREFIX "mtrr."
1863 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/crash.c linux-2.6.23.15-grsec/arch/i386/kernel/crash.c
1864 +--- linux-2.6.23.15/arch/i386/kernel/crash.c 2007-10-09 21:31:38.000000000 +0100
1865 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/crash.c 2008-02-11 10:37:44.000000000 +0000
1866 +@@ -55,7 +55,7 @@ static int crash_nmi_callback(struct not
1867 + return NOTIFY_STOP;
1868 + local_irq_disable();
1869 +
1870 +- if (!user_mode_vm(regs)) {
1871 ++ if (!user_mode(regs)) {
1872 + crash_fixup_ss_esp(&fixed_regs, regs);
1873 + regs = &fixed_regs;
1874 + }
1875 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/doublefault.c linux-2.6.23.15-grsec/arch/i386/kernel/doublefault.c
1876 +--- linux-2.6.23.15/arch/i386/kernel/doublefault.c 2007-10-09 21:31:38.000000000 +0100
1877 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/doublefault.c 2008-02-11 10:37:44.000000000 +0000
1878 +@@ -11,17 +11,17 @@
1879 +
1880 + #define DOUBLEFAULT_STACKSIZE (1024)
1881 + static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
1882 +-#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
1883 ++#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
1884 +
1885 + #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
1886 +
1887 + static void doublefault_fn(void)
1888 + {
1889 +- struct Xgt_desc_struct gdt_desc = {0, 0};
1890 ++ struct Xgt_desc_struct gdt_desc = {0, NULL, 0};
1891 + unsigned long gdt, tss;
1892 +
1893 + store_gdt(&gdt_desc);
1894 +- gdt = gdt_desc.address;
1895 ++ gdt = (unsigned long)gdt_desc.address;
1896 +
1897 + printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
1898 +
1899 +@@ -59,10 +59,10 @@ struct tss_struct doublefault_tss __cach
1900 + /* 0x2 bit is always set */
1901 + .eflags = X86_EFLAGS_SF | 0x2,
1902 + .esp = STACK_START,
1903 +- .es = __USER_DS,
1904 ++ .es = __KERNEL_DS,
1905 + .cs = __KERNEL_CS,
1906 + .ss = __KERNEL_DS,
1907 +- .ds = __USER_DS,
1908 ++ .ds = __KERNEL_DS,
1909 + .fs = __KERNEL_PERCPU,
1910 +
1911 + .__cr3 = __pa(swapper_pg_dir)
1912 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/efi.c linux-2.6.23.15-grsec/arch/i386/kernel/efi.c
1913 +--- linux-2.6.23.15/arch/i386/kernel/efi.c 2007-10-09 21:31:38.000000000 +0100
1914 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/efi.c 2008-02-11 10:37:44.000000000 +0000
1915 +@@ -63,45 +63,23 @@ extern void * boot_ioremap(unsigned long
1916 +
1917 + static unsigned long efi_rt_eflags;
1918 + static DEFINE_SPINLOCK(efi_rt_lock);
1919 +-static pgd_t efi_bak_pg_dir_pointer[2];
1920 ++static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS] __attribute__ ((aligned (4096)));
1921 +
1922 + static void efi_call_phys_prelog(void) __acquires(efi_rt_lock)
1923 + {
1924 +- unsigned long cr4;
1925 +- unsigned long temp;
1926 + struct Xgt_desc_struct gdt_descr;
1927 +
1928 + spin_lock(&efi_rt_lock);
1929 + local_irq_save(efi_rt_eflags);
1930 +
1931 +- /*
1932 +- * If I don't have PSE, I should just duplicate two entries in page
1933 +- * directory. If I have PSE, I just need to duplicate one entry in
1934 +- * page directory.
1935 +- */
1936 +- cr4 = read_cr4();
1937 +-
1938 +- if (cr4 & X86_CR4_PSE) {
1939 +- efi_bak_pg_dir_pointer[0].pgd =
1940 +- swapper_pg_dir[pgd_index(0)].pgd;
1941 +- swapper_pg_dir[0].pgd =
1942 +- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
1943 +- } else {
1944 +- efi_bak_pg_dir_pointer[0].pgd =
1945 +- swapper_pg_dir[pgd_index(0)].pgd;
1946 +- efi_bak_pg_dir_pointer[1].pgd =
1947 +- swapper_pg_dir[pgd_index(0x400000)].pgd;
1948 +- swapper_pg_dir[pgd_index(0)].pgd =
1949 +- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
1950 +- temp = PAGE_OFFSET + 0x400000;
1951 +- swapper_pg_dir[pgd_index(0x400000)].pgd =
1952 +- swapper_pg_dir[pgd_index(temp)].pgd;
1953 +- }
1954 ++ clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
1955 ++ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
1956 ++ min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
1957 +
1958 + /*
1959 + * After the lock is released, the original page table is restored.
1960 + */
1961 +- local_flush_tlb();
1962 ++ __flush_tlb_all();
1963 +
1964 + gdt_descr.address = __pa(get_cpu_gdt_table(0));
1965 + gdt_descr.size = GDT_SIZE - 1;
1966 +@@ -110,35 +88,23 @@ static void efi_call_phys_prelog(void) _
1967 +
1968 + static void efi_call_phys_epilog(void) __releases(efi_rt_lock)
1969 + {
1970 +- unsigned long cr4;
1971 + struct Xgt_desc_struct gdt_descr;
1972 +
1973 +- gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
1974 ++ gdt_descr.address = get_cpu_gdt_table(0);
1975 + gdt_descr.size = GDT_SIZE - 1;
1976 + load_gdt(&gdt_descr);
1977 +-
1978 +- cr4 = read_cr4();
1979 +-
1980 +- if (cr4 & X86_CR4_PSE) {
1981 +- swapper_pg_dir[pgd_index(0)].pgd =
1982 +- efi_bak_pg_dir_pointer[0].pgd;
1983 +- } else {
1984 +- swapper_pg_dir[pgd_index(0)].pgd =
1985 +- efi_bak_pg_dir_pointer[0].pgd;
1986 +- swapper_pg_dir[pgd_index(0x400000)].pgd =
1987 +- efi_bak_pg_dir_pointer[1].pgd;
1988 +- }
1989 ++ clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
1990 +
1991 + /*
1992 + * After the lock is released, the original page table is restored.
1993 + */
1994 +- local_flush_tlb();
1995 ++ __flush_tlb_all();
1996 +
1997 + local_irq_restore(efi_rt_eflags);
1998 + spin_unlock(&efi_rt_lock);
1999 + }
2000 +
2001 +-static efi_status_t
2002 ++static efi_status_t __init
2003 + phys_efi_set_virtual_address_map(unsigned long memory_map_size,
2004 + unsigned long descriptor_size,
2005 + u32 descriptor_version,
2006 +@@ -154,7 +120,7 @@ phys_efi_set_virtual_address_map(unsigne
2007 + return status;
2008 + }
2009 +
2010 +-static efi_status_t
2011 ++static efi_status_t __init
2012 + phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
2013 + {
2014 + efi_status_t status;
2015 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/efi_stub.S linux-2.6.23.15-grsec/arch/i386/kernel/efi_stub.S
2016 +--- linux-2.6.23.15/arch/i386/kernel/efi_stub.S 2007-10-09 21:31:38.000000000 +0100
2017 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/efi_stub.S 2008-02-11 10:37:44.000000000 +0000
2018 +@@ -6,6 +6,7 @@
2019 + */
2020 +
2021 + #include <linux/linkage.h>
2022 ++#include <linux/init.h>
2023 + #include <asm/page.h>
2024 +
2025 + /*
2026 +@@ -20,7 +21,7 @@
2027 + * service functions will comply with gcc calling convention, too.
2028 + */
2029 +
2030 +-.text
2031 ++__INIT
2032 + ENTRY(efi_call_phys)
2033 + /*
2034 + * 0. The function can only be called in Linux kernel. So CS has been
2035 +@@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
2036 + * The mapping of lower virtual memory has been created in prelog and
2037 + * epilog.
2038 + */
2039 +- movl $1f, %edx
2040 +- subl $__PAGE_OFFSET, %edx
2041 +- jmp *%edx
2042 ++ jmp 1f-__PAGE_OFFSET
2043 + 1:
2044 +
2045 + /*
2046 +@@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
2047 + * parameter 2, ..., param n. To make things easy, we save the return
2048 + * address of efi_call_phys in a global variable.
2049 + */
2050 +- popl %edx
2051 +- movl %edx, saved_return_addr
2052 +- /* get the function pointer into ECX*/
2053 +- popl %ecx
2054 +- movl %ecx, efi_rt_function_ptr
2055 +- movl $2f, %edx
2056 +- subl $__PAGE_OFFSET, %edx
2057 +- pushl %edx
2058 ++ popl (saved_return_addr)
2059 ++ popl (efi_rt_function_ptr)
2060 +
2061 + /*
2062 + * 3. Clear PG bit in %CR0.
2063 +@@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
2064 + /*
2065 + * 5. Call the physical function.
2066 + */
2067 +- jmp *%ecx
2068 ++ call *(efi_rt_function_ptr-__PAGE_OFFSET)
2069 +
2070 +-2:
2071 + /*
2072 + * 6. After EFI runtime service returns, control will return to
2073 + * following instruction. We'd better readjust stack pointer first.
2074 +@@ -88,34 +80,27 @@ ENTRY(efi_call_phys)
2075 + movl %cr0, %edx
2076 + orl $0x80000000, %edx
2077 + movl %edx, %cr0
2078 +- jmp 1f
2079 +-1:
2080 ++
2081 + /*
2082 + * 8. Now restore the virtual mode from flat mode by
2083 + * adding EIP with PAGE_OFFSET.
2084 + */
2085 +- movl $1f, %edx
2086 +- jmp *%edx
2087 ++ jmp 1f+__PAGE_OFFSET
2088 + 1:
2089 +
2090 + /*
2091 + * 9. Balance the stack. And because EAX contain the return value,
2092 + * we'd better not clobber it.
2093 + */
2094 +- leal efi_rt_function_ptr, %edx
2095 +- movl (%edx), %ecx
2096 +- pushl %ecx
2097 ++ pushl (efi_rt_function_ptr)
2098 +
2099 + /*
2100 +- * 10. Push the saved return address onto the stack and return.
2101 ++ * 10. Return to the saved return address.
2102 + */
2103 +- leal saved_return_addr, %edx
2104 +- movl (%edx), %ecx
2105 +- pushl %ecx
2106 +- ret
2107 ++ jmpl *(saved_return_addr)
2108 + .previous
2109 +
2110 +-.data
2111 ++__INITDATA
2112 + saved_return_addr:
2113 + .long 0
2114 + efi_rt_function_ptr:
2115 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/entry.S linux-2.6.23.15-grsec/arch/i386/kernel/entry.S
2116 +--- linux-2.6.23.15/arch/i386/kernel/entry.S 2007-10-09 21:31:38.000000000 +0100
2117 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/entry.S 2008-02-11 10:37:44.000000000 +0000
2118 +@@ -97,7 +97,7 @@ VM_MASK = 0x00020000
2119 + #define resume_userspace_sig resume_userspace
2120 + #endif
2121 +
2122 +-#define SAVE_ALL \
2123 ++#define __SAVE_ALL(_DS) \
2124 + cld; \
2125 + pushl %fs; \
2126 + CFI_ADJUST_CFA_OFFSET 4;\
2127 +@@ -129,12 +129,26 @@ VM_MASK = 0x00020000
2128 + pushl %ebx; \
2129 + CFI_ADJUST_CFA_OFFSET 4;\
2130 + CFI_REL_OFFSET ebx, 0;\
2131 +- movl $(__USER_DS), %edx; \
2132 ++ movl $(_DS), %edx; \
2133 + movl %edx, %ds; \
2134 + movl %edx, %es; \
2135 + movl $(__KERNEL_PERCPU), %edx; \
2136 + movl %edx, %fs
2137 +
2138 ++#ifdef CONFIG_PAX_KERNEXEC
2139 ++#define SAVE_ALL \
2140 ++ __SAVE_ALL(__KERNEL_DS); \
2141 ++ GET_CR0_INTO_EDX; \
2142 ++ movl %edx, %esi; \
2143 ++ orl $X86_CR0_WP, %edx; \
2144 ++ xorl %edx, %esi; \
2145 ++ SET_CR0_FROM_EDX
2146 ++#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
2147 ++#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
2148 ++#else
2149 ++#define SAVE_ALL __SAVE_ALL(__USER_DS)
2150 ++#endif
2151 ++
2152 + #define RESTORE_INT_REGS \
2153 + popl %ebx; \
2154 + CFI_ADJUST_CFA_OFFSET -4;\
2155 +@@ -248,7 +262,17 @@ check_userspace:
2156 + movb PT_CS(%esp), %al
2157 + andl $(VM_MASK | SEGMENT_RPL_MASK), %eax
2158 + cmpl $USER_RPL, %eax
2159 ++
2160 ++#ifdef CONFIG_PAX_KERNEXEC
2161 ++ jae resume_userspace
2162 ++
2163 ++ GET_CR0_INTO_EDX
2164 ++ xorl %esi, %edx
2165 ++ SET_CR0_FROM_EDX
2166 ++ jmp resume_kernel
2167 ++#else
2168 + jb resume_kernel # not returning to v8086 or userspace
2169 ++#endif
2170 +
2171 + ENTRY(resume_userspace)
2172 + DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt
2173 +@@ -307,10 +331,9 @@ sysenter_past_esp:
2174 + /*CFI_REL_OFFSET cs, 0*/
2175 + /*
2176 + * Push current_thread_info()->sysenter_return to the stack.
2177 +- * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
2178 +- * pushed above; +8 corresponds to copy_thread's esp0 setting.
2179 + */
2180 +- pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
2181 ++ GET_THREAD_INFO(%ebp)
2182 ++ pushl TI_sysenter_return(%ebp)
2183 + CFI_ADJUST_CFA_OFFSET 4
2184 + CFI_REL_OFFSET eip, 0
2185 +
2186 +@@ -318,9 +341,17 @@ sysenter_past_esp:
2187 + * Load the potential sixth argument from user stack.
2188 + * Careful about security.
2189 + */
2190 ++ movl 12(%esp),%ebp
2191 ++
2192 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
2193 ++ mov 16(%esp),%ds
2194 ++1: movl %ds:(%ebp),%ebp
2195 ++#else
2196 + cmpl $__PAGE_OFFSET-3,%ebp
2197 + jae syscall_fault
2198 + 1: movl (%ebp),%ebp
2199 ++#endif
2200 ++
2201 + .section __ex_table,"a"
2202 + .align 4
2203 + .long 1b,syscall_fault
2204 +@@ -343,20 +374,37 @@ sysenter_past_esp:
2205 + movl TI_flags(%ebp), %ecx
2206 + testw $_TIF_ALLWORK_MASK, %cx
2207 + jne syscall_exit_work
2208 ++
2209 ++#ifdef CONFIG_PAX_RANDKSTACK
2210 ++ pushl %eax
2211 ++ CFI_ADJUST_CFA_OFFSET 4
2212 ++ call pax_randomize_kstack
2213 ++ popl %eax
2214 ++ CFI_ADJUST_CFA_OFFSET -4
2215 ++#endif
2216 ++
2217 + /* if something modifies registers it must also disable sysexit */
2218 + movl PT_EIP(%esp), %edx
2219 + movl PT_OLDESP(%esp), %ecx
2220 + xorl %ebp,%ebp
2221 + TRACE_IRQS_ON
2222 + 1: mov PT_FS(%esp), %fs
2223 ++2: mov PT_DS(%esp), %ds
2224 ++3: mov PT_ES(%esp), %es
2225 + ENABLE_INTERRUPTS_SYSEXIT
2226 + CFI_ENDPROC
2227 + .pushsection .fixup,"ax"
2228 +-2: movl $0,PT_FS(%esp)
2229 ++4: movl $0,PT_FS(%esp)
2230 + jmp 1b
2231 ++5: movl $0,PT_DS(%esp)
2232 ++ jmp 2b
2233 ++6: movl $0,PT_ES(%esp)
2234 ++ jmp 3b
2235 + .section __ex_table,"a"
2236 + .align 4
2237 +- .long 1b,2b
2238 ++ .long 1b,4b
2239 ++ .long 2b,5b
2240 ++ .long 3b,6b
2241 + .popsection
2242 + ENDPROC(sysenter_entry)
2243 +
2244 +@@ -389,6 +437,10 @@ no_singlestep:
2245 + testw $_TIF_ALLWORK_MASK, %cx # current->work
2246 + jne syscall_exit_work
2247 +
2248 ++#ifdef CONFIG_PAX_RANDKSTACK
2249 ++ call pax_randomize_kstack
2250 ++#endif
2251 ++
2252 + restore_all:
2253 + movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
2254 + # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
2255 +@@ -552,17 +604,24 @@ syscall_badsys:
2256 + END(syscall_badsys)
2257 + CFI_ENDPROC
2258 +
2259 +-#define FIXUP_ESPFIX_STACK \
2260 +- /* since we are on a wrong stack, we cant make it a C code :( */ \
2261 +- PER_CPU(gdt_page, %ebx); \
2262 +- GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \
2263 +- addl %esp, %eax; \
2264 +- pushl $__KERNEL_DS; \
2265 +- CFI_ADJUST_CFA_OFFSET 4; \
2266 +- pushl %eax; \
2267 +- CFI_ADJUST_CFA_OFFSET 4; \
2268 +- lss (%esp), %esp; \
2269 ++.macro FIXUP_ESPFIX_STACK
2270 ++ /* since we are on a wrong stack, we cant make it a C code :( */
2271 ++#ifdef CONFIG_SMP
2272 ++ movl PER_CPU_VAR(cpu_number), %ebx;
2273 ++ shll $PAGE_SHIFT_asm, %ebx;
2274 ++ addl $cpu_gdt_table, %ebx;
2275 ++#else
2276 ++ movl $cpu_gdt_table, %ebx;
2277 ++#endif
2278 ++ GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah);
2279 ++ addl %esp, %eax;
2280 ++ pushl $__KERNEL_DS;
2281 ++ CFI_ADJUST_CFA_OFFSET 4;
2282 ++ pushl %eax;
2283 ++ CFI_ADJUST_CFA_OFFSET 4;
2284 ++ lss (%esp), %esp;
2285 + CFI_ADJUST_CFA_OFFSET -8;
2286 ++.endm
2287 + #define UNWIND_ESPFIX_STACK \
2288 + movl %ss, %eax; \
2289 + /* see if on espfix stack */ \
2290 +@@ -579,7 +638,7 @@ END(syscall_badsys)
2291 + * Build the entry stubs and pointer table with
2292 + * some assembler magic.
2293 + */
2294 +-.data
2295 ++.section .rodata,"a",@progbits
2296 + ENTRY(interrupt)
2297 + .text
2298 +
2299 +@@ -679,12 +738,21 @@ error_code:
2300 + popl %ecx
2301 + CFI_ADJUST_CFA_OFFSET -4
2302 + /*CFI_REGISTER es, ecx*/
2303 ++
2304 ++#ifdef CONFIG_PAX_KERNEXEC
2305 ++ GET_CR0_INTO_EDX
2306 ++ movl %edx, %esi
2307 ++ orl $X86_CR0_WP, %edx
2308 ++ xorl %edx, %esi
2309 ++ SET_CR0_FROM_EDX
2310 ++#endif
2311 ++
2312 + movl PT_FS(%esp), %edi # get the function address
2313 + movl PT_ORIG_EAX(%esp), %edx # get the error code
2314 + movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
2315 + mov %ecx, PT_FS(%esp)
2316 + /*CFI_REL_OFFSET fs, ES*/
2317 +- movl $(__USER_DS), %ecx
2318 ++ movl $(__KERNEL_DS), %ecx
2319 + movl %ecx, %ds
2320 + movl %ecx, %es
2321 + movl %esp,%eax # pt_regs pointer
2322 +@@ -818,6 +886,13 @@ nmi_stack_correct:
2323 + xorl %edx,%edx # zero error code
2324 + movl %esp,%eax # pt_regs pointer
2325 + call do_nmi
2326 ++
2327 ++#ifdef CONFIG_PAX_KERNEXEC
2328 ++ GET_CR0_INTO_EDX
2329 ++ xorl %esi, %edx
2330 ++ SET_CR0_FROM_EDX
2331 ++#endif
2332 ++
2333 + jmp restore_nocheck_notrace
2334 + CFI_ENDPROC
2335 +
2336 +@@ -858,6 +933,13 @@ nmi_espfix_stack:
2337 + FIXUP_ESPFIX_STACK # %eax == %esp
2338 + xorl %edx,%edx # zero error code
2339 + call do_nmi
2340 ++
2341 ++#ifdef CONFIG_PAX_KERNEXEC
2342 ++ GET_CR0_INTO_EDX
2343 ++ xorl %esi, %edx
2344 ++ SET_CR0_FROM_EDX
2345 ++#endif
2346 ++
2347 + RESTORE_REGS
2348 + lss 12+4(%esp), %esp # back to espfix stack
2349 + CFI_ADJUST_CFA_OFFSET -24
2350 +@@ -1106,7 +1188,6 @@ ENDPROC(xen_failsafe_callback)
2351 +
2352 + #endif /* CONFIG_XEN */
2353 +
2354 +-.section .rodata,"a"
2355 + #include "syscall_table.S"
2356 +
2357 + syscall_table_size=(.-sys_call_table)
2358 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/head.S linux-2.6.23.15-grsec/arch/i386/kernel/head.S
2359 +--- linux-2.6.23.15/arch/i386/kernel/head.S 2007-10-09 21:31:38.000000000 +0100
2360 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/head.S 2008-02-11 10:37:44.000000000 +0000
2361 +@@ -18,6 +18,7 @@
2362 + #include <asm/thread_info.h>
2363 + #include <asm/asm-offsets.h>
2364 + #include <asm/setup.h>
2365 ++#include <asm/msr-index.h>
2366 +
2367 + /*
2368 + * References to members of the new_cpu_data structure.
2369 +@@ -51,17 +52,22 @@
2370 + */
2371 + LOW_PAGES = 1<<(32-PAGE_SHIFT_asm)
2372 +
2373 +-#if PTRS_PER_PMD > 1
2374 +-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD
2375 +-#else
2376 +-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD)
2377 +-#endif
2378 ++PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PTE)
2379 + BOOTBITMAP_SIZE = LOW_PAGES / 8
2380 + ALLOCATOR_SLOP = 4
2381 +
2382 + INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
2383 +
2384 + /*
2385 ++ * Real beginning of normal "text" segment
2386 ++ */
2387 ++ENTRY(stext)
2388 ++ENTRY(_stext)
2389 ++
2390 ++.section .text.startup,"ax",@progbits
2391 ++ ljmp $(__BOOT_CS),$phys_startup_32
2392 ++
2393 ++/*
2394 + * 32-bit kernel entrypoint; only used by the boot CPU. On entry,
2395 + * %esi points to the real-mode code as a 32-bit pointer.
2396 + * CS and DS must be 4 GB flat segments, but we don't depend on
2397 +@@ -69,6 +75,12 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE +
2398 + * can.
2399 + */
2400 + .section .text.head,"ax",@progbits
2401 ++
2402 ++#ifdef CONFIG_PAX_KERNEXEC
2403 ++/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
2404 ++.fill 4096,1,0xcc
2405 ++#endif
2406 ++
2407 + ENTRY(startup_32)
2408 +
2409 + /*
2410 +@@ -82,6 +94,43 @@ ENTRY(startup_32)
2411 + movl %eax,%fs
2412 + movl %eax,%gs
2413 +
2414 ++ movl $__per_cpu_start,%eax
2415 ++ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 2)
2416 ++ rorl $16,%eax
2417 ++ movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 4)
2418 ++ movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 7)
2419 ++ movl $__per_cpu_end + PERCPU_MODULE_RESERVE,%eax
2420 ++ subl $__per_cpu_start,%eax
2421 ++ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 0)
2422 ++
2423 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
2424 ++ /* check for VMware */
2425 ++ movl $0x564d5868,%eax
2426 ++ xorl %ebx,%ebx
2427 ++ movl $0xa,%ecx
2428 ++ movl $0x5658,%edx
2429 ++ in (%dx),%eax
2430 ++ cmpl $0x564d5868,%ebx
2431 ++ jz 1f
2432 ++
2433 ++ movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),%eax
2434 ++ movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_KERNEL_DS * 8 + 4)
2435 ++1:
2436 ++#endif
2437 ++
2438 ++#ifdef CONFIG_PAX_KERNEXEC
2439 ++ movl $KERNEL_TEXT_OFFSET,%eax
2440 ++ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 2)
2441 ++ rorl $16,%eax
2442 ++ movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 4)
2443 ++ movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 7)
2444 ++
2445 ++ movb %al,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 4)
2446 ++ movb %ah,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 7)
2447 ++ rorl $16,%eax
2448 ++ movw %ax,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 2)
2449 ++#endif
2450 ++
2451 + /*
2452 + * Clear BSS first so that there are no surprises...
2453 + * No need to cld as DF is already clear from cld above...
2454 +@@ -129,24 +178,42 @@ ENTRY(startup_32)
2455 + * Warning: don't use %esi or the stack in this code. However, %esp
2456 + * can be used as a GPR if you really need it...
2457 + */
2458 +-page_pde_offset = (__PAGE_OFFSET >> 20);
2459 +-
2460 ++#ifdef CONFIG_X86_PAE
2461 ++page_pde_offset = ((__PAGE_OFFSET >> 21) * (PAGE_SIZE_asm / PTRS_PER_PTE));
2462 ++#else
2463 ++page_pde_offset = ((__PAGE_OFFSET >> 22) * (PAGE_SIZE_asm / PTRS_PER_PTE));
2464 ++#endif
2465 + movl $(pg0 - __PAGE_OFFSET), %edi
2466 ++#ifdef CONFIG_X86_PAE
2467 ++ movl $(swapper_pm_dir - __PAGE_OFFSET), %edx
2468 ++#else
2469 + movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
2470 +- movl $0x007, %eax /* 0x007 = PRESENT+RW+USER */
2471 ++#endif
2472 ++ movl $0x063, %eax /* 0x063 = PRESENT+RW+ACCESSED+DIRTY */
2473 + 10:
2474 +- leal 0x007(%edi),%ecx /* Create PDE entry */
2475 ++ leal 0x063(%edi),%ecx /* Create PDE entry */
2476 + movl %ecx,(%edx) /* Store identity PDE entry */
2477 + movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */
2478 ++#ifdef CONFIG_X86_PAE
2479 ++ movl $0,4(%edx)
2480 ++ movl $0,page_pde_offset+4(%edx)
2481 ++ addl $8,%edx
2482 ++ movl $512, %ecx
2483 ++#else
2484 + addl $4,%edx
2485 + movl $1024, %ecx
2486 ++#endif
2487 + 11:
2488 + stosl
2489 ++#ifdef CONFIG_X86_PAE
2490 ++ movl $0,(%edi)
2491 ++ addl $4,%edi
2492 ++#endif
2493 + addl $0x1000,%eax
2494 + loop 11b
2495 + /* End condition: we must map up to and including INIT_MAP_BEYOND_END */
2496 +- /* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
2497 +- leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp
2498 ++ /* bytes beyond the end of our own page tables; the +0x063 is the attribute bits */
2499 ++ leal (INIT_MAP_BEYOND_END+0x063)(%edi),%ebp
2500 + cmpl %ebp,%eax
2501 + jb 10b
2502 + movl %edi,(init_pg_tables_end - __PAGE_OFFSET)
2503 +@@ -167,10 +234,12 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
2504 + #endif
2505 +
2506 + /* Do an early initialization of the fixmap area */
2507 +- movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
2508 +- movl $(swapper_pg_pmd - __PAGE_OFFSET), %eax
2509 +- addl $0x007, %eax /* 0x007 = PRESENT+RW+USER */
2510 +- movl %eax, 4092(%edx)
2511 ++ /* 0x067 = PRESENT+RW+USER+ACCESSED+DIRTY */
2512 ++#ifdef CONFIG_X86_PAE
2513 ++ movl $(swapper_pg_pmd - __PAGE_OFFSET + 0x067), (swapper_pm_dir - __PAGE_OFFSET + 4096 - 8)
2514 ++#else
2515 ++ movl $(swapper_pg_pmd - __PAGE_OFFSET + 0x067), (swapper_pg_dir - __PAGE_OFFSET + 4096 - 4)
2516 ++#endif
2517 +
2518 + #ifdef CONFIG_SMP
2519 + ENTRY(startup_32_smp)
2520 +@@ -181,6 +250,11 @@ ENTRY(startup_32_smp)
2521 + movl %eax,%fs
2522 + movl %eax,%gs
2523 +
2524 ++ /* This is a secondary processor (AP) */
2525 ++ xorl %ebx,%ebx
2526 ++ incl %ebx
2527 ++#endif /* CONFIG_SMP */
2528 ++
2529 + /*
2530 + * New page tables may be in 4Mbyte page mode and may
2531 + * be using the global pages.
2532 +@@ -196,42 +270,47 @@ ENTRY(startup_32_smp)
2533 + * not yet offset PAGE_OFFSET..
2534 + */
2535 + #define cr4_bits mmu_cr4_features-__PAGE_OFFSET
2536 ++3:
2537 + movl cr4_bits,%edx
2538 + andl %edx,%edx
2539 +- jz 6f
2540 ++ jz 5f
2541 + movl %cr4,%eax # Turn on paging options (PSE,PAE,..)
2542 + orl %edx,%eax
2543 + movl %eax,%cr4
2544 +
2545 +- btl $5, %eax # check if PAE is enabled
2546 +- jnc 6f
2547 ++#ifdef CONFIG_X86_PAE
2548 ++ movl %ebx,%edi
2549 +
2550 + /* Check if extended functions are implemented */
2551 + movl $0x80000000, %eax
2552 + cpuid
2553 + cmpl $0x80000000, %eax
2554 +- jbe 6f
2555 ++ jbe 4f
2556 + mov $0x80000001, %eax
2557 + cpuid
2558 + /* Execute Disable bit supported? */
2559 + btl $20, %edx
2560 +- jnc 6f
2561 ++ jnc 4f
2562 +
2563 + /* Setup EFER (Extended Feature Enable Register) */
2564 +- movl $0xc0000080, %ecx
2565 ++ movl $MSR_EFER, %ecx
2566 + rdmsr
2567 +
2568 + btsl $11, %eax
2569 + /* Make changes effective */
2570 + wrmsr
2571 +
2572 +-6:
2573 +- /* This is a secondary processor (AP) */
2574 +- xorl %ebx,%ebx
2575 +- incl %ebx
2576 ++ btsl $63-32,__supported_pte_mask+4-__PAGE_OFFSET
2577 ++ movl $1,nx_enabled-__PAGE_OFFSET
2578 +
2579 +-#endif /* CONFIG_SMP */
2580 +-3:
2581 ++#if !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF)
2582 ++ movl $0,disable_x86_sep-__PAGE_OFFSET
2583 ++#endif
2584 ++
2585 ++4:
2586 ++ movl %edi,%ebx
2587 ++#endif
2588 ++5:
2589 +
2590 + /*
2591 + * Enable paging
2592 +@@ -256,9 +335,7 @@ ENTRY(startup_32_smp)
2593 +
2594 + #ifdef CONFIG_SMP
2595 + andl %ebx,%ebx
2596 +- jz 1f /* Initial CPU cleans BSS */
2597 +- jmp checkCPUtype
2598 +-1:
2599 ++ jnz checkCPUtype /* Initial CPU cleans BSS */
2600 + #endif /* CONFIG_SMP */
2601 +
2602 + /*
2603 +@@ -335,12 +412,12 @@ is386: movl $2,%ecx # set MP
2604 + ljmp $(__KERNEL_CS),$1f
2605 + 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
2606 + movl %eax,%ss # after changing gdt.
2607 +- movl %eax,%fs # gets reset once there's real percpu
2608 +-
2609 +- movl $(__USER_DS),%eax # DS/ES contains default USER segment
2610 + movl %eax,%ds
2611 + movl %eax,%es
2612 +
2613 ++ movl $(__KERNEL_PERCPU), %eax
2614 ++ movl %eax,%fs # set this cpu's percpu
2615 ++
2616 + xorl %eax,%eax # Clear GS and LDT
2617 + movl %eax,%gs
2618 + lldt %ax
2619 +@@ -351,11 +428,7 @@ is386: movl $2,%ecx # set MP
2620 + movb ready, %cl
2621 + movb $1, ready
2622 + cmpb $0,%cl # the first CPU calls start_kernel
2623 +- je 1f
2624 +- movl $(__KERNEL_PERCPU), %eax
2625 +- movl %eax,%fs # set this cpu's percpu
2626 +- jmp initialize_secondary # all other CPUs call initialize_secondary
2627 +-1:
2628 ++ jne initialize_secondary # all other CPUs call initialize_secondary
2629 + #endif /* CONFIG_SMP */
2630 + jmp start_kernel
2631 +
2632 +@@ -441,8 +514,8 @@ early_page_fault:
2633 + jmp early_fault
2634 +
2635 + early_fault:
2636 +- cld
2637 + #ifdef CONFIG_PRINTK
2638 ++ cld
2639 + movl $(__KERNEL_DS),%eax
2640 + movl %eax,%ds
2641 + movl %eax,%es
2642 +@@ -466,8 +539,8 @@ hlt_loop:
2643 + /* This is the default interrupt "handler" :-) */
2644 + ALIGN
2645 + ignore_int:
2646 +- cld
2647 + #ifdef CONFIG_PRINTK
2648 ++ cld
2649 + pushl %eax
2650 + pushl %ecx
2651 + pushl %edx
2652 +@@ -498,31 +571,58 @@ ignore_int:
2653 + #endif
2654 + iret
2655 +
2656 +-.section .text
2657 +-/*
2658 +- * Real beginning of normal "text" segment
2659 +- */
2660 +-ENTRY(stext)
2661 +-ENTRY(_stext)
2662 +-
2663 + /*
2664 + * BSS section
2665 + */
2666 +-.section ".bss.page_aligned","wa"
2667 ++.section .swapper_pg_dir,"a",@progbits
2668 + .align PAGE_SIZE_asm
2669 + ENTRY(swapper_pg_dir)
2670 ++#ifdef CONFIG_X86_PAE
2671 ++ .long swapper_pm_dir-__PAGE_OFFSET+1
2672 ++ .long 0
2673 ++ .long swapper_pm_dir+512*8-__PAGE_OFFSET+1
2674 ++ .long 0
2675 ++ .long swapper_pm_dir+512*16-__PAGE_OFFSET+1
2676 ++ .long 0
2677 ++ .long swapper_pm_dir+512*24-__PAGE_OFFSET+1
2678 ++ .long 0
2679 ++#else
2680 + .fill 1024,4,0
2681 ++#endif
2682 ++
2683 ++.section .swapper_pm_dir,"a",@progbits
2684 ++#ifdef CONFIG_X86_PAE
2685 ++ENTRY(swapper_pm_dir)
2686 ++ .fill 512,8,0
2687 ++ .fill 512,8,0
2688 ++ .fill 512,8,0
2689 ++ .fill 512,8,0
2690 ++#endif
2691 ++
2692 + ENTRY(swapper_pg_pmd)
2693 + .fill 1024,4,0
2694 ++
2695 ++.section .empty_zero_page,"a",@progbits
2696 + ENTRY(empty_zero_page)
2697 + .fill 4096,1,0
2698 +
2699 + /*
2700 ++ * The IDT has to be page-aligned to simplify the Pentium
2701 ++ * F0 0F bug workaround.. We have a special link segment
2702 ++ * for this.
2703 ++ */
2704 ++.section .idt,"a",@progbits
2705 ++ENTRY(idt_table)
2706 ++ .fill 256,8,0
2707 ++
2708 ++/*
2709 + * This starts the data section.
2710 + */
2711 + .data
2712 ++
2713 ++.section .rodata,"a",@progbits
2714 + ENTRY(stack_start)
2715 +- .long init_thread_union+THREAD_SIZE
2716 ++ .long init_thread_union+THREAD_SIZE-8
2717 + .long __BOOT_DS
2718 +
2719 + ready: .byte 0
2720 +@@ -565,7 +665,7 @@ idt_descr:
2721 + .word 0 # 32 bit align gdt_desc.address
2722 + ENTRY(early_gdt_descr)
2723 + .word GDT_ENTRIES*8-1
2724 +- .long per_cpu__gdt_page /* Overwritten for secondary CPUs */
2725 ++ .long cpu_gdt_table /* Overwritten for secondary CPUs */
2726 +
2727 + /*
2728 + * The boot_gdt must mirror the equivalent in setup.S and is
2729 +@@ -574,5 +674,61 @@ ENTRY(early_gdt_descr)
2730 + .align L1_CACHE_BYTES
2731 + ENTRY(boot_gdt)
2732 + .fill GDT_ENTRY_BOOT_CS,8,0
2733 +- .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
2734 +- .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
2735 ++ .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */
2736 ++ .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */
2737 ++
2738 ++ .align PAGE_SIZE_asm
2739 ++ENTRY(cpu_gdt_table)
2740 ++ .quad 0x0000000000000000 /* NULL descriptor */
2741 ++ .quad 0x0000000000000000 /* 0x0b reserved */
2742 ++ .quad 0x0000000000000000 /* 0x13 reserved */
2743 ++ .quad 0x0000000000000000 /* 0x1b reserved */
2744 ++ .quad 0x0000000000000000 /* 0x20 unused */
2745 ++ .quad 0x0000000000000000 /* 0x28 unused */
2746 ++ .quad 0x0000000000000000 /* 0x33 TLS entry 1 */
2747 ++ .quad 0x0000000000000000 /* 0x3b TLS entry 2 */
2748 ++ .quad 0x0000000000000000 /* 0x43 TLS entry 3 */
2749 ++ .quad 0x0000000000000000 /* 0x4b reserved */
2750 ++ .quad 0x0000000000000000 /* 0x53 reserved */
2751 ++ .quad 0x0000000000000000 /* 0x5b reserved */
2752 ++
2753 ++ .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
2754 ++ .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
2755 ++ .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */
2756 ++ .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */
2757 ++
2758 ++ .quad 0x0000000000000000 /* 0x80 TSS descriptor */
2759 ++ .quad 0x0000000000000000 /* 0x88 LDT descriptor */
2760 ++
2761 ++ /*
2762 ++ * Segments used for calling PnP BIOS have byte granularity.
2763 ++ * The code segments and data segments have fixed 64k limits,
2764 ++ * the transfer segment sizes are set at run time.
2765 ++ */
2766 ++ .quad 0x00409b000000ffff /* 0x90 32-bit code */
2767 ++ .quad 0x00009b000000ffff /* 0x98 16-bit code */
2768 ++ .quad 0x000093000000ffff /* 0xa0 16-bit data */
2769 ++ .quad 0x0000930000000000 /* 0xa8 16-bit data */
2770 ++ .quad 0x0000930000000000 /* 0xb0 16-bit data */
2771 ++
2772 ++ /*
2773 ++ * The APM segments have byte granularity and their bases
2774 ++ * are set at run time. All have 64k limits.
2775 ++ */
2776 ++ .quad 0x00409b000000ffff /* 0xb8 APM CS code */
2777 ++ .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */
2778 ++ .quad 0x004093000000ffff /* 0xc8 APM DS data */
2779 ++
2780 ++ .quad 0x00c0930000000000 /* 0xd0 - ESPFIX SS */
2781 ++ .quad 0x0040930000000000 /* 0xd8 - PERCPU */
2782 ++ .quad 0x0000000000000000 /* 0xe0 - PCIBIOS_CS */
2783 ++ .quad 0x0000000000000000 /* 0xe8 - PCIBIOS_DS */
2784 ++ .quad 0x0000000000000000 /* 0xf0 - unused */
2785 ++ .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
2786 ++
2787 ++ /* Be sure this is zeroed to avoid false validations in Xen */
2788 ++ .fill PAGE_SIZE_asm - GDT_ENTRIES,1,0
2789 ++
2790 ++#ifdef CONFIG_SMP
2791 ++ .fill (NR_CPUS-1) * (PAGE_SIZE_asm),1,0 /* other CPU's GDT */
2792 ++#endif
2793 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/hpet.c linux-2.6.23.15-grsec/arch/i386/kernel/hpet.c
2794 +--- linux-2.6.23.15/arch/i386/kernel/hpet.c 2007-10-09 21:31:38.000000000 +0100
2795 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/hpet.c 2008-02-11 10:37:44.000000000 +0000
2796 +@@ -96,7 +96,7 @@ static void hpet_reserve_platform_timers
2797 + hd.hd_irq[1] = HPET_LEGACY_RTC;
2798 +
2799 + for (i = 2; i < nrtimers; timer++, i++)
2800 +- hd.hd_irq[i] = (timer->hpet_config & Tn_INT_ROUTE_CNF_MASK) >>
2801 ++ hd.hd_irq[i] = (readl(&timer->hpet_config) & Tn_INT_ROUTE_CNF_MASK) >>
2802 + Tn_INT_ROUTE_CNF_SHIFT;
2803 +
2804 + hpet_alloc(&hd);
2805 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/i386_ksyms.c linux-2.6.23.15-grsec/arch/i386/kernel/i386_ksyms.c
2806 +--- linux-2.6.23.15/arch/i386/kernel/i386_ksyms.c 2007-10-09 21:31:38.000000000 +0100
2807 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/i386_ksyms.c 2008-02-11 10:37:44.000000000 +0000
2808 +@@ -2,12 +2,16 @@
2809 + #include <asm/checksum.h>
2810 + #include <asm/desc.h>
2811 +
2812 ++EXPORT_SYMBOL_GPL(cpu_gdt_table);
2813 ++
2814 + EXPORT_SYMBOL(__down_failed);
2815 + EXPORT_SYMBOL(__down_failed_interruptible);
2816 + EXPORT_SYMBOL(__down_failed_trylock);
2817 + EXPORT_SYMBOL(__up_wakeup);
2818 + /* Networking helper routines. */
2819 + EXPORT_SYMBOL(csum_partial_copy_generic);
2820 ++EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
2821 ++EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
2822 +
2823 + EXPORT_SYMBOL(__get_user_1);
2824 + EXPORT_SYMBOL(__get_user_2);
2825 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/i8259.c linux-2.6.23.15-grsec/arch/i386/kernel/i8259.c
2826 +--- linux-2.6.23.15/arch/i386/kernel/i8259.c 2007-10-09 21:31:38.000000000 +0100
2827 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/i8259.c 2008-02-11 10:37:44.000000000 +0000
2828 +@@ -350,7 +350,7 @@ static irqreturn_t math_error_irq(int cp
2829 + * New motherboards sometimes make IRQ 13 be a PCI interrupt,
2830 + * so allow interrupt sharing.
2831 + */
2832 +-static struct irqaction fpu_irq = { math_error_irq, 0, CPU_MASK_NONE, "fpu", NULL, NULL };
2833 ++static struct irqaction fpu_irq = { math_error_irq, 0, CPU_MASK_NONE, "fpu", NULL, NULL, 0, NULL };
2834 +
2835 + void __init init_ISA_irqs (void)
2836 + {
2837 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/init_task.c linux-2.6.23.15-grsec/arch/i386/kernel/init_task.c
2838 +--- linux-2.6.23.15/arch/i386/kernel/init_task.c 2007-10-09 21:31:38.000000000 +0100
2839 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/init_task.c 2008-02-11 10:37:44.000000000 +0000
2840 +@@ -42,5 +42,5 @@ EXPORT_SYMBOL(init_task);
2841 + * per-CPU TSS segments. Threads are completely 'soft' on Linux,
2842 + * no more per-task TSS's.
2843 + */
2844 +-DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
2845 ++struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
2846 +
2847 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/ioport.c linux-2.6.23.15-grsec/arch/i386/kernel/ioport.c
2848 +--- linux-2.6.23.15/arch/i386/kernel/ioport.c 2007-10-09 21:31:38.000000000 +0100
2849 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/ioport.c 2008-02-11 10:37:44.000000000 +0000
2850 +@@ -16,6 +16,7 @@
2851 + #include <linux/slab.h>
2852 + #include <linux/thread_info.h>
2853 + #include <linux/syscalls.h>
2854 ++#include <linux/grsecurity.h>
2855 +
2856 + /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
2857 + static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
2858 +@@ -64,9 +65,16 @@ asmlinkage long sys_ioperm(unsigned long
2859 +
2860 + if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
2861 + return -EINVAL;
2862 ++#ifdef CONFIG_GRKERNSEC_IO
2863 ++ if (turn_on) {
2864 ++ gr_handle_ioperm();
2865 ++#else
2866 + if (turn_on && !capable(CAP_SYS_RAWIO))
2867 ++#endif
2868 + return -EPERM;
2869 +-
2870 ++#ifdef CONFIG_GRKERNSEC_IO
2871 ++ }
2872 ++#endif
2873 + /*
2874 + * If it's the first ioperm() call in this thread's lifetime, set the
2875 + * IO bitmap up. ioperm() is much less timing critical than clone(),
2876 +@@ -89,7 +97,7 @@ asmlinkage long sys_ioperm(unsigned long
2877 + * because the ->io_bitmap_max value must match the bitmap
2878 + * contents:
2879 + */
2880 +- tss = &per_cpu(init_tss, get_cpu());
2881 ++ tss = init_tss + get_cpu();
2882 +
2883 + set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
2884 +
2885 +@@ -143,8 +151,13 @@ asmlinkage long sys_iopl(unsigned long u
2886 + return -EINVAL;
2887 + /* Trying to gain more privileges? */
2888 + if (level > old) {
2889 ++#ifdef CONFIG_GRKERNSEC_IO
2890 ++ gr_handle_iopl();
2891 ++ return -EPERM;
2892 ++#else
2893 + if (!capable(CAP_SYS_RAWIO))
2894 + return -EPERM;
2895 ++#endif
2896 + }
2897 + t->iopl = level << 12;
2898 + regs->eflags = (regs->eflags & ~X86_EFLAGS_IOPL) | t->iopl;
2899 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/irq.c linux-2.6.23.15-grsec/arch/i386/kernel/irq.c
2900 +--- linux-2.6.23.15/arch/i386/kernel/irq.c 2007-10-09 21:31:38.000000000 +0100
2901 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/irq.c 2008-02-11 10:37:44.000000000 +0000
2902 +@@ -117,7 +117,7 @@ fastcall unsigned int do_IRQ(struct pt_r
2903 + int arg1, arg2, ebx;
2904 +
2905 + /* build the stack frame on the IRQ stack */
2906 +- isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
2907 ++ isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
2908 + irqctx->tinfo.task = curctx->tinfo.task;
2909 + irqctx->tinfo.previous_esp = current_stack_pointer;
2910 +
2911 +@@ -213,7 +213,7 @@ asmlinkage void do_softirq(void)
2912 + irqctx->tinfo.previous_esp = current_stack_pointer;
2913 +
2914 + /* build the stack frame on the softirq stack */
2915 +- isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
2916 ++ isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
2917 +
2918 + asm volatile(
2919 + " xchgl %%ebx,%%esp \n"
2920 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/kprobes.c linux-2.6.23.15-grsec/arch/i386/kernel/kprobes.c
2921 +--- linux-2.6.23.15/arch/i386/kernel/kprobes.c 2007-10-09 21:31:38.000000000 +0100
2922 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/kprobes.c 2008-02-11 10:37:44.000000000 +0000
2923 +@@ -49,9 +49,24 @@ static __always_inline void set_jmp_op(v
2924 + char op;
2925 + long raddr;
2926 + } __attribute__((packed)) *jop;
2927 +- jop = (struct __arch_jmp_op *)from;
2928 ++
2929 ++#ifdef CONFIG_PAX_KERNEXEC
2930 ++ unsigned long cr0;
2931 ++#endif
2932 ++
2933 ++ jop = (struct __arch_jmp_op *)(from + __KERNEL_TEXT_OFFSET);
2934 ++
2935 ++#ifdef CONFIG_PAX_KERNEXEC
2936 ++ pax_open_kernel(cr0);
2937 ++#endif
2938 ++
2939 + jop->raddr = (long)(to) - ((long)(from) + 5);
2940 + jop->op = RELATIVEJUMP_INSTRUCTION;
2941 ++
2942 ++#ifdef CONFIG_PAX_KERNEXEC
2943 ++ pax_close_kernel(cr0);
2944 ++#endif
2945 ++
2946 + }
2947 +
2948 + /*
2949 +@@ -153,14 +168,28 @@ static int __kprobes is_IF_modifier(kpro
2950 +
2951 + int __kprobes arch_prepare_kprobe(struct kprobe *p)
2952 + {
2953 ++
2954 ++#ifdef CONFIG_PAX_KERNEXEC
2955 ++ unsigned long cr0;
2956 ++#endif
2957 ++
2958 + /* insn: must be on special executable page on i386. */
2959 + p->ainsn.insn = get_insn_slot();
2960 + if (!p->ainsn.insn)
2961 + return -ENOMEM;
2962 +
2963 +- memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
2964 +- p->opcode = *p->addr;
2965 +- if (can_boost(p->addr)) {
2966 ++#ifdef CONFIG_PAX_KERNEXEC
2967 ++ pax_open_kernel(cr0);
2968 ++#endif
2969 ++
2970 ++ memcpy(p->ainsn.insn, p->addr + __KERNEL_TEXT_OFFSET, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
2971 ++
2972 ++#ifdef CONFIG_PAX_KERNEXEC
2973 ++ pax_close_kernel(cr0);
2974 ++#endif
2975 ++
2976 ++ p->opcode = *(p->addr + __KERNEL_TEXT_OFFSET);
2977 ++ if (can_boost(p->addr + __KERNEL_TEXT_OFFSET)) {
2978 + p->ainsn.boostable = 0;
2979 + } else {
2980 + p->ainsn.boostable = -1;
2981 +@@ -219,7 +248,7 @@ static void __kprobes prepare_singlestep
2982 + if (p->opcode == BREAKPOINT_INSTRUCTION)
2983 + regs->eip = (unsigned long)p->addr;
2984 + else
2985 +- regs->eip = (unsigned long)p->ainsn.insn;
2986 ++ regs->eip = (unsigned long)p->ainsn.insn - __KERNEL_TEXT_OFFSET;
2987 + }
2988 +
2989 + /* Called with kretprobe_lock held */
2990 +@@ -325,7 +354,7 @@ ss_probe:
2991 + if (p->ainsn.boostable == 1 && !p->post_handler){
2992 + /* Boost up -- we can execute copied instructions directly */
2993 + reset_current_kprobe();
2994 +- regs->eip = (unsigned long)p->ainsn.insn;
2995 ++ regs->eip = (unsigned long)p->ainsn.insn - __KERNEL_TEXT_OFFSET;
2996 + preempt_enable_no_resched();
2997 + return 1;
2998 + }
2999 +@@ -475,7 +504,7 @@ static void __kprobes resume_execution(s
3000 + struct pt_regs *regs, struct kprobe_ctlblk *kcb)
3001 + {
3002 + unsigned long *tos = (unsigned long *)&regs->esp;
3003 +- unsigned long copy_eip = (unsigned long)p->ainsn.insn;
3004 ++ unsigned long copy_eip = (unsigned long)p->ainsn.insn - __KERNEL_TEXT_OFFSET;
3005 + unsigned long orig_eip = (unsigned long)p->addr;
3006 +
3007 + regs->eflags &= ~TF_MASK;
3008 +@@ -648,7 +677,7 @@ int __kprobes kprobe_exceptions_notify(s
3009 + struct die_args *args = (struct die_args *)data;
3010 + int ret = NOTIFY_DONE;
3011 +
3012 +- if (args->regs && user_mode_vm(args->regs))
3013 ++ if (args->regs && user_mode(args->regs))
3014 + return ret;
3015 +
3016 + switch (val) {
3017 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/ldt.c linux-2.6.23.15-grsec/arch/i386/kernel/ldt.c
3018 +--- linux-2.6.23.15/arch/i386/kernel/ldt.c 2007-10-09 21:31:38.000000000 +0100
3019 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/ldt.c 2008-02-11 10:37:44.000000000 +0000
3020 +@@ -58,7 +58,7 @@ static int alloc_ldt(mm_context_t *pc, i
3021 + #ifdef CONFIG_SMP
3022 + cpumask_t mask;
3023 + preempt_disable();
3024 +- load_LDT(pc);
3025 ++ load_LDT_nolock(pc);
3026 + mask = cpumask_of_cpu(smp_processor_id());
3027 + if (!cpus_equal(current->mm->cpu_vm_mask, mask))
3028 + smp_call_function(flush_ldt, NULL, 1, 1);
3029 +@@ -102,6 +102,22 @@ int init_new_context(struct task_struct
3030 + retval = copy_ldt(&mm->context, &old_mm->context);
3031 + up(&old_mm->context.sem);
3032 + }
3033 ++
3034 ++ if (tsk == current) {
3035 ++ mm->context.vdso = ~0UL;
3036 ++
3037 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
3038 ++ mm->context.user_cs_base = 0UL;
3039 ++ mm->context.user_cs_limit = ~0UL;
3040 ++
3041 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
3042 ++ cpus_clear(mm->context.cpu_user_cs_mask);
3043 ++#endif
3044 ++
3045 ++#endif
3046 ++
3047 ++ }
3048 ++
3049 + return retval;
3050 + }
3051 +
3052 +@@ -212,6 +228,13 @@ static int write_ldt(void __user * ptr,
3053 + }
3054 + }
3055 +
3056 ++#ifdef CONFIG_PAX_SEGMEXEC
3057 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
3058 ++ error = -EINVAL;
3059 ++ goto out_unlock;
3060 ++ }
3061 ++#endif
3062 ++
3063 + entry_1 = LDT_entry_a(&ldt_info);
3064 + entry_2 = LDT_entry_b(&ldt_info);
3065 + if (oldmode)
3066 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/machine_kexec.c linux-2.6.23.15-grsec/arch/i386/kernel/machine_kexec.c
3067 +--- linux-2.6.23.15/arch/i386/kernel/machine_kexec.c 2007-10-09 21:31:38.000000000 +0100
3068 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/machine_kexec.c 2008-02-11 10:37:44.000000000 +0000
3069 +@@ -29,25 +29,25 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED
3070 + static u32 kexec_pte0[1024] PAGE_ALIGNED;
3071 + static u32 kexec_pte1[1024] PAGE_ALIGNED;
3072 +
3073 +-static void set_idt(void *newidt, __u16 limit)
3074 ++static void set_idt(struct desc_struct *newidt, __u16 limit)
3075 + {
3076 + struct Xgt_desc_struct curidt;
3077 +
3078 + /* ia32 supports unaliged loads & stores */
3079 + curidt.size = limit;
3080 +- curidt.address = (unsigned long)newidt;
3081 ++ curidt.address = newidt;
3082 +
3083 + load_idt(&curidt);
3084 + };
3085 +
3086 +
3087 +-static void set_gdt(void *newgdt, __u16 limit)
3088 ++static void set_gdt(struct desc_struct *newgdt, __u16 limit)
3089 + {
3090 + struct Xgt_desc_struct curgdt;
3091 +
3092 + /* ia32 supports unaligned loads & stores */
3093 + curgdt.size = limit;
3094 +- curgdt.address = (unsigned long)newgdt;
3095 ++ curgdt.address = newgdt;
3096 +
3097 + load_gdt(&curgdt);
3098 + };
3099 +@@ -110,10 +110,10 @@ NORET_TYPE void machine_kexec(struct kim
3100 + local_irq_disable();
3101 +
3102 + control_page = page_address(image->control_code_page);
3103 +- memcpy(control_page, relocate_kernel, PAGE_SIZE);
3104 ++ memcpy(control_page, relocate_kernel + __KERNEL_TEXT_OFFSET, PAGE_SIZE);
3105 +
3106 + page_list[PA_CONTROL_PAGE] = __pa(control_page);
3107 +- page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
3108 ++ page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel + __KERNEL_TEXT_OFFSET;
3109 + page_list[PA_PGD] = __pa(kexec_pgd);
3110 + page_list[VA_PGD] = (unsigned long)kexec_pgd;
3111 + #ifdef CONFIG_X86_PAE
3112 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/module.c linux-2.6.23.15-grsec/arch/i386/kernel/module.c
3113 +--- linux-2.6.23.15/arch/i386/kernel/module.c 2007-10-09 21:31:38.000000000 +0100
3114 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/module.c 2008-02-11 10:37:44.000000000 +0000
3115 +@@ -23,6 +23,8 @@
3116 + #include <linux/kernel.h>
3117 + #include <linux/bug.h>
3118 +
3119 ++#include <asm/desc.h>
3120 ++
3121 + #if 0
3122 + #define DEBUGP printk
3123 + #else
3124 +@@ -33,9 +35,30 @@ void *module_alloc(unsigned long size)
3125 + {
3126 + if (size == 0)
3127 + return NULL;
3128 ++
3129 ++#ifdef CONFIG_PAX_KERNEXEC
3130 ++ return vmalloc(size);
3131 ++#else
3132 + return vmalloc_exec(size);
3133 ++#endif
3134 ++
3135 + }
3136 +
3137 ++#ifdef CONFIG_PAX_KERNEXEC
3138 ++void *module_alloc_exec(unsigned long size)
3139 ++{
3140 ++ struct vm_struct *area;
3141 ++
3142 ++ if (size == 0)
3143 ++ return NULL;
3144 ++
3145 ++ area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
3146 ++ if (area)
3147 ++ return area->addr;
3148 ++
3149 ++ return NULL;
3150 ++}
3151 ++#endif
3152 +
3153 + /* Free memory returned from module_alloc */
3154 + void module_free(struct module *mod, void *module_region)
3155 +@@ -45,6 +68,45 @@ void module_free(struct module *mod, voi
3156 + table entries. */
3157 + }
3158 +
3159 ++#ifdef CONFIG_PAX_KERNEXEC
3160 ++void module_free_exec(struct module *mod, void *module_region)
3161 ++{
3162 ++ struct vm_struct **p, *tmp;
3163 ++
3164 ++ if (!module_region)
3165 ++ return;
3166 ++
3167 ++ if ((PAGE_SIZE-1) & (unsigned long)module_region) {
3168 ++ printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
3169 ++ WARN_ON(1);
3170 ++ return;
3171 ++ }
3172 ++
3173 ++ write_lock(&vmlist_lock);
3174 ++ for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next)
3175 ++ if (tmp->addr == module_region)
3176 ++ break;
3177 ++
3178 ++ if (tmp) {
3179 ++ unsigned long cr0;
3180 ++
3181 ++ pax_open_kernel(cr0);
3182 ++ memset(tmp->addr, 0xCC, tmp->size);
3183 ++ pax_close_kernel(cr0);
3184 ++
3185 ++ *p = tmp->next;
3186 ++ kfree(tmp);
3187 ++ }
3188 ++ write_unlock(&vmlist_lock);
3189 ++
3190 ++ if (!tmp) {
3191 ++ printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
3192 ++ module_region);
3193 ++ WARN_ON(1);
3194 ++ }
3195 ++}
3196 ++#endif
3197 ++
3198 + /* We don't need anything special. */
3199 + int module_frob_arch_sections(Elf_Ehdr *hdr,
3200 + Elf_Shdr *sechdrs,
3201 +@@ -63,14 +125,20 @@ int apply_relocate(Elf32_Shdr *sechdrs,
3202 + unsigned int i;
3203 + Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
3204 + Elf32_Sym *sym;
3205 +- uint32_t *location;
3206 ++ uint32_t *plocation, location;
3207 ++
3208 ++#ifdef CONFIG_PAX_KERNEXEC
3209 ++ unsigned long cr0;
3210 ++#endif
3211 +
3212 + DEBUGP("Applying relocate section %u to %u\n", relsec,
3213 + sechdrs[relsec].sh_info);
3214 + for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
3215 + /* This is where to make the change */
3216 +- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
3217 +- + rel[i].r_offset;
3218 ++ plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
3219 ++ location = (uint32_t)plocation;
3220 ++ if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
3221 ++ plocation = (void *)plocation + __KERNEL_TEXT_OFFSET;
3222 + /* This is the symbol it is referring to. Note that all
3223 + undefined symbols have been resolved. */
3224 + sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
3225 +@@ -78,12 +146,32 @@ int apply_relocate(Elf32_Shdr *sechdrs,
3226 +
3227 + switch (ELF32_R_TYPE(rel[i].r_info)) {
3228 + case R_386_32:
3229 ++
3230 ++#ifdef CONFIG_PAX_KERNEXEC
3231 ++ pax_open_kernel(cr0);
3232 ++#endif
3233 ++
3234 + /* We add the value into the location given */
3235 +- *location += sym->st_value;
3236 ++ *plocation += sym->st_value;
3237 ++
3238 ++#ifdef CONFIG_PAX_KERNEXEC
3239 ++ pax_close_kernel(cr0);
3240 ++#endif
3241 ++
3242 + break;
3243 + case R_386_PC32:
3244 ++
3245 ++#ifdef CONFIG_PAX_KERNEXEC
3246 ++ pax_open_kernel(cr0);
3247 ++#endif
3248 ++
3249 + /* Add the value, subtract its postition */
3250 +- *location += sym->st_value - (uint32_t)location;
3251 ++ *plocation += sym->st_value - location;
3252 ++
3253 ++#ifdef CONFIG_PAX_KERNEXEC
3254 ++ pax_close_kernel(cr0);
3255 ++#endif
3256 ++
3257 + break;
3258 + default:
3259 + printk(KERN_ERR "module %s: Unknown relocation: %u\n",
3260 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/paravirt.c linux-2.6.23.15-grsec/arch/i386/kernel/paravirt.c
3261 +--- linux-2.6.23.15/arch/i386/kernel/paravirt.c 2007-10-09 21:31:38.000000000 +0100
3262 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/paravirt.c 2008-02-11 10:37:44.000000000 +0000
3263 +@@ -198,7 +198,7 @@ unsigned paravirt_patch_insns(void *insn
3264 + if (insn_len > len || start == NULL)
3265 + insn_len = len;
3266 + else
3267 +- memcpy(insnbuf, start, insn_len);
3268 ++ memcpy(insnbuf, start + __KERNEL_TEXT_OFFSET, insn_len);
3269 +
3270 + return insn_len;
3271 + }
3272 +@@ -273,7 +273,7 @@ int paravirt_disable_iospace(void)
3273 + return ret;
3274 + }
3275 +
3276 +-struct paravirt_ops paravirt_ops = {
3277 ++struct paravirt_ops paravirt_ops __read_only = {
3278 + .name = "bare hardware",
3279 + .paravirt_enabled = 0,
3280 + .kernel_rpl = 0,
3281 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/process.c linux-2.6.23.15-grsec/arch/i386/kernel/process.c
3282 +--- linux-2.6.23.15/arch/i386/kernel/process.c 2007-10-09 21:31:38.000000000 +0100
3283 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/process.c 2008-02-11 10:37:44.000000000 +0000
3284 +@@ -68,15 +68,17 @@ EXPORT_SYMBOL(boot_option_idle_override)
3285 + DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
3286 + EXPORT_PER_CPU_SYMBOL(current_task);
3287 +
3288 ++#ifdef CONFIG_SMP
3289 + DEFINE_PER_CPU(int, cpu_number);
3290 + EXPORT_PER_CPU_SYMBOL(cpu_number);
3291 ++#endif
3292 +
3293 + /*
3294 + * Return saved PC of a blocked thread.
3295 + */
3296 + unsigned long thread_saved_pc(struct task_struct *tsk)
3297 + {
3298 +- return ((unsigned long *)tsk->thread.esp)[3];
3299 ++ return tsk->thread.eip;
3300 + }
3301 +
3302 + /*
3303 +@@ -307,7 +309,7 @@ void show_regs(struct pt_regs * regs)
3304 + printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id());
3305 + print_symbol("EIP is at %s\n", regs->eip);
3306 +
3307 +- if (user_mode_vm(regs))
3308 ++ if (user_mode(regs))
3309 + printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
3310 + printk(" EFLAGS: %08lx %s (%s %.*s)\n",
3311 + regs->eflags, print_tainted(), init_utsname()->release,
3312 +@@ -358,8 +360,8 @@ int kernel_thread(int (*fn)(void *), voi
3313 + regs.ebx = (unsigned long) fn;
3314 + regs.edx = (unsigned long) arg;
3315 +
3316 +- regs.xds = __USER_DS;
3317 +- regs.xes = __USER_DS;
3318 ++ regs.xds = __KERNEL_DS;
3319 ++ regs.xes = __KERNEL_DS;
3320 + regs.xfs = __KERNEL_PERCPU;
3321 + regs.orig_eax = -1;
3322 + regs.eip = (unsigned long) kernel_thread_helper;
3323 +@@ -381,7 +383,7 @@ void exit_thread(void)
3324 + struct task_struct *tsk = current;
3325 + struct thread_struct *t = &tsk->thread;
3326 + int cpu = get_cpu();
3327 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
3328 ++ struct tss_struct *tss = init_tss + cpu;
3329 +
3330 + kfree(t->io_bitmap_ptr);
3331 + t->io_bitmap_ptr = NULL;
3332 +@@ -402,6 +404,7 @@ void flush_thread(void)
3333 + {
3334 + struct task_struct *tsk = current;
3335 +
3336 ++ __asm__("mov %0,%%gs\n" : : "r" (0) : "memory");
3337 + memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
3338 + memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
3339 + clear_tsk_thread_flag(tsk, TIF_DEBUG);
3340 +@@ -435,7 +438,7 @@ int copy_thread(int nr, unsigned long cl
3341 + struct task_struct *tsk;
3342 + int err;
3343 +
3344 +- childregs = task_pt_regs(p);
3345 ++ childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
3346 + *childregs = *regs;
3347 + childregs->eax = 0;
3348 + childregs->esp = esp;
3349 +@@ -477,6 +480,11 @@ int copy_thread(int nr, unsigned long cl
3350 + if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
3351 + goto out;
3352 +
3353 ++#ifdef CONFIG_PAX_SEGMEXEC
3354 ++ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
3355 ++ goto out;
3356 ++#endif
3357 ++
3358 + desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
3359 + desc->a = LDT_entry_a(&info);
3360 + desc->b = LDT_entry_b(&info);
3361 +@@ -663,7 +671,7 @@ struct task_struct fastcall * __switch_t
3362 + struct thread_struct *prev = &prev_p->thread,
3363 + *next = &next_p->thread;
3364 + int cpu = smp_processor_id();
3365 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
3366 ++ struct tss_struct *tss = init_tss + cpu;
3367 +
3368 + /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
3369 +
3370 +@@ -691,6 +699,11 @@ struct task_struct fastcall * __switch_t
3371 + */
3372 + savesegment(gs, prev->gs);
3373 +
3374 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
3375 ++ if (!segment_eq(task_thread_info(prev_p)->addr_limit, task_thread_info(next_p)->addr_limit))
3376 ++ __set_fs(task_thread_info(next_p)->addr_limit, cpu);
3377 ++#endif
3378 ++
3379 + /*
3380 + * Load the per-thread Thread-Local Storage descriptor.
3381 + */
3382 +@@ -855,6 +868,12 @@ asmlinkage int sys_set_thread_area(struc
3383 +
3384 + if (copy_from_user(&info, u_info, sizeof(info)))
3385 + return -EFAULT;
3386 ++
3387 ++#ifdef CONFIG_PAX_SEGMEXEC
3388 ++ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
3389 ++ return -EINVAL;
3390 ++#endif
3391 ++
3392 + idx = info.entry_number;
3393 +
3394 + /*
3395 +@@ -943,9 +962,28 @@ asmlinkage int sys_get_thread_area(struc
3396 + return 0;
3397 + }
3398 +
3399 +-unsigned long arch_align_stack(unsigned long sp)
3400 ++#ifdef CONFIG_PAX_RANDKSTACK
3401 ++asmlinkage void pax_randomize_kstack(void)
3402 + {
3403 +- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
3404 +- sp -= get_random_int() % 8192;
3405 +- return sp & ~0xf;
3406 ++ struct tss_struct *tss;
3407 ++ unsigned long time;
3408 ++
3409 ++ if (!randomize_va_space)
3410 ++ return;
3411 ++
3412 ++ tss = init_tss + smp_processor_id();
3413 ++ rdtscl(time);
3414 ++
3415 ++ /* P4 seems to return a 0 LSB, ignore it */
3416 ++#ifdef CONFIG_MPENTIUM4
3417 ++ time &= 0x1EUL;
3418 ++ time <<= 2;
3419 ++#else
3420 ++ time &= 0xFUL;
3421 ++ time <<= 3;
3422 ++#endif
3423 ++
3424 ++ tss->x86_tss.esp0 ^= time;
3425 ++ current->thread.esp0 = tss->x86_tss.esp0;
3426 + }
3427 ++#endif
3428 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/ptrace.c linux-2.6.23.15-grsec/arch/i386/kernel/ptrace.c
3429 +--- linux-2.6.23.15/arch/i386/kernel/ptrace.c 2007-10-09 21:31:38.000000000 +0100
3430 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/ptrace.c 2008-02-11 10:37:44.000000000 +0000
3431 +@@ -161,22 +161,20 @@ static unsigned long convert_eip_to_line
3432 + * and APM bios ones we just ignore here.
3433 + */
3434 + if (seg & LDT_SEGMENT) {
3435 +- u32 *desc;
3436 ++ struct desc_struct *desc;
3437 + unsigned long base;
3438 +
3439 + seg &= ~7UL;
3440 +
3441 + down(&child->mm->context.sem);
3442 + if (unlikely((seg >> 3) >= child->mm->context.size))
3443 +- addr = -1L; /* bogus selector, access would fault */
3444 ++ addr = -EINVAL;
3445 + else {
3446 +- desc = child->mm->context.ldt + seg;
3447 +- base = ((desc[0] >> 16) |
3448 +- ((desc[1] & 0xff) << 16) |
3449 +- (desc[1] & 0xff000000));
3450 ++ desc = &child->mm->context.ldt[seg >> 3];
3451 ++ base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000);
3452 +
3453 + /* 16-bit code segment? */
3454 +- if (!((desc[1] >> 22) & 1))
3455 ++ if (!((desc->b >> 22) & 1))
3456 + addr &= 0xffff;
3457 + addr += base;
3458 + }
3459 +@@ -191,6 +189,9 @@ static inline int is_setting_trap_flag(s
3460 + unsigned char opcode[15];
3461 + unsigned long addr = convert_eip_to_linear(child, regs);
3462 +
3463 ++ if (addr == -EINVAL)
3464 ++ return 0;
3465 ++
3466 + copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
3467 + for (i = 0; i < copied; i++) {
3468 + switch (opcode[i]) {
3469 +@@ -341,6 +342,11 @@ ptrace_set_thread_area(struct task_struc
3470 + if (copy_from_user(&info, user_desc, sizeof(info)))
3471 + return -EFAULT;
3472 +
3473 ++#ifdef CONFIG_PAX_SEGMEXEC
3474 ++ if ((child->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
3475 ++ return -EINVAL;
3476 ++#endif
3477 ++
3478 + if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
3479 + return -EINVAL;
3480 +
3481 +@@ -420,6 +426,17 @@ long arch_ptrace(struct task_struct *chi
3482 + if(addr == (long) &dummy->u_debugreg[5]) break;
3483 + if(addr < (long) &dummy->u_debugreg[4] &&
3484 + ((unsigned long) data) >= TASK_SIZE-3) break;
3485 ++
3486 ++#ifdef CONFIG_GRKERNSEC
3487 ++ if(addr >= (long) &dummy->u_debugreg[0] &&
3488 ++ addr <= (long) &dummy->u_debugreg[3]){
3489 ++ long reg = (addr - (long) &dummy->u_debugreg[0]) >> 2;
3490 ++ long type = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3;
3491 ++ long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3;
3492 ++ if((type & 1) && (data & align))
3493 ++ break;
3494 ++ }
3495 ++#endif
3496 +
3497 + /* Sanity-check data. Take one half-byte at once with
3498 + * check = (val >> (16 + 4*i)) & 0xf. It contains the
3499 +@@ -636,7 +653,7 @@ void send_sigtrap(struct task_struct *ts
3500 + info.si_code = TRAP_BRKPT;
3501 +
3502 + /* User-mode eip? */
3503 +- info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL;
3504 ++ info.si_addr = user_mode(regs) ? (void __user *) regs->eip : NULL;
3505 +
3506 + /* Send us the fakey SIGTRAP */
3507 + force_sig_info(SIGTRAP, &info, tsk);
3508 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/reboot.c linux-2.6.23.15-grsec/arch/i386/kernel/reboot.c
3509 +--- linux-2.6.23.15/arch/i386/kernel/reboot.c 2007-10-09 21:31:38.000000000 +0100
3510 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/reboot.c 2008-02-11 10:37:44.000000000 +0000
3511 +@@ -26,7 +26,7 @@
3512 + void (*pm_power_off)(void);
3513 + EXPORT_SYMBOL(pm_power_off);
3514 +
3515 +-static int reboot_mode;
3516 ++static unsigned short reboot_mode;
3517 + static int reboot_thru_bios;
3518 +
3519 + #ifdef CONFIG_SMP
3520 +@@ -138,7 +138,7 @@ static struct dmi_system_id __initdata r
3521 + DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
3522 + },
3523 + },
3524 +- { }
3525 ++ { NULL, NULL, {{0, NULL}}, NULL}
3526 + };
3527 +
3528 + static int __init reboot_init(void)
3529 +@@ -156,18 +156,18 @@ core_initcall(reboot_init);
3530 + doesn't work with at least one type of 486 motherboard. It is easy
3531 + to stop this code working; hence the copious comments. */
3532 +
3533 +-static unsigned long long
3534 +-real_mode_gdt_entries [3] =
3535 ++static struct desc_struct
3536 ++real_mode_gdt_entries [3] __read_only =
3537 + {
3538 +- 0x0000000000000000ULL, /* Null descriptor */
3539 +- 0x00009a000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
3540 +- 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
3541 ++ {0x00000000, 0x00000000}, /* Null descriptor */
3542 ++ {0x0000ffff, 0x00009b00}, /* 16-bit real-mode 64k code at 0x00000000 */
3543 ++ {0x0100ffff, 0x00009300} /* 16-bit real-mode 64k data at 0x00000100 */
3544 + };
3545 +
3546 +-static struct Xgt_desc_struct
3547 +-real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries },
3548 +-real_mode_idt = { 0x3ff, 0 },
3549 +-no_idt = { 0, 0 };
3550 ++static const struct Xgt_desc_struct
3551 ++real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (struct desc_struct *)__pa(real_mode_gdt_entries), 0 },
3552 ++real_mode_idt = { 0x3ff, NULL, 0 },
3553 ++no_idt = { 0, NULL, 0 };
3554 +
3555 +
3556 + /* This is 16-bit protected mode code to disable paging and the cache,
3557 +@@ -189,7 +189,7 @@ no_idt = { 0, 0 };
3558 + More could be done here to set up the registers as if a CPU reset had
3559 + occurred; hopefully real BIOSs don't assume much. */
3560 +
3561 +-static unsigned char real_mode_switch [] =
3562 ++static const unsigned char real_mode_switch [] =
3563 + {
3564 + 0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */
3565 + 0x66, 0x83, 0xe0, 0x11, /* andl $0x00000011,%eax */
3566 +@@ -203,7 +203,7 @@ static unsigned char real_mode_switch []
3567 + 0x24, 0x10, /* f: andb $0x10,al */
3568 + 0x66, 0x0f, 0x22, 0xc0 /* movl %eax,%cr0 */
3569 + };
3570 +-static unsigned char jump_to_bios [] =
3571 ++static const unsigned char jump_to_bios [] =
3572 + {
3573 + 0xea, 0x00, 0x00, 0xff, 0xff /* ljmp $0xffff,$0x0000 */
3574 + };
3575 +@@ -213,7 +213,7 @@ static unsigned char jump_to_bios [] =
3576 + * specified by the code and length parameters.
3577 + * We assume that length will aways be less that 100!
3578 + */
3579 +-void machine_real_restart(unsigned char *code, int length)
3580 ++void machine_real_restart(const unsigned char *code, unsigned int length)
3581 + {
3582 + local_irq_disable();
3583 +
3584 +@@ -234,9 +234,8 @@ void machine_real_restart(unsigned char
3585 + /* Remap the kernel at virtual address zero, as well as offset zero
3586 + from the kernel segment. This assumes the kernel segment starts at
3587 + virtual address PAGE_OFFSET. */
3588 +-
3589 +- memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
3590 +- sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
3591 ++ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
3592 ++ min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
3593 +
3594 + /*
3595 + * Use `swapper_pg_dir' as our page directory.
3596 +@@ -249,7 +248,7 @@ void machine_real_restart(unsigned char
3597 + REBOOT.COM programs, and the previous reset routine did this
3598 + too. */
3599 +
3600 +- *((unsigned short *)0x472) = reboot_mode;
3601 ++ *(unsigned short *)(__va(0x472)) = reboot_mode;
3602 +
3603 + /* For the switch to real mode, copy some code to low memory. It has
3604 + to be in the first 64k because it is running in 16-bit mode, and it
3605 +@@ -257,9 +256,8 @@ void machine_real_restart(unsigned char
3606 + off paging. Copy it near the end of the first page, out of the way
3607 + of BIOS variables. */
3608 +
3609 +- memcpy ((void *) (0x1000 - sizeof (real_mode_switch) - 100),
3610 +- real_mode_switch, sizeof (real_mode_switch));
3611 +- memcpy ((void *) (0x1000 - 100), code, length);
3612 ++ memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch));
3613 ++ memcpy(__va(0x1000 - 100), code, length);
3614 +
3615 + /* Set up the IDT for real mode. */
3616 +
3617 +@@ -345,7 +343,7 @@ static void native_machine_emergency_res
3618 + __asm__ __volatile__("int3");
3619 + }
3620 + /* rebooting needs to touch the page at absolute addr 0 */
3621 +- *((unsigned short *)__va(0x472)) = reboot_mode;
3622 ++ *(unsigned short *)(__va(0x472)) = reboot_mode;
3623 + for (;;) {
3624 + mach_reboot_fixups(); /* for board specific fixups */
3625 + mach_reboot();
3626 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/setup.c linux-2.6.23.15-grsec/arch/i386/kernel/setup.c
3627 +--- linux-2.6.23.15/arch/i386/kernel/setup.c 2007-10-09 21:31:38.000000000 +0100
3628 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/setup.c 2008-02-11 10:37:44.000000000 +0000
3629 +@@ -82,7 +82,11 @@ struct cpuinfo_x86 new_cpu_data __cpuini
3630 + struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
3631 + EXPORT_SYMBOL(boot_cpu_data);
3632 +
3633 ++#ifdef CONFIG_X86_PAE
3634 ++unsigned long mmu_cr4_features = X86_CR4_PAE;
3635 ++#else
3636 + unsigned long mmu_cr4_features;
3637 ++#endif
3638 +
3639 + /* for MCA, but anyone else can use it if they want */
3640 + unsigned int machine_id;
3641 +@@ -395,8 +399,8 @@ void __init setup_bootmem_allocator(void
3642 + * the (very unlikely) case of us accidentally initializing the
3643 + * bootmem allocator with an invalid RAM area.
3644 + */
3645 +- reserve_bootmem(__pa_symbol(_text), (PFN_PHYS(min_low_pfn) +
3646 +- bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text));
3647 ++ reserve_bootmem(LOAD_PHYSICAL_ADDR, (PFN_PHYS(min_low_pfn) +
3648 ++ bootmap_size + PAGE_SIZE-1) - LOAD_PHYSICAL_ADDR);
3649 +
3650 + /*
3651 + * reserve physical page 0 - it's a special BIOS page on many boxes,
3652 +@@ -549,14 +553,14 @@ void __init setup_arch(char **cmdline_p)
3653 +
3654 + if (!MOUNT_ROOT_RDONLY)
3655 + root_mountflags &= ~MS_RDONLY;
3656 +- init_mm.start_code = (unsigned long) _text;
3657 +- init_mm.end_code = (unsigned long) _etext;
3658 ++ init_mm.start_code = (unsigned long) _text + __KERNEL_TEXT_OFFSET;
3659 ++ init_mm.end_code = (unsigned long) _etext + __KERNEL_TEXT_OFFSET;
3660 + init_mm.end_data = (unsigned long) _edata;
3661 + init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
3662 +
3663 +- code_resource.start = virt_to_phys(_text);
3664 +- code_resource.end = virt_to_phys(_etext)-1;
3665 +- data_resource.start = virt_to_phys(_etext);
3666 ++ code_resource.start = virt_to_phys(_text + __KERNEL_TEXT_OFFSET);
3667 ++ code_resource.end = virt_to_phys(_etext + __KERNEL_TEXT_OFFSET)-1;
3668 ++ data_resource.start = virt_to_phys(_data);
3669 + data_resource.end = virt_to_phys(_edata)-1;
3670 +
3671 + parse_early_param();
3672 +@@ -651,3 +655,23 @@ void __init setup_arch(char **cmdline_p)
3673 + #endif
3674 + #endif
3675 + }
3676 ++
3677 ++unsigned long __per_cpu_offset[NR_CPUS] __read_only;
3678 ++
3679 ++EXPORT_SYMBOL(__per_cpu_offset);
3680 ++
3681 ++void __init setup_per_cpu_areas(void)
3682 ++{
3683 ++ unsigned long size, i;
3684 ++ char *ptr;
3685 ++
3686 ++ /* Copy section for each CPU (we discard the original) */
3687 ++ size = ALIGN(PERCPU_ENOUGH_ROOM, PAGE_SIZE);
3688 ++ ptr = alloc_bootmem_pages(size * num_possible_cpus());
3689 ++
3690 ++ for_each_possible_cpu(i) {
3691 ++ __per_cpu_offset[i] = (unsigned long)ptr;
3692 ++ memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
3693 ++ ptr += size;
3694 ++ }
3695 ++}
3696 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/signal.c linux-2.6.23.15-grsec/arch/i386/kernel/signal.c
3697 +--- linux-2.6.23.15/arch/i386/kernel/signal.c 2007-10-09 21:31:38.000000000 +0100
3698 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/signal.c 2008-02-11 10:37:44.000000000 +0000
3699 +@@ -357,9 +357,9 @@ static int setup_frame(int sig, struct k
3700 + }
3701 +
3702 + if (current->binfmt->hasvdso)
3703 +- restorer = (void *)VDSO_SYM(&__kernel_sigreturn);
3704 ++ restorer = (void __user *)VDSO_SYM(&__kernel_sigreturn);
3705 + else
3706 +- restorer = (void *)&frame->retcode;
3707 ++ restorer = (void __user *)&frame->retcode;
3708 + if (ka->sa.sa_flags & SA_RESTORER)
3709 + restorer = ka->sa.sa_restorer;
3710 +
3711 +@@ -455,7 +455,8 @@ static int setup_rt_frame(int sig, struc
3712 + goto give_sigsegv;
3713 +
3714 + /* Set up to return from userspace. */
3715 +- restorer = (void *)VDSO_SYM(&__kernel_rt_sigreturn);
3716 ++
3717 ++ restorer = (void __user *)VDSO_SYM(&__kernel_rt_sigreturn);
3718 + if (ka->sa.sa_flags & SA_RESTORER)
3719 + restorer = ka->sa.sa_restorer;
3720 + err |= __put_user(restorer, &frame->pretcode);
3721 +@@ -588,7 +589,7 @@ static void fastcall do_signal(struct pt
3722 + * before reaching here, so testing against kernel
3723 + * CS suffices.
3724 + */
3725 +- if (!user_mode(regs))
3726 ++ if (!user_mode_novm(regs))
3727 + return;
3728 +
3729 + if (test_thread_flag(TIF_RESTORE_SIGMASK))
3730 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/smp.c linux-2.6.23.15-grsec/arch/i386/kernel/smp.c
3731 +--- linux-2.6.23.15/arch/i386/kernel/smp.c 2007-10-09 21:31:38.000000000 +0100
3732 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/smp.c 2008-02-11 10:37:44.000000000 +0000
3733 +@@ -104,7 +104,7 @@
3734 + * about nothing of note with C stepping upwards.
3735 + */
3736 +
3737 +-DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, };
3738 ++DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, {0} };
3739 +
3740 + /*
3741 + * the following functions deal with sending IPIs between CPUs.
3742 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/smpboot.c linux-2.6.23.15-grsec/arch/i386/kernel/smpboot.c
3743 +--- linux-2.6.23.15/arch/i386/kernel/smpboot.c 2007-10-09 21:31:38.000000000 +0100
3744 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/smpboot.c 2008-02-11 10:37:44.000000000 +0000
3745 +@@ -118,7 +118,7 @@ DEFINE_PER_CPU(int, cpu_state) = { 0 };
3746 + * has made sure it's suitably aligned.
3747 + */
3748 +
3749 +-static unsigned long __devinit setup_trampoline(void)
3750 ++static unsigned long __cpuinit setup_trampoline(void)
3751 + {
3752 + memcpy(trampoline_base, trampoline_data, trampoline_end - trampoline_data);
3753 + return virt_to_phys(trampoline_base);
3754 +@@ -772,6 +772,10 @@ static int __cpuinit do_boot_cpu(int api
3755 + unsigned long start_eip;
3756 + unsigned short nmi_high = 0, nmi_low = 0;
3757 +
3758 ++#ifdef CONFIG_PAX_KERNEXEC
3759 ++ unsigned long cr0;
3760 ++#endif
3761 ++
3762 + /*
3763 + * Save current MTRR state in case it was changed since early boot
3764 + * (e.g. by the ACPI SMI) to initialize new CPUs with MTRRs in sync:
3765 +@@ -788,7 +792,16 @@ static int __cpuinit do_boot_cpu(int api
3766 +
3767 + init_gdt(cpu);
3768 + per_cpu(current_task, cpu) = idle;
3769 +- early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
3770 ++
3771 ++#ifdef CONFIG_PAX_KERNEXEC
3772 ++ pax_open_kernel(cr0);
3773 ++#endif
3774 ++
3775 ++ early_gdt_descr.address = get_cpu_gdt_table(cpu);
3776 ++
3777 ++#ifdef CONFIG_PAX_KERNEXEC
3778 ++ pax_close_kernel(cr0);
3779 ++#endif
3780 +
3781 + idle->thread.eip = (unsigned long) start_secondary;
3782 + /* start_eip had better be page-aligned! */
3783 +@@ -1105,7 +1118,7 @@ static void __init smp_boot_cpus(unsigne
3784 + * construct cpu_sibling_map[], so that we can tell sibling CPUs
3785 + * efficiently.
3786 + */
3787 +- for (cpu = 0; cpu < NR_CPUS; cpu++) {
3788 ++ for_each_possible_cpu(cpu) {
3789 + cpus_clear(cpu_sibling_map[cpu]);
3790 + cpus_clear(cpu_core_map[cpu]);
3791 + }
3792 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/smpcommon.c linux-2.6.23.15-grsec/arch/i386/kernel/smpcommon.c
3793 +--- linux-2.6.23.15/arch/i386/kernel/smpcommon.c 2007-10-09 21:31:38.000000000 +0100
3794 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/smpcommon.c 2008-02-11 10:37:44.000000000 +0000
3795 +@@ -3,6 +3,7 @@
3796 + */
3797 + #include <linux/module.h>
3798 + #include <asm/smp.h>
3799 ++#include <asm/sections.h>
3800 +
3801 + DEFINE_PER_CPU(unsigned long, this_cpu_off);
3802 + EXPORT_PER_CPU_SYMBOL(this_cpu_off);
3803 +@@ -14,10 +15,29 @@ __cpuinit void init_gdt(int cpu)
3804 + {
3805 + struct desc_struct *gdt = get_cpu_gdt_table(cpu);
3806 +
3807 +- pack_descriptor((u32 *)&gdt[GDT_ENTRY_PERCPU].a,
3808 +- (u32 *)&gdt[GDT_ENTRY_PERCPU].b,
3809 +- __per_cpu_offset[cpu], 0xFFFFF,
3810 +- 0x80 | DESCTYPE_S | 0x2, 0x8);
3811 ++#ifdef CONFIG_PAX_KERNEXEC
3812 ++ unsigned long cr0;
3813 ++
3814 ++ pax_open_kernel(cr0);
3815 ++#endif
3816 ++
3817 ++ if (cpu)
3818 ++ memcpy(gdt, cpu_gdt_table, GDT_SIZE);
3819 ++
3820 ++ if (PERCPU_ENOUGH_ROOM <= 64*1024*1024)
3821 ++ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PERCPU].a,
3822 ++ (__u32 *)&gdt[GDT_ENTRY_PERCPU].b,
3823 ++ __per_cpu_offset[cpu], PERCPU_ENOUGH_ROOM-1,
3824 ++ 0x80 | DESCTYPE_S | 0x3, 0x4);
3825 ++ else
3826 ++ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PERCPU].a,
3827 ++ (__u32 *)&gdt[GDT_ENTRY_PERCPU].b,
3828 ++ __per_cpu_offset[cpu], ((PERCPU_ENOUGH_ROOM-1) >> PAGE_SHIFT),
3829 ++ 0x80 | DESCTYPE_S | 0x3, 0xC);
3830 ++
3831 ++#ifdef CONFIG_PAX_KERNEXEC
3832 ++ pax_close_kernel(cr0);
3833 ++#endif
3834 +
3835 + per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu];
3836 + per_cpu(cpu_number, cpu) = cpu;
3837 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/sys_i386.c linux-2.6.23.15-grsec/arch/i386/kernel/sys_i386.c
3838 +--- linux-2.6.23.15/arch/i386/kernel/sys_i386.c 2007-10-09 21:31:38.000000000 +0100
3839 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/sys_i386.c 2008-02-11 10:37:44.000000000 +0000
3840 +@@ -41,6 +41,21 @@ asmlinkage int sys_pipe(unsigned long __
3841 + return error;
3842 + }
3843 +
3844 ++int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
3845 ++{
3846 ++ unsigned long task_size = TASK_SIZE;
3847 ++
3848 ++#ifdef CONFIG_PAX_SEGMEXEC
3849 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
3850 ++ task_size = SEGMEXEC_TASK_SIZE;
3851 ++#endif
3852 ++
3853 ++ if (len > task_size || addr > task_size - len)
3854 ++ return -EINVAL;
3855 ++
3856 ++ return 0;
3857 ++}
3858 ++
3859 + asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
3860 + unsigned long prot, unsigned long flags,
3861 + unsigned long fd, unsigned long pgoff)
3862 +@@ -100,6 +115,205 @@ out:
3863 + return err;
3864 + }
3865 +
3866 ++unsigned long
3867 ++arch_get_unmapped_area(struct file *filp, unsigned long addr,
3868 ++ unsigned long len, unsigned long pgoff, unsigned long flags)
3869 ++{
3870 ++ struct mm_struct *mm = current->mm;
3871 ++ struct vm_area_struct *vma;
3872 ++ unsigned long start_addr, task_size = TASK_SIZE;
3873 ++
3874 ++#ifdef CONFIG_PAX_SEGMEXEC
3875 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
3876 ++ task_size = SEGMEXEC_TASK_SIZE;
3877 ++#endif
3878 ++
3879 ++ if (len > task_size)
3880 ++ return -ENOMEM;
3881 ++
3882 ++ if (flags & MAP_FIXED)
3883 ++ return addr;
3884 ++
3885 ++#ifdef CONFIG_PAX_RANDMMAP
3886 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
3887 ++#endif
3888 ++
3889 ++ if (addr) {
3890 ++ addr = PAGE_ALIGN(addr);
3891 ++ vma = find_vma(mm, addr);
3892 ++ if (task_size - len >= addr &&
3893 ++ (!vma || addr + len <= vma->vm_start))
3894 ++ return addr;
3895 ++ }
3896 ++ if (len > mm->cached_hole_size) {
3897 ++ start_addr = addr = mm->free_area_cache;
3898 ++ } else {
3899 ++ start_addr = addr = mm->mmap_base;
3900 ++ mm->cached_hole_size = 0;
3901 ++ }
3902 ++
3903 ++#ifdef CONFIG_PAX_PAGEEXEC
3904 ++ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
3905 ++ start_addr = 0x00110000UL;
3906 ++
3907 ++#ifdef CONFIG_PAX_RANDMMAP
3908 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
3909 ++ start_addr += mm->delta_mmap & 0x03FFF000UL;
3910 ++#endif
3911 ++
3912 ++ if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
3913 ++ start_addr = addr = mm->mmap_base;
3914 ++ else
3915 ++ addr = start_addr;
3916 ++ }
3917 ++#endif
3918 ++
3919 ++full_search:
3920 ++ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
3921 ++ /* At this point: (!vma || addr < vma->vm_end). */
3922 ++ if (task_size - len < addr) {
3923 ++ /*
3924 ++ * Start a new search - just in case we missed
3925 ++ * some holes.
3926 ++ */
3927 ++ if (start_addr != mm->mmap_base) {
3928 ++ start_addr = addr = mm->mmap_base;
3929 ++ mm->cached_hole_size = 0;
3930 ++ goto full_search;
3931 ++ }
3932 ++ return -ENOMEM;
3933 ++ }
3934 ++ if (!vma || addr + len <= vma->vm_start) {
3935 ++ /*
3936 ++ * Remember the place where we stopped the search:
3937 ++ */
3938 ++ mm->free_area_cache = addr + len;
3939 ++ return addr;
3940 ++ }
3941 ++ if (addr + mm->cached_hole_size < vma->vm_start)
3942 ++ mm->cached_hole_size = vma->vm_start - addr;
3943 ++ addr = vma->vm_end;
3944 ++ if (mm->start_brk <= addr && addr < mm->mmap_base) {
3945 ++ start_addr = addr = mm->mmap_base;
3946 ++ mm->cached_hole_size = 0;
3947 ++ goto full_search;
3948 ++ }
3949 ++ }
3950 ++}
3951 ++
3952 ++unsigned long
3953 ++arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
3954 ++ const unsigned long len, const unsigned long pgoff,
3955 ++ const unsigned long flags)
3956 ++{
3957 ++ struct vm_area_struct *vma;
3958 ++ struct mm_struct *mm = current->mm;
3959 ++ unsigned long base = mm->mmap_base, addr = addr0, task_size = TASK_SIZE;
3960 ++
3961 ++#ifdef CONFIG_PAX_SEGMEXEC
3962 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
3963 ++ task_size = SEGMEXEC_TASK_SIZE;
3964 ++#endif
3965 ++
3966 ++ /* requested length too big for entire address space */
3967 ++ if (len > task_size)
3968 ++ return -ENOMEM;
3969 ++
3970 ++ if (flags & MAP_FIXED)
3971 ++ return addr;
3972 ++
3973 ++#ifdef CONFIG_PAX_PAGEEXEC
3974 ++ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
3975 ++ goto bottomup;
3976 ++#endif
3977 ++
3978 ++#ifdef CONFIG_PAX_RANDMMAP
3979 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
3980 ++#endif
3981 ++
3982 ++ /* requesting a specific address */
3983 ++ if (addr) {
3984 ++ addr = PAGE_ALIGN(addr);
3985 ++ vma = find_vma(mm, addr);
3986 ++ if (task_size - len >= addr &&
3987 ++ (!vma || addr + len <= vma->vm_start))
3988 ++ return addr;
3989 ++ }
3990 ++
3991 ++ /* check if free_area_cache is useful for us */
3992 ++ if (len <= mm->cached_hole_size) {
3993 ++ mm->cached_hole_size = 0;
3994 ++ mm->free_area_cache = mm->mmap_base;
3995 ++ }
3996 ++
3997 ++ /* either no address requested or can't fit in requested address hole */
3998 ++ addr = mm->free_area_cache;
3999 ++
4000 ++ /* make sure it can fit in the remaining address space */
4001 ++ if (addr > len) {
4002 ++ vma = find_vma(mm, addr-len);
4003 ++ if (!vma || addr <= vma->vm_start)
4004 ++ /* remember the address as a hint for next time */
4005 ++ return (mm->free_area_cache = addr-len);
4006 ++ }
4007 ++
4008 ++ if (mm->mmap_base < len)
4009 ++ goto bottomup;
4010 ++
4011 ++ addr = mm->mmap_base-len;
4012 ++
4013 ++ do {
4014 ++ /*
4015 ++ * Lookup failure means no vma is above this address,
4016 ++ * else if new region fits below vma->vm_start,
4017 ++ * return with success:
4018 ++ */
4019 ++ vma = find_vma(mm, addr);
4020 ++ if (!vma || addr+len <= vma->vm_start)
4021 ++ /* remember the address as a hint for next time */
4022 ++ return (mm->free_area_cache = addr);
4023 ++
4024 ++ /* remember the largest hole we saw so far */
4025 ++ if (addr + mm->cached_hole_size < vma->vm_start)
4026 ++ mm->cached_hole_size = vma->vm_start - addr;
4027 ++
4028 ++ /* try just below the current vma->vm_start */
4029 ++ addr = vma->vm_start-len;
4030 ++ } while (len < vma->vm_start);
4031 ++
4032 ++bottomup:
4033 ++ /*
4034 ++ * A failed mmap() very likely causes application failure,
4035 ++ * so fall back to the bottom-up function here. This scenario
4036 ++ * can happen with large stack limits and large mmap()
4037 ++ * allocations.
4038 ++ */
4039 ++
4040 ++#ifdef CONFIG_PAX_SEGMEXEC
4041 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
4042 ++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
4043 ++ else
4044 ++#endif
4045 ++
4046 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
4047 ++
4048 ++#ifdef CONFIG_PAX_RANDMMAP
4049 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
4050 ++ mm->mmap_base += mm->delta_mmap;
4051 ++#endif
4052 ++
4053 ++ mm->free_area_cache = mm->mmap_base;
4054 ++ mm->cached_hole_size = ~0UL;
4055 ++ addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
4056 ++ /*
4057 ++ * Restore the topdown base:
4058 ++ */
4059 ++ mm->mmap_base = base;
4060 ++ mm->free_area_cache = base;
4061 ++ mm->cached_hole_size = ~0UL;
4062 ++
4063 ++ return addr;
4064 ++}
4065 +
4066 + struct sel_arg_struct {
4067 + unsigned long n;
4068 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/syscall_table.S linux-2.6.23.15-grsec/arch/i386/kernel/syscall_table.S
4069 +--- linux-2.6.23.15/arch/i386/kernel/syscall_table.S 2007-10-09 21:31:38.000000000 +0100
4070 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/syscall_table.S 2008-02-11 10:37:44.000000000 +0000
4071 +@@ -1,3 +1,4 @@
4072 ++.section .rodata,"a",@progbits
4073 + ENTRY(sys_call_table)
4074 + .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
4075 + .long sys_exit
4076 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/sysenter.c linux-2.6.23.15-grsec/arch/i386/kernel/sysenter.c
4077 +--- linux-2.6.23.15/arch/i386/kernel/sysenter.c 2007-10-09 21:31:38.000000000 +0100
4078 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/sysenter.c 2008-02-11 10:37:44.000000000 +0000
4079 +@@ -177,7 +177,7 @@ static __init void relocate_vdso(Elf32_E
4080 + void enable_sep_cpu(void)
4081 + {
4082 + int cpu = get_cpu();
4083 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
4084 ++ struct tss_struct *tss = init_tss + cpu;
4085 +
4086 + if (!boot_cpu_has(X86_FEATURE_SEP)) {
4087 + put_cpu();
4088 +@@ -200,7 +200,7 @@ static int __init gate_vma_init(void)
4089 + gate_vma.vm_start = FIXADDR_USER_START;
4090 + gate_vma.vm_end = FIXADDR_USER_END;
4091 + gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
4092 +- gate_vma.vm_page_prot = __P101;
4093 ++ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
4094 + /*
4095 + * Make sure the vDSO gets into every core dump.
4096 + * Dumping its contents makes post-mortem fully interpretable later
4097 +@@ -283,7 +283,7 @@ int arch_setup_additional_pages(struct l
4098 + if (compat)
4099 + addr = VDSO_HIGH_BASE;
4100 + else {
4101 +- addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
4102 ++ addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
4103 + if (IS_ERR_VALUE(addr)) {
4104 + ret = addr;
4105 + goto up_fail;
4106 +@@ -308,7 +308,7 @@ int arch_setup_additional_pages(struct l
4107 + goto up_fail;
4108 + }
4109 +
4110 +- current->mm->context.vdso = (void *)addr;
4111 ++ current->mm->context.vdso = addr;
4112 + current_thread_info()->sysenter_return =
4113 + (void *)VDSO_SYM(&SYSENTER_RETURN);
4114 +
4115 +@@ -320,8 +320,14 @@ int arch_setup_additional_pages(struct l
4116 +
4117 + const char *arch_vma_name(struct vm_area_struct *vma)
4118 + {
4119 +- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
4120 ++ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
4121 + return "[vdso]";
4122 ++
4123 ++#ifdef CONFIG_PAX_SEGMEXEC
4124 ++ if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso)
4125 ++ return "[vdso]";
4126 ++#endif
4127 ++
4128 + return NULL;
4129 + }
4130 +
4131 +@@ -330,7 +336,7 @@ struct vm_area_struct *get_gate_vma(stru
4132 + struct mm_struct *mm = tsk->mm;
4133 +
4134 + /* Check to see if this task was created in compat vdso mode */
4135 +- if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
4136 ++ if (mm && mm->context.vdso == VDSO_HIGH_BASE)
4137 + return &gate_vma;
4138 + return NULL;
4139 + }
4140 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/time.c linux-2.6.23.15-grsec/arch/i386/kernel/time.c
4141 +--- linux-2.6.23.15/arch/i386/kernel/time.c 2007-10-09 21:31:38.000000000 +0100
4142 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/time.c 2008-02-11 10:37:44.000000000 +0000
4143 +@@ -132,20 +132,30 @@ unsigned long profile_pc(struct pt_regs
4144 + if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->xcs) &&
4145 + in_lock_functions(pc)) {
4146 + #ifdef CONFIG_FRAME_POINTER
4147 +- return *(unsigned long *)(regs->ebp + 4);
4148 ++ return *(unsigned long *)(regs->ebp + 4) + __KERNEL_TEXT_OFFSET;
4149 + #else
4150 + unsigned long *sp = (unsigned long *)&regs->esp;
4151 +
4152 + /* Return address is either directly at stack pointer
4153 + or above a saved eflags. Eflags has bits 22-31 zero,
4154 + kernel addresses don't. */
4155 ++
4156 ++#ifdef CONFIG_PAX_KERNEXEC
4157 ++ return sp[0] + __KERNEL_TEXT_OFFSET;
4158 ++#else
4159 + if (sp[0] >> 22)
4160 + return sp[0];
4161 + if (sp[1] >> 22)
4162 + return sp[1];
4163 + #endif
4164 ++
4165 ++#endif
4166 + }
4167 + #endif
4168 ++
4169 ++ if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->xcs))
4170 ++ pc += __KERNEL_TEXT_OFFSET;
4171 ++
4172 + return pc;
4173 + }
4174 + EXPORT_SYMBOL(profile_pc);
4175 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/traps.c linux-2.6.23.15-grsec/arch/i386/kernel/traps.c
4176 +--- linux-2.6.23.15/arch/i386/kernel/traps.c 2007-10-09 21:31:38.000000000 +0100
4177 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/traps.c 2008-02-11 10:37:44.000000000 +0000
4178 +@@ -31,6 +31,7 @@
4179 + #include <linux/uaccess.h>
4180 + #include <linux/nmi.h>
4181 + #include <linux/bug.h>
4182 ++#include <linux/binfmts.h>
4183 +
4184 + #ifdef CONFIG_EISA
4185 + #include <linux/ioport.h>
4186 +@@ -70,12 +71,7 @@ asmlinkage int system_call(void);
4187 + /* Do we ignore FPU interrupts ? */
4188 + char ignore_fpu_irq = 0;
4189 +
4190 +-/*
4191 +- * The IDT has to be page-aligned to simplify the Pentium
4192 +- * F0 0F bug workaround.. We have a special link segment
4193 +- * for this.
4194 +- */
4195 +-struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
4196 ++extern struct desc_struct idt_table[256];
4197 +
4198 + asmlinkage void divide_error(void);
4199 + asmlinkage void debug(void);
4200 +@@ -297,7 +293,7 @@ void show_registers(struct pt_regs *regs
4201 + esp = (unsigned long) (&regs->esp);
4202 + savesegment(ss, ss);
4203 + savesegment(gs, gs);
4204 +- if (user_mode_vm(regs)) {
4205 ++ if (user_mode(regs)) {
4206 + in_kernel = 0;
4207 + esp = regs->esp;
4208 + ss = regs->xss & 0xffff;
4209 +@@ -329,17 +325,18 @@ void show_registers(struct pt_regs *regs
4210 + unsigned int code_prologue = code_bytes * 43 / 64;
4211 + unsigned int code_len = code_bytes;
4212 + unsigned char c;
4213 ++ unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->xcs) >> 3]);
4214 +
4215 + printk("\n" KERN_EMERG "Stack: ");
4216 + show_stack_log_lvl(NULL, regs, (unsigned long *)esp, KERN_EMERG);
4217 +
4218 + printk(KERN_EMERG "Code: ");
4219 +
4220 +- eip = (u8 *)regs->eip - code_prologue;
4221 ++ eip = (u8 *)regs->eip - code_prologue + cs_base;
4222 + if (eip < (u8 *)PAGE_OFFSET ||
4223 + probe_kernel_address(eip, c)) {
4224 + /* try starting at EIP */
4225 +- eip = (u8 *)regs->eip;
4226 ++ eip = (u8 *)regs->eip + cs_base;
4227 + code_len = code_len - code_prologue + 1;
4228 + }
4229 + for (i = 0; i < code_len; i++, eip++) {
4230 +@@ -348,7 +345,7 @@ void show_registers(struct pt_regs *regs
4231 + printk(" Bad EIP value.");
4232 + break;
4233 + }
4234 +- if (eip == (u8 *)regs->eip)
4235 ++ if (eip == (u8 *)regs->eip + cs_base)
4236 + printk("<%02x> ", c);
4237 + else
4238 + printk("%02x ", c);
4239 +@@ -361,6 +358,7 @@ int is_valid_bugaddr(unsigned long eip)
4240 + {
4241 + unsigned short ud2;
4242 +
4243 ++ eip += __KERNEL_TEXT_OFFSET;
4244 + if (eip < PAGE_OFFSET)
4245 + return 0;
4246 + if (probe_kernel_address((unsigned short *)eip, ud2))
4247 +@@ -468,7 +466,7 @@ void die(const char * str, struct pt_reg
4248 +
4249 + static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
4250 + {
4251 +- if (!user_mode_vm(regs))
4252 ++ if (!user_mode(regs))
4253 + die(str, regs, err);
4254 + }
4255 +
4256 +@@ -484,7 +482,7 @@ static void __kprobes do_trap(int trapnr
4257 + goto trap_signal;
4258 + }
4259 +
4260 +- if (!user_mode(regs))
4261 ++ if (!user_mode_novm(regs))
4262 + goto kernel_trap;
4263 +
4264 + trap_signal: {
4265 +@@ -589,7 +587,7 @@ fastcall void __kprobes do_general_prote
4266 + long error_code)
4267 + {
4268 + int cpu = get_cpu();
4269 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
4270 ++ struct tss_struct *tss = &init_tss[cpu];
4271 + struct thread_struct *thread = &current->thread;
4272 +
4273 + /*
4274 +@@ -622,9 +620,25 @@ fastcall void __kprobes do_general_prote
4275 + if (regs->eflags & VM_MASK)
4276 + goto gp_in_vm86;
4277 +
4278 +- if (!user_mode(regs))
4279 ++ if (!user_mode_novm(regs))
4280 + goto gp_in_kernel;
4281 +
4282 ++#ifdef CONFIG_PAX_PAGEEXEC
4283 ++ if (!nx_enabled && current->mm && (current->mm->pax_flags & MF_PAX_PAGEEXEC)) {
4284 ++ struct mm_struct *mm = current->mm;
4285 ++ unsigned long limit;
4286 ++
4287 ++ down_write(&mm->mmap_sem);
4288 ++ limit = mm->context.user_cs_limit;
4289 ++ if (limit < TASK_SIZE) {
4290 ++ track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC);
4291 ++ up_write(&mm->mmap_sem);
4292 ++ return;
4293 ++ }
4294 ++ up_write(&mm->mmap_sem);
4295 ++ }
4296 ++#endif
4297 ++
4298 + current->thread.error_code = error_code;
4299 + current->thread.trap_no = 13;
4300 + if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) &&
4301 +@@ -649,6 +663,13 @@ gp_in_kernel:
4302 + if (notify_die(DIE_GPF, "general protection fault", regs,
4303 + error_code, 13, SIGSEGV) == NOTIFY_STOP)
4304 + return;
4305 ++
4306 ++#ifdef CONFIG_PAX_KERNEXEC
4307 ++ if ((regs->xcs & 0xFFFF) == __KERNEL_CS)
4308 ++ die("PAX: suspicious general protection fault", regs, error_code);
4309 ++ else
4310 ++#endif
4311 ++
4312 + die("general protection fault", regs, error_code);
4313 + }
4314 + }
4315 +@@ -738,7 +759,7 @@ void __kprobes die_nmi(struct pt_regs *r
4316 + /* If we are in kernel we are probably nested up pretty bad
4317 + * and might aswell get out now while we still can.
4318 + */
4319 +- if (!user_mode_vm(regs)) {
4320 ++ if (!user_mode(regs)) {
4321 + current->thread.trap_no = 2;
4322 + crash_kexec(regs);
4323 + }
4324 +@@ -885,7 +906,7 @@ fastcall void __kprobes do_debug(struct
4325 + * check for kernel mode by just checking the CPL
4326 + * of CS.
4327 + */
4328 +- if (!user_mode(regs))
4329 ++ if (!user_mode_novm(regs))
4330 + goto clear_TF_reenable;
4331 + }
4332 +
4333 +@@ -1063,18 +1084,14 @@ fastcall void do_spurious_interrupt_bug(
4334 + fastcall unsigned long patch_espfix_desc(unsigned long uesp,
4335 + unsigned long kesp)
4336 + {
4337 +- struct desc_struct *gdt = __get_cpu_var(gdt_page).gdt;
4338 + unsigned long base = (kesp - uesp) & -THREAD_SIZE;
4339 + unsigned long new_kesp = kesp - base;
4340 + unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
4341 +- __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
4342 ++ __u32 a, b;
4343 ++
4344 + /* Set up base for espfix segment */
4345 +- desc &= 0x00f0ff0000000000ULL;
4346 +- desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
4347 +- ((((__u64)base) << 32) & 0xff00000000000000ULL) |
4348 +- ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
4349 +- (lim_pages & 0xffff);
4350 +- *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
4351 ++ pack_descriptor(&a, &b, base, lim_pages, 0x93, 0xC);
4352 ++ write_gdt_entry(get_cpu_gdt_table(smp_processor_id()), GDT_ENTRY_ESPFIX_SS, a, b);
4353 + return new_kesp;
4354 + }
4355 +
4356 +@@ -1123,7 +1140,7 @@ void __init trap_init_f00f_bug(void)
4357 + * Update the IDT descriptor and reload the IDT so that
4358 + * it uses the read-only mapped virtual address.
4359 + */
4360 +- idt_descr.address = fix_to_virt(FIX_F00F_IDT);
4361 ++ idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
4362 + load_idt(&idt_descr);
4363 + }
4364 + #endif
4365 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/tsc.c linux-2.6.23.15-grsec/arch/i386/kernel/tsc.c
4366 +--- linux-2.6.23.15/arch/i386/kernel/tsc.c 2008-02-11 10:36:03.000000000 +0000
4367 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/tsc.c 2008-02-11 10:37:44.000000000 +0000
4368 +@@ -322,7 +322,7 @@ static struct dmi_system_id __initdata b
4369 + DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
4370 + },
4371 + },
4372 +- {}
4373 ++ { NULL, NULL, {{0, NULL}}, NULL}
4374 + };
4375 +
4376 + /*
4377 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/vm86.c linux-2.6.23.15-grsec/arch/i386/kernel/vm86.c
4378 +--- linux-2.6.23.15/arch/i386/kernel/vm86.c 2007-10-09 21:31:38.000000000 +0100
4379 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/vm86.c 2008-02-11 10:37:44.000000000 +0000
4380 +@@ -148,7 +148,7 @@ struct pt_regs * fastcall save_v86_state
4381 + do_exit(SIGSEGV);
4382 + }
4383 +
4384 +- tss = &per_cpu(init_tss, get_cpu());
4385 ++ tss = init_tss + get_cpu();
4386 + current->thread.esp0 = current->thread.saved_esp0;
4387 + current->thread.sysenter_cs = __KERNEL_CS;
4388 + load_esp0(tss, &current->thread);
4389 +@@ -324,7 +324,7 @@ static void do_sys_vm86(struct kernel_vm
4390 + tsk->thread.saved_fs = info->regs32->xfs;
4391 + savesegment(gs, tsk->thread.saved_gs);
4392 +
4393 +- tss = &per_cpu(init_tss, get_cpu());
4394 ++ tss = init_tss + get_cpu();
4395 + tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
4396 + if (cpu_has_sep)
4397 + tsk->thread.sysenter_cs = 0;
4398 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/vmi.c linux-2.6.23.15-grsec/arch/i386/kernel/vmi.c
4399 +--- linux-2.6.23.15/arch/i386/kernel/vmi.c 2007-10-09 21:31:38.000000000 +0100
4400 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/vmi.c 2008-02-11 10:37:44.000000000 +0000
4401 +@@ -98,18 +98,43 @@ static unsigned patch_internal(int call,
4402 + {
4403 + u64 reloc;
4404 + struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
4405 ++
4406 ++#ifdef CONFIG_PAX_KERNEXEC
4407 ++ unsigned long cr0;
4408 ++#endif
4409 ++
4410 + reloc = call_vrom_long_func(vmi_rom, get_reloc, call);
4411 + switch(rel->type) {
4412 + case VMI_RELOCATION_CALL_REL:
4413 + BUG_ON(len < 5);
4414 ++
4415 ++#ifdef CONFIG_PAX_KERNEXEC
4416 ++ pax_open_kernel(cr0);
4417 ++#endif
4418 ++
4419 + *(char *)insnbuf = MNEM_CALL;
4420 + patch_offset(insnbuf, eip, (unsigned long)rel->eip);
4421 ++
4422 ++#ifdef CONFIG_PAX_KERNEXEC
4423 ++ pax_close_kernel(cr0);
4424 ++#endif
4425 ++
4426 + return 5;
4427 +
4428 + case VMI_RELOCATION_JUMP_REL:
4429 + BUG_ON(len < 5);
4430 ++
4431 ++#ifdef CONFIG_PAX_KERNEXEC
4432 ++ pax_open_kernel(cr0);
4433 ++#endif
4434 ++
4435 + *(char *)insnbuf = MNEM_JMP;
4436 + patch_offset(insnbuf, eip, (unsigned long)rel->eip);
4437 ++
4438 ++#ifdef CONFIG_PAX_KERNEXEC
4439 ++ pax_close_kernel(cr0);
4440 ++#endif
4441 ++
4442 + return 5;
4443 +
4444 + case VMI_RELOCATION_NOP:
4445 +@@ -492,14 +517,14 @@ static void vmi_set_pud(pud_t *pudp, pud
4446 +
4447 + static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
4448 + {
4449 +- const pte_t pte = { 0 };
4450 ++ const pte_t pte = __pte(0ULL);
4451 + vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE);
4452 + vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
4453 + }
4454 +
4455 + static void vmi_pmd_clear(pmd_t *pmd)
4456 + {
4457 +- const pte_t pte = { 0 };
4458 ++ const pte_t pte = __pte(0ULL);
4459 + vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD);
4460 + vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD);
4461 + }
4462 +@@ -528,8 +553,8 @@ vmi_startup_ipi_hook(int phys_apicid, un
4463 + ap.ss = __KERNEL_DS;
4464 + ap.esp = (unsigned long) start_esp;
4465 +
4466 +- ap.ds = __USER_DS;
4467 +- ap.es = __USER_DS;
4468 ++ ap.ds = __KERNEL_DS;
4469 ++ ap.es = __KERNEL_DS;
4470 + ap.fs = __KERNEL_PERCPU;
4471 + ap.gs = 0;
4472 +
4473 +@@ -726,12 +751,20 @@ static inline int __init activate_vmi(vo
4474 + u64 reloc;
4475 + const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc;
4476 +
4477 ++#ifdef CONFIG_PAX_KERNEXEC
4478 ++ unsigned long cr0;
4479 ++#endif
4480 ++
4481 + if (call_vrom_func(vmi_rom, vmi_init) != 0) {
4482 + printk(KERN_ERR "VMI ROM failed to initialize!");
4483 + return 0;
4484 + }
4485 + savesegment(cs, kernel_cs);
4486 +
4487 ++#ifdef CONFIG_PAX_KERNEXEC
4488 ++ pax_open_kernel(cr0);
4489 ++#endif
4490 ++
4491 + paravirt_ops.paravirt_enabled = 1;
4492 + paravirt_ops.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
4493 +
4494 +@@ -910,6 +943,10 @@ static inline int __init activate_vmi(vo
4495 +
4496 + para_fill(safe_halt, Halt);
4497 +
4498 ++#ifdef CONFIG_PAX_KERNEXEC
4499 ++ pax_close_kernel(cr0);
4500 ++#endif
4501 ++
4502 + /*
4503 + * Alternative instruction rewriting doesn't happen soon enough
4504 + * to convert VMI_IRET to a call instead of a jump; so we have
4505 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/vmlinux.lds.S linux-2.6.23.15-grsec/arch/i386/kernel/vmlinux.lds.S
4506 +--- linux-2.6.23.15/arch/i386/kernel/vmlinux.lds.S 2007-10-09 21:31:38.000000000 +0100
4507 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/vmlinux.lds.S 2008-02-11 10:37:44.000000000 +0000
4508 +@@ -21,6 +21,13 @@
4509 + #include <asm/page.h>
4510 + #include <asm/cache.h>
4511 + #include <asm/boot.h>
4512 ++#include <asm/segment.h>
4513 ++
4514 ++#ifdef CONFIG_X86_PAE
4515 ++#define PMD_SHIFT 21
4516 ++#else
4517 ++#define PMD_SHIFT 22
4518 ++#endif
4519 +
4520 + OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
4521 + OUTPUT_ARCH(i386)
4522 +@@ -28,22 +35,124 @@ ENTRY(phys_startup_32)
4523 + jiffies = jiffies_64;
4524 +
4525 + PHDRS {
4526 +- text PT_LOAD FLAGS(5); /* R_E */
4527 +- data PT_LOAD FLAGS(7); /* RWE */
4528 +- note PT_NOTE FLAGS(0); /* ___ */
4529 ++ initdata PT_LOAD FLAGS(6); /* RW_ */
4530 ++ percpu PT_LOAD FLAGS(6); /* RW_ */
4531 ++ inittext PT_LOAD FLAGS(5); /* R_E */
4532 ++ text PT_LOAD FLAGS(5); /* R_E */
4533 ++ rodata PT_LOAD FLAGS(4); /* R__ */
4534 ++ data PT_LOAD FLAGS(6); /* RW_ */
4535 ++ note PT_NOTE FLAGS(0); /* ___ */
4536 + }
4537 + SECTIONS
4538 + {
4539 + . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
4540 +- phys_startup_32 = startup_32 - LOAD_OFFSET;
4541 +
4542 +- .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
4543 +- _text = .; /* Text and read-only data */
4544 ++ .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
4545 ++ phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
4546 ++ *(.text.startup)
4547 ++ } :initdata
4548 ++
4549 ++ /* might get freed after init */
4550 ++ . = ALIGN(4096);
4551 ++ .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
4552 ++ __smp_locks = .;
4553 ++ *(.smp_locks)
4554 ++ __smp_locks_end = .;
4555 ++ }
4556 ++ /* will be freed after init
4557 ++ * Following ALIGN() is required to make sure no other data falls on the
4558 ++ * same page where __smp_alt_end is pointing as that page might be freed
4559 ++ * after boot. Always make sure that ALIGN() directive is present after
4560 ++ * the section which contains __smp_alt_end.
4561 ++ */
4562 ++ . = ALIGN(4096);
4563 ++
4564 ++ /* will be freed after init */
4565 ++ .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
4566 ++ __init_begin = .;
4567 ++ *(.init.data)
4568 ++ }
4569 ++ . = ALIGN(16);
4570 ++ .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
4571 ++ __setup_start = .;
4572 ++ *(.init.setup)
4573 ++ __setup_end = .;
4574 ++ }
4575 ++ .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
4576 ++ __initcall_start = .;
4577 ++ INITCALLS
4578 ++ __initcall_end = .;
4579 ++ }
4580 ++ .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
4581 ++ __con_initcall_start = .;
4582 ++ *(.con_initcall.init)
4583 ++ __con_initcall_end = .;
4584 ++ }
4585 ++ SECURITY_INIT
4586 ++ . = ALIGN(4);
4587 ++ .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
4588 ++ __alt_instructions = .;
4589 ++ *(.altinstructions)
4590 ++ __alt_instructions_end = .;
4591 ++ }
4592 ++ .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
4593 ++ *(.altinstr_replacement)
4594 ++ }
4595 ++ . = ALIGN(4);
4596 ++ .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
4597 ++ __parainstructions = .;
4598 ++ *(.parainstructions)
4599 ++ __parainstructions_end = .;
4600 ++ }
4601 ++ .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
4602 ++#if defined(CONFIG_BLK_DEV_INITRD)
4603 ++ . = ALIGN(4096);
4604 ++ .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
4605 ++ __initramfs_start = .;
4606 ++ *(.init.ramfs)
4607 ++ __initramfs_end = .;
4608 ++ }
4609 ++#endif
4610 ++ . = ALIGN(4096);
4611 ++ per_cpu_start = .;
4612 ++ .data.percpu (0) : AT(ADDR(.data.percpu) - LOAD_OFFSET + per_cpu_start) {
4613 ++ __per_cpu_start = . + per_cpu_start;
4614 ++ LONG(0)
4615 ++ *(.data.percpu)
4616 ++ *(.data.percpu.shared_aligned)
4617 ++ __per_cpu_end = . + per_cpu_start;
4618 ++ } :percpu
4619 ++ . += per_cpu_start;
4620 ++
4621 ++ /* read-only */
4622 ++
4623 ++ . = ALIGN(4096); /* Init code and data */
4624 ++ .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
4625 ++ _sinittext = .;
4626 ++ *(.init.text)
4627 ++ _einittext = .;
4628 ++ } :inittext
4629 ++
4630 ++ /* .exit.text is discard at runtime, not link time, to deal with references
4631 ++ from .altinstructions and .eh_frame */
4632 ++ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { *(.exit.text) }
4633 ++
4634 ++ .filler : AT(ADDR(.filler) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
4635 ++ BYTE(0)
4636 ++ . = ALIGN(4*1024*1024) - 1;
4637 ++ }
4638 ++
4639 ++ /* freed after init ends here */
4640 ++
4641 ++ .text.head : AT(ADDR(.text.head) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
4642 ++ __init_end = . + __KERNEL_TEXT_OFFSET;
4643 ++ KERNEL_TEXT_OFFSET = . + __KERNEL_TEXT_OFFSET;
4644 ++ _text = .; /* Text and read-only data */
4645 + *(.text.head)
4646 + } :text = 0x9090
4647 +
4648 + /* read-only */
4649 +- .text : AT(ADDR(.text) - LOAD_OFFSET) {
4650 ++ .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
4651 + TEXT_TEXT
4652 + SCHED_TEXT
4653 + LOCK_TEXT
4654 +@@ -53,16 +162,17 @@ SECTIONS
4655 + _etext = .; /* End of text section */
4656 + } :text = 0x9090
4657 +
4658 +- . = ALIGN(16); /* Exception table */
4659 ++ . += __KERNEL_TEXT_OFFSET;
4660 ++ . = ALIGN(4096); /* Exception table */
4661 + __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
4662 + __start___ex_table = .;
4663 + *(__ex_table)
4664 + __stop___ex_table = .;
4665 +- }
4666 ++ } :rodata
4667 +
4668 +- NOTES :text :note
4669 ++ NOTES :rodata :note
4670 +
4671 +- BUG_TABLE :text
4672 ++ BUG_TABLE :rodata
4673 +
4674 + . = ALIGN(4);
4675 + .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
4676 +@@ -73,9 +183,36 @@ SECTIONS
4677 +
4678 + RODATA
4679 +
4680 ++ . = ALIGN(4096);
4681 ++ .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
4682 ++ *(.idt)
4683 ++ . = ALIGN(4096);
4684 ++ *(.empty_zero_page)
4685 ++ *(.swapper_pm_dir)
4686 ++ *(.swapper_pg_dir)
4687 ++ }
4688 ++
4689 ++#ifdef CONFIG_PAX_KERNEXEC
4690 ++
4691 ++#ifdef CONFIG_MODULES
4692 ++ . = ALIGN(4096);
4693 ++ .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
4694 ++ MODULES_VADDR = .;
4695 ++ BYTE(0)
4696 ++ . += (6 * 1024 * 1024);
4697 ++ . = ALIGN(1 << PMD_SHIFT) - 1;
4698 ++ MODULES_END = .;
4699 ++ }
4700 ++#else
4701 ++ . = ALIGN(1 << PMD_SHIFT) - 1;
4702 ++#endif
4703 ++
4704 ++#endif
4705 ++
4706 + /* writeable */
4707 + . = ALIGN(4096);
4708 + .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
4709 ++ _data = .;
4710 + DATA_DATA
4711 + CONSTRUCTORS
4712 + } :data
4713 +@@ -91,7 +228,6 @@ SECTIONS
4714 + . = ALIGN(4096);
4715 + .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
4716 + *(.data.page_aligned)
4717 +- *(.data.idt)
4718 + }
4719 +
4720 + . = ALIGN(32);
4721 +@@ -111,86 +247,7 @@ SECTIONS
4722 + *(.data.init_task)
4723 + }
4724 +
4725 +- /* might get freed after init */
4726 +- . = ALIGN(4096);
4727 +- .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
4728 +- __smp_locks = .;
4729 +- *(.smp_locks)
4730 +- __smp_locks_end = .;
4731 +- }
4732 +- /* will be freed after init
4733 +- * Following ALIGN() is required to make sure no other data falls on the
4734 +- * same page where __smp_alt_end is pointing as that page might be freed
4735 +- * after boot. Always make sure that ALIGN() directive is present after
4736 +- * the section which contains __smp_alt_end.
4737 +- */
4738 +- . = ALIGN(4096);
4739 +-
4740 +- /* will be freed after init */
4741 +- . = ALIGN(4096); /* Init code and data */
4742 +- .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
4743 +- __init_begin = .;
4744 +- _sinittext = .;
4745 +- *(.init.text)
4746 +- _einittext = .;
4747 +- }
4748 +- .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
4749 +- . = ALIGN(16);
4750 +- .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
4751 +- __setup_start = .;
4752 +- *(.init.setup)
4753 +- __setup_end = .;
4754 +- }
4755 +- .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
4756 +- __initcall_start = .;
4757 +- INITCALLS
4758 +- __initcall_end = .;
4759 +- }
4760 +- .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
4761 +- __con_initcall_start = .;
4762 +- *(.con_initcall.init)
4763 +- __con_initcall_end = .;
4764 +- }
4765 +- SECURITY_INIT
4766 +- . = ALIGN(4);
4767 +- .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
4768 +- __alt_instructions = .;
4769 +- *(.altinstructions)
4770 +- __alt_instructions_end = .;
4771 +- }
4772 +- .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
4773 +- *(.altinstr_replacement)
4774 +- }
4775 +- . = ALIGN(4);
4776 +- .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
4777 +- __parainstructions = .;
4778 +- *(.parainstructions)
4779 +- __parainstructions_end = .;
4780 +- }
4781 +- /* .exit.text is discard at runtime, not link time, to deal with references
4782 +- from .altinstructions and .eh_frame */
4783 +- .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
4784 +- .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
4785 +-#if defined(CONFIG_BLK_DEV_INITRD)
4786 +- . = ALIGN(4096);
4787 +- .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
4788 +- __initramfs_start = .;
4789 +- *(.init.ramfs)
4790 +- __initramfs_end = .;
4791 +- }
4792 +-#endif
4793 +- . = ALIGN(4096);
4794 +- .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
4795 +- __per_cpu_start = .;
4796 +- *(.data.percpu)
4797 +- *(.data.percpu.shared_aligned)
4798 +- __per_cpu_end = .;
4799 +- }
4800 +- . = ALIGN(4096);
4801 +- /* freed after init ends here */
4802 +-
4803 + .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
4804 +- __init_end = .;
4805 + __bss_start = .; /* BSS */
4806 + *(.bss.page_aligned)
4807 + *(.bss)
4808 +diff -Nurp linux-2.6.23.15/arch/i386/lib/checksum.S linux-2.6.23.15-grsec/arch/i386/lib/checksum.S
4809 +--- linux-2.6.23.15/arch/i386/lib/checksum.S 2007-10-09 21:31:38.000000000 +0100
4810 ++++ linux-2.6.23.15-grsec/arch/i386/lib/checksum.S 2008-02-11 10:37:44.000000000 +0000
4811 +@@ -28,7 +28,8 @@
4812 + #include <linux/linkage.h>
4813 + #include <asm/dwarf2.h>
4814 + #include <asm/errno.h>
4815 +-
4816 ++#include <asm/segment.h>
4817 ++
4818 + /*
4819 + * computes a partial checksum, e.g. for TCP/UDP fragments
4820 + */
4821 +@@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic (
4822 +
4823 + #define ARGBASE 16
4824 + #define FP 12
4825 +-
4826 +-ENTRY(csum_partial_copy_generic)
4827 ++
4828 ++ENTRY(csum_partial_copy_generic_to_user)
4829 + CFI_STARTPROC
4830 ++ pushl $(__USER_DS)
4831 ++ CFI_ADJUST_CFA_OFFSET 4
4832 ++ popl %es
4833 ++ CFI_ADJUST_CFA_OFFSET -4
4834 ++ jmp csum_partial_copy_generic
4835 ++
4836 ++ENTRY(csum_partial_copy_generic_from_user)
4837 ++ pushl $(__USER_DS)
4838 ++ CFI_ADJUST_CFA_OFFSET 4
4839 ++ popl %ds
4840 ++ CFI_ADJUST_CFA_OFFSET -4
4841 ++
4842 ++ENTRY(csum_partial_copy_generic)
4843 + subl $4,%esp
4844 + CFI_ADJUST_CFA_OFFSET 4
4845 + pushl %edi
4846 +@@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic)
4847 + jmp 4f
4848 + SRC(1: movw (%esi), %bx )
4849 + addl $2, %esi
4850 +-DST( movw %bx, (%edi) )
4851 ++DST( movw %bx, %es:(%edi) )
4852 + addl $2, %edi
4853 + addw %bx, %ax
4854 + adcl $0, %eax
4855 +@@ -343,30 +357,30 @@ DST( movw %bx, (%edi) )
4856 + SRC(1: movl (%esi), %ebx )
4857 + SRC( movl 4(%esi), %edx )
4858 + adcl %ebx, %eax
4859 +-DST( movl %ebx, (%edi) )
4860 ++DST( movl %ebx, %es:(%edi) )
4861 + adcl %edx, %eax
4862 +-DST( movl %edx, 4(%edi) )
4863 ++DST( movl %edx, %es:4(%edi) )
4864 +
4865 + SRC( movl 8(%esi), %ebx )
4866 + SRC( movl 12(%esi), %edx )
4867 + adcl %ebx, %eax
4868 +-DST( movl %ebx, 8(%edi) )
4869 ++DST( movl %ebx, %es:8(%edi) )
4870 + adcl %edx, %eax
4871 +-DST( movl %edx, 12(%edi) )
4872 ++DST( movl %edx, %es:12(%edi) )
4873 +
4874 + SRC( movl 16(%esi), %ebx )
4875 + SRC( movl 20(%esi), %edx )
4876 + adcl %ebx, %eax
4877 +-DST( movl %ebx, 16(%edi) )
4878 ++DST( movl %ebx, %es:16(%edi) )
4879 + adcl %edx, %eax
4880 +-DST( movl %edx, 20(%edi) )
4881 ++DST( movl %edx, %es:20(%edi) )
4882 +
4883 + SRC( movl 24(%esi), %ebx )
4884 + SRC( movl 28(%esi), %edx )
4885 + adcl %ebx, %eax
4886 +-DST( movl %ebx, 24(%edi) )
4887 ++DST( movl %ebx, %es:24(%edi) )
4888 + adcl %edx, %eax
4889 +-DST( movl %edx, 28(%edi) )
4890 ++DST( movl %edx, %es:28(%edi) )
4891 +
4892 + lea 32(%esi), %esi
4893 + lea 32(%edi), %edi
4894 +@@ -380,7 +394,7 @@ DST( movl %edx, 28(%edi) )
4895 + shrl $2, %edx # This clears CF
4896 + SRC(3: movl (%esi), %ebx )
4897 + adcl %ebx, %eax
4898 +-DST( movl %ebx, (%edi) )
4899 ++DST( movl %ebx, %es:(%edi) )
4900 + lea 4(%esi), %esi
4901 + lea 4(%edi), %edi
4902 + dec %edx
4903 +@@ -392,12 +406,12 @@ DST( movl %ebx, (%edi) )
4904 + jb 5f
4905 + SRC( movw (%esi), %cx )
4906 + leal 2(%esi), %esi
4907 +-DST( movw %cx, (%edi) )
4908 ++DST( movw %cx, %es:(%edi) )
4909 + leal 2(%edi), %edi
4910 + je 6f
4911 + shll $16,%ecx
4912 + SRC(5: movb (%esi), %cl )
4913 +-DST( movb %cl, (%edi) )
4914 ++DST( movb %cl, %es:(%edi) )
4915 + 6: addl %ecx, %eax
4916 + adcl $0, %eax
4917 + 7:
4918 +@@ -408,7 +422,7 @@ DST( movb %cl, (%edi) )
4919 +
4920 + 6001:
4921 + movl ARGBASE+20(%esp), %ebx # src_err_ptr
4922 +- movl $-EFAULT, (%ebx)
4923 ++ movl $-EFAULT, %ss:(%ebx)
4924 +
4925 + # zero the complete destination - computing the rest
4926 + # is too much work
4927 +@@ -421,11 +435,19 @@ DST( movb %cl, (%edi) )
4928 +
4929 + 6002:
4930 + movl ARGBASE+24(%esp), %ebx # dst_err_ptr
4931 +- movl $-EFAULT,(%ebx)
4932 ++ movl $-EFAULT,%ss:(%ebx)
4933 + jmp 5000b
4934 +
4935 + .previous
4936 +
4937 ++ pushl %ss
4938 ++ CFI_ADJUST_CFA_OFFSET 4
4939 ++ popl %ds
4940 ++ CFI_ADJUST_CFA_OFFSET -4
4941 ++ pushl %ss
4942 ++ CFI_ADJUST_CFA_OFFSET 4
4943 ++ popl %es
4944 ++ CFI_ADJUST_CFA_OFFSET -4
4945 + popl %ebx
4946 + CFI_ADJUST_CFA_OFFSET -4
4947 + CFI_RESTORE ebx
4948 +@@ -439,26 +461,41 @@ DST( movb %cl, (%edi) )
4949 + CFI_ADJUST_CFA_OFFSET -4
4950 + ret
4951 + CFI_ENDPROC
4952 +-ENDPROC(csum_partial_copy_generic)
4953 ++ENDPROC(csum_partial_copy_generic_to_user)
4954 +
4955 + #else
4956 +
4957 + /* Version for PentiumII/PPro */
4958 +
4959 + #define ROUND1(x) \
4960 ++ nop; nop; nop; \
4961 + SRC(movl x(%esi), %ebx ) ; \
4962 + addl %ebx, %eax ; \
4963 +- DST(movl %ebx, x(%edi) ) ;
4964 ++ DST(movl %ebx, %es:x(%edi)) ;
4965 +
4966 + #define ROUND(x) \
4967 ++ nop; nop; nop; \
4968 + SRC(movl x(%esi), %ebx ) ; \
4969 + adcl %ebx, %eax ; \
4970 +- DST(movl %ebx, x(%edi) ) ;
4971 ++ DST(movl %ebx, %es:x(%edi)) ;
4972 +
4973 + #define ARGBASE 12
4974 +-
4975 +-ENTRY(csum_partial_copy_generic)
4976 ++
4977 ++ENTRY(csum_partial_copy_generic_to_user)
4978 + CFI_STARTPROC
4979 ++ pushl $(__USER_DS)
4980 ++ CFI_ADJUST_CFA_OFFSET 4
4981 ++ popl %es
4982 ++ CFI_ADJUST_CFA_OFFSET -4
4983 ++ jmp csum_partial_copy_generic
4984 ++
4985 ++ENTRY(csum_partial_copy_generic_from_user)
4986 ++ pushl $(__USER_DS)
4987 ++ CFI_ADJUST_CFA_OFFSET 4
4988 ++ popl %ds
4989 ++ CFI_ADJUST_CFA_OFFSET -4
4990 ++
4991 ++ENTRY(csum_partial_copy_generic)
4992 + pushl %ebx
4993 + CFI_ADJUST_CFA_OFFSET 4
4994 + CFI_REL_OFFSET ebx, 0
4995 +@@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic)
4996 + subl %ebx, %edi
4997 + lea -1(%esi),%edx
4998 + andl $-32,%edx
4999 +- lea 3f(%ebx,%ebx), %ebx
5000 ++ lea 3f(%ebx,%ebx,2), %ebx
5001 + testl %esi, %esi
5002 + jmp *%ebx
5003 + 1: addl $64,%esi
5004 +@@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic)
5005 + jb 5f
5006 + SRC( movw (%esi), %dx )
5007 + leal 2(%esi), %esi
5008 +-DST( movw %dx, (%edi) )
5009 ++DST( movw %dx, %es:(%edi) )
5010 + leal 2(%edi), %edi
5011 + je 6f
5012 + shll $16,%edx
5013 + 5:
5014 + SRC( movb (%esi), %dl )
5015 +-DST( movb %dl, (%edi) )
5016 ++DST( movb %dl, %es:(%edi) )
5017 + 6: addl %edx, %eax
5018 + adcl $0, %eax
5019 + 7:
5020 + .section .fixup, "ax"
5021 + 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
5022 +- movl $-EFAULT, (%ebx)
5023 ++ movl $-EFAULT, %ss:(%ebx)
5024 + # zero the complete destination (computing the rest is too much work)
5025 + movl ARGBASE+8(%esp),%edi # dst
5026 + movl ARGBASE+12(%esp),%ecx # len
5027 +@@ -523,10 +560,18 @@ DST( movb %dl, (%edi) )
5028 + rep; stosb
5029 + jmp 7b
5030 + 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
5031 +- movl $-EFAULT, (%ebx)
5032 ++ movl $-EFAULT, %ss:(%ebx)
5033 + jmp 7b
5034 + .previous
5035 +
5036 ++ pushl %ss
5037 ++ CFI_ADJUST_CFA_OFFSET 4
5038 ++ popl %ds
5039 ++ CFI_ADJUST_CFA_OFFSET -4
5040 ++ pushl %ss
5041 ++ CFI_ADJUST_CFA_OFFSET 4
5042 ++ popl %es
5043 ++ CFI_ADJUST_CFA_OFFSET -4
5044 + popl %esi
5045 + CFI_ADJUST_CFA_OFFSET -4
5046 + CFI_RESTORE esi
5047 +@@ -538,7 +583,7 @@ DST( movb %dl, (%edi) )
5048 + CFI_RESTORE ebx
5049 + ret
5050 + CFI_ENDPROC
5051 +-ENDPROC(csum_partial_copy_generic)
5052 ++ENDPROC(csum_partial_copy_generic_to_user)
5053 +
5054 + #undef ROUND
5055 + #undef ROUND1
5056 +diff -Nurp linux-2.6.23.15/arch/i386/lib/getuser.S linux-2.6.23.15-grsec/arch/i386/lib/getuser.S
5057 +--- linux-2.6.23.15/arch/i386/lib/getuser.S 2007-10-09 21:31:38.000000000 +0100
5058 ++++ linux-2.6.23.15-grsec/arch/i386/lib/getuser.S 2008-02-11 10:37:44.000000000 +0000
5059 +@@ -11,7 +11,7 @@
5060 + #include <linux/linkage.h>
5061 + #include <asm/dwarf2.h>
5062 + #include <asm/thread_info.h>
5063 +-
5064 ++#include <asm/segment.h>
5065 +
5066 + /*
5067 + * __get_user_X
5068 +@@ -31,7 +31,11 @@ ENTRY(__get_user_1)
5069 + GET_THREAD_INFO(%edx)
5070 + cmpl TI_addr_limit(%edx),%eax
5071 + jae bad_get_user
5072 ++ pushl $(__USER_DS)
5073 ++ popl %ds
5074 + 1: movzbl (%eax),%edx
5075 ++ pushl %ss
5076 ++ pop %ds
5077 + xorl %eax,%eax
5078 + ret
5079 + CFI_ENDPROC
5080 +@@ -44,7 +48,11 @@ ENTRY(__get_user_2)
5081 + GET_THREAD_INFO(%edx)
5082 + cmpl TI_addr_limit(%edx),%eax
5083 + jae bad_get_user
5084 ++ pushl $(__USER_DS)
5085 ++ popl %ds
5086 + 2: movzwl -1(%eax),%edx
5087 ++ pushl %ss
5088 ++ pop %ds
5089 + xorl %eax,%eax
5090 + ret
5091 + CFI_ENDPROC
5092 +@@ -57,7 +65,11 @@ ENTRY(__get_user_4)
5093 + GET_THREAD_INFO(%edx)
5094 + cmpl TI_addr_limit(%edx),%eax
5095 + jae bad_get_user
5096 ++ pushl $(__USER_DS)
5097 ++ popl %ds
5098 + 3: movl -3(%eax),%edx
5099 ++ pushl %ss
5100 ++ pop %ds
5101 + xorl %eax,%eax
5102 + ret
5103 + CFI_ENDPROC
5104 +@@ -65,6 +77,8 @@ ENDPROC(__get_user_4)
5105 +
5106 + bad_get_user:
5107 + CFI_STARTPROC
5108 ++ pushl %ss
5109 ++ pop %ds
5110 + xorl %edx,%edx
5111 + movl $-14,%eax
5112 + ret
5113 +diff -Nurp linux-2.6.23.15/arch/i386/lib/mmx.c linux-2.6.23.15-grsec/arch/i386/lib/mmx.c
5114 +--- linux-2.6.23.15/arch/i386/lib/mmx.c 2007-10-09 21:31:38.000000000 +0100
5115 ++++ linux-2.6.23.15-grsec/arch/i386/lib/mmx.c 2008-02-11 10:37:44.000000000 +0000
5116 +@@ -30,6 +30,7 @@ void *_mmx_memcpy(void *to, const void *
5117 + {
5118 + void *p;
5119 + int i;
5120 ++ unsigned long cr0;
5121 +
5122 + if (unlikely(in_interrupt()))
5123 + return __memcpy(to, from, len);
5124 +@@ -40,52 +41,80 @@ void *_mmx_memcpy(void *to, const void *
5125 + kernel_fpu_begin();
5126 +
5127 + __asm__ __volatile__ (
5128 +- "1: prefetch (%0)\n" /* This set is 28 bytes */
5129 +- " prefetch 64(%0)\n"
5130 +- " prefetch 128(%0)\n"
5131 +- " prefetch 192(%0)\n"
5132 +- " prefetch 256(%0)\n"
5133 ++ "1: prefetch (%1)\n" /* This set is 28 bytes */
5134 ++ " prefetch 64(%1)\n"
5135 ++ " prefetch 128(%1)\n"
5136 ++ " prefetch 192(%1)\n"
5137 ++ " prefetch 256(%1)\n"
5138 + "2: \n"
5139 + ".section .fixup, \"ax\"\n"
5140 +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
5141 ++ "3: \n"
5142 ++
5143 ++#ifdef CONFIG_PAX_KERNEXEC
5144 ++ " movl %%cr0, %0\n"
5145 ++ " movl %0, %%eax\n"
5146 ++ " andl $0xFFFEFFFF, %%eax\n"
5147 ++ " movl %%eax, %%cr0\n"
5148 ++#endif
5149 ++
5150 ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
5151 ++
5152 ++#ifdef CONFIG_PAX_KERNEXEC
5153 ++ " movl %0, %%cr0\n"
5154 ++#endif
5155 ++
5156 + " jmp 2b\n"
5157 + ".previous\n"
5158 + ".section __ex_table,\"a\"\n"
5159 + " .align 4\n"
5160 + " .long 1b, 3b\n"
5161 + ".previous"
5162 +- : : "r" (from) );
5163 ++ : "=&r" (cr0) : "r" (from) : "ax");
5164 +
5165 +
5166 + for(; i>5; i--)
5167 + {
5168 + __asm__ __volatile__ (
5169 +- "1: prefetch 320(%0)\n"
5170 +- "2: movq (%0), %%mm0\n"
5171 +- " movq 8(%0), %%mm1\n"
5172 +- " movq 16(%0), %%mm2\n"
5173 +- " movq 24(%0), %%mm3\n"
5174 +- " movq %%mm0, (%1)\n"
5175 +- " movq %%mm1, 8(%1)\n"
5176 +- " movq %%mm2, 16(%1)\n"
5177 +- " movq %%mm3, 24(%1)\n"
5178 +- " movq 32(%0), %%mm0\n"
5179 +- " movq 40(%0), %%mm1\n"
5180 +- " movq 48(%0), %%mm2\n"
5181 +- " movq 56(%0), %%mm3\n"
5182 +- " movq %%mm0, 32(%1)\n"
5183 +- " movq %%mm1, 40(%1)\n"
5184 +- " movq %%mm2, 48(%1)\n"
5185 +- " movq %%mm3, 56(%1)\n"
5186 ++ "1: prefetch 320(%1)\n"
5187 ++ "2: movq (%1), %%mm0\n"
5188 ++ " movq 8(%1), %%mm1\n"
5189 ++ " movq 16(%1), %%mm2\n"
5190 ++ " movq 24(%1), %%mm3\n"
5191 ++ " movq %%mm0, (%2)\n"
5192 ++ " movq %%mm1, 8(%2)\n"
5193 ++ " movq %%mm2, 16(%2)\n"
5194 ++ " movq %%mm3, 24(%2)\n"
5195 ++ " movq 32(%1), %%mm0\n"
5196 ++ " movq 40(%1), %%mm1\n"
5197 ++ " movq 48(%1), %%mm2\n"
5198 ++ " movq 56(%1), %%mm3\n"
5199 ++ " movq %%mm0, 32(%2)\n"
5200 ++ " movq %%mm1, 40(%2)\n"
5201 ++ " movq %%mm2, 48(%2)\n"
5202 ++ " movq %%mm3, 56(%2)\n"
5203 + ".section .fixup, \"ax\"\n"
5204 +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
5205 ++ "3:\n"
5206 ++
5207 ++#ifdef CONFIG_PAX_KERNEXEC
5208 ++ " movl %%cr0, %0\n"
5209 ++ " movl %0, %%eax\n"
5210 ++ " andl $0xFFFEFFFF, %%eax\n"
5211 ++ " movl %%eax, %%cr0\n"
5212 ++#endif
5213 ++
5214 ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
5215 ++
5216 ++#ifdef CONFIG_PAX_KERNEXEC
5217 ++ " movl %0, %%cr0\n"
5218 ++#endif
5219 ++
5220 + " jmp 2b\n"
5221 + ".previous\n"
5222 + ".section __ex_table,\"a\"\n"
5223 + " .align 4\n"
5224 + " .long 1b, 3b\n"
5225 + ".previous"
5226 +- : : "r" (from), "r" (to) : "memory");
5227 ++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
5228 + from+=64;
5229 + to+=64;
5230 + }
5231 +@@ -164,6 +193,7 @@ static void fast_clear_page(void *page)
5232 + static void fast_copy_page(void *to, void *from)
5233 + {
5234 + int i;
5235 ++ unsigned long cr0;
5236 +
5237 + kernel_fpu_begin();
5238 +
5239 +@@ -171,51 +201,79 @@ static void fast_copy_page(void *to, voi
5240 + * but that is for later. -AV
5241 + */
5242 + __asm__ __volatile__ (
5243 +- "1: prefetch (%0)\n"
5244 +- " prefetch 64(%0)\n"
5245 +- " prefetch 128(%0)\n"
5246 +- " prefetch 192(%0)\n"
5247 +- " prefetch 256(%0)\n"
5248 ++ "1: prefetch (%1)\n"
5249 ++ " prefetch 64(%1)\n"
5250 ++ " prefetch 128(%1)\n"
5251 ++ " prefetch 192(%1)\n"
5252 ++ " prefetch 256(%1)\n"
5253 + "2: \n"
5254 + ".section .fixup, \"ax\"\n"
5255 +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
5256 ++ "3: \n"
5257 ++
5258 ++#ifdef CONFIG_PAX_KERNEXEC
5259 ++ " movl %%cr0, %0\n"
5260 ++ " movl %0, %%eax\n"
5261 ++ " andl $0xFFFEFFFF, %%eax\n"
5262 ++ " movl %%eax, %%cr0\n"
5263 ++#endif
5264 ++
5265 ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
5266 ++
5267 ++#ifdef CONFIG_PAX_KERNEXEC
5268 ++ " movl %0, %%cr0\n"
5269 ++#endif
5270 ++
5271 + " jmp 2b\n"
5272 + ".previous\n"
5273 + ".section __ex_table,\"a\"\n"
5274 + " .align 4\n"
5275 + " .long 1b, 3b\n"
5276 + ".previous"
5277 +- : : "r" (from) );
5278 ++ : "=&r" (cr0) : "r" (from) : "ax");
5279 +
5280 + for(i=0; i<(4096-320)/64; i++)
5281 + {
5282 + __asm__ __volatile__ (
5283 +- "1: prefetch 320(%0)\n"
5284 +- "2: movq (%0), %%mm0\n"
5285 +- " movntq %%mm0, (%1)\n"
5286 +- " movq 8(%0), %%mm1\n"
5287 +- " movntq %%mm1, 8(%1)\n"
5288 +- " movq 16(%0), %%mm2\n"
5289 +- " movntq %%mm2, 16(%1)\n"
5290 +- " movq 24(%0), %%mm3\n"
5291 +- " movntq %%mm3, 24(%1)\n"
5292 +- " movq 32(%0), %%mm4\n"
5293 +- " movntq %%mm4, 32(%1)\n"
5294 +- " movq 40(%0), %%mm5\n"
5295 +- " movntq %%mm5, 40(%1)\n"
5296 +- " movq 48(%0), %%mm6\n"
5297 +- " movntq %%mm6, 48(%1)\n"
5298 +- " movq 56(%0), %%mm7\n"
5299 +- " movntq %%mm7, 56(%1)\n"
5300 ++ "1: prefetch 320(%1)\n"
5301 ++ "2: movq (%1), %%mm0\n"
5302 ++ " movntq %%mm0, (%2)\n"
5303 ++ " movq 8(%1), %%mm1\n"
5304 ++ " movntq %%mm1, 8(%2)\n"
5305 ++ " movq 16(%1), %%mm2\n"
5306 ++ " movntq %%mm2, 16(%2)\n"
5307 ++ " movq 24(%1), %%mm3\n"
5308 ++ " movntq %%mm3, 24(%2)\n"
5309 ++ " movq 32(%1), %%mm4\n"
5310 ++ " movntq %%mm4, 32(%2)\n"
5311 ++ " movq 40(%1), %%mm5\n"
5312 ++ " movntq %%mm5, 40(%2)\n"
5313 ++ " movq 48(%1), %%mm6\n"
5314 ++ " movntq %%mm6, 48(%2)\n"
5315 ++ " movq 56(%1), %%mm7\n"
5316 ++ " movntq %%mm7, 56(%2)\n"
5317 + ".section .fixup, \"ax\"\n"
5318 +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
5319 ++ "3:\n"
5320 ++
5321 ++#ifdef CONFIG_PAX_KERNEXEC
5322 ++ " movl %%cr0, %0\n"
5323 ++ " movl %0, %%eax\n"
5324 ++ " andl $0xFFFEFFFF, %%eax\n"
5325 ++ " movl %%eax, %%cr0\n"
5326 ++#endif
5327 ++
5328 ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
5329 ++
5330 ++#ifdef CONFIG_PAX_KERNEXEC
5331 ++ " movl %0, %%cr0\n"
5332 ++#endif
5333 ++
5334 + " jmp 2b\n"
5335 + ".previous\n"
5336 + ".section __ex_table,\"a\"\n"
5337 + " .align 4\n"
5338 + " .long 1b, 3b\n"
5339 + ".previous"
5340 +- : : "r" (from), "r" (to) : "memory");
5341 ++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
5342 + from+=64;
5343 + to+=64;
5344 + }
5345 +@@ -296,56 +354,84 @@ static void fast_clear_page(void *page)
5346 + static void fast_copy_page(void *to, void *from)
5347 + {
5348 + int i;
5349 +-
5350 +-
5351 ++ unsigned long cr0;
5352 ++
5353 + kernel_fpu_begin();
5354 +
5355 + __asm__ __volatile__ (
5356 +- "1: prefetch (%0)\n"
5357 +- " prefetch 64(%0)\n"
5358 +- " prefetch 128(%0)\n"
5359 +- " prefetch 192(%0)\n"
5360 +- " prefetch 256(%0)\n"
5361 ++ "1: prefetch (%1)\n"
5362 ++ " prefetch 64(%1)\n"
5363 ++ " prefetch 128(%1)\n"
5364 ++ " prefetch 192(%1)\n"
5365 ++ " prefetch 256(%1)\n"
5366 + "2: \n"
5367 + ".section .fixup, \"ax\"\n"
5368 +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
5369 ++ "3: \n"
5370 ++
5371 ++#ifdef CONFIG_PAX_KERNEXEC
5372 ++ " movl %%cr0, %0\n"
5373 ++ " movl %0, %%eax\n"
5374 ++ " andl $0xFFFEFFFF, %%eax\n"
5375 ++ " movl %%eax, %%cr0\n"
5376 ++#endif
5377 ++
5378 ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
5379 ++
5380 ++#ifdef CONFIG_PAX_KERNEXEC
5381 ++ " movl %0, %%cr0\n"
5382 ++#endif
5383 ++
5384 + " jmp 2b\n"
5385 + ".previous\n"
5386 + ".section __ex_table,\"a\"\n"
5387 + " .align 4\n"
5388 + " .long 1b, 3b\n"
5389 + ".previous"
5390 +- : : "r" (from) );
5391 ++ : "=&r" (cr0) : "r" (from) : "ax");
5392 +
5393 + for(i=0; i<4096/64; i++)
5394 + {
5395 + __asm__ __volatile__ (
5396 +- "1: prefetch 320(%0)\n"
5397 +- "2: movq (%0), %%mm0\n"
5398 +- " movq 8(%0), %%mm1\n"
5399 +- " movq 16(%0), %%mm2\n"
5400 +- " movq 24(%0), %%mm3\n"
5401 +- " movq %%mm0, (%1)\n"
5402 +- " movq %%mm1, 8(%1)\n"
5403 +- " movq %%mm2, 16(%1)\n"
5404 +- " movq %%mm3, 24(%1)\n"
5405 +- " movq 32(%0), %%mm0\n"
5406 +- " movq 40(%0), %%mm1\n"
5407 +- " movq 48(%0), %%mm2\n"
5408 +- " movq 56(%0), %%mm3\n"
5409 +- " movq %%mm0, 32(%1)\n"
5410 +- " movq %%mm1, 40(%1)\n"
5411 +- " movq %%mm2, 48(%1)\n"
5412 +- " movq %%mm3, 56(%1)\n"
5413 ++ "1: prefetch 320(%1)\n"
5414 ++ "2: movq (%1), %%mm0\n"
5415 ++ " movq 8(%1), %%mm1\n"
5416 ++ " movq 16(%1), %%mm2\n"
5417 ++ " movq 24(%1), %%mm3\n"
5418 ++ " movq %%mm0, (%2)\n"
5419 ++ " movq %%mm1, 8(%2)\n"
5420 ++ " movq %%mm2, 16(%2)\n"
5421 ++ " movq %%mm3, 24(%2)\n"
5422 ++ " movq 32(%1), %%mm0\n"
5423 ++ " movq 40(%1), %%mm1\n"
5424 ++ " movq 48(%1), %%mm2\n"
5425 ++ " movq 56(%1), %%mm3\n"
5426 ++ " movq %%mm0, 32(%2)\n"
5427 ++ " movq %%mm1, 40(%2)\n"
5428 ++ " movq %%mm2, 48(%2)\n"
5429 ++ " movq %%mm3, 56(%2)\n"
5430 + ".section .fixup, \"ax\"\n"
5431 +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
5432 ++ "3:\n"
5433 ++
5434 ++#ifdef CONFIG_PAX_KERNEXEC
5435 ++ " movl %%cr0, %0\n"
5436 ++ " movl %0, %%eax\n"
5437 ++ " andl $0xFFFEFFFF, %%eax\n"
5438 ++ " movl %%eax, %%cr0\n"
5439 ++#endif
5440 ++
5441 ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
5442 ++
5443 ++#ifdef CONFIG_PAX_KERNEXEC
5444 ++ " movl %0, %%cr0\n"
5445 ++#endif
5446 ++
5447 + " jmp 2b\n"
5448 + ".previous\n"
5449 + ".section __ex_table,\"a\"\n"
5450 + " .align 4\n"
5451 + " .long 1b, 3b\n"
5452 + ".previous"
5453 +- : : "r" (from), "r" (to) : "memory");
5454 ++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
5455 + from+=64;
5456 + to+=64;
5457 + }
5458 +diff -Nurp linux-2.6.23.15/arch/i386/lib/putuser.S linux-2.6.23.15-grsec/arch/i386/lib/putuser.S
5459 +--- linux-2.6.23.15/arch/i386/lib/putuser.S 2007-10-09 21:31:38.000000000 +0100
5460 ++++ linux-2.6.23.15-grsec/arch/i386/lib/putuser.S 2008-02-11 10:37:44.000000000 +0000
5461 +@@ -11,7 +11,7 @@
5462 + #include <linux/linkage.h>
5463 + #include <asm/dwarf2.h>
5464 + #include <asm/thread_info.h>
5465 +-
5466 ++#include <asm/segment.h>
5467 +
5468 + /*
5469 + * __put_user_X
5470 +@@ -41,7 +41,11 @@ ENTRY(__put_user_1)
5471 + ENTER
5472 + cmpl TI_addr_limit(%ebx),%ecx
5473 + jae bad_put_user
5474 ++ pushl $(__USER_DS)
5475 ++ popl %ds
5476 + 1: movb %al,(%ecx)
5477 ++ pushl %ss
5478 ++ popl %ds
5479 + xorl %eax,%eax
5480 + EXIT
5481 + ENDPROC(__put_user_1)
5482 +@@ -52,7 +56,11 @@ ENTRY(__put_user_2)
5483 + subl $1,%ebx
5484 + cmpl %ebx,%ecx
5485 + jae bad_put_user
5486 ++ pushl $(__USER_DS)
5487 ++ popl %ds
5488 + 2: movw %ax,(%ecx)
5489 ++ pushl %ss
5490 ++ popl %ds
5491 + xorl %eax,%eax
5492 + EXIT
5493 + ENDPROC(__put_user_2)
5494 +@@ -63,7 +71,11 @@ ENTRY(__put_user_4)
5495 + subl $3,%ebx
5496 + cmpl %ebx,%ecx
5497 + jae bad_put_user
5498 ++ pushl $(__USER_DS)
5499 ++ popl %ds
5500 + 3: movl %eax,(%ecx)
5501 ++ pushl %ss
5502 ++ popl %ds
5503 + xorl %eax,%eax
5504 + EXIT
5505 + ENDPROC(__put_user_4)
5506 +@@ -74,8 +86,12 @@ ENTRY(__put_user_8)
5507 + subl $7,%ebx
5508 + cmpl %ebx,%ecx
5509 + jae bad_put_user
5510 ++ pushl $(__USER_DS)
5511 ++ popl %ds
5512 + 4: movl %eax,(%ecx)
5513 + 5: movl %edx,4(%ecx)
5514 ++ pushl %ss
5515 ++ popl %ds
5516 + xorl %eax,%eax
5517 + EXIT
5518 + ENDPROC(__put_user_8)
5519 +@@ -85,6 +101,10 @@ bad_put_user:
5520 + CFI_DEF_CFA esp, 2*4
5521 + CFI_OFFSET eip, -1*4
5522 + CFI_OFFSET ebx, -2*4
5523 ++ pushl %ss
5524 ++ CFI_ADJUST_CFA_OFFSET 4
5525 ++ popl %ds
5526 ++ CFI_ADJUST_CFA_OFFSET -4
5527 + movl $-14,%eax
5528 + EXIT
5529 + END(bad_put_user)
5530 +diff -Nurp linux-2.6.23.15/arch/i386/lib/usercopy.c linux-2.6.23.15-grsec/arch/i386/lib/usercopy.c
5531 +--- linux-2.6.23.15/arch/i386/lib/usercopy.c 2007-10-09 21:31:38.000000000 +0100
5532 ++++ linux-2.6.23.15-grsec/arch/i386/lib/usercopy.c 2008-02-11 10:37:44.000000000 +0000
5533 +@@ -29,34 +29,41 @@ static inline int __movsl_is_ok(unsigned
5534 + * Copy a null terminated string from userspace.
5535 + */
5536 +
5537 +-#define __do_strncpy_from_user(dst,src,count,res) \
5538 +-do { \
5539 +- int __d0, __d1, __d2; \
5540 +- might_sleep(); \
5541 +- __asm__ __volatile__( \
5542 +- " testl %1,%1\n" \
5543 +- " jz 2f\n" \
5544 +- "0: lodsb\n" \
5545 +- " stosb\n" \
5546 +- " testb %%al,%%al\n" \
5547 +- " jz 1f\n" \
5548 +- " decl %1\n" \
5549 +- " jnz 0b\n" \
5550 +- "1: subl %1,%0\n" \
5551 +- "2:\n" \
5552 +- ".section .fixup,\"ax\"\n" \
5553 +- "3: movl %5,%0\n" \
5554 +- " jmp 2b\n" \
5555 +- ".previous\n" \
5556 +- ".section __ex_table,\"a\"\n" \
5557 +- " .align 4\n" \
5558 +- " .long 0b,3b\n" \
5559 +- ".previous" \
5560 +- : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \
5561 +- "=&D" (__d2) \
5562 +- : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
5563 +- : "memory"); \
5564 +-} while (0)
5565 ++static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
5566 ++{
5567 ++ int __d0, __d1, __d2;
5568 ++ long res = -EFAULT;
5569 ++
5570 ++ might_sleep();
5571 ++ __asm__ __volatile__(
5572 ++ " movw %w10,%%ds\n"
5573 ++ " testl %1,%1\n"
5574 ++ " jz 2f\n"
5575 ++ "0: lodsb\n"
5576 ++ " stosb\n"
5577 ++ " testb %%al,%%al\n"
5578 ++ " jz 1f\n"
5579 ++ " decl %1\n"
5580 ++ " jnz 0b\n"
5581 ++ "1: subl %1,%0\n"
5582 ++ "2:\n"
5583 ++ " pushl %%ss\n"
5584 ++ " popl %%ds\n"
5585 ++ ".section .fixup,\"ax\"\n"
5586 ++ "3: movl %5,%0\n"
5587 ++ " jmp 2b\n"
5588 ++ ".previous\n"
5589 ++ ".section __ex_table,\"a\"\n"
5590 ++ " .align 4\n"
5591 ++ " .long 0b,3b\n"
5592 ++ ".previous"
5593 ++ : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),
5594 ++ "=&D" (__d2)
5595 ++ : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
5596 ++ "r"(__USER_DS)
5597 ++ : "memory");
5598 ++ return res;
5599 ++}
5600 +
5601 + /**
5602 + * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
5603 +@@ -81,9 +88,7 @@ do { \
5604 + long
5605 + __strncpy_from_user(char *dst, const char __user *src, long count)
5606 + {
5607 +- long res;
5608 +- __do_strncpy_from_user(dst, src, count, res);
5609 +- return res;
5610 ++ return __do_strncpy_from_user(dst, src, count);
5611 + }
5612 + EXPORT_SYMBOL(__strncpy_from_user);
5613 +
5614 +@@ -110,7 +115,7 @@ strncpy_from_user(char *dst, const char
5615 + {
5616 + long res = -EFAULT;
5617 + if (access_ok(VERIFY_READ, src, 1))
5618 +- __do_strncpy_from_user(dst, src, count, res);
5619 ++ res = __do_strncpy_from_user(dst, src, count);
5620 + return res;
5621 + }
5622 + EXPORT_SYMBOL(strncpy_from_user);
5623 +@@ -119,27 +124,33 @@ EXPORT_SYMBOL(strncpy_from_user);
5624 + * Zero Userspace
5625 + */
5626 +
5627 +-#define __do_clear_user(addr,size) \
5628 +-do { \
5629 +- int __d0; \
5630 +- might_sleep(); \
5631 +- __asm__ __volatile__( \
5632 +- "0: rep; stosl\n" \
5633 +- " movl %2,%0\n" \
5634 +- "1: rep; stosb\n" \
5635 +- "2:\n" \
5636 +- ".section .fixup,\"ax\"\n" \
5637 +- "3: lea 0(%2,%0,4),%0\n" \
5638 +- " jmp 2b\n" \
5639 +- ".previous\n" \
5640 +- ".section __ex_table,\"a\"\n" \
5641 +- " .align 4\n" \
5642 +- " .long 0b,3b\n" \
5643 +- " .long 1b,2b\n" \
5644 +- ".previous" \
5645 +- : "=&c"(size), "=&D" (__d0) \
5646 +- : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
5647 +-} while (0)
5648 ++static unsigned long __do_clear_user(void __user *addr, unsigned long size)
5649 ++{
5650 ++ int __d0;
5651 ++
5652 ++ might_sleep();
5653 ++ __asm__ __volatile__(
5654 ++ " movw %w6,%%es\n"
5655 ++ "0: rep; stosl\n"
5656 ++ " movl %2,%0\n"
5657 ++ "1: rep; stosb\n"
5658 ++ "2:\n"
5659 ++ " pushl %%ss\n"
5660 ++ " popl %%es\n"
5661 ++ ".section .fixup,\"ax\"\n"
5662 ++ "3: lea 0(%2,%0,4),%0\n"
5663 ++ " jmp 2b\n"
5664 ++ ".previous\n"
5665 ++ ".section __ex_table,\"a\"\n"
5666 ++ " .align 4\n"
5667 ++ " .long 0b,3b\n"
5668 ++ " .long 1b,2b\n"
5669 ++ ".previous"
5670 ++ : "=&c"(size), "=&D" (__d0)
5671 ++ : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
5672 ++ "r"(__USER_DS));
5673 ++ return size;
5674 ++}
5675 +
5676 + /**
5677 + * clear_user: - Zero a block of memory in user space.
5678 +@@ -156,7 +167,7 @@ clear_user(void __user *to, unsigned lon
5679 + {
5680 + might_sleep();
5681 + if (access_ok(VERIFY_WRITE, to, n))
5682 +- __do_clear_user(to, n);
5683 ++ n = __do_clear_user(to, n);
5684 + return n;
5685 + }
5686 + EXPORT_SYMBOL(clear_user);
5687 +@@ -175,8 +186,7 @@ EXPORT_SYMBOL(clear_user);
5688 + unsigned long
5689 + __clear_user(void __user *to, unsigned long n)
5690 + {
5691 +- __do_clear_user(to, n);
5692 +- return n;
5693 ++ return __do_clear_user(to, n);
5694 + }
5695 + EXPORT_SYMBOL(__clear_user);
5696 +
5697 +@@ -199,14 +209,17 @@ long strnlen_user(const char __user *s,
5698 + might_sleep();
5699 +
5700 + __asm__ __volatile__(
5701 ++ " movw %w8,%%es\n"
5702 + " testl %0, %0\n"
5703 + " jz 3f\n"
5704 +- " andl %0,%%ecx\n"
5705 ++ " movl %0,%%ecx\n"
5706 + "0: repne; scasb\n"
5707 + " setne %%al\n"
5708 + " subl %%ecx,%0\n"
5709 + " addl %0,%%eax\n"
5710 + "1:\n"
5711 ++ " pushl %%ss\n"
5712 ++ " popl %%es\n"
5713 + ".section .fixup,\"ax\"\n"
5714 + "2: xorl %%eax,%%eax\n"
5715 + " jmp 1b\n"
5716 +@@ -218,7 +231,7 @@ long strnlen_user(const char __user *s,
5717 + " .long 0b,2b\n"
5718 + ".previous"
5719 + :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
5720 +- :"0" (n), "1" (s), "2" (0), "3" (mask)
5721 ++ :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
5722 + :"cc");
5723 + return res & mask;
5724 + }
5725 +@@ -226,10 +239,121 @@ EXPORT_SYMBOL(strnlen_user);
5726 +
5727 + #ifdef CONFIG_X86_INTEL_USERCOPY
5728 + static unsigned long
5729 +-__copy_user_intel(void __user *to, const void *from, unsigned long size)
5730 ++__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
5731 ++{
5732 ++ int d0, d1;
5733 ++ __asm__ __volatile__(
5734 ++ " movw %w6, %%es\n"
5735 ++ " .align 2,0x90\n"
5736 ++ "1: movl 32(%4), %%eax\n"
5737 ++ " cmpl $67, %0\n"
5738 ++ " jbe 3f\n"
5739 ++ "2: movl 64(%4), %%eax\n"
5740 ++ " .align 2,0x90\n"
5741 ++ "3: movl 0(%4), %%eax\n"
5742 ++ "4: movl 4(%4), %%edx\n"
5743 ++ "5: movl %%eax, %%es:0(%3)\n"
5744 ++ "6: movl %%edx, %%es:4(%3)\n"
5745 ++ "7: movl 8(%4), %%eax\n"
5746 ++ "8: movl 12(%4),%%edx\n"
5747 ++ "9: movl %%eax, %%es:8(%3)\n"
5748 ++ "10: movl %%edx, %%es:12(%3)\n"
5749 ++ "11: movl 16(%4), %%eax\n"
5750 ++ "12: movl 20(%4), %%edx\n"
5751 ++ "13: movl %%eax, %%es:16(%3)\n"
5752 ++ "14: movl %%edx, %%es:20(%3)\n"
5753 ++ "15: movl 24(%4), %%eax\n"
5754 ++ "16: movl 28(%4), %%edx\n"
5755 ++ "17: movl %%eax, %%es:24(%3)\n"
5756 ++ "18: movl %%edx, %%es:28(%3)\n"
5757 ++ "19: movl 32(%4), %%eax\n"
5758 ++ "20: movl 36(%4), %%edx\n"
5759 ++ "21: movl %%eax, %%es:32(%3)\n"
5760 ++ "22: movl %%edx, %%es:36(%3)\n"
5761 ++ "23: movl 40(%4), %%eax\n"
5762 ++ "24: movl 44(%4), %%edx\n"
5763 ++ "25: movl %%eax, %%es:40(%3)\n"
5764 ++ "26: movl %%edx, %%es:44(%3)\n"
5765 ++ "27: movl 48(%4), %%eax\n"
5766 ++ "28: movl 52(%4), %%edx\n"
5767 ++ "29: movl %%eax, %%es:48(%3)\n"
5768 ++ "30: movl %%edx, %%es:52(%3)\n"
5769 ++ "31: movl 56(%4), %%eax\n"
5770 ++ "32: movl 60(%4), %%edx\n"
5771 ++ "33: movl %%eax, %%es:56(%3)\n"
5772 ++ "34: movl %%edx, %%es:60(%3)\n"
5773 ++ " addl $-64, %0\n"
5774 ++ " addl $64, %4\n"
5775 ++ " addl $64, %3\n"
5776 ++ " cmpl $63, %0\n"
5777 ++ " ja 1b\n"
5778 ++ "35: movl %0, %%eax\n"
5779 ++ " shrl $2, %0\n"
5780 ++ " andl $3, %%eax\n"
5781 ++ " cld\n"
5782 ++ "99: rep; movsl\n"
5783 ++ "36: movl %%eax, %0\n"
5784 ++ "37: rep; movsb\n"
5785 ++ "100:\n"
5786 ++ " pushl %%ss\n"
5787 ++ " popl %%es\n"
5788 ++ ".section .fixup,\"ax\"\n"
5789 ++ "101: lea 0(%%eax,%0,4),%0\n"
5790 ++ " jmp 100b\n"
5791 ++ ".previous\n"
5792 ++ ".section __ex_table,\"a\"\n"
5793 ++ " .align 4\n"
5794 ++ " .long 1b,100b\n"
5795 ++ " .long 2b,100b\n"
5796 ++ " .long 3b,100b\n"
5797 ++ " .long 4b,100b\n"
5798 ++ " .long 5b,100b\n"
5799 ++ " .long 6b,100b\n"
5800 ++ " .long 7b,100b\n"
5801 ++ " .long 8b,100b\n"
5802 ++ " .long 9b,100b\n"
5803 ++ " .long 10b,100b\n"
5804 ++ " .long 11b,100b\n"
5805 ++ " .long 12b,100b\n"
5806 ++ " .long 13b,100b\n"
5807 ++ " .long 14b,100b\n"
5808 ++ " .long 15b,100b\n"
5809 ++ " .long 16b,100b\n"
5810 ++ " .long 17b,100b\n"
5811 ++ " .long 18b,100b\n"
5812 ++ " .long 19b,100b\n"
5813 ++ " .long 20b,100b\n"
5814 ++ " .long 21b,100b\n"
5815 ++ " .long 22b,100b\n"
5816 ++ " .long 23b,100b\n"
5817 ++ " .long 24b,100b\n"
5818 ++ " .long 25b,100b\n"
5819 ++ " .long 26b,100b\n"
5820 ++ " .long 27b,100b\n"
5821 ++ " .long 28b,100b\n"
5822 ++ " .long 29b,100b\n"
5823 ++ " .long 30b,100b\n"
5824 ++ " .long 31b,100b\n"
5825 ++ " .long 32b,100b\n"
5826 ++ " .long 33b,100b\n"
5827 ++ " .long 34b,100b\n"
5828 ++ " .long 35b,100b\n"
5829 ++ " .long 36b,100b\n"
5830 ++ " .long 37b,100b\n"
5831 ++ " .long 99b,101b\n"
5832 ++ ".previous"
5833 ++ : "=&c"(size), "=&D" (d0), "=&S" (d1)
5834 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
5835 ++ : "eax", "edx", "memory");
5836 ++ return size;
5837 ++}
5838 ++
5839 ++static unsigned long
5840 ++__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
5841 + {
5842 + int d0, d1;
5843 + __asm__ __volatile__(
5844 ++ " movw %w6, %%ds\n"
5845 + " .align 2,0x90\n"
5846 + "1: movl 32(%4), %%eax\n"
5847 + " cmpl $67, %0\n"
5848 +@@ -238,36 +362,36 @@ __copy_user_intel(void __user *to, const
5849 + " .align 2,0x90\n"
5850 + "3: movl 0(%4), %%eax\n"
5851 + "4: movl 4(%4), %%edx\n"
5852 +- "5: movl %%eax, 0(%3)\n"
5853 +- "6: movl %%edx, 4(%3)\n"
5854 ++ "5: movl %%eax, %%es:0(%3)\n"
5855 ++ "6: movl %%edx, %%es:4(%3)\n"
5856 + "7: movl 8(%4), %%eax\n"
5857 + "8: movl 12(%4),%%edx\n"
5858 +- "9: movl %%eax, 8(%3)\n"
5859 +- "10: movl %%edx, 12(%3)\n"
5860 ++ "9: movl %%eax, %%es:8(%3)\n"
5861 ++ "10: movl %%edx, %%es:12(%3)\n"
5862 + "11: movl 16(%4), %%eax\n"
5863 + "12: movl 20(%4), %%edx\n"
5864 +- "13: movl %%eax, 16(%3)\n"
5865 +- "14: movl %%edx, 20(%3)\n"
5866 ++ "13: movl %%eax, %%es:16(%3)\n"
5867 ++ "14: movl %%edx, %%es:20(%3)\n"
5868 + "15: movl 24(%4), %%eax\n"
5869 + "16: movl 28(%4), %%edx\n"
5870 +- "17: movl %%eax, 24(%3)\n"
5871 +- "18: movl %%edx, 28(%3)\n"
5872 ++ "17: movl %%eax, %%es:24(%3)\n"
5873 ++ "18: movl %%edx, %%es:28(%3)\n"
5874 + "19: movl 32(%4), %%eax\n"
5875 + "20: movl 36(%4), %%edx\n"
5876 +- "21: movl %%eax, 32(%3)\n"
5877 +- "22: movl %%edx, 36(%3)\n"
5878 ++ "21: movl %%eax, %%es:32(%3)\n"
5879 ++ "22: movl %%edx, %%es:36(%3)\n"
5880 + "23: movl 40(%4), %%eax\n"
5881 + "24: movl 44(%4), %%edx\n"
5882 +- "25: movl %%eax, 40(%3)\n"
5883 +- "26: movl %%edx, 44(%3)\n"
5884 ++ "25: movl %%eax, %%es:40(%3)\n"
5885 ++ "26: movl %%edx, %%es:44(%3)\n"
5886 + "27: movl 48(%4), %%eax\n"
5887 + "28: movl 52(%4), %%edx\n"
5888 +- "29: movl %%eax, 48(%3)\n"
5889 +- "30: movl %%edx, 52(%3)\n"
5890 ++ "29: movl %%eax, %%es:48(%3)\n"
5891 ++ "30: movl %%edx, %%es:52(%3)\n"
5892 + "31: movl 56(%4), %%eax\n"
5893 + "32: movl 60(%4), %%edx\n"
5894 +- "33: movl %%eax, 56(%3)\n"
5895 +- "34: movl %%edx, 60(%3)\n"
5896 ++ "33: movl %%eax, %%es:56(%3)\n"
5897 ++ "34: movl %%edx, %%es:60(%3)\n"
5898 + " addl $-64, %0\n"
5899 + " addl $64, %4\n"
5900 + " addl $64, %3\n"
5901 +@@ -281,6 +405,8 @@ __copy_user_intel(void __user *to, const
5902 + "36: movl %%eax, %0\n"
5903 + "37: rep; movsb\n"
5904 + "100:\n"
5905 ++ " pushl %%ss\n"
5906 ++ " popl %%ds\n"
5907 + ".section .fixup,\"ax\"\n"
5908 + "101: lea 0(%%eax,%0,4),%0\n"
5909 + " jmp 100b\n"
5910 +@@ -327,7 +453,7 @@ __copy_user_intel(void __user *to, const
5911 + " .long 99b,101b\n"
5912 + ".previous"
5913 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
5914 +- : "1"(to), "2"(from), "0"(size)
5915 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
5916 + : "eax", "edx", "memory");
5917 + return size;
5918 + }
5919 +@@ -337,6 +463,7 @@ __copy_user_zeroing_intel(void *to, cons
5920 + {
5921 + int d0, d1;
5922 + __asm__ __volatile__(
5923 ++ " movw %w6, %%ds\n"
5924 + " .align 2,0x90\n"
5925 + "0: movl 32(%4), %%eax\n"
5926 + " cmpl $67, %0\n"
5927 +@@ -345,36 +472,36 @@ __copy_user_zeroing_intel(void *to, cons
5928 + " .align 2,0x90\n"
5929 + "2: movl 0(%4), %%eax\n"
5930 + "21: movl 4(%4), %%edx\n"
5931 +- " movl %%eax, 0(%3)\n"
5932 +- " movl %%edx, 4(%3)\n"
5933 ++ " movl %%eax, %%es:0(%3)\n"
5934 ++ " movl %%edx, %%es:4(%3)\n"
5935 + "3: movl 8(%4), %%eax\n"
5936 + "31: movl 12(%4),%%edx\n"
5937 +- " movl %%eax, 8(%3)\n"
5938 +- " movl %%edx, 12(%3)\n"
5939 ++ " movl %%eax, %%es:8(%3)\n"
5940 ++ " movl %%edx, %%es:12(%3)\n"
5941 + "4: movl 16(%4), %%eax\n"
5942 + "41: movl 20(%4), %%edx\n"
5943 +- " movl %%eax, 16(%3)\n"
5944 +- " movl %%edx, 20(%3)\n"
5945 ++ " movl %%eax, %%es:16(%3)\n"
5946 ++ " movl %%edx, %%es:20(%3)\n"
5947 + "10: movl 24(%4), %%eax\n"
5948 + "51: movl 28(%4), %%edx\n"
5949 +- " movl %%eax, 24(%3)\n"
5950 +- " movl %%edx, 28(%3)\n"
5951 ++ " movl %%eax, %%es:24(%3)\n"
5952 ++ " movl %%edx, %%es:28(%3)\n"
5953 + "11: movl 32(%4), %%eax\n"
5954 + "61: movl 36(%4), %%edx\n"
5955 +- " movl %%eax, 32(%3)\n"
5956 +- " movl %%edx, 36(%3)\n"
5957 ++ " movl %%eax, %%es:32(%3)\n"
5958 ++ " movl %%edx, %%es:36(%3)\n"
5959 + "12: movl 40(%4), %%eax\n"
5960 + "71: movl 44(%4), %%edx\n"
5961 +- " movl %%eax, 40(%3)\n"
5962 +- " movl %%edx, 44(%3)\n"
5963 ++ " movl %%eax, %%es:40(%3)\n"
5964 ++ " movl %%edx, %%es:44(%3)\n"
5965 + "13: movl 48(%4), %%eax\n"
5966 + "81: movl 52(%4), %%edx\n"
5967 +- " movl %%eax, 48(%3)\n"
5968 +- " movl %%edx, 52(%3)\n"
5969 ++ " movl %%eax, %%es:48(%3)\n"
5970 ++ " movl %%edx, %%es:52(%3)\n"
5971 + "14: movl 56(%4), %%eax\n"
5972 + "91: movl 60(%4), %%edx\n"
5973 +- " movl %%eax, 56(%3)\n"
5974 +- " movl %%edx, 60(%3)\n"
5975 ++ " movl %%eax, %%es:56(%3)\n"
5976 ++ " movl %%edx, %%es:60(%3)\n"
5977 + " addl $-64, %0\n"
5978 + " addl $64, %4\n"
5979 + " addl $64, %3\n"
5980 +@@ -388,6 +515,8 @@ __copy_user_zeroing_intel(void *to, cons
5981 + " movl %%eax,%0\n"
5982 + "7: rep; movsb\n"
5983 + "8:\n"
5984 ++ " pushl %%ss\n"
5985 ++ " popl %%ds\n"
5986 + ".section .fixup,\"ax\"\n"
5987 + "9: lea 0(%%eax,%0,4),%0\n"
5988 + "16: pushl %0\n"
5989 +@@ -422,7 +551,7 @@ __copy_user_zeroing_intel(void *to, cons
5990 + " .long 7b,16b\n"
5991 + ".previous"
5992 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
5993 +- : "1"(to), "2"(from), "0"(size)
5994 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
5995 + : "eax", "edx", "memory");
5996 + return size;
5997 + }
5998 +@@ -438,6 +567,7 @@ static unsigned long __copy_user_zeroing
5999 + int d0, d1;
6000 +
6001 + __asm__ __volatile__(
6002 ++ " movw %w6, %%ds\n"
6003 + " .align 2,0x90\n"
6004 + "0: movl 32(%4), %%eax\n"
6005 + " cmpl $67, %0\n"
6006 +@@ -446,36 +576,36 @@ static unsigned long __copy_user_zeroing
6007 + " .align 2,0x90\n"
6008 + "2: movl 0(%4), %%eax\n"
6009 + "21: movl 4(%4), %%edx\n"
6010 +- " movnti %%eax, 0(%3)\n"
6011 +- " movnti %%edx, 4(%3)\n"
6012 ++ " movnti %%eax, %%es:0(%3)\n"
6013 ++ " movnti %%edx, %%es:4(%3)\n"
6014 + "3: movl 8(%4), %%eax\n"
6015 + "31: movl 12(%4),%%edx\n"
6016 +- " movnti %%eax, 8(%3)\n"
6017 +- " movnti %%edx, 12(%3)\n"
6018 ++ " movnti %%eax, %%es:8(%3)\n"
6019 ++ " movnti %%edx, %%es:12(%3)\n"
6020 + "4: movl 16(%4), %%eax\n"
6021 + "41: movl 20(%4), %%edx\n"
6022 +- " movnti %%eax, 16(%3)\n"
6023 +- " movnti %%edx, 20(%3)\n"
6024 ++ " movnti %%eax, %%es:16(%3)\n"
6025 ++ " movnti %%edx, %%es:20(%3)\n"
6026 + "10: movl 24(%4), %%eax\n"
6027 + "51: movl 28(%4), %%edx\n"
6028 +- " movnti %%eax, 24(%3)\n"
6029 +- " movnti %%edx, 28(%3)\n"
6030 ++ " movnti %%eax, %%es:24(%3)\n"
6031 ++ " movnti %%edx, %%es:28(%3)\n"
6032 + "11: movl 32(%4), %%eax\n"
6033 + "61: movl 36(%4), %%edx\n"
6034 +- " movnti %%eax, 32(%3)\n"
6035 +- " movnti %%edx, 36(%3)\n"
6036 ++ " movnti %%eax, %%es:32(%3)\n"
6037 ++ " movnti %%edx, %%es:36(%3)\n"
6038 + "12: movl 40(%4), %%eax\n"
6039 + "71: movl 44(%4), %%edx\n"
6040 +- " movnti %%eax, 40(%3)\n"
6041 +- " movnti %%edx, 44(%3)\n"
6042 ++ " movnti %%eax, %%es:40(%3)\n"
6043 ++ " movnti %%edx, %%es:44(%3)\n"
6044 + "13: movl 48(%4), %%eax\n"
6045 + "81: movl 52(%4), %%edx\n"
6046 +- " movnti %%eax, 48(%3)\n"
6047 +- " movnti %%edx, 52(%3)\n"
6048 ++ " movnti %%eax, %%es:48(%3)\n"
6049 ++ " movnti %%edx, %%es:52(%3)\n"
6050 + "14: movl 56(%4), %%eax\n"
6051 + "91: movl 60(%4), %%edx\n"
6052 +- " movnti %%eax, 56(%3)\n"
6053 +- " movnti %%edx, 60(%3)\n"
6054 ++ " movnti %%eax, %%es:56(%3)\n"
6055 ++ " movnti %%edx, %%es:60(%3)\n"
6056 + " addl $-64, %0\n"
6057 + " addl $64, %4\n"
6058 + " addl $64, %3\n"
6059 +@@ -490,6 +620,8 @@ static unsigned long __copy_user_zeroing
6060 + " movl %%eax,%0\n"
6061 + "7: rep; movsb\n"
6062 + "8:\n"
6063 ++ " pushl %%ss\n"
6064 ++ " popl %%ds\n"
6065 + ".section .fixup,\"ax\"\n"
6066 + "9: lea 0(%%eax,%0,4),%0\n"
6067 + "16: pushl %0\n"
6068 +@@ -524,7 +656,7 @@ static unsigned long __copy_user_zeroing
6069 + " .long 7b,16b\n"
6070 + ".previous"
6071 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
6072 +- : "1"(to), "2"(from), "0"(size)
6073 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
6074 + : "eax", "edx", "memory");
6075 + return size;
6076 + }
6077 +@@ -535,6 +667,7 @@ static unsigned long __copy_user_intel_n
6078 + int d0, d1;
6079 +
6080 + __asm__ __volatile__(
6081 ++ " movw %w6, %%ds\n"
6082 + " .align 2,0x90\n"
6083 + "0: movl 32(%4), %%eax\n"
6084 + " cmpl $67, %0\n"
6085 +@@ -543,36 +676,36 @@ static unsigned long __copy_user_intel_n
6086 + " .align 2,0x90\n"
6087 + "2: movl 0(%4), %%eax\n"
6088 + "21: movl 4(%4), %%edx\n"
6089 +- " movnti %%eax, 0(%3)\n"
6090 +- " movnti %%edx, 4(%3)\n"
6091 ++ " movnti %%eax, %%es:0(%3)\n"
6092 ++ " movnti %%edx, %%es:4(%3)\n"
6093 + "3: movl 8(%4), %%eax\n"
6094 + "31: movl 12(%4),%%edx\n"
6095 +- " movnti %%eax, 8(%3)\n"
6096 +- " movnti %%edx, 12(%3)\n"
6097 ++ " movnti %%eax, %%es:8(%3)\n"
6098 ++ " movnti %%edx, %%es:12(%3)\n"
6099 + "4: movl 16(%4), %%eax\n"
6100 + "41: movl 20(%4), %%edx\n"
6101 +- " movnti %%eax, 16(%3)\n"
6102 +- " movnti %%edx, 20(%3)\n"
6103 ++ " movnti %%eax, %%es:16(%3)\n"
6104 ++ " movnti %%edx, %%es:20(%3)\n"
6105 + "10: movl 24(%4), %%eax\n"
6106 + "51: movl 28(%4), %%edx\n"
6107 +- " movnti %%eax, 24(%3)\n"
6108 +- " movnti %%edx, 28(%3)\n"
6109 ++ " movnti %%eax, %%es:24(%3)\n"
6110 ++ " movnti %%edx, %%es:28(%3)\n"
6111 + "11: movl 32(%4), %%eax\n"
6112 + "61: movl 36(%4), %%edx\n"
6113 +- " movnti %%eax, 32(%3)\n"
6114 +- " movnti %%edx, 36(%3)\n"
6115 ++ " movnti %%eax, %%es:32(%3)\n"
6116 ++ " movnti %%edx, %%es:36(%3)\n"
6117 + "12: movl 40(%4), %%eax\n"
6118 + "71: movl 44(%4), %%edx\n"
6119 +- " movnti %%eax, 40(%3)\n"
6120 +- " movnti %%edx, 44(%3)\n"
6121 ++ " movnti %%eax, %%es:40(%3)\n"
6122 ++ " movnti %%edx, %%es:44(%3)\n"
6123 + "13: movl 48(%4), %%eax\n"
6124 + "81: movl 52(%4), %%edx\n"
6125 +- " movnti %%eax, 48(%3)\n"
6126 +- " movnti %%edx, 52(%3)\n"
6127 ++ " movnti %%eax, %%es:48(%3)\n"
6128 ++ " movnti %%edx, %%es:52(%3)\n"
6129 + "14: movl 56(%4), %%eax\n"
6130 + "91: movl 60(%4), %%edx\n"
6131 +- " movnti %%eax, 56(%3)\n"
6132 +- " movnti %%edx, 60(%3)\n"
6133 ++ " movnti %%eax, %%es:56(%3)\n"
6134 ++ " movnti %%edx, %%es:60(%3)\n"
6135 + " addl $-64, %0\n"
6136 + " addl $64, %4\n"
6137 + " addl $64, %3\n"
6138 +@@ -587,6 +720,8 @@ static unsigned long __copy_user_intel_n
6139 + " movl %%eax,%0\n"
6140 + "7: rep; movsb\n"
6141 + "8:\n"
6142 ++ " pushl %%ss\n"
6143 ++ " popl %%ds\n"
6144 + ".section .fixup,\"ax\"\n"
6145 + "9: lea 0(%%eax,%0,4),%0\n"
6146 + "16: jmp 8b\n"
6147 +@@ -615,7 +750,7 @@ static unsigned long __copy_user_intel_n
6148 + " .long 7b,16b\n"
6149 + ".previous"
6150 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
6151 +- : "1"(to), "2"(from), "0"(size)
6152 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
6153 + : "eax", "edx", "memory");
6154 + return size;
6155 + }
6156 +@@ -628,90 +763,146 @@ static unsigned long __copy_user_intel_n
6157 + */
6158 + unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
6159 + unsigned long size);
6160 +-unsigned long __copy_user_intel(void __user *to, const void *from,
6161 ++unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
6162 ++ unsigned long size);
6163 ++unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
6164 + unsigned long size);
6165 + unsigned long __copy_user_zeroing_intel_nocache(void *to,
6166 + const void __user *from, unsigned long size);
6167 + #endif /* CONFIG_X86_INTEL_USERCOPY */
6168 +
6169 + /* Generic arbitrary sized copy. */
6170 +-#define __copy_user(to,from,size) \
6171 +-do { \
6172 +- int __d0, __d1, __d2; \
6173 +- __asm__ __volatile__( \
6174 +- " cmp $7,%0\n" \
6175 +- " jbe 1f\n" \
6176 +- " movl %1,%0\n" \
6177 +- " negl %0\n" \
6178 +- " andl $7,%0\n" \
6179 +- " subl %0,%3\n" \
6180 +- "4: rep; movsb\n" \
6181 +- " movl %3,%0\n" \
6182 +- " shrl $2,%0\n" \
6183 +- " andl $3,%3\n" \
6184 +- " .align 2,0x90\n" \
6185 +- "0: rep; movsl\n" \
6186 +- " movl %3,%0\n" \
6187 +- "1: rep; movsb\n" \
6188 +- "2:\n" \
6189 +- ".section .fixup,\"ax\"\n" \
6190 +- "5: addl %3,%0\n" \
6191 +- " jmp 2b\n" \
6192 +- "3: lea 0(%3,%0,4),%0\n" \
6193 +- " jmp 2b\n" \
6194 +- ".previous\n" \
6195 +- ".section __ex_table,\"a\"\n" \
6196 +- " .align 4\n" \
6197 +- " .long 4b,5b\n" \
6198 +- " .long 0b,3b\n" \
6199 +- " .long 1b,2b\n" \
6200 +- ".previous" \
6201 +- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
6202 +- : "3"(size), "0"(size), "1"(to), "2"(from) \
6203 +- : "memory"); \
6204 +-} while (0)
6205 +-
6206 +-#define __copy_user_zeroing(to,from,size) \
6207 +-do { \
6208 +- int __d0, __d1, __d2; \
6209 +- __asm__ __volatile__( \
6210 +- " cmp $7,%0\n" \
6211 +- " jbe 1f\n" \
6212 +- " movl %1,%0\n" \
6213 +- " negl %0\n" \
6214 +- " andl $7,%0\n" \
6215 +- " subl %0,%3\n" \
6216 +- "4: rep; movsb\n" \
6217 +- " movl %3,%0\n" \
6218 +- " shrl $2,%0\n" \
6219 +- " andl $3,%3\n" \
6220 +- " .align 2,0x90\n" \
6221 +- "0: rep; movsl\n" \
6222 +- " movl %3,%0\n" \
6223 +- "1: rep; movsb\n" \
6224 +- "2:\n" \
6225 +- ".section .fixup,\"ax\"\n" \
6226 +- "5: addl %3,%0\n" \
6227 +- " jmp 6f\n" \
6228 +- "3: lea 0(%3,%0,4),%0\n" \
6229 +- "6: pushl %0\n" \
6230 +- " pushl %%eax\n" \
6231 +- " xorl %%eax,%%eax\n" \
6232 +- " rep; stosb\n" \
6233 +- " popl %%eax\n" \
6234 +- " popl %0\n" \
6235 +- " jmp 2b\n" \
6236 +- ".previous\n" \
6237 +- ".section __ex_table,\"a\"\n" \
6238 +- " .align 4\n" \
6239 +- " .long 4b,5b\n" \
6240 +- " .long 0b,3b\n" \
6241 +- " .long 1b,6b\n" \
6242 +- ".previous" \
6243 +- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
6244 +- : "3"(size), "0"(size), "1"(to), "2"(from) \
6245 +- : "memory"); \
6246 +-} while (0)
6247 ++static unsigned long
6248 ++__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
6249 ++{
6250 ++ int __d0, __d1, __d2;
6251 ++
6252 ++ __asm__ __volatile__(
6253 ++ " movw %w8,%%es\n"
6254 ++ " cmp $7,%0\n"
6255 ++ " jbe 1f\n"
6256 ++ " movl %1,%0\n"
6257 ++ " negl %0\n"
6258 ++ " andl $7,%0\n"
6259 ++ " subl %0,%3\n"
6260 ++ "4: rep; movsb\n"
6261 ++ " movl %3,%0\n"
6262 ++ " shrl $2,%0\n"
6263 ++ " andl $3,%3\n"
6264 ++ " .align 2,0x90\n"
6265 ++ "0: rep; movsl\n"
6266 ++ " movl %3,%0\n"
6267 ++ "1: rep; movsb\n"
6268 ++ "2:\n"
6269 ++ " pushl %%ss\n"
6270 ++ " popl %%es\n"
6271 ++ ".section .fixup,\"ax\"\n"
6272 ++ "5: addl %3,%0\n"
6273 ++ " jmp 2b\n"
6274 ++ "3: lea 0(%3,%0,4),%0\n"
6275 ++ " jmp 2b\n"
6276 ++ ".previous\n"
6277 ++ ".section __ex_table,\"a\"\n"
6278 ++ " .align 4\n"
6279 ++ " .long 4b,5b\n"
6280 ++ " .long 0b,3b\n"
6281 ++ " .long 1b,2b\n"
6282 ++ ".previous"
6283 ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
6284 ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
6285 ++ : "memory");
6286 ++ return size;
6287 ++}
6288 ++
6289 ++static unsigned long
6290 ++__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
6291 ++{
6292 ++ int __d0, __d1, __d2;
6293 ++
6294 ++ __asm__ __volatile__(
6295 ++ " movw %w8,%%ds\n"
6296 ++ " cmp $7,%0\n"
6297 ++ " jbe 1f\n"
6298 ++ " movl %1,%0\n"
6299 ++ " negl %0\n"
6300 ++ " andl $7,%0\n"
6301 ++ " subl %0,%3\n"
6302 ++ "4: rep; movsb\n"
6303 ++ " movl %3,%0\n"
6304 ++ " shrl $2,%0\n"
6305 ++ " andl $3,%3\n"
6306 ++ " .align 2,0x90\n"
6307 ++ "0: rep; movsl\n"
6308 ++ " movl %3,%0\n"
6309 ++ "1: rep; movsb\n"
6310 ++ "2:\n"
6311 ++ " pushl %%ss\n"
6312 ++ " popl %%ds\n"
6313 ++ ".section .fixup,\"ax\"\n"
6314 ++ "5: addl %3,%0\n"
6315 ++ " jmp 2b\n"
6316 ++ "3: lea 0(%3,%0,4),%0\n"
6317 ++ " jmp 2b\n"
6318 ++ ".previous\n"
6319 ++ ".section __ex_table,\"a\"\n"
6320 ++ " .align 4\n"
6321 ++ " .long 4b,5b\n"
6322 ++ " .long 0b,3b\n"
6323 ++ " .long 1b,2b\n"
6324 ++ ".previous"
6325 ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
6326 ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
6327 ++ : "memory");
6328 ++ return size;
6329 ++}
6330 ++
6331 ++static unsigned long
6332 ++__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
6333 ++{
6334 ++ int __d0, __d1, __d2;
6335 ++
6336 ++ __asm__ __volatile__(
6337 ++ " movw %w8,%%ds\n"
6338 ++ " cmp $7,%0\n"
6339 ++ " jbe 1f\n"
6340 ++ " movl %1,%0\n"
6341 ++ " negl %0\n"
6342 ++ " andl $7,%0\n"
6343 ++ " subl %0,%3\n"
6344 ++ "4: rep; movsb\n"
6345 ++ " movl %3,%0\n"
6346 ++ " shrl $2,%0\n"
6347 ++ " andl $3,%3\n"
6348 ++ " .align 2,0x90\n"
6349 ++ "0: rep; movsl\n"
6350 ++ " movl %3,%0\n"
6351 ++ "1: rep; movsb\n"
6352 ++ "2:\n"
6353 ++ " pushl %%ss\n"
6354 ++ " popl %%ds\n"
6355 ++ ".section .fixup,\"ax\"\n"
6356 ++ "5: addl %3,%0\n"
6357 ++ " jmp 6f\n"
6358 ++ "3: lea 0(%3,%0,4),%0\n"
6359 ++ "6: pushl %0\n"
6360 ++ " pushl %%eax\n"
6361 ++ " xorl %%eax,%%eax\n"
6362 ++ " rep; stosb\n"
6363 ++ " popl %%eax\n"
6364 ++ " popl %0\n"
6365 ++ " jmp 2b\n"
6366 ++ ".previous\n"
6367 ++ ".section __ex_table,\"a\"\n"
6368 ++ " .align 4\n"
6369 ++ " .long 4b,5b\n"
6370 ++ " .long 0b,3b\n"
6371 ++ " .long 1b,6b\n"
6372 ++ ".previous"
6373 ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
6374 ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
6375 ++ : "memory");
6376 ++ return size;
6377 ++}
6378 +
6379 + unsigned long __copy_to_user_ll(void __user *to, const void *from,
6380 + unsigned long n)
6381 +@@ -774,9 +965,9 @@ survive:
6382 + }
6383 + #endif
6384 + if (movsl_is_ok(to, from, n))
6385 +- __copy_user(to, from, n);
6386 ++ n = __generic_copy_to_user(to, from, n);
6387 + else
6388 +- n = __copy_user_intel(to, from, n);
6389 ++ n = __generic_copy_to_user_intel(to, from, n);
6390 + return n;
6391 + }
6392 + EXPORT_SYMBOL(__copy_to_user_ll);
6393 +@@ -785,7 +976,7 @@ unsigned long __copy_from_user_ll(void *
6394 + unsigned long n)
6395 + {
6396 + if (movsl_is_ok(to, from, n))
6397 +- __copy_user_zeroing(to, from, n);
6398 ++ n = __copy_user_zeroing(to, from, n);
6399 + else
6400 + n = __copy_user_zeroing_intel(to, from, n);
6401 + return n;
6402 +@@ -796,9 +987,9 @@ unsigned long __copy_from_user_ll_nozero
6403 + unsigned long n)
6404 + {
6405 + if (movsl_is_ok(to, from, n))
6406 +- __copy_user(to, from, n);
6407 ++ n = __generic_copy_from_user(to, from, n);
6408 + else
6409 +- n = __copy_user_intel((void __user *)to,
6410 ++ n = __generic_copy_from_user_intel((void __user *)to,
6411 + (const void *)from, n);
6412 + return n;
6413 + }
6414 +@@ -809,11 +1000,11 @@ unsigned long __copy_from_user_ll_nocach
6415 + {
6416 + #ifdef CONFIG_X86_INTEL_USERCOPY
6417 + if ( n > 64 && cpu_has_xmm2)
6418 +- n = __copy_user_zeroing_intel_nocache(to, from, n);
6419 ++ n = __copy_user_zeroing_intel_nocache(to, from, n);
6420 + else
6421 +- __copy_user_zeroing(to, from, n);
6422 ++ n = __copy_user_zeroing(to, from, n);
6423 + #else
6424 +- __copy_user_zeroing(to, from, n);
6425 ++ n = __copy_user_zeroing(to, from, n);
6426 + #endif
6427 + return n;
6428 + }
6429 +@@ -823,11 +1014,11 @@ unsigned long __copy_from_user_ll_nocach
6430 + {
6431 + #ifdef CONFIG_X86_INTEL_USERCOPY
6432 + if ( n > 64 && cpu_has_xmm2)
6433 +- n = __copy_user_intel_nocache(to, from, n);
6434 ++ n = __copy_user_intel_nocache(to, from, n);
6435 + else
6436 +- __copy_user(to, from, n);
6437 ++ n = __generic_copy_from_user(to, from, n);
6438 + #else
6439 +- __copy_user(to, from, n);
6440 ++ n = __generic_copy_from_user(to, from, n);
6441 + #endif
6442 + return n;
6443 + }
6444 +@@ -880,3 +1071,30 @@ copy_from_user(void *to, const void __us
6445 + return n;
6446 + }
6447 + EXPORT_SYMBOL(copy_from_user);
6448 ++
6449 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
6450 ++void __set_fs(mm_segment_t x, int cpu)
6451 ++{
6452 ++ unsigned long limit = x.seg;
6453 ++ __u32 a, b;
6454 ++
6455 ++ current_thread_info()->addr_limit = x;
6456 ++ if (likely(limit))
6457 ++ limit = (limit - 1UL) >> PAGE_SHIFT;
6458 ++ pack_descriptor(&a, &b, 0UL, limit, 0xF3, 0xC);
6459 ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, a, b);
6460 ++}
6461 ++
6462 ++void set_fs(mm_segment_t x)
6463 ++{
6464 ++ __set_fs(x, get_cpu());
6465 ++ put_cpu_no_resched();
6466 ++}
6467 ++#else
6468 ++void set_fs(mm_segment_t x)
6469 ++{
6470 ++ current_thread_info()->addr_limit = x;
6471 ++}
6472 ++#endif
6473 ++
6474 ++EXPORT_SYMBOL(set_fs);
6475 +diff -Nurp linux-2.6.23.15/arch/i386/mach-default/setup.c linux-2.6.23.15-grsec/arch/i386/mach-default/setup.c
6476 +--- linux-2.6.23.15/arch/i386/mach-default/setup.c 2007-10-09 21:31:38.000000000 +0100
6477 ++++ linux-2.6.23.15-grsec/arch/i386/mach-default/setup.c 2008-02-11 10:37:44.000000000 +0000
6478 +@@ -35,7 +35,7 @@ void __init pre_intr_init_hook(void)
6479 + /*
6480 + * IRQ2 is cascade interrupt to second interrupt controller
6481 + */
6482 +-static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL};
6483 ++static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL, 0, NULL};
6484 +
6485 + /**
6486 + * intr_init_hook - post gate setup interrupt initialisation
6487 +diff -Nurp linux-2.6.23.15/arch/i386/mach-voyager/voyager_basic.c linux-2.6.23.15-grsec/arch/i386/mach-voyager/voyager_basic.c
6488 +--- linux-2.6.23.15/arch/i386/mach-voyager/voyager_basic.c 2007-10-09 21:31:38.000000000 +0100
6489 ++++ linux-2.6.23.15-grsec/arch/i386/mach-voyager/voyager_basic.c 2008-02-11 10:37:44.000000000 +0000
6490 +@@ -130,7 +130,7 @@ voyager_memory_detect(int region, __u32
6491 + __u8 cmos[4];
6492 + ClickMap_t *map;
6493 + unsigned long map_addr;
6494 +- unsigned long old;
6495 ++ pte_t old;
6496 +
6497 + if(region >= CLICK_ENTRIES) {
6498 + printk("Voyager: Illegal ClickMap region %d\n", region);
6499 +@@ -144,7 +144,7 @@ voyager_memory_detect(int region, __u32
6500 +
6501 + /* steal page 0 for this */
6502 + old = pg0[0];
6503 +- pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
6504 ++ pg0[0] = __pte((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
6505 + local_flush_tlb();
6506 + /* now clear everything out but page 0 */
6507 + map = (ClickMap_t *)(map_addr & (~PAGE_MASK));
6508 +diff -Nurp linux-2.6.23.15/arch/i386/mach-voyager/voyager_smp.c linux-2.6.23.15-grsec/arch/i386/mach-voyager/voyager_smp.c
6509 +--- linux-2.6.23.15/arch/i386/mach-voyager/voyager_smp.c 2007-10-09 21:31:38.000000000 +0100
6510 ++++ linux-2.6.23.15-grsec/arch/i386/mach-voyager/voyager_smp.c 2008-02-11 10:37:44.000000000 +0000
6511 +@@ -554,6 +554,10 @@ do_boot_cpu(__u8 cpu)
6512 + __u32 *hijack_vector;
6513 + __u32 start_phys_address = setup_trampoline();
6514 +
6515 ++#ifdef CONFIG_PAX_KERNEXEC
6516 ++ unsigned long cr0;
6517 ++#endif
6518 ++
6519 + /* There's a clever trick to this: The linux trampoline is
6520 + * compiled to begin at absolute location zero, so make the
6521 + * address zero but have the data segment selector compensate
6522 +@@ -573,7 +577,17 @@ do_boot_cpu(__u8 cpu)
6523 +
6524 + init_gdt(cpu);
6525 + per_cpu(current_task, cpu) = idle;
6526 +- early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
6527 ++
6528 ++#ifdef CONFIG_PAX_KERNEXEC
6529 ++ pax_open_kernel(cr0);
6530 ++#endif
6531 ++
6532 ++ early_gdt_descr.address = get_cpu_gdt_table(cpu);
6533 ++
6534 ++#ifdef CONFIG_PAX_KERNEXEC
6535 ++ pax_close_kernel(cr0);
6536 ++#endif
6537 ++
6538 + irq_ctx_init(cpu);
6539 +
6540 + /* Note: Don't modify initial ss override */
6541 +@@ -1276,7 +1290,7 @@ smp_local_timer_interrupt(void)
6542 + per_cpu(prof_counter, cpu);
6543 + }
6544 +
6545 +- update_process_times(user_mode_vm(get_irq_regs()));
6546 ++ update_process_times(user_mode(get_irq_regs()));
6547 + }
6548 +
6549 + if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
6550 +diff -Nurp linux-2.6.23.15/arch/i386/mm/boot_ioremap.c linux-2.6.23.15-grsec/arch/i386/mm/boot_ioremap.c
6551 +--- linux-2.6.23.15/arch/i386/mm/boot_ioremap.c 2007-10-09 21:31:38.000000000 +0100
6552 ++++ linux-2.6.23.15-grsec/arch/i386/mm/boot_ioremap.c 2008-02-11 10:37:44.000000000 +0000
6553 +@@ -7,57 +7,37 @@
6554 + * Written by Dave Hansen <haveblue@××××××.com>
6555 + */
6556 +
6557 +-
6558 +-/*
6559 +- * We need to use the 2-level pagetable functions, but CONFIG_X86_PAE
6560 +- * keeps that from happenning. If anyone has a better way, I'm listening.
6561 +- *
6562 +- * boot_pte_t is defined only if this all works correctly
6563 +- */
6564 +-
6565 +-#undef CONFIG_X86_PAE
6566 + #undef CONFIG_PARAVIRT
6567 + #include <asm/page.h>
6568 + #include <asm/pgtable.h>
6569 + #include <asm/tlbflush.h>
6570 + #include <linux/init.h>
6571 + #include <linux/stddef.h>
6572 +-
6573 +-/*
6574 +- * I'm cheating here. It is known that the two boot PTE pages are
6575 +- * allocated next to each other. I'm pretending that they're just
6576 +- * one big array.
6577 +- */
6578 +-
6579 +-#define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
6580 +-
6581 +-static unsigned long boot_pte_index(unsigned long vaddr)
6582 +-{
6583 +- return __pa(vaddr) >> PAGE_SHIFT;
6584 +-}
6585 +-
6586 +-static inline boot_pte_t* boot_vaddr_to_pte(void *address)
6587 +-{
6588 +- boot_pte_t* boot_pg = (boot_pte_t*)pg0;
6589 +- return &boot_pg[boot_pte_index((unsigned long)address)];
6590 +-}
6591 ++#include <linux/sched.h>
6592 +
6593 + /*
6594 + * This is only for a caller who is clever enough to page-align
6595 + * phys_addr and virtual_source, and who also has a preference
6596 + * about which virtual address from which to steal ptes
6597 + */
6598 +-static void __boot_ioremap(unsigned long phys_addr, unsigned long nrpages,
6599 +- void* virtual_source)
6600 ++static void __init __boot_ioremap(unsigned long phys_addr, unsigned long nrpages,
6601 ++ char* virtual_source)
6602 + {
6603 +- boot_pte_t* pte;
6604 +- int i;
6605 +- char *vaddr = virtual_source;
6606 ++ pgd_t *pgd;
6607 ++ pud_t *pud;
6608 ++ pmd_t *pmd;
6609 ++ pte_t* pte;
6610 ++ unsigned int i;
6611 ++ unsigned long vaddr = (unsigned long)virtual_source;
6612 ++
6613 ++ pgd = pgd_offset_k(vaddr);
6614 ++ pud = pud_offset(pgd, vaddr);
6615 ++ pmd = pmd_offset(pud, vaddr);
6616 ++ pte = pte_offset_kernel(pmd, vaddr);
6617 +
6618 +- pte = boot_vaddr_to_pte(virtual_source);
6619 + for (i=0; i < nrpages; i++, phys_addr += PAGE_SIZE, pte++) {
6620 + set_pte(pte, pfn_pte(phys_addr>>PAGE_SHIFT, PAGE_KERNEL));
6621 +- __flush_tlb_one(&vaddr[i*PAGE_SIZE]);
6622 ++ __flush_tlb_one(&virtual_source[i*PAGE_SIZE]);
6623 + }
6624 + }
6625 +
6626 +diff -Nurp linux-2.6.23.15/arch/i386/mm/extable.c linux-2.6.23.15-grsec/arch/i386/mm/extable.c
6627 +--- linux-2.6.23.15/arch/i386/mm/extable.c 2007-10-09 21:31:38.000000000 +0100
6628 ++++ linux-2.6.23.15-grsec/arch/i386/mm/extable.c 2008-02-11 10:37:44.000000000 +0000
6629 +@@ -4,14 +4,63 @@
6630 +
6631 + #include <linux/module.h>
6632 + #include <linux/spinlock.h>
6633 ++#include <linux/sort.h>
6634 + #include <asm/uaccess.h>
6635 +
6636 ++/*
6637 ++ * The exception table needs to be sorted so that the binary
6638 ++ * search that we use to find entries in it works properly.
6639 ++ * This is used both for the kernel exception table and for
6640 ++ * the exception tables of modules that get loaded.
6641 ++ */
6642 ++static int cmp_ex(const void *a, const void *b)
6643 ++{
6644 ++ const struct exception_table_entry *x = a, *y = b;
6645 ++
6646 ++ /* avoid overflow */
6647 ++ if (x->insn > y->insn)
6648 ++ return 1;
6649 ++ if (x->insn < y->insn)
6650 ++ return -1;
6651 ++ return 0;
6652 ++}
6653 ++
6654 ++static void swap_ex(void *a, void *b, int size)
6655 ++{
6656 ++ struct exception_table_entry t, *x = a, *y = b;
6657 ++
6658 ++#ifdef CONFIG_PAX_KERNEXEC
6659 ++ unsigned long cr0;
6660 ++#endif
6661 ++
6662 ++ t = *x;
6663 ++
6664 ++#ifdef CONFIG_PAX_KERNEXEC
6665 ++ pax_open_kernel(cr0);
6666 ++#endif
6667 ++
6668 ++ *x = *y;
6669 ++ *y = t;
6670 ++
6671 ++#ifdef CONFIG_PAX_KERNEXEC
6672 ++ pax_close_kernel(cr0);
6673 ++#endif
6674 ++
6675 ++}
6676 ++
6677 ++void sort_extable(struct exception_table_entry *start,
6678 ++ struct exception_table_entry *finish)
6679 ++{
6680 ++ sort(start, finish - start, sizeof(struct exception_table_entry),
6681 ++ cmp_ex, swap_ex);
6682 ++}
6683 ++
6684 + int fixup_exception(struct pt_regs *regs)
6685 + {
6686 + const struct exception_table_entry *fixup;
6687 +
6688 + #ifdef CONFIG_PNPBIOS
6689 +- if (unlikely(SEGMENT_IS_PNP_CODE(regs->xcs)))
6690 ++ if (unlikely(!(regs->eflags & VM_MASK) && SEGMENT_IS_PNP_CODE(regs->xcs)))
6691 + {
6692 + extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
6693 + extern u32 pnp_bios_is_utter_crap;
6694 +diff -Nurp linux-2.6.23.15/arch/i386/mm/fault.c linux-2.6.23.15-grsec/arch/i386/mm/fault.c
6695 +--- linux-2.6.23.15/arch/i386/mm/fault.c 2007-10-09 21:31:38.000000000 +0100
6696 ++++ linux-2.6.23.15-grsec/arch/i386/mm/fault.c 2008-02-11 10:37:44.000000000 +0000
6697 +@@ -25,10 +25,14 @@
6698 + #include <linux/kprobes.h>
6699 + #include <linux/uaccess.h>
6700 + #include <linux/kdebug.h>
6701 ++#include <linux/unistd.h>
6702 ++#include <linux/compiler.h>
6703 ++#include <linux/binfmts.h>
6704 +
6705 + #include <asm/system.h>
6706 + #include <asm/desc.h>
6707 + #include <asm/segment.h>
6708 ++#include <asm/tlbflush.h>
6709 +
6710 + extern void die(const char *,struct pt_regs *,long);
6711 +
6712 +@@ -79,7 +83,8 @@ static inline unsigned long get_segment_
6713 + {
6714 + unsigned long eip = regs->eip;
6715 + unsigned seg = regs->xcs & 0xffff;
6716 +- u32 seg_ar, seg_limit, base, *desc;
6717 ++ u32 seg_ar, seg_limit, base;
6718 ++ struct desc_struct *desc;
6719 +
6720 + /* Unlikely, but must come before segment checks. */
6721 + if (unlikely(regs->eflags & VM_MASK)) {
6722 +@@ -93,7 +98,7 @@ static inline unsigned long get_segment_
6723 +
6724 + /* By far the most common cases. */
6725 + if (likely(SEGMENT_IS_FLAT_CODE(seg)))
6726 +- return eip;
6727 ++ return eip + (seg == __KERNEL_CS ? __KERNEL_TEXT_OFFSET : 0);
6728 +
6729 + /* Check the segment exists, is within the current LDT/GDT size,
6730 + that kernel/user (ring 0..3) has the appropriate privilege,
6731 +@@ -111,16 +116,19 @@ static inline unsigned long get_segment_
6732 + if (seg & (1<<2)) {
6733 + /* Must lock the LDT while reading it. */
6734 + down(&current->mm->context.sem);
6735 +- desc = current->mm->context.ldt;
6736 +- desc = (void *)desc + (seg & ~7);
6737 ++ if ((seg >> 3) >= current->mm->context.size) {
6738 ++ up(&current->mm->context.sem);
6739 ++ *eip_limit = 0;
6740 ++ return 1; /* So that returned eip > *eip_limit. */
6741 ++ }
6742 ++ desc = &current->mm->context.ldt[seg >> 3];
6743 + } else {
6744 + /* Must disable preemption while reading the GDT. */
6745 +- desc = (u32 *)get_cpu_gdt_table(get_cpu());
6746 +- desc = (void *)desc + (seg & ~7);
6747 ++ desc = &get_cpu_gdt_table(get_cpu())[seg >> 3];
6748 + }
6749 +
6750 + /* Decode the code segment base from the descriptor */
6751 +- base = get_desc_base((unsigned long *)desc);
6752 ++ base = get_desc_base(desc);
6753 +
6754 + if (seg & (1<<2)) {
6755 + up(&current->mm->context.sem);
6756 +@@ -221,6 +229,30 @@ static noinline void force_sig_info_faul
6757 +
6758 + fastcall void do_invalid_op(struct pt_regs *, unsigned long);
6759 +
6760 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
6761 ++static int pax_handle_fetch_fault(struct pt_regs *regs);
6762 ++#endif
6763 ++
6764 ++#ifdef CONFIG_PAX_PAGEEXEC
6765 ++static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
6766 ++{
6767 ++ pgd_t *pgd;
6768 ++ pud_t *pud;
6769 ++ pmd_t *pmd;
6770 ++
6771 ++ pgd = pgd_offset(mm, address);
6772 ++ if (!pgd_present(*pgd))
6773 ++ return NULL;
6774 ++ pud = pud_offset(pgd, address);
6775 ++ if (!pud_present(*pud))
6776 ++ return NULL;
6777 ++ pmd = pmd_offset(pud, address);
6778 ++ if (!pmd_present(*pmd))
6779 ++ return NULL;
6780 ++ return pmd;
6781 ++}
6782 ++#endif
6783 ++
6784 + static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
6785 + {
6786 + unsigned index = pgd_index(address);
6787 +@@ -304,14 +336,21 @@ fastcall void __kprobes do_page_fault(st
6788 + struct task_struct *tsk;
6789 + struct mm_struct *mm;
6790 + struct vm_area_struct * vma;
6791 +- unsigned long address;
6792 + int write, si_code;
6793 + int fault;
6794 ++ pte_t *pte;
6795 ++
6796 ++#ifdef CONFIG_PAX_PAGEEXEC
6797 ++ pmd_t *pmd;
6798 ++ spinlock_t *ptl;
6799 ++ unsigned char pte_mask;
6800 ++#endif
6801 +
6802 + /* get the address */
6803 +- address = read_cr2();
6804 ++ const unsigned long address = read_cr2();
6805 +
6806 + tsk = current;
6807 ++ mm = tsk->mm;
6808 +
6809 + si_code = SEGV_MAPERR;
6810 +
6811 +@@ -348,14 +387,12 @@ fastcall void __kprobes do_page_fault(st
6812 + if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
6813 + local_irq_enable();
6814 +
6815 +- mm = tsk->mm;
6816 +-
6817 + /*
6818 + * If we're in an interrupt, have no user context or are running in an
6819 + * atomic region then we must not take the fault..
6820 + */
6821 + if (in_atomic() || !mm)
6822 +- goto bad_area_nosemaphore;
6823 ++ goto bad_area_nopax;
6824 +
6825 + /* When running in the kernel we expect faults to occur only to
6826 + * addresses in user space. All other faults represent errors in the
6827 +@@ -375,10 +412,104 @@ fastcall void __kprobes do_page_fault(st
6828 + if (!down_read_trylock(&mm->mmap_sem)) {
6829 + if ((error_code & 4) == 0 &&
6830 + !search_exception_tables(regs->eip))
6831 +- goto bad_area_nosemaphore;
6832 ++ goto bad_area_nopax;
6833 + down_read(&mm->mmap_sem);
6834 + }
6835 +
6836 ++#ifdef CONFIG_PAX_PAGEEXEC
6837 ++ if (nx_enabled || (error_code & 5) != 5 || (regs->eflags & X86_EFLAGS_VM) ||
6838 ++ !(mm->pax_flags & MF_PAX_PAGEEXEC))
6839 ++ goto not_pax_fault;
6840 ++
6841 ++ /* PaX: it's our fault, let's handle it if we can */
6842 ++
6843 ++ /* PaX: take a look at read faults before acquiring any locks */
6844 ++ if (unlikely(!(error_code & 2) && (regs->eip == address))) {
6845 ++ /* instruction fetch attempt from a protected page in user mode */
6846 ++ up_read(&mm->mmap_sem);
6847 ++
6848 ++#ifdef CONFIG_PAX_EMUTRAMP
6849 ++ switch (pax_handle_fetch_fault(regs)) {
6850 ++ case 2:
6851 ++ return;
6852 ++ }
6853 ++#endif
6854 ++
6855 ++ pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp);
6856 ++ do_exit(SIGKILL);
6857 ++ }
6858 ++
6859 ++ pmd = pax_get_pmd(mm, address);
6860 ++ if (unlikely(!pmd))
6861 ++ goto not_pax_fault;
6862 ++
6863 ++ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
6864 ++ if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
6865 ++ pte_unmap_unlock(pte, ptl);
6866 ++ goto not_pax_fault;
6867 ++ }
6868 ++
6869 ++ if (unlikely((error_code & 2) && !pte_write(*pte))) {
6870 ++ /* write attempt to a protected page in user mode */
6871 ++ pte_unmap_unlock(pte, ptl);
6872 ++ goto not_pax_fault;
6873 ++ }
6874 ++
6875 ++#ifdef CONFIG_SMP
6876 ++ if (likely(address > get_limit(regs->xcs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
6877 ++#else
6878 ++ if (likely(address > get_limit(regs->xcs)))
6879 ++#endif
6880 ++ {
6881 ++ set_pte(pte, pte_mkread(*pte));
6882 ++ __flush_tlb_one(address);
6883 ++ pte_unmap_unlock(pte, ptl);
6884 ++ up_read(&mm->mmap_sem);
6885 ++ return;
6886 ++ }
6887 ++
6888 ++ pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
6889 ++
6890 ++ /*
6891 ++ * PaX: fill DTLB with user rights and retry
6892 ++ */
6893 ++ __asm__ __volatile__ (
6894 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
6895 ++ "movw %w4,%%es\n"
6896 ++#endif
6897 ++ "orb %2,(%1)\n"
6898 ++#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
6899 ++/*
6900 ++ * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
6901 ++ * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
6902 ++ * page fault when examined during a TLB load attempt. this is true not only
6903 ++ * for PTEs holding a non-present entry but also present entries that will
6904 ++ * raise a page fault (such as those set up by PaX, or the copy-on-write
6905 ++ * mechanism). in effect it means that we do *not* need to flush the TLBs
6906 ++ * for our target pages since their PTEs are simply not in the TLBs at all.
6907 ++
6908 ++ * the best thing in omitting it is that we gain around 15-20% speed in the
6909 ++ * fast path of the page fault handler and can get rid of tracing since we
6910 ++ * can no longer flush unintended entries.
6911 ++ */
6912 ++ "invlpg (%0)\n"
6913 ++#endif
6914 ++ "testb $0,%%es:(%0)\n"
6915 ++ "xorb %3,(%1)\n"
6916 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
6917 ++ "pushl %%ss\n"
6918 ++ "popl %%es\n"
6919 ++#endif
6920 ++ :
6921 ++ : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
6922 ++ : "memory", "cc");
6923 ++ pte_unmap_unlock(pte, ptl);
6924 ++ up_read(&mm->mmap_sem);
6925 ++ return;
6926 ++
6927 ++not_pax_fault:
6928 ++#endif
6929 ++
6930 + vma = find_vma(mm, address);
6931 + if (!vma)
6932 + goto bad_area;
6933 +@@ -396,6 +527,12 @@ fastcall void __kprobes do_page_fault(st
6934 + if (address + 65536 + 32 * sizeof(unsigned long) < regs->esp)
6935 + goto bad_area;
6936 + }
6937 ++
6938 ++#ifdef CONFIG_PAX_SEGMEXEC
6939 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)
6940 ++ goto bad_area;
6941 ++#endif
6942 ++
6943 + if (expand_stack(vma, address))
6944 + goto bad_area;
6945 + /*
6946 +@@ -405,6 +542,8 @@ fastcall void __kprobes do_page_fault(st
6947 + good_area:
6948 + si_code = SEGV_ACCERR;
6949 + write = 0;
6950 ++ if (nx_enabled && (error_code & 16) && !(vma->vm_flags & VM_EXEC))
6951 ++ goto bad_area;
6952 + switch (error_code & 3) {
6953 + default: /* 3: write, present */
6954 + /* fall through */
6955 +@@ -458,6 +597,41 @@ bad_area:
6956 + up_read(&mm->mmap_sem);
6957 +
6958 + bad_area_nosemaphore:
6959 ++
6960 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
6961 ++ if (mm && (error_code & 4) && !(regs->eflags & X86_EFLAGS_VM)) {
6962 ++ /*
6963 ++ * It's possible to have interrupts off here.
6964 ++ */
6965 ++ local_irq_enable();
6966 ++
6967 ++#ifdef CONFIG_PAX_PAGEEXEC
6968 ++ if ((nx_enabled && (error_code & 16)) ||
6969 ++ ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(error_code & 3) && (regs->eip == address))) {
6970 ++ pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp);
6971 ++ do_exit(SIGKILL);
6972 ++ }
6973 ++#endif
6974 ++
6975 ++#ifdef CONFIG_PAX_SEGMEXEC
6976 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & 3) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
6977 ++
6978 ++#ifdef CONFIG_PAX_EMUTRAMP
6979 ++ switch (pax_handle_fetch_fault(regs)) {
6980 ++ case 2:
6981 ++ return;
6982 ++ }
6983 ++#endif
6984 ++
6985 ++ pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp);
6986 ++ do_exit(SIGKILL);
6987 ++ }
6988 ++#endif
6989 ++
6990 ++ }
6991 ++#endif
6992 ++
6993 ++bad_area_nopax:
6994 + /* User mode accesses just cause a SIGSEGV */
6995 + if (error_code & 4) {
6996 + /*
6997 +@@ -495,7 +669,7 @@ bad_area_nosemaphore:
6998 + if (boot_cpu_data.f00f_bug) {
6999 + unsigned long nr;
7000 +
7001 +- nr = (address - idt_descr.address) >> 3;
7002 ++ nr = (address - (unsigned long)idt_descr.address) >> 3;
7003 +
7004 + if (nr == 6) {
7005 + do_invalid_op(regs, 0);
7006 +@@ -528,18 +702,34 @@ no_context:
7007 + __typeof__(pte_val(__pte(0))) page;
7008 +
7009 + #ifdef CONFIG_X86_PAE
7010 +- if (error_code & 16) {
7011 +- pte_t *pte = lookup_address(address);
7012 ++ if (nx_enabled && (error_code & 16)) {
7013 ++ pte = lookup_address(address);
7014 +
7015 + if (pte && pte_present(*pte) && !pte_exec_kernel(*pte))
7016 + printk(KERN_CRIT "kernel tried to execute "
7017 + "NX-protected page - exploit attempt? "
7018 +- "(uid: %d)\n", current->uid);
7019 ++ "(uid: %d, task: %s, pid: %d)\n",
7020 ++ current->uid, current->comm, current->pid);
7021 + }
7022 + #endif
7023 + if (address < PAGE_SIZE)
7024 + printk(KERN_ALERT "BUG: unable to handle kernel NULL "
7025 + "pointer dereference");
7026 ++
7027 ++#ifdef CONFIG_PAX_KERNEXEC
7028 ++#ifdef CONFIG_MODULES
7029 ++ else if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
7030 ++#else
7031 ++ else if (init_mm.start_code <= address && address < init_mm.end_code)
7032 ++#endif
7033 ++ if (tsk->signal->curr_ip)
7034 ++ printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
7035 ++ NIPQUAD(tsk->signal->curr_ip), tsk->comm, tsk->pid, tsk->uid, tsk->euid);
7036 ++ else
7037 ++ printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
7038 ++ tsk->comm, tsk->pid, tsk->uid, tsk->euid);
7039 ++#endif
7040 ++
7041 + else
7042 + printk(KERN_ALERT "BUG: unable to handle kernel paging"
7043 + " request");
7044 +@@ -570,7 +760,7 @@ no_context:
7045 + * it's allocated already.
7046 + */
7047 + if ((page >> PAGE_SHIFT) < max_low_pfn
7048 +- && (page & _PAGE_PRESENT)) {
7049 ++ && (page & (_PAGE_PRESENT | _PAGE_PSE)) == _PAGE_PRESENT) {
7050 + page &= PAGE_MASK;
7051 + page = ((__typeof__(page) *) __va(page))[(address >> PAGE_SHIFT)
7052 + & (PTRS_PER_PTE - 1)];
7053 +@@ -655,3 +845,92 @@ void vmalloc_sync_all(void)
7054 + start = address + PGDIR_SIZE;
7055 + }
7056 + }
7057 ++
7058 ++#ifdef CONFIG_PAX_EMUTRAMP
7059 ++/*
7060 ++ * PaX: decide what to do with offenders (regs->eip = fault address)
7061 ++ *
7062 ++ * returns 1 when task should be killed
7063 ++ * 2 when gcc trampoline was detected
7064 ++ */
7065 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
7066 ++{
7067 ++ int err;
7068 ++
7069 ++ if (regs->eflags & X86_EFLAGS_VM)
7070 ++ return 1;
7071 ++
7072 ++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
7073 ++ return 1;
7074 ++
7075 ++ do { /* PaX: gcc trampoline emulation #1 */
7076 ++ unsigned char mov1, mov2;
7077 ++ unsigned short jmp;
7078 ++ unsigned long addr1, addr2;
7079 ++
7080 ++ err = get_user(mov1, (unsigned char __user *)regs->eip);
7081 ++ err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
7082 ++ err |= get_user(mov2, (unsigned char __user *)(regs->eip + 5));
7083 ++ err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
7084 ++ err |= get_user(jmp, (unsigned short __user *)(regs->eip + 10));
7085 ++
7086 ++ if (err)
7087 ++ break;
7088 ++
7089 ++ if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
7090 ++ regs->ecx = addr1;
7091 ++ regs->eax = addr2;
7092 ++ regs->eip = addr2;
7093 ++ return 2;
7094 ++ }
7095 ++ } while (0);
7096 ++
7097 ++ do { /* PaX: gcc trampoline emulation #2 */
7098 ++ unsigned char mov, jmp;
7099 ++ unsigned long addr1, addr2;
7100 ++
7101 ++ err = get_user(mov, (unsigned char __user *)regs->eip);
7102 ++ err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
7103 ++ err |= get_user(jmp, (unsigned char __user *)(regs->eip + 5));
7104 ++ err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
7105 ++
7106 ++ if (err)
7107 ++ break;
7108 ++
7109 ++ if (mov == 0xB9 && jmp == 0xE9) {
7110 ++ regs->ecx = addr1;
7111 ++ regs->eip += addr2 + 10;
7112 ++ return 2;
7113 ++ }
7114 ++ } while (0);
7115 ++
7116 ++ return 1; /* PaX in action */
7117 ++}
7118 ++#endif
7119 ++
7120 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
7121 ++void pax_report_insns(void *pc, void *sp)
7122 ++{
7123 ++ long i;
7124 ++
7125 ++ printk(KERN_ERR "PAX: bytes at PC: ");
7126 ++ for (i = 0; i < 20; i++) {
7127 ++ unsigned char c;
7128 ++ if (get_user(c, (unsigned char __user *)pc+i))
7129 ++ printk("?? ");
7130 ++ else
7131 ++ printk("%02x ", c);
7132 ++ }
7133 ++ printk("\n");
7134 ++
7135 ++ printk(KERN_ERR "PAX: bytes at SP-4: ");
7136 ++ for (i = -1; i < 20; i++) {
7137 ++ unsigned long c;
7138 ++ if (get_user(c, (unsigned long __user *)sp+i))
7139 ++ printk("???????? ");
7140 ++ else
7141 ++ printk("%08lx ", c);
7142 ++ }
7143 ++ printk("\n");
7144 ++}
7145 ++#endif
7146 +diff -Nurp linux-2.6.23.15/arch/i386/mm/hugetlbpage.c linux-2.6.23.15-grsec/arch/i386/mm/hugetlbpage.c
7147 +--- linux-2.6.23.15/arch/i386/mm/hugetlbpage.c 2007-10-09 21:31:38.000000000 +0100
7148 ++++ linux-2.6.23.15-grsec/arch/i386/mm/hugetlbpage.c 2008-02-11 10:37:44.000000000 +0000
7149 +@@ -229,13 +229,18 @@ static unsigned long hugetlb_get_unmappe
7150 + {
7151 + struct mm_struct *mm = current->mm;
7152 + struct vm_area_struct *vma;
7153 +- unsigned long start_addr;
7154 ++ unsigned long start_addr, task_size = TASK_SIZE;
7155 ++
7156 ++#ifdef CONFIG_PAX_SEGMEXEC
7157 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
7158 ++ task_size = SEGMEXEC_TASK_SIZE;
7159 ++#endif
7160 +
7161 + if (len > mm->cached_hole_size) {
7162 +- start_addr = mm->free_area_cache;
7163 ++ start_addr = mm->free_area_cache;
7164 + } else {
7165 +- start_addr = TASK_UNMAPPED_BASE;
7166 +- mm->cached_hole_size = 0;
7167 ++ start_addr = mm->mmap_base;
7168 ++ mm->cached_hole_size = 0;
7169 + }
7170 +
7171 + full_search:
7172 +@@ -243,13 +248,13 @@ full_search:
7173 +
7174 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
7175 + /* At this point: (!vma || addr < vma->vm_end). */
7176 +- if (TASK_SIZE - len < addr) {
7177 ++ if (task_size - len < addr) {
7178 + /*
7179 + * Start a new search - just in case we missed
7180 + * some holes.
7181 + */
7182 +- if (start_addr != TASK_UNMAPPED_BASE) {
7183 +- start_addr = TASK_UNMAPPED_BASE;
7184 ++ if (start_addr != mm->mmap_base) {
7185 ++ start_addr = mm->mmap_base;
7186 + mm->cached_hole_size = 0;
7187 + goto full_search;
7188 + }
7189 +@@ -271,9 +276,8 @@ static unsigned long hugetlb_get_unmappe
7190 + {
7191 + struct mm_struct *mm = current->mm;
7192 + struct vm_area_struct *vma, *prev_vma;
7193 +- unsigned long base = mm->mmap_base, addr = addr0;
7194 ++ unsigned long base = mm->mmap_base, addr;
7195 + unsigned long largest_hole = mm->cached_hole_size;
7196 +- int first_time = 1;
7197 +
7198 + /* don't allow allocations above current base */
7199 + if (mm->free_area_cache > base)
7200 +@@ -283,7 +287,7 @@ static unsigned long hugetlb_get_unmappe
7201 + largest_hole = 0;
7202 + mm->free_area_cache = base;
7203 + }
7204 +-try_again:
7205 ++
7206 + /* make sure it can fit in the remaining address space */
7207 + if (mm->free_area_cache < len)
7208 + goto fail;
7209 +@@ -325,22 +329,26 @@ try_again:
7210 +
7211 + fail:
7212 + /*
7213 +- * if hint left us with no space for the requested
7214 +- * mapping then try again:
7215 +- */
7216 +- if (first_time) {
7217 +- mm->free_area_cache = base;
7218 +- largest_hole = 0;
7219 +- first_time = 0;
7220 +- goto try_again;
7221 +- }
7222 +- /*
7223 + * A failed mmap() very likely causes application failure,
7224 + * so fall back to the bottom-up function here. This scenario
7225 + * can happen with large stack limits and large mmap()
7226 + * allocations.
7227 + */
7228 +- mm->free_area_cache = TASK_UNMAPPED_BASE;
7229 ++
7230 ++#ifdef CONFIG_PAX_SEGMEXEC
7231 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
7232 ++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
7233 ++ else
7234 ++#endif
7235 ++
7236 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
7237 ++
7238 ++#ifdef CONFIG_PAX_RANDMMAP
7239 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
7240 ++ mm->mmap_base += mm->delta_mmap;
7241 ++#endif
7242 ++
7243 ++ mm->free_area_cache = mm->mmap_base;
7244 + mm->cached_hole_size = ~0UL;
7245 + addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
7246 + len, pgoff, flags);
7247 +@@ -348,6 +356,7 @@ fail:
7248 + /*
7249 + * Restore the topdown base:
7250 + */
7251 ++ mm->mmap_base = base;
7252 + mm->free_area_cache = base;
7253 + mm->cached_hole_size = ~0UL;
7254 +
7255 +@@ -360,10 +369,17 @@ hugetlb_get_unmapped_area(struct file *f
7256 + {
7257 + struct mm_struct *mm = current->mm;
7258 + struct vm_area_struct *vma;
7259 ++ unsigned long task_size = TASK_SIZE;
7260 +
7261 + if (len & ~HPAGE_MASK)
7262 + return -EINVAL;
7263 +- if (len > TASK_SIZE)
7264 ++
7265 ++#ifdef CONFIG_PAX_SEGMEXEC
7266 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
7267 ++ task_size = SEGMEXEC_TASK_SIZE;
7268 ++#endif
7269 ++
7270 ++ if (len > task_size)
7271 + return -ENOMEM;
7272 +
7273 + if (flags & MAP_FIXED) {
7274 +@@ -375,7 +391,7 @@ hugetlb_get_unmapped_area(struct file *f
7275 + if (addr) {
7276 + addr = ALIGN(addr, HPAGE_SIZE);
7277 + vma = find_vma(mm, addr);
7278 +- if (TASK_SIZE - len >= addr &&
7279 ++ if (task_size - len >= addr &&
7280 + (!vma || addr + len <= vma->vm_start))
7281 + return addr;
7282 + }
7283 +diff -Nurp linux-2.6.23.15/arch/i386/mm/init.c linux-2.6.23.15-grsec/arch/i386/mm/init.c
7284 +--- linux-2.6.23.15/arch/i386/mm/init.c 2007-10-09 21:31:38.000000000 +0100
7285 ++++ linux-2.6.23.15-grsec/arch/i386/mm/init.c 2008-02-11 10:37:44.000000000 +0000
7286 +@@ -44,6 +44,7 @@
7287 + #include <asm/tlbflush.h>
7288 + #include <asm/sections.h>
7289 + #include <asm/paravirt.h>
7290 ++#include <asm/desc.h>
7291 +
7292 + unsigned int __VMALLOC_RESERVE = 128 << 20;
7293 +
7294 +@@ -53,32 +54,6 @@ unsigned long highstart_pfn, highend_pfn
7295 + static int noinline do_test_wp_bit(void);
7296 +
7297 + /*
7298 +- * Creates a middle page table and puts a pointer to it in the
7299 +- * given global directory entry. This only returns the gd entry
7300 +- * in non-PAE compilation mode, since the middle layer is folded.
7301 +- */
7302 +-static pmd_t * __init one_md_table_init(pgd_t *pgd)
7303 +-{
7304 +- pud_t *pud;
7305 +- pmd_t *pmd_table;
7306 +-
7307 +-#ifdef CONFIG_X86_PAE
7308 +- if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
7309 +- pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
7310 +-
7311 +- paravirt_alloc_pd(__pa(pmd_table) >> PAGE_SHIFT);
7312 +- set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
7313 +- pud = pud_offset(pgd, 0);
7314 +- if (pmd_table != pmd_offset(pud, 0))
7315 +- BUG();
7316 +- }
7317 +-#endif
7318 +- pud = pud_offset(pgd, 0);
7319 +- pmd_table = pmd_offset(pud, 0);
7320 +- return pmd_table;
7321 +-}
7322 +-
7323 +-/*
7324 + * Create a page table and place a pointer to it in a middle page
7325 + * directory entry.
7326 + */
7327 +@@ -88,7 +63,11 @@ static pte_t * __init one_page_table_ini
7328 + pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
7329 +
7330 + paravirt_alloc_pt(&init_mm, __pa(page_table) >> PAGE_SHIFT);
7331 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
7332 ++ set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
7333 ++#else
7334 + set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
7335 ++#endif
7336 + BUG_ON(page_table != pte_offset_kernel(pmd, 0));
7337 + }
7338 +
7339 +@@ -109,6 +88,7 @@ static pte_t * __init one_page_table_ini
7340 + static void __init page_table_range_init (unsigned long start, unsigned long end, pgd_t *pgd_base)
7341 + {
7342 + pgd_t *pgd;
7343 ++ pud_t *pud;
7344 + pmd_t *pmd;
7345 + int pgd_idx, pmd_idx;
7346 + unsigned long vaddr;
7347 +@@ -119,8 +99,13 @@ static void __init page_table_range_init
7348 + pgd = pgd_base + pgd_idx;
7349 +
7350 + for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
7351 +- pmd = one_md_table_init(pgd);
7352 +- pmd = pmd + pmd_index(vaddr);
7353 ++ pud = pud_offset(pgd, vaddr);
7354 ++ pmd = pmd_offset(pud, vaddr);
7355 ++
7356 ++#ifdef CONFIG_X86_PAE
7357 ++ paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT);
7358 ++#endif
7359 ++
7360 + for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
7361 + one_page_table_init(pmd);
7362 +
7363 +@@ -130,11 +115,23 @@ static void __init page_table_range_init
7364 + }
7365 + }
7366 +
7367 +-static inline int is_kernel_text(unsigned long addr)
7368 ++static inline int is_kernel_text(unsigned long start, unsigned long end)
7369 + {
7370 +- if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
7371 +- return 1;
7372 +- return 0;
7373 ++ unsigned long etext;
7374 ++
7375 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
7376 ++ etext = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
7377 ++#else
7378 ++ etext = (unsigned long)&_etext;
7379 ++#endif
7380 ++
7381 ++ if ((start > etext + __KERNEL_TEXT_OFFSET ||
7382 ++ end <= (unsigned long)_stext + __KERNEL_TEXT_OFFSET) &&
7383 ++ (start > (unsigned long)_einittext + __KERNEL_TEXT_OFFSET ||
7384 ++ end <= (unsigned long)_sinittext + __KERNEL_TEXT_OFFSET) &&
7385 ++ (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000)))
7386 ++ return 0;
7387 ++ return 1;
7388 + }
7389 +
7390 + /*
7391 +@@ -146,25 +143,29 @@ static void __init kernel_physical_mappi
7392 + {
7393 + unsigned long pfn;
7394 + pgd_t *pgd;
7395 ++ pud_t *pud;
7396 + pmd_t *pmd;
7397 + pte_t *pte;
7398 +- int pgd_idx, pmd_idx, pte_ofs;
7399 ++ unsigned int pgd_idx, pmd_idx, pte_ofs;
7400 +
7401 + pgd_idx = pgd_index(PAGE_OFFSET);
7402 + pgd = pgd_base + pgd_idx;
7403 + pfn = 0;
7404 +
7405 +- for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
7406 +- pmd = one_md_table_init(pgd);
7407 +- if (pfn >= max_low_pfn)
7408 +- continue;
7409 ++ for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
7410 ++ pud = pud_offset(pgd, 0);
7411 ++ pmd = pmd_offset(pud, 0);
7412 ++
7413 ++#ifdef CONFIG_X86_PAE
7414 ++ paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT);
7415 ++#endif
7416 ++
7417 + for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
7418 +- unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET;
7419 ++ unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
7420 +
7421 + /* Map with big pages if possible, otherwise create normal page tables. */
7422 +- if (cpu_has_pse) {
7423 +- unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1;
7424 +- if (is_kernel_text(address) || is_kernel_text(address2))
7425 ++ if (cpu_has_pse && address >= (unsigned long)__va(0x100000)) {
7426 ++ if (is_kernel_text(address, address + PMD_SIZE))
7427 + set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC));
7428 + else
7429 + set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
7430 +@@ -176,7 +177,7 @@ static void __init kernel_physical_mappi
7431 + for (pte_ofs = 0;
7432 + pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn;
7433 + pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
7434 +- if (is_kernel_text(address))
7435 ++ if (is_kernel_text(address, address + PAGE_SIZE))
7436 + set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
7437 + else
7438 + set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
7439 +@@ -326,9 +327,9 @@ static void __init set_highmem_pages_ini
7440 + #define set_highmem_pages_init(bad_ppro) do { } while (0)
7441 + #endif /* CONFIG_HIGHMEM */
7442 +
7443 +-unsigned long long __PAGE_KERNEL = _PAGE_KERNEL;
7444 ++unsigned long long __PAGE_KERNEL __read_only = _PAGE_KERNEL;
7445 + EXPORT_SYMBOL(__PAGE_KERNEL);
7446 +-unsigned long long __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC;
7447 ++unsigned long long __PAGE_KERNEL_EXEC __read_only = _PAGE_KERNEL_EXEC;
7448 +
7449 + #ifdef CONFIG_NUMA
7450 + extern void __init remap_numa_kva(void);
7451 +@@ -339,26 +340,10 @@ extern void __init remap_numa_kva(void);
7452 + void __init native_pagetable_setup_start(pgd_t *base)
7453 + {
7454 + #ifdef CONFIG_X86_PAE
7455 +- int i;
7456 ++ unsigned int i;
7457 +
7458 +- /*
7459 +- * Init entries of the first-level page table to the
7460 +- * zero page, if they haven't already been set up.
7461 +- *
7462 +- * In a normal native boot, we'll be running on a
7463 +- * pagetable rooted in swapper_pg_dir, but not in PAE
7464 +- * mode, so this will end up clobbering the mappings
7465 +- * for the lower 24Mbytes of the address space,
7466 +- * without affecting the kernel address space.
7467 +- */
7468 +- for (i = 0; i < USER_PTRS_PER_PGD; i++)
7469 +- set_pgd(&base[i],
7470 +- __pgd(__pa(empty_zero_page) | _PAGE_PRESENT));
7471 +-
7472 +- /* Make sure kernel address space is empty so that a pagetable
7473 +- will be allocated for it. */
7474 +- memset(&base[USER_PTRS_PER_PGD], 0,
7475 +- KERNEL_PGD_PTRS * sizeof(pgd_t));
7476 ++ for (i = 0; i < PTRS_PER_PGD; i++)
7477 ++ paravirt_alloc_pd(__pa(swapper_pm_dir + i) >> PAGE_SHIFT);
7478 + #else
7479 + paravirt_alloc_pd(__pa(swapper_pg_dir) >> PAGE_SHIFT);
7480 + #endif
7481 +@@ -366,16 +351,6 @@ void __init native_pagetable_setup_start
7482 +
7483 + void __init native_pagetable_setup_done(pgd_t *base)
7484 + {
7485 +-#ifdef CONFIG_X86_PAE
7486 +- /*
7487 +- * Add low memory identity-mappings - SMP needs it when
7488 +- * starting up on an AP from real-mode. In the non-PAE
7489 +- * case we already have these mappings through head.S.
7490 +- * All user-space mappings are explicitly cleared after
7491 +- * SMP startup.
7492 +- */
7493 +- set_pgd(&base[0], base[USER_PTRS_PER_PGD]);
7494 +-#endif
7495 + }
7496 +
7497 + /*
7498 +@@ -437,12 +412,12 @@ static void __init pagetable_init (void)
7499 + * Swap suspend & friends need this for resume because things like the intel-agp
7500 + * driver might have split up a kernel 4MB mapping.
7501 + */
7502 +-char __nosavedata swsusp_pg_dir[PAGE_SIZE]
7503 ++pgd_t __nosavedata swsusp_pg_dir[PTRS_PER_PGD]
7504 + __attribute__ ((aligned (PAGE_SIZE)));
7505 +
7506 + static inline void save_pg_dir(void)
7507 + {
7508 +- memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
7509 ++ clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD);
7510 + }
7511 + #else
7512 + static inline void save_pg_dir(void)
7513 +@@ -471,12 +446,11 @@ void zap_low_mappings (void)
7514 + flush_tlb_all();
7515 + }
7516 +
7517 +-int nx_enabled = 0;
7518 ++int nx_enabled;
7519 +
7520 + #ifdef CONFIG_X86_PAE
7521 +
7522 +-static int disable_nx __initdata = 0;
7523 +-u64 __supported_pte_mask __read_mostly = ~_PAGE_NX;
7524 ++u64 __supported_pte_mask __read_only = ~_PAGE_NX;
7525 + EXPORT_SYMBOL_GPL(__supported_pte_mask);
7526 +
7527 + /*
7528 +@@ -487,36 +461,31 @@ EXPORT_SYMBOL_GPL(__supported_pte_mask);
7529 + * on Enable
7530 + * off Disable
7531 + */
7532 ++#if !defined(CONFIG_PAX_PAGEEXEC)
7533 + static int __init noexec_setup(char *str)
7534 + {
7535 + if (!str || !strcmp(str, "on")) {
7536 +- if (cpu_has_nx) {
7537 +- __supported_pte_mask |= _PAGE_NX;
7538 +- disable_nx = 0;
7539 +- }
7540 ++ if (cpu_has_nx)
7541 ++ nx_enabled = 1;
7542 + } else if (!strcmp(str,"off")) {
7543 +- disable_nx = 1;
7544 +- __supported_pte_mask &= ~_PAGE_NX;
7545 ++ nx_enabled = 0;
7546 + } else
7547 + return -EINVAL;
7548 +
7549 + return 0;
7550 + }
7551 + early_param("noexec", noexec_setup);
7552 ++#endif
7553 +
7554 + static void __init set_nx(void)
7555 + {
7556 +- unsigned int v[4], l, h;
7557 ++ if (!nx_enabled && cpu_has_nx) {
7558 ++ unsigned l, h;
7559 +
7560 +- if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
7561 +- cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
7562 +- if ((v[3] & (1 << 20)) && !disable_nx) {
7563 +- rdmsr(MSR_EFER, l, h);
7564 +- l |= EFER_NX;
7565 +- wrmsr(MSR_EFER, l, h);
7566 +- nx_enabled = 1;
7567 +- __supported_pte_mask |= _PAGE_NX;
7568 +- }
7569 ++ __supported_pte_mask &= ~_PAGE_NX;
7570 ++ rdmsr(MSR_EFER, l, h);
7571 ++ l &= ~EFER_NX;
7572 ++ wrmsr(MSR_EFER, l, h);
7573 + }
7574 + }
7575 +
7576 +@@ -569,14 +538,6 @@ void __init paging_init(void)
7577 +
7578 + load_cr3(swapper_pg_dir);
7579 +
7580 +-#ifdef CONFIG_X86_PAE
7581 +- /*
7582 +- * We will bail out later - printk doesn't work right now so
7583 +- * the user would just see a hanging kernel.
7584 +- */
7585 +- if (cpu_has_pae)
7586 +- set_in_cr4(X86_CR4_PAE);
7587 +-#endif
7588 + __flush_tlb_all();
7589 +
7590 + kmap_init();
7591 +@@ -647,7 +608,7 @@ void __init mem_init(void)
7592 + set_highmem_pages_init(bad_ppro);
7593 +
7594 + codesize = (unsigned long) &_etext - (unsigned long) &_text;
7595 +- datasize = (unsigned long) &_edata - (unsigned long) &_etext;
7596 ++ datasize = (unsigned long) &_edata - (unsigned long) &_data;
7597 + initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
7598 +
7599 + kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
7600 +@@ -692,10 +653,10 @@ void __init mem_init(void)
7601 + (unsigned long)&__init_begin, (unsigned long)&__init_end,
7602 + ((unsigned long)&__init_end - (unsigned long)&__init_begin) >> 10,
7603 +
7604 +- (unsigned long)&_etext, (unsigned long)&_edata,
7605 +- ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
7606 ++ (unsigned long)&_data, (unsigned long)&_edata,
7607 ++ ((unsigned long)&_edata - (unsigned long)&_data) >> 10,
7608 +
7609 +- (unsigned long)&_text, (unsigned long)&_etext,
7610 ++ (unsigned long)&_text + __KERNEL_TEXT_OFFSET, (unsigned long)&_etext + __KERNEL_TEXT_OFFSET,
7611 + ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
7612 +
7613 + #ifdef CONFIG_HIGHMEM
7614 +@@ -706,10 +667,6 @@ void __init mem_init(void)
7615 + BUG_ON((unsigned long)high_memory > VMALLOC_START);
7616 + #endif /* double-sanity-check paranoia */
7617 +
7618 +-#ifdef CONFIG_X86_PAE
7619 +- if (!cpu_has_pae)
7620 +- panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
7621 +-#endif
7622 + if (boot_cpu_data.wp_works_ok < 0)
7623 + test_wp_bit();
7624 +
7625 +@@ -844,6 +801,38 @@ void free_init_pages(char *what, unsigne
7626 +
7627 + void free_initmem(void)
7628 + {
7629 ++
7630 ++#ifdef CONFIG_PAX_KERNEXEC
7631 ++ /* PaX: limit KERNEL_CS to actual size */
7632 ++ unsigned long addr, limit;
7633 ++ __u32 a, b;
7634 ++ int cpu;
7635 ++ pgd_t *pgd;
7636 ++ pud_t *pud;
7637 ++ pmd_t *pmd;
7638 ++
7639 ++#ifdef CONFIG_MODULES
7640 ++ limit = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
7641 ++#else
7642 ++ limit = (unsigned long)&_etext;
7643 ++#endif
7644 ++ limit = (limit - 1UL) >> PAGE_SHIFT;
7645 ++
7646 ++ for (cpu = 0; cpu < NR_CPUS; cpu++) {
7647 ++ pack_descriptor(&a, &b, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC);
7648 ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, a, b);
7649 ++ }
7650 ++
7651 ++ /* PaX: make KERNEL_CS read-only */
7652 ++ for (addr = __KERNEL_TEXT_OFFSET; addr < (unsigned long)&_data; addr += PMD_SIZE) {
7653 ++ pgd = pgd_offset_k(addr);
7654 ++ pud = pud_offset(pgd, addr);
7655 ++ pmd = pmd_offset(pud, addr);
7656 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
7657 ++ }
7658 ++ flush_tlb_all();
7659 ++#endif
7660 ++
7661 + free_init_pages("unused kernel memory",
7662 + (unsigned long)(&__init_begin),
7663 + (unsigned long)(&__init_end));
7664 +diff -Nurp linux-2.6.23.15/arch/i386/mm/mmap.c linux-2.6.23.15-grsec/arch/i386/mm/mmap.c
7665 +--- linux-2.6.23.15/arch/i386/mm/mmap.c 2007-10-09 21:31:38.000000000 +0100
7666 ++++ linux-2.6.23.15-grsec/arch/i386/mm/mmap.c 2008-02-11 10:37:44.000000000 +0000
7667 +@@ -35,12 +35,18 @@
7668 + * Leave an at least ~128 MB hole.
7669 + */
7670 + #define MIN_GAP (128*1024*1024)
7671 +-#define MAX_GAP (TASK_SIZE/6*5)
7672 ++#define MAX_GAP (task_size/6*5)
7673 +
7674 + static inline unsigned long mmap_base(struct mm_struct *mm)
7675 + {
7676 + unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
7677 + unsigned long random_factor = 0;
7678 ++ unsigned long task_size = TASK_SIZE;
7679 ++
7680 ++#ifdef CONFIG_PAX_SEGMEXEC
7681 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
7682 ++ task_size = SEGMEXEC_TASK_SIZE;
7683 ++#endif
7684 +
7685 + if (current->flags & PF_RANDOMIZE)
7686 + random_factor = get_random_int() % (1024*1024);
7687 +@@ -50,7 +56,7 @@ static inline unsigned long mmap_base(st
7688 + else if (gap > MAX_GAP)
7689 + gap = MAX_GAP;
7690 +
7691 +- return PAGE_ALIGN(TASK_SIZE - gap - random_factor);
7692 ++ return PAGE_ALIGN(task_size - gap - random_factor);
7693 + }
7694 +
7695 + /*
7696 +@@ -66,11 +72,30 @@ void arch_pick_mmap_layout(struct mm_str
7697 + if (sysctl_legacy_va_layout ||
7698 + (current->personality & ADDR_COMPAT_LAYOUT) ||
7699 + current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
7700 ++
7701 ++#ifdef CONFIG_PAX_SEGMEXEC
7702 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
7703 ++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
7704 ++ else
7705 ++#endif
7706 ++
7707 + mm->mmap_base = TASK_UNMAPPED_BASE;
7708 ++
7709 ++#ifdef CONFIG_PAX_RANDMMAP
7710 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
7711 ++ mm->mmap_base += mm->delta_mmap;
7712 ++#endif
7713 ++
7714 + mm->get_unmapped_area = arch_get_unmapped_area;
7715 + mm->unmap_area = arch_unmap_area;
7716 + } else {
7717 + mm->mmap_base = mmap_base(mm);
7718 ++
7719 ++#ifdef CONFIG_PAX_RANDMMAP
7720 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
7721 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
7722 ++#endif
7723 ++
7724 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
7725 + mm->unmap_area = arch_unmap_area_topdown;
7726 + }
7727 +diff -Nurp linux-2.6.23.15/arch/i386/mm/pageattr.c linux-2.6.23.15-grsec/arch/i386/mm/pageattr.c
7728 +--- linux-2.6.23.15/arch/i386/mm/pageattr.c 2007-10-09 21:31:38.000000000 +0100
7729 ++++ linux-2.6.23.15-grsec/arch/i386/mm/pageattr.c 2008-02-11 10:37:44.000000000 +0000
7730 +@@ -13,6 +13,7 @@
7731 + #include <asm/tlbflush.h>
7732 + #include <asm/pgalloc.h>
7733 + #include <asm/sections.h>
7734 ++#include <asm/desc.h>
7735 +
7736 + static DEFINE_SPINLOCK(cpa_lock);
7737 + static struct list_head df_list = LIST_HEAD_INIT(df_list);
7738 +@@ -37,16 +38,16 @@ pte_t *lookup_address(unsigned long addr
7739 + }
7740 +
7741 + static struct page *split_large_page(unsigned long address, pgprot_t prot,
7742 +- pgprot_t ref_prot)
7743 ++ pgprot_t ref_prot, unsigned long flags)
7744 + {
7745 + int i;
7746 + unsigned long addr;
7747 + struct page *base;
7748 + pte_t *pbase;
7749 +
7750 +- spin_unlock_irq(&cpa_lock);
7751 ++ spin_unlock_irqrestore(&cpa_lock, flags);
7752 + base = alloc_pages(GFP_KERNEL, 0);
7753 +- spin_lock_irq(&cpa_lock);
7754 ++ spin_lock_irqsave(&cpa_lock, flags);
7755 + if (!base)
7756 + return NULL;
7757 +
7758 +@@ -99,7 +100,18 @@ static void set_pmd_pte(pte_t *kpte, uns
7759 + struct page *page;
7760 + unsigned long flags;
7761 +
7762 ++#ifdef CONFIG_PAX_KERNEXEC
7763 ++ unsigned long cr0;
7764 ++
7765 ++ pax_open_kernel(cr0);
7766 ++#endif
7767 ++
7768 + set_pte_atomic(kpte, pte); /* change init_mm */
7769 ++
7770 ++#ifdef CONFIG_PAX_KERNEXEC
7771 ++ pax_close_kernel(cr0);
7772 ++#endif
7773 ++
7774 + if (SHARED_KERNEL_PMD)
7775 + return;
7776 +
7777 +@@ -126,7 +138,7 @@ static inline void revert_page(struct pa
7778 + pte_t *linear;
7779 +
7780 + ref_prot =
7781 +- ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
7782 ++ ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
7783 + ? PAGE_KERNEL_LARGE_EXEC : PAGE_KERNEL_LARGE;
7784 +
7785 + linear = (pte_t *)
7786 +@@ -143,7 +155,7 @@ static inline void save_page(struct page
7787 + }
7788 +
7789 + static int
7790 +-__change_page_attr(struct page *page, pgprot_t prot)
7791 ++__change_page_attr(struct page *page, pgprot_t prot, unsigned long flags)
7792 + {
7793 + pte_t *kpte;
7794 + unsigned long address;
7795 +@@ -167,13 +179,20 @@ __change_page_attr(struct page *page, pg
7796 + struct page *split;
7797 +
7798 + ref_prot =
7799 +- ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
7800 ++ ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
7801 + ? PAGE_KERNEL_EXEC : PAGE_KERNEL;
7802 +- split = split_large_page(address, prot, ref_prot);
7803 ++ split = split_large_page(address, prot, ref_prot, flags);
7804 + if (!split)
7805 + return -ENOMEM;
7806 +- set_pmd_pte(kpte,address,mk_pte(split, ref_prot));
7807 +- kpte_page = split;
7808 ++ if (pte_huge(*kpte)) {
7809 ++ set_pmd_pte(kpte,address,mk_pte(split, ref_prot));
7810 ++ kpte_page = split;
7811 ++ } else {
7812 ++ __free_pages(split, 0);
7813 ++ kpte = lookup_address(address);
7814 ++ kpte_page = virt_to_page(kpte);
7815 ++ set_pte_atomic(kpte, mk_pte(page, prot));
7816 ++ }
7817 + }
7818 + page_private(kpte_page)++;
7819 + } else if (!pte_huge(*kpte)) {
7820 +@@ -225,7 +244,7 @@ int change_page_attr(struct page *page,
7821 +
7822 + spin_lock_irqsave(&cpa_lock, flags);
7823 + for (i = 0; i < numpages; i++, page++) {
7824 +- err = __change_page_attr(page, prot);
7825 ++ err = __change_page_attr(page, prot, flags);
7826 + if (err)
7827 + break;
7828 + }
7829 +diff -Nurp linux-2.6.23.15/arch/i386/oprofile/backtrace.c linux-2.6.23.15-grsec/arch/i386/oprofile/backtrace.c
7830 +--- linux-2.6.23.15/arch/i386/oprofile/backtrace.c 2007-10-09 21:31:38.000000000 +0100
7831 ++++ linux-2.6.23.15-grsec/arch/i386/oprofile/backtrace.c 2008-02-11 10:37:44.000000000 +0000
7832 +@@ -22,7 +22,7 @@ struct frame_head {
7833 + static struct frame_head *
7834 + dump_kernel_backtrace(struct frame_head * head)
7835 + {
7836 +- oprofile_add_trace(head->ret);
7837 ++ oprofile_add_trace(head->ret + __KERNEL_TEXT_OFFSET);
7838 +
7839 + /* frame pointers should strictly progress back up the stack
7840 + * (towards higher addresses) */
7841 +@@ -116,7 +116,7 @@ x86_backtrace(struct pt_regs * const reg
7842 + head = (struct frame_head *)regs->ebp;
7843 + #endif
7844 +
7845 +- if (!user_mode_vm(regs)) {
7846 ++ if (!user_mode(regs)) {
7847 + while (depth-- && valid_kernel_stack(head, regs))
7848 + head = dump_kernel_backtrace(head);
7849 + return;
7850 +diff -Nurp linux-2.6.23.15/arch/i386/oprofile/op_model_p4.c linux-2.6.23.15-grsec/arch/i386/oprofile/op_model_p4.c
7851 +--- linux-2.6.23.15/arch/i386/oprofile/op_model_p4.c 2007-10-09 21:31:38.000000000 +0100
7852 ++++ linux-2.6.23.15-grsec/arch/i386/oprofile/op_model_p4.c 2008-02-11 10:37:44.000000000 +0000
7853 +@@ -47,7 +47,7 @@ static inline void setup_num_counters(vo
7854 + #endif
7855 + }
7856 +
7857 +-static int inline addr_increment(void)
7858 ++static inline int addr_increment(void)
7859 + {
7860 + #ifdef CONFIG_SMP
7861 + return smp_num_siblings == 2 ? 2 : 1;
7862 +diff -Nurp linux-2.6.23.15/arch/i386/pci/common.c linux-2.6.23.15-grsec/arch/i386/pci/common.c
7863 +--- linux-2.6.23.15/arch/i386/pci/common.c 2007-10-09 21:31:38.000000000 +0100
7864 ++++ linux-2.6.23.15-grsec/arch/i386/pci/common.c 2008-02-11 10:37:44.000000000 +0000
7865 +@@ -287,7 +287,7 @@ static struct dmi_system_id __devinitdat
7866 + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL685c G1"),
7867 + },
7868 + },
7869 +- {}
7870 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
7871 + };
7872 +
7873 + struct pci_bus * __devinit pcibios_scan_root(int busnum)
7874 +diff -Nurp linux-2.6.23.15/arch/i386/pci/early.c linux-2.6.23.15-grsec/arch/i386/pci/early.c
7875 +--- linux-2.6.23.15/arch/i386/pci/early.c 2007-10-09 21:31:38.000000000 +0100
7876 ++++ linux-2.6.23.15-grsec/arch/i386/pci/early.c 2008-02-11 10:37:44.000000000 +0000
7877 +@@ -7,7 +7,7 @@
7878 + /* Direct PCI access. This is used for PCI accesses in early boot before
7879 + the PCI subsystem works. */
7880 +
7881 +-#define PDprintk(x...)
7882 ++#define PDprintk(x...) do {} while (0)
7883 +
7884 + u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
7885 + {
7886 +diff -Nurp linux-2.6.23.15/arch/i386/pci/fixup.c linux-2.6.23.15-grsec/arch/i386/pci/fixup.c
7887 +--- linux-2.6.23.15/arch/i386/pci/fixup.c 2007-10-09 21:31:38.000000000 +0100
7888 ++++ linux-2.6.23.15-grsec/arch/i386/pci/fixup.c 2008-02-11 10:37:44.000000000 +0000
7889 +@@ -386,7 +386,7 @@ static struct dmi_system_id __devinitdat
7890 + DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
7891 + },
7892 + },
7893 +- { }
7894 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
7895 + };
7896 +
7897 + static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
7898 +diff -Nurp linux-2.6.23.15/arch/i386/pci/irq.c linux-2.6.23.15-grsec/arch/i386/pci/irq.c
7899 +--- linux-2.6.23.15/arch/i386/pci/irq.c 2007-10-09 21:31:38.000000000 +0100
7900 ++++ linux-2.6.23.15-grsec/arch/i386/pci/irq.c 2008-02-11 10:37:44.000000000 +0000
7901 +@@ -508,7 +508,7 @@ static __init int intel_router_probe(str
7902 + static struct pci_device_id __initdata pirq_440gx[] = {
7903 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
7904 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
7905 +- { },
7906 ++ { PCI_DEVICE(0, 0) }
7907 + };
7908 +
7909 + /* 440GX has a proprietary PIRQ router -- don't use it */
7910 +@@ -1051,7 +1051,7 @@ static struct dmi_system_id __initdata p
7911 + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
7912 + },
7913 + },
7914 +- { }
7915 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
7916 + };
7917 +
7918 + static int __init pcibios_irq_init(void)
7919 +diff -Nurp linux-2.6.23.15/arch/i386/pci/pcbios.c linux-2.6.23.15-grsec/arch/i386/pci/pcbios.c
7920 +--- linux-2.6.23.15/arch/i386/pci/pcbios.c 2007-10-09 21:31:38.000000000 +0100
7921 ++++ linux-2.6.23.15-grsec/arch/i386/pci/pcbios.c 2008-02-11 10:37:44.000000000 +0000
7922 +@@ -57,50 +57,124 @@ union bios32 {
7923 + static struct {
7924 + unsigned long address;
7925 + unsigned short segment;
7926 +-} bios32_indirect = { 0, __KERNEL_CS };
7927 ++} bios32_indirect __read_only = { 0, __PCIBIOS_CS };
7928 +
7929 + /*
7930 + * Returns the entry point for the given service, NULL on error
7931 + */
7932 +
7933 +-static unsigned long bios32_service(unsigned long service)
7934 ++static unsigned long __devinit bios32_service(unsigned long service)
7935 + {
7936 + unsigned char return_code; /* %al */
7937 + unsigned long address; /* %ebx */
7938 + unsigned long length; /* %ecx */
7939 + unsigned long entry; /* %edx */
7940 + unsigned long flags;
7941 ++ struct desc_struct *gdt;
7942 ++
7943 ++#ifdef CONFIG_PAX_KERNEXEC
7944 ++ unsigned long cr0;
7945 ++#endif
7946 +
7947 + local_irq_save(flags);
7948 +- __asm__("lcall *(%%edi); cld"
7949 ++
7950 ++ gdt = get_cpu_gdt_table(smp_processor_id());
7951 ++
7952 ++#ifdef CONFIG_PAX_KERNEXEC
7953 ++ pax_open_kernel(cr0);
7954 ++#endif
7955 ++
7956 ++ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].a,
7957 ++ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].b,
7958 ++ 0UL, 0xFFFFFUL, 0x9B, 0xC);
7959 ++ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].a,
7960 ++ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].b,
7961 ++ 0UL, 0xFFFFFUL, 0x93, 0xC);
7962 ++
7963 ++#ifdef CONFIG_PAX_KERNEXEC
7964 ++ pax_close_kernel(cr0);
7965 ++#endif
7966 ++
7967 ++ __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld"
7968 + : "=a" (return_code),
7969 + "=b" (address),
7970 + "=c" (length),
7971 + "=d" (entry)
7972 + : "0" (service),
7973 + "1" (0),
7974 +- "D" (&bios32_indirect));
7975 ++ "D" (&bios32_indirect),
7976 ++ "r"(__PCIBIOS_DS)
7977 ++ : "memory");
7978 ++
7979 ++#ifdef CONFIG_PAX_KERNEXEC
7980 ++ pax_open_kernel(cr0);
7981 ++#endif
7982 ++
7983 ++ gdt[GDT_ENTRY_PCIBIOS_CS].a = 0;
7984 ++ gdt[GDT_ENTRY_PCIBIOS_CS].b = 0;
7985 ++ gdt[GDT_ENTRY_PCIBIOS_DS].a = 0;
7986 ++ gdt[GDT_ENTRY_PCIBIOS_DS].b = 0;
7987 ++
7988 ++#ifdef CONFIG_PAX_KERNEXEC
7989 ++ pax_close_kernel(cr0);
7990 ++#endif
7991 ++
7992 + local_irq_restore(flags);
7993 +
7994 + switch (return_code) {
7995 +- case 0:
7996 +- return address + entry;
7997 +- case 0x80: /* Not present */
7998 +- printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
7999 +- return 0;
8000 +- default: /* Shouldn't happen */
8001 +- printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
8002 +- service, return_code);
8003 ++ case 0: {
8004 ++ int cpu;
8005 ++ unsigned char flags;
8006 ++
8007 ++ printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry);
8008 ++ if (address >= 0xFFFF0 || length >= 0xFFFF0 - address || length <= entry) {
8009 ++ printk(KERN_WARNING "bios32_service: not valid\n");
8010 + return 0;
8011 ++ }
8012 ++ address = address + PAGE_OFFSET;
8013 ++ length += 16UL; /* some BIOSs underreport this... */
8014 ++ flags = 4;
8015 ++ if (length >= 64*1024*1024) {
8016 ++ length >>= PAGE_SHIFT;
8017 ++ flags |= 8;
8018 ++ }
8019 ++
8020 ++#ifdef CONFIG_PAX_KERNEXEC
8021 ++ pax_open_kernel(cr0);
8022 ++#endif
8023 ++
8024 ++ for (cpu = 0; cpu < NR_CPUS; cpu++) {
8025 ++ gdt = get_cpu_gdt_table(cpu);
8026 ++ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].a,
8027 ++ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].b,
8028 ++ address, length, 0x9b, flags);
8029 ++ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].a,
8030 ++ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].b,
8031 ++ address, length, 0x93, flags);
8032 ++ }
8033 ++
8034 ++#ifdef CONFIG_PAX_KERNEXEC
8035 ++ pax_close_kernel(cr0);
8036 ++#endif
8037 ++
8038 ++ return entry;
8039 ++ }
8040 ++ case 0x80: /* Not present */
8041 ++ printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
8042 ++ return 0;
8043 ++ default: /* Shouldn't happen */
8044 ++ printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
8045 ++ service, return_code);
8046 ++ return 0;
8047 + }
8048 + }
8049 +
8050 + static struct {
8051 + unsigned long address;
8052 + unsigned short segment;
8053 +-} pci_indirect = { 0, __KERNEL_CS };
8054 ++} pci_indirect __read_only = { 0, __PCIBIOS_CS };
8055 +
8056 +-static int pci_bios_present;
8057 ++static int pci_bios_present __read_only;
8058 +
8059 + static int __devinit check_pcibios(void)
8060 + {
8061 +@@ -109,11 +183,13 @@ static int __devinit check_pcibios(void)
8062 + unsigned long flags, pcibios_entry;
8063 +
8064 + if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
8065 +- pci_indirect.address = pcibios_entry + PAGE_OFFSET;
8066 ++ pci_indirect.address = pcibios_entry;
8067 +
8068 + local_irq_save(flags);
8069 +- __asm__(
8070 +- "lcall *(%%edi); cld\n\t"
8071 ++ __asm__("movw %w6, %%ds\n\t"
8072 ++ "lcall *%%ss:(%%edi); cld\n\t"
8073 ++ "push %%ss\n\t"
8074 ++ "pop %%ds\n\t"
8075 + "jc 1f\n\t"
8076 + "xor %%ah, %%ah\n"
8077 + "1:"
8078 +@@ -122,7 +198,8 @@ static int __devinit check_pcibios(void)
8079 + "=b" (ebx),
8080 + "=c" (ecx)
8081 + : "1" (PCIBIOS_PCI_BIOS_PRESENT),
8082 +- "D" (&pci_indirect)
8083 ++ "D" (&pci_indirect),
8084 ++ "r" (__PCIBIOS_DS)
8085 + : "memory");
8086 + local_irq_restore(flags);
8087 +
8088 +@@ -158,7 +235,10 @@ static int __devinit pci_bios_find_devic
8089 + unsigned short bx;
8090 + unsigned short ret;
8091 +
8092 +- __asm__("lcall *(%%edi); cld\n\t"
8093 ++ __asm__("movw %w7, %%ds\n\t"
8094 ++ "lcall *%%ss:(%%edi); cld\n\t"
8095 ++ "push %%ss\n\t"
8096 ++ "pop %%ds\n\t"
8097 + "jc 1f\n\t"
8098 + "xor %%ah, %%ah\n"
8099 + "1:"
8100 +@@ -168,7 +248,8 @@ static int __devinit pci_bios_find_devic
8101 + "c" (device_id),
8102 + "d" (vendor),
8103 + "S" ((int) index),
8104 +- "D" (&pci_indirect));
8105 ++ "D" (&pci_indirect),
8106 ++ "r" (__PCIBIOS_DS));
8107 + *bus = (bx >> 8) & 0xff;
8108 + *device_fn = bx & 0xff;
8109 + return (int) (ret & 0xff00) >> 8;
8110 +@@ -188,7 +269,10 @@ static int pci_bios_read(unsigned int se
8111 +
8112 + switch (len) {
8113 + case 1:
8114 +- __asm__("lcall *(%%esi); cld\n\t"
8115 ++ __asm__("movw %w6, %%ds\n\t"
8116 ++ "lcall *%%ss:(%%esi); cld\n\t"
8117 ++ "push %%ss\n\t"
8118 ++ "pop %%ds\n\t"
8119 + "jc 1f\n\t"
8120 + "xor %%ah, %%ah\n"
8121 + "1:"
8122 +@@ -197,10 +281,14 @@ static int pci_bios_read(unsigned int se
8123 + : "1" (PCIBIOS_READ_CONFIG_BYTE),
8124 + "b" (bx),
8125 + "D" ((long)reg),
8126 +- "S" (&pci_indirect));
8127 ++ "S" (&pci_indirect),
8128 ++ "r" (__PCIBIOS_DS));
8129 + break;
8130 + case 2:
8131 +- __asm__("lcall *(%%esi); cld\n\t"
8132 ++ __asm__("movw %w6, %%ds\n\t"
8133 ++ "lcall *%%ss:(%%esi); cld\n\t"
8134 ++ "push %%ss\n\t"
8135 ++ "pop %%ds\n\t"
8136 + "jc 1f\n\t"
8137 + "xor %%ah, %%ah\n"
8138 + "1:"
8139 +@@ -209,10 +297,14 @@ static int pci_bios_read(unsigned int se
8140 + : "1" (PCIBIOS_READ_CONFIG_WORD),
8141 + "b" (bx),
8142 + "D" ((long)reg),
8143 +- "S" (&pci_indirect));
8144 ++ "S" (&pci_indirect),
8145 ++ "r" (__PCIBIOS_DS));
8146 + break;
8147 + case 4:
8148 +- __asm__("lcall *(%%esi); cld\n\t"
8149 ++ __asm__("movw %w6, %%ds\n\t"
8150 ++ "lcall *%%ss:(%%esi); cld\n\t"
8151 ++ "push %%ss\n\t"
8152 ++ "pop %%ds\n\t"
8153 + "jc 1f\n\t"
8154 + "xor %%ah, %%ah\n"
8155 + "1:"
8156 +@@ -221,7 +313,8 @@ static int pci_bios_read(unsigned int se
8157 + : "1" (PCIBIOS_READ_CONFIG_DWORD),
8158 + "b" (bx),
8159 + "D" ((long)reg),
8160 +- "S" (&pci_indirect));
8161 ++ "S" (&pci_indirect),
8162 ++ "r" (__PCIBIOS_DS));
8163 + break;
8164 + }
8165 +
8166 +@@ -244,7 +337,10 @@ static int pci_bios_write(unsigned int s
8167 +
8168 + switch (len) {
8169 + case 1:
8170 +- __asm__("lcall *(%%esi); cld\n\t"
8171 ++ __asm__("movw %w6, %%ds\n\t"
8172 ++ "lcall *%%ss:(%%esi); cld\n\t"
8173 ++ "push %%ss\n\t"
8174 ++ "pop %%ds\n\t"
8175 + "jc 1f\n\t"
8176 + "xor %%ah, %%ah\n"
8177 + "1:"
8178 +@@ -253,10 +349,14 @@ static int pci_bios_write(unsigned int s
8179 + "c" (value),
8180 + "b" (bx),
8181 + "D" ((long)reg),
8182 +- "S" (&pci_indirect));
8183 ++ "S" (&pci_indirect),
8184 ++ "r" (__PCIBIOS_DS));
8185 + break;
8186 + case 2:
8187 +- __asm__("lcall *(%%esi); cld\n\t"
8188 ++ __asm__("movw %w6, %%ds\n\t"
8189 ++ "lcall *%%ss:(%%esi); cld\n\t"
8190 ++ "push %%ss\n\t"
8191 ++ "pop %%ds\n\t"
8192 + "jc 1f\n\t"
8193 + "xor %%ah, %%ah\n"
8194 + "1:"
8195 +@@ -265,10 +365,14 @@ static int pci_bios_write(unsigned int s
8196 + "c" (value),
8197 + "b" (bx),
8198 + "D" ((long)reg),
8199 +- "S" (&pci_indirect));
8200 ++ "S" (&pci_indirect),
8201 ++ "r" (__PCIBIOS_DS));
8202 + break;
8203 + case 4:
8204 +- __asm__("lcall *(%%esi); cld\n\t"
8205 ++ __asm__("movw %w6, %%ds\n\t"
8206 ++ "lcall *%%ss:(%%esi); cld\n\t"
8207 ++ "push %%ss\n\t"
8208 ++ "pop %%ds\n\t"
8209 + "jc 1f\n\t"
8210 + "xor %%ah, %%ah\n"
8211 + "1:"
8212 +@@ -277,7 +381,8 @@ static int pci_bios_write(unsigned int s
8213 + "c" (value),
8214 + "b" (bx),
8215 + "D" ((long)reg),
8216 +- "S" (&pci_indirect));
8217 ++ "S" (&pci_indirect),
8218 ++ "r" (__PCIBIOS_DS));
8219 + break;
8220 + }
8221 +
8222 +@@ -430,10 +535,13 @@ struct irq_routing_table * pcibios_get_i
8223 +
8224 + DBG("PCI: Fetching IRQ routing table... ");
8225 + __asm__("push %%es\n\t"
8226 ++ "movw %w8, %%ds\n\t"
8227 + "push %%ds\n\t"
8228 + "pop %%es\n\t"
8229 +- "lcall *(%%esi); cld\n\t"
8230 ++ "lcall *%%ss:(%%esi); cld\n\t"
8231 + "pop %%es\n\t"
8232 ++ "push %%ss\n\t"
8233 ++ "pop %%ds\n"
8234 + "jc 1f\n\t"
8235 + "xor %%ah, %%ah\n"
8236 + "1:"
8237 +@@ -444,7 +552,8 @@ struct irq_routing_table * pcibios_get_i
8238 + "1" (0),
8239 + "D" ((long) &opt),
8240 + "S" (&pci_indirect),
8241 +- "m" (opt)
8242 ++ "m" (opt),
8243 ++ "r" (__PCIBIOS_DS)
8244 + : "memory");
8245 + DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map);
8246 + if (ret & 0xff00)
8247 +@@ -468,7 +577,10 @@ int pcibios_set_irq_routing(struct pci_d
8248 + {
8249 + int ret;
8250 +
8251 +- __asm__("lcall *(%%esi); cld\n\t"
8252 ++ __asm__("movw %w5, %%ds\n\t"
8253 ++ "lcall *%%ss:(%%esi); cld\n\t"
8254 ++ "push %%ss\n\t"
8255 ++ "pop %%ds\n"
8256 + "jc 1f\n\t"
8257 + "xor %%ah, %%ah\n"
8258 + "1:"
8259 +@@ -476,7 +588,8 @@ int pcibios_set_irq_routing(struct pci_d
8260 + : "0" (PCIBIOS_SET_PCI_HW_INT),
8261 + "b" ((dev->bus->number << 8) | dev->devfn),
8262 + "c" ((irq << 8) | (pin + 10)),
8263 +- "S" (&pci_indirect));
8264 ++ "S" (&pci_indirect),
8265 ++ "r" (__PCIBIOS_DS));
8266 + return !(ret & 0xff00);
8267 + }
8268 + EXPORT_SYMBOL(pcibios_set_irq_routing);
8269 +diff -Nurp linux-2.6.23.15/arch/i386/power/cpu.c linux-2.6.23.15-grsec/arch/i386/power/cpu.c
8270 +--- linux-2.6.23.15/arch/i386/power/cpu.c 2007-10-09 21:31:38.000000000 +0100
8271 ++++ linux-2.6.23.15-grsec/arch/i386/power/cpu.c 2008-02-11 10:37:44.000000000 +0000
8272 +@@ -64,7 +64,7 @@ static void do_fpu_end(void)
8273 + static void fix_processor_context(void)
8274 + {
8275 + int cpu = smp_processor_id();
8276 +- struct tss_struct * t = &per_cpu(init_tss, cpu);
8277 ++ struct tss_struct *t = init_tss + cpu;
8278 +
8279 + set_tss_desc(cpu,t); /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */
8280 +
8281 +diff -Nurp linux-2.6.23.15/arch/i386/xen/enlighten.c linux-2.6.23.15-grsec/arch/i386/xen/enlighten.c
8282 +--- linux-2.6.23.15/arch/i386/xen/enlighten.c 2008-02-11 10:36:03.000000000 +0000
8283 ++++ linux-2.6.23.15-grsec/arch/i386/xen/enlighten.c 2008-02-11 10:37:44.000000000 +0000
8284 +@@ -320,7 +320,7 @@ static void xen_set_ldt(const void *addr
8285 + static void xen_load_gdt(const struct Xgt_desc_struct *dtr)
8286 + {
8287 + unsigned long *frames;
8288 +- unsigned long va = dtr->address;
8289 ++ unsigned long va = (unsigned long)dtr->address;
8290 + unsigned int size = dtr->size + 1;
8291 + unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
8292 + int f;
8293 +@@ -335,7 +335,7 @@ static void xen_load_gdt(const struct Xg
8294 + mcs = xen_mc_entry(sizeof(*frames) * pages);
8295 + frames = mcs.args;
8296 +
8297 +- for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
8298 ++ for (f = 0; va < (unsigned long)dtr->address + size; va += PAGE_SIZE, f++) {
8299 + frames[f] = virt_to_mfn(va);
8300 + make_lowmem_page_readonly((void *)va);
8301 + }
8302 +@@ -429,7 +429,7 @@ static void xen_write_idt_entry(struct d
8303 +
8304 + preempt_disable();
8305 +
8306 +- start = __get_cpu_var(idt_desc).address;
8307 ++ start = (unsigned long)__get_cpu_var(idt_desc).address;
8308 + end = start + __get_cpu_var(idt_desc).size + 1;
8309 +
8310 + xen_mc_flush();
8311 +diff -Nurp linux-2.6.23.15/arch/i386/xen/smp.c linux-2.6.23.15-grsec/arch/i386/xen/smp.c
8312 +--- linux-2.6.23.15/arch/i386/xen/smp.c 2007-10-09 21:31:38.000000000 +0100
8313 ++++ linux-2.6.23.15-grsec/arch/i386/xen/smp.c 2008-02-11 10:37:44.000000000 +0000
8314 +@@ -144,7 +144,7 @@ void __init xen_smp_prepare_boot_cpu(voi
8315 +
8316 + /* We've switched to the "real" per-cpu gdt, so make sure the
8317 + old memory can be recycled */
8318 +- make_lowmem_page_readwrite(&per_cpu__gdt_page);
8319 ++ make_lowmem_page_readwrite(get_cpu_gdt_table(smp_processor_id()));
8320 +
8321 + for (cpu = 0; cpu < NR_CPUS; cpu++) {
8322 + cpus_clear(cpu_sibling_map[cpu]);
8323 +@@ -198,7 +198,7 @@ static __cpuinit int
8324 + cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
8325 + {
8326 + struct vcpu_guest_context *ctxt;
8327 +- struct gdt_page *gdt = &per_cpu(gdt_page, cpu);
8328 ++ struct desc_struct *gdt = get_cpu_gdt_table(cpu);
8329 +
8330 + if (cpu_test_and_set(cpu, cpu_initialized_map))
8331 + return 0;
8332 +@@ -222,11 +222,11 @@ cpu_initialize_context(unsigned int cpu,
8333 +
8334 + ctxt->ldt_ents = 0;
8335 +
8336 +- BUG_ON((unsigned long)gdt->gdt & ~PAGE_MASK);
8337 +- make_lowmem_page_readonly(gdt->gdt);
8338 ++ BUG_ON((unsigned long)gdt & ~PAGE_MASK);
8339 ++ make_lowmem_page_readonly(gdt);
8340 +
8341 +- ctxt->gdt_frames[0] = virt_to_mfn(gdt->gdt);
8342 +- ctxt->gdt_ents = ARRAY_SIZE(gdt->gdt);
8343 ++ ctxt->gdt_frames[0] = virt_to_mfn(gdt);
8344 ++ ctxt->gdt_ents = GDT_ENTRIES;
8345 +
8346 + ctxt->user_regs.cs = __KERNEL_CS;
8347 + ctxt->user_regs.esp = idle->thread.esp0 - sizeof(struct pt_regs);
8348 +diff -Nurp linux-2.6.23.15/arch/ia64/ia32/binfmt_elf32.c linux-2.6.23.15-grsec/arch/ia64/ia32/binfmt_elf32.c
8349 +--- linux-2.6.23.15/arch/ia64/ia32/binfmt_elf32.c 2007-10-09 21:31:38.000000000 +0100
8350 ++++ linux-2.6.23.15-grsec/arch/ia64/ia32/binfmt_elf32.c 2008-02-11 10:37:44.000000000 +0000
8351 +@@ -45,6 +45,13 @@ randomize_stack_top(unsigned long stack_
8352 +
8353 + #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
8354 +
8355 ++#ifdef CONFIG_PAX_ASLR
8356 ++#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
8357 ++
8358 ++#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
8359 ++#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
8360 ++#endif
8361 ++
8362 + /* Ugly but avoids duplication */
8363 + #include "../../../fs/binfmt_elf.c"
8364 +
8365 +diff -Nurp linux-2.6.23.15/arch/ia64/ia32/ia32priv.h linux-2.6.23.15-grsec/arch/ia64/ia32/ia32priv.h
8366 +--- linux-2.6.23.15/arch/ia64/ia32/ia32priv.h 2007-10-09 21:31:38.000000000 +0100
8367 ++++ linux-2.6.23.15-grsec/arch/ia64/ia32/ia32priv.h 2008-02-11 10:37:44.000000000 +0000
8368 +@@ -304,7 +304,14 @@ struct old_linux32_dirent {
8369 + #define ELF_DATA ELFDATA2LSB
8370 + #define ELF_ARCH EM_386
8371 +
8372 +-#define IA32_STACK_TOP IA32_PAGE_OFFSET
8373 ++#ifdef CONFIG_PAX_RANDUSTACK
8374 ++#define __IA32_DELTA_STACK (current->mm->delta_stack)
8375 ++#else
8376 ++#define __IA32_DELTA_STACK 0UL
8377 ++#endif
8378 ++
8379 ++#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
8380 ++
8381 + #define IA32_GATE_OFFSET IA32_PAGE_OFFSET
8382 + #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
8383 +
8384 +diff -Nurp linux-2.6.23.15/arch/ia64/kernel/module.c linux-2.6.23.15-grsec/arch/ia64/kernel/module.c
8385 +--- linux-2.6.23.15/arch/ia64/kernel/module.c 2007-10-09 21:31:38.000000000 +0100
8386 ++++ linux-2.6.23.15-grsec/arch/ia64/kernel/module.c 2008-02-11 10:37:44.000000000 +0000
8387 +@@ -321,7 +321,7 @@ module_alloc (unsigned long size)
8388 + void
8389 + module_free (struct module *mod, void *module_region)
8390 + {
8391 +- if (mod->arch.init_unw_table && module_region == mod->module_init) {
8392 ++ if (mod->arch.init_unw_table && module_region == mod->module_init_rx) {
8393 + unw_remove_unwind_table(mod->arch.init_unw_table);
8394 + mod->arch.init_unw_table = NULL;
8395 + }
8396 +@@ -499,15 +499,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
8397 + }
8398 +
8399 + static inline int
8400 ++in_init_rx (const struct module *mod, uint64_t addr)
8401 ++{
8402 ++ return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
8403 ++}
8404 ++
8405 ++static inline int
8406 ++in_init_rw (const struct module *mod, uint64_t addr)
8407 ++{
8408 ++ return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
8409 ++}
8410 ++
8411 ++static inline int
8412 + in_init (const struct module *mod, uint64_t addr)
8413 + {
8414 +- return addr - (uint64_t) mod->module_init < mod->init_size;
8415 ++ return in_init_rx(mod, value) || in_init_rw(mod, value);
8416 ++}
8417 ++
8418 ++static inline int
8419 ++in_core_rx (const struct module *mod, uint64_t addr)
8420 ++{
8421 ++ return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
8422 ++}
8423 ++
8424 ++static inline int
8425 ++in_core_rw (const struct module *mod, uint64_t addr)
8426 ++{
8427 ++ return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
8428 + }
8429 +
8430 + static inline int
8431 + in_core (const struct module *mod, uint64_t addr)
8432 + {
8433 +- return addr - (uint64_t) mod->module_core < mod->core_size;
8434 ++ return in_core_rx(mod, value) || in_core_rw(mod, value);
8435 + }
8436 +
8437 + static inline int
8438 +@@ -691,7 +715,14 @@ do_reloc (struct module *mod, uint8_t r_
8439 + break;
8440 +
8441 + case RV_BDREL:
8442 +- val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
8443 ++ if (in_init_rx(mod, val))
8444 ++ val -= (uint64_t) mod->module_init_rx;
8445 ++ else if (in_init_rw(mod, val))
8446 ++ val -= (uint64_t) mod->module_init_rw;
8447 ++ else if (in_core_rx(mod, val))
8448 ++ val -= (uint64_t) mod->module_core_rx;
8449 ++ else if (in_core_rw(mod, val))
8450 ++ val -= (uint64_t) mod->module_core_rw;
8451 + break;
8452 +
8453 + case RV_LTV:
8454 +@@ -825,15 +856,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
8455 + * addresses have been selected...
8456 + */
8457 + uint64_t gp;
8458 +- if (mod->core_size > MAX_LTOFF)
8459 ++ if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
8460 + /*
8461 + * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
8462 + * at the end of the module.
8463 + */
8464 +- gp = mod->core_size - MAX_LTOFF / 2;
8465 ++ gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
8466 + else
8467 +- gp = mod->core_size / 2;
8468 +- gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
8469 ++ gp = (mod->core_size_rx + mod->core_size_rw) / 2;
8470 ++ gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
8471 + mod->arch.gp = gp;
8472 + DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp);
8473 + }
8474 +diff -Nurp linux-2.6.23.15/arch/ia64/kernel/ptrace.c linux-2.6.23.15-grsec/arch/ia64/kernel/ptrace.c
8475 +--- linux-2.6.23.15/arch/ia64/kernel/ptrace.c 2007-10-09 21:31:38.000000000 +0100
8476 ++++ linux-2.6.23.15-grsec/arch/ia64/kernel/ptrace.c 2008-02-11 10:37:44.000000000 +0000
8477 +@@ -17,6 +17,7 @@
8478 + #include <linux/security.h>
8479 + #include <linux/audit.h>
8480 + #include <linux/signal.h>
8481 ++#include <linux/grsecurity.h>
8482 +
8483 + #include <asm/pgtable.h>
8484 + #include <asm/processor.h>
8485 +@@ -1451,6 +1452,9 @@ sys_ptrace (long request, pid_t pid, uns
8486 + if (pid == 1) /* no messing around with init! */
8487 + goto out_tsk;
8488 +
8489 ++ if (gr_handle_ptrace(child, request))
8490 ++ goto out_tsk;
8491 ++
8492 + if (request == PTRACE_ATTACH) {
8493 + ret = ptrace_attach(child);
8494 + goto out_tsk;
8495 +diff -Nurp linux-2.6.23.15/arch/ia64/kernel/sys_ia64.c linux-2.6.23.15-grsec/arch/ia64/kernel/sys_ia64.c
8496 +--- linux-2.6.23.15/arch/ia64/kernel/sys_ia64.c 2007-10-09 21:31:38.000000000 +0100
8497 ++++ linux-2.6.23.15-grsec/arch/ia64/kernel/sys_ia64.c 2008-02-11 10:37:44.000000000 +0000
8498 +@@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
8499 + if (REGION_NUMBER(addr) == RGN_HPAGE)
8500 + addr = 0;
8501 + #endif
8502 ++
8503 ++#ifdef CONFIG_PAX_RANDMMAP
8504 ++ if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
8505 ++ addr = mm->free_area_cache;
8506 ++ else
8507 ++#endif
8508 ++
8509 + if (!addr)
8510 + addr = mm->free_area_cache;
8511 +
8512 +@@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil
8513 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
8514 + /* At this point: (!vma || addr < vma->vm_end). */
8515 + if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
8516 +- if (start_addr != TASK_UNMAPPED_BASE) {
8517 ++ if (start_addr != mm->mmap_base) {
8518 + /* Start a new search --- just in case we missed some holes. */
8519 +- addr = TASK_UNMAPPED_BASE;
8520 ++ addr = mm->mmap_base;
8521 + goto full_search;
8522 + }
8523 + return -ENOMEM;
8524 +diff -Nurp linux-2.6.23.15/arch/ia64/mm/fault.c linux-2.6.23.15-grsec/arch/ia64/mm/fault.c
8525 +--- linux-2.6.23.15/arch/ia64/mm/fault.c 2007-10-09 21:31:38.000000000 +0100
8526 ++++ linux-2.6.23.15-grsec/arch/ia64/mm/fault.c 2008-02-11 10:37:44.000000000 +0000
8527 +@@ -10,6 +10,7 @@
8528 + #include <linux/interrupt.h>
8529 + #include <linux/kprobes.h>
8530 + #include <linux/kdebug.h>
8531 ++#include <linux/binfmts.h>
8532 +
8533 + #include <asm/pgtable.h>
8534 + #include <asm/processor.h>
8535 +@@ -72,6 +73,23 @@ mapped_kernel_page_is_present (unsigned
8536 + return pte_present(pte);
8537 + }
8538 +
8539 ++#ifdef CONFIG_PAX_PAGEEXEC
8540 ++void pax_report_insns(void *pc, void *sp)
8541 ++{
8542 ++ unsigned long i;
8543 ++
8544 ++ printk(KERN_ERR "PAX: bytes at PC: ");
8545 ++ for (i = 0; i < 8; i++) {
8546 ++ unsigned int c;
8547 ++ if (get_user(c, (unsigned int *)pc+i))
8548 ++ printk("???????? ");
8549 ++ else
8550 ++ printk("%08x ", c);
8551 ++ }
8552 ++ printk("\n");
8553 ++}
8554 ++#endif
8555 ++
8556 + void __kprobes
8557 + ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
8558 + {
8559 +@@ -145,9 +163,23 @@ ia64_do_page_fault (unsigned long addres
8560 + mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
8561 + | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
8562 +
8563 +- if ((vma->vm_flags & mask) != mask)
8564 ++ if ((vma->vm_flags & mask) != mask) {
8565 ++
8566 ++#ifdef CONFIG_PAX_PAGEEXEC
8567 ++ if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
8568 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
8569 ++ goto bad_area;
8570 ++
8571 ++ up_read(&mm->mmap_sem);
8572 ++ pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
8573 ++ do_exit(SIGKILL);
8574 ++ }
8575 ++#endif
8576 ++
8577 + goto bad_area;
8578 +
8579 ++ }
8580 ++
8581 + survive:
8582 + /*
8583 + * If for any reason at all we couldn't handle the fault, make
8584 +diff -Nurp linux-2.6.23.15/arch/ia64/mm/init.c linux-2.6.23.15-grsec/arch/ia64/mm/init.c
8585 +--- linux-2.6.23.15/arch/ia64/mm/init.c 2007-10-09 21:31:38.000000000 +0100
8586 ++++ linux-2.6.23.15-grsec/arch/ia64/mm/init.c 2008-02-11 10:37:44.000000000 +0000
8587 +@@ -20,8 +20,8 @@
8588 + #include <linux/proc_fs.h>
8589 + #include <linux/bitops.h>
8590 + #include <linux/kexec.h>
8591 ++#include <linux/a.out.h>
8592 +
8593 +-#include <asm/a.out.h>
8594 + #include <asm/dma.h>
8595 + #include <asm/ia32.h>
8596 + #include <asm/io.h>
8597 +@@ -130,8 +130,21 @@ ia64_init_addr_space (void)
8598 + vma->vm_mm = current->mm;
8599 + vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
8600 + vma->vm_end = vma->vm_start + PAGE_SIZE;
8601 +- vma->vm_page_prot = protection_map[VM_DATA_DEFAULT_FLAGS & 0x7];
8602 + vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
8603 ++
8604 ++#ifdef CONFIG_PAX_PAGEEXEC
8605 ++ if (current->mm->pax_flags & MF_PAX_PAGEEXEC) {
8606 ++ vm->vm_flags &= ~VM_EXEC;
8607 ++
8608 ++#ifdef CONFIG_PAX_MPROTECT
8609 ++ if (current->mm->pax_flags & MF_PAX_MPROTECT)
8610 ++ vma->vm_flags &= ~VM_MAYEXEC;
8611 ++#endif
8612 ++
8613 ++ }
8614 ++#endif
8615 ++
8616 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
8617 + down_write(&current->mm->mmap_sem);
8618 + if (insert_vm_struct(current->mm, vma)) {
8619 + up_write(&current->mm->mmap_sem);
8620 +diff -Nurp linux-2.6.23.15/arch/mips/kernel/binfmt_elfn32.c linux-2.6.23.15-grsec/arch/mips/kernel/binfmt_elfn32.c
8621 +--- linux-2.6.23.15/arch/mips/kernel/binfmt_elfn32.c 2007-10-09 21:31:38.000000000 +0100
8622 ++++ linux-2.6.23.15-grsec/arch/mips/kernel/binfmt_elfn32.c 2008-02-11 10:37:44.000000000 +0000
8623 +@@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
8624 + #undef ELF_ET_DYN_BASE
8625 + #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
8626 +
8627 ++#ifdef CONFIG_PAX_ASLR
8628 ++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
8629 ++
8630 ++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
8631 ++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
8632 ++#endif
8633 ++
8634 + #include <asm/processor.h>
8635 + #include <linux/module.h>
8636 + #include <linux/elfcore.h>
8637 +diff -Nurp linux-2.6.23.15/arch/mips/kernel/binfmt_elfo32.c linux-2.6.23.15-grsec/arch/mips/kernel/binfmt_elfo32.c
8638 +--- linux-2.6.23.15/arch/mips/kernel/binfmt_elfo32.c 2007-10-09 21:31:38.000000000 +0100
8639 ++++ linux-2.6.23.15-grsec/arch/mips/kernel/binfmt_elfo32.c 2008-02-11 10:37:44.000000000 +0000
8640 +@@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
8641 + #undef ELF_ET_DYN_BASE
8642 + #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
8643 +
8644 ++#ifdef CONFIG_PAX_ASLR
8645 ++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
8646 ++
8647 ++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
8648 ++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
8649 ++#endif
8650 ++
8651 + #include <asm/processor.h>
8652 + #include <linux/module.h>
8653 + #include <linux/elfcore.h>
8654 +diff -Nurp linux-2.6.23.15/arch/mips/kernel/syscall.c linux-2.6.23.15-grsec/arch/mips/kernel/syscall.c
8655 +--- linux-2.6.23.15/arch/mips/kernel/syscall.c 2007-10-09 21:31:38.000000000 +0100
8656 ++++ linux-2.6.23.15-grsec/arch/mips/kernel/syscall.c 2008-02-11 10:37:44.000000000 +0000
8657 +@@ -88,6 +88,11 @@ unsigned long arch_get_unmapped_area(str
8658 + do_color_align = 0;
8659 + if (filp || (flags & MAP_SHARED))
8660 + do_color_align = 1;
8661 ++
8662 ++#ifdef CONFIG_PAX_RANDMMAP
8663 ++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
8664 ++#endif
8665 ++
8666 + if (addr) {
8667 + if (do_color_align)
8668 + addr = COLOUR_ALIGN(addr, pgoff);
8669 +@@ -98,7 +103,7 @@ unsigned long arch_get_unmapped_area(str
8670 + (!vmm || addr + len <= vmm->vm_start))
8671 + return addr;
8672 + }
8673 +- addr = TASK_UNMAPPED_BASE;
8674 ++ addr = current->mm->mmap_base;
8675 + if (do_color_align)
8676 + addr = COLOUR_ALIGN(addr, pgoff);
8677 + else
8678 +diff -Nurp linux-2.6.23.15/arch/mips/mm/fault.c linux-2.6.23.15-grsec/arch/mips/mm/fault.c
8679 +--- linux-2.6.23.15/arch/mips/mm/fault.c 2007-10-09 21:31:38.000000000 +0100
8680 ++++ linux-2.6.23.15-grsec/arch/mips/mm/fault.c 2008-02-11 10:37:44.000000000 +0000
8681 +@@ -26,6 +26,23 @@
8682 + #include <asm/ptrace.h>
8683 + #include <asm/highmem.h> /* For VMALLOC_END */
8684 +
8685 ++#ifdef CONFIG_PAX_PAGEEXEC
8686 ++void pax_report_insns(void *pc)
8687 ++{
8688 ++ unsigned long i;
8689 ++
8690 ++ printk(KERN_ERR "PAX: bytes at PC: ");
8691 ++ for (i = 0; i < 5; i++) {
8692 ++ unsigned int c;
8693 ++ if (get_user(c, (unsigned int *)pc+i))
8694 ++ printk("???????? ");
8695 ++ else
8696 ++ printk("%08x ", c);
8697 ++ }
8698 ++ printk("\n");
8699 ++}
8700 ++#endif
8701 ++
8702 + /*
8703 + * This routine handles page faults. It determines the address,
8704 + * and the problem, and then passes it off to one of the appropriate
8705 +diff -Nurp linux-2.6.23.15/arch/parisc/kernel/module.c linux-2.6.23.15-grsec/arch/parisc/kernel/module.c
8706 +--- linux-2.6.23.15/arch/parisc/kernel/module.c 2007-10-09 21:31:38.000000000 +0100
8707 ++++ linux-2.6.23.15-grsec/arch/parisc/kernel/module.c 2008-02-11 10:37:44.000000000 +0000
8708 +@@ -73,16 +73,38 @@
8709 +
8710 + /* three functions to determine where in the module core
8711 + * or init pieces the location is */
8712 ++static inline int in_init_rx(struct module *me, void *loc)
8713 ++{
8714 ++ return (loc >= me->module_init_rx &&
8715 ++ loc < (me->module_init_rx + me->init_size_rx));
8716 ++}
8717 ++
8718 ++static inline int in_init_rw(struct module *me, void *loc)
8719 ++{
8720 ++ return (loc >= me->module_init_rw &&
8721 ++ loc < (me->module_init_rw + me->init_size_rw));
8722 ++}
8723 ++
8724 + static inline int in_init(struct module *me, void *loc)
8725 + {
8726 +- return (loc >= me->module_init &&
8727 +- loc <= (me->module_init + me->init_size));
8728 ++ return in_init_rx(me, loc) || in_init_rw(me, loc);
8729 ++}
8730 ++
8731 ++static inline int in_core_rx(struct module *me, void *loc)
8732 ++{
8733 ++ return (loc >= me->module_core_rx &&
8734 ++ loc < (me->module_core_rx + me->core_size_rx));
8735 ++}
8736 ++
8737 ++static inline int in_core_rw(struct module *me, void *loc)
8738 ++{
8739 ++ return (loc >= me->module_core_rw &&
8740 ++ loc < (me->module_core_rw + me->core_size_rw));
8741 + }
8742 +
8743 + static inline int in_core(struct module *me, void *loc)
8744 + {
8745 +- return (loc >= me->module_core &&
8746 +- loc <= (me->module_core + me->core_size));
8747 ++ return in_core_rx(me, loc) || in_core_rw(me, loc);
8748 + }
8749 +
8750 + static inline int in_local(struct module *me, void *loc)
8751 +@@ -296,21 +318,21 @@ int module_frob_arch_sections(CONST Elf_
8752 + }
8753 +
8754 + /* align things a bit */
8755 +- me->core_size = ALIGN(me->core_size, 16);
8756 +- me->arch.got_offset = me->core_size;
8757 +- me->core_size += gots * sizeof(struct got_entry);
8758 +-
8759 +- me->core_size = ALIGN(me->core_size, 16);
8760 +- me->arch.fdesc_offset = me->core_size;
8761 +- me->core_size += fdescs * sizeof(Elf_Fdesc);
8762 +-
8763 +- me->core_size = ALIGN(me->core_size, 16);
8764 +- me->arch.stub_offset = me->core_size;
8765 +- me->core_size += stubs * sizeof(struct stub_entry);
8766 +-
8767 +- me->init_size = ALIGN(me->init_size, 16);
8768 +- me->arch.init_stub_offset = me->init_size;
8769 +- me->init_size += init_stubs * sizeof(struct stub_entry);
8770 ++ me->core_size_rw = ALIGN(me->core_size_rw, 16);
8771 ++ me->arch.got_offset = me->core_size_rw;
8772 ++ me->core_size_rw += gots * sizeof(struct got_entry);
8773 ++
8774 ++ me->core_size_rw = ALIGN(me->core_size_rw, 16);
8775 ++ me->arch.fdesc_offset = me->core_size_rw;
8776 ++ me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
8777 ++
8778 ++ me->core_size_rx = ALIGN(me->core_size_rx, 16);
8779 ++ me->arch.stub_offset = me->core_size_rx;
8780 ++ me->core_size_rx += stubs * sizeof(struct stub_entry);
8781 ++
8782 ++ me->init_size_rx = ALIGN(me->init_size_rx, 16);
8783 ++ me->arch.init_stub_offset = me->init_size_rx;
8784 ++ me->init_size_rx += init_stubs * sizeof(struct stub_entry);
8785 +
8786 + me->arch.got_max = gots;
8787 + me->arch.fdesc_max = fdescs;
8788 +@@ -330,7 +352,7 @@ static Elf64_Word get_got(struct module
8789 +
8790 + BUG_ON(value == 0);
8791 +
8792 +- got = me->module_core + me->arch.got_offset;
8793 ++ got = me->module_core_rw + me->arch.got_offset;
8794 + for (i = 0; got[i].addr; i++)
8795 + if (got[i].addr == value)
8796 + goto out;
8797 +@@ -348,7 +370,7 @@ static Elf64_Word get_got(struct module
8798 + #ifdef CONFIG_64BIT
8799 + static Elf_Addr get_fdesc(struct module *me, unsigned long value)
8800 + {
8801 +- Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
8802 ++ Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
8803 +
8804 + if (!value) {
8805 + printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
8806 +@@ -366,7 +388,7 @@ static Elf_Addr get_fdesc(struct module
8807 +
8808 + /* Create new one */
8809 + fdesc->addr = value;
8810 +- fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
8811 ++ fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
8812 + return (Elf_Addr)fdesc;
8813 + }
8814 + #endif /* CONFIG_64BIT */
8815 +@@ -386,12 +408,12 @@ static Elf_Addr get_stub(struct module *
8816 + if(init_section) {
8817 + i = me->arch.init_stub_count++;
8818 + BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
8819 +- stub = me->module_init + me->arch.init_stub_offset +
8820 ++ stub = me->module_init_rx + me->arch.init_stub_offset +
8821 + i * sizeof(struct stub_entry);
8822 + } else {
8823 + i = me->arch.stub_count++;
8824 + BUG_ON(me->arch.stub_count > me->arch.stub_max);
8825 +- stub = me->module_core + me->arch.stub_offset +
8826 ++ stub = me->module_core_rx + me->arch.stub_offset +
8827 + i * sizeof(struct stub_entry);
8828 + }
8829 +
8830 +@@ -759,7 +781,7 @@ register_unwind_table(struct module *me,
8831 +
8832 + table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
8833 + end = table + sechdrs[me->arch.unwind_section].sh_size;
8834 +- gp = (Elf_Addr)me->module_core + me->arch.got_offset;
8835 ++ gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
8836 +
8837 + DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
8838 + me->arch.unwind_section, table, end, gp);
8839 +diff -Nurp linux-2.6.23.15/arch/parisc/kernel/sys_parisc.c linux-2.6.23.15-grsec/arch/parisc/kernel/sys_parisc.c
8840 +--- linux-2.6.23.15/arch/parisc/kernel/sys_parisc.c 2007-10-09 21:31:38.000000000 +0100
8841 ++++ linux-2.6.23.15-grsec/arch/parisc/kernel/sys_parisc.c 2008-02-11 10:37:44.000000000 +0000
8842 +@@ -111,7 +111,7 @@ unsigned long arch_get_unmapped_area(str
8843 + if (flags & MAP_FIXED)
8844 + return addr;
8845 + if (!addr)
8846 +- addr = TASK_UNMAPPED_BASE;
8847 ++ addr = current->mm->mmap_base;
8848 +
8849 + if (filp) {
8850 + addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
8851 +diff -Nurp linux-2.6.23.15/arch/parisc/kernel/traps.c linux-2.6.23.15-grsec/arch/parisc/kernel/traps.c
8852 +--- linux-2.6.23.15/arch/parisc/kernel/traps.c 2007-10-09 21:31:38.000000000 +0100
8853 ++++ linux-2.6.23.15-grsec/arch/parisc/kernel/traps.c 2008-02-11 10:37:44.000000000 +0000
8854 +@@ -713,9 +713,7 @@ void handle_interruption(int code, struc
8855 +
8856 + down_read(&current->mm->mmap_sem);
8857 + vma = find_vma(current->mm,regs->iaoq[0]);
8858 +- if (vma && (regs->iaoq[0] >= vma->vm_start)
8859 +- && (vma->vm_flags & VM_EXEC)) {
8860 +-
8861 ++ if (vma && (regs->iaoq[0] >= vma->vm_start)) {
8862 + fault_address = regs->iaoq[0];
8863 + fault_space = regs->iasq[0];
8864 +
8865 +diff -Nurp linux-2.6.23.15/arch/parisc/mm/fault.c linux-2.6.23.15-grsec/arch/parisc/mm/fault.c
8866 +--- linux-2.6.23.15/arch/parisc/mm/fault.c 2007-10-09 21:31:38.000000000 +0100
8867 ++++ linux-2.6.23.15-grsec/arch/parisc/mm/fault.c 2008-02-11 10:37:44.000000000 +0000
8868 +@@ -16,6 +16,8 @@
8869 + #include <linux/sched.h>
8870 + #include <linux/interrupt.h>
8871 + #include <linux/module.h>
8872 ++#include <linux/unistd.h>
8873 ++#include <linux/binfmts.h>
8874 +
8875 + #include <asm/uaccess.h>
8876 + #include <asm/traps.h>
8877 +@@ -53,7 +55,7 @@ DEFINE_PER_CPU(struct exception_data, ex
8878 + static unsigned long
8879 + parisc_acctyp(unsigned long code, unsigned int inst)
8880 + {
8881 +- if (code == 6 || code == 16)
8882 ++ if (code == 6 || code == 7 || code == 16)
8883 + return VM_EXEC;
8884 +
8885 + switch (inst & 0xf0000000) {
8886 +@@ -139,6 +141,116 @@ parisc_acctyp(unsigned long code, unsign
8887 + }
8888 + #endif
8889 +
8890 ++#ifdef CONFIG_PAX_PAGEEXEC
8891 ++/*
8892 ++ * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
8893 ++ *
8894 ++ * returns 1 when task should be killed
8895 ++ * 2 when rt_sigreturn trampoline was detected
8896 ++ * 3 when unpatched PLT trampoline was detected
8897 ++ */
8898 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
8899 ++{
8900 ++
8901 ++#ifdef CONFIG_PAX_EMUPLT
8902 ++ int err;
8903 ++
8904 ++ do { /* PaX: unpatched PLT emulation */
8905 ++ unsigned int bl, depwi;
8906 ++
8907 ++ err = get_user(bl, (unsigned int *)instruction_pointer(regs));
8908 ++ err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
8909 ++
8910 ++ if (err)
8911 ++ break;
8912 ++
8913 ++ if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
8914 ++ unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
8915 ++
8916 ++ err = get_user(ldw, (unsigned int *)addr);
8917 ++ err |= get_user(bv, (unsigned int *)(addr+4));
8918 ++ err |= get_user(ldw2, (unsigned int *)(addr+8));
8919 ++
8920 ++ if (err)
8921 ++ break;
8922 ++
8923 ++ if (ldw == 0x0E801096U &&
8924 ++ bv == 0xEAC0C000U &&
8925 ++ ldw2 == 0x0E881095U)
8926 ++ {
8927 ++ unsigned int resolver, map;
8928 ++
8929 ++ err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
8930 ++ err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
8931 ++ if (err)
8932 ++ break;
8933 ++
8934 ++ regs->gr[20] = instruction_pointer(regs)+8;
8935 ++ regs->gr[21] = map;
8936 ++ regs->gr[22] = resolver;
8937 ++ regs->iaoq[0] = resolver | 3UL;
8938 ++ regs->iaoq[1] = regs->iaoq[0] + 4;
8939 ++ return 3;
8940 ++ }
8941 ++ }
8942 ++ } while (0);
8943 ++#endif
8944 ++
8945 ++#ifdef CONFIG_PAX_EMUTRAMP
8946 ++
8947 ++#ifndef CONFIG_PAX_EMUSIGRT
8948 ++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
8949 ++ return 1;
8950 ++#endif
8951 ++
8952 ++ do { /* PaX: rt_sigreturn emulation */
8953 ++ unsigned int ldi1, ldi2, bel, nop;
8954 ++
8955 ++ err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
8956 ++ err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
8957 ++ err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
8958 ++ err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
8959 ++
8960 ++ if (err)
8961 ++ break;
8962 ++
8963 ++ if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
8964 ++ ldi2 == 0x3414015AU &&
8965 ++ bel == 0xE4008200U &&
8966 ++ nop == 0x08000240U)
8967 ++ {
8968 ++ regs->gr[25] = (ldi1 & 2) >> 1;
8969 ++ regs->gr[20] = __NR_rt_sigreturn;
8970 ++ regs->gr[31] = regs->iaoq[1] + 16;
8971 ++ regs->sr[0] = regs->iasq[1];
8972 ++ regs->iaoq[0] = 0x100UL;
8973 ++ regs->iaoq[1] = regs->iaoq[0] + 4;
8974 ++ regs->iasq[0] = regs->sr[2];
8975 ++ regs->iasq[1] = regs->sr[2];
8976 ++ return 2;
8977 ++ }
8978 ++ } while (0);
8979 ++#endif
8980 ++
8981 ++ return 1;
8982 ++}
8983 ++
8984 ++void pax_report_insns(void *pc, void *sp)
8985 ++{
8986 ++ unsigned long i;
8987 ++
8988 ++ printk(KERN_ERR "PAX: bytes at PC: ");
8989 ++ for (i = 0; i < 5; i++) {
8990 ++ unsigned int c;
8991 ++ if (get_user(c, (unsigned int *)pc+i))
8992 ++ printk("???????? ");
8993 ++ else
8994 ++ printk("%08x ", c);
8995 ++ }
8996 ++ printk("\n");
8997 ++}
8998 ++#endif
8999 ++
9000 + void do_page_fault(struct pt_regs *regs, unsigned long code,
9001 + unsigned long address)
9002 + {
9003 +@@ -165,8 +277,33 @@ good_area:
9004 +
9005 + acc_type = parisc_acctyp(code,regs->iir);
9006 +
9007 +- if ((vma->vm_flags & acc_type) != acc_type)
9008 ++ if ((vma->vm_flags & acc_type) != acc_type) {
9009 ++
9010 ++#ifdef CONFIG_PAX_PAGEEXEC
9011 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
9012 ++ (address & ~3UL) == instruction_pointer(regs))
9013 ++ {
9014 ++ up_read(&mm->mmap_sem);
9015 ++ switch (pax_handle_fetch_fault(regs)) {
9016 ++
9017 ++#ifdef CONFIG_PAX_EMUPLT
9018 ++ case 3:
9019 ++ return;
9020 ++#endif
9021 ++
9022 ++#ifdef CONFIG_PAX_EMUTRAMP
9023 ++ case 2:
9024 ++ return;
9025 ++#endif
9026 ++
9027 ++ }
9028 ++ pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
9029 ++ do_exit(SIGKILL);
9030 ++ }
9031 ++#endif
9032 ++
9033 + goto bad_area;
9034 ++ }
9035 +
9036 + /*
9037 + * If for any reason at all we couldn't handle the fault, make
9038 +diff -Nurp linux-2.6.23.15/arch/powerpc/kernel/module_32.c linux-2.6.23.15-grsec/arch/powerpc/kernel/module_32.c
9039 +--- linux-2.6.23.15/arch/powerpc/kernel/module_32.c 2007-10-09 21:31:38.000000000 +0100
9040 ++++ linux-2.6.23.15-grsec/arch/powerpc/kernel/module_32.c 2008-02-11 10:37:44.000000000 +0000
9041 +@@ -126,7 +126,7 @@ int module_frob_arch_sections(Elf32_Ehdr
9042 + me->arch.core_plt_section = i;
9043 + }
9044 + if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
9045 +- printk("Module doesn't contain .plt or .init.plt sections.\n");
9046 ++ printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
9047 + return -ENOEXEC;
9048 + }
9049 +
9050 +@@ -167,11 +167,16 @@ static uint32_t do_plt_call(void *locati
9051 +
9052 + DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
9053 + /* Init, or core PLT? */
9054 +- if (location >= mod->module_core
9055 +- && location < mod->module_core + mod->core_size)
9056 ++ if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
9057 ++ (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
9058 + entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
9059 +- else
9060 ++ else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
9061 ++ (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
9062 + entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
9063 ++ else {
9064 ++ printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
9065 ++ return ~0UL;
9066 ++ }
9067 +
9068 + /* Find this entry, or if that fails, the next avail. entry */
9069 + while (entry->jump[0]) {
9070 +diff -Nurp linux-2.6.23.15/arch/powerpc/kernel/signal_32.c linux-2.6.23.15-grsec/arch/powerpc/kernel/signal_32.c
9071 +--- linux-2.6.23.15/arch/powerpc/kernel/signal_32.c 2007-10-09 21:31:38.000000000 +0100
9072 ++++ linux-2.6.23.15-grsec/arch/powerpc/kernel/signal_32.c 2008-02-11 10:37:44.000000000 +0000
9073 +@@ -728,7 +728,7 @@ int handle_rt_signal32(unsigned long sig
9074 +
9075 + /* Save user registers on the stack */
9076 + frame = &rt_sf->uc.uc_mcontext;
9077 +- if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
9078 ++ if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
9079 + if (save_user_regs(regs, frame, 0))
9080 + goto badframe;
9081 + regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
9082 +diff -Nurp linux-2.6.23.15/arch/powerpc/kernel/signal_64.c linux-2.6.23.15-grsec/arch/powerpc/kernel/signal_64.c
9083 +--- linux-2.6.23.15/arch/powerpc/kernel/signal_64.c 2007-10-09 21:31:38.000000000 +0100
9084 ++++ linux-2.6.23.15-grsec/arch/powerpc/kernel/signal_64.c 2008-02-11 10:37:44.000000000 +0000
9085 +@@ -359,7 +359,7 @@ int handle_rt_signal64(int signr, struct
9086 + current->thread.fpscr.val = 0;
9087 +
9088 + /* Set up to return from userspace. */
9089 +- if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
9090 ++ if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
9091 + regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
9092 + } else {
9093 + err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
9094 +diff -Nurp linux-2.6.23.15/arch/powerpc/kernel/vdso.c linux-2.6.23.15-grsec/arch/powerpc/kernel/vdso.c
9095 +--- linux-2.6.23.15/arch/powerpc/kernel/vdso.c 2007-10-09 21:31:38.000000000 +0100
9096 ++++ linux-2.6.23.15-grsec/arch/powerpc/kernel/vdso.c 2008-02-11 10:37:44.000000000 +0000
9097 +@@ -211,7 +211,7 @@ int arch_setup_additional_pages(struct l
9098 + vdso_base = VDSO32_MBASE;
9099 + #endif
9100 +
9101 +- current->mm->context.vdso_base = 0;
9102 ++ current->mm->context.vdso_base = ~0UL;
9103 +
9104 + /* vDSO has a problem and was disabled, just don't "enable" it for the
9105 + * process
9106 +@@ -228,7 +228,7 @@ int arch_setup_additional_pages(struct l
9107 + */
9108 + down_write(&mm->mmap_sem);
9109 + vdso_base = get_unmapped_area(NULL, vdso_base,
9110 +- vdso_pages << PAGE_SHIFT, 0, 0);
9111 ++ vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
9112 + if (IS_ERR_VALUE(vdso_base)) {
9113 + rc = vdso_base;
9114 + goto fail_mmapsem;
9115 +diff -Nurp linux-2.6.23.15/arch/powerpc/mm/fault.c linux-2.6.23.15-grsec/arch/powerpc/mm/fault.c
9116 +--- linux-2.6.23.15/arch/powerpc/mm/fault.c 2007-10-09 21:31:38.000000000 +0100
9117 ++++ linux-2.6.23.15-grsec/arch/powerpc/mm/fault.c 2008-02-11 10:37:44.000000000 +0000
9118 +@@ -29,6 +29,12 @@
9119 + #include <linux/module.h>
9120 + #include <linux/kprobes.h>
9121 + #include <linux/kdebug.h>
9122 ++#include <linux/binfmts.h>
9123 ++#include <linux/slab.h>
9124 ++#include <linux/pagemap.h>
9125 ++#include <linux/compiler.h>
9126 ++#include <linux/binfmts.h>
9127 ++#include <linux/unistd.h>
9128 +
9129 + #include <asm/page.h>
9130 + #include <asm/pgtable.h>
9131 +@@ -62,6 +68,364 @@ static inline int notify_page_fault(stru
9132 + }
9133 + #endif
9134 +
9135 ++#ifdef CONFIG_PAX_EMUSIGRT
9136 ++void pax_syscall_close(struct vm_area_struct *vma)
9137 ++{
9138 ++ vma->vm_mm->call_syscall = 0UL;
9139 ++}
9140 ++
9141 ++static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
9142 ++{
9143 ++ struct page *page;
9144 ++ unsigned int *kaddr;
9145 ++
9146 ++ page = alloc_page(GFP_HIGHUSER);
9147 ++ if (!page)
9148 ++ return NOPAGE_OOM;
9149 ++
9150 ++ kaddr = kmap(page);
9151 ++ memset(kaddr, 0, PAGE_SIZE);
9152 ++ kaddr[0] = 0x44000002U; /* sc */
9153 ++ __flush_dcache_icache(kaddr);
9154 ++ kunmap(page);
9155 ++ if (type)
9156 ++ *type = VM_FAULT_MAJOR;
9157 ++ return page;
9158 ++}
9159 ++
9160 ++static struct vm_operations_struct pax_vm_ops = {
9161 ++ .close = pax_syscall_close,
9162 ++ .nopage = pax_syscall_nopage,
9163 ++};
9164 ++
9165 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
9166 ++{
9167 ++ int ret;
9168 ++
9169 ++ memset(vma, 0, sizeof(*vma));
9170 ++ vma->vm_mm = current->mm;
9171 ++ vma->vm_start = addr;
9172 ++ vma->vm_end = addr + PAGE_SIZE;
9173 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
9174 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
9175 ++ vma->vm_ops = &pax_vm_ops;
9176 ++
9177 ++ ret = insert_vm_struct(current->mm, vma);
9178 ++ if (ret)
9179 ++ return ret;
9180 ++
9181 ++ ++current->mm->total_vm;
9182 ++ return 0;
9183 ++}
9184 ++#endif
9185 ++
9186 ++#ifdef CONFIG_PAX_PAGEEXEC
9187 ++/*
9188 ++ * PaX: decide what to do with offenders (regs->nip = fault address)
9189 ++ *
9190 ++ * returns 1 when task should be killed
9191 ++ * 2 when patched GOT trampoline was detected
9192 ++ * 3 when patched PLT trampoline was detected
9193 ++ * 4 when unpatched PLT trampoline was detected
9194 ++ * 5 when sigreturn trampoline was detected
9195 ++ * 6 when rt_sigreturn trampoline was detected
9196 ++ */
9197 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
9198 ++{
9199 ++
9200 ++#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
9201 ++ int err;
9202 ++#endif
9203 ++
9204 ++#ifdef CONFIG_PAX_EMUPLT
9205 ++ do { /* PaX: patched GOT emulation */
9206 ++ unsigned int blrl;
9207 ++
9208 ++ err = get_user(blrl, (unsigned int *)regs->nip);
9209 ++
9210 ++ if (!err && blrl == 0x4E800021U) {
9211 ++ unsigned long temp = regs->nip;
9212 ++
9213 ++ regs->nip = regs->link & 0xFFFFFFFCUL;
9214 ++ regs->link = temp + 4UL;
9215 ++ return 2;
9216 ++ }
9217 ++ } while (0);
9218 ++
9219 ++ do { /* PaX: patched PLT emulation #1 */
9220 ++ unsigned int b;
9221 ++
9222 ++ err = get_user(b, (unsigned int *)regs->nip);
9223 ++
9224 ++ if (!err && (b & 0xFC000003U) == 0x48000000U) {
9225 ++ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
9226 ++ return 3;
9227 ++ }
9228 ++ } while (0);
9229 ++
9230 ++ do { /* PaX: unpatched PLT emulation #1 */
9231 ++ unsigned int li, b;
9232 ++
9233 ++ err = get_user(li, (unsigned int *)regs->nip);
9234 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
9235 ++
9236 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
9237 ++ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
9238 ++ unsigned long addr = b | 0xFC000000UL;
9239 ++
9240 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
9241 ++ err = get_user(rlwinm, (unsigned int *)addr);
9242 ++ err |= get_user(add, (unsigned int *)(addr+4));
9243 ++ err |= get_user(li2, (unsigned int *)(addr+8));
9244 ++ err |= get_user(addis2, (unsigned int *)(addr+12));
9245 ++ err |= get_user(mtctr, (unsigned int *)(addr+16));
9246 ++ err |= get_user(li3, (unsigned int *)(addr+20));
9247 ++ err |= get_user(addis3, (unsigned int *)(addr+24));
9248 ++ err |= get_user(bctr, (unsigned int *)(addr+28));
9249 ++
9250 ++ if (err)
9251 ++ break;
9252 ++
9253 ++ if (rlwinm == 0x556C083CU &&
9254 ++ add == 0x7D6C5A14U &&
9255 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
9256 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
9257 ++ mtctr == 0x7D8903A6U &&
9258 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
9259 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
9260 ++ bctr == 0x4E800420U)
9261 ++ {
9262 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
9263 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
9264 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
9265 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
9266 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
9267 ++ regs->nip = regs->ctr;
9268 ++ return 4;
9269 ++ }
9270 ++ }
9271 ++ } while (0);
9272 ++
9273 ++#if 0
9274 ++ do { /* PaX: unpatched PLT emulation #2 */
9275 ++ unsigned int lis, lwzu, b, bctr;
9276 ++
9277 ++ err = get_user(lis, (unsigned int *)regs->nip);
9278 ++ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
9279 ++ err |= get_user(b, (unsigned int *)(regs->nip+8));
9280 ++ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
9281 ++
9282 ++ if (err)
9283 ++ break;
9284 ++
9285 ++ if ((lis & 0xFFFF0000U) == 0x39600000U &&
9286 ++ (lwzu & 0xU) == 0xU &&
9287 ++ (b & 0xFC000003U) == 0x48000000U &&
9288 ++ bctr == 0x4E800420U)
9289 ++ {
9290 ++ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
9291 ++ unsigned long addr = b | 0xFC000000UL;
9292 ++
9293 ++ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
9294 ++ err = get_user(addis, (unsigned int*)addr);
9295 ++ err |= get_user(addi, (unsigned int*)(addr+4));
9296 ++ err |= get_user(rlwinm, (unsigned int*)(addr+8));
9297 ++ err |= get_user(add, (unsigned int*)(addr+12));
9298 ++ err |= get_user(li2, (unsigned int*)(addr+16));
9299 ++ err |= get_user(addis2, (unsigned int*)(addr+20));
9300 ++ err |= get_user(mtctr, (unsigned int*)(addr+24));
9301 ++ err |= get_user(li3, (unsigned int*)(addr+28));
9302 ++ err |= get_user(addis3, (unsigned int*)(addr+32));
9303 ++ err |= get_user(bctr, (unsigned int*)(addr+36));
9304 ++
9305 ++ if (err)
9306 ++ break;
9307 ++
9308 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
9309 ++ (addi & 0xFFFF0000U) == 0x396B0000U &&
9310 ++ rlwinm == 0x556C083CU &&
9311 ++ add == 0x7D6C5A14U &&
9312 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
9313 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
9314 ++ mtctr == 0x7D8903A6U &&
9315 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
9316 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
9317 ++ bctr == 0x4E800420U)
9318 ++ {
9319 ++ regs->gpr[PT_R11] =
9320 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
9321 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
9322 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
9323 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
9324 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
9325 ++ regs->nip = regs->ctr;
9326 ++ return 4;
9327 ++ }
9328 ++ }
9329 ++ } while (0);
9330 ++#endif
9331 ++
9332 ++ do { /* PaX: unpatched PLT emulation #3 */
9333 ++ unsigned int li, b;
9334 ++
9335 ++ err = get_user(li, (unsigned int *)regs->nip);
9336 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
9337 ++
9338 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
9339 ++ unsigned int addis, lwz, mtctr, bctr;
9340 ++ unsigned long addr = b | 0xFC000000UL;
9341 ++
9342 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
9343 ++ err = get_user(addis, (unsigned int *)addr);
9344 ++ err |= get_user(lwz, (unsigned int *)(addr+4));
9345 ++ err |= get_user(mtctr, (unsigned int *)(addr+8));
9346 ++ err |= get_user(bctr, (unsigned int *)(addr+12));
9347 ++
9348 ++ if (err)
9349 ++ break;
9350 ++
9351 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
9352 ++ (lwz & 0xFFFF0000U) == 0x816B0000U &&
9353 ++ mtctr == 0x7D6903A6U &&
9354 ++ bctr == 0x4E800420U)
9355 ++ {
9356 ++ unsigned int r11;
9357 ++
9358 ++ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
9359 ++ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
9360 ++
9361 ++ err = get_user(r11, (unsigned int *)addr);
9362 ++ if (err)
9363 ++ break;
9364 ++
9365 ++ regs->gpr[PT_R11] = r11;
9366 ++ regs->ctr = r11;
9367 ++ regs->nip = r11;
9368 ++ return 4;
9369 ++ }
9370 ++ }
9371 ++ } while (0);
9372 ++#endif
9373 ++
9374 ++#ifdef CONFIG_PAX_EMUSIGRT
9375 ++ do { /* PaX: sigreturn emulation */
9376 ++ unsigned int li, sc;
9377 ++
9378 ++ err = get_user(li, (unsigned int *)regs->nip);
9379 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
9380 ++
9381 ++ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
9382 ++ struct vm_area_struct *vma;
9383 ++ unsigned long call_syscall;
9384 ++
9385 ++ down_read(&current->mm->mmap_sem);
9386 ++ call_syscall = current->mm->call_syscall;
9387 ++ up_read(&current->mm->mmap_sem);
9388 ++ if (likely(call_syscall))
9389 ++ goto emulate;
9390 ++
9391 ++ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
9392 ++
9393 ++ down_write(&current->mm->mmap_sem);
9394 ++ if (current->mm->call_syscall) {
9395 ++ call_syscall = current->mm->call_syscall;
9396 ++ up_write(&current->mm->mmap_sem);
9397 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
9398 ++ goto emulate;
9399 ++ }
9400 ++
9401 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
9402 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
9403 ++ up_write(&current->mm->mmap_sem);
9404 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
9405 ++ return 1;
9406 ++ }
9407 ++
9408 ++ if (pax_insert_vma(vma, call_syscall)) {
9409 ++ up_write(&current->mm->mmap_sem);
9410 ++ kmem_cache_free(vm_area_cachep, vma);
9411 ++ return 1;
9412 ++ }
9413 ++
9414 ++ current->mm->call_syscall = call_syscall;
9415 ++ up_write(&current->mm->mmap_sem);
9416 ++
9417 ++emulate:
9418 ++ regs->gpr[PT_R0] = __NR_sigreturn;
9419 ++ regs->nip = call_syscall;
9420 ++ return 5;
9421 ++ }
9422 ++ } while (0);
9423 ++
9424 ++ do { /* PaX: rt_sigreturn emulation */
9425 ++ unsigned int li, sc;
9426 ++
9427 ++ err = get_user(li, (unsigned int *)regs->nip);
9428 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
9429 ++
9430 ++ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
9431 ++ struct vm_area_struct *vma;
9432 ++ unsigned int call_syscall;
9433 ++
9434 ++ down_read(&current->mm->mmap_sem);
9435 ++ call_syscall = current->mm->call_syscall;
9436 ++ up_read(&current->mm->mmap_sem);
9437 ++ if (likely(call_syscall))
9438 ++ goto rt_emulate;
9439 ++
9440 ++ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
9441 ++
9442 ++ down_write(&current->mm->mmap_sem);
9443 ++ if (current->mm->call_syscall) {
9444 ++ call_syscall = current->mm->call_syscall;
9445 ++ up_write(&current->mm->mmap_sem);
9446 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
9447 ++ goto rt_emulate;
9448 ++ }
9449 ++
9450 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
9451 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
9452 ++ up_write(&current->mm->mmap_sem);
9453 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
9454 ++ return 1;
9455 ++ }
9456 ++
9457 ++ if (pax_insert_vma(vma, call_syscall)) {
9458 ++ up_write(&current->mm->mmap_sem);
9459 ++ kmem_cache_free(vm_area_cachep, vma);
9460 ++ return 1;
9461 ++ }
9462 ++
9463 ++ current->mm->call_syscall = call_syscall;
9464 ++ up_write(&current->mm->mmap_sem);
9465 ++
9466 ++rt_emulate:
9467 ++ regs->gpr[PT_R0] = __NR_rt_sigreturn;
9468 ++ regs->nip = call_syscall;
9469 ++ return 6;
9470 ++ }
9471 ++ } while (0);
9472 ++#endif
9473 ++
9474 ++ return 1;
9475 ++}
9476 ++
9477 ++void pax_report_insns(void *pc, void *sp)
9478 ++{
9479 ++ unsigned long i;
9480 ++
9481 ++ printk(KERN_ERR "PAX: bytes at PC: ");
9482 ++ for (i = 0; i < 5; i++) {
9483 ++ unsigned int c;
9484 ++ if (get_user(c, (unsigned int *)pc+i))
9485 ++ printk("???????? ");
9486 ++ else
9487 ++ printk("%08x ", c);
9488 ++ }
9489 ++ printk("\n");
9490 ++}
9491 ++#endif
9492 ++
9493 + /*
9494 + * Check whether the instruction at regs->nip is a store using
9495 + * an update addressing form which will update r1.
9496 +@@ -157,7 +521,7 @@ int __kprobes do_page_fault(struct pt_re
9497 + * indicate errors in DSISR but can validly be set in SRR1.
9498 + */
9499 + if (trap == 0x400)
9500 +- error_code &= 0x48200000;
9501 ++ error_code &= 0x58200000;
9502 + else
9503 + is_write = error_code & DSISR_ISSTORE;
9504 + #else
9505 +@@ -357,6 +721,37 @@ bad_area:
9506 + bad_area_nosemaphore:
9507 + /* User mode accesses cause a SIGSEGV */
9508 + if (user_mode(regs)) {
9509 ++
9510 ++#ifdef CONFIG_PAX_PAGEEXEC
9511 ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
9512 ++#ifdef CONFIG_PPC64
9513 ++ if (is_exec && (error_code & DSISR_PROTFAULT)) {
9514 ++#else
9515 ++ if (is_exec && regs->nip == address) {
9516 ++#endif
9517 ++ switch (pax_handle_fetch_fault(regs)) {
9518 ++
9519 ++#ifdef CONFIG_PAX_EMUPLT
9520 ++ case 2:
9521 ++ case 3:
9522 ++ case 4:
9523 ++ return 0;
9524 ++#endif
9525 ++
9526 ++#ifdef CONFIG_PAX_EMUSIGRT
9527 ++ case 5:
9528 ++ case 6:
9529 ++ return 0;
9530 ++#endif
9531 ++
9532 ++ }
9533 ++
9534 ++ pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[PT_R1]);
9535 ++ do_exit(SIGKILL);
9536 ++ }
9537 ++ }
9538 ++#endif
9539 ++
9540 + _exception(SIGSEGV, regs, code, address);
9541 + return 0;
9542 + }
9543 +diff -Nurp linux-2.6.23.15/arch/powerpc/mm/mmap.c linux-2.6.23.15-grsec/arch/powerpc/mm/mmap.c
9544 +--- linux-2.6.23.15/arch/powerpc/mm/mmap.c 2007-10-09 21:31:38.000000000 +0100
9545 ++++ linux-2.6.23.15-grsec/arch/powerpc/mm/mmap.c 2008-02-11 10:37:44.000000000 +0000
9546 +@@ -75,10 +75,22 @@ void arch_pick_mmap_layout(struct mm_str
9547 + */
9548 + if (mmap_is_legacy()) {
9549 + mm->mmap_base = TASK_UNMAPPED_BASE;
9550 ++
9551 ++#ifdef CONFIG_PAX_RANDMMAP
9552 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
9553 ++ mm->mmap_base += mm->delta_mmap;
9554 ++#endif
9555 ++
9556 + mm->get_unmapped_area = arch_get_unmapped_area;
9557 + mm->unmap_area = arch_unmap_area;
9558 + } else {
9559 + mm->mmap_base = mmap_base();
9560 ++
9561 ++#ifdef CONFIG_PAX_RANDMMAP
9562 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
9563 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
9564 ++#endif
9565 ++
9566 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
9567 + mm->unmap_area = arch_unmap_area_topdown;
9568 + }
9569 +diff -Nurp linux-2.6.23.15/arch/ppc/mm/fault.c linux-2.6.23.15-grsec/arch/ppc/mm/fault.c
9570 +--- linux-2.6.23.15/arch/ppc/mm/fault.c 2007-10-09 21:31:38.000000000 +0100
9571 ++++ linux-2.6.23.15-grsec/arch/ppc/mm/fault.c 2008-02-11 10:37:44.000000000 +0000
9572 +@@ -25,6 +25,11 @@
9573 + #include <linux/interrupt.h>
9574 + #include <linux/highmem.h>
9575 + #include <linux/module.h>
9576 ++#include <linux/slab.h>
9577 ++#include <linux/pagemap.h>
9578 ++#include <linux/compiler.h>
9579 ++#include <linux/binfmts.h>
9580 ++#include <linux/unistd.h>
9581 +
9582 + #include <asm/page.h>
9583 + #include <asm/pgtable.h>
9584 +@@ -48,6 +53,364 @@ unsigned long pte_misses; /* updated by
9585 + unsigned long pte_errors; /* updated by do_page_fault() */
9586 + unsigned int probingmem;
9587 +
9588 ++#ifdef CONFIG_PAX_EMUSIGRT
9589 ++void pax_syscall_close(struct vm_area_struct *vma)
9590 ++{
9591 ++ vma->vm_mm->call_syscall = 0UL;
9592 ++}
9593 ++
9594 ++static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
9595 ++{
9596 ++ struct page *page;
9597 ++ unsigned int *kaddr;
9598 ++
9599 ++ page = alloc_page(GFP_HIGHUSER);
9600 ++ if (!page)
9601 ++ return NOPAGE_OOM;
9602 ++
9603 ++ kaddr = kmap(page);
9604 ++ memset(kaddr, 0, PAGE_SIZE);
9605 ++ kaddr[0] = 0x44000002U; /* sc */
9606 ++ __flush_dcache_icache(kaddr);
9607 ++ kunmap(page);
9608 ++ if (type)
9609 ++ *type = VM_FAULT_MAJOR;
9610 ++ return page;
9611 ++}
9612 ++
9613 ++static struct vm_operations_struct pax_vm_ops = {
9614 ++ .close = pax_syscall_close,
9615 ++ .nopage = pax_syscall_nopage,
9616 ++};
9617 ++
9618 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
9619 ++{
9620 ++ int ret;
9621 ++
9622 ++ memset(vma, 0, sizeof(*vma));
9623 ++ vma->vm_mm = current->mm;
9624 ++ vma->vm_start = addr;
9625 ++ vma->vm_end = addr + PAGE_SIZE;
9626 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
9627 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
9628 ++ vma->vm_ops = &pax_vm_ops;
9629 ++
9630 ++ ret = insert_vm_struct(current->mm, vma);
9631 ++ if (ret)
9632 ++ return ret;
9633 ++
9634 ++ ++current->mm->total_vm;
9635 ++ return 0;
9636 ++}
9637 ++#endif
9638 ++
9639 ++#ifdef CONFIG_PAX_PAGEEXEC
9640 ++/*
9641 ++ * PaX: decide what to do with offenders (regs->nip = fault address)
9642 ++ *
9643 ++ * returns 1 when task should be killed
9644 ++ * 2 when patched GOT trampoline was detected
9645 ++ * 3 when patched PLT trampoline was detected
9646 ++ * 4 when unpatched PLT trampoline was detected
9647 ++ * 5 when sigreturn trampoline was detected
9648 ++ * 6 when rt_sigreturn trampoline was detected
9649 ++ */
9650 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
9651 ++{
9652 ++
9653 ++#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
9654 ++ int err;
9655 ++#endif
9656 ++
9657 ++#ifdef CONFIG_PAX_EMUPLT
9658 ++ do { /* PaX: patched GOT emulation */
9659 ++ unsigned int blrl;
9660 ++
9661 ++ err = get_user(blrl, (unsigned int *)regs->nip);
9662 ++
9663 ++ if (!err && blrl == 0x4E800021U) {
9664 ++ unsigned long temp = regs->nip;
9665 ++
9666 ++ regs->nip = regs->link & 0xFFFFFFFCUL;
9667 ++ regs->link = temp + 4UL;
9668 ++ return 2;
9669 ++ }
9670 ++ } while (0);
9671 ++
9672 ++ do { /* PaX: patched PLT emulation #1 */
9673 ++ unsigned int b;
9674 ++
9675 ++ err = get_user(b, (unsigned int *)regs->nip);
9676 ++
9677 ++ if (!err && (b & 0xFC000003U) == 0x48000000U) {
9678 ++ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
9679 ++ return 3;
9680 ++ }
9681 ++ } while (0);
9682 ++
9683 ++ do { /* PaX: unpatched PLT emulation #1 */
9684 ++ unsigned int li, b;
9685 ++
9686 ++ err = get_user(li, (unsigned int *)regs->nip);
9687 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
9688 ++
9689 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
9690 ++ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
9691 ++ unsigned long addr = b | 0xFC000000UL;
9692 ++
9693 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
9694 ++ err = get_user(rlwinm, (unsigned int *)addr);
9695 ++ err |= get_user(add, (unsigned int *)(addr+4));
9696 ++ err |= get_user(li2, (unsigned int *)(addr+8));
9697 ++ err |= get_user(addis2, (unsigned int *)(addr+12));
9698 ++ err |= get_user(mtctr, (unsigned int *)(addr+16));
9699 ++ err |= get_user(li3, (unsigned int *)(addr+20));
9700 ++ err |= get_user(addis3, (unsigned int *)(addr+24));
9701 ++ err |= get_user(bctr, (unsigned int *)(addr+28));
9702 ++
9703 ++ if (err)
9704 ++ break;
9705 ++
9706 ++ if (rlwinm == 0x556C083CU &&
9707 ++ add == 0x7D6C5A14U &&
9708 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
9709 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
9710 ++ mtctr == 0x7D8903A6U &&
9711 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
9712 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
9713 ++ bctr == 0x4E800420U)
9714 ++ {
9715 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
9716 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
9717 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
9718 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
9719 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
9720 ++ regs->nip = regs->ctr;
9721 ++ return 4;
9722 ++ }
9723 ++ }
9724 ++ } while (0);
9725 ++
9726 ++#if 0
9727 ++ do { /* PaX: unpatched PLT emulation #2 */
9728 ++ unsigned int lis, lwzu, b, bctr;
9729 ++
9730 ++ err = get_user(lis, (unsigned int *)regs->nip);
9731 ++ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
9732 ++ err |= get_user(b, (unsigned int *)(regs->nip+8));
9733 ++ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
9734 ++
9735 ++ if (err)
9736 ++ break;
9737 ++
9738 ++ if ((lis & 0xFFFF0000U) == 0x39600000U &&
9739 ++ (lwzu & 0xU) == 0xU &&
9740 ++ (b & 0xFC000003U) == 0x48000000U &&
9741 ++ bctr == 0x4E800420U)
9742 ++ {
9743 ++ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
9744 ++ unsigned long addr = b | 0xFC000000UL;
9745 ++
9746 ++ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
9747 ++ err = get_user(addis, (unsigned int*)addr);
9748 ++ err |= get_user(addi, (unsigned int*)(addr+4));
9749 ++ err |= get_user(rlwinm, (unsigned int*)(addr+8));
9750 ++ err |= get_user(add, (unsigned int*)(addr+12));
9751 ++ err |= get_user(li2, (unsigned int*)(addr+16));
9752 ++ err |= get_user(addis2, (unsigned int*)(addr+20));
9753 ++ err |= get_user(mtctr, (unsigned int*)(addr+24));
9754 ++ err |= get_user(li3, (unsigned int*)(addr+28));
9755 ++ err |= get_user(addis3, (unsigned int*)(addr+32));
9756 ++ err |= get_user(bctr, (unsigned int*)(addr+36));
9757 ++
9758 ++ if (err)
9759 ++ break;
9760 ++
9761 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
9762 ++ (addi & 0xFFFF0000U) == 0x396B0000U &&
9763 ++ rlwinm == 0x556C083CU &&
9764 ++ add == 0x7D6C5A14U &&
9765 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
9766 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
9767 ++ mtctr == 0x7D8903A6U &&
9768 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
9769 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
9770 ++ bctr == 0x4E800420U)
9771 ++ {
9772 ++ regs->gpr[PT_R11] =
9773 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
9774 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
9775 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
9776 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
9777 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
9778 ++ regs->nip = regs->ctr;
9779 ++ return 4;
9780 ++ }
9781 ++ }
9782 ++ } while (0);
9783 ++#endif
9784 ++
9785 ++ do { /* PaX: unpatched PLT emulation #3 */
9786 ++ unsigned int li, b;
9787 ++
9788 ++ err = get_user(li, (unsigned int *)regs->nip);
9789 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
9790 ++
9791 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
9792 ++ unsigned int addis, lwz, mtctr, bctr;
9793 ++ unsigned long addr = b | 0xFC000000UL;
9794 ++
9795 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
9796 ++ err = get_user(addis, (unsigned int *)addr);
9797 ++ err |= get_user(lwz, (unsigned int *)(addr+4));
9798 ++ err |= get_user(mtctr, (unsigned int *)(addr+8));
9799 ++ err |= get_user(bctr, (unsigned int *)(addr+12));
9800 ++
9801 ++ if (err)
9802 ++ break;
9803 ++
9804 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
9805 ++ (lwz & 0xFFFF0000U) == 0x816B0000U &&
9806 ++ mtctr == 0x7D6903A6U &&
9807 ++ bctr == 0x4E800420U)
9808 ++ {
9809 ++ unsigned int r11;
9810 ++
9811 ++ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
9812 ++ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
9813 ++
9814 ++ err = get_user(r11, (unsigned int *)addr);
9815 ++ if (err)
9816 ++ break;
9817 ++
9818 ++ regs->gpr[PT_R11] = r11;
9819 ++ regs->ctr = r11;
9820 ++ regs->nip = r11;
9821 ++ return 4;
9822 ++ }
9823 ++ }
9824 ++ } while (0);
9825 ++#endif
9826 ++
9827 ++#ifdef CONFIG_PAX_EMUSIGRT
9828 ++ do { /* PaX: sigreturn emulation */
9829 ++ unsigned int li, sc;
9830 ++
9831 ++ err = get_user(li, (unsigned int *)regs->nip);
9832 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
9833 ++
9834 ++ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
9835 ++ struct vm_area_struct *vma;
9836 ++ unsigned long call_syscall;
9837 ++
9838 ++ down_read(&current->mm->mmap_sem);
9839 ++ call_syscall = current->mm->call_syscall;
9840 ++ up_read(&current->mm->mmap_sem);
9841 ++ if (likely(call_syscall))
9842 ++ goto emulate;
9843 ++
9844 ++ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
9845 ++
9846 ++ down_write(&current->mm->mmap_sem);
9847 ++ if (current->mm->call_syscall) {
9848 ++ call_syscall = current->mm->call_syscall;
9849 ++ up_write(&current->mm->mmap_sem);
9850 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
9851 ++ goto emulate;
9852 ++ }
9853 ++
9854 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
9855 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
9856 ++ up_write(&current->mm->mmap_sem);
9857 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
9858 ++ return 1;
9859 ++ }
9860 ++
9861 ++ if (pax_insert_vma(vma, call_syscall)) {
9862 ++ up_write(&current->mm->mmap_sem);
9863 ++ kmem_cache_free(vm_area_cachep, vma);
9864 ++ return 1;
9865 ++ }
9866 ++
9867 ++ current->mm->call_syscall = call_syscall;
9868 ++ up_write(&current->mm->mmap_sem);
9869 ++
9870 ++emulate:
9871 ++ regs->gpr[PT_R0] = __NR_sigreturn;
9872 ++ regs->nip = call_syscall;
9873 ++ return 5;
9874 ++ }
9875 ++ } while (0);
9876 ++
9877 ++ do { /* PaX: rt_sigreturn emulation */
9878 ++ unsigned int li, sc;
9879 ++
9880 ++ err = get_user(li, (unsigned int *)regs->nip);
9881 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
9882 ++
9883 ++ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
9884 ++ struct vm_area_struct *vma;
9885 ++ unsigned int call_syscall;
9886 ++
9887 ++ down_read(&current->mm->mmap_sem);
9888 ++ call_syscall = current->mm->call_syscall;
9889 ++ up_read(&current->mm->mmap_sem);
9890 ++ if (likely(call_syscall))
9891 ++ goto rt_emulate;
9892 ++
9893 ++ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
9894 ++
9895 ++ down_write(&current->mm->mmap_sem);
9896 ++ if (current->mm->call_syscall) {
9897 ++ call_syscall = current->mm->call_syscall;
9898 ++ up_write(&current->mm->mmap_sem);
9899 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
9900 ++ goto rt_emulate;
9901 ++ }
9902 ++
9903 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
9904 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
9905 ++ up_write(&current->mm->mmap_sem);
9906 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
9907 ++ return 1;
9908 ++ }
9909 ++
9910 ++ if (pax_insert_vma(vma, call_syscall)) {
9911 ++ up_write(&current->mm->mmap_sem);
9912 ++ kmem_cache_free(vm_area_cachep, vma);
9913 ++ return 1;
9914 ++ }
9915 ++
9916 ++ current->mm->call_syscall = call_syscall;
9917 ++ up_write(&current->mm->mmap_sem);
9918 ++
9919 ++rt_emulate:
9920 ++ regs->gpr[PT_R0] = __NR_rt_sigreturn;
9921 ++ regs->nip = call_syscall;
9922 ++ return 6;
9923 ++ }
9924 ++ } while (0);
9925 ++#endif
9926 ++
9927 ++ return 1;
9928 ++}
9929 ++
9930 ++void pax_report_insns(void *pc, void *sp)
9931 ++{
9932 ++ unsigned long i;
9933 ++
9934 ++ printk(KERN_ERR "PAX: bytes at PC: ");
9935 ++ for (i = 0; i < 5; i++) {
9936 ++ unsigned int c;
9937 ++ if (get_user(c, (unsigned int *)pc+i))
9938 ++ printk("???????? ");
9939 ++ else
9940 ++ printk("%08x ", c);
9941 ++ }
9942 ++ printk("\n");
9943 ++}
9944 ++#endif
9945 ++
9946 + /*
9947 + * Check whether the instruction at regs->nip is a store using
9948 + * an update addressing form which will update r1.
9949 +@@ -109,7 +472,7 @@ int do_page_fault(struct pt_regs *regs,
9950 + * indicate errors in DSISR but can validly be set in SRR1.
9951 + */
9952 + if (TRAP(regs) == 0x400)
9953 +- error_code &= 0x48200000;
9954 ++ error_code &= 0x58200000;
9955 + else
9956 + is_write = error_code & 0x02000000;
9957 + #endif /* CONFIG_4xx || CONFIG_BOOKE */
9958 +@@ -204,15 +567,14 @@ good_area:
9959 + pte_t *ptep;
9960 + pmd_t *pmdp;
9961 +
9962 +-#if 0
9963 ++#if 1
9964 + /* It would be nice to actually enforce the VM execute
9965 + permission on CPUs which can do so, but far too
9966 + much stuff in userspace doesn't get the permissions
9967 + right, so we let any page be executed for now. */
9968 + if (! (vma->vm_flags & VM_EXEC))
9969 + goto bad_area;
9970 +-#endif
9971 +-
9972 ++#else
9973 + /* Since 4xx/Book-E supports per-page execute permission,
9974 + * we lazily flush dcache to icache. */
9975 + ptep = NULL;
9976 +@@ -235,6 +597,7 @@ good_area:
9977 + pte_unmap_unlock(ptep, ptl);
9978 + }
9979 + #endif
9980 ++#endif
9981 + /* a read */
9982 + } else {
9983 + /* protection fault */
9984 +@@ -278,6 +641,33 @@ bad_area:
9985 +
9986 + /* User mode accesses cause a SIGSEGV */
9987 + if (user_mode(regs)) {
9988 ++
9989 ++#ifdef CONFIG_PAX_PAGEEXEC
9990 ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
9991 ++ if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
9992 ++ switch (pax_handle_fetch_fault(regs)) {
9993 ++
9994 ++#ifdef CONFIG_PAX_EMUPLT
9995 ++ case 2:
9996 ++ case 3:
9997 ++ case 4:
9998 ++ return 0;
9999 ++#endif
10000 ++
10001 ++#ifdef CONFIG_PAX_EMUSIGRT
10002 ++ case 5:
10003 ++ case 6:
10004 ++ return 0;
10005 ++#endif
10006 ++
10007 ++ }
10008 ++
10009 ++ pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[1]);
10010 ++ do_exit(SIGKILL);
10011 ++ }
10012 ++ }
10013 ++#endif
10014 ++
10015 + _exception(SIGSEGV, regs, code, address);
10016 + return 0;
10017 + }
10018 +diff -Nurp linux-2.6.23.15/arch/s390/kernel/module.c linux-2.6.23.15-grsec/arch/s390/kernel/module.c
10019 +--- linux-2.6.23.15/arch/s390/kernel/module.c 2007-10-09 21:31:38.000000000 +0100
10020 ++++ linux-2.6.23.15-grsec/arch/s390/kernel/module.c 2008-02-11 10:37:44.000000000 +0000
10021 +@@ -166,11 +166,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
10022 +
10023 + /* Increase core size by size of got & plt and set start
10024 + offsets for got and plt. */
10025 +- me->core_size = ALIGN(me->core_size, 4);
10026 +- me->arch.got_offset = me->core_size;
10027 +- me->core_size += me->arch.got_size;
10028 +- me->arch.plt_offset = me->core_size;
10029 +- me->core_size += me->arch.plt_size;
10030 ++ me->core_size_rw = ALIGN(me->core_size_rw, 4);
10031 ++ me->arch.got_offset = me->core_size_rw;
10032 ++ me->core_size_rw += me->arch.got_size;
10033 ++ me->arch.plt_offset = me->core_size_rx;
10034 ++ me->core_size_rx += me->arch.plt_size;
10035 + return 0;
10036 + }
10037 +
10038 +@@ -256,7 +256,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
10039 + if (info->got_initialized == 0) {
10040 + Elf_Addr *gotent;
10041 +
10042 +- gotent = me->module_core + me->arch.got_offset +
10043 ++ gotent = me->module_core_rw + me->arch.got_offset +
10044 + info->got_offset;
10045 + *gotent = val;
10046 + info->got_initialized = 1;
10047 +@@ -280,7 +280,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
10048 + else if (r_type == R_390_GOTENT ||
10049 + r_type == R_390_GOTPLTENT)
10050 + *(unsigned int *) loc =
10051 +- (val + (Elf_Addr) me->module_core - loc) >> 1;
10052 ++ (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
10053 + else if (r_type == R_390_GOT64 ||
10054 + r_type == R_390_GOTPLT64)
10055 + *(unsigned long *) loc = val;
10056 +@@ -294,7 +294,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
10057 + case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
10058 + if (info->plt_initialized == 0) {
10059 + unsigned int *ip;
10060 +- ip = me->module_core + me->arch.plt_offset +
10061 ++ ip = me->module_core_rx + me->arch.plt_offset +
10062 + info->plt_offset;
10063 + #ifndef CONFIG_64BIT
10064 + ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
10065 +@@ -316,7 +316,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
10066 + val = me->arch.plt_offset - me->arch.got_offset +
10067 + info->plt_offset + rela->r_addend;
10068 + else
10069 +- val = (Elf_Addr) me->module_core +
10070 ++ val = (Elf_Addr) me->module_core_rx +
10071 + me->arch.plt_offset + info->plt_offset +
10072 + rela->r_addend - loc;
10073 + if (r_type == R_390_PLT16DBL)
10074 +@@ -336,7 +336,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
10075 + case R_390_GOTOFF32: /* 32 bit offset to GOT. */
10076 + case R_390_GOTOFF64: /* 64 bit offset to GOT. */
10077 + val = val + rela->r_addend -
10078 +- ((Elf_Addr) me->module_core + me->arch.got_offset);
10079 ++ ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
10080 + if (r_type == R_390_GOTOFF16)
10081 + *(unsigned short *) loc = val;
10082 + else if (r_type == R_390_GOTOFF32)
10083 +@@ -346,7 +346,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
10084 + break;
10085 + case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
10086 + case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
10087 +- val = (Elf_Addr) me->module_core + me->arch.got_offset +
10088 ++ val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
10089 + rela->r_addend - loc;
10090 + if (r_type == R_390_GOTPC)
10091 + *(unsigned int *) loc = val;
10092 +diff -Nurp linux-2.6.23.15/arch/sparc/Makefile linux-2.6.23.15-grsec/arch/sparc/Makefile
10093 +--- linux-2.6.23.15/arch/sparc/Makefile 2007-10-09 21:31:38.000000000 +0100
10094 ++++ linux-2.6.23.15-grsec/arch/sparc/Makefile 2008-02-11 10:37:44.000000000 +0000
10095 +@@ -36,7 +36,7 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc
10096 + # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
10097 + INIT_Y := $(patsubst %/, %/built-in.o, $(init-y))
10098 + CORE_Y := $(core-y)
10099 +-CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
10100 ++CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
10101 + CORE_Y := $(patsubst %/, %/built-in.o, $(CORE_Y))
10102 + DRIVERS_Y := $(patsubst %/, %/built-in.o, $(drivers-y))
10103 + NET_Y := $(patsubst %/, %/built-in.o, $(net-y))
10104 +diff -Nurp linux-2.6.23.15/arch/sparc/kernel/ptrace.c linux-2.6.23.15-grsec/arch/sparc/kernel/ptrace.c
10105 +--- linux-2.6.23.15/arch/sparc/kernel/ptrace.c 2007-10-09 21:31:38.000000000 +0100
10106 ++++ linux-2.6.23.15-grsec/arch/sparc/kernel/ptrace.c 2008-02-11 10:37:44.000000000 +0000
10107 +@@ -19,6 +19,7 @@
10108 + #include <linux/smp_lock.h>
10109 + #include <linux/security.h>
10110 + #include <linux/signal.h>
10111 ++#include <linux/grsecurity.h>
10112 +
10113 + #include <asm/pgtable.h>
10114 + #include <asm/system.h>
10115 +@@ -303,6 +304,11 @@ asmlinkage void do_ptrace(struct pt_regs
10116 + goto out;
10117 + }
10118 +
10119 ++ if (gr_handle_ptrace(child, request)) {
10120 ++ pt_error_return(regs, EPERM);
10121 ++ goto out_tsk;
10122 ++ }
10123 ++
10124 + if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
10125 + || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
10126 + if (ptrace_attach(child)) {
10127 +diff -Nurp linux-2.6.23.15/arch/sparc/kernel/sys_sparc.c linux-2.6.23.15-grsec/arch/sparc/kernel/sys_sparc.c
10128 +--- linux-2.6.23.15/arch/sparc/kernel/sys_sparc.c 2007-10-09 21:31:38.000000000 +0100
10129 ++++ linux-2.6.23.15-grsec/arch/sparc/kernel/sys_sparc.c 2008-02-11 10:37:44.000000000 +0000
10130 +@@ -57,7 +57,7 @@ unsigned long arch_get_unmapped_area(str
10131 + if (ARCH_SUN4C_SUN4 && len > 0x20000000)
10132 + return -ENOMEM;
10133 + if (!addr)
10134 +- addr = TASK_UNMAPPED_BASE;
10135 ++ addr = current->mm->mmap_base;
10136 +
10137 + if (flags & MAP_SHARED)
10138 + addr = COLOUR_ALIGN(addr);
10139 +diff -Nurp linux-2.6.23.15/arch/sparc/mm/fault.c linux-2.6.23.15-grsec/arch/sparc/mm/fault.c
10140 +--- linux-2.6.23.15/arch/sparc/mm/fault.c 2007-10-09 21:31:38.000000000 +0100
10141 ++++ linux-2.6.23.15-grsec/arch/sparc/mm/fault.c 2008-02-11 10:37:44.000000000 +0000
10142 +@@ -21,6 +21,10 @@
10143 + #include <linux/interrupt.h>
10144 + #include <linux/module.h>
10145 + #include <linux/kdebug.h>
10146 ++#include <linux/slab.h>
10147 ++#include <linux/pagemap.h>
10148 ++#include <linux/compiler.h>
10149 ++#include <linux/binfmts.h>
10150 +
10151 + #include <asm/system.h>
10152 + #include <asm/page.h>
10153 +@@ -216,6 +220,252 @@ static unsigned long compute_si_addr(str
10154 + return safe_compute_effective_address(regs, insn);
10155 + }
10156 +
10157 ++#ifdef CONFIG_PAX_PAGEEXEC
10158 ++void pax_emuplt_close(struct vm_area_struct *vma)
10159 ++{
10160 ++ vma->vm_mm->call_dl_resolve = 0UL;
10161 ++}
10162 ++
10163 ++static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
10164 ++{
10165 ++ struct page *page;
10166 ++ unsigned int *kaddr;
10167 ++
10168 ++ page = alloc_page(GFP_HIGHUSER);
10169 ++ if (!page)
10170 ++ return NOPAGE_OOM;
10171 ++
10172 ++ kaddr = kmap(page);
10173 ++ memset(kaddr, 0, PAGE_SIZE);
10174 ++ kaddr[0] = 0x9DE3BFA8U; /* save */
10175 ++ flush_dcache_page(page);
10176 ++ kunmap(page);
10177 ++ if (type)
10178 ++ *type = VM_FAULT_MAJOR;
10179 ++
10180 ++ return page;
10181 ++}
10182 ++
10183 ++static struct vm_operations_struct pax_vm_ops = {
10184 ++ .close = pax_emuplt_close,
10185 ++ .nopage = pax_emuplt_nopage,
10186 ++};
10187 ++
10188 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
10189 ++{
10190 ++ int ret;
10191 ++
10192 ++ memset(vma, 0, sizeof(*vma));
10193 ++ vma->vm_mm = current->mm;
10194 ++ vma->vm_start = addr;
10195 ++ vma->vm_end = addr + PAGE_SIZE;
10196 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
10197 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
10198 ++ vma->vm_ops = &pax_vm_ops;
10199 ++
10200 ++ ret = insert_vm_struct(current->mm, vma);
10201 ++ if (ret)
10202 ++ return ret;
10203 ++
10204 ++ ++current->mm->total_vm;
10205 ++ return 0;
10206 ++}
10207 ++
10208 ++/*
10209 ++ * PaX: decide what to do with offenders (regs->pc = fault address)
10210 ++ *
10211 ++ * returns 1 when task should be killed
10212 ++ * 2 when patched PLT trampoline was detected
10213 ++ * 3 when unpatched PLT trampoline was detected
10214 ++ */
10215 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
10216 ++{
10217 ++
10218 ++#ifdef CONFIG_PAX_EMUPLT
10219 ++ int err;
10220 ++
10221 ++ do { /* PaX: patched PLT emulation #1 */
10222 ++ unsigned int sethi1, sethi2, jmpl;
10223 ++
10224 ++ err = get_user(sethi1, (unsigned int *)regs->pc);
10225 ++ err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
10226 ++ err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
10227 ++
10228 ++ if (err)
10229 ++ break;
10230 ++
10231 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
10232 ++ (sethi2 & 0xFFC00000U) == 0x03000000U &&
10233 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U)
10234 ++ {
10235 ++ unsigned int addr;
10236 ++
10237 ++ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
10238 ++ addr = regs->u_regs[UREG_G1];
10239 ++ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
10240 ++ regs->pc = addr;
10241 ++ regs->npc = addr+4;
10242 ++ return 2;
10243 ++ }
10244 ++ } while (0);
10245 ++
10246 ++ { /* PaX: patched PLT emulation #2 */
10247 ++ unsigned int ba;
10248 ++
10249 ++ err = get_user(ba, (unsigned int *)regs->pc);
10250 ++
10251 ++ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
10252 ++ unsigned int addr;
10253 ++
10254 ++ addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
10255 ++ regs->pc = addr;
10256 ++ regs->npc = addr+4;
10257 ++ return 2;
10258 ++ }
10259 ++ }
10260 ++
10261 ++ do { /* PaX: patched PLT emulation #3 */
10262 ++ unsigned int sethi, jmpl, nop;
10263 ++
10264 ++ err = get_user(sethi, (unsigned int *)regs->pc);
10265 ++ err |= get_user(jmpl, (unsigned int *)(regs->pc+4));
10266 ++ err |= get_user(nop, (unsigned int *)(regs->pc+8));
10267 ++
10268 ++ if (err)
10269 ++ break;
10270 ++
10271 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
10272 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
10273 ++ nop == 0x01000000U)
10274 ++ {
10275 ++ unsigned int addr;
10276 ++
10277 ++ addr = (sethi & 0x003FFFFFU) << 10;
10278 ++ regs->u_regs[UREG_G1] = addr;
10279 ++ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
10280 ++ regs->pc = addr;
10281 ++ regs->npc = addr+4;
10282 ++ return 2;
10283 ++ }
10284 ++ } while (0);
10285 ++
10286 ++ do { /* PaX: unpatched PLT emulation step 1 */
10287 ++ unsigned int sethi, ba, nop;
10288 ++
10289 ++ err = get_user(sethi, (unsigned int *)regs->pc);
10290 ++ err |= get_user(ba, (unsigned int *)(regs->pc+4));
10291 ++ err |= get_user(nop, (unsigned int *)(regs->pc+8));
10292 ++
10293 ++ if (err)
10294 ++ break;
10295 ++
10296 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
10297 ++ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
10298 ++ nop == 0x01000000U)
10299 ++ {
10300 ++ unsigned int addr, save, call;
10301 ++
10302 ++ if ((ba & 0xFFC00000U) == 0x30800000U)
10303 ++ addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
10304 ++ else
10305 ++ addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
10306 ++
10307 ++ err = get_user(save, (unsigned int *)addr);
10308 ++ err |= get_user(call, (unsigned int *)(addr+4));
10309 ++ err |= get_user(nop, (unsigned int *)(addr+8));
10310 ++ if (err)
10311 ++ break;
10312 ++
10313 ++ if (save == 0x9DE3BFA8U &&
10314 ++ (call & 0xC0000000U) == 0x40000000U &&
10315 ++ nop == 0x01000000U)
10316 ++ {
10317 ++ struct vm_area_struct *vma;
10318 ++ unsigned long call_dl_resolve;
10319 ++
10320 ++ down_read(&current->mm->mmap_sem);
10321 ++ call_dl_resolve = current->mm->call_dl_resolve;
10322 ++ up_read(&current->mm->mmap_sem);
10323 ++ if (likely(call_dl_resolve))
10324 ++ goto emulate;
10325 ++
10326 ++ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
10327 ++
10328 ++ down_write(&current->mm->mmap_sem);
10329 ++ if (current->mm->call_dl_resolve) {
10330 ++ call_dl_resolve = current->mm->call_dl_resolve;
10331 ++ up_write(&current->mm->mmap_sem);
10332 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
10333 ++ goto emulate;
10334 ++ }
10335 ++
10336 ++ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
10337 ++ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
10338 ++ up_write(&current->mm->mmap_sem);
10339 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
10340 ++ return 1;
10341 ++ }
10342 ++
10343 ++ if (pax_insert_vma(vma, call_dl_resolve)) {
10344 ++ up_write(&current->mm->mmap_sem);
10345 ++ kmem_cache_free(vm_area_cachep, vma);
10346 ++ return 1;
10347 ++ }
10348 ++
10349 ++ current->mm->call_dl_resolve = call_dl_resolve;
10350 ++ up_write(&current->mm->mmap_sem);
10351 ++
10352 ++emulate:
10353 ++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
10354 ++ regs->pc = call_dl_resolve;
10355 ++ regs->npc = addr+4;
10356 ++ return 3;
10357 ++ }
10358 ++ }
10359 ++ } while (0);
10360 ++
10361 ++ do { /* PaX: unpatched PLT emulation step 2 */
10362 ++ unsigned int save, call, nop;
10363 ++
10364 ++ err = get_user(save, (unsigned int *)(regs->pc-4));
10365 ++ err |= get_user(call, (unsigned int *)regs->pc);
10366 ++ err |= get_user(nop, (unsigned int *)(regs->pc+4));
10367 ++ if (err)
10368 ++ break;
10369 ++
10370 ++ if (save == 0x9DE3BFA8U &&
10371 ++ (call & 0xC0000000U) == 0x40000000U &&
10372 ++ nop == 0x01000000U)
10373 ++ {
10374 ++ unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
10375 ++
10376 ++ regs->u_regs[UREG_RETPC] = regs->pc;
10377 ++ regs->pc = dl_resolve;
10378 ++ regs->npc = dl_resolve+4;
10379 ++ return 3;
10380 ++ }
10381 ++ } while (0);
10382 ++#endif
10383 ++
10384 ++ return 1;
10385 ++}
10386 ++
10387 ++void pax_report_insns(void *pc, void *sp)
10388 ++{
10389 ++ unsigned long i;
10390 ++
10391 ++ printk(KERN_ERR "PAX: bytes at PC: ");
10392 ++ for (i = 0; i < 5; i++) {
10393 ++ unsigned int c;
10394 ++ if (get_user(c, (unsigned int *)pc+i))
10395 ++ printk("???????? ");
10396 ++ else
10397 ++ printk("%08x ", c);
10398 ++ }
10399 ++ printk("\n");
10400 ++}
10401 ++#endif
10402 ++
10403 + asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
10404 + unsigned long address)
10405 + {
10406 +@@ -280,6 +530,24 @@ good_area:
10407 + if(!(vma->vm_flags & VM_WRITE))
10408 + goto bad_area;
10409 + } else {
10410 ++
10411 ++#ifdef CONFIG_PAX_PAGEEXEC
10412 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
10413 ++ up_read(&mm->mmap_sem);
10414 ++ switch (pax_handle_fetch_fault(regs)) {
10415 ++
10416 ++#ifdef CONFIG_PAX_EMUPLT
10417 ++ case 2:
10418 ++ case 3:
10419 ++ return;
10420 ++#endif
10421 ++
10422 ++ }
10423 ++ pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]);
10424 ++ do_exit(SIGKILL);
10425 ++ }
10426 ++#endif
10427 ++
10428 + /* Allow reads even for write-only mappings */
10429 + if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
10430 + goto bad_area;
10431 +diff -Nurp linux-2.6.23.15/arch/sparc/mm/init.c linux-2.6.23.15-grsec/arch/sparc/mm/init.c
10432 +--- linux-2.6.23.15/arch/sparc/mm/init.c 2007-10-09 21:31:38.000000000 +0100
10433 ++++ linux-2.6.23.15-grsec/arch/sparc/mm/init.c 2008-02-11 10:37:44.000000000 +0000
10434 +@@ -336,17 +336,17 @@ void __init paging_init(void)
10435 +
10436 + /* Initialize the protection map with non-constant, MMU dependent values. */
10437 + protection_map[0] = PAGE_NONE;
10438 +- protection_map[1] = PAGE_READONLY;
10439 +- protection_map[2] = PAGE_COPY;
10440 +- protection_map[3] = PAGE_COPY;
10441 ++ protection_map[1] = PAGE_READONLY_NOEXEC;
10442 ++ protection_map[2] = PAGE_COPY_NOEXEC;
10443 ++ protection_map[3] = PAGE_COPY_NOEXEC;
10444 + protection_map[4] = PAGE_READONLY;
10445 + protection_map[5] = PAGE_READONLY;
10446 + protection_map[6] = PAGE_COPY;
10447 + protection_map[7] = PAGE_COPY;
10448 + protection_map[8] = PAGE_NONE;
10449 +- protection_map[9] = PAGE_READONLY;
10450 +- protection_map[10] = PAGE_SHARED;
10451 +- protection_map[11] = PAGE_SHARED;
10452 ++ protection_map[9] = PAGE_READONLY_NOEXEC;
10453 ++ protection_map[10] = PAGE_SHARED_NOEXEC;
10454 ++ protection_map[11] = PAGE_SHARED_NOEXEC;
10455 + protection_map[12] = PAGE_READONLY;
10456 + protection_map[13] = PAGE_READONLY;
10457 + protection_map[14] = PAGE_SHARED;
10458 +diff -Nurp linux-2.6.23.15/arch/sparc/mm/srmmu.c linux-2.6.23.15-grsec/arch/sparc/mm/srmmu.c
10459 +--- linux-2.6.23.15/arch/sparc/mm/srmmu.c 2007-10-09 21:31:38.000000000 +0100
10460 ++++ linux-2.6.23.15-grsec/arch/sparc/mm/srmmu.c 2008-02-11 10:37:44.000000000 +0000
10461 +@@ -2157,6 +2157,13 @@ void __init ld_mmu_srmmu(void)
10462 + PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED);
10463 + BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
10464 + BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
10465 ++
10466 ++#ifdef CONFIG_PAX_PAGEEXEC
10467 ++ PAGE_SHARED_NOEXEC = pgprot_val(SRMMU_PAGE_SHARED_NOEXEC);
10468 ++ BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
10469 ++ BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
10470 ++#endif
10471 ++
10472 + BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
10473 + page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
10474 +
10475 +diff -Nurp linux-2.6.23.15/arch/sparc64/kernel/Makefile linux-2.6.23.15-grsec/arch/sparc64/kernel/Makefile
10476 +--- linux-2.6.23.15/arch/sparc64/kernel/Makefile 2007-10-09 21:31:38.000000000 +0100
10477 ++++ linux-2.6.23.15-grsec/arch/sparc64/kernel/Makefile 2008-02-11 10:37:44.000000000 +0000
10478 +@@ -3,7 +3,7 @@
10479 + #
10480 +
10481 + EXTRA_AFLAGS := -ansi
10482 +-EXTRA_CFLAGS := -Werror
10483 ++#EXTRA_CFLAGS := -Werror
10484 +
10485 + extra-y := head.o init_task.o vmlinux.lds
10486 +
10487 +diff -Nurp linux-2.6.23.15/arch/sparc64/kernel/ptrace.c linux-2.6.23.15-grsec/arch/sparc64/kernel/ptrace.c
10488 +--- linux-2.6.23.15/arch/sparc64/kernel/ptrace.c 2007-10-09 21:31:38.000000000 +0100
10489 ++++ linux-2.6.23.15-grsec/arch/sparc64/kernel/ptrace.c 2008-02-11 10:37:44.000000000 +0000
10490 +@@ -22,6 +22,7 @@
10491 + #include <linux/seccomp.h>
10492 + #include <linux/audit.h>
10493 + #include <linux/signal.h>
10494 ++#include <linux/grsecurity.h>
10495 +
10496 + #include <asm/asi.h>
10497 + #include <asm/pgtable.h>
10498 +@@ -216,6 +217,11 @@ asmlinkage void do_ptrace(struct pt_regs
10499 + goto out;
10500 + }
10501 +
10502 ++ if (gr_handle_ptrace(child, (long)request)) {
10503 ++ pt_error_return(regs, EPERM);
10504 ++ goto out_tsk;
10505 ++ }
10506 ++
10507 + if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
10508 + || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
10509 + if (ptrace_attach(child)) {
10510 +diff -Nurp linux-2.6.23.15/arch/sparc64/kernel/sys_sparc.c linux-2.6.23.15-grsec/arch/sparc64/kernel/sys_sparc.c
10511 +--- linux-2.6.23.15/arch/sparc64/kernel/sys_sparc.c 2008-02-11 10:36:03.000000000 +0000
10512 ++++ linux-2.6.23.15-grsec/arch/sparc64/kernel/sys_sparc.c 2008-02-11 10:37:44.000000000 +0000
10513 +@@ -124,7 +124,7 @@ unsigned long arch_get_unmapped_area(str
10514 + /* We do not accept a shared mapping if it would violate
10515 + * cache aliasing constraints.
10516 + */
10517 +- if ((flags & MAP_SHARED) &&
10518 ++ if ((filp || (flags & MAP_SHARED)) &&
10519 + ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
10520 + return -EINVAL;
10521 + return addr;
10522 +@@ -139,6 +139,10 @@ unsigned long arch_get_unmapped_area(str
10523 + if (filp || (flags & MAP_SHARED))
10524 + do_color_align = 1;
10525 +
10526 ++#ifdef CONFIG_PAX_RANDMMAP
10527 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
10528 ++#endif
10529 ++
10530 + if (addr) {
10531 + if (do_color_align)
10532 + addr = COLOUR_ALIGN(addr, pgoff);
10533 +@@ -152,9 +156,9 @@ unsigned long arch_get_unmapped_area(str
10534 + }
10535 +
10536 + if (len > mm->cached_hole_size) {
10537 +- start_addr = addr = mm->free_area_cache;
10538 ++ start_addr = addr = mm->free_area_cache;
10539 + } else {
10540 +- start_addr = addr = TASK_UNMAPPED_BASE;
10541 ++ start_addr = addr = mm->mmap_base;
10542 + mm->cached_hole_size = 0;
10543 + }
10544 +
10545 +@@ -174,8 +178,8 @@ full_search:
10546 + vma = find_vma(mm, VA_EXCLUDE_END);
10547 + }
10548 + if (unlikely(task_size < addr)) {
10549 +- if (start_addr != TASK_UNMAPPED_BASE) {
10550 +- start_addr = addr = TASK_UNMAPPED_BASE;
10551 ++ if (start_addr != mm->mmap_base) {
10552 ++ start_addr = addr = mm->mmap_base;
10553 + mm->cached_hole_size = 0;
10554 + goto full_search;
10555 + }
10556 +@@ -215,7 +219,7 @@ arch_get_unmapped_area_topdown(struct fi
10557 + /* We do not accept a shared mapping if it would violate
10558 + * cache aliasing constraints.
10559 + */
10560 +- if ((flags & MAP_SHARED) &&
10561 ++ if ((filp || (flags & MAP_SHARED)) &&
10562 + ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
10563 + return -EINVAL;
10564 + return addr;
10565 +@@ -378,6 +382,12 @@ void arch_pick_mmap_layout(struct mm_str
10566 + current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
10567 + sysctl_legacy_va_layout) {
10568 + mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
10569 ++
10570 ++#ifdef CONFIG_PAX_RANDMMAP
10571 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
10572 ++ mm->mmap_base += mm->delta_mmap;
10573 ++#endif
10574 ++
10575 + mm->get_unmapped_area = arch_get_unmapped_area;
10576 + mm->unmap_area = arch_unmap_area;
10577 + } else {
10578 +@@ -392,6 +402,12 @@ void arch_pick_mmap_layout(struct mm_str
10579 + gap = (task_size / 6 * 5);
10580 +
10581 + mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
10582 ++
10583 ++#ifdef CONFIG_PAX_RANDMMAP
10584 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
10585 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
10586 ++#endif
10587 ++
10588 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
10589 + mm->unmap_area = arch_unmap_area_topdown;
10590 + }
10591 +diff -Nurp linux-2.6.23.15/arch/sparc64/mm/Makefile linux-2.6.23.15-grsec/arch/sparc64/mm/Makefile
10592 +--- linux-2.6.23.15/arch/sparc64/mm/Makefile 2007-10-09 21:31:38.000000000 +0100
10593 ++++ linux-2.6.23.15-grsec/arch/sparc64/mm/Makefile 2008-02-11 10:37:44.000000000 +0000
10594 +@@ -3,7 +3,7 @@
10595 + #
10596 +
10597 + EXTRA_AFLAGS := -ansi
10598 +-EXTRA_CFLAGS := -Werror
10599 ++#EXTRA_CFLAGS := -Werror
10600 +
10601 + obj-y := ultra.o tlb.o tsb.o fault.o init.o generic.o
10602 +
10603 +diff -Nurp linux-2.6.23.15/arch/sparc64/mm/fault.c linux-2.6.23.15-grsec/arch/sparc64/mm/fault.c
10604 +--- linux-2.6.23.15/arch/sparc64/mm/fault.c 2007-10-09 21:31:38.000000000 +0100
10605 ++++ linux-2.6.23.15-grsec/arch/sparc64/mm/fault.c 2008-02-11 10:37:44.000000000 +0000
10606 +@@ -20,6 +20,10 @@
10607 + #include <linux/kprobes.h>
10608 + #include <linux/kallsyms.h>
10609 + #include <linux/kdebug.h>
10610 ++#include <linux/slab.h>
10611 ++#include <linux/pagemap.h>
10612 ++#include <linux/compiler.h>
10613 ++#include <linux/binfmts.h>
10614 +
10615 + #include <asm/page.h>
10616 + #include <asm/pgtable.h>
10617 +@@ -270,6 +274,369 @@ cannot_handle:
10618 + unhandled_fault (address, current, regs);
10619 + }
10620 +
10621 ++#ifdef CONFIG_PAX_PAGEEXEC
10622 ++#ifdef CONFIG_PAX_EMUPLT
10623 ++static void pax_emuplt_close(struct vm_area_struct *vma)
10624 ++{
10625 ++ vma->vm_mm->call_dl_resolve = 0UL;
10626 ++}
10627 ++
10628 ++static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
10629 ++{
10630 ++ struct page *page;
10631 ++ unsigned int *kaddr;
10632 ++
10633 ++ page = alloc_page(GFP_HIGHUSER);
10634 ++ if (!page)
10635 ++ return NOPAGE_OOM;
10636 ++
10637 ++ kaddr = kmap(page);
10638 ++ memset(kaddr, 0, PAGE_SIZE);
10639 ++ kaddr[0] = 0x9DE3BFA8U; /* save */
10640 ++ flush_dcache_page(page);
10641 ++ kunmap(page);
10642 ++ if (type)
10643 ++ *type = VM_FAULT_MAJOR;
10644 ++ return page;
10645 ++}
10646 ++
10647 ++static struct vm_operations_struct pax_vm_ops = {
10648 ++ .close = pax_emuplt_close,
10649 ++ .nopage = pax_emuplt_nopage,
10650 ++};
10651 ++
10652 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
10653 ++{
10654 ++ int ret;
10655 ++
10656 ++ memset(vma, 0, sizeof(*vma));
10657 ++ vma->vm_mm = current->mm;
10658 ++ vma->vm_start = addr;
10659 ++ vma->vm_end = addr + PAGE_SIZE;
10660 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
10661 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
10662 ++ vma->vm_ops = &pax_vm_ops;
10663 ++
10664 ++ ret = insert_vm_struct(current->mm, vma);
10665 ++ if (ret)
10666 ++ return ret;
10667 ++
10668 ++ ++current->mm->total_vm;
10669 ++ return 0;
10670 ++}
10671 ++#endif
10672 ++
10673 ++/*
10674 ++ * PaX: decide what to do with offenders (regs->tpc = fault address)
10675 ++ *
10676 ++ * returns 1 when task should be killed
10677 ++ * 2 when patched PLT trampoline was detected
10678 ++ * 3 when unpatched PLT trampoline was detected
10679 ++ */
10680 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
10681 ++{
10682 ++
10683 ++#ifdef CONFIG_PAX_EMUPLT
10684 ++ int err;
10685 ++
10686 ++ do { /* PaX: patched PLT emulation #1 */
10687 ++ unsigned int sethi1, sethi2, jmpl;
10688 ++
10689 ++ err = get_user(sethi1, (unsigned int *)regs->tpc);
10690 ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
10691 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+8));
10692 ++
10693 ++ if (err)
10694 ++ break;
10695 ++
10696 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
10697 ++ (sethi2 & 0xFFC00000U) == 0x03000000U &&
10698 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U)
10699 ++ {
10700 ++ unsigned long addr;
10701 ++
10702 ++ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
10703 ++ addr = regs->u_regs[UREG_G1];
10704 ++ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
10705 ++ regs->tpc = addr;
10706 ++ regs->tnpc = addr+4;
10707 ++ return 2;
10708 ++ }
10709 ++ } while (0);
10710 ++
10711 ++ { /* PaX: patched PLT emulation #2 */
10712 ++ unsigned int ba;
10713 ++
10714 ++ err = get_user(ba, (unsigned int *)regs->tpc);
10715 ++
10716 ++ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
10717 ++ unsigned long addr;
10718 ++
10719 ++ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
10720 ++ regs->tpc = addr;
10721 ++ regs->tnpc = addr+4;
10722 ++ return 2;
10723 ++ }
10724 ++ }
10725 ++
10726 ++ do { /* PaX: patched PLT emulation #3 */
10727 ++ unsigned int sethi, jmpl, nop;
10728 ++
10729 ++ err = get_user(sethi, (unsigned int *)regs->tpc);
10730 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+4));
10731 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
10732 ++
10733 ++ if (err)
10734 ++ break;
10735 ++
10736 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
10737 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
10738 ++ nop == 0x01000000U)
10739 ++ {
10740 ++ unsigned long addr;
10741 ++
10742 ++ addr = (sethi & 0x003FFFFFU) << 10;
10743 ++ regs->u_regs[UREG_G1] = addr;
10744 ++ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
10745 ++ regs->tpc = addr;
10746 ++ regs->tnpc = addr+4;
10747 ++ return 2;
10748 ++ }
10749 ++ } while (0);
10750 ++
10751 ++ do { /* PaX: patched PLT emulation #4 */
10752 ++ unsigned int mov1, call, mov2;
10753 ++
10754 ++ err = get_user(mov1, (unsigned int *)regs->tpc);
10755 ++ err |= get_user(call, (unsigned int *)(regs->tpc+4));
10756 ++ err |= get_user(mov2, (unsigned int *)(regs->tpc+8));
10757 ++
10758 ++ if (err)
10759 ++ break;
10760 ++
10761 ++ if (mov1 == 0x8210000FU &&
10762 ++ (call & 0xC0000000U) == 0x40000000U &&
10763 ++ mov2 == 0x9E100001U)
10764 ++ {
10765 ++ unsigned long addr;
10766 ++
10767 ++ regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
10768 ++ addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
10769 ++ regs->tpc = addr;
10770 ++ regs->tnpc = addr+4;
10771 ++ return 2;
10772 ++ }
10773 ++ } while (0);
10774 ++
10775 ++ do { /* PaX: patched PLT emulation #5 */
10776 ++ unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
10777 ++
10778 ++ err = get_user(sethi1, (unsigned int *)regs->tpc);
10779 ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
10780 ++ err |= get_user(or1, (unsigned int *)(regs->tpc+8));
10781 ++ err |= get_user(or2, (unsigned int *)(regs->tpc+12));
10782 ++ err |= get_user(sllx, (unsigned int *)(regs->tpc+16));
10783 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+20));
10784 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+24));
10785 ++
10786 ++ if (err)
10787 ++ break;
10788 ++
10789 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
10790 ++ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
10791 ++ (or1 & 0xFFFFE000U) == 0x82106000U &&
10792 ++ (or2 & 0xFFFFE000U) == 0x8A116000U &&
10793 ++ sllx == 0x83287020 &&
10794 ++ jmpl == 0x81C04005U &&
10795 ++ nop == 0x01000000U)
10796 ++ {
10797 ++ unsigned long addr;
10798 ++
10799 ++ regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
10800 ++ regs->u_regs[UREG_G1] <<= 32;
10801 ++ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
10802 ++ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
10803 ++ regs->tpc = addr;
10804 ++ regs->tnpc = addr+4;
10805 ++ return 2;
10806 ++ }
10807 ++ } while (0);
10808 ++
10809 ++ do { /* PaX: patched PLT emulation #6 */
10810 ++ unsigned int sethi1, sethi2, sllx, or, jmpl, nop;
10811 ++
10812 ++ err = get_user(sethi1, (unsigned int *)regs->tpc);
10813 ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
10814 ++ err |= get_user(sllx, (unsigned int *)(regs->tpc+8));
10815 ++ err |= get_user(or, (unsigned int *)(regs->tpc+12));
10816 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+16));
10817 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+20));
10818 ++
10819 ++ if (err)
10820 ++ break;
10821 ++
10822 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
10823 ++ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
10824 ++ sllx == 0x83287020 &&
10825 ++ (or & 0xFFFFE000U) == 0x8A116000U &&
10826 ++ jmpl == 0x81C04005U &&
10827 ++ nop == 0x01000000U)
10828 ++ {
10829 ++ unsigned long addr;
10830 ++
10831 ++ regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
10832 ++ regs->u_regs[UREG_G1] <<= 32;
10833 ++ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
10834 ++ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
10835 ++ regs->tpc = addr;
10836 ++ regs->tnpc = addr+4;
10837 ++ return 2;
10838 ++ }
10839 ++ } while (0);
10840 ++
10841 ++ do { /* PaX: patched PLT emulation #7 */
10842 ++ unsigned int sethi, ba, nop;
10843 ++
10844 ++ err = get_user(sethi, (unsigned int *)regs->tpc);
10845 ++ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
10846 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
10847 ++
10848 ++ if (err)
10849 ++ break;
10850 ++
10851 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
10852 ++ (ba & 0xFFF00000U) == 0x30600000U &&
10853 ++ nop == 0x01000000U)
10854 ++ {
10855 ++ unsigned long addr;
10856 ++
10857 ++ addr = (sethi & 0x003FFFFFU) << 10;
10858 ++ regs->u_regs[UREG_G1] = addr;
10859 ++ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
10860 ++ regs->tpc = addr;
10861 ++ regs->tnpc = addr+4;
10862 ++ return 2;
10863 ++ }
10864 ++ } while (0);
10865 ++
10866 ++ do { /* PaX: unpatched PLT emulation step 1 */
10867 ++ unsigned int sethi, ba, nop;
10868 ++
10869 ++ err = get_user(sethi, (unsigned int *)regs->tpc);
10870 ++ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
10871 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
10872 ++
10873 ++ if (err)
10874 ++ break;
10875 ++
10876 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
10877 ++ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
10878 ++ nop == 0x01000000U)
10879 ++ {
10880 ++ unsigned long addr;
10881 ++ unsigned int save, call;
10882 ++
10883 ++ if ((ba & 0xFFC00000U) == 0x30800000U)
10884 ++ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
10885 ++ else
10886 ++ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
10887 ++
10888 ++ err = get_user(save, (unsigned int *)addr);
10889 ++ err |= get_user(call, (unsigned int *)(addr+4));
10890 ++ err |= get_user(nop, (unsigned int *)(addr+8));
10891 ++ if (err)
10892 ++ break;
10893 ++
10894 ++ if (save == 0x9DE3BFA8U &&
10895 ++ (call & 0xC0000000U) == 0x40000000U &&
10896 ++ nop == 0x01000000U)
10897 ++ {
10898 ++ struct vm_area_struct *vma;
10899 ++ unsigned long call_dl_resolve;
10900 ++
10901 ++ down_read(&current->mm->mmap_sem);
10902 ++ call_dl_resolve = current->mm->call_dl_resolve;
10903 ++ up_read(&current->mm->mmap_sem);
10904 ++ if (likely(call_dl_resolve))
10905 ++ goto emulate;
10906 ++
10907 ++ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
10908 ++
10909 ++ down_write(&current->mm->mmap_sem);
10910 ++ if (current->mm->call_dl_resolve) {
10911 ++ call_dl_resolve = current->mm->call_dl_resolve;
10912 ++ up_write(&current->mm->mmap_sem);
10913 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
10914 ++ goto emulate;
10915 ++ }
10916 ++
10917 ++ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
10918 ++ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
10919 ++ up_write(&current->mm->mmap_sem);
10920 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
10921 ++ return 1;
10922 ++ }
10923 ++
10924 ++ if (pax_insert_vma(vma, call_dl_resolve)) {
10925 ++ up_write(&current->mm->mmap_sem);
10926 ++ kmem_cache_free(vm_area_cachep, vma);
10927 ++ return 1;
10928 ++ }
10929 ++
10930 ++ current->mm->call_dl_resolve = call_dl_resolve;
10931 ++ up_write(&current->mm->mmap_sem);
10932 ++
10933 ++emulate:
10934 ++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
10935 ++ regs->tpc = call_dl_resolve;
10936 ++ regs->tnpc = addr+4;
10937 ++ return 3;
10938 ++ }
10939 ++ }
10940 ++ } while (0);
10941 ++
10942 ++ do { /* PaX: unpatched PLT emulation step 2 */
10943 ++ unsigned int save, call, nop;
10944 ++
10945 ++ err = get_user(save, (unsigned int *)(regs->tpc-4));
10946 ++ err |= get_user(call, (unsigned int *)regs->tpc);
10947 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+4));
10948 ++ if (err)
10949 ++ break;
10950 ++
10951 ++ if (save == 0x9DE3BFA8U &&
10952 ++ (call & 0xC0000000U) == 0x40000000U &&
10953 ++ nop == 0x01000000U)
10954 ++ {
10955 ++ unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
10956 ++
10957 ++ regs->u_regs[UREG_RETPC] = regs->tpc;
10958 ++ regs->tpc = dl_resolve;
10959 ++ regs->tnpc = dl_resolve+4;
10960 ++ return 3;
10961 ++ }
10962 ++ } while (0);
10963 ++#endif
10964 ++
10965 ++ return 1;
10966 ++}
10967 ++
10968 ++void pax_report_insns(void *pc, void *sp)
10969 ++{
10970 ++ unsigned long i;
10971 ++
10972 ++ printk(KERN_ERR "PAX: bytes at PC: ");
10973 ++ for (i = 0; i < 5; i++) {
10974 ++ unsigned int c;
10975 ++ if (get_user(c, (unsigned int *)pc+i))
10976 ++ printk("???????? ");
10977 ++ else
10978 ++ printk("%08x ", c);
10979 ++ }
10980 ++ printk("\n");
10981 ++}
10982 ++#endif
10983 ++
10984 + asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
10985 + {
10986 + struct mm_struct *mm = current->mm;
10987 +@@ -311,8 +678,10 @@ asmlinkage void __kprobes do_sparc64_fau
10988 + goto intr_or_no_mm;
10989 +
10990 + if (test_thread_flag(TIF_32BIT)) {
10991 +- if (!(regs->tstate & TSTATE_PRIV))
10992 ++ if (!(regs->tstate & TSTATE_PRIV)) {
10993 + regs->tpc &= 0xffffffff;
10994 ++ regs->tnpc &= 0xffffffff;
10995 ++ }
10996 + address &= 0xffffffff;
10997 + }
10998 +
10999 +@@ -329,6 +698,29 @@ asmlinkage void __kprobes do_sparc64_fau
11000 + if (!vma)
11001 + goto bad_area;
11002 +
11003 ++#ifdef CONFIG_PAX_PAGEEXEC
11004 ++ /* PaX: detect ITLB misses on non-exec pages */
11005 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
11006 ++ !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
11007 ++ {
11008 ++ if (address != regs->tpc)
11009 ++ goto good_area;
11010 ++
11011 ++ up_read(&mm->mmap_sem);
11012 ++ switch (pax_handle_fetch_fault(regs)) {
11013 ++
11014 ++#ifdef CONFIG_PAX_EMUPLT
11015 ++ case 2:
11016 ++ case 3:
11017 ++ return;
11018 ++#endif
11019 ++
11020 ++ }
11021 ++ pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
11022 ++ do_exit(SIGKILL);
11023 ++ }
11024 ++#endif
11025 ++
11026 + /* Pure DTLB misses do not tell us whether the fault causing
11027 + * load/store/atomic was a write or not, it only says that there
11028 + * was no match. So in such a case we (carefully) read the
11029 +diff -Nurp linux-2.6.23.15/arch/v850/kernel/module.c linux-2.6.23.15-grsec/arch/v850/kernel/module.c
11030 +--- linux-2.6.23.15/arch/v850/kernel/module.c 2007-10-09 21:31:38.000000000 +0100
11031 ++++ linux-2.6.23.15-grsec/arch/v850/kernel/module.c 2008-02-11 10:37:44.000000000 +0000
11032 +@@ -150,8 +150,8 @@ static uint32_t do_plt_call (void *locat
11033 + tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
11034 +
11035 + /* Init, or core PLT? */
11036 +- if (location >= mod->module_core
11037 +- && location < mod->module_core + mod->core_size)
11038 ++ if (location >= mod->module_core_rx
11039 ++ && location < mod->module_core_rx + mod->core_size_rx)
11040 + entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
11041 + else
11042 + entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
11043 +diff -Nurp linux-2.6.23.15/arch/x86_64/ia32/ia32_binfmt.c linux-2.6.23.15-grsec/arch/x86_64/ia32/ia32_binfmt.c
11044 +--- linux-2.6.23.15/arch/x86_64/ia32/ia32_binfmt.c 2007-10-09 21:31:38.000000000 +0100
11045 ++++ linux-2.6.23.15-grsec/arch/x86_64/ia32/ia32_binfmt.c 2008-02-11 10:37:44.000000000 +0000
11046 +@@ -36,12 +36,12 @@
11047 + #define AT_SYSINFO 32
11048 + #define AT_SYSINFO_EHDR 33
11049 +
11050 +-int sysctl_vsyscall32 = 1;
11051 ++int sysctl_vsyscall32;
11052 +
11053 + #undef ARCH_DLINFO
11054 + #define ARCH_DLINFO do { \
11055 + if (sysctl_vsyscall32) { \
11056 +- current->mm->context.vdso = (void *)VSYSCALL32_BASE; \
11057 ++ current->mm->context.vdso = VSYSCALL32_BASE; \
11058 + NEW_AUX_ENT(AT_SYSINFO, (u32)(u64)VSYSCALL32_VSYSCALL); \
11059 + NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL32_BASE); \
11060 + } \
11061 +@@ -145,6 +145,13 @@ struct elf_prpsinfo
11062 + //#include <asm/ia32.h>
11063 + #include <linux/elf.h>
11064 +
11065 ++#ifdef CONFIG_PAX_ASLR
11066 ++#define PAX_ELF_ET_DYN_BASE 0x08048000UL
11067 ++
11068 ++#define PAX_DELTA_MMAP_LEN 16
11069 ++#define PAX_DELTA_STACK_LEN 16
11070 ++#endif
11071 ++
11072 + typedef struct user_i387_ia32_struct elf_fpregset_t;
11073 + typedef struct user32_fxsr_struct elf_fpxregset_t;
11074 +
11075 +@@ -298,7 +305,7 @@ static ctl_table abi_table2[] = {
11076 + .mode = 0644,
11077 + .proc_handler = proc_dointvec
11078 + },
11079 +- {}
11080 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
11081 + };
11082 +
11083 + static ctl_table abi_root_table2[] = {
11084 +@@ -308,7 +315,7 @@ static ctl_table abi_root_table2[] = {
11085 + .mode = 0555,
11086 + .child = abi_table2
11087 + },
11088 +- {}
11089 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
11090 + };
11091 +
11092 + static __init int ia32_binfmt_init(void)
11093 +diff -Nurp linux-2.6.23.15/arch/x86_64/ia32/ia32_signal.c linux-2.6.23.15-grsec/arch/x86_64/ia32/ia32_signal.c
11094 +--- linux-2.6.23.15/arch/x86_64/ia32/ia32_signal.c 2007-10-09 21:31:38.000000000 +0100
11095 ++++ linux-2.6.23.15-grsec/arch/x86_64/ia32/ia32_signal.c 2008-02-11 10:37:44.000000000 +0000
11096 +@@ -573,6 +573,7 @@ int ia32_setup_rt_frame(int sig, struct
11097 + __NR_ia32_rt_sigreturn,
11098 + 0x80cd,
11099 + 0,
11100 ++ 0
11101 + };
11102 + err |= __copy_to_user(frame->retcode, &code, 8);
11103 + }
11104 +diff -Nurp linux-2.6.23.15/arch/x86_64/ia32/mmap32.c linux-2.6.23.15-grsec/arch/x86_64/ia32/mmap32.c
11105 +--- linux-2.6.23.15/arch/x86_64/ia32/mmap32.c 2007-10-09 21:31:38.000000000 +0100
11106 ++++ linux-2.6.23.15-grsec/arch/x86_64/ia32/mmap32.c 2008-02-11 10:37:44.000000000 +0000
11107 +@@ -69,10 +69,22 @@ void ia32_pick_mmap_layout(struct mm_str
11108 + (current->personality & ADDR_COMPAT_LAYOUT) ||
11109 + current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
11110 + mm->mmap_base = TASK_UNMAPPED_BASE;
11111 ++
11112 ++#ifdef CONFIG_PAX_RANDMMAP
11113 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
11114 ++ mm->mmap_base += mm->delta_mmap;
11115 ++#endif
11116 ++
11117 + mm->get_unmapped_area = arch_get_unmapped_area;
11118 + mm->unmap_area = arch_unmap_area;
11119 + } else {
11120 + mm->mmap_base = mmap_base(mm);
11121 ++
11122 ++#ifdef CONFIG_PAX_RANDMMAP
11123 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
11124 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
11125 ++#endif
11126 ++
11127 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
11128 + mm->unmap_area = arch_unmap_area_topdown;
11129 + }
11130 +diff -Nurp linux-2.6.23.15/arch/x86_64/ia32/ptrace32.c linux-2.6.23.15-grsec/arch/x86_64/ia32/ptrace32.c
11131 +--- linux-2.6.23.15/arch/x86_64/ia32/ptrace32.c 2007-10-09 21:31:38.000000000 +0100
11132 ++++ linux-2.6.23.15-grsec/arch/x86_64/ia32/ptrace32.c 2008-02-11 10:37:44.000000000 +0000
11133 +@@ -382,7 +382,7 @@ asmlinkage long sys32_ptrace(long reques
11134 + /* no checking to be bug-to-bug compatible with i386. */
11135 + /* but silence warning */
11136 + if (__copy_from_user(&child->thread.i387.fxsave, u, sizeof(*u)))
11137 +- ;
11138 ++ {}
11139 + set_stopped_child_used_math(child);
11140 + child->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
11141 + ret = 0;
11142 +diff -Nurp linux-2.6.23.15/arch/x86_64/ia32/syscall32.c linux-2.6.23.15-grsec/arch/x86_64/ia32/syscall32.c
11143 +--- linux-2.6.23.15/arch/x86_64/ia32/syscall32.c 2007-10-09 21:31:38.000000000 +0100
11144 ++++ linux-2.6.23.15-grsec/arch/x86_64/ia32/syscall32.c 2008-02-11 10:37:44.000000000 +0000
11145 +@@ -30,6 +30,9 @@ int syscall32_setup_pages(struct linux_b
11146 + struct mm_struct *mm = current->mm;
11147 + int ret;
11148 +
11149 ++ if (!sysctl_vsyscall32)
11150 ++ return 0;
11151 ++
11152 + down_write(&mm->mmap_sem);
11153 + /*
11154 + * MAYWRITE to allow gdb to COW and set breakpoints
11155 +diff -Nurp linux-2.6.23.15/arch/x86_64/kernel/hpet.c linux-2.6.23.15-grsec/arch/x86_64/kernel/hpet.c
11156 +--- linux-2.6.23.15/arch/x86_64/kernel/hpet.c 2007-10-09 21:31:38.000000000 +0100
11157 ++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/hpet.c 2008-02-11 10:37:44.000000000 +0000
11158 +@@ -65,7 +65,7 @@ static __init int late_hpet_init(void)
11159 + hpet = (struct hpet *) fix_to_virt(FIX_HPET_BASE);
11160 + timer = &hpet->hpet_timers[2];
11161 + for (i = 2; i < ntimer; timer++, i++)
11162 +- hd.hd_irq[i] = (timer->hpet_config &
11163 ++ hd.hd_irq[i] = (readl(&timer->hpet_config) &
11164 + Tn_INT_ROUTE_CNF_MASK) >>
11165 + Tn_INT_ROUTE_CNF_SHIFT;
11166 +
11167 +diff -Nurp linux-2.6.23.15/arch/x86_64/kernel/i8259.c linux-2.6.23.15-grsec/arch/x86_64/kernel/i8259.c
11168 +--- linux-2.6.23.15/arch/x86_64/kernel/i8259.c 2007-10-09 21:31:38.000000000 +0100
11169 ++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/i8259.c 2008-02-11 10:37:44.000000000 +0000
11170 +@@ -395,7 +395,7 @@ device_initcall(i8259A_init_sysfs);
11171 + * IRQ2 is cascade interrupt to second interrupt controller
11172 + */
11173 +
11174 +-static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL};
11175 ++static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL, 0, NULL};
11176 + DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
11177 + [0 ... IRQ0_VECTOR - 1] = -1,
11178 + [IRQ0_VECTOR] = 0,
11179 +diff -Nurp linux-2.6.23.15/arch/x86_64/kernel/ioport.c linux-2.6.23.15-grsec/arch/x86_64/kernel/ioport.c
11180 +--- linux-2.6.23.15/arch/x86_64/kernel/ioport.c 2007-10-09 21:31:38.000000000 +0100
11181 ++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/ioport.c 2008-02-11 10:37:44.000000000 +0000
11182 +@@ -16,6 +16,7 @@
11183 + #include <linux/slab.h>
11184 + #include <linux/thread_info.h>
11185 + #include <linux/syscalls.h>
11186 ++#include <linux/grsecurity.h>
11187 +
11188 + /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
11189 + static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
11190 +@@ -41,8 +42,16 @@ asmlinkage long sys_ioperm(unsigned long
11191 +
11192 + if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
11193 + return -EINVAL;
11194 ++
11195 ++#ifdef CONFIG_GRKERNSEC_IO
11196 ++ if (turn_on) {
11197 ++ gr_handle_ioperm();
11198 ++ return -EPERM;
11199 ++ }
11200 ++#else
11201 + if (turn_on && !capable(CAP_SYS_RAWIO))
11202 + return -EPERM;
11203 ++#endif
11204 +
11205 + /*
11206 + * If it's the first ioperm() call in this thread's lifetime, set the
11207 +@@ -111,8 +120,13 @@ asmlinkage long sys_iopl(unsigned int le
11208 + return -EINVAL;
11209 + /* Trying to gain more privileges? */
11210 + if (level > old) {
11211 ++#ifdef CONFIG_GRKERNSEC_IO
11212 ++ gr_handle_iopl();
11213 ++ return -EPERM;
11214 ++#else
11215 + if (!capable(CAP_SYS_RAWIO))
11216 + return -EPERM;
11217 ++#endif
11218 + }
11219 + regs->eflags = (regs->eflags &~ X86_EFLAGS_IOPL) | (level << 12);
11220 + return 0;
11221 +diff -Nurp linux-2.6.23.15/arch/x86_64/kernel/mce.c linux-2.6.23.15-grsec/arch/x86_64/kernel/mce.c
11222 +--- linux-2.6.23.15/arch/x86_64/kernel/mce.c 2007-10-09 21:31:38.000000000 +0100
11223 ++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/mce.c 2008-02-11 10:37:44.000000000 +0000
11224 +@@ -665,6 +665,7 @@ static struct miscdevice mce_log_device
11225 + MISC_MCELOG_MINOR,
11226 + "mcelog",
11227 + &mce_chrdev_ops,
11228 ++ {NULL, NULL}, NULL, NULL
11229 + };
11230 +
11231 + static unsigned long old_cr4 __initdata;
11232 +diff -Nurp linux-2.6.23.15/arch/x86_64/kernel/process.c linux-2.6.23.15-grsec/arch/x86_64/kernel/process.c
11233 +--- linux-2.6.23.15/arch/x86_64/kernel/process.c 2007-10-09 21:31:38.000000000 +0100
11234 ++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/process.c 2008-02-11 10:37:44.000000000 +0000
11235 +@@ -894,10 +894,3 @@ int dump_task_regs(struct task_struct *t
11236 +
11237 + return 1;
11238 + }
11239 +-
11240 +-unsigned long arch_align_stack(unsigned long sp)
11241 +-{
11242 +- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
11243 +- sp -= get_random_int() % 8192;
11244 +- return sp & ~0xf;
11245 +-}
11246 +diff -Nurp linux-2.6.23.15/arch/x86_64/kernel/setup64.c linux-2.6.23.15-grsec/arch/x86_64/kernel/setup64.c
11247 +--- linux-2.6.23.15/arch/x86_64/kernel/setup64.c 2007-10-09 21:31:38.000000000 +0100
11248 ++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/setup64.c 2008-02-11 10:37:44.000000000 +0000
11249 +@@ -37,7 +37,7 @@ struct desc_ptr idt_descr = { 256 * 16 -
11250 + char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
11251 +
11252 + unsigned long __supported_pte_mask __read_mostly = ~0UL;
11253 +-static int do_not_nx __cpuinitdata = 0;
11254 ++EXPORT_SYMBOL(__supported_pte_mask);
11255 +
11256 + /* noexec=on|off
11257 + Control non executable mappings for 64bit processes.
11258 +@@ -51,16 +51,14 @@ static int __init nonx_setup(char *str)
11259 + return -EINVAL;
11260 + if (!strncmp(str, "on", 2)) {
11261 + __supported_pte_mask |= _PAGE_NX;
11262 +- do_not_nx = 0;
11263 + } else if (!strncmp(str, "off", 3)) {
11264 +- do_not_nx = 1;
11265 + __supported_pte_mask &= ~_PAGE_NX;
11266 + }
11267 + return 0;
11268 + }
11269 + early_param("noexec", nonx_setup);
11270 +
11271 +-int force_personality32 = 0;
11272 ++int force_personality32;
11273 +
11274 + /* noexec32=on|off
11275 + Control non executable heap for 32bit processes.
11276 +@@ -177,7 +175,7 @@ void __cpuinit check_efer(void)
11277 + unsigned long efer;
11278 +
11279 + rdmsrl(MSR_EFER, efer);
11280 +- if (!(efer & EFER_NX) || do_not_nx) {
11281 ++ if (!(efer & EFER_NX)) {
11282 + __supported_pte_mask &= ~_PAGE_NX;
11283 + }
11284 + }
11285 +diff -Nurp linux-2.6.23.15/arch/x86_64/kernel/signal.c linux-2.6.23.15-grsec/arch/x86_64/kernel/signal.c
11286 +--- linux-2.6.23.15/arch/x86_64/kernel/signal.c 2007-10-09 21:31:38.000000000 +0100
11287 ++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/signal.c 2008-02-11 10:37:44.000000000 +0000
11288 +@@ -254,8 +254,8 @@ static int setup_rt_frame(int sig, struc
11289 + err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
11290 + err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
11291 + if (sizeof(*set) == 16) {
11292 +- __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
11293 +- __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
11294 ++ err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
11295 ++ err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
11296 + } else
11297 + err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
11298 +
11299 +diff -Nurp linux-2.6.23.15/arch/x86_64/kernel/sys_x86_64.c linux-2.6.23.15-grsec/arch/x86_64/kernel/sys_x86_64.c
11300 +--- linux-2.6.23.15/arch/x86_64/kernel/sys_x86_64.c 2007-10-09 21:31:38.000000000 +0100
11301 ++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/sys_x86_64.c 2008-02-11 10:37:44.000000000 +0000
11302 +@@ -65,8 +65,8 @@ out:
11303 + return error;
11304 + }
11305 +
11306 +-static void find_start_end(unsigned long flags, unsigned long *begin,
11307 +- unsigned long *end)
11308 ++static void find_start_end(struct mm_struct *mm, unsigned long flags,
11309 ++ unsigned long *begin, unsigned long *end)
11310 + {
11311 + if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
11312 + /* This is usually used needed to map code in small
11313 +@@ -79,7 +79,7 @@ static void find_start_end(unsigned long
11314 + *begin = 0x40000000;
11315 + *end = 0x80000000;
11316 + } else {
11317 +- *begin = TASK_UNMAPPED_BASE;
11318 ++ *begin = mm->mmap_base;
11319 + *end = TASK_SIZE;
11320 + }
11321 + }
11322 +@@ -96,11 +96,15 @@ arch_get_unmapped_area(struct file *filp
11323 + if (flags & MAP_FIXED)
11324 + return addr;
11325 +
11326 +- find_start_end(flags, &begin, &end);
11327 ++ find_start_end(mm, flags, &begin, &end);
11328 +
11329 + if (len > end)
11330 + return -ENOMEM;
11331 +
11332 ++#ifdef CONFIG_PAX_RANDMMAP
11333 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
11334 ++#endif
11335 ++
11336 + if (addr) {
11337 + addr = PAGE_ALIGN(addr);
11338 + vma = find_vma(mm, addr);
11339 +diff -Nurp linux-2.6.23.15/arch/x86_64/kernel/vsyscall.c linux-2.6.23.15-grsec/arch/x86_64/kernel/vsyscall.c
11340 +--- linux-2.6.23.15/arch/x86_64/kernel/vsyscall.c 2007-10-09 21:31:38.000000000 +0100
11341 ++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/vsyscall.c 2008-02-11 10:37:44.000000000 +0000
11342 +@@ -273,13 +273,13 @@ static ctl_table kernel_table2[] = {
11343 + .mode = 0644,
11344 + .strategy = vsyscall_sysctl_nostrat,
11345 + .proc_handler = vsyscall_sysctl_change },
11346 +- {}
11347 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
11348 + };
11349 +
11350 + static ctl_table kernel_root_table2[] = {
11351 + { .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555,
11352 + .child = kernel_table2 },
11353 +- {}
11354 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
11355 + };
11356 +
11357 + #endif
11358 +diff -Nurp linux-2.6.23.15/arch/x86_64/mm/fault.c linux-2.6.23.15-grsec/arch/x86_64/mm/fault.c
11359 +--- linux-2.6.23.15/arch/x86_64/mm/fault.c 2007-10-09 21:31:38.000000000 +0100
11360 ++++ linux-2.6.23.15-grsec/arch/x86_64/mm/fault.c 2008-02-11 10:37:44.000000000 +0000
11361 +@@ -25,6 +25,7 @@
11362 + #include <linux/kprobes.h>
11363 + #include <linux/uaccess.h>
11364 + #include <linux/kdebug.h>
11365 ++#include <linux/binfmts.h>
11366 +
11367 + #include <asm/system.h>
11368 + #include <asm/pgalloc.h>
11369 +@@ -291,6 +292,163 @@ static int vmalloc_fault(unsigned long a
11370 + return 0;
11371 + }
11372 +
11373 ++#ifdef CONFIG_PAX_EMUTRAMP
11374 ++static int pax_handle_fetch_fault_32(struct pt_regs *regs)
11375 ++{
11376 ++ int err;
11377 ++
11378 ++ do { /* PaX: gcc trampoline emulation #1 */
11379 ++ unsigned char mov1, mov2;
11380 ++ unsigned short jmp;
11381 ++ unsigned int addr1, addr2;
11382 ++
11383 ++ if ((regs->rip + 11) >> 32)
11384 ++ break;
11385 ++
11386 ++ err = get_user(mov1, (unsigned char __user *)regs->rip);
11387 ++ err |= get_user(addr1, (unsigned int __user *)(regs->rip + 1));
11388 ++ err |= get_user(mov2, (unsigned char __user *)(regs->rip + 5));
11389 ++ err |= get_user(addr2, (unsigned int __user *)(regs->rip + 6));
11390 ++ err |= get_user(jmp, (unsigned short __user *)(regs->rip + 10));
11391 ++
11392 ++ if (err)
11393 ++ break;
11394 ++
11395 ++ if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
11396 ++ regs->rcx = addr1;
11397 ++ regs->rax = addr2;
11398 ++ regs->rip = addr2;
11399 ++ return 2;
11400 ++ }
11401 ++ } while (0);
11402 ++
11403 ++ do { /* PaX: gcc trampoline emulation #2 */
11404 ++ unsigned char mov, jmp;
11405 ++ unsigned int addr1, addr2;
11406 ++
11407 ++ if ((regs->rip + 9) >> 32)
11408 ++ break;
11409 ++
11410 ++ err = get_user(mov, (unsigned char __user *)regs->rip);
11411 ++ err |= get_user(addr1, (unsigned int __user *)(regs->rip + 1));
11412 ++ err |= get_user(jmp, (unsigned char __user *)(regs->rip + 5));
11413 ++ err |= get_user(addr2, (unsigned int __user *)(regs->rip + 6));
11414 ++
11415 ++ if (err)
11416 ++ break;
11417 ++
11418 ++ if (mov == 0xB9 && jmp == 0xE9) {
11419 ++ regs->rcx = addr1;
11420 ++ regs->rip = (unsigned int)(regs->rip + addr2 + 10);
11421 ++ return 2;
11422 ++ }
11423 ++ } while (0);
11424 ++
11425 ++ return 1; /* PaX in action */
11426 ++}
11427 ++
11428 ++static int pax_handle_fetch_fault_64(struct pt_regs *regs)
11429 ++{
11430 ++ int err;
11431 ++
11432 ++ do { /* PaX: gcc trampoline emulation #1 */
11433 ++ unsigned short mov1, mov2, jmp1;
11434 ++ unsigned char jmp2;
11435 ++ unsigned int addr1;
11436 ++ unsigned long addr2;
11437 ++
11438 ++ err = get_user(mov1, (unsigned short __user *)regs->rip);
11439 ++ err |= get_user(addr1, (unsigned int __user *)(regs->rip + 2));
11440 ++ err |= get_user(mov2, (unsigned short __user *)(regs->rip + 6));
11441 ++ err |= get_user(addr2, (unsigned long __user *)(regs->rip + 8));
11442 ++ err |= get_user(jmp1, (unsigned short __user *)(regs->rip + 16));
11443 ++ err |= get_user(jmp2, (unsigned char __user *)(regs->rip + 18));
11444 ++
11445 ++ if (err)
11446 ++ break;
11447 ++
11448 ++ if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
11449 ++ regs->r11 = addr1;
11450 ++ regs->r10 = addr2;
11451 ++ regs->rip = addr1;
11452 ++ return 2;
11453 ++ }
11454 ++ } while (0);
11455 ++
11456 ++ do { /* PaX: gcc trampoline emulation #2 */
11457 ++ unsigned short mov1, mov2, jmp1;
11458 ++ unsigned char jmp2;
11459 ++ unsigned long addr1, addr2;
11460 ++
11461 ++ err = get_user(mov1, (unsigned short __user *)regs->rip);
11462 ++ err |= get_user(addr1, (unsigned long __user *)(regs->rip + 2));
11463 ++ err |= get_user(mov2, (unsigned short __user *)(regs->rip + 10));
11464 ++ err |= get_user(addr2, (unsigned long __user *)(regs->rip + 12));
11465 ++ err |= get_user(jmp1, (unsigned short __user *)(regs->rip + 20));
11466 ++ err |= get_user(jmp2, (unsigned char __user *)(regs->rip + 22));
11467 ++
11468 ++ if (err)
11469 ++ break;
11470 ++
11471 ++ if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
11472 ++ regs->r11 = addr1;
11473 ++ regs->r10 = addr2;
11474 ++ regs->rip = addr1;
11475 ++ return 2;
11476 ++ }
11477 ++ } while (0);
11478 ++
11479 ++ return 1; /* PaX in action */
11480 ++}
11481 ++
11482 ++/*
11483 ++ * PaX: decide what to do with offenders (regs->rip = fault address)
11484 ++ *
11485 ++ * returns 1 when task should be killed
11486 ++ * 2 when gcc trampoline was detected
11487 ++ */
11488 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
11489 ++{
11490 ++ if (regs->eflags & X86_EFLAGS_VM)
11491 ++ return 1;
11492 ++
11493 ++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
11494 ++ return 1;
11495 ++
11496 ++ if (regs->cs == __USER32_CS || (regs->cs & (1<<2)))
11497 ++ return pax_handle_fetch_fault_32(regs);
11498 ++ else
11499 ++ return pax_handle_fetch_fault_64(regs);
11500 ++}
11501 ++#endif
11502 ++
11503 ++#ifdef CONFIG_PAX_PAGEEXEC
11504 ++void pax_report_insns(void *pc, void *sp)
11505 ++{
11506 ++ long i;
11507 ++
11508 ++ printk(KERN_ERR "PAX: bytes at PC: ");
11509 ++ for (i = 0; i < 20; i++) {
11510 ++ unsigned char c;
11511 ++ if (get_user(c, (unsigned char __user *)pc+i))
11512 ++ printk("?? ");
11513 ++ else
11514 ++ printk("%02x ", c);
11515 ++ }
11516 ++ printk("\n");
11517 ++
11518 ++ printk(KERN_ERR "PAX: bytes at SP-8: ");
11519 ++ for (i = -1; i < 10; i++) {
11520 ++ unsigned long c;
11521 ++ if (get_user(c, (unsigned long __user *)sp+i))
11522 ++ printk("???????????????? ");
11523 ++ else
11524 ++ printk("%016lx ", c);
11525 ++ }
11526 ++ printk("\n");
11527 ++}
11528 ++#endif
11529 ++
11530 + static int page_fault_trace;
11531 + int show_unhandled_signals = 1;
11532 +
11533 +@@ -427,6 +585,8 @@ asmlinkage void __kprobes do_page_fault(
11534 + good_area:
11535 + info.si_code = SEGV_ACCERR;
11536 + write = 0;
11537 ++ if ((error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
11538 ++ goto bad_area;
11539 + switch (error_code & (PF_PROT|PF_WRITE)) {
11540 + default: /* 3: write, present */
11541 + /* fall through */
11542 +@@ -478,6 +638,21 @@ bad_area_nosemaphore:
11543 + */
11544 + local_irq_enable();
11545 +
11546 ++#ifdef CONFIG_PAX_PAGEEXEC
11547 ++ if (mm && (mm->pax_flags & MF_PAX_PAGEEXEC) && (error_code & 16)) {
11548 ++
11549 ++#ifdef CONFIG_PAX_EMUTRAMP
11550 ++ switch (pax_handle_fetch_fault(regs)) {
11551 ++ case 2:
11552 ++ return;
11553 ++ }
11554 ++#endif
11555 ++
11556 ++ pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp);
11557 ++ do_exit(SIGKILL);
11558 ++ }
11559 ++#endif
11560 ++
11561 + if (is_prefetch(regs, address, error_code))
11562 + return;
11563 +
11564 +@@ -499,7 +674,7 @@ bad_area_nosemaphore:
11565 + tsk->comm, tsk->pid, address, regs->rip,
11566 + regs->rsp, error_code);
11567 + }
11568 +-
11569 ++
11570 + tsk->thread.cr2 = address;
11571 + /* Kernel addresses are always protection faults */
11572 + tsk->thread.error_code = error_code | (address >= TASK_SIZE);
11573 +diff -Nurp linux-2.6.23.15/arch/x86_64/mm/init.c linux-2.6.23.15-grsec/arch/x86_64/mm/init.c
11574 +--- linux-2.6.23.15/arch/x86_64/mm/init.c 2008-02-11 10:36:03.000000000 +0000
11575 ++++ linux-2.6.23.15-grsec/arch/x86_64/mm/init.c 2008-02-11 10:37:44.000000000 +0000
11576 +@@ -45,7 +45,7 @@
11577 + #include <asm/sections.h>
11578 +
11579 + #ifndef Dprintk
11580 +-#define Dprintk(x...)
11581 ++#define Dprintk(x...) do {} while (0)
11582 + #endif
11583 +
11584 + const struct dma_mapping_ops* dma_ops;
11585 +@@ -736,7 +736,7 @@ int in_gate_area_no_task(unsigned long a
11586 +
11587 + const char *arch_vma_name(struct vm_area_struct *vma)
11588 + {
11589 +- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
11590 ++ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
11591 + return "[vdso]";
11592 + if (vma == &gate_vma)
11593 + return "[vsyscall]";
11594 +diff -Nurp linux-2.6.23.15/arch/x86_64/mm/mmap.c linux-2.6.23.15-grsec/arch/x86_64/mm/mmap.c
11595 +--- linux-2.6.23.15/arch/x86_64/mm/mmap.c 2007-10-09 21:31:38.000000000 +0100
11596 ++++ linux-2.6.23.15-grsec/arch/x86_64/mm/mmap.c 2008-02-11 10:37:44.000000000 +0000
11597 +@@ -23,6 +23,12 @@ void arch_pick_mmap_layout(struct mm_str
11598 + unsigned rnd = get_random_int() & 0xfffffff;
11599 + mm->mmap_base += ((unsigned long)rnd) << PAGE_SHIFT;
11600 + }
11601 ++
11602 ++#ifdef CONFIG_PAX_RANDMMAP
11603 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
11604 ++ mm->mmap_base += mm->delta_mmap;
11605 ++#endif
11606 ++
11607 + mm->get_unmapped_area = arch_get_unmapped_area;
11608 + mm->unmap_area = arch_unmap_area;
11609 + }
11610 +diff -Nurp linux-2.6.23.15/arch/x86_64/mm/numa.c linux-2.6.23.15-grsec/arch/x86_64/mm/numa.c
11611 +--- linux-2.6.23.15/arch/x86_64/mm/numa.c 2007-10-09 21:31:38.000000000 +0100
11612 ++++ linux-2.6.23.15-grsec/arch/x86_64/mm/numa.c 2008-02-11 10:37:44.000000000 +0000
11613 +@@ -19,7 +19,7 @@
11614 + #include <asm/acpi.h>
11615 +
11616 + #ifndef Dprintk
11617 +-#define Dprintk(x...)
11618 ++#define Dprintk(x...) do {} while (0)
11619 + #endif
11620 +
11621 + struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
11622 +diff -Nurp linux-2.6.23.15/arch/x86_64/vdso/vma.c linux-2.6.23.15-grsec/arch/x86_64/vdso/vma.c
11623 +--- linux-2.6.23.15/arch/x86_64/vdso/vma.c 2007-10-09 21:31:38.000000000 +0100
11624 ++++ linux-2.6.23.15-grsec/arch/x86_64/vdso/vma.c 2008-02-11 10:37:44.000000000 +0000
11625 +@@ -126,7 +126,7 @@ int arch_setup_additional_pages(struct l
11626 + if (ret)
11627 + goto up_fail;
11628 +
11629 +- current->mm->context.vdso = (void *)addr;
11630 ++ current->mm->context.vdso = addr;
11631 + up_fail:
11632 + up_write(&mm->mmap_sem);
11633 + return ret;
11634 +diff -Nurp linux-2.6.23.15/crypto/async_tx/async_tx.c linux-2.6.23.15-grsec/crypto/async_tx/async_tx.c
11635 +--- linux-2.6.23.15/crypto/async_tx/async_tx.c 2007-10-09 21:31:38.000000000 +0100
11636 ++++ linux-2.6.23.15-grsec/crypto/async_tx/async_tx.c 2008-02-11 10:37:44.000000000 +0000
11637 +@@ -342,8 +342,8 @@ async_tx_init(void)
11638 + err:
11639 + printk(KERN_ERR "async_tx: initialization failure\n");
11640 +
11641 +- while (--cap >= 0)
11642 +- free_percpu(channel_table[cap]);
11643 ++ while (cap)
11644 ++ free_percpu(channel_table[--cap]);
11645 +
11646 + return 1;
11647 + }
11648 +diff -Nurp linux-2.6.23.15/crypto/lrw.c linux-2.6.23.15-grsec/crypto/lrw.c
11649 +--- linux-2.6.23.15/crypto/lrw.c 2007-10-09 21:31:38.000000000 +0100
11650 ++++ linux-2.6.23.15-grsec/crypto/lrw.c 2008-02-11 10:37:44.000000000 +0000
11651 +@@ -54,7 +54,7 @@ static int setkey(struct crypto_tfm *par
11652 + struct priv *ctx = crypto_tfm_ctx(parent);
11653 + struct crypto_cipher *child = ctx->child;
11654 + int err, i;
11655 +- be128 tmp = { 0 };
11656 ++ be128 tmp = { 0, 0 };
11657 + int bsize = crypto_cipher_blocksize(child);
11658 +
11659 + crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
11660 +diff -Nurp linux-2.6.23.15/drivers/acpi/blacklist.c linux-2.6.23.15-grsec/drivers/acpi/blacklist.c
11661 +--- linux-2.6.23.15/drivers/acpi/blacklist.c 2008-02-11 10:36:03.000000000 +0000
11662 ++++ linux-2.6.23.15-grsec/drivers/acpi/blacklist.c 2008-02-11 10:37:44.000000000 +0000
11663 +@@ -71,7 +71,7 @@ static struct acpi_blacklist_item acpi_b
11664 + {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
11665 + "Incorrect _ADR", 1},
11666 +
11667 +- {""}
11668 ++ {"", "", 0, 0, 0, all_versions, 0}
11669 + };
11670 +
11671 + #if CONFIG_ACPI_BLACKLIST_YEAR
11672 +diff -Nurp linux-2.6.23.15/drivers/acpi/processor_core.c linux-2.6.23.15-grsec/drivers/acpi/processor_core.c
11673 +--- linux-2.6.23.15/drivers/acpi/processor_core.c 2007-10-09 21:31:38.000000000 +0100
11674 ++++ linux-2.6.23.15-grsec/drivers/acpi/processor_core.c 2008-02-11 10:37:44.000000000 +0000
11675 +@@ -643,7 +643,7 @@ static int __cpuinit acpi_processor_star
11676 + return 0;
11677 + }
11678 +
11679 +- BUG_ON((pr->id >= NR_CPUS) || (pr->id < 0));
11680 ++ BUG_ON(pr->id >= NR_CPUS);
11681 +
11682 + /*
11683 + * Buggy BIOS check
11684 +diff -Nurp linux-2.6.23.15/drivers/acpi/processor_idle.c linux-2.6.23.15-grsec/drivers/acpi/processor_idle.c
11685 +--- linux-2.6.23.15/drivers/acpi/processor_idle.c 2007-10-09 21:31:38.000000000 +0100
11686 ++++ linux-2.6.23.15-grsec/drivers/acpi/processor_idle.c 2008-02-11 10:37:44.000000000 +0000
11687 +@@ -164,7 +164,7 @@ static struct dmi_system_id __cpuinitdat
11688 + DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
11689 + DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
11690 + (void *)2},
11691 +- {},
11692 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
11693 + };
11694 +
11695 + static inline u32 ticks_elapsed(u32 t1, u32 t2)
11696 +diff -Nurp linux-2.6.23.15/drivers/acpi/sleep/main.c linux-2.6.23.15-grsec/drivers/acpi/sleep/main.c
11697 +--- linux-2.6.23.15/drivers/acpi/sleep/main.c 2008-02-11 10:36:03.000000000 +0000
11698 ++++ linux-2.6.23.15-grsec/drivers/acpi/sleep/main.c 2008-02-11 10:37:44.000000000 +0000
11699 +@@ -228,7 +228,7 @@ static struct dmi_system_id __initdata a
11700 + .ident = "Toshiba Satellite 4030cdt",
11701 + .matches = {DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),},
11702 + },
11703 +- {},
11704 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
11705 + };
11706 + #endif /* CONFIG_SUSPEND */
11707 +
11708 +diff -Nurp linux-2.6.23.15/drivers/acpi/tables/tbfadt.c linux-2.6.23.15-grsec/drivers/acpi/tables/tbfadt.c
11709 +--- linux-2.6.23.15/drivers/acpi/tables/tbfadt.c 2007-10-09 21:31:38.000000000 +0100
11710 ++++ linux-2.6.23.15-grsec/drivers/acpi/tables/tbfadt.c 2008-02-11 10:37:44.000000000 +0000
11711 +@@ -48,7 +48,7 @@
11712 + ACPI_MODULE_NAME("tbfadt")
11713 +
11714 + /* Local prototypes */
11715 +-static void inline
11716 ++static inline void
11717 + acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
11718 + u8 bit_width, u64 address);
11719 +
11720 +@@ -122,7 +122,7 @@ static struct acpi_fadt_info fadt_info_t
11721 + *
11722 + ******************************************************************************/
11723 +
11724 +-static void inline
11725 ++static inline void
11726 + acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
11727 + u8 bit_width, u64 address)
11728 + {
11729 +diff -Nurp linux-2.6.23.15/drivers/ata/ahci.c linux-2.6.23.15-grsec/drivers/ata/ahci.c
11730 +--- linux-2.6.23.15/drivers/ata/ahci.c 2008-02-11 10:36:03.000000000 +0000
11731 ++++ linux-2.6.23.15-grsec/drivers/ata/ahci.c 2008-02-11 10:37:44.000000000 +0000
11732 +@@ -523,7 +523,7 @@ static const struct pci_device_id ahci_p
11733 + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
11734 + PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
11735 +
11736 +- { } /* terminate list */
11737 ++ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
11738 + };
11739 +
11740 +
11741 +diff -Nurp linux-2.6.23.15/drivers/ata/ata_piix.c linux-2.6.23.15-grsec/drivers/ata/ata_piix.c
11742 +--- linux-2.6.23.15/drivers/ata/ata_piix.c 2007-10-09 21:31:38.000000000 +0100
11743 ++++ linux-2.6.23.15-grsec/drivers/ata/ata_piix.c 2008-02-11 10:37:44.000000000 +0000
11744 +@@ -257,7 +257,7 @@ static const struct pci_device_id piix_p
11745 + /* SATA Controller IDE (Tolapai) */
11746 + { 0x8086, 0x5028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, tolapai_sata_ahci },
11747 +
11748 +- { } /* terminate list */
11749 ++ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
11750 + };
11751 +
11752 + static struct pci_driver piix_pci_driver = {
11753 +@@ -617,7 +617,7 @@ static const struct ich_laptop ich_lapto
11754 + { 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */
11755 + { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */
11756 + /* end marker */
11757 +- { 0, }
11758 ++ { 0, 0, 0 }
11759 + };
11760 +
11761 + /**
11762 +@@ -963,7 +963,7 @@ static int piix_broken_suspend(void)
11763 + },
11764 + },
11765 +
11766 +- { } /* terminate list */
11767 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } /* terminate list */
11768 + };
11769 + static const char *oemstrs[] = {
11770 + "Tecra M3,",
11771 +diff -Nurp linux-2.6.23.15/drivers/ata/libata-core.c linux-2.6.23.15-grsec/drivers/ata/libata-core.c
11772 +--- linux-2.6.23.15/drivers/ata/libata-core.c 2008-02-11 10:36:03.000000000 +0000
11773 ++++ linux-2.6.23.15-grsec/drivers/ata/libata-core.c 2008-02-11 10:37:44.000000000 +0000
11774 +@@ -472,7 +472,7 @@ static const struct ata_xfer_ent {
11775 + { ATA_SHIFT_PIO, ATA_BITS_PIO, XFER_PIO_0 },
11776 + { ATA_SHIFT_MWDMA, ATA_BITS_MWDMA, XFER_MW_DMA_0 },
11777 + { ATA_SHIFT_UDMA, ATA_BITS_UDMA, XFER_UDMA_0 },
11778 +- { -1, },
11779 ++ { -1, 0, 0 },
11780 + };
11781 +
11782 + /**
11783 +@@ -2546,7 +2546,7 @@ static const struct ata_timing ata_timin
11784 +
11785 + /* { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960, 0 }, */
11786 +
11787 +- { 0xFF }
11788 ++ { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
11789 + };
11790 +
11791 + #define ENOUGH(v,unit) (((v)-1)/(unit)+1)
11792 +@@ -3799,7 +3799,7 @@ static const struct ata_blacklist_entry
11793 + { "MAXTOR 6L080L4", "A93.0500", ATA_HORKAGE_BROKEN_HPA },
11794 +
11795 + /* End Marker */
11796 +- { }
11797 ++ { NULL, NULL, 0 }
11798 + };
11799 +
11800 + static unsigned long ata_dev_blacklisted(const struct ata_device *dev)
11801 +diff -Nurp linux-2.6.23.15/drivers/char/agp/frontend.c linux-2.6.23.15-grsec/drivers/char/agp/frontend.c
11802 +--- linux-2.6.23.15/drivers/char/agp/frontend.c 2007-10-09 21:31:38.000000000 +0100
11803 ++++ linux-2.6.23.15-grsec/drivers/char/agp/frontend.c 2008-02-11 10:37:44.000000000 +0000
11804 +@@ -820,7 +820,7 @@ static int agpioc_reserve_wrap(struct ag
11805 + if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
11806 + return -EFAULT;
11807 +
11808 +- if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
11809 ++ if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
11810 + return -EFAULT;
11811 +
11812 + client = agp_find_client_by_pid(reserve.pid);
11813 +diff -Nurp linux-2.6.23.15/drivers/char/agp/intel-agp.c linux-2.6.23.15-grsec/drivers/char/agp/intel-agp.c
11814 +--- linux-2.6.23.15/drivers/char/agp/intel-agp.c 2007-10-09 21:31:38.000000000 +0100
11815 ++++ linux-2.6.23.15-grsec/drivers/char/agp/intel-agp.c 2008-02-11 10:37:44.000000000 +0000
11816 +@@ -2071,7 +2071,7 @@ static struct pci_device_id agp_intel_pc
11817 + ID(PCI_DEVICE_ID_INTEL_G33_HB),
11818 + ID(PCI_DEVICE_ID_INTEL_Q35_HB),
11819 + ID(PCI_DEVICE_ID_INTEL_Q33_HB),
11820 +- { }
11821 ++ { 0, 0, 0, 0, 0, 0, 0 }
11822 + };
11823 +
11824 + MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
11825 +diff -Nurp linux-2.6.23.15/drivers/char/drm/drm_pciids.h linux-2.6.23.15-grsec/drivers/char/drm/drm_pciids.h
11826 +--- linux-2.6.23.15/drivers/char/drm/drm_pciids.h 2007-10-09 21:31:38.000000000 +0100
11827 ++++ linux-2.6.23.15-grsec/drivers/char/drm/drm_pciids.h 2008-02-11 10:37:44.000000000 +0000
11828 +@@ -251,7 +251,7 @@
11829 + {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
11830 + {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
11831 + {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
11832 +- {0, 0, 0}
11833 ++ {0, 0, 0, 0, 0, 0, 0 }
11834 +
11835 + #define i830_PCI_IDS \
11836 + {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
11837 +diff -Nurp linux-2.6.23.15/drivers/char/hpet.c linux-2.6.23.15-grsec/drivers/char/hpet.c
11838 +--- linux-2.6.23.15/drivers/char/hpet.c 2007-10-09 21:31:38.000000000 +0100
11839 ++++ linux-2.6.23.15-grsec/drivers/char/hpet.c 2008-02-11 10:37:44.000000000 +0000
11840 +@@ -1028,7 +1028,7 @@ static struct acpi_driver hpet_acpi_driv
11841 + },
11842 + };
11843 +
11844 +-static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
11845 ++static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL };
11846 +
11847 + static int __init hpet_init(void)
11848 + {
11849 +diff -Nurp linux-2.6.23.15/drivers/char/keyboard.c linux-2.6.23.15-grsec/drivers/char/keyboard.c
11850 +--- linux-2.6.23.15/drivers/char/keyboard.c 2007-10-09 21:31:38.000000000 +0100
11851 ++++ linux-2.6.23.15-grsec/drivers/char/keyboard.c 2008-02-11 10:37:44.000000000 +0000
11852 +@@ -605,6 +605,16 @@ static void k_spec(struct vc_data *vc, u
11853 + kbd->kbdmode == VC_MEDIUMRAW) &&
11854 + value != KVAL(K_SAK))
11855 + return; /* SAK is allowed even in raw mode */
11856 ++
11857 ++#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
11858 ++ {
11859 ++ void *func = fn_handler[value];
11860 ++ if (func == fn_show_state || func == fn_show_ptregs ||
11861 ++ func == fn_show_mem)
11862 ++ return;
11863 ++ }
11864 ++#endif
11865 ++
11866 + fn_handler[value](vc);
11867 + }
11868 +
11869 +@@ -1340,7 +1350,7 @@ static const struct input_device_id kbd_
11870 + .evbit = { BIT(EV_SND) },
11871 + },
11872 +
11873 +- { }, /* Terminating entry */
11874 ++ { 0 }, /* Terminating entry */
11875 + };
11876 +
11877 + MODULE_DEVICE_TABLE(input, kbd_ids);
11878 +diff -Nurp linux-2.6.23.15/drivers/char/mem.c linux-2.6.23.15-grsec/drivers/char/mem.c
11879 +--- linux-2.6.23.15/drivers/char/mem.c 2007-10-09 21:31:38.000000000 +0100
11880 ++++ linux-2.6.23.15-grsec/drivers/char/mem.c 2008-02-11 10:37:44.000000000 +0000
11881 +@@ -26,6 +26,7 @@
11882 + #include <linux/bootmem.h>
11883 + #include <linux/splice.h>
11884 + #include <linux/pfn.h>
11885 ++#include <linux/grsecurity.h>
11886 +
11887 + #include <asm/uaccess.h>
11888 + #include <asm/io.h>
11889 +@@ -34,6 +35,10 @@
11890 + # include <linux/efi.h>
11891 + #endif
11892 +
11893 ++#ifdef CONFIG_GRKERNSEC
11894 ++extern struct file_operations grsec_fops;
11895 ++#endif
11896 ++
11897 + /*
11898 + * Architectures vary in how they handle caching for addresses
11899 + * outside of main memory.
11900 +@@ -180,6 +185,11 @@ static ssize_t write_mem(struct file * f
11901 + if (!valid_phys_addr_range(p, count))
11902 + return -EFAULT;
11903 +
11904 ++#ifdef CONFIG_GRKERNSEC_KMEM
11905 ++ gr_handle_mem_write();
11906 ++ return -EPERM;
11907 ++#endif
11908 ++
11909 + written = 0;
11910 +
11911 + #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
11912 +@@ -281,6 +291,11 @@ static int mmap_mem(struct file * file,
11913 + if (!private_mapping_ok(vma))
11914 + return -ENOSYS;
11915 +
11916 ++#ifdef CONFIG_GRKERNSEC_KMEM
11917 ++ if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
11918 ++ return -EPERM;
11919 ++#endif
11920 ++
11921 + vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
11922 + size,
11923 + vma->vm_page_prot);
11924 +@@ -512,6 +527,11 @@ static ssize_t write_kmem(struct file *
11925 + ssize_t written;
11926 + char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
11927 +
11928 ++#ifdef CONFIG_GRKERNSEC_KMEM
11929 ++ gr_handle_kmem_write();
11930 ++ return -EPERM;
11931 ++#endif
11932 ++
11933 + if (p < (unsigned long) high_memory) {
11934 +
11935 + wrote = count;
11936 +@@ -635,6 +655,10 @@ static inline size_t read_zero_pagealign
11937 + struct vm_area_struct * vma;
11938 + unsigned long addr=(unsigned long)buf;
11939 +
11940 ++#ifdef CONFIG_PAX_SEGMEXEC
11941 ++ struct vm_area_struct *vma_m;
11942 ++#endif
11943 ++
11944 + mm = current->mm;
11945 + /* Oops, this was forgotten before. -ben */
11946 + down_read(&mm->mmap_sem);
11947 +@@ -651,8 +675,14 @@ static inline size_t read_zero_pagealign
11948 + if (count > size)
11949 + count = size;
11950 +
11951 ++#ifdef CONFIG_PAX_SEGMEXEC
11952 ++ vma_m = pax_find_mirror_vma(vma);
11953 ++ if (vma_m)
11954 ++ zap_page_range(vma_m, addr + SEGMEXEC_TASK_SIZE, count, NULL);
11955 ++#endif
11956 ++
11957 + zap_page_range(vma, addr, count, NULL);
11958 +- if (zeromap_page_range(vma, addr, count, PAGE_COPY))
11959 ++ if (zeromap_page_range(vma, addr, count, vma->vm_page_prot))
11960 + break;
11961 +
11962 + size -= count;
11963 +@@ -805,6 +835,16 @@ static loff_t memory_lseek(struct file *
11964 +
11965 + static int open_port(struct inode * inode, struct file * filp)
11966 + {
11967 ++#ifdef CONFIG_GRKERNSEC_KMEM
11968 ++ gr_handle_open_port();
11969 ++ return -EPERM;
11970 ++#endif
11971 ++
11972 ++ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
11973 ++}
11974 ++
11975 ++static int open_mem(struct inode * inode, struct file * filp)
11976 ++{
11977 + return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
11978 + }
11979 +
11980 +@@ -812,7 +852,6 @@ static int open_port(struct inode * inod
11981 + #define full_lseek null_lseek
11982 + #define write_zero write_null
11983 + #define read_full read_zero
11984 +-#define open_mem open_port
11985 + #define open_kmem open_mem
11986 + #define open_oldmem open_mem
11987 +
11988 +@@ -945,6 +984,11 @@ static int memory_open(struct inode * in
11989 + filp->f_op = &oldmem_fops;
11990 + break;
11991 + #endif
11992 ++#ifdef CONFIG_GRKERNSEC
11993 ++ case 13:
11994 ++ filp->f_op = &grsec_fops;
11995 ++ break;
11996 ++#endif
11997 + default:
11998 + return -ENXIO;
11999 + }
12000 +@@ -977,6 +1021,9 @@ static const struct {
12001 + #ifdef CONFIG_CRASH_DUMP
12002 + {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
12003 + #endif
12004 ++#ifdef CONFIG_GRKERNSEC
12005 ++ {13,"grsec", S_IRUSR | S_IWUGO, &grsec_fops},
12006 ++#endif
12007 + };
12008 +
12009 + static struct class *mem_class;
12010 +diff -Nurp linux-2.6.23.15/drivers/char/nvram.c linux-2.6.23.15-grsec/drivers/char/nvram.c
12011 +--- linux-2.6.23.15/drivers/char/nvram.c 2007-10-09 21:31:38.000000000 +0100
12012 ++++ linux-2.6.23.15-grsec/drivers/char/nvram.c 2008-02-11 10:37:44.000000000 +0000
12013 +@@ -430,7 +430,10 @@ static const struct file_operations nvra
12014 + static struct miscdevice nvram_dev = {
12015 + NVRAM_MINOR,
12016 + "nvram",
12017 +- &nvram_fops
12018 ++ &nvram_fops,
12019 ++ {NULL, NULL},
12020 ++ NULL,
12021 ++ NULL
12022 + };
12023 +
12024 + static int __init
12025 +diff -Nurp linux-2.6.23.15/drivers/char/random.c linux-2.6.23.15-grsec/drivers/char/random.c
12026 +--- linux-2.6.23.15/drivers/char/random.c 2008-02-11 10:36:03.000000000 +0000
12027 ++++ linux-2.6.23.15-grsec/drivers/char/random.c 2008-02-11 10:37:44.000000000 +0000
12028 +@@ -248,8 +248,13 @@
12029 + /*
12030 + * Configuration information
12031 + */
12032 ++#ifdef CONFIG_GRKERNSEC_RANDNET
12033 ++#define INPUT_POOL_WORDS 512
12034 ++#define OUTPUT_POOL_WORDS 128
12035 ++#else
12036 + #define INPUT_POOL_WORDS 128
12037 + #define OUTPUT_POOL_WORDS 32
12038 ++#endif
12039 + #define SEC_XFER_SIZE 512
12040 +
12041 + /*
12042 +@@ -286,10 +291,17 @@ static struct poolinfo {
12043 + int poolwords;
12044 + int tap1, tap2, tap3, tap4, tap5;
12045 + } poolinfo_table[] = {
12046 ++#ifdef CONFIG_GRKERNSEC_RANDNET
12047 ++ /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
12048 ++ { 512, 411, 308, 208, 104, 1 },
12049 ++ /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
12050 ++ { 128, 103, 76, 51, 25, 1 },
12051 ++#else
12052 + /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
12053 + { 128, 103, 76, 51, 25, 1 },
12054 + /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
12055 + { 32, 26, 20, 14, 7, 1 },
12056 ++#endif
12057 + #if 0
12058 + /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
12059 + { 2048, 1638, 1231, 819, 411, 1 },
12060 +@@ -1172,7 +1184,7 @@ EXPORT_SYMBOL(generate_random_uuid);
12061 + #include <linux/sysctl.h>
12062 +
12063 + static int min_read_thresh = 8, min_write_thresh;
12064 +-static int max_read_thresh = INPUT_POOL_WORDS * 32;
12065 ++static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
12066 + static int max_write_thresh = INPUT_POOL_WORDS * 32;
12067 + static char sysctl_bootid[16];
12068 +
12069 +diff -Nurp linux-2.6.23.15/drivers/char/vt_ioctl.c linux-2.6.23.15-grsec/drivers/char/vt_ioctl.c
12070 +--- linux-2.6.23.15/drivers/char/vt_ioctl.c 2007-10-09 21:31:38.000000000 +0100
12071 ++++ linux-2.6.23.15-grsec/drivers/char/vt_ioctl.c 2008-02-11 10:37:44.000000000 +0000
12072 +@@ -95,6 +95,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
12073 + case KDSKBENT:
12074 + if (!perm)
12075 + return -EPERM;
12076 ++
12077 ++#ifdef CONFIG_GRKERNSEC
12078 ++ if (!capable(CAP_SYS_TTY_CONFIG))
12079 ++ return -EPERM;
12080 ++#endif
12081 ++
12082 + if (!i && v == K_NOSUCHMAP) {
12083 + /* deallocate map */
12084 + key_map = key_maps[s];
12085 +@@ -235,6 +241,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry
12086 + goto reterr;
12087 + }
12088 +
12089 ++#ifdef CONFIG_GRKERNSEC
12090 ++ if (!capable(CAP_SYS_TTY_CONFIG)) {
12091 ++ ret = -EPERM;
12092 ++ goto reterr;
12093 ++ }
12094 ++#endif
12095 ++
12096 + q = func_table[i];
12097 + first_free = funcbufptr + (funcbufsize - funcbufleft);
12098 + for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
12099 +diff -Nurp linux-2.6.23.15/drivers/dma/ioatdma.c linux-2.6.23.15-grsec/drivers/dma/ioatdma.c
12100 +--- linux-2.6.23.15/drivers/dma/ioatdma.c 2007-10-09 21:31:38.000000000 +0100
12101 ++++ linux-2.6.23.15-grsec/drivers/dma/ioatdma.c 2008-02-11 10:37:44.000000000 +0000
12102 +@@ -244,7 +244,6 @@ static void ioat_dma_free_chan_resources
12103 + struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
12104 + struct ioat_device *ioat_device = to_ioat_device(chan->device);
12105 + struct ioat_desc_sw *desc, *_desc;
12106 +- u16 chanctrl;
12107 + int in_use_descs = 0;
12108 +
12109 + ioat_dma_memcpy_cleanup(ioat_chan);
12110 +diff -Nurp linux-2.6.23.15/drivers/edac/edac_core.h linux-2.6.23.15-grsec/drivers/edac/edac_core.h
12111 +--- linux-2.6.23.15/drivers/edac/edac_core.h 2007-10-09 21:31:38.000000000 +0100
12112 ++++ linux-2.6.23.15-grsec/drivers/edac/edac_core.h 2008-02-11 10:37:44.000000000 +0000
12113 +@@ -86,11 +86,11 @@ extern int edac_debug_level;
12114 +
12115 + #else /* !CONFIG_EDAC_DEBUG */
12116 +
12117 +-#define debugf0( ... )
12118 +-#define debugf1( ... )
12119 +-#define debugf2( ... )
12120 +-#define debugf3( ... )
12121 +-#define debugf4( ... )
12122 ++#define debugf0( ... ) do {} while (0)
12123 ++#define debugf1( ... ) do {} while (0)
12124 ++#define debugf2( ... ) do {} while (0)
12125 ++#define debugf3( ... ) do {} while (0)
12126 ++#define debugf4( ... ) do {} while (0)
12127 +
12128 + #endif /* !CONFIG_EDAC_DEBUG */
12129 +
12130 +diff -Nurp linux-2.6.23.15/drivers/hwmon/fscpos.c linux-2.6.23.15-grsec/drivers/hwmon/fscpos.c
12131 +--- linux-2.6.23.15/drivers/hwmon/fscpos.c 2007-10-09 21:31:38.000000000 +0100
12132 ++++ linux-2.6.23.15-grsec/drivers/hwmon/fscpos.c 2008-02-11 10:37:44.000000000 +0000
12133 +@@ -231,7 +231,6 @@ static ssize_t set_pwm(struct i2c_client
12134 + unsigned long v = simple_strtoul(buf, NULL, 10);
12135 +
12136 + /* Range: 0..255 */
12137 +- if (v < 0) v = 0;
12138 + if (v > 255) v = 255;
12139 +
12140 + mutex_lock(&data->update_lock);
12141 +diff -Nurp linux-2.6.23.15/drivers/hwmon/k8temp.c linux-2.6.23.15-grsec/drivers/hwmon/k8temp.c
12142 +--- linux-2.6.23.15/drivers/hwmon/k8temp.c 2007-10-09 21:31:38.000000000 +0100
12143 ++++ linux-2.6.23.15-grsec/drivers/hwmon/k8temp.c 2008-02-11 10:37:44.000000000 +0000
12144 +@@ -130,7 +130,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
12145 +
12146 + static struct pci_device_id k8temp_ids[] = {
12147 + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
12148 +- { 0 },
12149 ++ { 0, 0, 0, 0, 0, 0, 0 },
12150 + };
12151 +
12152 + MODULE_DEVICE_TABLE(pci, k8temp_ids);
12153 +diff -Nurp linux-2.6.23.15/drivers/hwmon/sis5595.c linux-2.6.23.15-grsec/drivers/hwmon/sis5595.c
12154 +--- linux-2.6.23.15/drivers/hwmon/sis5595.c 2007-10-09 21:31:38.000000000 +0100
12155 ++++ linux-2.6.23.15-grsec/drivers/hwmon/sis5595.c 2008-02-11 10:37:44.000000000 +0000
12156 +@@ -673,7 +673,7 @@ static struct sis5595_data *sis5595_upda
12157 +
12158 + static struct pci_device_id sis5595_pci_ids[] = {
12159 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
12160 +- { 0, }
12161 ++ { 0, 0, 0, 0, 0, 0, 0 }
12162 + };
12163 +
12164 + MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
12165 +diff -Nurp linux-2.6.23.15/drivers/hwmon/thmc50.c linux-2.6.23.15-grsec/drivers/hwmon/thmc50.c
12166 +--- linux-2.6.23.15/drivers/hwmon/thmc50.c 2007-10-09 21:31:38.000000000 +0100
12167 ++++ linux-2.6.23.15-grsec/drivers/hwmon/thmc50.c 2008-02-11 10:37:44.000000000 +0000
12168 +@@ -47,9 +47,9 @@ I2C_CLIENT_MODULE_PARM(adm1022_temp3, "L
12169 + #define THMC50_REG_DIE_CODE 0x3F
12170 + #define THMC50_REG_ANALOG_OUT 0x19
12171 +
12172 +-const static u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 };
12173 +-const static u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C };
12174 +-const static u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B };
12175 ++static const u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 };
12176 ++static const u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C };
12177 ++static const u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B };
12178 +
12179 + #define THMC50_REG_CONF_nFANOFF 0x20
12180 +
12181 +diff -Nurp linux-2.6.23.15/drivers/hwmon/via686a.c linux-2.6.23.15-grsec/drivers/hwmon/via686a.c
12182 +--- linux-2.6.23.15/drivers/hwmon/via686a.c 2007-10-09 21:31:38.000000000 +0100
12183 ++++ linux-2.6.23.15-grsec/drivers/hwmon/via686a.c 2008-02-11 10:37:44.000000000 +0000
12184 +@@ -740,7 +740,7 @@ static struct via686a_data *via686a_upda
12185 +
12186 + static struct pci_device_id via686a_pci_ids[] = {
12187 + { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
12188 +- { 0, }
12189 ++ { 0, 0, 0, 0, 0, 0, 0 }
12190 + };
12191 +
12192 + MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
12193 +diff -Nurp linux-2.6.23.15/drivers/hwmon/vt8231.c linux-2.6.23.15-grsec/drivers/hwmon/vt8231.c
12194 +--- linux-2.6.23.15/drivers/hwmon/vt8231.c 2007-10-09 21:31:38.000000000 +0100
12195 ++++ linux-2.6.23.15-grsec/drivers/hwmon/vt8231.c 2008-02-11 10:37:44.000000000 +0000
12196 +@@ -662,7 +662,7 @@ static struct platform_driver vt8231_dri
12197 +
12198 + static struct pci_device_id vt8231_pci_ids[] = {
12199 + { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
12200 +- { 0, }
12201 ++ { 0, 0, 0, 0, 0, 0, 0 }
12202 + };
12203 +
12204 + MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
12205 +diff -Nurp linux-2.6.23.15/drivers/hwmon/w83791d.c linux-2.6.23.15-grsec/drivers/hwmon/w83791d.c
12206 +--- linux-2.6.23.15/drivers/hwmon/w83791d.c 2007-10-09 21:31:38.000000000 +0100
12207 ++++ linux-2.6.23.15-grsec/drivers/hwmon/w83791d.c 2008-02-11 10:37:44.000000000 +0000
12208 +@@ -289,8 +289,8 @@ static int w83791d_attach_adapter(struct
12209 + static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind);
12210 + static int w83791d_detach_client(struct i2c_client *client);
12211 +
12212 +-static int w83791d_read(struct i2c_client *client, u8 register);
12213 +-static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
12214 ++static int w83791d_read(struct i2c_client *client, u8 reg);
12215 ++static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
12216 + static struct w83791d_data *w83791d_update_device(struct device *dev);
12217 +
12218 + #ifdef DEBUG
12219 +diff -Nurp linux-2.6.23.15/drivers/i2c/busses/i2c-i801.c linux-2.6.23.15-grsec/drivers/i2c/busses/i2c-i801.c
12220 +--- linux-2.6.23.15/drivers/i2c/busses/i2c-i801.c 2007-10-09 21:31:38.000000000 +0100
12221 ++++ linux-2.6.23.15-grsec/drivers/i2c/busses/i2c-i801.c 2008-02-11 10:37:44.000000000 +0000
12222 +@@ -543,7 +543,7 @@ static struct pci_device_id i801_ids[] =
12223 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) },
12224 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) },
12225 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_6) },
12226 +- { 0, }
12227 ++ { 0, 0, 0, 0, 0, 0, 0 }
12228 + };
12229 +
12230 + MODULE_DEVICE_TABLE (pci, i801_ids);
12231 +diff -Nurp linux-2.6.23.15/drivers/i2c/busses/i2c-i810.c linux-2.6.23.15-grsec/drivers/i2c/busses/i2c-i810.c
12232 +--- linux-2.6.23.15/drivers/i2c/busses/i2c-i810.c 2007-10-09 21:31:38.000000000 +0100
12233 ++++ linux-2.6.23.15-grsec/drivers/i2c/busses/i2c-i810.c 2008-02-11 10:37:44.000000000 +0000
12234 +@@ -198,7 +198,7 @@ static struct pci_device_id i810_ids[] _
12235 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG) },
12236 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC) },
12237 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG) },
12238 +- { 0, },
12239 ++ { 0, 0, 0, 0, 0, 0, 0 },
12240 + };
12241 +
12242 + MODULE_DEVICE_TABLE (pci, i810_ids);
12243 +diff -Nurp linux-2.6.23.15/drivers/i2c/busses/i2c-piix4.c linux-2.6.23.15-grsec/drivers/i2c/busses/i2c-piix4.c
12244 +--- linux-2.6.23.15/drivers/i2c/busses/i2c-piix4.c 2007-10-09 21:31:38.000000000 +0100
12245 ++++ linux-2.6.23.15-grsec/drivers/i2c/busses/i2c-piix4.c 2008-02-11 10:37:44.000000000 +0000
12246 +@@ -113,7 +113,7 @@ static struct dmi_system_id __devinitdat
12247 + .ident = "IBM",
12248 + .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
12249 + },
12250 +- { },
12251 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL },
12252 + };
12253 +
12254 + static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
12255 +@@ -411,7 +411,7 @@ static struct pci_device_id piix4_ids[]
12256 + .driver_data = 3 },
12257 + { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3),
12258 + .driver_data = 0 },
12259 +- { 0, }
12260 ++ { 0, 0, 0, 0, 0, 0, 0 }
12261 + };
12262 +
12263 + MODULE_DEVICE_TABLE (pci, piix4_ids);
12264 +diff -Nurp linux-2.6.23.15/drivers/i2c/busses/i2c-sis630.c linux-2.6.23.15-grsec/drivers/i2c/busses/i2c-sis630.c
12265 +--- linux-2.6.23.15/drivers/i2c/busses/i2c-sis630.c 2007-10-09 21:31:38.000000000 +0100
12266 ++++ linux-2.6.23.15-grsec/drivers/i2c/busses/i2c-sis630.c 2008-02-11 10:37:44.000000000 +0000
12267 +@@ -465,7 +465,7 @@ static struct i2c_adapter sis630_adapter
12268 + static struct pci_device_id sis630_ids[] __devinitdata = {
12269 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
12270 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
12271 +- { 0, }
12272 ++ { PCI_DEVICE(0, 0) }
12273 + };
12274 +
12275 + MODULE_DEVICE_TABLE (pci, sis630_ids);
12276 +diff -Nurp linux-2.6.23.15/drivers/i2c/busses/i2c-sis96x.c linux-2.6.23.15-grsec/drivers/i2c/busses/i2c-sis96x.c
12277 +--- linux-2.6.23.15/drivers/i2c/busses/i2c-sis96x.c 2007-10-09 21:31:38.000000000 +0100
12278 ++++ linux-2.6.23.15-grsec/drivers/i2c/busses/i2c-sis96x.c 2008-02-11 10:37:44.000000000 +0000
12279 +@@ -255,7 +255,7 @@ static struct i2c_adapter sis96x_adapter
12280 +
12281 + static struct pci_device_id sis96x_ids[] = {
12282 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
12283 +- { 0, }
12284 ++ { PCI_DEVICE(0, 0) }
12285 + };
12286 +
12287 + MODULE_DEVICE_TABLE (pci, sis96x_ids);
12288 +diff -Nurp linux-2.6.23.15/drivers/ide/ide-cd.c linux-2.6.23.15-grsec/drivers/ide/ide-cd.c
12289 +--- linux-2.6.23.15/drivers/ide/ide-cd.c 2007-10-09 21:31:38.000000000 +0100
12290 ++++ linux-2.6.23.15-grsec/drivers/ide/ide-cd.c 2008-02-11 10:37:44.000000000 +0000
12291 +@@ -457,8 +457,6 @@ void cdrom_analyze_sense_data(ide_drive_
12292 + sector &= ~(bio_sectors -1);
12293 + valid = (sector - failed_command->sector) << 9;
12294 +
12295 +- if (valid < 0)
12296 +- valid = 0;
12297 + if (sector < get_capacity(info->disk) &&
12298 + drive->probed_capacity - sector < 4 * 75) {
12299 + set_capacity(info->disk, sector);
12300 +diff -Nurp linux-2.6.23.15/drivers/ieee1394/dv1394.c linux-2.6.23.15-grsec/drivers/ieee1394/dv1394.c
12301 +--- linux-2.6.23.15/drivers/ieee1394/dv1394.c 2007-10-09 21:31:38.000000000 +0100
12302 ++++ linux-2.6.23.15-grsec/drivers/ieee1394/dv1394.c 2008-02-11 10:37:44.000000000 +0000
12303 +@@ -739,7 +739,7 @@ static void frame_prepare(struct video_c
12304 + based upon DIF section and sequence
12305 + */
12306 +
12307 +-static void inline
12308 ++static inline void
12309 + frame_put_packet (struct frame *f, struct packet *p)
12310 + {
12311 + int section_type = p->data[0] >> 5; /* section type is in bits 5 - 7 */
12312 +@@ -918,7 +918,7 @@ static int do_dv1394_init(struct video_c
12313 + /* default SYT offset is 3 cycles */
12314 + init->syt_offset = 3;
12315 +
12316 +- if ( (init->channel > 63) || (init->channel < 0) )
12317 ++ if (init->channel > 63)
12318 + init->channel = 63;
12319 +
12320 + chan_mask = (u64)1 << init->channel;
12321 +@@ -2173,7 +2173,7 @@ static struct ieee1394_device_id dv1394_
12322 + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
12323 + .version = AVC_SW_VERSION_ENTRY & 0xffffff
12324 + },
12325 +- { }
12326 ++ { 0, 0, 0, 0, 0, 0 }
12327 + };
12328 +
12329 + MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
12330 +diff -Nurp linux-2.6.23.15/drivers/ieee1394/eth1394.c linux-2.6.23.15-grsec/drivers/ieee1394/eth1394.c
12331 +--- linux-2.6.23.15/drivers/ieee1394/eth1394.c 2007-10-09 21:31:38.000000000 +0100
12332 ++++ linux-2.6.23.15-grsec/drivers/ieee1394/eth1394.c 2008-02-11 10:37:44.000000000 +0000
12333 +@@ -449,7 +449,7 @@ static struct ieee1394_device_id eth1394
12334 + .specifier_id = ETHER1394_GASP_SPECIFIER_ID,
12335 + .version = ETHER1394_GASP_VERSION,
12336 + },
12337 +- {}
12338 ++ { 0, 0, 0, 0, 0, 0 }
12339 + };
12340 +
12341 + MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
12342 +diff -Nurp linux-2.6.23.15/drivers/ieee1394/hosts.c linux-2.6.23.15-grsec/drivers/ieee1394/hosts.c
12343 +--- linux-2.6.23.15/drivers/ieee1394/hosts.c 2007-10-09 21:31:38.000000000 +0100
12344 ++++ linux-2.6.23.15-grsec/drivers/ieee1394/hosts.c 2008-02-11 10:37:44.000000000 +0000
12345 +@@ -78,6 +78,7 @@ static int dummy_isoctl(struct hpsb_iso
12346 + }
12347 +
12348 + static struct hpsb_host_driver dummy_driver = {
12349 ++ .name = "dummy",
12350 + .transmit_packet = dummy_transmit_packet,
12351 + .devctl = dummy_devctl,
12352 + .isoctl = dummy_isoctl
12353 +diff -Nurp linux-2.6.23.15/drivers/ieee1394/ohci1394.c linux-2.6.23.15-grsec/drivers/ieee1394/ohci1394.c
12354 +--- linux-2.6.23.15/drivers/ieee1394/ohci1394.c 2007-10-09 21:31:38.000000000 +0100
12355 ++++ linux-2.6.23.15-grsec/drivers/ieee1394/ohci1394.c 2008-02-11 10:37:44.000000000 +0000
12356 +@@ -147,9 +147,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
12357 + printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
12358 +
12359 + /* Module Parameters */
12360 +-static int phys_dma = 1;
12361 ++static int phys_dma;
12362 + module_param(phys_dma, int, 0444);
12363 +-MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1).");
12364 ++MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 0).");
12365 +
12366 + static void dma_trm_tasklet(unsigned long data);
12367 + static void dma_trm_reset(struct dma_trm_ctx *d);
12368 +@@ -3396,7 +3396,7 @@ static struct pci_device_id ohci1394_pci
12369 + .subvendor = PCI_ANY_ID,
12370 + .subdevice = PCI_ANY_ID,
12371 + },
12372 +- { 0, },
12373 ++ { 0, 0, 0, 0, 0, 0, 0 },
12374 + };
12375 +
12376 + MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
12377 +diff -Nurp linux-2.6.23.15/drivers/ieee1394/raw1394.c linux-2.6.23.15-grsec/drivers/ieee1394/raw1394.c
12378 +--- linux-2.6.23.15/drivers/ieee1394/raw1394.c 2007-10-09 21:31:38.000000000 +0100
12379 ++++ linux-2.6.23.15-grsec/drivers/ieee1394/raw1394.c 2008-02-11 10:37:44.000000000 +0000
12380 +@@ -2952,7 +2952,7 @@ static struct ieee1394_device_id raw1394
12381 + .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
12382 + .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
12383 + .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff},
12384 +- {}
12385 ++ { 0, 0, 0, 0, 0, 0 }
12386 + };
12387 +
12388 + MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
12389 +diff -Nurp linux-2.6.23.15/drivers/ieee1394/sbp2.c linux-2.6.23.15-grsec/drivers/ieee1394/sbp2.c
12390 +--- linux-2.6.23.15/drivers/ieee1394/sbp2.c 2007-10-09 21:31:38.000000000 +0100
12391 ++++ linux-2.6.23.15-grsec/drivers/ieee1394/sbp2.c 2008-02-11 10:37:44.000000000 +0000
12392 +@@ -272,7 +272,7 @@ static struct ieee1394_device_id sbp2_id
12393 + .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
12394 + .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
12395 + .version = SBP2_SW_VERSION_ENTRY & 0xffffff},
12396 +- {}
12397 ++ { 0, 0, 0, 0, 0, 0 }
12398 + };
12399 + MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
12400 +
12401 +@@ -2063,7 +2063,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot
12402 + MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
12403 + MODULE_LICENSE("GPL");
12404 +
12405 +-static int sbp2_module_init(void)
12406 ++static int __init sbp2_module_init(void)
12407 + {
12408 + int ret;
12409 +
12410 +diff -Nurp linux-2.6.23.15/drivers/ieee1394/video1394.c linux-2.6.23.15-grsec/drivers/ieee1394/video1394.c
12411 +--- linux-2.6.23.15/drivers/ieee1394/video1394.c 2007-10-09 21:31:38.000000000 +0100
12412 ++++ linux-2.6.23.15-grsec/drivers/ieee1394/video1394.c 2008-02-11 10:37:44.000000000 +0000
12413 +@@ -893,7 +893,7 @@ static long video1394_ioctl(struct file
12414 + if (unlikely(d == NULL))
12415 + return -EFAULT;
12416 +
12417 +- if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) {
12418 ++ if (unlikely(v.buffer>=d->num_desc - 1)) {
12419 + PRINT(KERN_ERR, ohci->host->id,
12420 + "Buffer %d out of range",v.buffer);
12421 + return -EINVAL;
12422 +@@ -959,7 +959,7 @@ static long video1394_ioctl(struct file
12423 + if (unlikely(d == NULL))
12424 + return -EFAULT;
12425 +
12426 +- if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) {
12427 ++ if (unlikely(v.buffer>d->num_desc - 1)) {
12428 + PRINT(KERN_ERR, ohci->host->id,
12429 + "Buffer %d out of range",v.buffer);
12430 + return -EINVAL;
12431 +@@ -1030,7 +1030,7 @@ static long video1394_ioctl(struct file
12432 + d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
12433 + if (d == NULL) return -EFAULT;
12434 +
12435 +- if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
12436 ++ if (v.buffer>=d->num_desc - 1) {
12437 + PRINT(KERN_ERR, ohci->host->id,
12438 + "Buffer %d out of range",v.buffer);
12439 + return -EINVAL;
12440 +@@ -1137,7 +1137,7 @@ static long video1394_ioctl(struct file
12441 + d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
12442 + if (d == NULL) return -EFAULT;
12443 +
12444 +- if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
12445 ++ if (v.buffer>=d->num_desc-1) {
12446 + PRINT(KERN_ERR, ohci->host->id,
12447 + "Buffer %d out of range",v.buffer);
12448 + return -EINVAL;
12449 +@@ -1309,7 +1309,7 @@ static struct ieee1394_device_id video13
12450 + .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
12451 + .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff
12452 + },
12453 +- { }
12454 ++ { 0, 0, 0, 0, 0, 0 }
12455 + };
12456 +
12457 + MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
12458 +diff -Nurp linux-2.6.23.15/drivers/input/keyboard/atkbd.c linux-2.6.23.15-grsec/drivers/input/keyboard/atkbd.c
12459 +--- linux-2.6.23.15/drivers/input/keyboard/atkbd.c 2007-10-09 21:31:38.000000000 +0100
12460 ++++ linux-2.6.23.15-grsec/drivers/input/keyboard/atkbd.c 2008-02-11 10:37:44.000000000 +0000
12461 +@@ -1075,7 +1075,7 @@ static struct serio_device_id atkbd_seri
12462 + .id = SERIO_ANY,
12463 + .extra = SERIO_ANY,
12464 + },
12465 +- { 0 }
12466 ++ { 0, 0, 0, 0 }
12467 + };
12468 +
12469 + MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
12470 +diff -Nurp linux-2.6.23.15/drivers/input/mouse/lifebook.c linux-2.6.23.15-grsec/drivers/input/mouse/lifebook.c
12471 +--- linux-2.6.23.15/drivers/input/mouse/lifebook.c 2007-10-09 21:31:38.000000000 +0100
12472 ++++ linux-2.6.23.15-grsec/drivers/input/mouse/lifebook.c 2008-02-11 10:37:44.000000000 +0000
12473 +@@ -102,7 +102,7 @@ static struct dmi_system_id lifebook_dmi
12474 + DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
12475 + },
12476 + },
12477 +- { }
12478 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
12479 + };
12480 +
12481 + static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
12482 +diff -Nurp linux-2.6.23.15/drivers/input/mouse/psmouse-base.c linux-2.6.23.15-grsec/drivers/input/mouse/psmouse-base.c
12483 +--- linux-2.6.23.15/drivers/input/mouse/psmouse-base.c 2007-10-09 21:31:38.000000000 +0100
12484 ++++ linux-2.6.23.15-grsec/drivers/input/mouse/psmouse-base.c 2008-02-11 10:37:44.000000000 +0000
12485 +@@ -1325,7 +1325,7 @@ static struct serio_device_id psmouse_se
12486 + .id = SERIO_ANY,
12487 + .extra = SERIO_ANY,
12488 + },
12489 +- { 0 }
12490 ++ { 0, 0, 0, 0 }
12491 + };
12492 +
12493 + MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
12494 +diff -Nurp linux-2.6.23.15/drivers/input/mouse/synaptics.c linux-2.6.23.15-grsec/drivers/input/mouse/synaptics.c
12495 +--- linux-2.6.23.15/drivers/input/mouse/synaptics.c 2007-10-09 21:31:38.000000000 +0100
12496 ++++ linux-2.6.23.15-grsec/drivers/input/mouse/synaptics.c 2008-02-11 10:37:44.000000000 +0000
12497 +@@ -417,7 +417,7 @@ static void synaptics_process_packet(str
12498 + break;
12499 + case 2:
12500 + if (SYN_MODEL_PEN(priv->model_id))
12501 +- ; /* Nothing, treat a pen as a single finger */
12502 ++ break; /* Nothing, treat a pen as a single finger */
12503 + break;
12504 + case 4 ... 15:
12505 + if (SYN_CAP_PALMDETECT(priv->capabilities))
12506 +@@ -624,7 +624,7 @@ static struct dmi_system_id toshiba_dmi_
12507 + DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
12508 + },
12509 + },
12510 +- { }
12511 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12512 + };
12513 + #endif
12514 +
12515 +diff -Nurp linux-2.6.23.15/drivers/input/mousedev.c linux-2.6.23.15-grsec/drivers/input/mousedev.c
12516 +--- linux-2.6.23.15/drivers/input/mousedev.c 2008-02-11 10:36:03.000000000 +0000
12517 ++++ linux-2.6.23.15-grsec/drivers/input/mousedev.c 2008-02-11 10:37:44.000000000 +0000
12518 +@@ -1048,7 +1048,7 @@ static struct input_handler mousedev_han
12519 +
12520 + #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
12521 + static struct miscdevice psaux_mouse = {
12522 +- PSMOUSE_MINOR, "psaux", &mousedev_fops
12523 ++ PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL
12524 + };
12525 + static int psaux_registered;
12526 + #endif
12527 +diff -Nurp linux-2.6.23.15/drivers/input/serio/i8042-x86ia64io.h linux-2.6.23.15-grsec/drivers/input/serio/i8042-x86ia64io.h
12528 +--- linux-2.6.23.15/drivers/input/serio/i8042-x86ia64io.h 2007-10-09 21:31:38.000000000 +0100
12529 ++++ linux-2.6.23.15-grsec/drivers/input/serio/i8042-x86ia64io.h 2008-02-11 10:37:44.000000000 +0000
12530 +@@ -110,7 +110,7 @@ static struct dmi_system_id __initdata i
12531 + DMI_MATCH(DMI_PRODUCT_VERSION, "5a"),
12532 + },
12533 + },
12534 +- { }
12535 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12536 + };
12537 +
12538 + /*
12539 +@@ -262,7 +262,7 @@ static struct dmi_system_id __initdata i
12540 + DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"),
12541 + },
12542 + },
12543 +- { }
12544 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12545 + };
12546 +
12547 +
12548 +diff -Nurp linux-2.6.23.15/drivers/input/serio/serio_raw.c linux-2.6.23.15-grsec/drivers/input/serio/serio_raw.c
12549 +--- linux-2.6.23.15/drivers/input/serio/serio_raw.c 2007-10-09 21:31:38.000000000 +0100
12550 ++++ linux-2.6.23.15-grsec/drivers/input/serio/serio_raw.c 2008-02-11 10:37:44.000000000 +0000
12551 +@@ -369,7 +369,7 @@ static struct serio_device_id serio_raw_
12552 + .id = SERIO_ANY,
12553 + .extra = SERIO_ANY,
12554 + },
12555 +- { 0 }
12556 ++ { 0, 0, 0, 0 }
12557 + };
12558 +
12559 + MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
12560 +diff -Nurp linux-2.6.23.15/drivers/kvm/kvm_main.c linux-2.6.23.15-grsec/drivers/kvm/kvm_main.c
12561 +--- linux-2.6.23.15/drivers/kvm/kvm_main.c 2008-02-11 10:36:03.000000000 +0000
12562 ++++ linux-2.6.23.15-grsec/drivers/kvm/kvm_main.c 2008-02-11 10:37:44.000000000 +0000
12563 +@@ -63,21 +63,21 @@ static struct kvm_stats_debugfs_item {
12564 + int offset;
12565 + struct dentry *dentry;
12566 + } debugfs_entries[] = {
12567 +- { "pf_fixed", STAT_OFFSET(pf_fixed) },
12568 +- { "pf_guest", STAT_OFFSET(pf_guest) },
12569 +- { "tlb_flush", STAT_OFFSET(tlb_flush) },
12570 +- { "invlpg", STAT_OFFSET(invlpg) },
12571 +- { "exits", STAT_OFFSET(exits) },
12572 +- { "io_exits", STAT_OFFSET(io_exits) },
12573 +- { "mmio_exits", STAT_OFFSET(mmio_exits) },
12574 +- { "signal_exits", STAT_OFFSET(signal_exits) },
12575 +- { "irq_window", STAT_OFFSET(irq_window_exits) },
12576 +- { "halt_exits", STAT_OFFSET(halt_exits) },
12577 +- { "request_irq", STAT_OFFSET(request_irq_exits) },
12578 +- { "irq_exits", STAT_OFFSET(irq_exits) },
12579 +- { "light_exits", STAT_OFFSET(light_exits) },
12580 +- { "efer_reload", STAT_OFFSET(efer_reload) },
12581 +- { NULL }
12582 ++ { "pf_fixed", STAT_OFFSET(pf_fixed), NULL },
12583 ++ { "pf_guest", STAT_OFFSET(pf_guest), NULL },
12584 ++ { "tlb_flush", STAT_OFFSET(tlb_flush), NULL },
12585 ++ { "invlpg", STAT_OFFSET(invlpg), NULL },
12586 ++ { "exits", STAT_OFFSET(exits), NULL },
12587 ++ { "io_exits", STAT_OFFSET(io_exits), NULL },
12588 ++ { "mmio_exits", STAT_OFFSET(mmio_exits), NULL },
12589 ++ { "signal_exits", STAT_OFFSET(signal_exits), NULL },
12590 ++ { "irq_window", STAT_OFFSET(irq_window_exits), NULL },
12591 ++ { "halt_exits", STAT_OFFSET(halt_exits), NULL },
12592 ++ { "request_irq", STAT_OFFSET(request_irq_exits), NULL },
12593 ++ { "irq_exits", STAT_OFFSET(irq_exits), NULL },
12594 ++ { "light_exits", STAT_OFFSET(light_exits), NULL },
12595 ++ { "efer_reload", STAT_OFFSET(efer_reload), NULL },
12596 ++ { NULL, 0, NULL }
12597 + };
12598 +
12599 + static struct dentry *debugfs_dir;
12600 +@@ -2255,7 +2255,7 @@ static int kvm_vcpu_ioctl_translate(stru
12601 + static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
12602 + struct kvm_interrupt *irq)
12603 + {
12604 +- if (irq->irq < 0 || irq->irq >= 256)
12605 ++ if (irq->irq >= 256)
12606 + return -EINVAL;
12607 + vcpu_load(vcpu);
12608 +
12609 +@@ -2895,6 +2895,9 @@ static struct miscdevice kvm_dev = {
12610 + KVM_MINOR,
12611 + "kvm",
12612 + &kvm_chardev_ops,
12613 ++ {NULL, NULL},
12614 ++ NULL,
12615 ++ NULL
12616 + };
12617 +
12618 + static int kvm_reboot(struct notifier_block *notifier, unsigned long val,
12619 +diff -Nurp linux-2.6.23.15/drivers/kvm/vmx.c linux-2.6.23.15-grsec/drivers/kvm/vmx.c
12620 +--- linux-2.6.23.15/drivers/kvm/vmx.c 2008-02-11 10:36:03.000000000 +0000
12621 ++++ linux-2.6.23.15-grsec/drivers/kvm/vmx.c 2008-02-11 10:37:44.000000000 +0000
12622 +@@ -2148,7 +2148,7 @@ again:
12623 +
12624 + vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
12625 +
12626 +- asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
12627 ++ asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS));
12628 +
12629 + if (unlikely(fail)) {
12630 + kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
12631 +diff -Nurp linux-2.6.23.15/drivers/kvm/x86_emulate.c linux-2.6.23.15-grsec/drivers/kvm/x86_emulate.c
12632 +--- linux-2.6.23.15/drivers/kvm/x86_emulate.c 2008-02-11 10:36:03.000000000 +0000
12633 ++++ linux-2.6.23.15-grsec/drivers/kvm/x86_emulate.c 2008-02-11 10:37:44.000000000 +0000
12634 +@@ -823,7 +823,7 @@ done_prefixes:
12635 + case DstReg:
12636 + dst.type = OP_REG;
12637 + if ((d & ByteOp)
12638 +- && !(twobyte_table && (b == 0xb6 || b == 0xb7))) {
12639 ++ && !(twobyte && (b == 0xb6 || b == 0xb7))) {
12640 + dst.ptr = decode_register(modrm_reg, _regs,
12641 + (rex_prefix == 0));
12642 + dst.val = *(u8 *) dst.ptr;
12643 +diff -Nurp linux-2.6.23.15/drivers/md/bitmap.c linux-2.6.23.15-grsec/drivers/md/bitmap.c
12644 +--- linux-2.6.23.15/drivers/md/bitmap.c 2008-02-11 10:36:03.000000000 +0000
12645 ++++ linux-2.6.23.15-grsec/drivers/md/bitmap.c 2008-02-11 10:37:44.000000000 +0000
12646 +@@ -57,7 +57,7 @@
12647 + # if DEBUG > 0
12648 + # define PRINTK(x...) printk(KERN_DEBUG x)
12649 + # else
12650 +-# define PRINTK(x...)
12651 ++# define PRINTK(x...) do {} while (0)
12652 + # endif
12653 + #endif
12654 +
12655 +diff -Nurp linux-2.6.23.15/drivers/mtd/devices/doc2000.c linux-2.6.23.15-grsec/drivers/mtd/devices/doc2000.c
12656 +--- linux-2.6.23.15/drivers/mtd/devices/doc2000.c 2007-10-09 21:31:38.000000000 +0100
12657 ++++ linux-2.6.23.15-grsec/drivers/mtd/devices/doc2000.c 2008-02-11 10:37:44.000000000 +0000
12658 +@@ -632,7 +632,7 @@ static int doc_read(struct mtd_info *mtd
12659 + len = ((from | 0x1ff) + 1) - from;
12660 +
12661 + /* The ECC will not be calculated correctly if less than 512 is read */
12662 +- if (len != 0x200 && eccbuf)
12663 ++ if (len != 0x200)
12664 + printk(KERN_WARNING
12665 + "ECC needs a full sector read (adr: %lx size %lx)\n",
12666 + (long) from, (long) len);
12667 +diff -Nurp linux-2.6.23.15/drivers/mtd/devices/doc2001.c linux-2.6.23.15-grsec/drivers/mtd/devices/doc2001.c
12668 +--- linux-2.6.23.15/drivers/mtd/devices/doc2001.c 2007-10-09 21:31:38.000000000 +0100
12669 ++++ linux-2.6.23.15-grsec/drivers/mtd/devices/doc2001.c 2008-02-11 10:37:44.000000000 +0000
12670 +@@ -398,6 +398,8 @@ static int doc_read (struct mtd_info *mt
12671 + /* Don't allow read past end of device */
12672 + if (from >= this->totlen)
12673 + return -EINVAL;
12674 ++ if (!len)
12675 ++ return -EINVAL;
12676 +
12677 + /* Don't allow a single read to cross a 512-byte block boundary */
12678 + if (from + len > ((from | 0x1ff) + 1))
12679 +diff -Nurp linux-2.6.23.15/drivers/mtd/devices/doc2001plus.c linux-2.6.23.15-grsec/drivers/mtd/devices/doc2001plus.c
12680 +--- linux-2.6.23.15/drivers/mtd/devices/doc2001plus.c 2007-10-09 21:31:38.000000000 +0100
12681 ++++ linux-2.6.23.15-grsec/drivers/mtd/devices/doc2001plus.c 2008-02-11 10:37:44.000000000 +0000
12682 +@@ -748,7 +748,7 @@ static int doc_write(struct mtd_info *mt
12683 + WriteDOC(DoC_GetDataOffset(mtd, &fto), docptr, Mplus_FlashCmd);
12684 +
12685 + /* On interleaved devices the flags for 2nd half 512 are before data */
12686 +- if (eccbuf && before)
12687 ++ if (before)
12688 + fto -= 2;
12689 +
12690 + /* issue the Serial Data In command to initial the Page Program process */
12691 +diff -Nurp linux-2.6.23.15/drivers/mtd/devices/slram.c linux-2.6.23.15-grsec/drivers/mtd/devices/slram.c
12692 +--- linux-2.6.23.15/drivers/mtd/devices/slram.c 2007-10-09 21:31:38.000000000 +0100
12693 ++++ linux-2.6.23.15-grsec/drivers/mtd/devices/slram.c 2008-02-11 10:37:44.000000000 +0000
12694 +@@ -270,7 +270,7 @@ static int parse_cmdline(char *devname,
12695 + }
12696 + T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n",
12697 + devname, devstart, devlength);
12698 +- if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) {
12699 ++ if (devlength % SLRAM_BLK_SZ != 0) {
12700 + E("slram: Illegal start / length parameter.\n");
12701 + return(-EINVAL);
12702 + }
12703 +diff -Nurp linux-2.6.23.15/drivers/mtd/ubi/build.c linux-2.6.23.15-grsec/drivers/mtd/ubi/build.c
12704 +--- linux-2.6.23.15/drivers/mtd/ubi/build.c 2007-10-09 21:31:38.000000000 +0100
12705 ++++ linux-2.6.23.15-grsec/drivers/mtd/ubi/build.c 2008-02-11 10:37:44.000000000 +0000
12706 +@@ -727,7 +727,7 @@ static int __init bytes_str_to_int(const
12707 + unsigned long result;
12708 +
12709 + result = simple_strtoul(str, &endp, 0);
12710 +- if (str == endp || result < 0) {
12711 ++ if (str == endp) {
12712 + printk("UBI error: incorrect bytes count: \"%s\"\n", str);
12713 + return -EINVAL;
12714 + }
12715 +diff -Nurp linux-2.6.23.15/drivers/net/eepro100.c linux-2.6.23.15-grsec/drivers/net/eepro100.c
12716 +--- linux-2.6.23.15/drivers/net/eepro100.c 2007-10-09 21:31:38.000000000 +0100
12717 ++++ linux-2.6.23.15-grsec/drivers/net/eepro100.c 2008-02-11 10:37:44.000000000 +0000
12718 +@@ -47,7 +47,7 @@ static int rxdmacount /* = 0 */;
12719 + # define rx_align(skb) skb_reserve((skb), 2)
12720 + # define RxFD_ALIGNMENT __attribute__ ((aligned (2), packed))
12721 + #else
12722 +-# define rx_align(skb)
12723 ++# define rx_align(skb) do {} while (0)
12724 + # define RxFD_ALIGNMENT
12725 + #endif
12726 +
12727 +@@ -2344,33 +2344,33 @@ static void __devexit eepro100_remove_on
12728 + }
12729 +
12730 + static struct pci_device_id eepro100_pci_tbl[] = {
12731 +- { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, },
12732 +- { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, },
12733 +- { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, },
12734 +- { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, },
12735 +- { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, },
12736 +- { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, },
12737 +- { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, },
12738 +- { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, },
12739 +- { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, },
12740 +- { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, },
12741 +- { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, },
12742 +- { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, },
12743 +- { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, },
12744 +- { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, },
12745 +- { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, },
12746 +- { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, },
12747 +- { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, },
12748 +- { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, },
12749 +- { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, },
12750 +- { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, },
12751 +- { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
12752 +- { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, },
12753 +- { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, },
12754 +- { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, },
12755 +- { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, },
12756 +- { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, },
12757 +- { 0,}
12758 ++ { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12759 ++ { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12760 ++ { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12761 ++ { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12762 ++ { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12763 ++ { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12764 ++ { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12765 ++ { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12766 ++ { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12767 ++ { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12768 ++ { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12769 ++ { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12770 ++ { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12771 ++ { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12772 ++ { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12773 ++ { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12774 ++ { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12775 ++ { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12776 ++ { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12777 ++ { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12778 ++ { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12779 ++ { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12780 ++ { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12781 ++ { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12782 ++ { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12783 ++ { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12784 ++ { 0, 0, 0, 0, 0, 0, 0 }
12785 + };
12786 + MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
12787 +
12788 +diff -Nurp linux-2.6.23.15/drivers/net/irda/vlsi_ir.c linux-2.6.23.15-grsec/drivers/net/irda/vlsi_ir.c
12789 +--- linux-2.6.23.15/drivers/net/irda/vlsi_ir.c 2007-10-09 21:31:38.000000000 +0100
12790 ++++ linux-2.6.23.15-grsec/drivers/net/irda/vlsi_ir.c 2008-02-11 10:37:44.000000000 +0000
12791 +@@ -906,13 +906,12 @@ static int vlsi_hard_start_xmit(struct s
12792 + /* no race - tx-ring already empty */
12793 + vlsi_set_baud(idev, iobase);
12794 + netif_wake_queue(ndev);
12795 +- }
12796 +- else
12797 +- ;
12798 ++ } else {
12799 + /* keep the speed change pending like it would
12800 + * for any len>0 packet. tx completion interrupt
12801 + * will apply it when the tx ring becomes empty.
12802 + */
12803 ++ }
12804 + spin_unlock_irqrestore(&idev->lock, flags);
12805 + dev_kfree_skb_any(skb);
12806 + return 0;
12807 +diff -Nurp linux-2.6.23.15/drivers/net/pcnet32.c linux-2.6.23.15-grsec/drivers/net/pcnet32.c
12808 +--- linux-2.6.23.15/drivers/net/pcnet32.c 2007-10-09 21:31:38.000000000 +0100
12809 ++++ linux-2.6.23.15-grsec/drivers/net/pcnet32.c 2008-02-11 10:37:44.000000000 +0000
12810 +@@ -82,7 +82,7 @@ static int cards_found;
12811 + /*
12812 + * VLB I/O addresses
12813 + */
12814 +-static unsigned int pcnet32_portlist[] __initdata =
12815 ++static unsigned int pcnet32_portlist[] __devinitdata =
12816 + { 0x300, 0x320, 0x340, 0x360, 0 };
12817 +
12818 + static int pcnet32_debug = 0;
12819 +diff -Nurp linux-2.6.23.15/drivers/net/tg3.h linux-2.6.23.15-grsec/drivers/net/tg3.h
12820 +--- linux-2.6.23.15/drivers/net/tg3.h 2007-10-09 21:31:38.000000000 +0100
12821 ++++ linux-2.6.23.15-grsec/drivers/net/tg3.h 2008-02-11 10:37:44.000000000 +0000
12822 +@@ -127,6 +127,7 @@
12823 + #define CHIPREV_ID_5750_A0 0x4000
12824 + #define CHIPREV_ID_5750_A1 0x4001
12825 + #define CHIPREV_ID_5750_A3 0x4003
12826 ++#define CHIPREV_ID_5750_C1 0x4201
12827 + #define CHIPREV_ID_5750_C2 0x4202
12828 + #define CHIPREV_ID_5752_A0_HW 0x5000
12829 + #define CHIPREV_ID_5752_A0 0x6000
12830 +diff -Nurp linux-2.6.23.15/drivers/pci/hotplug/cpqphp_nvram.c linux-2.6.23.15-grsec/drivers/pci/hotplug/cpqphp_nvram.c
12831 +--- linux-2.6.23.15/drivers/pci/hotplug/cpqphp_nvram.c 2007-10-09 21:31:38.000000000 +0100
12832 ++++ linux-2.6.23.15-grsec/drivers/pci/hotplug/cpqphp_nvram.c 2008-02-11 10:37:44.000000000 +0000
12833 +@@ -425,9 +425,13 @@ static u32 store_HRT (void __iomem *rom_
12834 +
12835 + void compaq_nvram_init (void __iomem *rom_start)
12836 + {
12837 ++
12838 ++#ifndef CONFIG_PAX_KERNEXEC
12839 + if (rom_start) {
12840 + compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
12841 + }
12842 ++#endif
12843 ++
12844 + dbg("int15 entry = %p\n", compaq_int15_entry_point);
12845 +
12846 + /* initialize our int15 lock */
12847 +diff -Nurp linux-2.6.23.15/drivers/pci/pcie/aer/aerdrv.c linux-2.6.23.15-grsec/drivers/pci/pcie/aer/aerdrv.c
12848 +--- linux-2.6.23.15/drivers/pci/pcie/aer/aerdrv.c 2007-10-09 21:31:38.000000000 +0100
12849 ++++ linux-2.6.23.15-grsec/drivers/pci/pcie/aer/aerdrv.c 2008-02-11 10:37:44.000000000 +0000
12850 +@@ -58,7 +58,7 @@ static struct pcie_port_service_id aer_i
12851 + .port_type = PCIE_RC_PORT,
12852 + .service_type = PCIE_PORT_SERVICE_AER,
12853 + },
12854 +- { /* end: all zeroes */ }
12855 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
12856 + };
12857 +
12858 + static struct pci_error_handlers aer_error_handlers = {
12859 +diff -Nurp linux-2.6.23.15/drivers/pci/pcie/aer/aerdrv_core.c linux-2.6.23.15-grsec/drivers/pci/pcie/aer/aerdrv_core.c
12860 +--- linux-2.6.23.15/drivers/pci/pcie/aer/aerdrv_core.c 2007-10-09 21:31:38.000000000 +0100
12861 ++++ linux-2.6.23.15-grsec/drivers/pci/pcie/aer/aerdrv_core.c 2008-02-11 10:37:44.000000000 +0000
12862 +@@ -660,7 +660,7 @@ static void aer_isr_one_error(struct pci
12863 + struct aer_err_source *e_src)
12864 + {
12865 + struct device *s_device;
12866 +- struct aer_err_info e_info = {0, 0, 0,};
12867 ++ struct aer_err_info e_info = {0, 0, 0, {0, 0, 0, 0}};
12868 + int i;
12869 + u16 id;
12870 +
12871 +diff -Nurp linux-2.6.23.15/drivers/pci/pcie/portdrv_pci.c linux-2.6.23.15-grsec/drivers/pci/pcie/portdrv_pci.c
12872 +--- linux-2.6.23.15/drivers/pci/pcie/portdrv_pci.c 2007-10-09 21:31:38.000000000 +0100
12873 ++++ linux-2.6.23.15-grsec/drivers/pci/pcie/portdrv_pci.c 2008-02-11 10:37:44.000000000 +0000
12874 +@@ -265,7 +265,7 @@ static void pcie_portdrv_err_resume(stru
12875 + static const struct pci_device_id port_pci_ids[] = { {
12876 + /* handle any PCI-Express port */
12877 + PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
12878 +- }, { /* end: all zeroes */ }
12879 ++ }, { 0, 0, 0, 0, 0, 0, 0 }
12880 + };
12881 + MODULE_DEVICE_TABLE(pci, port_pci_ids);
12882 +
12883 +diff -Nurp linux-2.6.23.15/drivers/pci/proc.c linux-2.6.23.15-grsec/drivers/pci/proc.c
12884 +--- linux-2.6.23.15/drivers/pci/proc.c 2007-10-09 21:31:38.000000000 +0100
12885 ++++ linux-2.6.23.15-grsec/drivers/pci/proc.c 2008-02-11 10:37:44.000000000 +0000
12886 +@@ -466,7 +466,15 @@ static int __init pci_proc_init(void)
12887 + {
12888 + struct proc_dir_entry *entry;
12889 + struct pci_dev *dev = NULL;
12890 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
12891 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
12892 ++ proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus);
12893 ++#elif CONFIG_GRKERNSEC_PROC_USERGROUP
12894 ++ proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus);
12895 ++#endif
12896 ++#else
12897 + proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
12898 ++#endif
12899 + entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
12900 + if (entry)
12901 + entry->proc_fops = &proc_bus_pci_dev_operations;
12902 +diff -Nurp linux-2.6.23.15/drivers/pcmcia/ti113x.h linux-2.6.23.15-grsec/drivers/pcmcia/ti113x.h
12903 +--- linux-2.6.23.15/drivers/pcmcia/ti113x.h 2007-10-09 21:31:38.000000000 +0100
12904 ++++ linux-2.6.23.15-grsec/drivers/pcmcia/ti113x.h 2008-02-11 10:37:44.000000000 +0000
12905 +@@ -897,7 +897,7 @@ static struct pci_device_id ene_tune_tbl
12906 + DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
12907 + ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
12908 +
12909 +- {}
12910 ++ { 0, 0, 0, 0, 0, 0, 0 }
12911 + };
12912 +
12913 + static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
12914 +diff -Nurp linux-2.6.23.15/drivers/pcmcia/yenta_socket.c linux-2.6.23.15-grsec/drivers/pcmcia/yenta_socket.c
12915 +--- linux-2.6.23.15/drivers/pcmcia/yenta_socket.c 2007-10-09 21:31:38.000000000 +0100
12916 ++++ linux-2.6.23.15-grsec/drivers/pcmcia/yenta_socket.c 2008-02-11 10:37:44.000000000 +0000
12917 +@@ -1358,7 +1358,7 @@ static struct pci_device_id yenta_table
12918 +
12919 + /* match any cardbus bridge */
12920 + CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
12921 +- { /* all zeroes */ }
12922 ++ { 0, 0, 0, 0, 0, 0, 0 }
12923 + };
12924 + MODULE_DEVICE_TABLE(pci, yenta_table);
12925 +
12926 +diff -Nurp linux-2.6.23.15/drivers/pnp/pnpbios/bioscalls.c linux-2.6.23.15-grsec/drivers/pnp/pnpbios/bioscalls.c
12927 +--- linux-2.6.23.15/drivers/pnp/pnpbios/bioscalls.c 2007-10-09 21:31:38.000000000 +0100
12928 ++++ linux-2.6.23.15-grsec/drivers/pnp/pnpbios/bioscalls.c 2008-02-11 10:37:44.000000000 +0000
12929 +@@ -61,7 +61,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
12930 + set_limit(gdt[(selname) >> 3], size); \
12931 + } while(0)
12932 +
12933 +-static struct desc_struct bad_bios_desc = { 0, 0x00409200 };
12934 ++static struct desc_struct bad_bios_desc __read_only = { 0, 0x00409300 };
12935 +
12936 + /*
12937 + * At some point we want to use this stack frame pointer to unwind
12938 +@@ -88,6 +88,10 @@ static inline u16 call_pnp_bios(u16 func
12939 + struct desc_struct save_desc_40;
12940 + int cpu;
12941 +
12942 ++#ifdef CONFIG_PAX_KERNEXEC
12943 ++ unsigned long cr0;
12944 ++#endif
12945 ++
12946 + /*
12947 + * PnP BIOSes are generally not terribly re-entrant.
12948 + * Also, don't rely on them to save everything correctly.
12949 +@@ -97,8 +101,17 @@ static inline u16 call_pnp_bios(u16 func
12950 +
12951 + cpu = get_cpu();
12952 + save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
12953 ++
12954 ++#ifdef CONFIG_PAX_KERNEXEC
12955 ++ pax_open_kernel(cr0);
12956 ++#endif
12957 ++
12958 + get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
12959 +
12960 ++#ifdef CONFIG_PAX_KERNEXEC
12961 ++ pax_close_kernel(cr0);
12962 ++#endif
12963 ++
12964 + /* On some boxes IRQ's during PnP BIOS calls are deadly. */
12965 + spin_lock_irqsave(&pnp_bios_lock, flags);
12966 +
12967 +@@ -135,7 +148,16 @@ static inline u16 call_pnp_bios(u16 func
12968 + :"memory");
12969 + spin_unlock_irqrestore(&pnp_bios_lock, flags);
12970 +
12971 ++#ifdef CONFIG_PAX_KERNEXEC
12972 ++ pax_open_kernel(cr0);
12973 ++#endif
12974 ++
12975 + get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
12976 ++
12977 ++#ifdef CONFIG_PAX_KERNEXEC
12978 ++ pax_close_kernel(cr0);
12979 ++#endif
12980 ++
12981 + put_cpu();
12982 +
12983 + /* If we get here and this is set then the PnP BIOS faulted on us. */
12984 +@@ -469,16 +491,25 @@ int pnp_bios_read_escd(char *data, u32 n
12985 + return status;
12986 + }
12987 +
12988 +-void pnpbios_calls_init(union pnp_bios_install_struct *header)
12989 ++void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
12990 + {
12991 + int i;
12992 +
12993 ++#ifdef CONFIG_PAX_KERNEXEC
12994 ++ unsigned long cr0;
12995 ++#endif
12996 ++
12997 + spin_lock_init(&pnp_bios_lock);
12998 + pnp_bios_callpoint.offset = header->fields.pm16offset;
12999 + pnp_bios_callpoint.segment = PNP_CS16;
13000 +
13001 + set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
13002 + _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
13003 ++
13004 ++#ifdef CONFIG_PAX_KERNEXEC
13005 ++ pax_open_kernel(cr0);
13006 ++#endif
13007 ++
13008 + for (i = 0; i < NR_CPUS; i++) {
13009 + struct desc_struct *gdt = get_cpu_gdt_table(i);
13010 + if (!gdt)
13011 +@@ -489,4 +520,9 @@ void pnpbios_calls_init(union pnp_bios_i
13012 + set_base(gdt[GDT_ENTRY_PNPBIOS_DS],
13013 + __va(header->fields.pm16dseg));
13014 + }
13015 ++
13016 ++#ifdef CONFIG_PAX_KERNEXEC
13017 ++ pax_close_kernel(cr0);
13018 ++#endif
13019 ++
13020 + }
13021 +diff -Nurp linux-2.6.23.15/drivers/pnp/quirks.c linux-2.6.23.15-grsec/drivers/pnp/quirks.c
13022 +--- linux-2.6.23.15/drivers/pnp/quirks.c 2007-10-09 21:31:38.000000000 +0100
13023 ++++ linux-2.6.23.15-grsec/drivers/pnp/quirks.c 2008-02-11 10:37:44.000000000 +0000
13024 +@@ -127,7 +127,7 @@ static struct pnp_fixup pnp_fixups[] = {
13025 + {"CTL0043", quirk_sb16audio_resources},
13026 + {"CTL0044", quirk_sb16audio_resources},
13027 + {"CTL0045", quirk_sb16audio_resources},
13028 +- {""}
13029 ++ {"", NULL}
13030 + };
13031 +
13032 + void pnp_fixup_device(struct pnp_dev *dev)
13033 +diff -Nurp linux-2.6.23.15/drivers/pnp/resource.c linux-2.6.23.15-grsec/drivers/pnp/resource.c
13034 +--- linux-2.6.23.15/drivers/pnp/resource.c 2007-10-09 21:31:38.000000000 +0100
13035 ++++ linux-2.6.23.15-grsec/drivers/pnp/resource.c 2008-02-11 10:37:44.000000000 +0000
13036 +@@ -345,7 +345,7 @@ int pnp_check_irq(struct pnp_dev *dev, i
13037 + return 1;
13038 +
13039 + /* check if the resource is valid */
13040 +- if (*irq < 0 || *irq > 15)
13041 ++ if (*irq > 15)
13042 + return 0;
13043 +
13044 + /* check if the resource is reserved */
13045 +@@ -412,7 +412,7 @@ int pnp_check_dma(struct pnp_dev *dev, i
13046 + return 1;
13047 +
13048 + /* check if the resource is valid */
13049 +- if (*dma < 0 || *dma == 4 || *dma > 7)
13050 ++ if (*dma == 4 || *dma > 7)
13051 + return 0;
13052 +
13053 + /* check if the resource is reserved */
13054 +diff -Nurp linux-2.6.23.15/drivers/scsi/scsi_lib.c linux-2.6.23.15-grsec/drivers/scsi/scsi_lib.c
13055 +--- linux-2.6.23.15/drivers/scsi/scsi_lib.c 2007-10-09 21:31:38.000000000 +0100
13056 ++++ linux-2.6.23.15-grsec/drivers/scsi/scsi_lib.c 2008-02-11 10:37:44.000000000 +0000
13057 +@@ -44,7 +44,7 @@ struct scsi_host_sg_pool {
13058 + #error SCSI_MAX_PHYS_SEGMENTS is too small
13059 + #endif
13060 +
13061 +-#define SP(x) { x, "sgpool-" #x }
13062 ++#define SP(x) { x, "sgpool-" #x, NULL, NULL }
13063 + static struct scsi_host_sg_pool scsi_sg_pools[] = {
13064 + SP(8),
13065 + SP(16),
13066 +diff -Nurp linux-2.6.23.15/drivers/scsi/scsi_logging.h linux-2.6.23.15-grsec/drivers/scsi/scsi_logging.h
13067 +--- linux-2.6.23.15/drivers/scsi/scsi_logging.h 2007-10-09 21:31:38.000000000 +0100
13068 ++++ linux-2.6.23.15-grsec/drivers/scsi/scsi_logging.h 2008-02-11 10:37:44.000000000 +0000
13069 +@@ -51,7 +51,7 @@ do { \
13070 + } while (0); \
13071 + } while (0)
13072 + #else
13073 +-#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
13074 ++#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
13075 + #endif /* CONFIG_SCSI_LOGGING */
13076 +
13077 + /*
13078 +diff -Nurp linux-2.6.23.15/drivers/serial/8250_pci.c linux-2.6.23.15-grsec/drivers/serial/8250_pci.c
13079 +--- linux-2.6.23.15/drivers/serial/8250_pci.c 2007-10-09 21:31:38.000000000 +0100
13080 ++++ linux-2.6.23.15-grsec/drivers/serial/8250_pci.c 2008-02-11 10:37:44.000000000 +0000
13081 +@@ -2589,7 +2589,7 @@ static struct pci_device_id serial_pci_t
13082 + PCI_ANY_ID, PCI_ANY_ID,
13083 + PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
13084 + 0xffff00, pbn_default },
13085 +- { 0, }
13086 ++ { 0, 0, 0, 0, 0, 0, 0 }
13087 + };
13088 +
13089 + static struct pci_driver serial_pci_driver = {
13090 +diff -Nurp linux-2.6.23.15/drivers/usb/class/cdc-acm.c linux-2.6.23.15-grsec/drivers/usb/class/cdc-acm.c
13091 +--- linux-2.6.23.15/drivers/usb/class/cdc-acm.c 2007-10-09 21:31:38.000000000 +0100
13092 ++++ linux-2.6.23.15-grsec/drivers/usb/class/cdc-acm.c 2008-02-11 10:37:44.000000000 +0000
13093 +@@ -1199,7 +1199,7 @@ static struct usb_device_id acm_ids[] =
13094 + USB_CDC_ACM_PROTO_AT_CDMA) },
13095 +
13096 + /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */
13097 +- { }
13098 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
13099 + };
13100 +
13101 + MODULE_DEVICE_TABLE (usb, acm_ids);
13102 +diff -Nurp linux-2.6.23.15/drivers/usb/class/usblp.c linux-2.6.23.15-grsec/drivers/usb/class/usblp.c
13103 +--- linux-2.6.23.15/drivers/usb/class/usblp.c 2007-10-09 21:31:38.000000000 +0100
13104 ++++ linux-2.6.23.15-grsec/drivers/usb/class/usblp.c 2008-02-11 10:37:44.000000000 +0000
13105 +@@ -225,7 +225,7 @@ static const struct quirk_printer_struct
13106 + { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
13107 + { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@×××.de> */
13108 + { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
13109 +- { 0, 0 }
13110 ++ { 0, 0, 0 }
13111 + };
13112 +
13113 + static int usblp_wwait(struct usblp *usblp, int nonblock);
13114 +@@ -1376,7 +1376,7 @@ static struct usb_device_id usblp_ids []
13115 + { USB_INTERFACE_INFO(7, 1, 2) },
13116 + { USB_INTERFACE_INFO(7, 1, 3) },
13117 + { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */
13118 +- { } /* Terminating entry */
13119 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
13120 + };
13121 +
13122 + MODULE_DEVICE_TABLE (usb, usblp_ids);
13123 +diff -Nurp linux-2.6.23.15/drivers/usb/core/hub.c linux-2.6.23.15-grsec/drivers/usb/core/hub.c
13124 +--- linux-2.6.23.15/drivers/usb/core/hub.c 2008-02-11 10:36:03.000000000 +0000
13125 ++++ linux-2.6.23.15-grsec/drivers/usb/core/hub.c 2008-02-11 10:37:44.000000000 +0000
13126 +@@ -2762,7 +2762,7 @@ static struct usb_device_id hub_id_table
13127 + .bDeviceClass = USB_CLASS_HUB},
13128 + { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
13129 + .bInterfaceClass = USB_CLASS_HUB},
13130 +- { } /* Terminating entry */
13131 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
13132 + };
13133 +
13134 + MODULE_DEVICE_TABLE (usb, hub_id_table);
13135 +diff -Nurp linux-2.6.23.15/drivers/usb/host/ehci-pci.c linux-2.6.23.15-grsec/drivers/usb/host/ehci-pci.c
13136 +--- linux-2.6.23.15/drivers/usb/host/ehci-pci.c 2007-10-09 21:31:38.000000000 +0100
13137 ++++ linux-2.6.23.15-grsec/drivers/usb/host/ehci-pci.c 2008-02-11 10:37:44.000000000 +0000
13138 +@@ -377,7 +377,7 @@ static const struct pci_device_id pci_id
13139 + PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
13140 + .driver_data = (unsigned long) &ehci_pci_hc_driver,
13141 + },
13142 +- { /* end: all zeroes */ }
13143 ++ { 0, 0, 0, 0, 0, 0, 0 }
13144 + };
13145 + MODULE_DEVICE_TABLE(pci, pci_ids);
13146 +
13147 +diff -Nurp linux-2.6.23.15/drivers/usb/host/uhci-hcd.c linux-2.6.23.15-grsec/drivers/usb/host/uhci-hcd.c
13148 +--- linux-2.6.23.15/drivers/usb/host/uhci-hcd.c 2007-10-09 21:31:38.000000000 +0100
13149 ++++ linux-2.6.23.15-grsec/drivers/usb/host/uhci-hcd.c 2008-02-11 10:37:44.000000000 +0000
13150 +@@ -894,7 +894,7 @@ static const struct pci_device_id uhci_p
13151 + /* handle any USB UHCI controller */
13152 + PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),
13153 + .driver_data = (unsigned long) &uhci_driver,
13154 +- }, { /* end: all zeroes */ }
13155 ++ }, { 0, 0, 0, 0, 0, 0, 0 }
13156 + };
13157 +
13158 + MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
13159 +diff -Nurp linux-2.6.23.15/drivers/usb/storage/debug.h linux-2.6.23.15-grsec/drivers/usb/storage/debug.h
13160 +--- linux-2.6.23.15/drivers/usb/storage/debug.h 2007-10-09 21:31:38.000000000 +0100
13161 ++++ linux-2.6.23.15-grsec/drivers/usb/storage/debug.h 2008-02-11 10:37:44.000000000 +0000
13162 +@@ -56,9 +56,9 @@ void usb_stor_show_sense( unsigned char
13163 + #define US_DEBUGPX(x...) printk( x )
13164 + #define US_DEBUG(x) x
13165 + #else
13166 +-#define US_DEBUGP(x...)
13167 +-#define US_DEBUGPX(x...)
13168 +-#define US_DEBUG(x)
13169 ++#define US_DEBUGP(x...) do {} while (0)
13170 ++#define US_DEBUGPX(x...) do {} while (0)
13171 ++#define US_DEBUG(x) do {} while (0)
13172 + #endif
13173 +
13174 + #endif
13175 +diff -Nurp linux-2.6.23.15/drivers/usb/storage/usb.c linux-2.6.23.15-grsec/drivers/usb/storage/usb.c
13176 +--- linux-2.6.23.15/drivers/usb/storage/usb.c 2007-10-09 21:31:38.000000000 +0100
13177 ++++ linux-2.6.23.15-grsec/drivers/usb/storage/usb.c 2008-02-11 10:37:44.000000000 +0000
13178 +@@ -134,7 +134,7 @@ static struct usb_device_id storage_usb_
13179 + #undef UNUSUAL_DEV
13180 + #undef USUAL_DEV
13181 + /* Terminating entry */
13182 +- { }
13183 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
13184 + };
13185 +
13186 + MODULE_DEVICE_TABLE (usb, storage_usb_ids);
13187 +@@ -174,7 +174,7 @@ static struct us_unusual_dev us_unusual_
13188 + # undef USUAL_DEV
13189 +
13190 + /* Terminating entry */
13191 +- { NULL }
13192 ++ { NULL, NULL, 0, 0, NULL }
13193 + };
13194 +
13195 +
13196 +diff -Nurp linux-2.6.23.15/drivers/video/fbcmap.c linux-2.6.23.15-grsec/drivers/video/fbcmap.c
13197 +--- linux-2.6.23.15/drivers/video/fbcmap.c 2007-10-09 21:31:38.000000000 +0100
13198 ++++ linux-2.6.23.15-grsec/drivers/video/fbcmap.c 2008-02-11 10:37:44.000000000 +0000
13199 +@@ -251,8 +251,7 @@ int fb_set_user_cmap(struct fb_cmap_user
13200 + int rc, size = cmap->len * sizeof(u16);
13201 + struct fb_cmap umap;
13202 +
13203 +- if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
13204 +- !info->fbops->fb_setcmap))
13205 ++ if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)
13206 + return -EINVAL;
13207 +
13208 + memset(&umap, 0, sizeof(struct fb_cmap));
13209 +diff -Nurp linux-2.6.23.15/drivers/video/fbmem.c linux-2.6.23.15-grsec/drivers/video/fbmem.c
13210 +--- linux-2.6.23.15/drivers/video/fbmem.c 2007-10-09 21:31:38.000000000 +0100
13211 ++++ linux-2.6.23.15-grsec/drivers/video/fbmem.c 2008-02-11 10:37:44.000000000 +0000
13212 +@@ -394,7 +394,7 @@ static void fb_do_show_logo(struct fb_in
13213 + image->dx += image->width + 8;
13214 + }
13215 + } else if (rotate == FB_ROTATE_UD) {
13216 +- for (x = 0; x < num && image->dx >= 0; x++) {
13217 ++ for (x = 0; x < num && (__s32)image->dx >= 0; x++) {
13218 + info->fbops->fb_imageblit(info, image);
13219 + image->dx -= image->width + 8;
13220 + }
13221 +@@ -406,7 +406,7 @@ static void fb_do_show_logo(struct fb_in
13222 + image->dy += image->height + 8;
13223 + }
13224 + } else if (rotate == FB_ROTATE_CCW) {
13225 +- for (x = 0; x < num && image->dy >= 0; x++) {
13226 ++ for (x = 0; x < num && (__s32)image->dy >= 0; x++) {
13227 + info->fbops->fb_imageblit(info, image);
13228 + image->dy -= image->height + 8;
13229 + }
13230 +@@ -1057,9 +1057,9 @@ fb_ioctl(struct inode *inode, struct fil
13231 + case FBIOPUT_CON2FBMAP:
13232 + if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
13233 + return - EFAULT;
13234 +- if (con2fb.console < 0 || con2fb.console > MAX_NR_CONSOLES)
13235 ++ if (con2fb.console > MAX_NR_CONSOLES)
13236 + return -EINVAL;
13237 +- if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
13238 ++ if (con2fb.framebuffer >= FB_MAX)
13239 + return -EINVAL;
13240 + #ifdef CONFIG_KMOD
13241 + if (!registered_fb[con2fb.framebuffer])
13242 +diff -Nurp linux-2.6.23.15/drivers/video/fbmon.c linux-2.6.23.15-grsec/drivers/video/fbmon.c
13243 +--- linux-2.6.23.15/drivers/video/fbmon.c 2007-10-09 21:31:38.000000000 +0100
13244 ++++ linux-2.6.23.15-grsec/drivers/video/fbmon.c 2008-02-11 10:37:44.000000000 +0000
13245 +@@ -45,7 +45,7 @@
13246 + #ifdef DEBUG
13247 + #define DPRINTK(fmt, args...) printk(fmt,## args)
13248 + #else
13249 +-#define DPRINTK(fmt, args...)
13250 ++#define DPRINTK(fmt, args...) do {} while (0)
13251 + #endif
13252 +
13253 + #define FBMON_FIX_HEADER 1
13254 +diff -Nurp linux-2.6.23.15/drivers/video/i810/i810_accel.c linux-2.6.23.15-grsec/drivers/video/i810/i810_accel.c
13255 +--- linux-2.6.23.15/drivers/video/i810/i810_accel.c 2007-10-09 21:31:38.000000000 +0100
13256 ++++ linux-2.6.23.15-grsec/drivers/video/i810/i810_accel.c 2008-02-11 10:37:44.000000000 +0000
13257 +@@ -73,6 +73,7 @@ static inline int wait_for_space(struct
13258 + }
13259 + }
13260 + printk("ringbuffer lockup!!!\n");
13261 ++ printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
13262 + i810_report_error(mmio);
13263 + par->dev_flags |= LOCKUP;
13264 + info->pixmap.scan_align = 1;
13265 +diff -Nurp linux-2.6.23.15/drivers/video/i810/i810_main.c linux-2.6.23.15-grsec/drivers/video/i810/i810_main.c
13266 +--- linux-2.6.23.15/drivers/video/i810/i810_main.c 2007-10-09 21:31:38.000000000 +0100
13267 ++++ linux-2.6.23.15-grsec/drivers/video/i810/i810_main.c 2008-02-11 10:37:44.000000000 +0000
13268 +@@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t
13269 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
13270 + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,
13271 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
13272 +- { 0 },
13273 ++ { 0, 0, 0, 0, 0, 0, 0 },
13274 + };
13275 +
13276 + static struct pci_driver i810fb_driver = {
13277 +@@ -1509,7 +1509,7 @@ static int i810fb_cursor(struct fb_info
13278 + int size = ((cursor->image.width + 7) >> 3) *
13279 + cursor->image.height;
13280 + int i;
13281 +- u8 *data = kmalloc(64 * 8, GFP_ATOMIC);
13282 ++ u8 *data = kmalloc(64 * 8, GFP_KERNEL);
13283 +
13284 + if (data == NULL)
13285 + return -ENOMEM;
13286 +diff -Nurp linux-2.6.23.15/drivers/video/modedb.c linux-2.6.23.15-grsec/drivers/video/modedb.c
13287 +--- linux-2.6.23.15/drivers/video/modedb.c 2007-10-09 21:31:38.000000000 +0100
13288 ++++ linux-2.6.23.15-grsec/drivers/video/modedb.c 2008-02-11 10:37:44.000000000 +0000
13289 +@@ -37,228 +37,228 @@ static const struct fb_videomode modedb[
13290 + {
13291 + /* 640x400 @ 70 Hz, 31.5 kHz hsync */
13292 + NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
13293 +- 0, FB_VMODE_NONINTERLACED
13294 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13295 + }, {
13296 + /* 640x480 @ 60 Hz, 31.5 kHz hsync */
13297 + NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
13298 +- 0, FB_VMODE_NONINTERLACED
13299 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13300 + }, {
13301 + /* 800x600 @ 56 Hz, 35.15 kHz hsync */
13302 + NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
13303 +- 0, FB_VMODE_NONINTERLACED
13304 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13305 + }, {
13306 + /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
13307 + NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
13308 +- 0, FB_VMODE_INTERLACED
13309 ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
13310 + }, {
13311 + /* 640x400 @ 85 Hz, 37.86 kHz hsync */
13312 + NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
13313 +- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13314 ++ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13315 + }, {
13316 + /* 640x480 @ 72 Hz, 36.5 kHz hsync */
13317 + NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
13318 +- 0, FB_VMODE_NONINTERLACED
13319 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13320 + }, {
13321 + /* 640x480 @ 75 Hz, 37.50 kHz hsync */
13322 + NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
13323 +- 0, FB_VMODE_NONINTERLACED
13324 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13325 + }, {
13326 + /* 800x600 @ 60 Hz, 37.8 kHz hsync */
13327 + NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
13328 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13329 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13330 + }, {
13331 + /* 640x480 @ 85 Hz, 43.27 kHz hsync */
13332 + NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
13333 +- 0, FB_VMODE_NONINTERLACED
13334 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13335 + }, {
13336 + /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
13337 + NULL, 69, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
13338 +- 0, FB_VMODE_INTERLACED
13339 ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
13340 + }, {
13341 + /* 800x600 @ 72 Hz, 48.0 kHz hsync */
13342 + NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
13343 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13344 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13345 + }, {
13346 + /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
13347 + NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
13348 +- 0, FB_VMODE_NONINTERLACED
13349 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13350 + }, {
13351 + /* 640x480 @ 100 Hz, 53.01 kHz hsync */
13352 + NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
13353 +- 0, FB_VMODE_NONINTERLACED
13354 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13355 + }, {
13356 + /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
13357 + NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
13358 +- 0, FB_VMODE_NONINTERLACED
13359 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13360 + }, {
13361 + /* 800x600 @ 85 Hz, 55.84 kHz hsync */
13362 + NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
13363 +- 0, FB_VMODE_NONINTERLACED
13364 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13365 + }, {
13366 + /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
13367 + NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
13368 +- 0, FB_VMODE_NONINTERLACED
13369 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13370 + }, {
13371 + /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
13372 + NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
13373 +- 0, FB_VMODE_INTERLACED
13374 ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
13375 + }, {
13376 + /* 800x600 @ 100 Hz, 64.02 kHz hsync */
13377 + NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
13378 +- 0, FB_VMODE_NONINTERLACED
13379 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13380 + }, {
13381 + /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
13382 + NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
13383 +- 0, FB_VMODE_NONINTERLACED
13384 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13385 + }, {
13386 + /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
13387 + NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
13388 +- 0, FB_VMODE_NONINTERLACED
13389 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13390 + }, {
13391 + /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
13392 + NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
13393 +- 0, FB_VMODE_NONINTERLACED
13394 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13395 + }, {
13396 + /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
13397 + NULL, 68, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
13398 +- 0, FB_VMODE_NONINTERLACED
13399 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13400 + }, {
13401 + /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
13402 + NULL, 75, 1400, 1050, 9271, 120, 56, 13, 0, 112, 3,
13403 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13404 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13405 + }, {
13406 + /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
13407 + NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
13408 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13409 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13410 + }, {
13411 + /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
13412 + NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
13413 +- 0, FB_VMODE_NONINTERLACED
13414 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13415 + }, {
13416 + /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
13417 + NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
13418 +- 0, FB_VMODE_NONINTERLACED
13419 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13420 + }, {
13421 + /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
13422 + NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
13423 +- 0, FB_VMODE_NONINTERLACED
13424 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13425 + }, {
13426 + /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
13427 + NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
13428 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13429 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13430 + }, {
13431 + /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
13432 + NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
13433 +- 0, FB_VMODE_NONINTERLACED
13434 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13435 + }, {
13436 + /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
13437 + NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
13438 +- 0, FB_VMODE_NONINTERLACED
13439 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13440 + }, {
13441 + /* 1024x768 @ 100Hz, 80.21 kHz hsync */
13442 + NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
13443 +- 0, FB_VMODE_NONINTERLACED
13444 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13445 + }, {
13446 + /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
13447 + NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
13448 +- 0, FB_VMODE_NONINTERLACED
13449 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13450 + }, {
13451 + /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
13452 + NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
13453 +- 0, FB_VMODE_NONINTERLACED
13454 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13455 + }, {
13456 + /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
13457 + NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
13458 +- 0, FB_VMODE_NONINTERLACED
13459 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13460 + }, {
13461 + /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
13462 + NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
13463 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13464 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13465 + }, {
13466 + /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
13467 + NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
13468 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13469 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13470 + }, {
13471 + /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
13472 + NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
13473 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13474 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13475 + }, {
13476 + /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
13477 + NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
13478 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13479 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13480 + }, {
13481 + /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
13482 + NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
13483 +- 0, FB_VMODE_NONINTERLACED
13484 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13485 + }, {
13486 + /* 1800x1440 @ 64Hz, 96.15 kHz hsync */
13487 + NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
13488 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13489 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13490 + }, {
13491 + /* 1800x1440 @ 70Hz, 104.52 kHz hsync */
13492 + NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
13493 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13494 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13495 + }, {
13496 + /* 512x384 @ 78 Hz, 31.50 kHz hsync */
13497 + NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
13498 +- 0, FB_VMODE_NONINTERLACED
13499 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13500 + }, {
13501 + /* 512x384 @ 85 Hz, 34.38 kHz hsync */
13502 + NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
13503 +- 0, FB_VMODE_NONINTERLACED
13504 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13505 + }, {
13506 + /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
13507 + NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
13508 +- 0, FB_VMODE_DOUBLE
13509 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13510 + }, {
13511 + /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
13512 + NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
13513 +- 0, FB_VMODE_DOUBLE
13514 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13515 + }, {
13516 + /* 320x240 @ 72 Hz, 36.5 kHz hsync */
13517 + NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
13518 +- 0, FB_VMODE_DOUBLE
13519 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13520 + }, {
13521 + /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
13522 + NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
13523 +- 0, FB_VMODE_DOUBLE
13524 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13525 + }, {
13526 + /* 400x300 @ 60 Hz, 37.8 kHz hsync */
13527 + NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
13528 +- 0, FB_VMODE_DOUBLE
13529 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13530 + }, {
13531 + /* 400x300 @ 72 Hz, 48.0 kHz hsync */
13532 + NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
13533 +- 0, FB_VMODE_DOUBLE
13534 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13535 + }, {
13536 + /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
13537 + NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
13538 +- 0, FB_VMODE_DOUBLE
13539 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13540 + }, {
13541 + /* 480x300 @ 60 Hz, 37.8 kHz hsync */
13542 + NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
13543 +- 0, FB_VMODE_DOUBLE
13544 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13545 + }, {
13546 + /* 480x300 @ 63 Hz, 39.6 kHz hsync */
13547 + NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
13548 +- 0, FB_VMODE_DOUBLE
13549 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13550 + }, {
13551 + /* 480x300 @ 72 Hz, 48.0 kHz hsync */
13552 + NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
13553 +- 0, FB_VMODE_DOUBLE
13554 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13555 + }, {
13556 + /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
13557 + NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
13558 + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
13559 +- FB_VMODE_NONINTERLACED
13560 ++ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13561 + }, {
13562 + /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
13563 + NULL, 60, 1152, 768, 15386, 158, 26, 29, 3, 136, 6,
13564 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13565 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13566 + }, {
13567 + /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
13568 + NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
13569 +- 0, FB_VMODE_NONINTERLACED
13570 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13571 + },
13572 + };
13573 +
13574 +diff -Nurp linux-2.6.23.15/drivers/video/vesafb.c linux-2.6.23.15-grsec/drivers/video/vesafb.c
13575 +--- linux-2.6.23.15/drivers/video/vesafb.c 2007-10-09 21:31:38.000000000 +0100
13576 ++++ linux-2.6.23.15-grsec/drivers/video/vesafb.c 2008-02-11 10:37:44.000000000 +0000
13577 +@@ -9,6 +9,7 @@
13578 + */
13579 +
13580 + #include <linux/module.h>
13581 ++#include <linux/moduleloader.h>
13582 + #include <linux/kernel.h>
13583 + #include <linux/errno.h>
13584 + #include <linux/string.h>
13585 +@@ -224,6 +225,7 @@ static int __init vesafb_probe(struct pl
13586 + unsigned int size_vmode;
13587 + unsigned int size_remap;
13588 + unsigned int size_total;
13589 ++ void *pmi_code = NULL;
13590 +
13591 + if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
13592 + return -ENODEV;
13593 +@@ -266,10 +268,6 @@ static int __init vesafb_probe(struct pl
13594 + size_remap = size_total;
13595 + vesafb_fix.smem_len = size_remap;
13596 +
13597 +-#ifndef __i386__
13598 +- screen_info.vesapm_seg = 0;
13599 +-#endif
13600 +-
13601 + if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
13602 + printk(KERN_WARNING
13603 + "vesafb: cannot reserve video memory at 0x%lx\n",
13604 +@@ -302,9 +300,21 @@ static int __init vesafb_probe(struct pl
13605 + printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
13606 + vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
13607 +
13608 ++#ifdef __i386__
13609 ++
13610 ++#ifdef CONFIG_PAX_KERNEXEC
13611 ++ pmi_code = module_alloc_exec(screen_info.vesapm_size);
13612 ++ if (!pmi_code)
13613 ++#else
13614 ++ if (0)
13615 ++#endif
13616 ++
13617 ++#endif
13618 ++ screen_info.vesapm_seg = 0;
13619 ++
13620 + if (screen_info.vesapm_seg) {
13621 +- printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
13622 +- screen_info.vesapm_seg,screen_info.vesapm_off);
13623 ++ printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n",
13624 ++ screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size);
13625 + }
13626 +
13627 + if (screen_info.vesapm_seg < 0xc000)
13628 +@@ -312,9 +322,29 @@ static int __init vesafb_probe(struct pl
13629 +
13630 + if (ypan || pmi_setpal) {
13631 + unsigned short *pmi_base;
13632 +- pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
13633 +- pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
13634 +- pmi_pal = (void*)((char*)pmi_base + pmi_base[2]);
13635 ++
13636 ++#ifdef CONFIG_PAX_KERNEXEC
13637 ++ unsigned long cr0;
13638 ++#endif
13639 ++
13640 ++ pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
13641 ++
13642 ++#ifdef CONFIG_PAX_KERNEXEC
13643 ++ pax_open_kernel(cr0);
13644 ++ memcpy(pmi_code, pmi_base, screen_info.vesapm_size);
13645 ++ pax_close_kernel(cr0);
13646 ++#else
13647 ++ pmi_code = pmi_base;
13648 ++#endif
13649 ++
13650 ++ pmi_start = (void*)((char*)pmi_code + pmi_base[1]);
13651 ++ pmi_pal = (void*)((char*)pmi_code + pmi_base[2]);
13652 ++
13653 ++#ifdef CONFIG_PAX_KERNEXEC
13654 ++ pmi_start -= __KERNEL_TEXT_OFFSET;
13655 ++ pmi_pal -= __KERNEL_TEXT_OFFSET;
13656 ++#endif
13657 ++
13658 + printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
13659 + if (pmi_base[3]) {
13660 + printk(KERN_INFO "vesafb: pmi: ports = ");
13661 +@@ -456,6 +486,11 @@ static int __init vesafb_probe(struct pl
13662 + info->node, info->fix.id);
13663 + return 0;
13664 + err:
13665 ++
13666 ++#ifdef CONFIG_PAX_KERNEXEC
13667 ++ module_free_exec(NULL, pmi_code);
13668 ++#endif
13669 ++
13670 + if (info->screen_base)
13671 + iounmap(info->screen_base);
13672 + framebuffer_release(info);
13673 +diff -Nurp linux-2.6.23.15/fs/Kconfig linux-2.6.23.15-grsec/fs/Kconfig
13674 +--- linux-2.6.23.15/fs/Kconfig 2007-10-09 21:31:38.000000000 +0100
13675 ++++ linux-2.6.23.15-grsec/fs/Kconfig 2008-02-11 10:37:44.000000000 +0000
13676 +@@ -909,7 +909,7 @@ config PROC_FS
13677 +
13678 + config PROC_KCORE
13679 + bool "/proc/kcore support" if !ARM
13680 +- depends on PROC_FS && MMU
13681 ++ depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
13682 +
13683 + config PROC_VMCORE
13684 + bool "/proc/vmcore support (EXPERIMENTAL)"
13685 +diff -Nurp linux-2.6.23.15/fs/binfmt_aout.c linux-2.6.23.15-grsec/fs/binfmt_aout.c
13686 +--- linux-2.6.23.15/fs/binfmt_aout.c 2007-10-09 21:31:38.000000000 +0100
13687 ++++ linux-2.6.23.15-grsec/fs/binfmt_aout.c 2008-02-11 10:37:44.000000000 +0000
13688 +@@ -24,6 +24,7 @@
13689 + #include <linux/binfmts.h>
13690 + #include <linux/personality.h>
13691 + #include <linux/init.h>
13692 ++#include <linux/grsecurity.h>
13693 +
13694 + #include <asm/system.h>
13695 + #include <asm/uaccess.h>
13696 +@@ -123,10 +124,12 @@ static int aout_core_dump(long signr, st
13697 + /* If the size of the dump file exceeds the rlimit, then see what would happen
13698 + if we wrote the stack, but not the data area. */
13699 + #ifdef __sparc__
13700 ++ gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize, 1);
13701 + if ((dump.u_dsize+dump.u_ssize) >
13702 + current->signal->rlim[RLIMIT_CORE].rlim_cur)
13703 + dump.u_dsize = 0;
13704 + #else
13705 ++ gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE, 1);
13706 + if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
13707 + current->signal->rlim[RLIMIT_CORE].rlim_cur)
13708 + dump.u_dsize = 0;
13709 +@@ -134,10 +137,12 @@ static int aout_core_dump(long signr, st
13710 +
13711 + /* Make sure we have enough room to write the stack and data areas. */
13712 + #ifdef __sparc__
13713 ++ gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
13714 + if ((dump.u_ssize) >
13715 + current->signal->rlim[RLIMIT_CORE].rlim_cur)
13716 + dump.u_ssize = 0;
13717 + #else
13718 ++ gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE, 1);
13719 + if ((dump.u_ssize+1) * PAGE_SIZE >
13720 + current->signal->rlim[RLIMIT_CORE].rlim_cur)
13721 + dump.u_ssize = 0;
13722 +@@ -294,6 +299,8 @@ static int load_aout_binary(struct linux
13723 + rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
13724 + if (rlim >= RLIM_INFINITY)
13725 + rlim = ~0;
13726 ++
13727 ++ gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
13728 + if (ex.a_data + ex.a_bss > rlim)
13729 + return -ENOMEM;
13730 +
13731 +@@ -326,6 +333,28 @@ static int load_aout_binary(struct linux
13732 + current->mm->mmap = NULL;
13733 + compute_creds(bprm);
13734 + current->flags &= ~PF_FORKNOEXEC;
13735 ++
13736 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
13737 ++ current->mm->pax_flags = 0UL;
13738 ++#endif
13739 ++
13740 ++#ifdef CONFIG_PAX_PAGEEXEC
13741 ++ if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
13742 ++ current->mm->pax_flags |= MF_PAX_PAGEEXEC;
13743 ++
13744 ++#ifdef CONFIG_PAX_EMUTRAMP
13745 ++ if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
13746 ++ current->mm->pax_flags |= MF_PAX_EMUTRAMP;
13747 ++#endif
13748 ++
13749 ++#ifdef CONFIG_PAX_MPROTECT
13750 ++ if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
13751 ++ current->mm->pax_flags |= MF_PAX_MPROTECT;
13752 ++#endif
13753 ++
13754 ++ }
13755 ++#endif
13756 ++
13757 + #ifdef __sparc__
13758 + if (N_MAGIC(ex) == NMAGIC) {
13759 + loff_t pos = fd_offset;
13760 +@@ -421,7 +450,7 @@ static int load_aout_binary(struct linux
13761 +
13762 + down_write(&current->mm->mmap_sem);
13763 + error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
13764 +- PROT_READ | PROT_WRITE | PROT_EXEC,
13765 ++ PROT_READ | PROT_WRITE,
13766 + MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
13767 + fd_offset + ex.a_text);
13768 + up_write(&current->mm->mmap_sem);
13769 +diff -Nurp linux-2.6.23.15/fs/binfmt_elf.c linux-2.6.23.15-grsec/fs/binfmt_elf.c
13770 +--- linux-2.6.23.15/fs/binfmt_elf.c 2007-10-09 21:31:38.000000000 +0100
13771 ++++ linux-2.6.23.15-grsec/fs/binfmt_elf.c 2008-02-11 10:37:44.000000000 +0000
13772 +@@ -39,10 +39,21 @@
13773 + #include <linux/random.h>
13774 + #include <linux/elf.h>
13775 + #include <linux/utsname.h>
13776 ++#include <linux/grsecurity.h>
13777 ++
13778 + #include <asm/uaccess.h>
13779 + #include <asm/param.h>
13780 + #include <asm/page.h>
13781 +
13782 ++#ifdef CONFIG_PAX_SEGMEXEC
13783 ++#include <asm/desc.h>
13784 ++#endif
13785 ++
13786 ++#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
13787 ++void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
13788 ++EXPORT_SYMBOL(pax_set_initial_flags_func);
13789 ++#endif
13790 ++
13791 + static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
13792 + static int load_elf_library(struct file *);
13793 + static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int);
13794 +@@ -84,6 +95,8 @@ static struct linux_binfmt elf_format =
13795 +
13796 + static int set_brk(unsigned long start, unsigned long end)
13797 + {
13798 ++ unsigned long e = end;
13799 ++
13800 + start = ELF_PAGEALIGN(start);
13801 + end = ELF_PAGEALIGN(end);
13802 + if (end > start) {
13803 +@@ -94,7 +107,7 @@ static int set_brk(unsigned long start,
13804 + if (BAD_ADDR(addr))
13805 + return addr;
13806 + }
13807 +- current->mm->start_brk = current->mm->brk = end;
13808 ++ current->mm->start_brk = current->mm->brk = e;
13809 + return 0;
13810 + }
13811 +
13812 +@@ -325,10 +338,9 @@ static unsigned long load_elf_interp(str
13813 + {
13814 + struct elf_phdr *elf_phdata;
13815 + struct elf_phdr *eppnt;
13816 +- unsigned long load_addr = 0;
13817 +- int load_addr_set = 0;
13818 ++ unsigned long load_addr = 0, min_addr, max_addr, task_size = TASK_SIZE;
13819 + unsigned long last_bss = 0, elf_bss = 0;
13820 +- unsigned long error = ~0UL;
13821 ++ unsigned long error = -EINVAL;
13822 + int retval, i, size;
13823 +
13824 + /* First of all, some simple consistency checks */
13825 +@@ -367,66 +379,86 @@ static unsigned long load_elf_interp(str
13826 + goto out_close;
13827 + }
13828 +
13829 ++#ifdef CONFIG_PAX_SEGMEXEC
13830 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
13831 ++ task_size = SEGMEXEC_TASK_SIZE;
13832 ++#endif
13833 ++
13834 + eppnt = elf_phdata;
13835 ++ min_addr = task_size;
13836 ++ max_addr = 0;
13837 ++ error = -ENOMEM;
13838 ++
13839 + for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
13840 +- if (eppnt->p_type == PT_LOAD) {
13841 +- int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
13842 +- int elf_prot = 0;
13843 +- unsigned long vaddr = 0;
13844 +- unsigned long k, map_addr;
13845 +-
13846 +- if (eppnt->p_flags & PF_R)
13847 +- elf_prot = PROT_READ;
13848 +- if (eppnt->p_flags & PF_W)
13849 +- elf_prot |= PROT_WRITE;
13850 +- if (eppnt->p_flags & PF_X)
13851 +- elf_prot |= PROT_EXEC;
13852 +- vaddr = eppnt->p_vaddr;
13853 +- if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
13854 +- elf_type |= MAP_FIXED;
13855 +-
13856 +- map_addr = elf_map(interpreter, load_addr + vaddr,
13857 +- eppnt, elf_prot, elf_type);
13858 +- error = map_addr;
13859 +- if (BAD_ADDR(map_addr))
13860 +- goto out_close;
13861 +-
13862 +- if (!load_addr_set &&
13863 +- interp_elf_ex->e_type == ET_DYN) {
13864 +- load_addr = map_addr - ELF_PAGESTART(vaddr);
13865 +- load_addr_set = 1;
13866 +- }
13867 ++ if (eppnt->p_type != PT_LOAD)
13868 ++ continue;
13869 +
13870 +- /*
13871 +- * Check to see if the section's size will overflow the
13872 +- * allowed task size. Note that p_filesz must always be
13873 +- * <= p_memsize so it's only necessary to check p_memsz.
13874 +- */
13875 +- k = load_addr + eppnt->p_vaddr;
13876 +- if (BAD_ADDR(k) ||
13877 +- eppnt->p_filesz > eppnt->p_memsz ||
13878 +- eppnt->p_memsz > TASK_SIZE ||
13879 +- TASK_SIZE - eppnt->p_memsz < k) {
13880 +- error = -ENOMEM;
13881 +- goto out_close;
13882 +- }
13883 ++ /*
13884 ++ * Check to see if the section's size will overflow the
13885 ++ * allowed task size. Note that p_filesz must always be
13886 ++ * <= p_memsize so it is only necessary to check p_memsz.
13887 ++ */
13888 ++ if (eppnt->p_filesz > eppnt->p_memsz || eppnt->p_vaddr >= eppnt->p_vaddr + eppnt->p_memsz)
13889 ++ goto out_close;
13890 +
13891 +- /*
13892 +- * Find the end of the file mapping for this phdr, and
13893 +- * keep track of the largest address we see for this.
13894 +- */
13895 +- k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
13896 +- if (k > elf_bss)
13897 +- elf_bss = k;
13898 ++ if (min_addr > ELF_PAGESTART(eppnt->p_vaddr))
13899 ++ min_addr = ELF_PAGESTART(eppnt->p_vaddr);
13900 ++ if (max_addr < ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz))
13901 ++ max_addr = ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz);
13902 ++ }
13903 ++ if (min_addr >= max_addr || max_addr > task_size)
13904 ++ goto out_close;
13905 +
13906 +- /*
13907 +- * Do the same thing for the memory mapping - between
13908 +- * elf_bss and last_bss is the bss section.
13909 +- */
13910 +- k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
13911 +- if (k > last_bss)
13912 +- last_bss = k;
13913 +- }
13914 ++ if (interp_elf_ex->e_type == ET_DYN) {
13915 ++ load_addr = get_unmapped_area(interpreter, 0, max_addr - min_addr, 0, MAP_PRIVATE | MAP_EXECUTABLE);
13916 ++
13917 ++ if (load_addr >= task_size)
13918 ++ goto out_close;
13919 ++
13920 ++ load_addr -= min_addr;
13921 ++ }
13922 ++
13923 ++ eppnt = elf_phdata;
13924 ++ for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
13925 ++ int elf_type = MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED;
13926 ++ int elf_prot = 0;
13927 ++ unsigned long vaddr = 0;
13928 ++ unsigned long k, map_addr;
13929 ++
13930 ++ if (eppnt->p_type != PT_LOAD)
13931 ++ continue;
13932 ++
13933 ++ if (eppnt->p_flags & PF_R)
13934 ++ elf_prot = PROT_READ;
13935 ++ if (eppnt->p_flags & PF_W)
13936 ++ elf_prot |= PROT_WRITE;
13937 ++ if (eppnt->p_flags & PF_X)
13938 ++ elf_prot |= PROT_EXEC;
13939 ++ vaddr = eppnt->p_vaddr;
13940 ++
13941 ++ map_addr = elf_map(interpreter, load_addr + vaddr,
13942 ++ eppnt, elf_prot, elf_type);
13943 ++ error = map_addr;
13944 ++ if (BAD_ADDR(map_addr))
13945 ++ goto out_close;
13946 ++
13947 ++ k = load_addr + eppnt->p_vaddr;
13948 ++
13949 ++ /*
13950 ++ * Find the end of the file mapping for this phdr, and
13951 ++ * keep track of the largest address we see for this.
13952 ++ */
13953 ++ k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
13954 ++ if (k > elf_bss)
13955 ++ elf_bss = k;
13956 ++
13957 ++ /*
13958 ++ * Do the same thing for the memory mapping - between
13959 ++ * elf_bss and last_bss is the bss section.
13960 ++ */
13961 ++ k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
13962 ++ if (k > last_bss)
13963 ++ last_bss = k;
13964 + }
13965 +
13966 + /*
13967 +@@ -454,6 +486,8 @@ static unsigned long load_elf_interp(str
13968 +
13969 + *interp_load_addr = load_addr;
13970 + error = ((unsigned long)interp_elf_ex->e_entry) + load_addr;
13971 ++ if (BAD_ADDR(error))
13972 ++ error = -EFAULT;
13973 +
13974 + out_close:
13975 + kfree(elf_phdata);
13976 +@@ -464,7 +498,7 @@ out:
13977 + static unsigned long load_aout_interp(struct exec *interp_ex,
13978 + struct file *interpreter)
13979 + {
13980 +- unsigned long text_data, elf_entry = ~0UL;
13981 ++ unsigned long text_data, elf_entry = -EINVAL;
13982 + char __user * addr;
13983 + loff_t offset;
13984 +
13985 +@@ -507,6 +541,177 @@ out:
13986 + return elf_entry;
13987 + }
13988 +
13989 ++#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
13990 ++static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
13991 ++{
13992 ++ unsigned long pax_flags = 0UL;
13993 ++
13994 ++#ifdef CONFIG_PAX_PAGEEXEC
13995 ++ if (elf_phdata->p_flags & PF_PAGEEXEC)
13996 ++ pax_flags |= MF_PAX_PAGEEXEC;
13997 ++#endif
13998 ++
13999 ++#ifdef CONFIG_PAX_SEGMEXEC
14000 ++ if (elf_phdata->p_flags & PF_SEGMEXEC)
14001 ++ pax_flags |= MF_PAX_SEGMEXEC;
14002 ++#endif
14003 ++
14004 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
14005 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14006 ++ if (nx_enabled)
14007 ++ pax_flags &= ~MF_PAX_SEGMEXEC;
14008 ++ else
14009 ++ pax_flags &= ~MF_PAX_PAGEEXEC;
14010 ++ }
14011 ++#endif
14012 ++
14013 ++#ifdef CONFIG_PAX_EMUTRAMP
14014 ++ if (elf_phdata->p_flags & PF_EMUTRAMP)
14015 ++ pax_flags |= MF_PAX_EMUTRAMP;
14016 ++#endif
14017 ++
14018 ++#ifdef CONFIG_PAX_MPROTECT
14019 ++ if (elf_phdata->p_flags & PF_MPROTECT)
14020 ++ pax_flags |= MF_PAX_MPROTECT;
14021 ++#endif
14022 ++
14023 ++#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
14024 ++ if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
14025 ++ pax_flags |= MF_PAX_RANDMMAP;
14026 ++#endif
14027 ++
14028 ++ return pax_flags;
14029 ++}
14030 ++#endif
14031 ++
14032 ++#ifdef CONFIG_PAX_PT_PAX_FLAGS
14033 ++static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
14034 ++{
14035 ++ unsigned long pax_flags = 0UL;
14036 ++
14037 ++#ifdef CONFIG_PAX_PAGEEXEC
14038 ++ if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
14039 ++ pax_flags |= MF_PAX_PAGEEXEC;
14040 ++#endif
14041 ++
14042 ++#ifdef CONFIG_PAX_SEGMEXEC
14043 ++ if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
14044 ++ pax_flags |= MF_PAX_SEGMEXEC;
14045 ++#endif
14046 ++
14047 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
14048 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14049 ++ if (nx_enabled)
14050 ++ pax_flags &= ~MF_PAX_SEGMEXEC;
14051 ++ else
14052 ++ pax_flags &= ~MF_PAX_PAGEEXEC;
14053 ++ }
14054 ++#endif
14055 ++
14056 ++#ifdef CONFIG_PAX_EMUTRAMP
14057 ++ if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
14058 ++ pax_flags |= MF_PAX_EMUTRAMP;
14059 ++#endif
14060 ++
14061 ++#ifdef CONFIG_PAX_MPROTECT
14062 ++ if (!(elf_phdata->p_flags & PF_NOMPROTECT))
14063 ++ pax_flags |= MF_PAX_MPROTECT;
14064 ++#endif
14065 ++
14066 ++#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
14067 ++ if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
14068 ++ pax_flags |= MF_PAX_RANDMMAP;
14069 ++#endif
14070 ++
14071 ++ return pax_flags;
14072 ++}
14073 ++#endif
14074 ++
14075 ++#ifdef CONFIG_PAX_EI_PAX
14076 ++static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
14077 ++{
14078 ++ unsigned long pax_flags = 0UL;
14079 ++
14080 ++#ifdef CONFIG_PAX_PAGEEXEC
14081 ++ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
14082 ++ pax_flags |= MF_PAX_PAGEEXEC;
14083 ++#endif
14084 ++
14085 ++#ifdef CONFIG_PAX_SEGMEXEC
14086 ++ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
14087 ++ pax_flags |= MF_PAX_SEGMEXEC;
14088 ++#endif
14089 ++
14090 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
14091 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14092 ++ if (nx_enabled)
14093 ++ pax_flags &= ~MF_PAX_SEGMEXEC;
14094 ++ else
14095 ++ pax_flags &= ~MF_PAX_PAGEEXEC;
14096 ++ }
14097 ++#endif
14098 ++
14099 ++#ifdef CONFIG_PAX_EMUTRAMP
14100 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
14101 ++ pax_flags |= MF_PAX_EMUTRAMP;
14102 ++#endif
14103 ++
14104 ++#ifdef CONFIG_PAX_MPROTECT
14105 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
14106 ++ pax_flags |= MF_PAX_MPROTECT;
14107 ++#endif
14108 ++
14109 ++#ifdef CONFIG_PAX_ASLR
14110 ++ if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
14111 ++ pax_flags |= MF_PAX_RANDMMAP;
14112 ++#endif
14113 ++
14114 ++ return pax_flags;
14115 ++}
14116 ++#endif
14117 ++
14118 ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
14119 ++static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
14120 ++{
14121 ++ unsigned long pax_flags = 0UL;
14122 ++
14123 ++#ifdef CONFIG_PAX_PT_PAX_FLAGS
14124 ++ unsigned long i;
14125 ++#endif
14126 ++
14127 ++#ifdef CONFIG_PAX_EI_PAX
14128 ++ pax_flags = pax_parse_ei_pax(elf_ex);
14129 ++#endif
14130 ++
14131 ++#ifdef CONFIG_PAX_PT_PAX_FLAGS
14132 ++ for (i = 0UL; i < elf_ex->e_phnum; i++)
14133 ++ if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
14134 ++ if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
14135 ++ ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
14136 ++ ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
14137 ++ ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
14138 ++ ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
14139 ++ return -EINVAL;
14140 ++
14141 ++#ifdef CONFIG_PAX_SOFTMODE
14142 ++ if (pax_softmode)
14143 ++ pax_flags = pax_parse_softmode(&elf_phdata[i]);
14144 ++ else
14145 ++#endif
14146 ++
14147 ++ pax_flags = pax_parse_hardmode(&elf_phdata[i]);
14148 ++ break;
14149 ++ }
14150 ++#endif
14151 ++
14152 ++ if (0 > pax_check_flags(&pax_flags))
14153 ++ return -EINVAL;
14154 ++
14155 ++ current->mm->pax_flags = pax_flags;
14156 ++ return 0;
14157 ++}
14158 ++#endif
14159 ++
14160 + /*
14161 + * These are the functions used to load ELF style executables and shared
14162 + * libraries. There is no binary dependent code anywhere else.
14163 +@@ -544,7 +749,7 @@ static int load_elf_binary(struct linux_
14164 + char * elf_interpreter = NULL;
14165 + unsigned int interpreter_type = INTERPRETER_NONE;
14166 + unsigned char ibcs2_interpreter = 0;
14167 +- unsigned long error;
14168 ++ unsigned long error = 0;
14169 + struct elf_phdr *elf_ppnt, *elf_phdata;
14170 + unsigned long elf_bss, elf_brk;
14171 + int elf_exec_fileno;
14172 +@@ -556,12 +761,12 @@ static int load_elf_binary(struct linux_
14173 + char passed_fileno[6];
14174 + struct files_struct *files;
14175 + int executable_stack = EXSTACK_DEFAULT;
14176 +- unsigned long def_flags = 0;
14177 + struct {
14178 + struct elfhdr elf_ex;
14179 + struct elfhdr interp_elf_ex;
14180 + struct exec interp_ex;
14181 + } *loc;
14182 ++ unsigned long task_size = TASK_SIZE;
14183 +
14184 + loc = kmalloc(sizeof(*loc), GFP_KERNEL);
14185 + if (!loc) {
14186 +@@ -788,14 +993,89 @@ static int load_elf_binary(struct linux_
14187 +
14188 + /* OK, This is the point of no return */
14189 + current->flags &= ~PF_FORKNOEXEC;
14190 +- current->mm->def_flags = def_flags;
14191 ++
14192 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
14193 ++ current->mm->pax_flags = 0UL;
14194 ++#endif
14195 ++
14196 ++#ifdef CONFIG_PAX_DLRESOLVE
14197 ++ current->mm->call_dl_resolve = 0UL;
14198 ++#endif
14199 ++
14200 ++#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
14201 ++ current->mm->call_syscall = 0UL;
14202 ++#endif
14203 ++
14204 ++#ifdef CONFIG_PAX_ASLR
14205 ++ current->mm->delta_mmap = 0UL;
14206 ++ current->mm->delta_stack = 0UL;
14207 ++#endif
14208 ++
14209 ++ current->mm->def_flags = 0;
14210 ++
14211 ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
14212 ++ if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
14213 ++ send_sig(SIGKILL, current, 0);
14214 ++ goto out_free_dentry;
14215 ++ }
14216 ++#endif
14217 ++
14218 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
14219 ++ pax_set_initial_flags(bprm);
14220 ++#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
14221 ++ if (pax_set_initial_flags_func)
14222 ++ (pax_set_initial_flags_func)(bprm);
14223 ++#endif
14224 ++
14225 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
14226 ++ if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !nx_enabled) {
14227 ++ current->mm->context.user_cs_limit = PAGE_SIZE;
14228 ++ current->mm->def_flags |= VM_PAGEEXEC;
14229 ++ }
14230 ++#endif
14231 ++
14232 ++#ifdef CONFIG_PAX_SEGMEXEC
14233 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
14234 ++ current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
14235 ++ current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE;
14236 ++ task_size = SEGMEXEC_TASK_SIZE;
14237 ++ }
14238 ++#endif
14239 ++
14240 ++#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
14241 ++ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14242 ++ set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
14243 ++ put_cpu_no_resched();
14244 ++ }
14245 ++#endif
14246 ++
14247 ++#ifdef CONFIG_PAX_ASLR
14248 ++ if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
14249 ++ current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT;
14250 ++ current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT;
14251 ++ }
14252 ++#endif
14253 ++
14254 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
14255 ++ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
14256 ++ executable_stack = EXSTACK_DEFAULT;
14257 ++#endif
14258 +
14259 + /* Do this immediately, since STACK_TOP as used in setup_arg_pages
14260 + may depend on the personality. */
14261 + SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);
14262 ++
14263 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
14264 ++ if (!(current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)))
14265 ++#endif
14266 ++
14267 + if (elf_read_implies_exec(loc->elf_ex, executable_stack))
14268 + current->personality |= READ_IMPLIES_EXEC;
14269 +
14270 ++#ifdef CONFIG_PAX_ASLR
14271 ++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
14272 ++#endif
14273 ++
14274 + if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
14275 + current->flags |= PF_RANDOMIZE;
14276 + arch_pick_mmap_layout(current->mm);
14277 +@@ -871,6 +1151,20 @@ static int load_elf_binary(struct linux_
14278 + * might try to exec. This is because the brk will
14279 + * follow the loader, and is not movable. */
14280 + load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
14281 ++
14282 ++#ifdef CONFIG_PAX_RANDMMAP
14283 ++ /* PaX: randomize base address at the default exe base if requested */
14284 ++ if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) {
14285 ++#ifdef CONFIG_SPARC64
14286 ++ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1);
14287 ++#else
14288 ++ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT;
14289 ++#endif
14290 ++ load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias);
14291 ++ elf_flags |= MAP_FIXED;
14292 ++ }
14293 ++#endif
14294 ++
14295 + }
14296 +
14297 + error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
14298 +@@ -903,9 +1197,9 @@ static int load_elf_binary(struct linux_
14299 + * allowed task size. Note that p_filesz must always be
14300 + * <= p_memsz so it is only necessary to check p_memsz.
14301 + */
14302 +- if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
14303 +- elf_ppnt->p_memsz > TASK_SIZE ||
14304 +- TASK_SIZE - elf_ppnt->p_memsz < k) {
14305 ++ if (k >= task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
14306 ++ elf_ppnt->p_memsz > task_size ||
14307 ++ task_size - elf_ppnt->p_memsz < k) {
14308 + /* set_brk can never work. Avoid overflows. */
14309 + send_sig(SIGKILL, current, 0);
14310 + retval = -EINVAL;
14311 +@@ -933,6 +1227,11 @@ static int load_elf_binary(struct linux_
14312 + start_data += load_bias;
14313 + end_data += load_bias;
14314 +
14315 ++#ifdef CONFIG_PAX_RANDMMAP
14316 ++ if (current->mm->pax_flags & MF_PAX_RANDMMAP)
14317 ++ elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4);
14318 ++#endif
14319 ++
14320 + /* Calling set_brk effectively mmaps the pages that we need
14321 + * for the bss and break sections. We must do this before
14322 + * mapping in the interpreter, to make sure it doesn't wind
14323 +@@ -944,9 +1243,11 @@ static int load_elf_binary(struct linux_
14324 + goto out_free_dentry;
14325 + }
14326 + if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
14327 +- send_sig(SIGSEGV, current, 0);
14328 +- retval = -EFAULT; /* Nobody gets to see this, but.. */
14329 +- goto out_free_dentry;
14330 ++ /*
14331 ++ * This bss-zeroing can fail if the ELF
14332 ++ * file specifies odd protections. So
14333 ++ * we don't check the return value
14334 ++ */
14335 + }
14336 +
14337 + if (elf_interpreter) {
14338 +@@ -1183,8 +1484,10 @@ static int dump_seek(struct file *file,
14339 + unsigned long n = off;
14340 + if (n > PAGE_SIZE)
14341 + n = PAGE_SIZE;
14342 +- if (!dump_write(file, buf, n))
14343 ++ if (!dump_write(file, buf, n)) {
14344 ++ free_page((unsigned long)buf);
14345 + return 0;
14346 ++ }
14347 + off -= n;
14348 + }
14349 + free_page((unsigned long)buf);
14350 +@@ -1199,7 +1502,7 @@ static int dump_seek(struct file *file,
14351 + *
14352 + * I think we should skip something. But I am not sure how. H.J.
14353 + */
14354 +-static int maydump(struct vm_area_struct *vma, unsigned long mm_flags)
14355 ++static int maydump(struct vm_area_struct *vma, unsigned long mm_flags, long signr)
14356 + {
14357 + /* The vma can be set up to tell us the answer directly. */
14358 + if (vma->vm_flags & VM_ALWAYSDUMP)
14359 +@@ -1218,7 +1521,7 @@ static int maydump(struct vm_area_struct
14360 + }
14361 +
14362 + /* By default, if it hasn't been written to, don't write it out. */
14363 +- if (!vma->anon_vma)
14364 ++ if (signr != SIGKILL && !vma->anon_vma)
14365 + return test_bit(MMF_DUMP_MAPPED_PRIVATE, &mm_flags);
14366 +
14367 + return test_bit(MMF_DUMP_ANON_PRIVATE, &mm_flags);
14368 +@@ -1275,8 +1578,11 @@ static int writenote(struct memelfnote *
14369 + #undef DUMP_WRITE
14370 +
14371 + #define DUMP_WRITE(addr, nr) \
14372 ++ do { \
14373 ++ gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
14374 + if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
14375 +- goto end_coredump;
14376 ++ goto end_coredump; \
14377 ++ } while (0);
14378 + #define DUMP_SEEK(off) \
14379 + if (!dump_seek(file, (off))) \
14380 + goto end_coredump;
14381 +@@ -1676,7 +1982,7 @@ static int elf_core_dump(long signr, str
14382 + phdr.p_offset = offset;
14383 + phdr.p_vaddr = vma->vm_start;
14384 + phdr.p_paddr = 0;
14385 +- phdr.p_filesz = maydump(vma, mm_flags) ? sz : 0;
14386 ++ phdr.p_filesz = maydump(vma, mm_flags, signr) ? sz : 0;
14387 + phdr.p_memsz = sz;
14388 + offset += phdr.p_filesz;
14389 + phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
14390 +@@ -1720,7 +2026,7 @@ static int elf_core_dump(long signr, str
14391 + vma = next_vma(vma, gate_vma)) {
14392 + unsigned long addr;
14393 +
14394 +- if (!maydump(vma, mm_flags))
14395 ++ if (!maydump(vma, mm_flags, signr))
14396 + continue;
14397 +
14398 + for (addr = vma->vm_start;
14399 +@@ -1743,6 +2049,7 @@ static int elf_core_dump(long signr, str
14400 + flush_cache_page(vma, addr,
14401 + page_to_pfn(page));
14402 + kaddr = kmap(page);
14403 ++ gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
14404 + if ((size += PAGE_SIZE) > limit ||
14405 + !dump_write(file, kaddr,
14406 + PAGE_SIZE)) {
14407 +diff -Nurp linux-2.6.23.15/fs/binfmt_flat.c linux-2.6.23.15-grsec/fs/binfmt_flat.c
14408 +--- linux-2.6.23.15/fs/binfmt_flat.c 2007-10-09 21:31:38.000000000 +0100
14409 ++++ linux-2.6.23.15-grsec/fs/binfmt_flat.c 2008-02-11 10:37:44.000000000 +0000
14410 +@@ -559,7 +559,9 @@ static int load_flat_file(struct linux_b
14411 + realdatastart = (unsigned long) -ENOMEM;
14412 + printk("Unable to allocate RAM for process data, errno %d\n",
14413 + (int)-realdatastart);
14414 ++ down_write(&current->mm->mmap_sem);
14415 + do_munmap(current->mm, textpos, text_len);
14416 ++ up_write(&current->mm->mmap_sem);
14417 + ret = realdatastart;
14418 + goto err;
14419 + }
14420 +@@ -581,8 +583,10 @@ static int load_flat_file(struct linux_b
14421 + }
14422 + if (result >= (unsigned long)-4096) {
14423 + printk("Unable to read data+bss, errno %d\n", (int)-result);
14424 ++ down_write(&current->mm->mmap_sem);
14425 + do_munmap(current->mm, textpos, text_len);
14426 + do_munmap(current->mm, realdatastart, data_len + extra);
14427 ++ up_write(&current->mm->mmap_sem);
14428 + ret = result;
14429 + goto err;
14430 + }
14431 +@@ -655,8 +659,10 @@ static int load_flat_file(struct linux_b
14432 + }
14433 + if (result >= (unsigned long)-4096) {
14434 + printk("Unable to read code+data+bss, errno %d\n",(int)-result);
14435 ++ down_write(&current->mm->mmap_sem);
14436 + do_munmap(current->mm, textpos, text_len + data_len + extra +
14437 + MAX_SHARED_LIBS * sizeof(unsigned long));
14438 ++ up_write(&current->mm->mmap_sem);
14439 + ret = result;
14440 + goto err;
14441 + }
14442 +diff -Nurp linux-2.6.23.15/fs/binfmt_misc.c linux-2.6.23.15-grsec/fs/binfmt_misc.c
14443 +--- linux-2.6.23.15/fs/binfmt_misc.c 2007-10-09 21:31:38.000000000 +0100
14444 ++++ linux-2.6.23.15-grsec/fs/binfmt_misc.c 2008-02-11 10:37:44.000000000 +0000
14445 +@@ -113,9 +113,11 @@ static int load_misc_binary(struct linux
14446 + struct files_struct *files = NULL;
14447 +
14448 + retval = -ENOEXEC;
14449 +- if (!enabled)
14450 ++ if (!enabled || bprm->misc)
14451 + goto _ret;
14452 +
14453 ++ bprm->misc++;
14454 ++
14455 + /* to keep locking time low, we copy the interpreter string */
14456 + read_lock(&entries_lock);
14457 + fmt = check_file(bprm);
14458 +@@ -720,7 +722,7 @@ static int bm_fill_super(struct super_bl
14459 + static struct tree_descr bm_files[] = {
14460 + [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
14461 + [3] = {"register", &bm_register_operations, S_IWUSR},
14462 +- /* last one */ {""}
14463 ++ /* last one */ {"", NULL, 0}
14464 + };
14465 + int err = simple_fill_super(sb, 0x42494e4d, bm_files);
14466 + if (!err)
14467 +diff -Nurp linux-2.6.23.15/fs/buffer.c linux-2.6.23.15-grsec/fs/buffer.c
14468 +--- linux-2.6.23.15/fs/buffer.c 2007-10-09 21:31:38.000000000 +0100
14469 ++++ linux-2.6.23.15-grsec/fs/buffer.c 2008-02-11 10:37:44.000000000 +0000
14470 +@@ -41,6 +41,7 @@
14471 + #include <linux/bitops.h>
14472 + #include <linux/mpage.h>
14473 + #include <linux/bit_spinlock.h>
14474 ++#include <linux/grsecurity.h>
14475 +
14476 + static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
14477 +
14478 +@@ -2017,6 +2018,7 @@ static int __generic_cont_expand(struct
14479 +
14480 + err = -EFBIG;
14481 + limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
14482 ++ gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
14483 + if (limit != RLIM_INFINITY && size > (loff_t)limit) {
14484 + send_sig(SIGXFSZ, current, 0);
14485 + goto out;
14486 +diff -Nurp linux-2.6.23.15/fs/cifs/cifs_uniupr.h linux-2.6.23.15-grsec/fs/cifs/cifs_uniupr.h
14487 +--- linux-2.6.23.15/fs/cifs/cifs_uniupr.h 2007-10-09 21:31:38.000000000 +0100
14488 ++++ linux-2.6.23.15-grsec/fs/cifs/cifs_uniupr.h 2008-02-11 10:37:44.000000000 +0000
14489 +@@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa
14490 + {0x0490, 0x04cc, UniCaseRangeU0490},
14491 + {0x1e00, 0x1ffc, UniCaseRangeU1e00},
14492 + {0xff40, 0xff5a, UniCaseRangeUff40},
14493 +- {0}
14494 ++ {0, 0, NULL}
14495 + };
14496 + #endif
14497 +
14498 +diff -Nurp linux-2.6.23.15/fs/cifs/dir.c linux-2.6.23.15-grsec/fs/cifs/dir.c
14499 +--- linux-2.6.23.15/fs/cifs/dir.c 2007-10-09 21:31:38.000000000 +0100
14500 ++++ linux-2.6.23.15-grsec/fs/cifs/dir.c 2008-02-11 10:37:44.000000000 +0000
14501 +@@ -397,7 +397,7 @@ int cifs_mknod(struct inode *inode, stru
14502 + /* BB Do not bother to decode buf since no
14503 + local inode yet to put timestamps in,
14504 + but we can reuse it safely */
14505 +- int bytes_written;
14506 ++ unsigned int bytes_written;
14507 + struct win_dev *pdev;
14508 + pdev = (struct win_dev *)buf;
14509 + if (S_ISCHR(mode)) {
14510 +diff -Nurp linux-2.6.23.15/fs/cifs/inode.c linux-2.6.23.15-grsec/fs/cifs/inode.c
14511 +--- linux-2.6.23.15/fs/cifs/inode.c 2008-02-11 10:36:03.000000000 +0000
14512 ++++ linux-2.6.23.15-grsec/fs/cifs/inode.c 2008-02-11 10:37:44.000000000 +0000
14513 +@@ -1470,7 +1470,7 @@ int cifs_setattr(struct dentry *direntry
14514 + atomic_dec(&open_file->wrtPending);
14515 + cFYI(1, ("SetFSize for attrs rc = %d", rc));
14516 + if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
14517 +- int bytes_written;
14518 ++ unsigned int bytes_written;
14519 + rc = CIFSSMBWrite(xid, pTcon,
14520 + nfid, 0, attrs->ia_size,
14521 + &bytes_written, NULL, NULL,
14522 +@@ -1503,7 +1503,7 @@ int cifs_setattr(struct dentry *direntry
14523 + cifs_sb->mnt_cifs_flags &
14524 + CIFS_MOUNT_MAP_SPECIAL_CHR);
14525 + if (rc == 0) {
14526 +- int bytes_written;
14527 ++ unsigned int bytes_written;
14528 + rc = CIFSSMBWrite(xid, pTcon,
14529 + netfid, 0,
14530 + attrs->ia_size,
14531 +diff -Nurp linux-2.6.23.15/fs/compat.c linux-2.6.23.15-grsec/fs/compat.c
14532 +--- linux-2.6.23.15/fs/compat.c 2007-10-09 21:31:38.000000000 +0100
14533 ++++ linux-2.6.23.15-grsec/fs/compat.c 2008-02-11 10:37:44.000000000 +0000
14534 +@@ -50,6 +50,7 @@
14535 + #include <linux/poll.h>
14536 + #include <linux/mm.h>
14537 + #include <linux/eventpoll.h>
14538 ++#include <linux/grsecurity.h>
14539 +
14540 + #include <asm/uaccess.h>
14541 + #include <asm/mmu_context.h>
14542 +@@ -1300,14 +1301,12 @@ static int compat_copy_strings(int argc,
14543 + if (!kmapped_page || kpos != (pos & PAGE_MASK)) {
14544 + struct page *page;
14545 +
14546 +-#ifdef CONFIG_STACK_GROWSUP
14547 + ret = expand_stack_downwards(bprm->vma, pos);
14548 + if (ret < 0) {
14549 + /* We've exceed the stack rlimit. */
14550 + ret = -E2BIG;
14551 + goto out;
14552 + }
14553 +-#endif
14554 + ret = get_user_pages(current, bprm->mm, pos,
14555 + 1, 1, 1, &page, NULL);
14556 + if (ret <= 0) {
14557 +@@ -1353,6 +1352,11 @@ int compat_do_execve(char * filename,
14558 + compat_uptr_t __user *envp,
14559 + struct pt_regs * regs)
14560 + {
14561 ++#ifdef CONFIG_GRKERNSEC
14562 ++ struct file *old_exec_file;
14563 ++ struct acl_subject_label *old_acl;
14564 ++ struct rlimit old_rlim[RLIM_NLIMITS];
14565 ++#endif
14566 + struct linux_binprm *bprm;
14567 + struct file *file;
14568 + int retval;
14569 +@@ -1373,6 +1377,14 @@ int compat_do_execve(char * filename,
14570 + bprm->filename = filename;
14571 + bprm->interp = filename;
14572 +
14573 ++ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
14574 ++ retval = -EAGAIN;
14575 ++ if (gr_handle_nproc())
14576 ++ goto out_file;
14577 ++ retval = -EACCES;
14578 ++ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
14579 ++ goto out_file;
14580 ++
14581 + retval = bprm_mm_init(bprm);
14582 + if (retval)
14583 + goto out_file;
14584 +@@ -1406,8 +1418,36 @@ int compat_do_execve(char * filename,
14585 + if (retval < 0)
14586 + goto out;
14587 +
14588 ++ if (!gr_tpe_allow(file)) {
14589 ++ retval = -EACCES;
14590 ++ goto out;
14591 ++ }
14592 ++
14593 ++ if (gr_check_crash_exec(file)) {
14594 ++ retval = -EACCES;
14595 ++ goto out;
14596 ++ }
14597 ++
14598 ++ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
14599 ++
14600 ++ gr_handle_exec_args(bprm, (char __user * __user *)argv);
14601 ++
14602 ++#ifdef CONFIG_GRKERNSEC
14603 ++ old_acl = current->acl;
14604 ++ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
14605 ++ old_exec_file = current->exec_file;
14606 ++ get_file(file);
14607 ++ current->exec_file = file;
14608 ++#endif
14609 ++
14610 ++ gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
14611 ++
14612 + retval = search_binary_handler(bprm, regs);
14613 + if (retval >= 0) {
14614 ++#ifdef CONFIG_GRKERNSEC
14615 ++ if (old_exec_file)
14616 ++ fput(old_exec_file);
14617 ++#endif
14618 + /* execve success */
14619 + security_bprm_free(bprm);
14620 + acct_update_integrals(current);
14621 +@@ -1415,6 +1455,13 @@ int compat_do_execve(char * filename,
14622 + return retval;
14623 + }
14624 +
14625 ++#ifdef CONFIG_GRKERNSEC
14626 ++ current->acl = old_acl;
14627 ++ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
14628 ++ fput(current->exec_file);
14629 ++ current->exec_file = old_exec_file;
14630 ++#endif
14631 ++
14632 + out:
14633 + if (bprm->security)
14634 + security_bprm_free(bprm);
14635 +diff -Nurp linux-2.6.23.15/fs/compat_ioctl.c linux-2.6.23.15-grsec/fs/compat_ioctl.c
14636 +--- linux-2.6.23.15/fs/compat_ioctl.c 2007-10-09 21:31:38.000000000 +0100
14637 ++++ linux-2.6.23.15-grsec/fs/compat_ioctl.c 2008-02-11 10:37:44.000000000 +0000
14638 +@@ -2431,15 +2431,15 @@ struct ioctl_trans {
14639 + };
14640 +
14641 + #define HANDLE_IOCTL(cmd,handler) \
14642 +- { (cmd), (ioctl_trans_handler_t)(handler) },
14643 ++ { (cmd), (ioctl_trans_handler_t)(handler), NULL },
14644 +
14645 + /* pointer to compatible structure or no argument */
14646 + #define COMPATIBLE_IOCTL(cmd) \
14647 +- { (cmd), do_ioctl32_pointer },
14648 ++ { (cmd), do_ioctl32_pointer, NULL },
14649 +
14650 + /* argument is an unsigned long integer, not a pointer */
14651 + #define ULONG_IOCTL(cmd) \
14652 +- { (cmd), (ioctl_trans_handler_t)sys_ioctl },
14653 ++ { (cmd), (ioctl_trans_handler_t)sys_ioctl, NULL },
14654 +
14655 + /* ioctl should not be warned about even if it's not implemented.
14656 + Valid reasons to use this:
14657 +diff -Nurp linux-2.6.23.15/fs/debugfs/inode.c linux-2.6.23.15-grsec/fs/debugfs/inode.c
14658 +--- linux-2.6.23.15/fs/debugfs/inode.c 2007-10-09 21:31:38.000000000 +0100
14659 ++++ linux-2.6.23.15-grsec/fs/debugfs/inode.c 2008-02-11 10:37:44.000000000 +0000
14660 +@@ -125,7 +125,7 @@ static inline int debugfs_positive(struc
14661 +
14662 + static int debug_fill_super(struct super_block *sb, void *data, int silent)
14663 + {
14664 +- static struct tree_descr debug_files[] = {{""}};
14665 ++ static struct tree_descr debug_files[] = {{"", NULL, 0}};
14666 +
14667 + return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
14668 + }
14669 +diff -Nurp linux-2.6.23.15/fs/exec.c linux-2.6.23.15-grsec/fs/exec.c
14670 +--- linux-2.6.23.15/fs/exec.c 2008-02-11 10:36:03.000000000 +0000
14671 ++++ linux-2.6.23.15-grsec/fs/exec.c 2008-02-11 10:37:44.000000000 +0000
14672 +@@ -50,6 +50,8 @@
14673 + #include <linux/tsacct_kern.h>
14674 + #include <linux/cn_proc.h>
14675 + #include <linux/audit.h>
14676 ++#include <linux/random.h>
14677 ++#include <linux/grsecurity.h>
14678 +
14679 + #include <asm/uaccess.h>
14680 + #include <asm/mmu_context.h>
14681 +@@ -184,18 +186,10 @@ static struct page *get_arg_page(struct
14682 + int write)
14683 + {
14684 + struct page *page;
14685 +- int ret;
14686 +
14687 +-#ifdef CONFIG_STACK_GROWSUP
14688 +- if (write) {
14689 +- ret = expand_stack_downwards(bprm->vma, pos);
14690 +- if (ret < 0)
14691 +- return NULL;
14692 +- }
14693 +-#endif
14694 +- ret = get_user_pages(current, bprm->mm, pos,
14695 +- 1, write, 1, &page, NULL);
14696 +- if (ret <= 0)
14697 ++ if (0 > expand_stack_downwards(bprm->vma, pos))
14698 ++ return NULL;
14699 ++ if (0 >= get_user_pages(current, bprm->mm, pos, 1, write, 1, &page, NULL))
14700 + return NULL;
14701 +
14702 + if (write) {
14703 +@@ -260,7 +254,12 @@ static int __bprm_mm_init(struct linux_b
14704 + vma->vm_start = vma->vm_end - PAGE_SIZE;
14705 +
14706 + vma->vm_flags = VM_STACK_FLAGS;
14707 +- vma->vm_page_prot = protection_map[vma->vm_flags & 0x7];
14708 ++
14709 ++#ifdef CONFIG_PAX_SEGMEXEC
14710 ++ vma->vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
14711 ++#endif
14712 ++
14713 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
14714 + err = insert_vm_struct(mm, vma);
14715 + if (err) {
14716 + up_write(&mm->mmap_sem);
14717 +@@ -272,6 +271,11 @@ static int __bprm_mm_init(struct linux_b
14718 +
14719 + bprm->p = vma->vm_end - sizeof(void *);
14720 +
14721 ++#ifdef CONFIG_PAX_RANDUSTACK
14722 ++ if (randomize_va_space)
14723 ++ bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK;
14724 ++#endif
14725 ++
14726 + return 0;
14727 +
14728 + err:
14729 +@@ -395,7 +399,7 @@ static int count(char __user * __user *
14730 + if (!p)
14731 + break;
14732 + argv++;
14733 +- if(++i > max)
14734 ++ if (++i > max)
14735 + return -E2BIG;
14736 + cond_resched();
14737 + }
14738 +@@ -535,6 +539,10 @@ static int shift_arg_pages(struct vm_are
14739 + if (vma != find_vma(mm, new_start))
14740 + return -EFAULT;
14741 +
14742 ++#ifdef CONFIG_PAX_SEGMEXEC
14743 ++ BUG_ON(pax_find_mirror_vma(vma));
14744 ++#endif
14745 ++
14746 + /*
14747 + * cover the whole range: [new_start, old_end)
14748 + */
14749 +@@ -623,6 +631,14 @@ int setup_arg_pages(struct linux_binprm
14750 + bprm->exec -= stack_shift;
14751 +
14752 + down_write(&mm->mmap_sem);
14753 ++
14754 ++ /* Move stack pages down in memory. */
14755 ++ if (stack_shift) {
14756 ++ ret = shift_arg_pages(vma, stack_shift);
14757 ++ if (ret)
14758 ++ goto out_unlock;
14759 ++ }
14760 ++
14761 + vm_flags = vma->vm_flags;
14762 +
14763 + /*
14764 +@@ -634,23 +650,28 @@ int setup_arg_pages(struct linux_binprm
14765 + vm_flags |= VM_EXEC;
14766 + else if (executable_stack == EXSTACK_DISABLE_X)
14767 + vm_flags &= ~VM_EXEC;
14768 ++ else
14769 ++ vm_flags = VM_STACK_FLAGS;
14770 + vm_flags |= mm->def_flags;
14771 +
14772 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
14773 ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14774 ++ vm_flags &= ~VM_EXEC;
14775 ++
14776 ++#ifdef CONFIG_PAX_MPROTECT
14777 ++ if (mm->pax_flags & MF_PAX_MPROTECT)
14778 ++ vm_flags &= ~VM_MAYEXEC;
14779 ++#endif
14780 ++
14781 ++ }
14782 ++#endif
14783 ++
14784 + ret = mprotect_fixup(vma, &prev, vma->vm_start, vma->vm_end,
14785 + vm_flags);
14786 + if (ret)
14787 + goto out_unlock;
14788 + BUG_ON(prev != vma);
14789 +
14790 +- /* Move stack pages down in memory. */
14791 +- if (stack_shift) {
14792 +- ret = shift_arg_pages(vma, stack_shift);
14793 +- if (ret) {
14794 +- up_write(&mm->mmap_sem);
14795 +- return ret;
14796 +- }
14797 +- }
14798 +-
14799 + #ifdef CONFIG_STACK_GROWSUP
14800 + stack_base = vma->vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
14801 + #else
14802 +@@ -662,7 +683,7 @@ int setup_arg_pages(struct linux_binprm
14803 +
14804 + out_unlock:
14805 + up_write(&mm->mmap_sem);
14806 +- return 0;
14807 ++ return ret;
14808 + }
14809 + EXPORT_SYMBOL(setup_arg_pages);
14810 +
14811 +@@ -682,7 +703,7 @@ struct file *open_exec(const char *name)
14812 + file = ERR_PTR(-EACCES);
14813 + if (!(nd.mnt->mnt_flags & MNT_NOEXEC) &&
14814 + S_ISREG(inode->i_mode)) {
14815 +- int err = vfs_permission(&nd, MAY_EXEC);
14816 ++ err = vfs_permission(&nd, MAY_EXEC);
14817 + file = ERR_PTR(err);
14818 + if (!err) {
14819 + file = nameidata_to_filp(&nd, O_RDONLY);
14820 +@@ -1339,6 +1360,11 @@ int do_execve(char * filename,
14821 + char __user *__user *envp,
14822 + struct pt_regs * regs)
14823 + {
14824 ++#ifdef CONFIG_GRKERNSEC
14825 ++ struct file *old_exec_file;
14826 ++ struct acl_subject_label *old_acl;
14827 ++ struct rlimit old_rlim[RLIM_NLIMITS];
14828 ++#endif
14829 + struct linux_binprm *bprm;
14830 + struct file *file;
14831 + unsigned long env_p;
14832 +@@ -1354,6 +1380,20 @@ int do_execve(char * filename,
14833 + if (IS_ERR(file))
14834 + goto out_kfree;
14835 +
14836 ++ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
14837 ++
14838 ++ if (gr_handle_nproc()) {
14839 ++ allow_write_access(file);
14840 ++ fput(file);
14841 ++ return -EAGAIN;
14842 ++ }
14843 ++
14844 ++ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
14845 ++ allow_write_access(file);
14846 ++ fput(file);
14847 ++ return -EACCES;
14848 ++ }
14849 ++
14850 + sched_exec();
14851 +
14852 + bprm->file = file;
14853 +@@ -1395,8 +1435,38 @@ int do_execve(char * filename,
14854 + goto out;
14855 + bprm->argv_len = env_p - bprm->p;
14856 +
14857 ++ if (!gr_tpe_allow(file)) {
14858 ++ retval = -EACCES;
14859 ++ goto out;
14860 ++ }
14861 ++
14862 ++ if (gr_check_crash_exec(file)) {
14863 ++ retval = -EACCES;
14864 ++ goto out;
14865 ++ }
14866 ++
14867 ++ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
14868 ++
14869 ++ gr_handle_exec_args(bprm, argv);
14870 ++
14871 ++#ifdef CONFIG_GRKERNSEC
14872 ++ old_acl = current->acl;
14873 ++ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
14874 ++ old_exec_file = current->exec_file;
14875 ++ get_file(file);
14876 ++ current->exec_file = file;
14877 ++#endif
14878 ++
14879 ++ retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
14880 ++ if (retval < 0)
14881 ++ goto out_fail;
14882 ++
14883 + retval = search_binary_handler(bprm,regs);
14884 + if (retval >= 0) {
14885 ++#ifdef CONFIG_GRKERNSEC
14886 ++ if (old_exec_file)
14887 ++ fput(old_exec_file);
14888 ++#endif
14889 + /* execve success */
14890 + free_arg_pages(bprm);
14891 + security_bprm_free(bprm);
14892 +@@ -1405,6 +1475,14 @@ int do_execve(char * filename,
14893 + return retval;
14894 + }
14895 +
14896 ++out_fail:
14897 ++#ifdef CONFIG_GRKERNSEC
14898 ++ current->acl = old_acl;
14899 ++ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
14900 ++ fput(current->exec_file);
14901 ++ current->exec_file = old_exec_file;
14902 ++#endif
14903 ++
14904 + out:
14905 + free_arg_pages(bprm);
14906 + if (bprm->security)
14907 +@@ -1561,6 +1639,114 @@ out:
14908 + return ispipe;
14909 + }
14910 +
14911 ++int pax_check_flags(unsigned long *flags)
14912 ++{
14913 ++ int retval = 0;
14914 ++
14915 ++#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC)
14916 ++ if (*flags & MF_PAX_SEGMEXEC)
14917 ++ {
14918 ++ *flags &= ~MF_PAX_SEGMEXEC;
14919 ++ retval = -EINVAL;
14920 ++ }
14921 ++#endif
14922 ++
14923 ++ if ((*flags & MF_PAX_PAGEEXEC)
14924 ++
14925 ++#ifdef CONFIG_PAX_PAGEEXEC
14926 ++ && (*flags & MF_PAX_SEGMEXEC)
14927 ++#endif
14928 ++
14929 ++ )
14930 ++ {
14931 ++ *flags &= ~MF_PAX_PAGEEXEC;
14932 ++ retval = -EINVAL;
14933 ++ }
14934 ++
14935 ++ if ((*flags & MF_PAX_MPROTECT)
14936 ++
14937 ++#ifdef CONFIG_PAX_MPROTECT
14938 ++ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
14939 ++#endif
14940 ++
14941 ++ )
14942 ++ {
14943 ++ *flags &= ~MF_PAX_MPROTECT;
14944 ++ retval = -EINVAL;
14945 ++ }
14946 ++
14947 ++ if ((*flags & MF_PAX_EMUTRAMP)
14948 ++
14949 ++#ifdef CONFIG_PAX_EMUTRAMP
14950 ++ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
14951 ++#endif
14952 ++
14953 ++ )
14954 ++ {
14955 ++ *flags &= ~MF_PAX_EMUTRAMP;
14956 ++ retval = -EINVAL;
14957 ++ }
14958 ++
14959 ++ return retval;
14960 ++}
14961 ++
14962 ++EXPORT_SYMBOL(pax_check_flags);
14963 ++
14964 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
14965 ++void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
14966 ++{
14967 ++ struct task_struct *tsk = current;
14968 ++ struct mm_struct *mm = current->mm;
14969 ++ char *buffer_exec = (char *)__get_free_page(GFP_ATOMIC);
14970 ++ char *buffer_fault = (char *)__get_free_page(GFP_ATOMIC);
14971 ++ char *path_exec = NULL;
14972 ++ char *path_fault = NULL;
14973 ++ unsigned long start = 0UL, end = 0UL, offset = 0UL;
14974 ++
14975 ++ if (buffer_exec && buffer_fault) {
14976 ++ struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL;
14977 ++
14978 ++ down_read(&mm->mmap_sem);
14979 ++ vma = mm->mmap;
14980 ++ while (vma && (!vma_exec || !vma_fault)) {
14981 ++ if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
14982 ++ vma_exec = vma;
14983 ++ if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
14984 ++ vma_fault = vma;
14985 ++ vma = vma->vm_next;
14986 ++ }
14987 ++ if (vma_exec) {
14988 ++ path_exec = d_path(vma_exec->vm_file->f_path.dentry, vma_exec->vm_file->f_path.mnt, buffer_exec, PAGE_SIZE);
14989 ++ if (IS_ERR(path_exec))
14990 ++ path_exec = "<path too long>";
14991 ++ }
14992 ++ if (vma_fault) {
14993 ++ start = vma_fault->vm_start;
14994 ++ end = vma_fault->vm_end;
14995 ++ offset = vma_fault->vm_pgoff << PAGE_SHIFT;
14996 ++ if (vma_fault->vm_file) {
14997 ++ path_fault = d_path(vma_fault->vm_file->f_path.dentry, vma_fault->vm_file->f_path.mnt, buffer_fault, PAGE_SIZE);
14998 ++ if (IS_ERR(path_fault))
14999 ++ path_fault = "<path too long>";
15000 ++ } else
15001 ++ path_fault = "<anonymous mapping>";
15002 ++ }
15003 ++ up_read(&mm->mmap_sem);
15004 ++ }
15005 ++ if (tsk->signal->curr_ip)
15006 ++ 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);
15007 ++ else
15008 ++ printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
15009 ++ printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
15010 ++ "PC: %p, SP: %p\n", path_exec, tsk->comm, tsk->pid,
15011 ++ tsk->uid, tsk->euid, pc, sp);
15012 ++ free_page((unsigned long)buffer_exec);
15013 ++ free_page((unsigned long)buffer_fault);
15014 ++ pax_report_insns(pc, sp);
15015 ++ do_coredump(SIGKILL, SIGKILL, regs);
15016 ++}
15017 ++#endif
15018 ++
15019 + static void zap_process(struct task_struct *start)
15020 + {
15021 + struct task_struct *t;
15022 +@@ -1753,6 +1939,10 @@ int do_coredump(long signr, int exit_cod
15023 + */
15024 + clear_thread_flag(TIF_SIGPENDING);
15025 +
15026 ++ if (signr == SIGKILL || signr == SIGILL)
15027 ++ gr_handle_brute_attach(current);
15028 ++
15029 ++ gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
15030 + if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
15031 + goto fail_unlock;
15032 +
15033 +diff -Nurp linux-2.6.23.15/fs/ext2/balloc.c linux-2.6.23.15-grsec/fs/ext2/balloc.c
15034 +--- linux-2.6.23.15/fs/ext2/balloc.c 2007-10-09 21:31:38.000000000 +0100
15035 ++++ linux-2.6.23.15-grsec/fs/ext2/balloc.c 2008-02-11 10:37:44.000000000 +0000
15036 +@@ -111,7 +111,7 @@ static int reserve_blocks(struct super_b
15037 + if (free_blocks < count)
15038 + count = free_blocks;
15039 +
15040 +- if (free_blocks < root_blocks + count && !capable(CAP_SYS_RESOURCE) &&
15041 ++ if (free_blocks < root_blocks + count && !capable_nolog(CAP_SYS_RESOURCE) &&
15042 + sbi->s_resuid != current->fsuid &&
15043 + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
15044 + /*
15045 +diff -Nurp linux-2.6.23.15/fs/ext3/balloc.c linux-2.6.23.15-grsec/fs/ext3/balloc.c
15046 +--- linux-2.6.23.15/fs/ext3/balloc.c 2007-10-09 21:31:38.000000000 +0100
15047 ++++ linux-2.6.23.15-grsec/fs/ext3/balloc.c 2008-02-11 10:37:44.000000000 +0000
15048 +@@ -1359,7 +1359,7 @@ static int ext3_has_free_blocks(struct e
15049 +
15050 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
15051 + root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
15052 +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
15053 ++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
15054 + sbi->s_resuid != current->fsuid &&
15055 + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
15056 + return 0;
15057 +diff -Nurp linux-2.6.23.15/fs/ext3/namei.c linux-2.6.23.15-grsec/fs/ext3/namei.c
15058 +--- linux-2.6.23.15/fs/ext3/namei.c 2007-10-09 21:31:38.000000000 +0100
15059 ++++ linux-2.6.23.15-grsec/fs/ext3/namei.c 2008-02-11 10:37:44.000000000 +0000
15060 +@@ -1188,9 +1188,9 @@ static struct ext3_dir_entry_2 *do_split
15061 + u32 hash2;
15062 + struct dx_map_entry *map;
15063 + char *data1 = (*bh)->b_data, *data2;
15064 +- unsigned split, move, size, i;
15065 ++ unsigned split, move, size;
15066 + struct ext3_dir_entry_2 *de = NULL, *de2;
15067 +- int err = 0;
15068 ++ int i, err = 0;
15069 +
15070 + bh2 = ext3_append (handle, dir, &newblock, &err);
15071 + if (!(bh2)) {
15072 +diff -Nurp linux-2.6.23.15/fs/ext3/xattr.c linux-2.6.23.15-grsec/fs/ext3/xattr.c
15073 +--- linux-2.6.23.15/fs/ext3/xattr.c 2007-10-09 21:31:38.000000000 +0100
15074 ++++ linux-2.6.23.15-grsec/fs/ext3/xattr.c 2008-02-11 10:37:44.000000000 +0000
15075 +@@ -89,8 +89,8 @@
15076 + printk("\n"); \
15077 + } while (0)
15078 + #else
15079 +-# define ea_idebug(f...)
15080 +-# define ea_bdebug(f...)
15081 ++# define ea_idebug(f...) do {} while (0)
15082 ++# define ea_bdebug(f...) do {} while (0)
15083 + #endif
15084 +
15085 + static void ext3_xattr_cache_insert(struct buffer_head *);
15086 +diff -Nurp linux-2.6.23.15/fs/ext4/balloc.c linux-2.6.23.15-grsec/fs/ext4/balloc.c
15087 +--- linux-2.6.23.15/fs/ext4/balloc.c 2007-10-09 21:31:38.000000000 +0100
15088 ++++ linux-2.6.23.15-grsec/fs/ext4/balloc.c 2008-02-11 10:37:44.000000000 +0000
15089 +@@ -1376,7 +1376,7 @@ static int ext4_has_free_blocks(struct e
15090 +
15091 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
15092 + root_blocks = ext4_r_blocks_count(sbi->s_es);
15093 +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
15094 ++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
15095 + sbi->s_resuid != current->fsuid &&
15096 + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
15097 + return 0;
15098 +diff -Nurp linux-2.6.23.15/fs/ext4/namei.c linux-2.6.23.15-grsec/fs/ext4/namei.c
15099 +--- linux-2.6.23.15/fs/ext4/namei.c 2007-10-09 21:31:38.000000000 +0100
15100 ++++ linux-2.6.23.15-grsec/fs/ext4/namei.c 2008-02-11 10:37:44.000000000 +0000
15101 +@@ -1186,9 +1186,9 @@ static struct ext4_dir_entry_2 *do_split
15102 + u32 hash2;
15103 + struct dx_map_entry *map;
15104 + char *data1 = (*bh)->b_data, *data2;
15105 +- unsigned split, move, size, i;
15106 ++ unsigned split, move, size;
15107 + struct ext4_dir_entry_2 *de = NULL, *de2;
15108 +- int err = 0;
15109 ++ int i, err = 0;
15110 +
15111 + bh2 = ext4_append (handle, dir, &newblock, &err);
15112 + if (!(bh2)) {
15113 +diff -Nurp linux-2.6.23.15/fs/fcntl.c linux-2.6.23.15-grsec/fs/fcntl.c
15114 +--- linux-2.6.23.15/fs/fcntl.c 2007-10-09 21:31:38.000000000 +0100
15115 ++++ linux-2.6.23.15-grsec/fs/fcntl.c 2008-02-11 10:37:44.000000000 +0000
15116 +@@ -18,6 +18,7 @@
15117 + #include <linux/ptrace.h>
15118 + #include <linux/signal.h>
15119 + #include <linux/rcupdate.h>
15120 ++#include <linux/grsecurity.h>
15121 +
15122 + #include <asm/poll.h>
15123 + #include <asm/siginfo.h>
15124 +@@ -63,6 +64,7 @@ static int locate_fd(struct files_struct
15125 + struct fdtable *fdt;
15126 +
15127 + error = -EINVAL;
15128 ++ gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
15129 + if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
15130 + goto out;
15131 +
15132 +@@ -82,6 +84,7 @@ repeat:
15133 + fdt->max_fds, start);
15134 +
15135 + error = -EMFILE;
15136 ++ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
15137 + if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
15138 + goto out;
15139 +
15140 +@@ -140,6 +143,8 @@ asmlinkage long sys_dup2(unsigned int ol
15141 + struct files_struct * files = current->files;
15142 + struct fdtable *fdt;
15143 +
15144 ++ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
15145 ++
15146 + spin_lock(&files->file_lock);
15147 + if (!(file = fcheck(oldfd)))
15148 + goto out_unlock;
15149 +@@ -458,7 +463,8 @@ static inline int sigio_perm(struct task
15150 + return (((fown->euid == 0) ||
15151 + (fown->euid == p->suid) || (fown->euid == p->uid) ||
15152 + (fown->uid == p->suid) || (fown->uid == p->uid)) &&
15153 +- !security_file_send_sigiotask(p, fown, sig));
15154 ++ !security_file_send_sigiotask(p, fown, sig) &&
15155 ++ !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
15156 + }
15157 +
15158 + static void send_sigio_to_task(struct task_struct *p,
15159 +diff -Nurp linux-2.6.23.15/fs/fuse/control.c linux-2.6.23.15-grsec/fs/fuse/control.c
15160 +--- linux-2.6.23.15/fs/fuse/control.c 2007-10-09 21:31:38.000000000 +0100
15161 ++++ linux-2.6.23.15-grsec/fs/fuse/control.c 2008-02-11 10:37:44.000000000 +0000
15162 +@@ -159,7 +159,7 @@ void fuse_ctl_remove_conn(struct fuse_co
15163 +
15164 + static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
15165 + {
15166 +- struct tree_descr empty_descr = {""};
15167 ++ struct tree_descr empty_descr = {"", NULL, 0};
15168 + struct fuse_conn *fc;
15169 + int err;
15170 +
15171 +diff -Nurp linux-2.6.23.15/fs/hfs/inode.c linux-2.6.23.15-grsec/fs/hfs/inode.c
15172 +--- linux-2.6.23.15/fs/hfs/inode.c 2007-10-09 21:31:38.000000000 +0100
15173 ++++ linux-2.6.23.15-grsec/fs/hfs/inode.c 2008-02-11 10:37:44.000000000 +0000
15174 +@@ -415,7 +415,7 @@ int hfs_write_inode(struct inode *inode,
15175 +
15176 + if (S_ISDIR(main_inode->i_mode)) {
15177 + if (fd.entrylength < sizeof(struct hfs_cat_dir))
15178 +- /* panic? */;
15179 ++ {/* panic? */}
15180 + hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
15181 + sizeof(struct hfs_cat_dir));
15182 + if (rec.type != HFS_CDR_DIR ||
15183 +@@ -436,7 +436,7 @@ int hfs_write_inode(struct inode *inode,
15184 + sizeof(struct hfs_cat_file));
15185 + } else {
15186 + if (fd.entrylength < sizeof(struct hfs_cat_file))
15187 +- /* panic? */;
15188 ++ {/* panic? */}
15189 + hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
15190 + sizeof(struct hfs_cat_file));
15191 + if (rec.type != HFS_CDR_FIL ||
15192 +diff -Nurp linux-2.6.23.15/fs/hfsplus/inode.c linux-2.6.23.15-grsec/fs/hfsplus/inode.c
15193 +--- linux-2.6.23.15/fs/hfsplus/inode.c 2007-10-09 21:31:38.000000000 +0100
15194 ++++ linux-2.6.23.15-grsec/fs/hfsplus/inode.c 2008-02-11 10:37:44.000000000 +0000
15195 +@@ -418,7 +418,7 @@ int hfsplus_cat_read_inode(struct inode
15196 + struct hfsplus_cat_folder *folder = &entry.folder;
15197 +
15198 + if (fd->entrylength < sizeof(struct hfsplus_cat_folder))
15199 +- /* panic? */;
15200 ++ {/* panic? */}
15201 + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
15202 + sizeof(struct hfsplus_cat_folder));
15203 + hfsplus_get_perms(inode, &folder->permissions, 1);
15204 +@@ -435,7 +435,7 @@ int hfsplus_cat_read_inode(struct inode
15205 + struct hfsplus_cat_file *file = &entry.file;
15206 +
15207 + if (fd->entrylength < sizeof(struct hfsplus_cat_file))
15208 +- /* panic? */;
15209 ++ {/* panic? */}
15210 + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
15211 + sizeof(struct hfsplus_cat_file));
15212 +
15213 +@@ -491,7 +491,7 @@ int hfsplus_cat_write_inode(struct inode
15214 + struct hfsplus_cat_folder *folder = &entry.folder;
15215 +
15216 + if (fd.entrylength < sizeof(struct hfsplus_cat_folder))
15217 +- /* panic? */;
15218 ++ {/* panic? */}
15219 + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
15220 + sizeof(struct hfsplus_cat_folder));
15221 + /* simple node checks? */
15222 +@@ -513,7 +513,7 @@ int hfsplus_cat_write_inode(struct inode
15223 + struct hfsplus_cat_file *file = &entry.file;
15224 +
15225 + if (fd.entrylength < sizeof(struct hfsplus_cat_file))
15226 +- /* panic? */;
15227 ++ {/* panic? */}
15228 + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
15229 + sizeof(struct hfsplus_cat_file));
15230 + hfsplus_inode_write_fork(inode, &file->data_fork);
15231 +diff -Nurp linux-2.6.23.15/fs/jffs2/debug.h linux-2.6.23.15-grsec/fs/jffs2/debug.h
15232 +--- linux-2.6.23.15/fs/jffs2/debug.h 2007-10-09 21:31:38.000000000 +0100
15233 ++++ linux-2.6.23.15-grsec/fs/jffs2/debug.h 2008-02-11 10:37:44.000000000 +0000
15234 +@@ -51,13 +51,13 @@
15235 + #if CONFIG_JFFS2_FS_DEBUG > 0
15236 + #define D1(x) x
15237 + #else
15238 +-#define D1(x)
15239 ++#define D1(x) do {} while (0);
15240 + #endif
15241 +
15242 + #if CONFIG_JFFS2_FS_DEBUG > 1
15243 + #define D2(x) x
15244 + #else
15245 +-#define D2(x)
15246 ++#define D2(x) do {} while (0);
15247 + #endif
15248 +
15249 + /* The prefixes of JFFS2 messages */
15250 +@@ -113,68 +113,68 @@
15251 + #ifdef JFFS2_DBG_READINODE_MESSAGES
15252 + #define dbg_readinode(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15253 + #else
15254 +-#define dbg_readinode(fmt, ...)
15255 ++#define dbg_readinode(fmt, ...) do {} while (0)
15256 + #endif
15257 +
15258 + /* Fragtree build debugging messages */
15259 + #ifdef JFFS2_DBG_FRAGTREE_MESSAGES
15260 + #define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15261 + #else
15262 +-#define dbg_fragtree(fmt, ...)
15263 ++#define dbg_fragtree(fmt, ...) do {} while (0)
15264 + #endif
15265 + #ifdef JFFS2_DBG_FRAGTREE2_MESSAGES
15266 + #define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15267 + #else
15268 +-#define dbg_fragtree2(fmt, ...)
15269 ++#define dbg_fragtree2(fmt, ...) do {} while (0)
15270 + #endif
15271 +
15272 + /* Directory entry list manilulation debugging messages */
15273 + #ifdef JFFS2_DBG_DENTLIST_MESSAGES
15274 + #define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15275 + #else
15276 +-#define dbg_dentlist(fmt, ...)
15277 ++#define dbg_dentlist(fmt, ...) do {} while (0)
15278 + #endif
15279 +
15280 + /* Print the messages about manipulating node_refs */
15281 + #ifdef JFFS2_DBG_NODEREF_MESSAGES
15282 + #define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15283 + #else
15284 +-#define dbg_noderef(fmt, ...)
15285 ++#define dbg_noderef(fmt, ...) do {} while (0)
15286 + #endif
15287 +
15288 + /* Manipulations with the list of inodes (JFFS2 inocache) */
15289 + #ifdef JFFS2_DBG_INOCACHE_MESSAGES
15290 + #define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15291 + #else
15292 +-#define dbg_inocache(fmt, ...)
15293 ++#define dbg_inocache(fmt, ...) do {} while (0)
15294 + #endif
15295 +
15296 + /* Summary debugging messages */
15297 + #ifdef JFFS2_DBG_SUMMARY_MESSAGES
15298 + #define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15299 + #else
15300 +-#define dbg_summary(fmt, ...)
15301 ++#define dbg_summary(fmt, ...) do {} while (0)
15302 + #endif
15303 +
15304 + /* File system build messages */
15305 + #ifdef JFFS2_DBG_FSBUILD_MESSAGES
15306 + #define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15307 + #else
15308 +-#define dbg_fsbuild(fmt, ...)
15309 ++#define dbg_fsbuild(fmt, ...) do {} while (0)
15310 + #endif
15311 +
15312 + /* Watch the object allocations */
15313 + #ifdef JFFS2_DBG_MEMALLOC_MESSAGES
15314 + #define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15315 + #else
15316 +-#define dbg_memalloc(fmt, ...)
15317 ++#define dbg_memalloc(fmt, ...) do {} while (0)
15318 + #endif
15319 +
15320 + /* Watch the XATTR subsystem */
15321 + #ifdef JFFS2_DBG_XATTR_MESSAGES
15322 + #define dbg_xattr(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15323 + #else
15324 +-#define dbg_xattr(fmt, ...)
15325 ++#define dbg_xattr(fmt, ...) do {} while (0)
15326 + #endif
15327 +
15328 + /* "Sanity" checks */
15329 +diff -Nurp linux-2.6.23.15/fs/jffs2/erase.c linux-2.6.23.15-grsec/fs/jffs2/erase.c
15330 +--- linux-2.6.23.15/fs/jffs2/erase.c 2007-10-09 21:31:38.000000000 +0100
15331 ++++ linux-2.6.23.15-grsec/fs/jffs2/erase.c 2008-02-11 10:37:44.000000000 +0000
15332 +@@ -389,7 +389,8 @@ static void jffs2_mark_erased_block(stru
15333 + struct jffs2_unknown_node marker = {
15334 + .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
15335 + .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
15336 +- .totlen = cpu_to_je32(c->cleanmarker_size)
15337 ++ .totlen = cpu_to_je32(c->cleanmarker_size),
15338 ++ .hdr_crc = cpu_to_je32(0)
15339 + };
15340 +
15341 + jffs2_prealloc_raw_node_refs(c, jeb, 1);
15342 +diff -Nurp linux-2.6.23.15/fs/jffs2/summary.h linux-2.6.23.15-grsec/fs/jffs2/summary.h
15343 +--- linux-2.6.23.15/fs/jffs2/summary.h 2007-10-09 21:31:38.000000000 +0100
15344 ++++ linux-2.6.23.15-grsec/fs/jffs2/summary.h 2008-02-11 10:37:44.000000000 +0000
15345 +@@ -188,18 +188,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_
15346 +
15347 + #define jffs2_sum_active() (0)
15348 + #define jffs2_sum_init(a) (0)
15349 +-#define jffs2_sum_exit(a)
15350 +-#define jffs2_sum_disable_collecting(a)
15351 ++#define jffs2_sum_exit(a) do {} while (0)
15352 ++#define jffs2_sum_disable_collecting(a) do {} while (0)
15353 + #define jffs2_sum_is_disabled(a) (0)
15354 +-#define jffs2_sum_reset_collected(a)
15355 ++#define jffs2_sum_reset_collected(a) do {} while (0)
15356 + #define jffs2_sum_add_kvec(a,b,c,d) (0)
15357 +-#define jffs2_sum_move_collected(a,b)
15358 ++#define jffs2_sum_move_collected(a,b) do {} while (0)
15359 + #define jffs2_sum_write_sumnode(a) (0)
15360 +-#define jffs2_sum_add_padding_mem(a,b)
15361 +-#define jffs2_sum_add_inode_mem(a,b,c)
15362 +-#define jffs2_sum_add_dirent_mem(a,b,c)
15363 +-#define jffs2_sum_add_xattr_mem(a,b,c)
15364 +-#define jffs2_sum_add_xref_mem(a,b,c)
15365 ++#define jffs2_sum_add_padding_mem(a,b) do {} while (0)
15366 ++#define jffs2_sum_add_inode_mem(a,b,c) do {} while (0)
15367 ++#define jffs2_sum_add_dirent_mem(a,b,c) do {} while (0)
15368 ++#define jffs2_sum_add_xattr_mem(a,b,c) do {} while (0)
15369 ++#define jffs2_sum_add_xref_mem(a,b,c) do {} while (0)
15370 + #define jffs2_sum_scan_sumnode(a,b,c,d,e) (0)
15371 +
15372 + #endif /* CONFIG_JFFS2_SUMMARY */
15373 +diff -Nurp linux-2.6.23.15/fs/jffs2/wbuf.c linux-2.6.23.15-grsec/fs/jffs2/wbuf.c
15374 +--- linux-2.6.23.15/fs/jffs2/wbuf.c 2007-10-09 21:31:38.000000000 +0100
15375 ++++ linux-2.6.23.15-grsec/fs/jffs2/wbuf.c 2008-02-11 10:37:44.000000000 +0000
15376 +@@ -973,7 +973,8 @@ static const struct jffs2_unknown_node o
15377 + {
15378 + .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK),
15379 + .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
15380 +- .totlen = constant_cpu_to_je32(8)
15381 ++ .totlen = constant_cpu_to_je32(8),
15382 ++ .hdr_crc = constant_cpu_to_je32(0)
15383 + };
15384 +
15385 + /*
15386 +diff -Nurp linux-2.6.23.15/fs/namei.c linux-2.6.23.15-grsec/fs/namei.c
15387 +--- linux-2.6.23.15/fs/namei.c 2008-02-11 10:36:03.000000000 +0000
15388 ++++ linux-2.6.23.15-grsec/fs/namei.c 2008-02-11 10:37:44.000000000 +0000
15389 +@@ -31,6 +31,7 @@
15390 + #include <linux/file.h>
15391 + #include <linux/fcntl.h>
15392 + #include <linux/namei.h>
15393 ++#include <linux/grsecurity.h>
15394 + #include <asm/namei.h>
15395 + #include <asm/uaccess.h>
15396 +
15397 +@@ -638,6 +639,13 @@ static inline int do_follow_link(struct
15398 + err = security_inode_follow_link(path->dentry, nd);
15399 + if (err)
15400 + goto loop;
15401 ++
15402 ++ if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
15403 ++ path->dentry->d_inode, path->dentry, nd->mnt)) {
15404 ++ err = -EACCES;
15405 ++ goto loop;
15406 ++ }
15407 ++
15408 + current->link_count++;
15409 + current->total_link_count++;
15410 + nd->depth++;
15411 +@@ -983,11 +991,18 @@ return_reval:
15412 + break;
15413 + }
15414 + return_base:
15415 ++ if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) {
15416 ++ path_release(nd);
15417 ++ return -ENOENT;
15418 ++ }
15419 + return 0;
15420 + out_dput:
15421 + dput_path(&next, nd);
15422 + break;
15423 + }
15424 ++ if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt))
15425 ++ err = -ENOENT;
15426 ++
15427 + path_release(nd);
15428 + return_err:
15429 + return err;
15430 +@@ -1649,9 +1664,17 @@ static int open_namei_create(struct name
15431 + int error;
15432 + struct dentry *dir = nd->dentry;
15433 +
15434 ++ if (!gr_acl_handle_creat(path->dentry, nd->dentry, nd->mnt, flag, mode)) {
15435 ++ error = -EACCES;
15436 ++ goto out_unlock_dput;
15437 ++ }
15438 ++
15439 + if (!IS_POSIXACL(dir->d_inode))
15440 + mode &= ~current->fs->umask;
15441 + error = vfs_create(dir->d_inode, path->dentry, mode, nd);
15442 ++ if (!error)
15443 ++ gr_handle_create(path->dentry, nd->mnt);
15444 ++out_unlock_dput:
15445 + mutex_unlock(&dir->d_inode->i_mutex);
15446 + dput(nd->dentry);
15447 + nd->dentry = path->dentry;
15448 +@@ -1702,6 +1725,17 @@ int open_namei(int dfd, const char *path
15449 + nd, flag);
15450 + if (error)
15451 + return error;
15452 ++
15453 ++ if (gr_handle_rawio(nd->dentry->d_inode)) {
15454 ++ error = -EPERM;
15455 ++ goto exit;
15456 ++ }
15457 ++
15458 ++ if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) {
15459 ++ error = -EACCES;
15460 ++ goto exit;
15461 ++ }
15462 ++
15463 + goto ok;
15464 + }
15465 +
15466 +@@ -1751,6 +1785,23 @@ do_last:
15467 + /*
15468 + * It already exists.
15469 + */
15470 ++
15471 ++ if (gr_handle_rawio(path.dentry->d_inode)) {
15472 ++ mutex_unlock(&dir->d_inode->i_mutex);
15473 ++ error = -EPERM;
15474 ++ goto exit_dput;
15475 ++ }
15476 ++ if (!gr_acl_handle_open(path.dentry, nd->mnt, flag)) {
15477 ++ mutex_unlock(&dir->d_inode->i_mutex);
15478 ++ error = -EACCES;
15479 ++ goto exit_dput;
15480 ++ }
15481 ++ if (gr_handle_fifo(path.dentry, nd->mnt, dir, flag, acc_mode)) {
15482 ++ mutex_unlock(&dir->d_inode->i_mutex);
15483 ++ error = -EACCES;
15484 ++ goto exit_dput;
15485 ++ }
15486 ++
15487 + mutex_unlock(&dir->d_inode->i_mutex);
15488 + audit_inode(pathname, path.dentry->d_inode);
15489 +
15490 +@@ -1806,6 +1857,13 @@ do_link:
15491 + error = security_inode_follow_link(path.dentry, nd);
15492 + if (error)
15493 + goto exit_dput;
15494 ++
15495 ++ if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
15496 ++ path.dentry, nd->mnt)) {
15497 ++ error = -EACCES;
15498 ++ goto exit_dput;
15499 ++ }
15500 ++
15501 + error = __do_follow_link(&path, nd);
15502 + if (error) {
15503 + /* Does someone understand code flow here? Or it is only
15504 +@@ -1934,6 +1992,22 @@ asmlinkage long sys_mknodat(int dfd, con
15505 + if (!IS_POSIXACL(nd.dentry->d_inode))
15506 + mode &= ~current->fs->umask;
15507 + if (!IS_ERR(dentry)) {
15508 ++ if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) {
15509 ++ error = -EPERM;
15510 ++ dput(dentry);
15511 ++ mutex_unlock(&nd.dentry->d_inode->i_mutex);
15512 ++ path_release(&nd);
15513 ++ goto out;
15514 ++ }
15515 ++
15516 ++ if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
15517 ++ error = -EACCES;
15518 ++ dput(dentry);
15519 ++ mutex_unlock(&nd.dentry->d_inode->i_mutex);
15520 ++ path_release(&nd);
15521 ++ goto out;
15522 ++ }
15523 ++
15524 + switch (mode & S_IFMT) {
15525 + case 0: case S_IFREG:
15526 + error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
15527 +@@ -1951,6 +2025,10 @@ asmlinkage long sys_mknodat(int dfd, con
15528 + default:
15529 + error = -EINVAL;
15530 + }
15531 ++
15532 ++ if (!error)
15533 ++ gr_handle_create(dentry, nd.mnt);
15534 ++
15535 + dput(dentry);
15536 + }
15537 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
15538 +@@ -2008,9 +2086,18 @@ asmlinkage long sys_mkdirat(int dfd, con
15539 + if (IS_ERR(dentry))
15540 + goto out_unlock;
15541 +
15542 ++ if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt)) {
15543 ++ error = -EACCES;
15544 ++ goto out_unlock_dput;
15545 ++ }
15546 ++
15547 + if (!IS_POSIXACL(nd.dentry->d_inode))
15548 + mode &= ~current->fs->umask;
15549 + error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
15550 ++
15551 ++ if (!error)
15552 ++ gr_handle_create(dentry, nd.mnt);
15553 ++out_unlock_dput:
15554 + dput(dentry);
15555 + out_unlock:
15556 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
15557 +@@ -2092,6 +2179,8 @@ static long do_rmdir(int dfd, const char
15558 + char * name;
15559 + struct dentry *dentry;
15560 + struct nameidata nd;
15561 ++ ino_t saved_ino = 0;
15562 ++ dev_t saved_dev = 0;
15563 +
15564 + name = getname(pathname);
15565 + if(IS_ERR(name))
15566 +@@ -2117,7 +2206,22 @@ static long do_rmdir(int dfd, const char
15567 + error = PTR_ERR(dentry);
15568 + if (IS_ERR(dentry))
15569 + goto exit2;
15570 ++
15571 ++ if (dentry->d_inode != NULL) {
15572 ++ if (dentry->d_inode->i_nlink <= 1) {
15573 ++ saved_ino = dentry->d_inode->i_ino;
15574 ++ saved_dev = dentry->d_inode->i_sb->s_dev;
15575 ++ }
15576 ++
15577 ++ if (!gr_acl_handle_rmdir(dentry, nd.mnt)) {
15578 ++ error = -EACCES;
15579 ++ goto dput_exit2;
15580 ++ }
15581 ++ }
15582 + error = vfs_rmdir(nd.dentry->d_inode, dentry);
15583 ++ if (!error && (saved_dev || saved_ino))
15584 ++ gr_handle_delete(saved_ino, saved_dev);
15585 ++dput_exit2:
15586 + dput(dentry);
15587 + exit2:
15588 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
15589 +@@ -2176,6 +2280,8 @@ static long do_unlinkat(int dfd, const c
15590 + struct dentry *dentry;
15591 + struct nameidata nd;
15592 + struct inode *inode = NULL;
15593 ++ ino_t saved_ino = 0;
15594 ++ dev_t saved_dev = 0;
15595 +
15596 + name = getname(pathname);
15597 + if(IS_ERR(name))
15598 +@@ -2191,13 +2297,26 @@ static long do_unlinkat(int dfd, const c
15599 + dentry = lookup_hash(&nd);
15600 + error = PTR_ERR(dentry);
15601 + if (!IS_ERR(dentry)) {
15602 ++ error = 0;
15603 + /* Why not before? Because we want correct error value */
15604 + if (nd.last.name[nd.last.len])
15605 + goto slashes;
15606 + inode = dentry->d_inode;
15607 +- if (inode)
15608 ++ if (inode) {
15609 ++ if (inode->i_nlink <= 1) {
15610 ++ saved_ino = inode->i_ino;
15611 ++ saved_dev = inode->i_sb->s_dev;
15612 ++ }
15613 ++
15614 ++ if (!gr_acl_handle_unlink(dentry, nd.mnt))
15615 ++ error = -EACCES;
15616 ++
15617 + atomic_inc(&inode->i_count);
15618 +- error = vfs_unlink(nd.dentry->d_inode, dentry);
15619 ++ }
15620 ++ if (!error)
15621 ++ error = vfs_unlink(nd.dentry->d_inode, dentry);
15622 ++ if (!error && (saved_ino || saved_dev))
15623 ++ gr_handle_delete(saved_ino, saved_dev);
15624 + exit2:
15625 + dput(dentry);
15626 + }
15627 +@@ -2278,7 +2397,16 @@ asmlinkage long sys_symlinkat(const char
15628 + if (IS_ERR(dentry))
15629 + goto out_unlock;
15630 +
15631 ++ if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from)) {
15632 ++ error = -EACCES;
15633 ++ goto out_dput_unlock;
15634 ++ }
15635 ++
15636 + error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
15637 ++
15638 ++ if (!error)
15639 ++ gr_handle_create(dentry, nd.mnt);
15640 ++out_dput_unlock:
15641 + dput(dentry);
15642 + out_unlock:
15643 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
15644 +@@ -2373,7 +2501,25 @@ asmlinkage long sys_linkat(int olddfd, c
15645 + error = PTR_ERR(new_dentry);
15646 + if (IS_ERR(new_dentry))
15647 + goto out_unlock;
15648 ++
15649 ++ if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt,
15650 ++ old_nd.dentry->d_inode,
15651 ++ old_nd.dentry->d_inode->i_mode, to)) {
15652 ++ error = -EACCES;
15653 ++ goto out_unlock_dput;
15654 ++ }
15655 ++
15656 ++ if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt,
15657 ++ old_nd.dentry, old_nd.mnt, to)) {
15658 ++ error = -EACCES;
15659 ++ goto out_unlock_dput;
15660 ++ }
15661 ++
15662 + error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
15663 ++
15664 ++ if (!error)
15665 ++ gr_handle_create(new_dentry, nd.mnt);
15666 ++out_unlock_dput:
15667 + dput(new_dentry);
15668 + out_unlock:
15669 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
15670 +@@ -2599,8 +2745,16 @@ static int do_rename(int olddfd, const c
15671 + if (new_dentry == trap)
15672 + goto exit5;
15673 +
15674 +- error = vfs_rename(old_dir->d_inode, old_dentry,
15675 ++ error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt,
15676 ++ old_dentry, old_dir->d_inode, oldnd.mnt,
15677 ++ newname);
15678 ++
15679 ++ if (!error)
15680 ++ error = vfs_rename(old_dir->d_inode, old_dentry,
15681 + new_dir->d_inode, new_dentry);
15682 ++ if (!error)
15683 ++ gr_handle_rename(old_dir->d_inode, newnd.dentry->d_inode, old_dentry,
15684 ++ new_dentry, oldnd.mnt, new_dentry->d_inode ? 1 : 0);
15685 + exit5:
15686 + dput(new_dentry);
15687 + exit4:
15688 +diff -Nurp linux-2.6.23.15/fs/namespace.c linux-2.6.23.15-grsec/fs/namespace.c
15689 +--- linux-2.6.23.15/fs/namespace.c 2007-10-09 21:31:38.000000000 +0100
15690 ++++ linux-2.6.23.15-grsec/fs/namespace.c 2008-02-11 10:37:44.000000000 +0000
15691 +@@ -25,6 +25,7 @@
15692 + #include <linux/security.h>
15693 + #include <linux/mount.h>
15694 + #include <linux/ramfs.h>
15695 ++#include <linux/grsecurity.h>
15696 + #include <asm/uaccess.h>
15697 + #include <asm/unistd.h>
15698 + #include "pnode.h"
15699 +@@ -597,6 +598,8 @@ static int do_umount(struct vfsmount *mn
15700 + DQUOT_OFF(sb);
15701 + retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
15702 + unlock_kernel();
15703 ++
15704 ++ gr_log_remount(mnt->mnt_devname, retval);
15705 + }
15706 + up_write(&sb->s_umount);
15707 + return retval;
15708 +@@ -617,6 +620,9 @@ static int do_umount(struct vfsmount *mn
15709 + security_sb_umount_busy(mnt);
15710 + up_write(&namespace_sem);
15711 + release_mounts(&umount_list);
15712 ++
15713 ++ gr_log_unmount(mnt->mnt_devname, retval);
15714 ++
15715 + return retval;
15716 + }
15717 +
15718 +@@ -1422,6 +1428,11 @@ long do_mount(char *dev_name, char *dir_
15719 + if (retval)
15720 + goto dput_out;
15721 +
15722 ++ if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) {
15723 ++ retval = -EPERM;
15724 ++ goto dput_out;
15725 ++ }
15726 ++
15727 + if (flags & MS_REMOUNT)
15728 + retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
15729 + data_page);
15730 +@@ -1436,6 +1447,9 @@ long do_mount(char *dev_name, char *dir_
15731 + dev_name, data_page);
15732 + dput_out:
15733 + path_release(&nd);
15734 ++
15735 ++ gr_log_mount(dev_name, dir_name, retval);
15736 ++
15737 + return retval;
15738 + }
15739 +
15740 +@@ -1673,6 +1687,9 @@ asmlinkage long sys_pivot_root(const cha
15741 + if (!capable(CAP_SYS_ADMIN))
15742 + return -EPERM;
15743 +
15744 ++ if (gr_handle_chroot_pivot())
15745 ++ return -EPERM;
15746 ++
15747 + lock_kernel();
15748 +
15749 + error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
15750 +diff -Nurp linux-2.6.23.15/fs/nfs/callback_xdr.c linux-2.6.23.15-grsec/fs/nfs/callback_xdr.c
15751 +--- linux-2.6.23.15/fs/nfs/callback_xdr.c 2007-10-09 21:31:38.000000000 +0100
15752 ++++ linux-2.6.23.15-grsec/fs/nfs/callback_xdr.c 2008-02-11 10:37:44.000000000 +0000
15753 +@@ -139,7 +139,7 @@ static __be32 decode_compound_hdr_arg(st
15754 + if (unlikely(status != 0))
15755 + return status;
15756 + /* We do not like overly long tags! */
15757 +- if (hdr->taglen > CB_OP_TAGLEN_MAXSZ-12 || hdr->taglen < 0) {
15758 ++ if (hdr->taglen > CB_OP_TAGLEN_MAXSZ-12) {
15759 + printk("NFSv4 CALLBACK %s: client sent tag of length %u\n",
15760 + __FUNCTION__, hdr->taglen);
15761 + return htonl(NFS4ERR_RESOURCE);
15762 +diff -Nurp linux-2.6.23.15/fs/nfs/nfs4proc.c linux-2.6.23.15-grsec/fs/nfs/nfs4proc.c
15763 +--- linux-2.6.23.15/fs/nfs/nfs4proc.c 2007-10-09 21:31:38.000000000 +0100
15764 ++++ linux-2.6.23.15-grsec/fs/nfs/nfs4proc.c 2008-02-11 10:37:44.000000000 +0000
15765 +@@ -657,7 +657,7 @@ static int _nfs4_do_open_reclaim(struct
15766 + static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
15767 + {
15768 + struct nfs_server *server = NFS_SERVER(state->inode);
15769 +- struct nfs4_exception exception = { };
15770 ++ struct nfs4_exception exception = {0, 0};
15771 + int err;
15772 + do {
15773 + err = _nfs4_do_open_reclaim(ctx, state);
15774 +@@ -699,7 +699,7 @@ static int _nfs4_open_delegation_recall(
15775 +
15776 + int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
15777 + {
15778 +- struct nfs4_exception exception = { };
15779 ++ struct nfs4_exception exception = {0, 0};
15780 + struct nfs_server *server = NFS_SERVER(state->inode);
15781 + int err;
15782 + do {
15783 +@@ -1020,7 +1020,7 @@ static int _nfs4_open_expired(struct nfs
15784 + static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
15785 + {
15786 + struct nfs_server *server = NFS_SERVER(state->inode);
15787 +- struct nfs4_exception exception = { };
15788 ++ struct nfs4_exception exception = {0, 0};
15789 + int err;
15790 +
15791 + do {
15792 +@@ -1122,7 +1122,7 @@ out_err:
15793 +
15794 + static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred)
15795 + {
15796 +- struct nfs4_exception exception = { };
15797 ++ struct nfs4_exception exception = {0, 0};
15798 + struct nfs4_state *res;
15799 + int status;
15800 +
15801 +@@ -1211,7 +1211,7 @@ static int nfs4_do_setattr(struct inode
15802 + struct iattr *sattr, struct nfs4_state *state)
15803 + {
15804 + struct nfs_server *server = NFS_SERVER(inode);
15805 +- struct nfs4_exception exception = { };
15806 ++ struct nfs4_exception exception = {0, 0};
15807 + int err;
15808 + do {
15809 + err = nfs4_handle_exception(server,
15810 +@@ -1504,7 +1504,7 @@ static int _nfs4_server_capabilities(str
15811 +
15812 + int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
15813 + {
15814 +- struct nfs4_exception exception = { };
15815 ++ struct nfs4_exception exception = {0, 0};
15816 + int err;
15817 + do {
15818 + err = nfs4_handle_exception(server,
15819 +@@ -1537,7 +1537,7 @@ static int _nfs4_lookup_root(struct nfs_
15820 + static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
15821 + struct nfs_fsinfo *info)
15822 + {
15823 +- struct nfs4_exception exception = { };
15824 ++ struct nfs4_exception exception = {0, 0};
15825 + int err;
15826 + do {
15827 + err = nfs4_handle_exception(server,
15828 +@@ -1626,7 +1626,7 @@ static int _nfs4_proc_getattr(struct nfs
15829 +
15830 + static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
15831 + {
15832 +- struct nfs4_exception exception = { };
15833 ++ struct nfs4_exception exception = {0, 0};
15834 + int err;
15835 + do {
15836 + err = nfs4_handle_exception(server,
15837 +@@ -1716,7 +1716,7 @@ static int nfs4_proc_lookupfh(struct nfs
15838 + struct qstr *name, struct nfs_fh *fhandle,
15839 + struct nfs_fattr *fattr)
15840 + {
15841 +- struct nfs4_exception exception = { };
15842 ++ struct nfs4_exception exception = {0, 0};
15843 + int err;
15844 + do {
15845 + err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr);
15846 +@@ -1745,7 +1745,7 @@ static int _nfs4_proc_lookup(struct inod
15847 +
15848 + static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
15849 + {
15850 +- struct nfs4_exception exception = { };
15851 ++ struct nfs4_exception exception = {0, 0};
15852 + int err;
15853 + do {
15854 + err = nfs4_handle_exception(NFS_SERVER(dir),
15855 +@@ -1801,7 +1801,7 @@ static int _nfs4_proc_access(struct inod
15856 +
15857 + static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
15858 + {
15859 +- struct nfs4_exception exception = { };
15860 ++ struct nfs4_exception exception = {0, 0};
15861 + int err;
15862 + do {
15863 + err = nfs4_handle_exception(NFS_SERVER(inode),
15864 +@@ -1856,7 +1856,7 @@ static int _nfs4_proc_readlink(struct in
15865 + static int nfs4_proc_readlink(struct inode *inode, struct page *page,
15866 + unsigned int pgbase, unsigned int pglen)
15867 + {
15868 +- struct nfs4_exception exception = { };
15869 ++ struct nfs4_exception exception = {0, 0};
15870 + int err;
15871 + do {
15872 + err = nfs4_handle_exception(NFS_SERVER(inode),
15873 +@@ -1950,7 +1950,7 @@ static int _nfs4_proc_remove(struct inod
15874 +
15875 + static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
15876 + {
15877 +- struct nfs4_exception exception = { };
15878 ++ struct nfs4_exception exception = {0, 0};
15879 + int err;
15880 + do {
15881 + err = nfs4_handle_exception(NFS_SERVER(dir),
15882 +@@ -2022,7 +2022,7 @@ static int _nfs4_proc_rename(struct inod
15883 + static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
15884 + struct inode *new_dir, struct qstr *new_name)
15885 + {
15886 +- struct nfs4_exception exception = { };
15887 ++ struct nfs4_exception exception = {0, 0};
15888 + int err;
15889 + do {
15890 + err = nfs4_handle_exception(NFS_SERVER(old_dir),
15891 +@@ -2069,7 +2069,7 @@ static int _nfs4_proc_link(struct inode
15892 +
15893 + static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
15894 + {
15895 +- struct nfs4_exception exception = { };
15896 ++ struct nfs4_exception exception = {0, 0};
15897 + int err;
15898 + do {
15899 + err = nfs4_handle_exception(NFS_SERVER(inode),
15900 +@@ -2126,7 +2126,7 @@ static int _nfs4_proc_symlink(struct ino
15901 + static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
15902 + struct page *page, unsigned int len, struct iattr *sattr)
15903 + {
15904 +- struct nfs4_exception exception = { };
15905 ++ struct nfs4_exception exception = {0, 0};
15906 + int err;
15907 + do {
15908 + err = nfs4_handle_exception(NFS_SERVER(dir),
15909 +@@ -2179,7 +2179,7 @@ static int _nfs4_proc_mkdir(struct inode
15910 + static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
15911 + struct iattr *sattr)
15912 + {
15913 +- struct nfs4_exception exception = { };
15914 ++ struct nfs4_exception exception = {0, 0};
15915 + int err;
15916 + do {
15917 + err = nfs4_handle_exception(NFS_SERVER(dir),
15918 +@@ -2225,7 +2225,7 @@ static int _nfs4_proc_readdir(struct den
15919 + static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
15920 + u64 cookie, struct page *page, unsigned int count, int plus)
15921 + {
15922 +- struct nfs4_exception exception = { };
15923 ++ struct nfs4_exception exception = {0, 0};
15924 + int err;
15925 + do {
15926 + err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode),
15927 +@@ -2295,7 +2295,7 @@ static int _nfs4_proc_mknod(struct inode
15928 + static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
15929 + struct iattr *sattr, dev_t rdev)
15930 + {
15931 +- struct nfs4_exception exception = { };
15932 ++ struct nfs4_exception exception = {0, 0};
15933 + int err;
15934 + do {
15935 + err = nfs4_handle_exception(NFS_SERVER(dir),
15936 +@@ -2324,7 +2324,7 @@ static int _nfs4_proc_statfs(struct nfs_
15937 +
15938 + static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
15939 + {
15940 +- struct nfs4_exception exception = { };
15941 ++ struct nfs4_exception exception = {0, 0};
15942 + int err;
15943 + do {
15944 + err = nfs4_handle_exception(server,
15945 +@@ -2352,7 +2352,7 @@ static int _nfs4_do_fsinfo(struct nfs_se
15946 +
15947 + static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
15948 + {
15949 +- struct nfs4_exception exception = { };
15950 ++ struct nfs4_exception exception = {0, 0};
15951 + int err;
15952 +
15953 + do {
15954 +@@ -2395,7 +2395,7 @@ static int _nfs4_proc_pathconf(struct nf
15955 + static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
15956 + struct nfs_pathconf *pathconf)
15957 + {
15958 +- struct nfs4_exception exception = { };
15959 ++ struct nfs4_exception exception = {0, 0};
15960 + int err;
15961 +
15962 + do {
15963 +@@ -2714,7 +2714,7 @@ out_free:
15964 +
15965 + static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
15966 + {
15967 +- struct nfs4_exception exception = { };
15968 ++ struct nfs4_exception exception = {0, 0};
15969 + ssize_t ret;
15970 + do {
15971 + ret = __nfs4_get_acl_uncached(inode, buf, buflen);
15972 +@@ -2768,7 +2768,7 @@ static int __nfs4_proc_set_acl(struct in
15973 +
15974 + static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
15975 + {
15976 +- struct nfs4_exception exception = { };
15977 ++ struct nfs4_exception exception = {0, 0};
15978 + int err;
15979 + do {
15980 + err = nfs4_handle_exception(NFS_SERVER(inode),
15981 +@@ -3065,7 +3065,7 @@ static int _nfs4_proc_delegreturn(struct
15982 + int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid)
15983 + {
15984 + struct nfs_server *server = NFS_SERVER(inode);
15985 +- struct nfs4_exception exception = { };
15986 ++ struct nfs4_exception exception = {0, 0};
15987 + int err;
15988 + do {
15989 + err = _nfs4_proc_delegreturn(inode, cred, stateid);
15990 +@@ -3140,7 +3140,7 @@ out:
15991 +
15992 + static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
15993 + {
15994 +- struct nfs4_exception exception = { };
15995 ++ struct nfs4_exception exception = {0, 0};
15996 + int err;
15997 +
15998 + do {
15999 +@@ -3474,7 +3474,7 @@ static int _nfs4_do_setlk(struct nfs4_st
16000 + static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
16001 + {
16002 + struct nfs_server *server = NFS_SERVER(state->inode);
16003 +- struct nfs4_exception exception = { };
16004 ++ struct nfs4_exception exception = {0, 0};
16005 + int err;
16006 +
16007 + do {
16008 +@@ -3492,7 +3492,7 @@ static int nfs4_lock_reclaim(struct nfs4
16009 + static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
16010 + {
16011 + struct nfs_server *server = NFS_SERVER(state->inode);
16012 +- struct nfs4_exception exception = { };
16013 ++ struct nfs4_exception exception = {0, 0};
16014 + int err;
16015 +
16016 + err = nfs4_set_lock_state(state, request);
16017 +@@ -3553,7 +3553,7 @@ out:
16018 +
16019 + static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
16020 + {
16021 +- struct nfs4_exception exception = { };
16022 ++ struct nfs4_exception exception = {0, 0};
16023 + int err;
16024 +
16025 + do {
16026 +@@ -3603,7 +3603,7 @@ nfs4_proc_lock(struct file *filp, int cm
16027 + int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
16028 + {
16029 + struct nfs_server *server = NFS_SERVER(state->inode);
16030 +- struct nfs4_exception exception = { };
16031 ++ struct nfs4_exception exception = {0, 0};
16032 + int err;
16033 +
16034 + err = nfs4_set_lock_state(state, fl);
16035 +diff -Nurp linux-2.6.23.15/fs/nfsd/export.c linux-2.6.23.15-grsec/fs/nfsd/export.c
16036 +--- linux-2.6.23.15/fs/nfsd/export.c 2007-10-09 21:31:38.000000000 +0100
16037 ++++ linux-2.6.23.15-grsec/fs/nfsd/export.c 2008-02-11 10:37:44.000000000 +0000
16038 +@@ -478,7 +478,7 @@ static int secinfo_parse(char **mesg, ch
16039 + * probably discover the problem when someone fails to
16040 + * authenticate.
16041 + */
16042 +- if (f->pseudoflavor < 0)
16043 ++ if ((s32)f->pseudoflavor < 0)
16044 + return -EINVAL;
16045 + err = get_int(mesg, &f->flags);
16046 + if (err)
16047 +diff -Nurp linux-2.6.23.15/fs/nfsd/nfs4state.c linux-2.6.23.15-grsec/fs/nfsd/nfs4state.c
16048 +--- linux-2.6.23.15/fs/nfsd/nfs4state.c 2007-10-09 21:31:38.000000000 +0100
16049 ++++ linux-2.6.23.15-grsec/fs/nfsd/nfs4state.c 2008-02-11 10:37:44.000000000 +0000
16050 +@@ -1248,7 +1248,7 @@ static int access_valid(u32 x)
16051 +
16052 + static int deny_valid(u32 x)
16053 + {
16054 +- return (x >= 0 && x < 5);
16055 ++ return (x < 5);
16056 + }
16057 +
16058 + static void
16059 +diff -Nurp linux-2.6.23.15/fs/nls/nls_base.c linux-2.6.23.15-grsec/fs/nls/nls_base.c
16060 +--- linux-2.6.23.15/fs/nls/nls_base.c 2007-10-09 21:31:38.000000000 +0100
16061 ++++ linux-2.6.23.15-grsec/fs/nls/nls_base.c 2008-02-11 10:37:44.000000000 +0000
16062 +@@ -42,7 +42,7 @@ static struct utf8_table utf8_table[] =
16063 + {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */},
16064 + {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */},
16065 + {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */},
16066 +- {0, /* end of table */}
16067 ++ {0, 0, 0, 0, 0, /* end of table */}
16068 + };
16069 +
16070 + int
16071 +diff -Nurp linux-2.6.23.15/fs/ntfs/file.c linux-2.6.23.15-grsec/fs/ntfs/file.c
16072 +--- linux-2.6.23.15/fs/ntfs/file.c 2007-10-09 21:31:38.000000000 +0100
16073 ++++ linux-2.6.23.15-grsec/fs/ntfs/file.c 2008-02-11 10:37:44.000000000 +0000
16074 +@@ -2295,6 +2295,6 @@ const struct inode_operations ntfs_file_
16075 + #endif /* NTFS_RW */
16076 + };
16077 +
16078 +-const struct file_operations ntfs_empty_file_ops = {};
16079 ++const struct file_operations ntfs_empty_file_ops;
16080 +
16081 +-const struct inode_operations ntfs_empty_inode_ops = {};
16082 ++const struct inode_operations ntfs_empty_inode_ops;
16083 +diff -Nurp linux-2.6.23.15/fs/open.c linux-2.6.23.15-grsec/fs/open.c
16084 +--- linux-2.6.23.15/fs/open.c 2007-10-09 21:31:38.000000000 +0100
16085 ++++ linux-2.6.23.15-grsec/fs/open.c 2008-02-11 10:37:44.000000000 +0000
16086 +@@ -27,6 +27,7 @@
16087 + #include <linux/rcupdate.h>
16088 + #include <linux/audit.h>
16089 + #include <linux/falloc.h>
16090 ++#include <linux/grsecurity.h>
16091 +
16092 + int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
16093 + {
16094 +@@ -204,6 +205,9 @@ int do_truncate(struct dentry *dentry, l
16095 + if (length < 0)
16096 + return -EINVAL;
16097 +
16098 ++ if (filp && !gr_acl_handle_truncate(dentry, filp->f_vfsmnt))
16099 ++ return -EACCES;
16100 ++
16101 + newattrs.ia_size = length;
16102 + newattrs.ia_valid = ATTR_SIZE | time_attrs;
16103 + if (filp) {
16104 +@@ -461,6 +465,9 @@ asmlinkage long sys_faccessat(int dfd, c
16105 + if(IS_RDONLY(nd.dentry->d_inode))
16106 + res = -EROFS;
16107 +
16108 ++ if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode))
16109 ++ res = -EACCES;
16110 ++
16111 + out_path_release:
16112 + path_release(&nd);
16113 + out:
16114 +@@ -490,6 +497,8 @@ asmlinkage long sys_chdir(const char __u
16115 + if (error)
16116 + goto dput_and_out;
16117 +
16118 ++ gr_log_chdir(nd.dentry, nd.mnt);
16119 ++
16120 + set_fs_pwd(current->fs, nd.mnt, nd.dentry);
16121 +
16122 + dput_and_out:
16123 +@@ -520,6 +529,13 @@ asmlinkage long sys_fchdir(unsigned int
16124 + goto out_putf;
16125 +
16126 + error = file_permission(file, MAY_EXEC);
16127 ++
16128 ++ if (!error && !gr_chroot_fchdir(dentry, mnt))
16129 ++ error = -EPERM;
16130 ++
16131 ++ if (!error)
16132 ++ gr_log_chdir(dentry, mnt);
16133 ++
16134 + if (!error)
16135 + set_fs_pwd(current->fs, mnt, dentry);
16136 + out_putf:
16137 +@@ -545,8 +561,16 @@ asmlinkage long sys_chroot(const char __
16138 + if (!capable(CAP_SYS_CHROOT))
16139 + goto dput_and_out;
16140 +
16141 ++ if (gr_handle_chroot_chroot(nd.dentry, nd.mnt))
16142 ++ goto dput_and_out;
16143 ++
16144 + set_fs_root(current->fs, nd.mnt, nd.dentry);
16145 + set_fs_altroot();
16146 ++
16147 ++ gr_handle_chroot_caps(current);
16148 ++
16149 ++ gr_handle_chroot_chdir(nd.dentry, nd.mnt);
16150 ++
16151 + error = 0;
16152 + dput_and_out:
16153 + path_release(&nd);
16154 +@@ -577,9 +601,22 @@ asmlinkage long sys_fchmod(unsigned int
16155 + err = -EPERM;
16156 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
16157 + goto out_putf;
16158 ++
16159 ++ if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
16160 ++ err = -EACCES;
16161 ++ goto out_putf;
16162 ++ }
16163 ++
16164 + mutex_lock(&inode->i_mutex);
16165 + if (mode == (mode_t) -1)
16166 + mode = inode->i_mode;
16167 ++
16168 ++ if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
16169 ++ err = -EPERM;
16170 ++ mutex_unlock(&inode->i_mutex);
16171 ++ goto out_putf;
16172 ++ }
16173 ++
16174 + newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
16175 + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
16176 + err = notify_change(dentry, &newattrs);
16177 +@@ -612,9 +649,21 @@ asmlinkage long sys_fchmodat(int dfd, co
16178 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
16179 + goto dput_and_out;
16180 +
16181 ++ if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) {
16182 ++ error = -EACCES;
16183 ++ goto dput_and_out;
16184 ++ };
16185 ++
16186 + mutex_lock(&inode->i_mutex);
16187 + if (mode == (mode_t) -1)
16188 + mode = inode->i_mode;
16189 ++
16190 ++ if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) {
16191 ++ error = -EACCES;
16192 ++ mutex_unlock(&inode->i_mutex);
16193 ++ goto dput_and_out;
16194 ++ }
16195 ++
16196 + newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
16197 + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
16198 + error = notify_change(nd.dentry, &newattrs);
16199 +@@ -631,7 +680,7 @@ asmlinkage long sys_chmod(const char __u
16200 + return sys_fchmodat(AT_FDCWD, filename, mode);
16201 + }
16202 +
16203 +-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
16204 ++static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
16205 + {
16206 + struct inode * inode;
16207 + int error;
16208 +@@ -648,6 +697,12 @@ static int chown_common(struct dentry *
16209 + error = -EPERM;
16210 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
16211 + goto out;
16212 ++
16213 ++ if (!gr_acl_handle_chown(dentry, mnt)) {
16214 ++ error = -EACCES;
16215 ++ goto out;
16216 ++ }
16217 ++
16218 + newattrs.ia_valid = ATTR_CTIME;
16219 + if (user != (uid_t) -1) {
16220 + newattrs.ia_valid |= ATTR_UID;
16221 +@@ -674,7 +729,7 @@ asmlinkage long sys_chown(const char __u
16222 + error = user_path_walk(filename, &nd);
16223 + if (error)
16224 + goto out;
16225 +- error = chown_common(nd.dentry, user, group);
16226 ++ error = chown_common(nd.dentry, user, group, nd.mnt);
16227 + path_release(&nd);
16228 + out:
16229 + return error;
16230 +@@ -694,7 +749,7 @@ asmlinkage long sys_fchownat(int dfd, co
16231 + error = __user_walk_fd(dfd, filename, follow, &nd);
16232 + if (error)
16233 + goto out;
16234 +- error = chown_common(nd.dentry, user, group);
16235 ++ error = chown_common(nd.dentry, user, group, nd.mnt);
16236 + path_release(&nd);
16237 + out:
16238 + return error;
16239 +@@ -708,7 +763,7 @@ asmlinkage long sys_lchown(const char __
16240 + error = user_path_walk_link(filename, &nd);
16241 + if (error)
16242 + goto out;
16243 +- error = chown_common(nd.dentry, user, group);
16244 ++ error = chown_common(nd.dentry, user, group, nd.mnt);
16245 + path_release(&nd);
16246 + out:
16247 + return error;
16248 +@@ -727,7 +782,7 @@ asmlinkage long sys_fchown(unsigned int
16249 +
16250 + dentry = file->f_path.dentry;
16251 + audit_inode(NULL, dentry->d_inode);
16252 +- error = chown_common(dentry, user, group);
16253 ++ error = chown_common(dentry, user, group, file->f_vfsmnt);
16254 + fput(file);
16255 + out:
16256 + return error;
16257 +@@ -934,6 +989,7 @@ repeat:
16258 + * N.B. For clone tasks sharing a files structure, this test
16259 + * will limit the total number of files that can be opened.
16260 + */
16261 ++ gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
16262 + if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
16263 + goto out;
16264 +
16265 +diff -Nurp linux-2.6.23.15/fs/partitions/efi.c linux-2.6.23.15-grsec/fs/partitions/efi.c
16266 +--- linux-2.6.23.15/fs/partitions/efi.c 2007-10-09 21:31:38.000000000 +0100
16267 ++++ linux-2.6.23.15-grsec/fs/partitions/efi.c 2008-02-11 10:37:44.000000000 +0000
16268 +@@ -99,7 +99,7 @@
16269 + #ifdef EFI_DEBUG
16270 + #define Dprintk(x...) printk(KERN_DEBUG x)
16271 + #else
16272 +-#define Dprintk(x...)
16273 ++#define Dprintk(x...) do {} while (0)
16274 + #endif
16275 +
16276 + /* This allows a kernel command line option 'gpt' to override
16277 +diff -Nurp linux-2.6.23.15/fs/pipe.c linux-2.6.23.15-grsec/fs/pipe.c
16278 +--- linux-2.6.23.15/fs/pipe.c 2007-10-09 21:31:38.000000000 +0100
16279 ++++ linux-2.6.23.15-grsec/fs/pipe.c 2008-02-11 10:37:44.000000000 +0000
16280 +@@ -888,7 +888,7 @@ void free_pipe_info(struct inode *inode)
16281 + inode->i_pipe = NULL;
16282 + }
16283 +
16284 +-static struct vfsmount *pipe_mnt __read_mostly;
16285 ++struct vfsmount *pipe_mnt __read_mostly;
16286 + static int pipefs_delete_dentry(struct dentry *dentry)
16287 + {
16288 + /*
16289 +diff -Nurp linux-2.6.23.15/fs/proc/array.c linux-2.6.23.15-grsec/fs/proc/array.c
16290 +--- linux-2.6.23.15/fs/proc/array.c 2008-02-11 10:36:03.000000000 +0000
16291 ++++ linux-2.6.23.15-grsec/fs/proc/array.c 2008-02-11 10:37:44.000000000 +0000
16292 +@@ -298,6 +298,21 @@ static inline char *task_context_switch_
16293 + p->nivcsw);
16294 + }
16295 +
16296 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
16297 ++static inline char *task_pax(struct task_struct *p, char *buffer)
16298 ++{
16299 ++ if (p->mm)
16300 ++ return buffer + sprintf(buffer, "PaX:\t%c%c%c%c%c\n",
16301 ++ p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
16302 ++ p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
16303 ++ p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
16304 ++ p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
16305 ++ p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
16306 ++ else
16307 ++ return buffer + sprintf(buffer, "PaX:\t-----\n");
16308 ++}
16309 ++#endif
16310 ++
16311 + int proc_pid_status(struct task_struct *task, char *buffer)
16312 + {
16313 + char *orig = buffer;
16314 +@@ -317,6 +332,11 @@ int proc_pid_status(struct task_struct *
16315 + buffer = task_show_regs(task, buffer);
16316 + #endif
16317 + buffer = task_context_switch_counts(task, buffer);
16318 ++
16319 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
16320 ++ buffer = task_pax(task, buffer);
16321 ++#endif
16322 ++
16323 + return buffer - orig;
16324 + }
16325 +
16326 +@@ -372,6 +392,12 @@ static cputime_t task_stime(struct task_
16327 + }
16328 + #endif
16329 +
16330 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16331 ++#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
16332 ++ (_mm->pax_flags & MF_PAX_RANDMMAP || \
16333 ++ _mm->pax_flags & MF_PAX_SEGMEXEC))
16334 ++#endif
16335 ++
16336 + static int do_task_stat(struct task_struct *task, char *buffer, int whole)
16337 + {
16338 + unsigned long vsize, eip, esp, wchan = ~0UL;
16339 +@@ -458,6 +484,19 @@ static int do_task_stat(struct task_stru
16340 + stime = task_stime(task);
16341 + }
16342 +
16343 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16344 ++ if (PAX_RAND_FLAGS(mm)) {
16345 ++ eip = 0;
16346 ++ esp = 0;
16347 ++ wchan = 0;
16348 ++ }
16349 ++#endif
16350 ++#ifdef CONFIG_GRKERNSEC_HIDESYM
16351 ++ wchan = 0;
16352 ++ eip =0;
16353 ++ esp =0;
16354 ++#endif
16355 ++
16356 + /* scale priority and nice values from timeslices to -20..20 */
16357 + /* to make it look like a "normal" Unix priority/nice value */
16358 + priority = task_prio(task);
16359 +@@ -498,9 +537,15 @@ static int do_task_stat(struct task_stru
16360 + vsize,
16361 + mm ? get_mm_rss(mm) : 0,
16362 + rsslim,
16363 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16364 ++ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
16365 ++ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
16366 ++ PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0),
16367 ++#else
16368 + mm ? mm->start_code : 0,
16369 + mm ? mm->end_code : 0,
16370 + mm ? mm->start_stack : 0,
16371 ++#endif
16372 + esp,
16373 + eip,
16374 + /* The signal information here is obsolete.
16375 +@@ -547,3 +592,14 @@ int proc_pid_statm(struct task_struct *t
16376 + return sprintf(buffer, "%d %d %d %d %d %d %d\n",
16377 + size, resident, shared, text, lib, data, 0);
16378 + }
16379 ++
16380 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
16381 ++int proc_pid_ipaddr(struct task_struct *task, char * buffer)
16382 ++{
16383 ++ int len;
16384 ++
16385 ++ len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
16386 ++ return len;
16387 ++}
16388 ++#endif
16389 ++
16390 +diff -Nurp linux-2.6.23.15/fs/proc/base.c linux-2.6.23.15-grsec/fs/proc/base.c
16391 +--- linux-2.6.23.15/fs/proc/base.c 2007-10-09 21:31:38.000000000 +0100
16392 ++++ linux-2.6.23.15-grsec/fs/proc/base.c 2008-02-11 10:37:44.000000000 +0000
16393 +@@ -73,6 +73,7 @@
16394 + #include <linux/nsproxy.h>
16395 + #include <linux/oom.h>
16396 + #include <linux/elf.h>
16397 ++#include <linux/grsecurity.h>
16398 + #include "internal.h"
16399 +
16400 + /* NOTE:
16401 +@@ -123,7 +124,7 @@ struct pid_entry {
16402 + NULL, &proc_info_file_operations, \
16403 + { .proc_read = &proc_##OTYPE } )
16404 +
16405 +-int maps_protect;
16406 ++int maps_protect = 1;
16407 + EXPORT_SYMBOL(maps_protect);
16408 +
16409 + static struct fs_struct *get_fs_struct(struct task_struct *task)
16410 +@@ -197,7 +198,7 @@ static int proc_root_link(struct inode *
16411 + (task->parent == current && \
16412 + (task->ptrace & PT_PTRACED) && \
16413 + (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \
16414 +- security_ptrace(current,task) == 0))
16415 ++ security_ptrace(current,task) == 0 && !gr_handle_proc_ptrace(task)))
16416 +
16417 + static int proc_pid_environ(struct task_struct *task, char * buffer)
16418 + {
16419 +@@ -263,9 +264,9 @@ static int proc_pid_auxv(struct task_str
16420 + struct mm_struct *mm = get_task_mm(task);
16421 + if (mm) {
16422 + unsigned int nwords = 0;
16423 +- do
16424 ++ do {
16425 + nwords += 2;
16426 +- while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
16427 ++ } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
16428 + res = nwords * sizeof(mm->saved_auxv[0]);
16429 + if (res > PAGE_SIZE)
16430 + res = PAGE_SIZE;
16431 +@@ -338,6 +339,8 @@ static int proc_fd_access_allowed(struct
16432 + task = get_proc_task(inode);
16433 + if (task) {
16434 + allowed = ptrace_may_attach(task);
16435 ++ if (allowed != 0)
16436 ++ allowed = !gr_acl_handle_procpidmem(task);
16437 + put_task_struct(task);
16438 + }
16439 + return allowed;
16440 +@@ -528,7 +531,7 @@ static ssize_t mem_read(struct file * fi
16441 + if (!task)
16442 + goto out_no_task;
16443 +
16444 +- if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
16445 ++ if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task))
16446 + goto out;
16447 +
16448 + ret = -ENOMEM;
16449 +@@ -598,7 +601,7 @@ static ssize_t mem_write(struct file * f
16450 + if (!task)
16451 + goto out_no_task;
16452 +
16453 +- if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
16454 ++ if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task))
16455 + goto out;
16456 +
16457 + copied = -ENOMEM;
16458 +@@ -1050,7 +1053,11 @@ static struct inode *proc_pid_make_inode
16459 + inode->i_gid = 0;
16460 + if (task_dumpable(task)) {
16461 + inode->i_uid = task->euid;
16462 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16463 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
16464 ++#else
16465 + inode->i_gid = task->egid;
16466 ++#endif
16467 + }
16468 + security_task_to_inode(task, inode);
16469 +
16470 +@@ -1066,17 +1073,45 @@ static int pid_getattr(struct vfsmount *
16471 + {
16472 + struct inode *inode = dentry->d_inode;
16473 + struct task_struct *task;
16474 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16475 ++ struct task_struct *tmp = current;
16476 ++#endif
16477 ++
16478 + generic_fillattr(inode, stat);
16479 +
16480 + rcu_read_lock();
16481 + stat->uid = 0;
16482 + stat->gid = 0;
16483 + task = pid_task(proc_pid(inode), PIDTYPE_PID);
16484 +- if (task) {
16485 ++
16486 ++ if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) {
16487 ++ rcu_read_unlock();
16488 ++ return -ENOENT;
16489 ++ }
16490 ++
16491 ++
16492 ++ if (task
16493 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16494 ++ && (!tmp->uid || (tmp->uid == task->uid)
16495 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16496 ++ || in_group_p(CONFIG_GRKERNSEC_PROC_GID)
16497 ++#endif
16498 ++ )
16499 ++#endif
16500 ++ ) {
16501 + if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
16502 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
16503 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
16504 ++#elif CONFIG_GRKERNSEC_PROC_USERGROUP
16505 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
16506 ++#endif
16507 + task_dumpable(task)) {
16508 + stat->uid = task->euid;
16509 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16510 ++ stat->gid = CONFIG_GRKERNSEC_PROC_GID;
16511 ++#else
16512 + stat->gid = task->egid;
16513 ++#endif
16514 + }
16515 + }
16516 + rcu_read_unlock();
16517 +@@ -1104,11 +1139,21 @@ static int pid_revalidate(struct dentry
16518 + {
16519 + struct inode *inode = dentry->d_inode;
16520 + struct task_struct *task = get_proc_task(inode);
16521 ++
16522 + if (task) {
16523 + if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
16524 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
16525 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
16526 ++#elif CONFIG_GRKERNSEC_PROC_USERGROUP
16527 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
16528 ++#endif
16529 + task_dumpable(task)) {
16530 + inode->i_uid = task->euid;
16531 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16532 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
16533 ++#else
16534 + inode->i_gid = task->egid;
16535 ++#endif
16536 + } else {
16537 + inode->i_uid = 0;
16538 + inode->i_gid = 0;
16539 +@@ -1118,6 +1163,7 @@ static int pid_revalidate(struct dentry
16540 + put_task_struct(task);
16541 + return 1;
16542 + }
16543 ++out:
16544 + d_drop(dentry);
16545 + return 0;
16546 + }
16547 +@@ -1374,6 +1420,9 @@ static struct dentry *proc_lookupfd_comm
16548 + if (fd == ~0U)
16549 + goto out;
16550 +
16551 ++ if (gr_acl_handle_procpidmem(task))
16552 ++ goto out;
16553 ++
16554 + result = instantiate(dir, dentry, task, &fd);
16555 + out:
16556 + put_task_struct(task);
16557 +@@ -1410,6 +1459,8 @@ static int proc_readfd_common(struct fil
16558 + goto out;
16559 + filp->f_pos++;
16560 + default:
16561 ++ if (gr_acl_handle_procpidmem(p))
16562 ++ goto out;
16563 + files = get_files_struct(p);
16564 + if (!files)
16565 + goto out;
16566 +@@ -1598,6 +1649,9 @@ static struct dentry *proc_pident_lookup
16567 + if (!task)
16568 + goto out_no_task;
16569 +
16570 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
16571 ++ goto out;
16572 ++
16573 + /*
16574 + * Yes, it does not scale. And it should not. Don't add
16575 + * new entries into /proc/<tgid>/ without very good reasons.
16576 +@@ -1643,6 +1697,9 @@ static int proc_pident_readdir(struct fi
16577 + if (!task)
16578 + goto out_no_task;
16579 +
16580 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
16581 ++ goto out;
16582 ++
16583 + ret = 0;
16584 + pid = task->pid;
16585 + i = filp->f_pos;
16586 +@@ -1998,6 +2055,9 @@ static struct dentry *proc_base_lookup(s
16587 + if (p > last)
16588 + goto out;
16589 +
16590 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
16591 ++ goto out;
16592 ++
16593 + error = proc_base_instantiate(dir, dentry, task, p);
16594 +
16595 + out:
16596 +@@ -2097,6 +2157,9 @@ static const struct pid_entry tgid_base_
16597 + #ifdef CONFIG_TASK_IO_ACCOUNTING
16598 + INF("io", S_IRUGO, pid_io_accounting),
16599 + #endif
16600 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
16601 ++ INF("ipaddr", S_IRUSR, pid_ipaddr),
16602 ++#endif
16603 + };
16604 +
16605 + static int proc_tgid_base_readdir(struct file * filp,
16606 +@@ -2200,7 +2263,14 @@ static struct dentry *proc_pid_instantia
16607 + if (!inode)
16608 + goto out;
16609 +
16610 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
16611 ++ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
16612 ++#elif CONFIG_GRKERNSEC_PROC_USERGROUP
16613 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
16614 ++ inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP;
16615 ++#else
16616 + inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
16617 ++#endif
16618 + inode->i_op = &proc_tgid_base_inode_operations;
16619 + inode->i_fop = &proc_tgid_base_operations;
16620 + inode->i_flags|=S_IMMUTABLE;
16621 +@@ -2241,7 +2311,11 @@ struct dentry *proc_pid_lookup(struct in
16622 + if (!task)
16623 + goto out;
16624 +
16625 ++ if (gr_check_hidden_task(task))
16626 ++ goto out_put_task;
16627 ++
16628 + result = proc_pid_instantiate(dir, dentry, task, NULL);
16629 ++out_put_task:
16630 + put_task_struct(task);
16631 + out:
16632 + return result;
16633 +@@ -2299,6 +2373,9 @@ int proc_pid_readdir(struct file * filp,
16634 + {
16635 + unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
16636 + struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode);
16637 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16638 ++ struct task_struct *tmp = current;
16639 ++#endif
16640 + struct task_struct *task;
16641 + int tgid;
16642 +
16643 +@@ -2316,6 +2393,18 @@ int proc_pid_readdir(struct file * filp,
16644 + task;
16645 + put_task_struct(task), task = next_tgid(tgid + 1)) {
16646 + tgid = task->pid;
16647 ++
16648 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task)
16649 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16650 ++ || (tmp->uid && (task->uid != tmp->uid)
16651 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16652 ++ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
16653 ++#endif
16654 ++ )
16655 ++#endif
16656 ++ )
16657 ++ continue;
16658 ++
16659 + filp->f_pos = tgid + TGID_OFFSET;
16660 + if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) {
16661 + put_task_struct(task);
16662 +diff -Nurp linux-2.6.23.15/fs/proc/inode.c linux-2.6.23.15-grsec/fs/proc/inode.c
16663 +--- linux-2.6.23.15/fs/proc/inode.c 2007-10-09 21:31:38.000000000 +0100
16664 ++++ linux-2.6.23.15-grsec/fs/proc/inode.c 2008-02-11 10:37:44.000000000 +0000
16665 +@@ -418,7 +418,11 @@ struct inode *proc_get_inode(struct supe
16666 + if (de->mode) {
16667 + inode->i_mode = de->mode;
16668 + inode->i_uid = de->uid;
16669 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16670 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
16671 ++#else
16672 + inode->i_gid = de->gid;
16673 ++#endif
16674 + }
16675 + if (de->size)
16676 + inode->i_size = de->size;
16677 +diff -Nurp linux-2.6.23.15/fs/proc/internal.h linux-2.6.23.15-grsec/fs/proc/internal.h
16678 +--- linux-2.6.23.15/fs/proc/internal.h 2007-10-09 21:31:38.000000000 +0100
16679 ++++ linux-2.6.23.15-grsec/fs/proc/internal.h 2008-02-11 10:37:44.000000000 +0000
16680 +@@ -45,6 +45,9 @@ extern int proc_tid_stat(struct task_str
16681 + extern int proc_tgid_stat(struct task_struct *, char *);
16682 + extern int proc_pid_status(struct task_struct *, char *);
16683 + extern int proc_pid_statm(struct task_struct *, char *);
16684 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
16685 ++extern int proc_pid_ipaddr(struct task_struct*,char*);
16686 ++#endif
16687 +
16688 + extern const struct file_operations proc_maps_operations;
16689 + extern const struct file_operations proc_numa_maps_operations;
16690 +diff -Nurp linux-2.6.23.15/fs/proc/proc_misc.c linux-2.6.23.15-grsec/fs/proc/proc_misc.c
16691 +--- linux-2.6.23.15/fs/proc/proc_misc.c 2007-10-09 21:31:38.000000000 +0100
16692 ++++ linux-2.6.23.15-grsec/fs/proc/proc_misc.c 2008-02-11 10:37:44.000000000 +0000
16693 +@@ -668,6 +668,8 @@ void create_seq_entry(char *name, mode_t
16694 +
16695 + void __init proc_misc_init(void)
16696 + {
16697 ++ int gr_mode = 0;
16698 ++
16699 + static struct {
16700 + char *name;
16701 + int (*read_proc)(char*,char**,off_t,int,int*,void*);
16702 +@@ -683,7 +685,9 @@ void __init proc_misc_init(void)
16703 + {"stram", stram_read_proc},
16704 + #endif
16705 + {"filesystems", filesystems_read_proc},
16706 ++#ifndef CONFIG_GRKERNSEC_PROC_ADD
16707 + {"cmdline", cmdline_read_proc},
16708 ++#endif
16709 + {"locks", locks_read_proc},
16710 + {"execdomains", execdomains_read_proc},
16711 + {NULL,}
16712 +@@ -691,6 +695,15 @@ void __init proc_misc_init(void)
16713 + for (p = simple_ones; p->name; p++)
16714 + create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
16715 +
16716 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
16717 ++ gr_mode = S_IRUSR;
16718 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16719 ++ gr_mode = S_IRUSR | S_IRGRP;
16720 ++#endif
16721 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
16722 ++ create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
16723 ++#endif
16724 ++
16725 + proc_symlink("mounts", NULL, "self/mounts");
16726 +
16727 + /* And now for trickier ones */
16728 +@@ -702,7 +715,11 @@ void __init proc_misc_init(void)
16729 + entry->proc_fops = &proc_kmsg_operations;
16730 + }
16731 + #endif
16732 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
16733 ++ create_seq_entry("devices", gr_mode, &proc_devinfo_operations);
16734 ++#else
16735 + create_seq_entry("devices", 0, &proc_devinfo_operations);
16736 ++#endif
16737 + create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
16738 + #ifdef CONFIG_BLOCK
16739 + create_seq_entry("partitions", 0, &proc_partitions_operations);
16740 +@@ -710,7 +727,11 @@ void __init proc_misc_init(void)
16741 + create_seq_entry("stat", 0, &proc_stat_operations);
16742 + create_seq_entry("interrupts", 0, &proc_interrupts_operations);
16743 + #ifdef CONFIG_SLAB
16744 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
16745 ++ create_seq_entry("slabinfo",S_IWUSR|gr_mode,&proc_slabinfo_operations);
16746 ++#else
16747 + create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
16748 ++#endif
16749 + #ifdef CONFIG_DEBUG_SLAB_LEAK
16750 + create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations);
16751 + #endif
16752 +@@ -727,7 +748,7 @@ void __init proc_misc_init(void)
16753 + #ifdef CONFIG_SCHEDSTATS
16754 + create_seq_entry("schedstat", 0, &proc_schedstat_operations);
16755 + #endif
16756 +-#ifdef CONFIG_PROC_KCORE
16757 ++#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
16758 + proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
16759 + if (proc_root_kcore) {
16760 + proc_root_kcore->proc_fops = &proc_kcore_operations;
16761 +diff -Nurp linux-2.6.23.15/fs/proc/proc_sysctl.c linux-2.6.23.15-grsec/fs/proc/proc_sysctl.c
16762 +--- linux-2.6.23.15/fs/proc/proc_sysctl.c 2007-10-09 21:31:38.000000000 +0100
16763 ++++ linux-2.6.23.15-grsec/fs/proc/proc_sysctl.c 2008-02-11 10:37:44.000000000 +0000
16764 +@@ -7,6 +7,8 @@
16765 + #include <linux/security.h>
16766 + #include "internal.h"
16767 +
16768 ++extern __u32 gr_handle_sysctl(const struct ctl_table *table, const int op);
16769 ++
16770 + static struct dentry_operations proc_sys_dentry_operations;
16771 + static const struct file_operations proc_sys_file_operations;
16772 + static struct inode_operations proc_sys_inode_operations;
16773 +@@ -151,6 +153,9 @@ static struct dentry *proc_sys_lookup(st
16774 + if (!table)
16775 + goto out;
16776 +
16777 ++ if (gr_handle_sysctl(table, 001))
16778 ++ goto out;
16779 ++
16780 + err = ERR_PTR(-ENOMEM);
16781 + inode = proc_sys_make_inode(dir, table);
16782 + if (!inode)
16783 +@@ -358,6 +363,9 @@ static int proc_sys_readdir(struct file
16784 + if (pos < filp->f_pos)
16785 + continue;
16786 +
16787 ++ if (gr_handle_sysctl(table, 0))
16788 ++ continue;
16789 ++
16790 + if (proc_sys_fill_cache(filp, dirent, filldir, table) < 0)
16791 + goto out;
16792 + filp->f_pos = pos + 1;
16793 +@@ -420,6 +428,30 @@ out:
16794 + return error;
16795 + }
16796 +
16797 ++/* Eric Biederman is to blame */
16798 ++static int proc_sys_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
16799 ++{
16800 ++ int error = 0;
16801 ++ struct ctl_table_header *head;
16802 ++ struct ctl_table *table;
16803 ++
16804 ++ table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head);
16805 ++ /* Has the sysctl entry disappeared on us? */
16806 ++ if (!table)
16807 ++ goto out;
16808 ++
16809 ++ if (gr_handle_sysctl(table, 001)) {
16810 ++ error = -ENOENT;
16811 ++ goto out;
16812 ++ }
16813 ++
16814 ++out:
16815 ++ sysctl_head_finish(head);
16816 ++
16817 ++ generic_fillattr(dentry->d_inode, stat);
16818 ++
16819 ++ return error;
16820 ++}
16821 + static int proc_sys_setattr(struct dentry *dentry, struct iattr *attr)
16822 + {
16823 + struct inode *inode = dentry->d_inode;
16824 +@@ -448,6 +480,7 @@ static struct inode_operations proc_sys_
16825 + .lookup = proc_sys_lookup,
16826 + .permission = proc_sys_permission,
16827 + .setattr = proc_sys_setattr,
16828 ++ .getattr = proc_sys_getattr,
16829 + };
16830 +
16831 + static int proc_sys_revalidate(struct dentry *dentry, struct nameidata *nd)
16832 +diff -Nurp linux-2.6.23.15/fs/proc/root.c linux-2.6.23.15-grsec/fs/proc/root.c
16833 +--- linux-2.6.23.15/fs/proc/root.c 2007-10-09 21:31:38.000000000 +0100
16834 ++++ linux-2.6.23.15-grsec/fs/proc/root.c 2008-02-11 10:37:44.000000000 +0000
16835 +@@ -61,7 +61,13 @@ void __init proc_root_init(void)
16836 + return;
16837 + }
16838 + proc_misc_init();
16839 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
16840 ++ proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR, NULL);
16841 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16842 ++ proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
16843 ++#else
16844 + proc_net = proc_mkdir("net", NULL);
16845 ++#endif
16846 + proc_net_stat = proc_mkdir("net/stat", NULL);
16847 +
16848 + #ifdef CONFIG_SYSVIPC
16849 +@@ -78,7 +84,15 @@ void __init proc_root_init(void)
16850 + #ifdef CONFIG_PROC_DEVICETREE
16851 + proc_device_tree_init();
16852 + #endif
16853 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
16854 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
16855 ++ proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
16856 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16857 ++ proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
16858 ++#endif
16859 ++#else
16860 + proc_bus = proc_mkdir("bus", NULL);
16861 ++#endif
16862 + proc_sys_init();
16863 + }
16864 +
16865 +diff -Nurp linux-2.6.23.15/fs/proc/task_mmu.c linux-2.6.23.15-grsec/fs/proc/task_mmu.c
16866 +--- linux-2.6.23.15/fs/proc/task_mmu.c 2007-10-09 21:31:38.000000000 +0100
16867 ++++ linux-2.6.23.15-grsec/fs/proc/task_mmu.c 2008-02-11 10:37:44.000000000 +0000
16868 +@@ -44,15 +44,27 @@ char *task_mem(struct mm_struct *mm, cha
16869 + "VmStk:\t%8lu kB\n"
16870 + "VmExe:\t%8lu kB\n"
16871 + "VmLib:\t%8lu kB\n"
16872 +- "VmPTE:\t%8lu kB\n",
16873 +- hiwater_vm << (PAGE_SHIFT-10),
16874 ++ "VmPTE:\t%8lu kB\n"
16875 ++
16876 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
16877 ++ "CsBase:\t%8lx\nCsLim:\t%8lx\n"
16878 ++#endif
16879 ++
16880 ++ ,hiwater_vm << (PAGE_SHIFT-10),
16881 + (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
16882 + mm->locked_vm << (PAGE_SHIFT-10),
16883 + hiwater_rss << (PAGE_SHIFT-10),
16884 + total_rss << (PAGE_SHIFT-10),
16885 + data << (PAGE_SHIFT-10),
16886 + mm->stack_vm << (PAGE_SHIFT-10), text, lib,
16887 +- (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
16888 ++ (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
16889 ++
16890 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
16891 ++ , mm->context.user_cs_base, mm->context.user_cs_limit
16892 ++#endif
16893 ++
16894 ++ );
16895 ++
16896 + return buffer;
16897 + }
16898 +
16899 +@@ -131,6 +143,12 @@ struct pmd_walker {
16900 + unsigned long, void *);
16901 + };
16902 +
16903 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16904 ++#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
16905 ++ (_mm->pax_flags & MF_PAX_RANDMMAP || \
16906 ++ _mm->pax_flags & MF_PAX_SEGMEXEC))
16907 ++#endif
16908 ++
16909 + static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats *mss)
16910 + {
16911 + struct proc_maps_private *priv = m->private;
16912 +@@ -153,13 +171,22 @@ static int show_map_internal(struct seq_
16913 + }
16914 +
16915 + seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
16916 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16917 ++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
16918 ++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
16919 ++#else
16920 + vma->vm_start,
16921 + vma->vm_end,
16922 ++#endif
16923 + flags & VM_READ ? 'r' : '-',
16924 + flags & VM_WRITE ? 'w' : '-',
16925 + flags & VM_EXEC ? 'x' : '-',
16926 + flags & VM_MAYSHARE ? 's' : 'p',
16927 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16928 ++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_pgoff << PAGE_SHIFT,
16929 ++#else
16930 + vma->vm_pgoff << PAGE_SHIFT,
16931 ++#endif
16932 + MAJOR(dev), MINOR(dev), ino, &len);
16933 +
16934 + /*
16935 +@@ -173,11 +200,11 @@ static int show_map_internal(struct seq_
16936 + const char *name = arch_vma_name(vma);
16937 + if (!name) {
16938 + if (mm) {
16939 +- if (vma->vm_start <= mm->start_brk &&
16940 +- vma->vm_end >= mm->brk) {
16941 ++ if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
16942 + name = "[heap]";
16943 +- } else if (vma->vm_start <= mm->start_stack &&
16944 +- vma->vm_end >= mm->start_stack) {
16945 ++ } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
16946 ++ (vma->vm_start <= mm->start_stack &&
16947 ++ vma->vm_end >= mm->start_stack)) {
16948 + name = "[stack]";
16949 + }
16950 + } else {
16951 +@@ -191,7 +218,27 @@ static int show_map_internal(struct seq_
16952 + }
16953 + seq_putc(m, '\n');
16954 +
16955 +- if (mss)
16956 ++
16957 ++ if (mss) {
16958 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16959 ++ if (PAX_RAND_FLAGS(mm))
16960 ++ seq_printf(m,
16961 ++ "Size: %8lu kB\n"
16962 ++ "Rss: %8lu kB\n"
16963 ++ "Shared_Clean: %8lu kB\n"
16964 ++ "Shared_Dirty: %8lu kB\n"
16965 ++ "Private_Clean: %8lu kB\n"
16966 ++ "Private_Dirty: %8lu kB\n",
16967 ++ "Referenced: %8lu kB\n",
16968 ++ 0UL,
16969 ++ 0UL,
16970 ++ 0UL,
16971 ++ 0UL,
16972 ++ 0UL,
16973 ++ 0UL,
16974 ++ 0UL);
16975 ++ else
16976 ++#endif
16977 + seq_printf(m,
16978 + "Size: %8lu kB\n"
16979 + "Rss: %8lu kB\n"
16980 +@@ -207,6 +254,7 @@ static int show_map_internal(struct seq_
16981 + mss->private_clean >> 10,
16982 + mss->private_dirty >> 10,
16983 + mss->referenced >> 10);
16984 ++ }
16985 +
16986 + if (m->count < m->size) /* vma is copied successfully */
16987 + m->version = (vma != get_gate_vma(task))? vma->vm_start: 0;
16988 +diff -Nurp linux-2.6.23.15/fs/readdir.c linux-2.6.23.15-grsec/fs/readdir.c
16989 +--- linux-2.6.23.15/fs/readdir.c 2007-10-09 21:31:38.000000000 +0100
16990 ++++ linux-2.6.23.15-grsec/fs/readdir.c 2008-02-11 10:37:44.000000000 +0000
16991 +@@ -16,6 +16,8 @@
16992 + #include <linux/security.h>
16993 + #include <linux/syscalls.h>
16994 + #include <linux/unistd.h>
16995 ++#include <linux/namei.h>
16996 ++#include <linux/grsecurity.h>
16997 +
16998 + #include <asm/uaccess.h>
16999 +
17000 +@@ -64,6 +66,7 @@ struct old_linux_dirent {
17001 +
17002 + struct readdir_callback {
17003 + struct old_linux_dirent __user * dirent;
17004 ++ struct file * file;
17005 + int result;
17006 + };
17007 +
17008 +@@ -79,6 +82,10 @@ static int fillonedir(void * __buf, cons
17009 + d_ino = ino;
17010 + if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
17011 + return -EOVERFLOW;
17012 ++
17013 ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
17014 ++ return 0;
17015 ++
17016 + buf->result++;
17017 + dirent = buf->dirent;
17018 + if (!access_ok(VERIFY_WRITE, dirent,
17019 +@@ -110,6 +117,7 @@ asmlinkage long old_readdir(unsigned int
17020 +
17021 + buf.result = 0;
17022 + buf.dirent = dirent;
17023 ++ buf.file = file;
17024 +
17025 + error = vfs_readdir(file, fillonedir, &buf);
17026 + if (error >= 0)
17027 +@@ -136,6 +144,7 @@ struct linux_dirent {
17028 + struct getdents_callback {
17029 + struct linux_dirent __user * current_dir;
17030 + struct linux_dirent __user * previous;
17031 ++ struct file * file;
17032 + int count;
17033 + int error;
17034 + };
17035 +@@ -154,6 +163,10 @@ static int filldir(void * __buf, const c
17036 + d_ino = ino;
17037 + if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
17038 + return -EOVERFLOW;
17039 ++
17040 ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
17041 ++ return 0;
17042 ++
17043 + dirent = buf->previous;
17044 + if (dirent) {
17045 + if (__put_user(offset, &dirent->d_off))
17046 +@@ -200,6 +213,7 @@ asmlinkage long sys_getdents(unsigned in
17047 + buf.previous = NULL;
17048 + buf.count = count;
17049 + buf.error = 0;
17050 ++ buf.file = file;
17051 +
17052 + error = vfs_readdir(file, filldir, &buf);
17053 + if (error < 0)
17054 +@@ -222,6 +236,7 @@ out:
17055 + struct getdents_callback64 {
17056 + struct linux_dirent64 __user * current_dir;
17057 + struct linux_dirent64 __user * previous;
17058 ++ struct file *file;
17059 + int count;
17060 + int error;
17061 + };
17062 +@@ -236,6 +251,10 @@ static int filldir64(void * __buf, const
17063 + buf->error = -EINVAL; /* only used if we fail.. */
17064 + if (reclen > buf->count)
17065 + return -EINVAL;
17066 ++
17067 ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
17068 ++ return 0;
17069 ++
17070 + dirent = buf->previous;
17071 + if (dirent) {
17072 + if (__put_user(offset, &dirent->d_off))
17073 +@@ -282,6 +301,7 @@ asmlinkage long sys_getdents64(unsigned
17074 +
17075 + buf.current_dir = dirent;
17076 + buf.previous = NULL;
17077 ++ buf.file = file;
17078 + buf.count = count;
17079 + buf.error = 0;
17080 +
17081 +diff -Nurp linux-2.6.23.15/fs/udf/balloc.c linux-2.6.23.15-grsec/fs/udf/balloc.c
17082 +--- linux-2.6.23.15/fs/udf/balloc.c 2007-10-09 21:31:38.000000000 +0100
17083 ++++ linux-2.6.23.15-grsec/fs/udf/balloc.c 2008-02-11 10:37:44.000000000 +0000
17084 +@@ -154,8 +154,7 @@ static void udf_bitmap_free_blocks(struc
17085 + unsigned long overflow;
17086 +
17087 + mutex_lock(&sbi->s_alloc_mutex);
17088 +- if (bloc.logicalBlockNum < 0 ||
17089 +- (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) {
17090 ++ if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) {
17091 + udf_debug("%d < %d || %d + %d > %d\n",
17092 + bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
17093 + UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum));
17094 +@@ -221,7 +220,7 @@ static int udf_bitmap_prealloc_blocks(st
17095 + struct buffer_head *bh;
17096 +
17097 + mutex_lock(&sbi->s_alloc_mutex);
17098 +- if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
17099 ++ if (first_block >= UDF_SB_PARTLEN(sb, partition))
17100 + goto out;
17101 +
17102 + if (first_block + block_count > UDF_SB_PARTLEN(sb, partition))
17103 +@@ -287,7 +286,7 @@ static int udf_bitmap_new_block(struct s
17104 + mutex_lock(&sbi->s_alloc_mutex);
17105 +
17106 + repeat:
17107 +- if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
17108 ++ if (goal >= UDF_SB_PARTLEN(sb, partition))
17109 + goal = 0;
17110 +
17111 + nr_groups = bitmap->s_nr_groups;
17112 +@@ -420,8 +419,7 @@ static void udf_table_free_blocks(struct
17113 + int i;
17114 +
17115 + mutex_lock(&sbi->s_alloc_mutex);
17116 +- if (bloc.logicalBlockNum < 0 ||
17117 +- (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) {
17118 ++ if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) {
17119 + udf_debug("%d < %d || %d + %d > %d\n",
17120 + bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
17121 + UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum));
17122 +@@ -627,7 +625,7 @@ static int udf_table_prealloc_blocks(str
17123 + struct extent_position epos;
17124 + int8_t etype = -1;
17125 +
17126 +- if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
17127 ++ if (first_block >= UDF_SB_PARTLEN(sb, partition))
17128 + return 0;
17129 +
17130 + if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT)
17131 +@@ -703,7 +701,7 @@ static int udf_table_new_block(struct su
17132 + return newblock;
17133 +
17134 + mutex_lock(&sbi->s_alloc_mutex);
17135 +- if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
17136 ++ if (goal >= UDF_SB_PARTLEN(sb, partition))
17137 + goal = 0;
17138 +
17139 + /* We search for the closest matching block to goal. If we find a exact hit,
17140 +diff -Nurp linux-2.6.23.15/fs/udf/inode.c linux-2.6.23.15-grsec/fs/udf/inode.c
17141 +--- linux-2.6.23.15/fs/udf/inode.c 2007-10-09 21:31:38.000000000 +0100
17142 ++++ linux-2.6.23.15-grsec/fs/udf/inode.c 2008-02-11 10:37:44.000000000 +0000
17143 +@@ -308,9 +308,6 @@ static int udf_get_block(struct inode *i
17144 +
17145 + lock_kernel();
17146 +
17147 +- if (block < 0)
17148 +- goto abort_negative;
17149 +-
17150 + if (block == UDF_I_NEXT_ALLOC_BLOCK(inode) + 1) {
17151 + UDF_I_NEXT_ALLOC_BLOCK(inode)++;
17152 + UDF_I_NEXT_ALLOC_GOAL(inode)++;
17153 +@@ -331,10 +328,6 @@ static int udf_get_block(struct inode *i
17154 + abort:
17155 + unlock_kernel();
17156 + return err;
17157 +-
17158 +-abort_negative:
17159 +- udf_warning(inode->i_sb, "udf_get_block", "block < 0");
17160 +- goto abort;
17161 + }
17162 +
17163 + static struct buffer_head *udf_getblk(struct inode *inode, long block,
17164 +diff -Nurp linux-2.6.23.15/fs/ufs/inode.c linux-2.6.23.15-grsec/fs/ufs/inode.c
17165 +--- linux-2.6.23.15/fs/ufs/inode.c 2007-10-09 21:31:38.000000000 +0100
17166 ++++ linux-2.6.23.15-grsec/fs/ufs/inode.c 2008-02-11 10:37:44.000000000 +0000
17167 +@@ -55,9 +55,7 @@ static int ufs_block_to_path(struct inod
17168 +
17169 +
17170 + UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
17171 +- if (i_block < 0) {
17172 +- ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
17173 +- } else if (i_block < direct_blocks) {
17174 ++ if (i_block < direct_blocks) {
17175 + offsets[n++] = i_block;
17176 + } else if ((i_block -= direct_blocks) < indirect_blocks) {
17177 + offsets[n++] = UFS_IND_BLOCK;
17178 +@@ -439,8 +437,6 @@ int ufs_getfrag_block(struct inode *inod
17179 + lock_kernel();
17180 +
17181 + UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
17182 +- if (fragment < 0)
17183 +- goto abort_negative;
17184 + if (fragment >
17185 + ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
17186 + << uspi->s_fpbshift))
17187 +@@ -503,10 +499,6 @@ abort:
17188 + unlock_kernel();
17189 + return err;
17190 +
17191 +-abort_negative:
17192 +- ufs_warning(sb, "ufs_get_block", "block < 0");
17193 +- goto abort;
17194 +-
17195 + abort_too_big:
17196 + ufs_warning(sb, "ufs_get_block", "block > big");
17197 + goto abort;
17198 +diff -Nurp linux-2.6.23.15/fs/utimes.c linux-2.6.23.15-grsec/fs/utimes.c
17199 +--- linux-2.6.23.15/fs/utimes.c 2007-10-09 21:31:38.000000000 +0100
17200 ++++ linux-2.6.23.15-grsec/fs/utimes.c 2008-02-11 10:37:44.000000000 +0000
17201 +@@ -6,6 +6,7 @@
17202 + #include <linux/sched.h>
17203 + #include <linux/stat.h>
17204 + #include <linux/utime.h>
17205 ++#include <linux/grsecurity.h>
17206 + #include <asm/uaccess.h>
17207 + #include <asm/unistd.h>
17208 +
17209 +@@ -47,6 +48,7 @@ long do_utimes(int dfd, char __user *fil
17210 + int error;
17211 + struct nameidata nd;
17212 + struct dentry *dentry;
17213 ++ struct vfsmount *mnt;
17214 + struct inode *inode;
17215 + struct iattr newattrs;
17216 + struct file *f = NULL;
17217 +@@ -65,12 +67,14 @@ long do_utimes(int dfd, char __user *fil
17218 + if (!f)
17219 + goto out;
17220 + dentry = f->f_path.dentry;
17221 ++ mnt = f->f_path.mnt;
17222 + } else {
17223 + error = __user_walk_fd(dfd, filename, (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW, &nd);
17224 + if (error)
17225 + goto out;
17226 +
17227 + dentry = nd.dentry;
17228 ++ mnt = nd.mnt;
17229 + }
17230 +
17231 + inode = dentry->d_inode;
17232 +@@ -117,6 +121,12 @@ long do_utimes(int dfd, char __user *fil
17233 + }
17234 + }
17235 + }
17236 ++
17237 ++ if (!gr_acl_handle_utime(dentry, mnt)) {
17238 ++ error = -EACCES;
17239 ++ goto dput_and_out;
17240 ++ }
17241 ++
17242 + mutex_lock(&inode->i_mutex);
17243 + error = notify_change(dentry, &newattrs);
17244 + mutex_unlock(&inode->i_mutex);
17245 +diff -Nurp linux-2.6.23.15/fs/xfs/xfs_bmap.c linux-2.6.23.15-grsec/fs/xfs/xfs_bmap.c
17246 +--- linux-2.6.23.15/fs/xfs/xfs_bmap.c 2007-10-09 21:31:38.000000000 +0100
17247 ++++ linux-2.6.23.15-grsec/fs/xfs/xfs_bmap.c 2008-02-11 10:37:44.000000000 +0000
17248 +@@ -374,7 +374,7 @@ xfs_bmap_validate_ret(
17249 + int nmap,
17250 + int ret_nmap);
17251 + #else
17252 +-#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
17253 ++#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
17254 + #endif /* DEBUG */
17255 +
17256 + #if defined(XFS_RW_TRACE)
17257 +diff -Nurp linux-2.6.23.15/grsecurity/Kconfig linux-2.6.23.15-grsec/grsecurity/Kconfig
17258 +--- linux-2.6.23.15/grsecurity/Kconfig 1970-01-01 01:00:00.000000000 +0100
17259 ++++ linux-2.6.23.15-grsec/grsecurity/Kconfig 2008-02-11 10:37:44.000000000 +0000
17260 +@@ -0,0 +1,873 @@
17261 ++#
17262 ++# grecurity configuration
17263 ++#
17264 ++
17265 ++menu "Grsecurity"
17266 ++
17267 ++config GRKERNSEC
17268 ++ bool "Grsecurity"
17269 ++ select CRYPTO
17270 ++ select CRYPTO_SHA256
17271 ++ help
17272 ++ If you say Y here, you will be able to configure many features
17273 ++ that will enhance the security of your system. It is highly
17274 ++ recommended that you say Y here and read through the help
17275 ++ for each option so that you fully understand the features and
17276 ++ can evaluate their usefulness for your machine.
17277 ++
17278 ++choice
17279 ++ prompt "Security Level"
17280 ++ depends GRKERNSEC
17281 ++ default GRKERNSEC_CUSTOM
17282 ++
17283 ++config GRKERNSEC_LOW
17284 ++ bool "Low"
17285 ++ select GRKERNSEC_LINK
17286 ++ select GRKERNSEC_FIFO
17287 ++ select GRKERNSEC_EXECVE
17288 ++ select GRKERNSEC_RANDNET
17289 ++ select GRKERNSEC_DMESG
17290 ++ select GRKERNSEC_CHROOT_CHDIR
17291 ++ select GRKERNSEC_MODSTOP if (MODULES)
17292 ++
17293 ++ help
17294 ++ If you choose this option, several of the grsecurity options will
17295 ++ be enabled that will give you greater protection against a number
17296 ++ of attacks, while assuring that none of your software will have any
17297 ++ conflicts with the additional security measures. If you run a lot
17298 ++ of unusual software, or you are having problems with the higher
17299 ++ security levels, you should say Y here. With this option, the
17300 ++ following features are enabled:
17301 ++
17302 ++ - Linking restrictions
17303 ++ - FIFO restrictions
17304 ++ - Enforcing RLIMIT_NPROC on execve
17305 ++ - Restricted dmesg
17306 ++ - Enforced chdir("/") on chroot
17307 ++ - Runtime module disabling
17308 ++
17309 ++config GRKERNSEC_MEDIUM
17310 ++ bool "Medium"
17311 ++ select PAX
17312 ++ select PAX_EI_PAX
17313 ++ select PAX_PT_PAX_FLAGS
17314 ++ select PAX_HAVE_ACL_FLAGS
17315 ++ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
17316 ++ select GRKERNSEC_CHROOT_SYSCTL
17317 ++ select GRKERNSEC_LINK
17318 ++ select GRKERNSEC_FIFO
17319 ++ select GRKERNSEC_EXECVE
17320 ++ select GRKERNSEC_DMESG
17321 ++ select GRKERNSEC_RANDNET
17322 ++ select GRKERNSEC_FORKFAIL
17323 ++ select GRKERNSEC_TIME
17324 ++ select GRKERNSEC_SIGNAL
17325 ++ select GRKERNSEC_CHROOT
17326 ++ select GRKERNSEC_CHROOT_UNIX
17327 ++ select GRKERNSEC_CHROOT_MOUNT
17328 ++ select GRKERNSEC_CHROOT_PIVOT
17329 ++ select GRKERNSEC_CHROOT_DOUBLE
17330 ++ select GRKERNSEC_CHROOT_CHDIR
17331 ++ select GRKERNSEC_CHROOT_MKNOD
17332 ++ select GRKERNSEC_PROC
17333 ++ select GRKERNSEC_PROC_USERGROUP
17334 ++ select GRKERNSEC_MODSTOP if (MODULES)
17335 ++ select PAX_RANDUSTACK
17336 ++ select PAX_ASLR
17337 ++ select PAX_RANDMMAP
17338 ++
17339 ++ help
17340 ++ If you say Y here, several features in addition to those included
17341 ++ in the low additional security level will be enabled. These
17342 ++ features provide even more security to your system, though in rare
17343 ++ cases they may be incompatible with very old or poorly written
17344 ++ software. If you enable this option, make sure that your auth
17345 ++ service (identd) is running as gid 1001. With this option,
17346 ++ the following features (in addition to those provided in the
17347 ++ low additional security level) will be enabled:
17348 ++
17349 ++ - Randomized TCP source ports
17350 ++ - Failed fork logging
17351 ++ - Time change logging
17352 ++ - Signal logging
17353 ++ - Deny mounts in chroot
17354 ++ - Deny double chrooting
17355 ++ - Deny sysctl writes in chroot
17356 ++ - Deny mknod in chroot
17357 ++ - Deny access to abstract AF_UNIX sockets out of chroot
17358 ++ - Deny pivot_root in chroot
17359 ++ - Denied writes of /dev/kmem, /dev/mem, and /dev/port
17360 ++ - /proc restrictions with special GID set to 10 (usually wheel)
17361 ++ - Address Space Layout Randomization (ASLR)
17362 ++
17363 ++config GRKERNSEC_HIGH
17364 ++ bool "High"
17365 ++ select GRKERNSEC_LINK
17366 ++ select GRKERNSEC_FIFO
17367 ++ select GRKERNSEC_EXECVE
17368 ++ select GRKERNSEC_DMESG
17369 ++ select GRKERNSEC_FORKFAIL
17370 ++ select GRKERNSEC_TIME
17371 ++ select GRKERNSEC_SIGNAL
17372 ++ select GRKERNSEC_CHROOT_SHMAT
17373 ++ select GRKERNSEC_CHROOT_UNIX
17374 ++ select GRKERNSEC_CHROOT_MOUNT
17375 ++ select GRKERNSEC_CHROOT_FCHDIR
17376 ++ select GRKERNSEC_CHROOT_PIVOT
17377 ++ select GRKERNSEC_CHROOT_DOUBLE
17378 ++ select GRKERNSEC_CHROOT_CHDIR
17379 ++ select GRKERNSEC_CHROOT_MKNOD
17380 ++ select GRKERNSEC_CHROOT_CAPS
17381 ++ select GRKERNSEC_CHROOT_SYSCTL
17382 ++ select GRKERNSEC_CHROOT_FINDTASK
17383 ++ select GRKERNSEC_PROC
17384 ++ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
17385 ++ select GRKERNSEC_HIDESYM
17386 ++ select GRKERNSEC_BRUTE
17387 ++ select GRKERNSEC_SHM if (SYSVIPC)
17388 ++ select GRKERNSEC_PROC_USERGROUP
17389 ++ select GRKERNSEC_KMEM
17390 ++ select GRKERNSEC_RESLOG
17391 ++ select GRKERNSEC_RANDNET
17392 ++ select GRKERNSEC_PROC_ADD
17393 ++ select GRKERNSEC_CHROOT_CHMOD
17394 ++ select GRKERNSEC_CHROOT_NICE
17395 ++ select GRKERNSEC_AUDIT_MOUNT
17396 ++ select GRKERNSEC_MODSTOP if (MODULES)
17397 ++ select PAX
17398 ++ select PAX_RANDUSTACK
17399 ++ select PAX_ASLR
17400 ++ select PAX_RANDMMAP
17401 ++ select PAX_NOEXEC
17402 ++ select PAX_MPROTECT
17403 ++ select PAX_EI_PAX
17404 ++ select PAX_PT_PAX_FLAGS
17405 ++ select PAX_HAVE_ACL_FLAGS
17406 ++ select PAX_KERNEXEC if (!X86_64 && !EFI && !COMPAT_VDSO && !PARAVIRT && X86_WP_WORKS_OK)
17407 ++ select PAX_MEMORY_UDEREF if (!X86_64 && !COMPAT_VDSO)
17408 ++ select PAX_RANDKSTACK if (X86_TSC && !X86_64)
17409 ++ select PAX_SEGMEXEC if (X86 && !X86_64)
17410 ++ select PAX_PAGEEXEC if (!X86)
17411 ++ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
17412 ++ select PAX_DLRESOLVE if (SPARC32 || SPARC64)
17413 ++ select PAX_SYSCALL if (PPC32)
17414 ++ select PAX_EMUTRAMP if (PARISC)
17415 ++ select PAX_EMUSIGRT if (PARISC)
17416 ++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
17417 ++ help
17418 ++ If you say Y here, many of the features of grsecurity will be
17419 ++ enabled, which will protect you against many kinds of attacks
17420 ++ against your system. The heightened security comes at a cost
17421 ++ of an increased chance of incompatibilities with rare software
17422 ++ on your machine. Since this security level enables PaX, you should
17423 ++ view <http://pax.grsecurity.net> and read about the PaX
17424 ++ project. While you are there, download chpax and run it on
17425 ++ binaries that cause problems with PaX. Also remember that
17426 ++ since the /proc restrictions are enabled, you must run your
17427 ++ identd as gid 1001. This security level enables the following
17428 ++ features in addition to those listed in the low and medium
17429 ++ security levels:
17430 ++
17431 ++ - Additional /proc restrictions
17432 ++ - Chmod restrictions in chroot
17433 ++ - No signals, ptrace, or viewing of processes outside of chroot
17434 ++ - Capability restrictions in chroot
17435 ++ - Deny fchdir out of chroot
17436 ++ - Priority restrictions in chroot
17437 ++ - Segmentation-based implementation of PaX
17438 ++ - Mprotect restrictions
17439 ++ - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
17440 ++ - Kernel stack randomization
17441 ++ - Mount/unmount/remount logging
17442 ++ - Kernel symbol hiding
17443 ++ - Destroy unused shared memory
17444 ++ - Prevention of memory exhaustion-based exploits
17445 ++config GRKERNSEC_CUSTOM
17446 ++ bool "Custom"
17447 ++ help
17448 ++ If you say Y here, you will be able to configure every grsecurity
17449 ++ option, which allows you to enable many more features that aren't
17450 ++ covered in the basic security levels. These additional features
17451 ++ include TPE, socket restrictions, and the sysctl system for
17452 ++ grsecurity. It is advised that you read through the help for
17453 ++ each option to determine its usefulness in your situation.
17454 ++
17455 ++endchoice
17456 ++
17457 ++menu "Address Space Protection"
17458 ++depends on GRKERNSEC
17459 ++
17460 ++config GRKERNSEC_KMEM
17461 ++ bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
17462 ++ help
17463 ++ If you say Y here, /dev/kmem and /dev/mem won't be allowed to
17464 ++ be written to via mmap or otherwise to modify the running kernel.
17465 ++ /dev/port will also not be allowed to be opened. If you have module
17466 ++ support disabled, enabling this will close up four ways that are
17467 ++ currently used to insert malicious code into the running kernel.
17468 ++ Even with all these features enabled, we still highly recommend that
17469 ++ you use the RBAC system, as it is still possible for an attacker to
17470 ++ modify the running kernel through privileged I/O granted by ioperm/iopl.
17471 ++ If you are not using XFree86, you may be able to stop this additional
17472 ++ case by enabling the 'Disable privileged I/O' option. Though nothing
17473 ++ legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
17474 ++ but only to video memory, which is the only writing we allow in this
17475 ++ case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
17476 ++ not be allowed to mprotect it with PROT_WRITE later.
17477 ++ It is highly recommended that you say Y here if you meet all the
17478 ++ conditions above.
17479 ++
17480 ++config GRKERNSEC_IO
17481 ++ bool "Disable privileged I/O"
17482 ++ depends on X86
17483 ++ select RTC
17484 ++ help
17485 ++ If you say Y here, all ioperm and iopl calls will return an error.
17486 ++ Ioperm and iopl can be used to modify the running kernel.
17487 ++ Unfortunately, some programs need this access to operate properly,
17488 ++ the most notable of which are XFree86 and hwclock. hwclock can be
17489 ++ remedied by having RTC support in the kernel, so CONFIG_RTC is
17490 ++ enabled if this option is enabled, to ensure that hwclock operates
17491 ++ correctly. XFree86 still will not operate correctly with this option
17492 ++ enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86
17493 ++ and you still want to protect your kernel against modification,
17494 ++ use the RBAC system.
17495 ++
17496 ++config GRKERNSEC_PROC_MEMMAP
17497 ++ bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
17498 ++ depends on PAX_NOEXEC || PAX_ASLR
17499 ++ help
17500 ++ If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
17501 ++ give no information about the addresses of its mappings if
17502 ++ PaX features that rely on random addresses are enabled on the task.
17503 ++ If you use PaX it is greatly recommended that you say Y here as it
17504 ++ closes up a hole that makes the full ASLR useless for suid
17505 ++ binaries.
17506 ++
17507 ++config GRKERNSEC_BRUTE
17508 ++ bool "Deter exploit bruteforcing"
17509 ++ help
17510 ++ If you say Y here, attempts to bruteforce exploits against forking
17511 ++ daemons such as apache or sshd will be deterred. When a child of a
17512 ++ forking daemon is killed by PaX or crashes due to an illegal
17513 ++ instruction, the parent process will be delayed 30 seconds upon every
17514 ++ subsequent fork until the administrator is able to assess the
17515 ++ situation and restart the daemon. It is recommended that you also
17516 ++ enable signal logging in the auditing section so that logs are
17517 ++ generated when a process performs an illegal instruction.
17518 ++
17519 ++config GRKERNSEC_MODSTOP
17520 ++ bool "Runtime module disabling"
17521 ++ depends on MODULES
17522 ++ help
17523 ++ If you say Y here, you will be able to disable the ability to (un)load
17524 ++ modules at runtime. This feature is useful if you need the ability
17525 ++ to load kernel modules at boot time, but do not want to allow an
17526 ++ attacker to load a rootkit kernel module into the system, or to remove
17527 ++ a loaded kernel module important to system functioning. You should
17528 ++ enable the /dev/mem protection feature as well, since rootkits can be
17529 ++ inserted into the kernel via other methods than kernel modules. Since
17530 ++ an untrusted module could still be loaded by modifying init scripts and
17531 ++ rebooting the system, it is also recommended that you enable the RBAC
17532 ++ system. If you enable this option, a sysctl option with name
17533 ++ "disable_modules" will be created. Setting this option to "1" disables
17534 ++ module loading. After this option is set, no further writes to it are
17535 ++ allowed until the system is rebooted.
17536 ++
17537 ++config GRKERNSEC_HIDESYM
17538 ++ bool "Hide kernel symbols"
17539 ++ help
17540 ++ If you say Y here, getting information on loaded modules, and
17541 ++ displaying all kernel symbols through a syscall will be restricted
17542 ++ to users with CAP_SYS_MODULE. This option is only effective
17543 ++ provided the following conditions are met:
17544 ++ 1) The kernel using grsecurity is not precompiled by some distribution
17545 ++ 2) You are using the RBAC system and hiding other files such as your
17546 ++ kernel image and System.map
17547 ++ 3) You have the additional /proc restrictions enabled, which removes
17548 ++ /proc/kcore
17549 ++ If the above conditions are met, this option will aid to provide a
17550 ++ useful protection against local and remote kernel exploitation of
17551 ++ overflows and arbitrary read/write vulnerabilities.
17552 ++
17553 ++endmenu
17554 ++menu "Role Based Access Control Options"
17555 ++depends on GRKERNSEC
17556 ++
17557 ++config GRKERNSEC_ACL_HIDEKERN
17558 ++ bool "Hide kernel processes"
17559 ++ help
17560 ++ If you say Y here, all kernel threads will be hidden to all
17561 ++ processes but those whose subject has the "view hidden processes"
17562 ++ flag.
17563 ++
17564 ++config GRKERNSEC_ACL_MAXTRIES
17565 ++ int "Maximum tries before password lockout"
17566 ++ default 3
17567 ++ help
17568 ++ This option enforces the maximum number of times a user can attempt
17569 ++ to authorize themselves with the grsecurity RBAC system before being
17570 ++ denied the ability to attempt authorization again for a specified time.
17571 ++ The lower the number, the harder it will be to brute-force a password.
17572 ++
17573 ++config GRKERNSEC_ACL_TIMEOUT
17574 ++ int "Time to wait after max password tries, in seconds"
17575 ++ default 30
17576 ++ help
17577 ++ This option specifies the time the user must wait after attempting to
17578 ++ authorize to the RBAC system with the maximum number of invalid
17579 ++ passwords. The higher the number, the harder it will be to brute-force
17580 ++ a password.
17581 ++
17582 ++endmenu
17583 ++menu "Filesystem Protections"
17584 ++depends on GRKERNSEC
17585 ++
17586 ++config GRKERNSEC_PROC
17587 ++ bool "Proc restrictions"
17588 ++ help
17589 ++ If you say Y here, the permissions of the /proc filesystem
17590 ++ will be altered to enhance system security and privacy. You MUST
17591 ++ choose either a user only restriction or a user and group restriction.
17592 ++ Depending upon the option you choose, you can either restrict users to
17593 ++ see only the processes they themselves run, or choose a group that can
17594 ++ view all processes and files normally restricted to root if you choose
17595 ++ the "restrict to user only" option. NOTE: If you're running identd as
17596 ++ a non-root user, you will have to run it as the group you specify here.
17597 ++
17598 ++config GRKERNSEC_PROC_USER
17599 ++ bool "Restrict /proc to user only"
17600 ++ depends on GRKERNSEC_PROC
17601 ++ help
17602 ++ If you say Y here, non-root users will only be able to view their own
17603 ++ processes, and restricts them from viewing network-related information,
17604 ++ and viewing kernel symbol and module information.
17605 ++
17606 ++config GRKERNSEC_PROC_USERGROUP
17607 ++ bool "Allow special group"
17608 ++ depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
17609 ++ help
17610 ++ If you say Y here, you will be able to select a group that will be
17611 ++ able to view all processes, network-related information, and
17612 ++ kernel and symbol information. This option is useful if you want
17613 ++ to run identd as a non-root user.
17614 ++
17615 ++config GRKERNSEC_PROC_GID
17616 ++ int "GID for special group"
17617 ++ depends on GRKERNSEC_PROC_USERGROUP
17618 ++ default 1001
17619 ++
17620 ++config GRKERNSEC_PROC_ADD
17621 ++ bool "Additional restrictions"
17622 ++ depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
17623 ++ help
17624 ++ If you say Y here, additional restrictions will be placed on
17625 ++ /proc that keep normal users from viewing device information and
17626 ++ slabinfo information that could be useful for exploits.
17627 ++
17628 ++config GRKERNSEC_LINK
17629 ++ bool "Linking restrictions"
17630 ++ help
17631 ++ If you say Y here, /tmp race exploits will be prevented, since users
17632 ++ will no longer be able to follow symlinks owned by other users in
17633 ++ world-writable +t directories (i.e. /tmp), unless the owner of the
17634 ++ symlink is the owner of the directory. users will also not be
17635 ++ able to hardlink to files they do not own. If the sysctl option is
17636 ++ enabled, a sysctl option with name "linking_restrictions" is created.
17637 ++
17638 ++config GRKERNSEC_FIFO
17639 ++ bool "FIFO restrictions"
17640 ++ help
17641 ++ If you say Y here, users will not be able to write to FIFOs they don't
17642 ++ own in world-writable +t directories (i.e. /tmp), unless the owner of
17643 ++ the FIFO is the same owner of the directory it's held in. If the sysctl
17644 ++ option is enabled, a sysctl option with name "fifo_restrictions" is
17645 ++ created.
17646 ++
17647 ++config GRKERNSEC_CHROOT
17648 ++ bool "Chroot jail restrictions"
17649 ++ help
17650 ++ If you say Y here, you will be able to choose several options that will
17651 ++ make breaking out of a chrooted jail much more difficult. If you
17652 ++ encounter no software incompatibilities with the following options, it
17653 ++ is recommended that you enable each one.
17654 ++
17655 ++config GRKERNSEC_CHROOT_MOUNT
17656 ++ bool "Deny mounts"
17657 ++ depends on GRKERNSEC_CHROOT
17658 ++ help
17659 ++ If you say Y here, processes inside a chroot will not be able to
17660 ++ mount or remount filesystems. If the sysctl option is enabled, a
17661 ++ sysctl option with name "chroot_deny_mount" is created.
17662 ++
17663 ++config GRKERNSEC_CHROOT_DOUBLE
17664 ++ bool "Deny double-chroots"
17665 ++ depends on GRKERNSEC_CHROOT
17666 ++ help
17667 ++ If you say Y here, processes inside a chroot will not be able to chroot
17668 ++ again outside the chroot. This is a widely used method of breaking
17669 ++ out of a chroot jail and should not be allowed. If the sysctl
17670 ++ option is enabled, a sysctl option with name
17671 ++ "chroot_deny_chroot" is created.
17672 ++
17673 ++config GRKERNSEC_CHROOT_PIVOT
17674 ++ bool "Deny pivot_root in chroot"
17675 ++ depends on GRKERNSEC_CHROOT
17676 ++ help
17677 ++ If you say Y here, processes inside a chroot will not be able to use
17678 ++ a function called pivot_root() that was introduced in Linux 2.3.41. It
17679 ++ works similar to chroot in that it changes the root filesystem. This
17680 ++ function could be misused in a chrooted process to attempt to break out
17681 ++ of the chroot, and therefore should not be allowed. If the sysctl
17682 ++ option is enabled, a sysctl option with name "chroot_deny_pivot" is
17683 ++ created.
17684 ++
17685 ++config GRKERNSEC_CHROOT_CHDIR
17686 ++ bool "Enforce chdir(\"/\") on all chroots"
17687 ++ depends on GRKERNSEC_CHROOT
17688 ++ help
17689 ++ If you say Y here, the current working directory of all newly-chrooted
17690 ++ applications will be set to the the root directory of the chroot.
17691 ++ The man page on chroot(2) states:
17692 ++ Note that this call does not change the current working
17693 ++ directory, so that `.' can be outside the tree rooted at
17694 ++ `/'. In particular, the super-user can escape from a
17695 ++ `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
17696 ++
17697 ++ It is recommended that you say Y here, since it's not known to break
17698 ++ any software. If the sysctl option is enabled, a sysctl option with
17699 ++ name "chroot_enforce_chdir" is created.
17700 ++
17701 ++config GRKERNSEC_CHROOT_CHMOD
17702 ++ bool "Deny (f)chmod +s"
17703 ++ depends on GRKERNSEC_CHROOT
17704 ++ help
17705 ++ If you say Y here, processes inside a chroot will not be able to chmod
17706 ++ or fchmod files to make them have suid or sgid bits. This protects
17707 ++ against another published method of breaking a chroot. If the sysctl
17708 ++ option is enabled, a sysctl option with name "chroot_deny_chmod" is
17709 ++ created.
17710 ++
17711 ++config GRKERNSEC_CHROOT_FCHDIR
17712 ++ bool "Deny fchdir out of chroot"
17713 ++ depends on GRKERNSEC_CHROOT
17714 ++ help
17715 ++ If you say Y here, a well-known method of breaking chroots by fchdir'ing
17716 ++ to a file descriptor of the chrooting process that points to a directory
17717 ++ outside the filesystem will be stopped. If the sysctl option
17718 ++ is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
17719 ++
17720 ++config GRKERNSEC_CHROOT_MKNOD
17721 ++ bool "Deny mknod"
17722 ++ depends on GRKERNSEC_CHROOT
17723 ++ help
17724 ++ If you say Y here, processes inside a chroot will not be allowed to
17725 ++ mknod. The problem with using mknod inside a chroot is that it
17726 ++ would allow an attacker to create a device entry that is the same
17727 ++ as one on the physical root of your system, which could range from
17728 ++ anything from the console device to a device for your harddrive (which
17729 ++ they could then use to wipe the drive or steal data). It is recommended
17730 ++ that you say Y here, unless you run into software incompatibilities.
17731 ++ If the sysctl option is enabled, a sysctl option with name
17732 ++ "chroot_deny_mknod" is created.
17733 ++
17734 ++config GRKERNSEC_CHROOT_SHMAT
17735 ++ bool "Deny shmat() out of chroot"
17736 ++ depends on GRKERNSEC_CHROOT
17737 ++ help
17738 ++ If you say Y here, processes inside a chroot will not be able to attach
17739 ++ to shared memory segments that were created outside of the chroot jail.
17740 ++ It is recommended that you say Y here. If the sysctl option is enabled,
17741 ++ a sysctl option with name "chroot_deny_shmat" is created.
17742 ++
17743 ++config GRKERNSEC_CHROOT_UNIX
17744 ++ bool "Deny access to abstract AF_UNIX sockets out of chroot"
17745 ++ depends on GRKERNSEC_CHROOT
17746 ++ help
17747 ++ If you say Y here, processes inside a chroot will not be able to
17748 ++ connect to abstract (meaning not belonging to a filesystem) Unix
17749 ++ domain sockets that were bound outside of a chroot. It is recommended
17750 ++ that you say Y here. If the sysctl option is enabled, a sysctl option
17751 ++ with name "chroot_deny_unix" is created.
17752 ++
17753 ++config GRKERNSEC_CHROOT_FINDTASK
17754 ++ bool "Protect outside processes"
17755 ++ depends on GRKERNSEC_CHROOT
17756 ++ help
17757 ++ If you say Y here, processes inside a chroot will not be able to
17758 ++ kill, send signals with fcntl, ptrace, capget, getpgid, getsid,
17759 ++ or view any process outside of the chroot. If the sysctl
17760 ++ option is enabled, a sysctl option with name "chroot_findtask" is
17761 ++ created.
17762 ++
17763 ++config GRKERNSEC_CHROOT_NICE
17764 ++ bool "Restrict priority changes"
17765 ++ depends on GRKERNSEC_CHROOT
17766 ++ help
17767 ++ If you say Y here, processes inside a chroot will not be able to raise
17768 ++ the priority of processes in the chroot, or alter the priority of
17769 ++ processes outside the chroot. This provides more security than simply
17770 ++ removing CAP_SYS_NICE from the process' capability set. If the
17771 ++ sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
17772 ++ is created.
17773 ++
17774 ++config GRKERNSEC_CHROOT_SYSCTL
17775 ++ bool "Deny sysctl writes"
17776 ++ depends on GRKERNSEC_CHROOT
17777 ++ help
17778 ++ If you say Y here, an attacker in a chroot will not be able to
17779 ++ write to sysctl entries, either by sysctl(2) or through a /proc
17780 ++ interface. It is strongly recommended that you say Y here. If the
17781 ++ sysctl option is enabled, a sysctl option with name
17782 ++ "chroot_deny_sysctl" is created.
17783 ++
17784 ++config GRKERNSEC_CHROOT_CAPS
17785 ++ bool "Capability restrictions"
17786 ++ depends on GRKERNSEC_CHROOT
17787 ++ help
17788 ++ If you say Y here, the capabilities on all root processes within a
17789 ++ chroot jail will be lowered to stop module insertion, raw i/o,
17790 ++ system and net admin tasks, rebooting the system, modifying immutable
17791 ++ files, modifying IPC owned by another, and changing the system time.
17792 ++ This is left an option because it can break some apps. Disable this
17793 ++ if your chrooted apps are having problems performing those kinds of
17794 ++ tasks. If the sysctl option is enabled, a sysctl option with
17795 ++ name "chroot_caps" is created.
17796 ++
17797 ++endmenu
17798 ++menu "Kernel Auditing"
17799 ++depends on GRKERNSEC
17800 ++
17801 ++config GRKERNSEC_AUDIT_GROUP
17802 ++ bool "Single group for auditing"
17803 ++ help
17804 ++ If you say Y here, the exec, chdir, (un)mount, and ipc logging features
17805 ++ will only operate on a group you specify. This option is recommended
17806 ++ if you only want to watch certain users instead of having a large
17807 ++ amount of logs from the entire system. If the sysctl option is enabled,
17808 ++ a sysctl option with name "audit_group" is created.
17809 ++
17810 ++config GRKERNSEC_AUDIT_GID
17811 ++ int "GID for auditing"
17812 ++ depends on GRKERNSEC_AUDIT_GROUP
17813 ++ default 1007
17814 ++
17815 ++config GRKERNSEC_EXECLOG
17816 ++ bool "Exec logging"
17817 ++ help
17818 ++ If you say Y here, all execve() calls will be logged (since the
17819 ++ other exec*() calls are frontends to execve(), all execution
17820 ++ will be logged). Useful for shell-servers that like to keep track
17821 ++ of their users. If the sysctl option is enabled, a sysctl option with
17822 ++ name "exec_logging" is created.
17823 ++ WARNING: This option when enabled will produce a LOT of logs, especially
17824 ++ on an active system.
17825 ++
17826 ++config GRKERNSEC_RESLOG
17827 ++ bool "Resource logging"
17828 ++ help
17829 ++ If you say Y here, all attempts to overstep resource limits will
17830 ++ be logged with the resource name, the requested size, and the current
17831 ++ limit. It is highly recommended that you say Y here. If the sysctl
17832 ++ option is enabled, a sysctl option with name "resource_logging" is
17833 ++ created. If the RBAC system is enabled, the sysctl value is ignored.
17834 ++
17835 ++config GRKERNSEC_CHROOT_EXECLOG
17836 ++ bool "Log execs within chroot"
17837 ++ help
17838 ++ If you say Y here, all executions inside a chroot jail will be logged
17839 ++ to syslog. This can cause a large amount of logs if certain
17840 ++ applications (eg. djb's daemontools) are installed on the system, and
17841 ++ is therefore left as an option. If the sysctl option is enabled, a
17842 ++ sysctl option with name "chroot_execlog" is created.
17843 ++
17844 ++config GRKERNSEC_AUDIT_CHDIR
17845 ++ bool "Chdir logging"
17846 ++ help
17847 ++ If you say Y here, all chdir() calls will be logged. If the sysctl
17848 ++ option is enabled, a sysctl option with name "audit_chdir" is created.
17849 ++
17850 ++config GRKERNSEC_AUDIT_MOUNT
17851 ++ bool "(Un)Mount logging"
17852 ++ help
17853 ++ If you say Y here, all mounts and unmounts will be logged. If the
17854 ++ sysctl option is enabled, a sysctl option with name "audit_mount" is
17855 ++ created.
17856 ++
17857 ++config GRKERNSEC_AUDIT_IPC
17858 ++ bool "IPC logging"
17859 ++ help
17860 ++ If you say Y here, creation and removal of message queues, semaphores,
17861 ++ and shared memory will be logged. If the sysctl option is enabled, a
17862 ++ sysctl option with name "audit_ipc" is created.
17863 ++
17864 ++config GRKERNSEC_SIGNAL
17865 ++ bool "Signal logging"
17866 ++ help
17867 ++ If you say Y here, certain important signals will be logged, such as
17868 ++ SIGSEGV, which will as a result inform you of when a error in a program
17869 ++ occurred, which in some cases could mean a possible exploit attempt.
17870 ++ If the sysctl option is enabled, a sysctl option with name
17871 ++ "signal_logging" is created.
17872 ++
17873 ++config GRKERNSEC_FORKFAIL
17874 ++ bool "Fork failure logging"
17875 ++ help
17876 ++ If you say Y here, all failed fork() attempts will be logged.
17877 ++ This could suggest a fork bomb, or someone attempting to overstep
17878 ++ their process limit. If the sysctl option is enabled, a sysctl option
17879 ++ with name "forkfail_logging" is created.
17880 ++
17881 ++config GRKERNSEC_TIME
17882 ++ bool "Time change logging"
17883 ++ help
17884 ++ If you say Y here, any changes of the system clock will be logged.
17885 ++ If the sysctl option is enabled, a sysctl option with name
17886 ++ "timechange_logging" is created.
17887 ++
17888 ++config GRKERNSEC_PROC_IPADDR
17889 ++ bool "/proc/<pid>/ipaddr support"
17890 ++ help
17891 ++ If you say Y here, a new entry will be added to each /proc/<pid>
17892 ++ directory that contains the IP address of the person using the task.
17893 ++ The IP is carried across local TCP and AF_UNIX stream sockets.
17894 ++ This information can be useful for IDS/IPSes to perform remote response
17895 ++ to a local attack. The entry is readable by only the owner of the
17896 ++ process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
17897 ++ the RBAC system), and thus does not create privacy concerns.
17898 ++
17899 ++config GRKERNSEC_AUDIT_TEXTREL
17900 ++ bool 'ELF text relocations logging (READ HELP)'
17901 ++ depends on PAX_MPROTECT
17902 ++ help
17903 ++ If you say Y here, text relocations will be logged with the filename
17904 ++ of the offending library or binary. The purpose of the feature is
17905 ++ to help Linux distribution developers get rid of libraries and
17906 ++ binaries that need text relocations which hinder the future progress
17907 ++ of PaX. Only Linux distribution developers should say Y here, and
17908 ++ never on a production machine, as this option creates an information
17909 ++ leak that could aid an attacker in defeating the randomization of
17910 ++ a single memory region. If the sysctl option is enabled, a sysctl
17911 ++ option with name "audit_textrel" is created.
17912 ++
17913 ++endmenu
17914 ++
17915 ++menu "Executable Protections"
17916 ++depends on GRKERNSEC
17917 ++
17918 ++config GRKERNSEC_EXECVE
17919 ++ bool "Enforce RLIMIT_NPROC on execs"
17920 ++ help
17921 ++ If you say Y here, users with a resource limit on processes will
17922 ++ have the value checked during execve() calls. The current system
17923 ++ only checks the system limit during fork() calls. If the sysctl option
17924 ++ is enabled, a sysctl option with name "execve_limiting" is created.
17925 ++
17926 ++config GRKERNSEC_SHM
17927 ++ bool "Destroy unused shared memory"
17928 ++ depends on SYSVIPC
17929 ++ help
17930 ++ If you say Y here, shared memory will be destroyed when no one is
17931 ++ attached to it. Otherwise, resources involved with the shared
17932 ++ memory can be used up and not be associated with any process (as the
17933 ++ shared memory still exists, and the creating process has exited). If
17934 ++ the sysctl option is enabled, a sysctl option with name
17935 ++ "destroy_unused_shm" is created.
17936 ++
17937 ++config GRKERNSEC_DMESG
17938 ++ bool "Dmesg(8) restriction"
17939 ++ help
17940 ++ If you say Y here, non-root users will not be able to use dmesg(8)
17941 ++ to view up to the last 4kb of messages in the kernel's log buffer.
17942 ++ If the sysctl option is enabled, a sysctl option with name "dmesg" is
17943 ++ created.
17944 ++
17945 ++config GRKERNSEC_TPE
17946 ++ bool "Trusted Path Execution (TPE)"
17947 ++ help
17948 ++ If you say Y here, you will be able to choose a gid to add to the
17949 ++ supplementary groups of users you want to mark as "untrusted."
17950 ++ These users will not be able to execute any files that are not in
17951 ++ root-owned directories writable only by root. If the sysctl option
17952 ++ is enabled, a sysctl option with name "tpe" is created.
17953 ++
17954 ++config GRKERNSEC_TPE_ALL
17955 ++ bool "Partially restrict non-root users"
17956 ++ depends on GRKERNSEC_TPE
17957 ++ help
17958 ++ If you say Y here, All non-root users other than the ones in the
17959 ++ group specified in the main TPE option will only be allowed to
17960 ++ execute files in directories they own that are not group or
17961 ++ world-writable, or in directories owned by root and writable only by
17962 ++ root. If the sysctl option is enabled, a sysctl option with name
17963 ++ "tpe_restrict_all" is created.
17964 ++
17965 ++config GRKERNSEC_TPE_INVERT
17966 ++ bool "Invert GID option"
17967 ++ depends on GRKERNSEC_TPE
17968 ++ help
17969 ++ If you say Y here, the group you specify in the TPE configuration will
17970 ++ decide what group TPE restrictions will be *disabled* for. This
17971 ++ option is useful if you want TPE restrictions to be applied to most
17972 ++ users on the system.
17973 ++
17974 ++config GRKERNSEC_TPE_GID
17975 ++ int "GID for untrusted users"
17976 ++ depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
17977 ++ default 1005
17978 ++ help
17979 ++ If you have selected the "Invert GID option" above, setting this
17980 ++ GID determines what group TPE restrictions will be *disabled* for.
17981 ++ If you have not selected the "Invert GID option" above, setting this
17982 ++ GID determines what group TPE restrictions will be *enabled* for.
17983 ++ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
17984 ++ is created.
17985 ++
17986 ++config GRKERNSEC_TPE_GID
17987 ++ int "GID for trusted users"
17988 ++ depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
17989 ++ default 1005
17990 ++ help
17991 ++ If you have selected the "Invert GID option" above, setting this
17992 ++ GID determines what group TPE restrictions will be *disabled* for.
17993 ++ If you have not selected the "Invert GID option" above, setting this
17994 ++ GID determines what group TPE restrictions will be *enabled* for.
17995 ++ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
17996 ++ is created.
17997 ++
17998 ++endmenu
17999 ++menu "Network Protections"
18000 ++depends on GRKERNSEC
18001 ++
18002 ++config GRKERNSEC_RANDNET
18003 ++ bool "Larger entropy pools"
18004 ++ help
18005 ++ If you say Y here, the entropy pools used for many features of Linux
18006 ++ and grsecurity will be doubled in size. Since several grsecurity
18007 ++ features use additional randomness, it is recommended that you say Y
18008 ++ here. Saying Y here has a similar effect as modifying
18009 ++ /proc/sys/kernel/random/poolsize.
18010 ++
18011 ++config GRKERNSEC_SOCKET
18012 ++ bool "Socket restrictions"
18013 ++ help
18014 ++ If you say Y here, you will be able to choose from several options.
18015 ++ If you assign a GID on your system and add it to the supplementary
18016 ++ groups of users you want to restrict socket access to, this patch
18017 ++ will perform up to three things, based on the option(s) you choose.
18018 ++
18019 ++config GRKERNSEC_SOCKET_ALL
18020 ++ bool "Deny any sockets to group"
18021 ++ depends on GRKERNSEC_SOCKET
18022 ++ help
18023 ++ If you say Y here, you will be able to choose a GID of whose users will
18024 ++ be unable to connect to other hosts from your machine or run server
18025 ++ applications from your machine. If the sysctl option is enabled, a
18026 ++ sysctl option with name "socket_all" is created.
18027 ++
18028 ++config GRKERNSEC_SOCKET_ALL_GID
18029 ++ int "GID to deny all sockets for"
18030 ++ depends on GRKERNSEC_SOCKET_ALL
18031 ++ default 1004
18032 ++ help
18033 ++ Here you can choose the GID to disable socket access for. Remember to
18034 ++ add the users you want socket access disabled for to the GID
18035 ++ specified here. If the sysctl option is enabled, a sysctl option
18036 ++ with name "socket_all_gid" is created.
18037 ++
18038 ++config GRKERNSEC_SOCKET_CLIENT
18039 ++ bool "Deny client sockets to group"
18040 ++ depends on GRKERNSEC_SOCKET
18041 ++ help
18042 ++ If you say Y here, you will be able to choose a GID of whose users will
18043 ++ be unable to connect to other hosts from your machine, but will be
18044 ++ able to run servers. If this option is enabled, all users in the group
18045 ++ you specify will have to use passive mode when initiating ftp transfers
18046 ++ from the shell on your machine. If the sysctl option is enabled, a
18047 ++ sysctl option with name "socket_client" is created.
18048 ++
18049 ++config GRKERNSEC_SOCKET_CLIENT_GID
18050 ++ int "GID to deny client sockets for"
18051 ++ depends on GRKERNSEC_SOCKET_CLIENT
18052 ++ default 1003
18053 ++ help
18054 ++ Here you can choose the GID to disable client socket access for.
18055 ++ Remember to add the users you want client socket access disabled for to
18056 ++ the GID specified here. If the sysctl option is enabled, a sysctl
18057 ++ option with name "socket_client_gid" is created.
18058 ++
18059 ++config GRKERNSEC_SOCKET_SERVER
18060 ++ bool "Deny server sockets to group"
18061 ++ depends on GRKERNSEC_SOCKET
18062 ++ help
18063 ++ If you say Y here, you will be able to choose a GID of whose users will
18064 ++ be unable to run server applications from your machine. If the sysctl
18065 ++ option is enabled, a sysctl option with name "socket_server" is created.
18066 ++
18067 ++config GRKERNSEC_SOCKET_SERVER_GID
18068 ++ int "GID to deny server sockets for"
18069 ++ depends on GRKERNSEC_SOCKET_SERVER
18070 ++ default 1002
18071 ++ help
18072 ++ Here you can choose the GID to disable server socket access for.
18073 ++ Remember to add the users you want server socket access disabled for to
18074 ++ the GID specified here. If the sysctl option is enabled, a sysctl
18075 ++ option with name "socket_server_gid" is created.
18076 ++
18077 ++endmenu
18078 ++menu "Sysctl support"
18079 ++depends on GRKERNSEC && SYSCTL
18080 ++
18081 ++config GRKERNSEC_SYSCTL
18082 ++ bool "Sysctl support"
18083 ++ help
18084 ++ If you say Y here, you will be able to change the options that
18085 ++ grsecurity runs with at bootup, without having to recompile your
18086 ++ kernel. You can echo values to files in /proc/sys/kernel/grsecurity
18087 ++ to enable (1) or disable (0) various features. All the sysctl entries
18088 ++ are mutable until the "grsec_lock" entry is set to a non-zero value.
18089 ++ All features enabled in the kernel configuration are disabled at boot
18090 ++ if you do not say Y to the "Turn on features by default" option.
18091 ++ All options should be set at startup, and the grsec_lock entry should
18092 ++ be set to a non-zero value after all the options are set.
18093 ++ *THIS IS EXTREMELY IMPORTANT*
18094 ++
18095 ++config GRKERNSEC_SYSCTL_ON
18096 ++ bool "Turn on features by default"
18097 ++ depends on GRKERNSEC_SYSCTL
18098 ++ help
18099 ++ If you say Y here, instead of having all features enabled in the
18100 ++ kernel configuration disabled at boot time, the features will be
18101 ++ enabled at boot time. It is recommended you say Y here unless
18102 ++ there is some reason you would want all sysctl-tunable features to
18103 ++ be disabled by default. As mentioned elsewhere, it is important
18104 ++ to enable the grsec_lock entry once you have finished modifying
18105 ++ the sysctl entries.
18106 ++
18107 ++endmenu
18108 ++menu "Logging Options"
18109 ++depends on GRKERNSEC
18110 ++
18111 ++config GRKERNSEC_FLOODTIME
18112 ++ int "Seconds in between log messages (minimum)"
18113 ++ default 10
18114 ++ help
18115 ++ This option allows you to enforce the number of seconds between
18116 ++ grsecurity log messages. The default should be suitable for most
18117 ++ people, however, if you choose to change it, choose a value small enough
18118 ++ to allow informative logs to be produced, but large enough to
18119 ++ prevent flooding.
18120 ++
18121 ++config GRKERNSEC_FLOODBURST
18122 ++ int "Number of messages in a burst (maximum)"
18123 ++ default 4
18124 ++ help
18125 ++ This option allows you to choose the maximum number of messages allowed
18126 ++ within the flood time interval you chose in a separate option. The
18127 ++ default should be suitable for most people, however if you find that
18128 ++ many of your logs are being interpreted as flooding, you may want to
18129 ++ raise this value.
18130 ++
18131 ++endmenu
18132 ++
18133 ++endmenu
18134 +diff -Nurp linux-2.6.23.15/grsecurity/Makefile linux-2.6.23.15-grsec/grsecurity/Makefile
18135 +--- linux-2.6.23.15/grsecurity/Makefile 1970-01-01 01:00:00.000000000 +0100
18136 ++++ linux-2.6.23.15-grsec/grsecurity/Makefile 2008-02-11 10:37:44.000000000 +0000
18137 +@@ -0,0 +1,20 @@
18138 ++# grsecurity's ACL system was originally written in 2001 by Michael Dalton
18139 ++# during 2001-2005 it has been completely redesigned by Brad Spengler
18140 ++# into an RBAC system
18141 ++#
18142 ++# All code in this directory and various hooks inserted throughout the kernel
18143 ++# are copyright Brad Spengler, and released under the GPL v2 or higher
18144 ++
18145 ++obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
18146 ++ grsec_mount.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
18147 ++ grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
18148 ++
18149 ++obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
18150 ++ gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
18151 ++ gracl_learn.o grsec_log.o
18152 ++obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
18153 ++
18154 ++ifndef CONFIG_GRKERNSEC
18155 ++obj-y += grsec_disabled.o
18156 ++endif
18157 ++
18158 +diff -Nurp linux-2.6.23.15/grsecurity/gracl.c linux-2.6.23.15-grsec/grsecurity/gracl.c
18159 +--- linux-2.6.23.15/grsecurity/gracl.c 1970-01-01 01:00:00.000000000 +0100
18160 ++++ linux-2.6.23.15-grsec/grsecurity/gracl.c 2008-02-11 10:37:44.000000000 +0000
18161 +@@ -0,0 +1,3722 @@
18162 ++#include <linux/kernel.h>
18163 ++#include <linux/module.h>
18164 ++#include <linux/sched.h>
18165 ++#include <linux/mm.h>
18166 ++#include <linux/file.h>
18167 ++#include <linux/fs.h>
18168 ++#include <linux/namei.h>
18169 ++#include <linux/mount.h>
18170 ++#include <linux/tty.h>
18171 ++#include <linux/proc_fs.h>
18172 ++#include <linux/smp_lock.h>
18173 ++#include <linux/slab.h>
18174 ++#include <linux/vmalloc.h>
18175 ++#include <linux/types.h>
18176 ++#include <linux/capability.h>
18177 ++#include <linux/sysctl.h>
18178 ++#include <linux/netdevice.h>
18179 ++#include <linux/ptrace.h>
18180 ++#include <linux/gracl.h>
18181 ++#include <linux/gralloc.h>
18182 ++#include <linux/grsecurity.h>
18183 ++#include <linux/grinternal.h>
18184 ++#include <linux/pid_namespace.h>
18185 ++#include <linux/percpu.h>
18186 ++
18187 ++#include <asm/uaccess.h>
18188 ++#include <asm/errno.h>
18189 ++#include <asm/mman.h>
18190 ++
18191 ++static struct acl_role_db acl_role_set;
18192 ++static struct name_db name_set;
18193 ++static struct inodev_db inodev_set;
18194 ++
18195 ++/* for keeping track of userspace pointers used for subjects, so we
18196 ++ can share references in the kernel as well
18197 ++*/
18198 ++
18199 ++static struct dentry *real_root;
18200 ++static struct vfsmount *real_root_mnt;
18201 ++
18202 ++static struct acl_subj_map_db subj_map_set;
18203 ++
18204 ++static struct acl_role_label *default_role;
18205 ++
18206 ++static u16 acl_sp_role_value;
18207 ++
18208 ++extern char *gr_shared_page[4];
18209 ++static DECLARE_MUTEX(gr_dev_sem);
18210 ++rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
18211 ++
18212 ++struct gr_arg *gr_usermode;
18213 ++
18214 ++static unsigned int gr_status = GR_STATUS_INIT;
18215 ++
18216 ++extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
18217 ++extern void gr_clear_learn_entries(void);
18218 ++
18219 ++#ifdef CONFIG_GRKERNSEC_RESLOG
18220 ++extern void gr_log_resource(const struct task_struct *task,
18221 ++ const int res, const unsigned long wanted, const int gt);
18222 ++#endif
18223 ++
18224 ++unsigned char *gr_system_salt;
18225 ++unsigned char *gr_system_sum;
18226 ++
18227 ++static struct sprole_pw **acl_special_roles = NULL;
18228 ++static __u16 num_sprole_pws = 0;
18229 ++
18230 ++static struct acl_role_label *kernel_role = NULL;
18231 ++
18232 ++static unsigned int gr_auth_attempts = 0;
18233 ++static unsigned long gr_auth_expires = 0UL;
18234 ++
18235 ++extern struct vfsmount *sock_mnt;
18236 ++extern struct vfsmount *pipe_mnt;
18237 ++extern struct vfsmount *shm_mnt;
18238 ++static struct acl_object_label *fakefs_obj;
18239 ++
18240 ++extern int gr_init_uidset(void);
18241 ++extern void gr_free_uidset(void);
18242 ++extern void gr_remove_uid(uid_t uid);
18243 ++extern int gr_find_uid(uid_t uid);
18244 ++
18245 ++__inline__ int
18246 ++gr_acl_is_enabled(void)
18247 ++{
18248 ++ return (gr_status & GR_READY);
18249 ++}
18250 ++
18251 ++char gr_roletype_to_char(void)
18252 ++{
18253 ++ switch (current->role->roletype &
18254 ++ (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
18255 ++ GR_ROLE_SPECIAL)) {
18256 ++ case GR_ROLE_DEFAULT:
18257 ++ return 'D';
18258 ++ case GR_ROLE_USER:
18259 ++ return 'U';
18260 ++ case GR_ROLE_GROUP:
18261 ++ return 'G';
18262 ++ case GR_ROLE_SPECIAL:
18263 ++ return 'S';
18264 ++ }
18265 ++
18266 ++ return 'X';
18267 ++}
18268 ++
18269 ++__inline__ int
18270 ++gr_acl_tpe_check(void)
18271 ++{
18272 ++ if (unlikely(!(gr_status & GR_READY)))
18273 ++ return 0;
18274 ++ if (current->role->roletype & GR_ROLE_TPE)
18275 ++ return 1;
18276 ++ else
18277 ++ return 0;
18278 ++}
18279 ++
18280 ++int
18281 ++gr_handle_rawio(const struct inode *inode)
18282 ++{
18283 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
18284 ++ if (inode && S_ISBLK(inode->i_mode) &&
18285 ++ grsec_enable_chroot_caps && proc_is_chrooted(current) &&
18286 ++ !capable(CAP_SYS_RAWIO))
18287 ++ return 1;
18288 ++#endif
18289 ++ return 0;
18290 ++}
18291 ++
18292 ++static int
18293 ++gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
18294 ++{
18295 ++ int i;
18296 ++ unsigned long *l1;
18297 ++ unsigned long *l2;
18298 ++ unsigned char *c1;
18299 ++ unsigned char *c2;
18300 ++ int num_longs;
18301 ++
18302 ++ if (likely(lena != lenb))
18303 ++ return 0;
18304 ++
18305 ++ l1 = (unsigned long *)a;
18306 ++ l2 = (unsigned long *)b;
18307 ++
18308 ++ num_longs = lena / sizeof(unsigned long);
18309 ++
18310 ++ for (i = num_longs; i--; l1++, l2++) {
18311 ++ if (unlikely(*l1 != *l2))
18312 ++ return 0;
18313 ++ }
18314 ++
18315 ++ c1 = (unsigned char *) l1;
18316 ++ c2 = (unsigned char *) l2;
18317 ++
18318 ++ i = lena - (num_longs * sizeof(unsigned long));
18319 ++
18320 ++ for (; i--; c1++, c2++) {
18321 ++ if (unlikely(*c1 != *c2))
18322 ++ return 0;
18323 ++ }
18324 ++
18325 ++ return 1;
18326 ++}
18327 ++
18328 ++static char * __our_d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
18329 ++ struct dentry *root, struct vfsmount *rootmnt,
18330 ++ char *buffer, int buflen)
18331 ++{
18332 ++ char * end = buffer+buflen;
18333 ++ char * retval;
18334 ++ int namelen;
18335 ++
18336 ++ *--end = '\0';
18337 ++ buflen--;
18338 ++
18339 ++ if (buflen < 1)
18340 ++ goto Elong;
18341 ++ /* Get '/' right */
18342 ++ retval = end-1;
18343 ++ *retval = '/';
18344 ++
18345 ++ for (;;) {
18346 ++ struct dentry * parent;
18347 ++
18348 ++ if (dentry == root && vfsmnt == rootmnt)
18349 ++ break;
18350 ++ if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
18351 ++ /* Global root? */
18352 ++ spin_lock(&vfsmount_lock);
18353 ++ if (vfsmnt->mnt_parent == vfsmnt) {
18354 ++ spin_unlock(&vfsmount_lock);
18355 ++ goto global_root;
18356 ++ }
18357 ++ dentry = vfsmnt->mnt_mountpoint;
18358 ++ vfsmnt = vfsmnt->mnt_parent;
18359 ++ spin_unlock(&vfsmount_lock);
18360 ++ continue;
18361 ++ }
18362 ++ parent = dentry->d_parent;
18363 ++ prefetch(parent);
18364 ++ namelen = dentry->d_name.len;
18365 ++ buflen -= namelen + 1;
18366 ++ if (buflen < 0)
18367 ++ goto Elong;
18368 ++ end -= namelen;
18369 ++ memcpy(end, dentry->d_name.name, namelen);
18370 ++ *--end = '/';
18371 ++ retval = end;
18372 ++ dentry = parent;
18373 ++ }
18374 ++
18375 ++ return retval;
18376 ++
18377 ++global_root:
18378 ++ namelen = dentry->d_name.len;
18379 ++ buflen -= namelen;
18380 ++ if (buflen < 0)
18381 ++ goto Elong;
18382 ++ retval -= namelen-1; /* hit the slash */
18383 ++ memcpy(retval, dentry->d_name.name, namelen);
18384 ++ return retval;
18385 ++Elong:
18386 ++ return ERR_PTR(-ENAMETOOLONG);
18387 ++}
18388 ++
18389 ++static char *
18390 ++gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
18391 ++ struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
18392 ++{
18393 ++ char *retval;
18394 ++
18395 ++ retval = __our_d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
18396 ++ if (unlikely(IS_ERR(retval)))
18397 ++ retval = strcpy(buf, "<path too long>");
18398 ++ else if (unlikely(retval[1] == '/' && retval[2] == '\0'))
18399 ++ retval[1] = '\0';
18400 ++
18401 ++ return retval;
18402 ++}
18403 ++
18404 ++static char *
18405 ++__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
18406 ++ char *buf, int buflen)
18407 ++{
18408 ++ char *res;
18409 ++
18410 ++ /* we can use real_root, real_root_mnt, because this is only called
18411 ++ by the RBAC system */
18412 ++ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
18413 ++
18414 ++ return res;
18415 ++}
18416 ++
18417 ++static char *
18418 ++d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
18419 ++ char *buf, int buflen)
18420 ++{
18421 ++ char *res;
18422 ++ struct dentry *root;
18423 ++ struct vfsmount *rootmnt;
18424 ++ struct task_struct *reaper = child_reaper(current);
18425 ++
18426 ++ /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
18427 ++ read_lock(&reaper->fs->lock);
18428 ++ root = dget(reaper->fs->root);
18429 ++ rootmnt = mntget(reaper->fs->rootmnt);
18430 ++ read_unlock(&reaper->fs->lock);
18431 ++
18432 ++ spin_lock(&dcache_lock);
18433 ++ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
18434 ++ spin_unlock(&dcache_lock);
18435 ++
18436 ++ dput(root);
18437 ++ mntput(rootmnt);
18438 ++ return res;
18439 ++}
18440 ++
18441 ++static char *
18442 ++gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
18443 ++{
18444 ++ char *ret;
18445 ++ spin_lock(&dcache_lock);
18446 ++ ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
18447 ++ PAGE_SIZE);
18448 ++ spin_unlock(&dcache_lock);
18449 ++ return ret;
18450 ++}
18451 ++
18452 ++char *
18453 ++gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
18454 ++{
18455 ++ return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
18456 ++ PAGE_SIZE);
18457 ++}
18458 ++
18459 ++char *
18460 ++gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
18461 ++{
18462 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
18463 ++ PAGE_SIZE);
18464 ++}
18465 ++
18466 ++char *
18467 ++gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
18468 ++{
18469 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
18470 ++ PAGE_SIZE);
18471 ++}
18472 ++
18473 ++char *
18474 ++gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
18475 ++{
18476 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
18477 ++ PAGE_SIZE);
18478 ++}
18479 ++
18480 ++char *
18481 ++gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
18482 ++{
18483 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
18484 ++ PAGE_SIZE);
18485 ++}
18486 ++
18487 ++__inline__ __u32
18488 ++to_gr_audit(const __u32 reqmode)
18489 ++{
18490 ++ /* masks off auditable permission flags, then shifts them to create
18491 ++ auditing flags, and adds the special case of append auditing if
18492 ++ we're requesting write */
18493 ++ return (((reqmode & ~GR_AUDITS) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
18494 ++}
18495 ++
18496 ++struct acl_subject_label *
18497 ++lookup_subject_map(const struct acl_subject_label *userp)
18498 ++{
18499 ++ unsigned int index = shash(userp, subj_map_set.s_size);
18500 ++ struct subject_map *match;
18501 ++
18502 ++ match = subj_map_set.s_hash[index];
18503 ++
18504 ++ while (match && match->user != userp)
18505 ++ match = match->next;
18506 ++
18507 ++ if (match != NULL)
18508 ++ return match->kernel;
18509 ++ else
18510 ++ return NULL;
18511 ++}
18512 ++
18513 ++static void
18514 ++insert_subj_map_entry(struct subject_map *subjmap)
18515 ++{
18516 ++ unsigned int index = shash(subjmap->user, subj_map_set.s_size);
18517 ++ struct subject_map **curr;
18518 ++
18519 ++ subjmap->prev = NULL;
18520 ++
18521 ++ curr = &subj_map_set.s_hash[index];
18522 ++ if (*curr != NULL)
18523 ++ (*curr)->prev = subjmap;
18524 ++
18525 ++ subjmap->next = *curr;
18526 ++ *curr = subjmap;
18527 ++
18528 ++ return;
18529 ++}
18530 ++
18531 ++static struct acl_role_label *
18532 ++lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
18533 ++ const gid_t gid)
18534 ++{
18535 ++ unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
18536 ++ struct acl_role_label *match;
18537 ++ struct role_allowed_ip *ipp;
18538 ++ unsigned int x;
18539 ++
18540 ++ match = acl_role_set.r_hash[index];
18541 ++
18542 ++ while (match) {
18543 ++ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
18544 ++ for (x = 0; x < match->domain_child_num; x++) {
18545 ++ if (match->domain_children[x] == uid)
18546 ++ goto found;
18547 ++ }
18548 ++ } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
18549 ++ break;
18550 ++ match = match->next;
18551 ++ }
18552 ++found:
18553 ++ if (match == NULL) {
18554 ++ try_group:
18555 ++ index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
18556 ++ match = acl_role_set.r_hash[index];
18557 ++
18558 ++ while (match) {
18559 ++ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
18560 ++ for (x = 0; x < match->domain_child_num; x++) {
18561 ++ if (match->domain_children[x] == gid)
18562 ++ goto found2;
18563 ++ }
18564 ++ } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
18565 ++ break;
18566 ++ match = match->next;
18567 ++ }
18568 ++found2:
18569 ++ if (match == NULL)
18570 ++ match = default_role;
18571 ++ if (match->allowed_ips == NULL)
18572 ++ return match;
18573 ++ else {
18574 ++ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
18575 ++ if (likely
18576 ++ ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
18577 ++ (ntohl(ipp->addr) & ipp->netmask)))
18578 ++ return match;
18579 ++ }
18580 ++ match = default_role;
18581 ++ }
18582 ++ } else if (match->allowed_ips == NULL) {
18583 ++ return match;
18584 ++ } else {
18585 ++ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
18586 ++ if (likely
18587 ++ ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
18588 ++ (ntohl(ipp->addr) & ipp->netmask)))
18589 ++ return match;
18590 ++ }
18591 ++ goto try_group;
18592 ++ }
18593 ++
18594 ++ return match;
18595 ++}
18596 ++
18597 ++struct acl_subject_label *
18598 ++lookup_acl_subj_label(const ino_t ino, const dev_t dev,
18599 ++ const struct acl_role_label *role)
18600 ++{
18601 ++ unsigned int index = fhash(ino, dev, role->subj_hash_size);
18602 ++ struct acl_subject_label *match;
18603 ++
18604 ++ match = role->subj_hash[index];
18605 ++
18606 ++ while (match && (match->inode != ino || match->device != dev ||
18607 ++ (match->mode & GR_DELETED))) {
18608 ++ match = match->next;
18609 ++ }
18610 ++
18611 ++ if (match && !(match->mode & GR_DELETED))
18612 ++ return match;
18613 ++ else
18614 ++ return NULL;
18615 ++}
18616 ++
18617 ++static struct acl_object_label *
18618 ++lookup_acl_obj_label(const ino_t ino, const dev_t dev,
18619 ++ const struct acl_subject_label *subj)
18620 ++{
18621 ++ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
18622 ++ struct acl_object_label *match;
18623 ++
18624 ++ match = subj->obj_hash[index];
18625 ++
18626 ++ while (match && (match->inode != ino || match->device != dev ||
18627 ++ (match->mode & GR_DELETED))) {
18628 ++ match = match->next;
18629 ++ }
18630 ++
18631 ++ if (match && !(match->mode & GR_DELETED))
18632 ++ return match;
18633 ++ else
18634 ++ return NULL;
18635 ++}
18636 ++
18637 ++static struct acl_object_label *
18638 ++lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
18639 ++ const struct acl_subject_label *subj)
18640 ++{
18641 ++ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
18642 ++ struct acl_object_label *match;
18643 ++
18644 ++ match = subj->obj_hash[index];
18645 ++
18646 ++ while (match && (match->inode != ino || match->device != dev ||
18647 ++ !(match->mode & GR_DELETED))) {
18648 ++ match = match->next;
18649 ++ }
18650 ++
18651 ++ if (match && (match->mode & GR_DELETED))
18652 ++ return match;
18653 ++
18654 ++ match = subj->obj_hash[index];
18655 ++
18656 ++ while (match && (match->inode != ino || match->device != dev ||
18657 ++ (match->mode & GR_DELETED))) {
18658 ++ match = match->next;
18659 ++ }
18660 ++
18661 ++ if (match && !(match->mode & GR_DELETED))
18662 ++ return match;
18663 ++ else
18664 ++ return NULL;
18665 ++}
18666 ++
18667 ++static struct name_entry *
18668 ++lookup_name_entry(const char *name)
18669 ++{
18670 ++ unsigned int len = strlen(name);
18671 ++ unsigned int key = full_name_hash(name, len);
18672 ++ unsigned int index = key % name_set.n_size;
18673 ++ struct name_entry *match;
18674 ++
18675 ++ match = name_set.n_hash[index];
18676 ++
18677 ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
18678 ++ match = match->next;
18679 ++
18680 ++ return match;
18681 ++}
18682 ++
18683 ++static struct name_entry *
18684 ++lookup_name_entry_create(const char *name)
18685 ++{
18686 ++ unsigned int len = strlen(name);
18687 ++ unsigned int key = full_name_hash(name, len);
18688 ++ unsigned int index = key % name_set.n_size;
18689 ++ struct name_entry *match;
18690 ++
18691 ++ match = name_set.n_hash[index];
18692 ++
18693 ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
18694 ++ !match->deleted))
18695 ++ match = match->next;
18696 ++
18697 ++ if (match && match->deleted)
18698 ++ return match;
18699 ++
18700 ++ match = name_set.n_hash[index];
18701 ++
18702 ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
18703 ++ match->deleted))
18704 ++ match = match->next;
18705 ++
18706 ++ if (match && !match->deleted)
18707 ++ return match;
18708 ++ else
18709 ++ return NULL;
18710 ++}
18711 ++
18712 ++static struct inodev_entry *
18713 ++lookup_inodev_entry(const ino_t ino, const dev_t dev)
18714 ++{
18715 ++ unsigned int index = fhash(ino, dev, inodev_set.i_size);
18716 ++ struct inodev_entry *match;
18717 ++
18718 ++ match = inodev_set.i_hash[index];
18719 ++
18720 ++ while (match && (match->nentry->inode != ino || match->nentry->device != dev))
18721 ++ match = match->next;
18722 ++
18723 ++ return match;
18724 ++}
18725 ++
18726 ++static void
18727 ++insert_inodev_entry(struct inodev_entry *entry)
18728 ++{
18729 ++ unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
18730 ++ inodev_set.i_size);
18731 ++ struct inodev_entry **curr;
18732 ++
18733 ++ entry->prev = NULL;
18734 ++
18735 ++ curr = &inodev_set.i_hash[index];
18736 ++ if (*curr != NULL)
18737 ++ (*curr)->prev = entry;
18738 ++
18739 ++ entry->next = *curr;
18740 ++ *curr = entry;
18741 ++
18742 ++ return;
18743 ++}
18744 ++
18745 ++static void
18746 ++__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
18747 ++{
18748 ++ unsigned int index =
18749 ++ rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
18750 ++ struct acl_role_label **curr;
18751 ++
18752 ++ role->prev = NULL;
18753 ++
18754 ++ curr = &acl_role_set.r_hash[index];
18755 ++ if (*curr != NULL)
18756 ++ (*curr)->prev = role;
18757 ++
18758 ++ role->next = *curr;
18759 ++ *curr = role;
18760 ++
18761 ++ return;
18762 ++}
18763 ++
18764 ++static void
18765 ++insert_acl_role_label(struct acl_role_label *role)
18766 ++{
18767 ++ int i;
18768 ++
18769 ++ if (role->roletype & GR_ROLE_DOMAIN) {
18770 ++ for (i = 0; i < role->domain_child_num; i++)
18771 ++ __insert_acl_role_label(role, role->domain_children[i]);
18772 ++ } else
18773 ++ __insert_acl_role_label(role, role->uidgid);
18774 ++}
18775 ++
18776 ++static int
18777 ++insert_name_entry(char *name, const ino_t inode, const dev_t device, __u8 deleted)
18778 ++{
18779 ++ struct name_entry **curr, *nentry;
18780 ++ struct inodev_entry *ientry;
18781 ++ unsigned int len = strlen(name);
18782 ++ unsigned int key = full_name_hash(name, len);
18783 ++ unsigned int index = key % name_set.n_size;
18784 ++
18785 ++ curr = &name_set.n_hash[index];
18786 ++
18787 ++ while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
18788 ++ curr = &((*curr)->next);
18789 ++
18790 ++ if (*curr != NULL)
18791 ++ return 1;
18792 ++
18793 ++ nentry = acl_alloc(sizeof (struct name_entry));
18794 ++ if (nentry == NULL)
18795 ++ return 0;
18796 ++ ientry = acl_alloc(sizeof (struct inodev_entry));
18797 ++ if (ientry == NULL)
18798 ++ return 0;
18799 ++ ientry->nentry = nentry;
18800 ++
18801 ++ nentry->key = key;
18802 ++ nentry->name = name;
18803 ++ nentry->inode = inode;
18804 ++ nentry->device = device;
18805 ++ nentry->len = len;
18806 ++ nentry->deleted = deleted;
18807 ++
18808 ++ nentry->prev = NULL;
18809 ++ curr = &name_set.n_hash[index];
18810 ++ if (*curr != NULL)
18811 ++ (*curr)->prev = nentry;
18812 ++ nentry->next = *curr;
18813 ++ *curr = nentry;
18814 ++
18815 ++ /* insert us into the table searchable by inode/dev */
18816 ++ insert_inodev_entry(ientry);
18817 ++
18818 ++ return 1;
18819 ++}
18820 ++
18821 ++static void
18822 ++insert_acl_obj_label(struct acl_object_label *obj,
18823 ++ struct acl_subject_label *subj)
18824 ++{
18825 ++ unsigned int index =
18826 ++ fhash(obj->inode, obj->device, subj->obj_hash_size);
18827 ++ struct acl_object_label **curr;
18828 ++
18829 ++
18830 ++ obj->prev = NULL;
18831 ++
18832 ++ curr = &subj->obj_hash[index];
18833 ++ if (*curr != NULL)
18834 ++ (*curr)->prev = obj;
18835 ++
18836 ++ obj->next = *curr;
18837 ++ *curr = obj;
18838 ++
18839 ++ return;
18840 ++}
18841 ++
18842 ++static void
18843 ++insert_acl_subj_label(struct acl_subject_label *obj,
18844 ++ struct acl_role_label *role)
18845 ++{
18846 ++ unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
18847 ++ struct acl_subject_label **curr;
18848 ++
18849 ++ obj->prev = NULL;
18850 ++
18851 ++ curr = &role->subj_hash[index];
18852 ++ if (*curr != NULL)
18853 ++ (*curr)->prev = obj;
18854 ++
18855 ++ obj->next = *curr;
18856 ++ *curr = obj;
18857 ++
18858 ++ return;
18859 ++}
18860 ++
18861 ++/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
18862 ++
18863 ++static void *
18864 ++create_table(__u32 * len, int elementsize)
18865 ++{
18866 ++ unsigned int table_sizes[] = {
18867 ++ 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
18868 ++ 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
18869 ++ 4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
18870 ++ 268435399, 536870909, 1073741789, 2147483647
18871 ++ };
18872 ++ void *newtable = NULL;
18873 ++ unsigned int pwr = 0;
18874 ++
18875 ++ while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
18876 ++ table_sizes[pwr] <= *len)
18877 ++ pwr++;
18878 ++
18879 ++ if (table_sizes[pwr] <= *len)
18880 ++ return newtable;
18881 ++
18882 ++ if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
18883 ++ newtable =
18884 ++ kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
18885 ++ else
18886 ++ newtable = vmalloc(table_sizes[pwr] * elementsize);
18887 ++
18888 ++ *len = table_sizes[pwr];
18889 ++
18890 ++ return newtable;
18891 ++}
18892 ++
18893 ++static int
18894 ++init_variables(const struct gr_arg *arg)
18895 ++{
18896 ++ struct task_struct *reaper = child_reaper(current);
18897 ++ unsigned int stacksize;
18898 ++
18899 ++ subj_map_set.s_size = arg->role_db.num_subjects;
18900 ++ acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
18901 ++ name_set.n_size = arg->role_db.num_objects;
18902 ++ inodev_set.i_size = arg->role_db.num_objects;
18903 ++
18904 ++ if (!subj_map_set.s_size || !acl_role_set.r_size ||
18905 ++ !name_set.n_size || !inodev_set.i_size)
18906 ++ return 1;
18907 ++
18908 ++ if (!gr_init_uidset())
18909 ++ return 1;
18910 ++
18911 ++ /* set up the stack that holds allocation info */
18912 ++
18913 ++ stacksize = arg->role_db.num_pointers + 5;
18914 ++
18915 ++ if (!acl_alloc_stack_init(stacksize))
18916 ++ return 1;
18917 ++
18918 ++ /* grab reference for the real root dentry and vfsmount */
18919 ++ read_lock(&reaper->fs->lock);
18920 ++ real_root_mnt = mntget(reaper->fs->rootmnt);
18921 ++ real_root = dget(reaper->fs->root);
18922 ++ read_unlock(&reaper->fs->lock);
18923 ++
18924 ++ fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
18925 ++ if (fakefs_obj == NULL)
18926 ++ return 1;
18927 ++ fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
18928 ++
18929 ++ subj_map_set.s_hash =
18930 ++ (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
18931 ++ acl_role_set.r_hash =
18932 ++ (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
18933 ++ name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
18934 ++ inodev_set.i_hash =
18935 ++ (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
18936 ++
18937 ++ if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
18938 ++ !name_set.n_hash || !inodev_set.i_hash)
18939 ++ return 1;
18940 ++
18941 ++ memset(subj_map_set.s_hash, 0,
18942 ++ sizeof(struct subject_map *) * subj_map_set.s_size);
18943 ++ memset(acl_role_set.r_hash, 0,
18944 ++ sizeof (struct acl_role_label *) * acl_role_set.r_size);
18945 ++ memset(name_set.n_hash, 0,
18946 ++ sizeof (struct name_entry *) * name_set.n_size);
18947 ++ memset(inodev_set.i_hash, 0,
18948 ++ sizeof (struct inodev_entry *) * inodev_set.i_size);
18949 ++
18950 ++ return 0;
18951 ++}
18952 ++
18953 ++/* free information not needed after startup
18954 ++ currently contains user->kernel pointer mappings for subjects
18955 ++*/
18956 ++
18957 ++static void
18958 ++free_init_variables(void)
18959 ++{
18960 ++ __u32 i;
18961 ++
18962 ++ if (subj_map_set.s_hash) {
18963 ++ for (i = 0; i < subj_map_set.s_size; i++) {
18964 ++ if (subj_map_set.s_hash[i]) {
18965 ++ kfree(subj_map_set.s_hash[i]);
18966 ++ subj_map_set.s_hash[i] = NULL;
18967 ++ }
18968 ++ }
18969 ++
18970 ++ if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
18971 ++ PAGE_SIZE)
18972 ++ kfree(subj_map_set.s_hash);
18973 ++ else
18974 ++ vfree(subj_map_set.s_hash);
18975 ++ }
18976 ++
18977 ++ return;
18978 ++}
18979 ++
18980 ++static void
18981 ++free_variables(void)
18982 ++{
18983 ++ struct acl_subject_label *s;
18984 ++ struct acl_role_label *r;
18985 ++ struct task_struct *task, *task2;
18986 ++ unsigned int i, x;
18987 ++
18988 ++ gr_clear_learn_entries();
18989 ++
18990 ++ read_lock(&tasklist_lock);
18991 ++ do_each_thread(task2, task) {
18992 ++ task->acl_sp_role = 0;
18993 ++ task->acl_role_id = 0;
18994 ++ task->acl = NULL;
18995 ++ task->role = NULL;
18996 ++ } while_each_thread(task2, task);
18997 ++ read_unlock(&tasklist_lock);
18998 ++
18999 ++ /* release the reference to the real root dentry and vfsmount */
19000 ++ if (real_root)
19001 ++ dput(real_root);
19002 ++ real_root = NULL;
19003 ++ if (real_root_mnt)
19004 ++ mntput(real_root_mnt);
19005 ++ real_root_mnt = NULL;
19006 ++
19007 ++ /* free all object hash tables */
19008 ++
19009 ++ FOR_EACH_ROLE_START(r, i)
19010 ++ if (r->subj_hash == NULL)
19011 ++ break;
19012 ++ FOR_EACH_SUBJECT_START(r, s, x)
19013 ++ if (s->obj_hash == NULL)
19014 ++ break;
19015 ++ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
19016 ++ kfree(s->obj_hash);
19017 ++ else
19018 ++ vfree(s->obj_hash);
19019 ++ FOR_EACH_SUBJECT_END(s, x)
19020 ++ FOR_EACH_NESTED_SUBJECT_START(r, s)
19021 ++ if (s->obj_hash == NULL)
19022 ++ break;
19023 ++ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
19024 ++ kfree(s->obj_hash);
19025 ++ else
19026 ++ vfree(s->obj_hash);
19027 ++ FOR_EACH_NESTED_SUBJECT_END(s)
19028 ++ if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
19029 ++ kfree(r->subj_hash);
19030 ++ else
19031 ++ vfree(r->subj_hash);
19032 ++ r->subj_hash = NULL;
19033 ++ FOR_EACH_ROLE_END(r,i)
19034 ++
19035 ++ acl_free_all();
19036 ++
19037 ++ if (acl_role_set.r_hash) {
19038 ++ if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
19039 ++ PAGE_SIZE)
19040 ++ kfree(acl_role_set.r_hash);
19041 ++ else
19042 ++ vfree(acl_role_set.r_hash);
19043 ++ }
19044 ++ if (name_set.n_hash) {
19045 ++ if ((name_set.n_size * sizeof (struct name_entry *)) <=
19046 ++ PAGE_SIZE)
19047 ++ kfree(name_set.n_hash);
19048 ++ else
19049 ++ vfree(name_set.n_hash);
19050 ++ }
19051 ++
19052 ++ if (inodev_set.i_hash) {
19053 ++ if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
19054 ++ PAGE_SIZE)
19055 ++ kfree(inodev_set.i_hash);
19056 ++ else
19057 ++ vfree(inodev_set.i_hash);
19058 ++ }
19059 ++
19060 ++ gr_free_uidset();
19061 ++
19062 ++ memset(&name_set, 0, sizeof (struct name_db));
19063 ++ memset(&inodev_set, 0, sizeof (struct inodev_db));
19064 ++ memset(&acl_role_set, 0, sizeof (struct acl_role_db));
19065 ++ memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
19066 ++
19067 ++ default_role = NULL;
19068 ++
19069 ++ return;
19070 ++}
19071 ++
19072 ++static __u32
19073 ++count_user_objs(struct acl_object_label *userp)
19074 ++{
19075 ++ struct acl_object_label o_tmp;
19076 ++ __u32 num = 0;
19077 ++
19078 ++ while (userp) {
19079 ++ if (copy_from_user(&o_tmp, userp,
19080 ++ sizeof (struct acl_object_label)))
19081 ++ break;
19082 ++
19083 ++ userp = o_tmp.prev;
19084 ++ num++;
19085 ++ }
19086 ++
19087 ++ return num;
19088 ++}
19089 ++
19090 ++static struct acl_subject_label *
19091 ++do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
19092 ++
19093 ++static int
19094 ++copy_user_glob(struct acl_object_label *obj)
19095 ++{
19096 ++ struct acl_object_label *g_tmp, **guser;
19097 ++ unsigned int len;
19098 ++ char *tmp;
19099 ++
19100 ++ if (obj->globbed == NULL)
19101 ++ return 0;
19102 ++
19103 ++ guser = &obj->globbed;
19104 ++ while (*guser) {
19105 ++ g_tmp = (struct acl_object_label *)
19106 ++ acl_alloc(sizeof (struct acl_object_label));
19107 ++ if (g_tmp == NULL)
19108 ++ return -ENOMEM;
19109 ++
19110 ++ if (copy_from_user(g_tmp, *guser,
19111 ++ sizeof (struct acl_object_label)))
19112 ++ return -EFAULT;
19113 ++
19114 ++ len = strnlen_user(g_tmp->filename, PATH_MAX);
19115 ++
19116 ++ if (!len || len >= PATH_MAX)
19117 ++ return -EINVAL;
19118 ++
19119 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
19120 ++ return -ENOMEM;
19121 ++
19122 ++ if (copy_from_user(tmp, g_tmp->filename, len))
19123 ++ return -EFAULT;
19124 ++
19125 ++ g_tmp->filename = tmp;
19126 ++
19127 ++ *guser = g_tmp;
19128 ++ guser = &(g_tmp->next);
19129 ++ }
19130 ++
19131 ++ return 0;
19132 ++}
19133 ++
19134 ++static int
19135 ++copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
19136 ++ struct acl_role_label *role)
19137 ++{
19138 ++ struct acl_object_label *o_tmp;
19139 ++ unsigned int len;
19140 ++ int ret;
19141 ++ char *tmp;
19142 ++
19143 ++ while (userp) {
19144 ++ if ((o_tmp = (struct acl_object_label *)
19145 ++ acl_alloc(sizeof (struct acl_object_label))) == NULL)
19146 ++ return -ENOMEM;
19147 ++
19148 ++ if (copy_from_user(o_tmp, userp,
19149 ++ sizeof (struct acl_object_label)))
19150 ++ return -EFAULT;
19151 ++
19152 ++ userp = o_tmp->prev;
19153 ++
19154 ++ len = strnlen_user(o_tmp->filename, PATH_MAX);
19155 ++
19156 ++ if (!len || len >= PATH_MAX)
19157 ++ return -EINVAL;
19158 ++
19159 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
19160 ++ return -ENOMEM;
19161 ++
19162 ++ if (copy_from_user(tmp, o_tmp->filename, len))
19163 ++ return -EFAULT;
19164 ++
19165 ++ o_tmp->filename = tmp;
19166 ++
19167 ++ insert_acl_obj_label(o_tmp, subj);
19168 ++ if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
19169 ++ o_tmp->device, (o_tmp->mode & GR_DELETED) ? 1 : 0))
19170 ++ return -ENOMEM;
19171 ++
19172 ++ ret = copy_user_glob(o_tmp);
19173 ++ if (ret)
19174 ++ return ret;
19175 ++
19176 ++ if (o_tmp->nested) {
19177 ++ o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
19178 ++ if (IS_ERR(o_tmp->nested))
19179 ++ return PTR_ERR(o_tmp->nested);
19180 ++
19181 ++ /* insert into nested subject list */
19182 ++ o_tmp->nested->next = role->hash->first;
19183 ++ role->hash->first = o_tmp->nested;
19184 ++ }
19185 ++ }
19186 ++
19187 ++ return 0;
19188 ++}
19189 ++
19190 ++static __u32
19191 ++count_user_subjs(struct acl_subject_label *userp)
19192 ++{
19193 ++ struct acl_subject_label s_tmp;
19194 ++ __u32 num = 0;
19195 ++
19196 ++ while (userp) {
19197 ++ if (copy_from_user(&s_tmp, userp,
19198 ++ sizeof (struct acl_subject_label)))
19199 ++ break;
19200 ++
19201 ++ userp = s_tmp.prev;
19202 ++ /* do not count nested subjects against this count, since
19203 ++ they are not included in the hash table, but are
19204 ++ attached to objects. We have already counted
19205 ++ the subjects in userspace for the allocation
19206 ++ stack
19207 ++ */
19208 ++ if (!(s_tmp.mode & GR_NESTED))
19209 ++ num++;
19210 ++ }
19211 ++
19212 ++ return num;
19213 ++}
19214 ++
19215 ++static int
19216 ++copy_user_allowedips(struct acl_role_label *rolep)
19217 ++{
19218 ++ struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
19219 ++
19220 ++ ruserip = rolep->allowed_ips;
19221 ++
19222 ++ while (ruserip) {
19223 ++ rlast = rtmp;
19224 ++
19225 ++ if ((rtmp = (struct role_allowed_ip *)
19226 ++ acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
19227 ++ return -ENOMEM;
19228 ++
19229 ++ if (copy_from_user(rtmp, ruserip,
19230 ++ sizeof (struct role_allowed_ip)))
19231 ++ return -EFAULT;
19232 ++
19233 ++ ruserip = rtmp->prev;
19234 ++
19235 ++ if (!rlast) {
19236 ++ rtmp->prev = NULL;
19237 ++ rolep->allowed_ips = rtmp;
19238 ++ } else {
19239 ++ rlast->next = rtmp;
19240 ++ rtmp->prev = rlast;
19241 ++ }
19242 ++
19243 ++ if (!ruserip)
19244 ++ rtmp->next = NULL;
19245 ++ }
19246 ++
19247 ++ return 0;
19248 ++}
19249 ++
19250 ++static int
19251 ++copy_user_transitions(struct acl_role_label *rolep)
19252 ++{
19253 ++ struct role_transition *rusertp, *rtmp = NULL, *rlast;
19254 ++
19255 ++ unsigned int len;
19256 ++ char *tmp;
19257 ++
19258 ++ rusertp = rolep->transitions;
19259 ++
19260 ++ while (rusertp) {
19261 ++ rlast = rtmp;
19262 ++
19263 ++ if ((rtmp = (struct role_transition *)
19264 ++ acl_alloc(sizeof (struct role_transition))) == NULL)
19265 ++ return -ENOMEM;
19266 ++
19267 ++ if (copy_from_user(rtmp, rusertp,
19268 ++ sizeof (struct role_transition)))
19269 ++ return -EFAULT;
19270 ++
19271 ++ rusertp = rtmp->prev;
19272 ++
19273 ++ len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
19274 ++
19275 ++ if (!len || len >= GR_SPROLE_LEN)
19276 ++ return -EINVAL;
19277 ++
19278 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
19279 ++ return -ENOMEM;
19280 ++
19281 ++ if (copy_from_user(tmp, rtmp->rolename, len))
19282 ++ return -EFAULT;
19283 ++
19284 ++ rtmp->rolename = tmp;
19285 ++
19286 ++ if (!rlast) {
19287 ++ rtmp->prev = NULL;
19288 ++ rolep->transitions = rtmp;
19289 ++ } else {
19290 ++ rlast->next = rtmp;
19291 ++ rtmp->prev = rlast;
19292 ++ }
19293 ++
19294 ++ if (!rusertp)
19295 ++ rtmp->next = NULL;
19296 ++ }
19297 ++
19298 ++ return 0;
19299 ++}
19300 ++
19301 ++static struct acl_subject_label *
19302 ++do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
19303 ++{
19304 ++ struct acl_subject_label *s_tmp = NULL, *s_tmp2;
19305 ++ unsigned int len;
19306 ++ char *tmp;
19307 ++ __u32 num_objs;
19308 ++ struct acl_ip_label **i_tmp, *i_utmp2;
19309 ++ struct gr_hash_struct ghash;
19310 ++ struct subject_map *subjmap;
19311 ++ unsigned int i_num;
19312 ++ int err;
19313 ++
19314 ++ s_tmp = lookup_subject_map(userp);
19315 ++
19316 ++ /* we've already copied this subject into the kernel, just return
19317 ++ the reference to it, and don't copy it over again
19318 ++ */
19319 ++ if (s_tmp)
19320 ++ return(s_tmp);
19321 ++
19322 ++ if ((s_tmp = (struct acl_subject_label *)
19323 ++ acl_alloc(sizeof (struct acl_subject_label))) == NULL)
19324 ++ return ERR_PTR(-ENOMEM);
19325 ++
19326 ++ subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
19327 ++ if (subjmap == NULL)
19328 ++ return ERR_PTR(-ENOMEM);
19329 ++
19330 ++ subjmap->user = userp;
19331 ++ subjmap->kernel = s_tmp;
19332 ++ insert_subj_map_entry(subjmap);
19333 ++
19334 ++ if (copy_from_user(s_tmp, userp,
19335 ++ sizeof (struct acl_subject_label)))
19336 ++ return ERR_PTR(-EFAULT);
19337 ++
19338 ++ len = strnlen_user(s_tmp->filename, PATH_MAX);
19339 ++
19340 ++ if (!len || len >= PATH_MAX)
19341 ++ return ERR_PTR(-EINVAL);
19342 ++
19343 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
19344 ++ return ERR_PTR(-ENOMEM);
19345 ++
19346 ++ if (copy_from_user(tmp, s_tmp->filename, len))
19347 ++ return ERR_PTR(-EFAULT);
19348 ++
19349 ++ s_tmp->filename = tmp;
19350 ++
19351 ++ if (!strcmp(s_tmp->filename, "/"))
19352 ++ role->root_label = s_tmp;
19353 ++
19354 ++ if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
19355 ++ return ERR_PTR(-EFAULT);
19356 ++
19357 ++ /* copy user and group transition tables */
19358 ++
19359 ++ if (s_tmp->user_trans_num) {
19360 ++ uid_t *uidlist;
19361 ++
19362 ++ uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
19363 ++ if (uidlist == NULL)
19364 ++ return ERR_PTR(-ENOMEM);
19365 ++ if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
19366 ++ return ERR_PTR(-EFAULT);
19367 ++
19368 ++ s_tmp->user_transitions = uidlist;
19369 ++ }
19370 ++
19371 ++ if (s_tmp->group_trans_num) {
19372 ++ gid_t *gidlist;
19373 ++
19374 ++ gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
19375 ++ if (gidlist == NULL)
19376 ++ return ERR_PTR(-ENOMEM);
19377 ++ if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
19378 ++ return ERR_PTR(-EFAULT);
19379 ++
19380 ++ s_tmp->group_transitions = gidlist;
19381 ++ }
19382 ++
19383 ++ /* set up object hash table */
19384 ++ num_objs = count_user_objs(ghash.first);
19385 ++
19386 ++ s_tmp->obj_hash_size = num_objs;
19387 ++ s_tmp->obj_hash =
19388 ++ (struct acl_object_label **)
19389 ++ create_table(&(s_tmp->obj_hash_size), sizeof(void *));
19390 ++
19391 ++ if (!s_tmp->obj_hash)
19392 ++ return ERR_PTR(-ENOMEM);
19393 ++
19394 ++ memset(s_tmp->obj_hash, 0,
19395 ++ s_tmp->obj_hash_size *
19396 ++ sizeof (struct acl_object_label *));
19397 ++
19398 ++ /* add in objects */
19399 ++ err = copy_user_objs(ghash.first, s_tmp, role);
19400 ++
19401 ++ if (err)
19402 ++ return ERR_PTR(err);
19403 ++
19404 ++ /* set pointer for parent subject */
19405 ++ if (s_tmp->parent_subject) {
19406 ++ s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
19407 ++
19408 ++ if (IS_ERR(s_tmp2))
19409 ++ return s_tmp2;
19410 ++
19411 ++ s_tmp->parent_subject = s_tmp2;
19412 ++ }
19413 ++
19414 ++ /* add in ip acls */
19415 ++
19416 ++ if (!s_tmp->ip_num) {
19417 ++ s_tmp->ips = NULL;
19418 ++ goto insert;
19419 ++ }
19420 ++
19421 ++ i_tmp =
19422 ++ (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
19423 ++ sizeof (struct
19424 ++ acl_ip_label *));
19425 ++
19426 ++ if (!i_tmp)
19427 ++ return ERR_PTR(-ENOMEM);
19428 ++
19429 ++ for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
19430 ++ *(i_tmp + i_num) =
19431 ++ (struct acl_ip_label *)
19432 ++ acl_alloc(sizeof (struct acl_ip_label));
19433 ++ if (!*(i_tmp + i_num))
19434 ++ return ERR_PTR(-ENOMEM);
19435 ++
19436 ++ if (copy_from_user
19437 ++ (&i_utmp2, s_tmp->ips + i_num,
19438 ++ sizeof (struct acl_ip_label *)))
19439 ++ return ERR_PTR(-EFAULT);
19440 ++
19441 ++ if (copy_from_user
19442 ++ (*(i_tmp + i_num), i_utmp2,
19443 ++ sizeof (struct acl_ip_label)))
19444 ++ return ERR_PTR(-EFAULT);
19445 ++
19446 ++ if ((*(i_tmp + i_num))->iface == NULL)
19447 ++ continue;
19448 ++
19449 ++ len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
19450 ++ if (!len || len >= IFNAMSIZ)
19451 ++ return ERR_PTR(-EINVAL);
19452 ++ tmp = acl_alloc(len);
19453 ++ if (tmp == NULL)
19454 ++ return ERR_PTR(-ENOMEM);
19455 ++ if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
19456 ++ return ERR_PTR(-EFAULT);
19457 ++ (*(i_tmp + i_num))->iface = tmp;
19458 ++ }
19459 ++
19460 ++ s_tmp->ips = i_tmp;
19461 ++
19462 ++insert:
19463 ++ if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
19464 ++ s_tmp->device, (s_tmp->mode & GR_DELETED) ? 1 : 0))
19465 ++ return ERR_PTR(-ENOMEM);
19466 ++
19467 ++ return s_tmp;
19468 ++}
19469 ++
19470 ++static int
19471 ++copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
19472 ++{
19473 ++ struct acl_subject_label s_pre;
19474 ++ struct acl_subject_label * ret;
19475 ++ int err;
19476 ++
19477 ++ while (userp) {
19478 ++ if (copy_from_user(&s_pre, userp,
19479 ++ sizeof (struct acl_subject_label)))
19480 ++ return -EFAULT;
19481 ++
19482 ++ /* do not add nested subjects here, add
19483 ++ while parsing objects
19484 ++ */
19485 ++
19486 ++ if (s_pre.mode & GR_NESTED) {
19487 ++ userp = s_pre.prev;
19488 ++ continue;
19489 ++ }
19490 ++
19491 ++ ret = do_copy_user_subj(userp, role);
19492 ++
19493 ++ err = PTR_ERR(ret);
19494 ++ if (IS_ERR(ret))
19495 ++ return err;
19496 ++
19497 ++ insert_acl_subj_label(ret, role);
19498 ++
19499 ++ userp = s_pre.prev;
19500 ++ }
19501 ++
19502 ++ return 0;
19503 ++}
19504 ++
19505 ++static int
19506 ++copy_user_acl(struct gr_arg *arg)
19507 ++{
19508 ++ struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
19509 ++ struct sprole_pw *sptmp;
19510 ++ struct gr_hash_struct *ghash;
19511 ++ uid_t *domainlist;
19512 ++ unsigned int r_num;
19513 ++ unsigned int len;
19514 ++ char *tmp;
19515 ++ int err = 0;
19516 ++ __u16 i;
19517 ++ __u32 num_subjs;
19518 ++
19519 ++ /* we need a default and kernel role */
19520 ++ if (arg->role_db.num_roles < 2)
19521 ++ return -EINVAL;
19522 ++
19523 ++ /* copy special role authentication info from userspace */
19524 ++
19525 ++ num_sprole_pws = arg->num_sprole_pws;
19526 ++ acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
19527 ++
19528 ++ if (!acl_special_roles) {
19529 ++ err = -ENOMEM;
19530 ++ goto cleanup;
19531 ++ }
19532 ++
19533 ++ for (i = 0; i < num_sprole_pws; i++) {
19534 ++ sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
19535 ++ if (!sptmp) {
19536 ++ err = -ENOMEM;
19537 ++ goto cleanup;
19538 ++ }
19539 ++ if (copy_from_user(sptmp, arg->sprole_pws + i,
19540 ++ sizeof (struct sprole_pw))) {
19541 ++ err = -EFAULT;
19542 ++ goto cleanup;
19543 ++ }
19544 ++
19545 ++ len =
19546 ++ strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
19547 ++
19548 ++ if (!len || len >= GR_SPROLE_LEN) {
19549 ++ err = -EINVAL;
19550 ++ goto cleanup;
19551 ++ }
19552 ++
19553 ++ if ((tmp = (char *) acl_alloc(len)) == NULL) {
19554 ++ err = -ENOMEM;
19555 ++ goto cleanup;
19556 ++ }
19557 ++
19558 ++ if (copy_from_user(tmp, sptmp->rolename, len)) {
19559 ++ err = -EFAULT;
19560 ++ goto cleanup;
19561 ++ }
19562 ++
19563 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
19564 ++ printk(KERN_ALERT "Copying special role %s\n", tmp);
19565 ++#endif
19566 ++ sptmp->rolename = tmp;
19567 ++ acl_special_roles[i] = sptmp;
19568 ++ }
19569 ++
19570 ++ r_utmp = (struct acl_role_label **) arg->role_db.r_table;
19571 ++
19572 ++ for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
19573 ++ r_tmp = acl_alloc(sizeof (struct acl_role_label));
19574 ++
19575 ++ if (!r_tmp) {
19576 ++ err = -ENOMEM;
19577 ++ goto cleanup;
19578 ++ }
19579 ++
19580 ++ if (copy_from_user(&r_utmp2, r_utmp + r_num,
19581 ++ sizeof (struct acl_role_label *))) {
19582 ++ err = -EFAULT;
19583 ++ goto cleanup;
19584 ++ }
19585 ++
19586 ++ if (copy_from_user(r_tmp, r_utmp2,
19587 ++ sizeof (struct acl_role_label))) {
19588 ++ err = -EFAULT;
19589 ++ goto cleanup;
19590 ++ }
19591 ++
19592 ++ len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
19593 ++
19594 ++ if (!len || len >= PATH_MAX) {
19595 ++ err = -EINVAL;
19596 ++ goto cleanup;
19597 ++ }
19598 ++
19599 ++ if ((tmp = (char *) acl_alloc(len)) == NULL) {
19600 ++ err = -ENOMEM;
19601 ++ goto cleanup;
19602 ++ }
19603 ++ if (copy_from_user(tmp, r_tmp->rolename, len)) {
19604 ++ err = -EFAULT;
19605 ++ goto cleanup;
19606 ++ }
19607 ++ r_tmp->rolename = tmp;
19608 ++
19609 ++ if (!strcmp(r_tmp->rolename, "default")
19610 ++ && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
19611 ++ default_role = r_tmp;
19612 ++ } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
19613 ++ kernel_role = r_tmp;
19614 ++ }
19615 ++
19616 ++ if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
19617 ++ err = -ENOMEM;
19618 ++ goto cleanup;
19619 ++ }
19620 ++ if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
19621 ++ err = -EFAULT;
19622 ++ goto cleanup;
19623 ++ }
19624 ++
19625 ++ r_tmp->hash = ghash;
19626 ++
19627 ++ num_subjs = count_user_subjs(r_tmp->hash->first);
19628 ++
19629 ++ r_tmp->subj_hash_size = num_subjs;
19630 ++ r_tmp->subj_hash =
19631 ++ (struct acl_subject_label **)
19632 ++ create_table(&(r_tmp->subj_hash_size), sizeof(void *));
19633 ++
19634 ++ if (!r_tmp->subj_hash) {
19635 ++ err = -ENOMEM;
19636 ++ goto cleanup;
19637 ++ }
19638 ++
19639 ++ err = copy_user_allowedips(r_tmp);
19640 ++ if (err)
19641 ++ goto cleanup;
19642 ++
19643 ++ /* copy domain info */
19644 ++ if (r_tmp->domain_children != NULL) {
19645 ++ domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
19646 ++ if (domainlist == NULL) {
19647 ++ err = -ENOMEM;
19648 ++ goto cleanup;
19649 ++ }
19650 ++ if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
19651 ++ err = -EFAULT;
19652 ++ goto cleanup;
19653 ++ }
19654 ++ r_tmp->domain_children = domainlist;
19655 ++ }
19656 ++
19657 ++ err = copy_user_transitions(r_tmp);
19658 ++ if (err)
19659 ++ goto cleanup;
19660 ++
19661 ++ memset(r_tmp->subj_hash, 0,
19662 ++ r_tmp->subj_hash_size *
19663 ++ sizeof (struct acl_subject_label *));
19664 ++
19665 ++ err = copy_user_subjs(r_tmp->hash->first, r_tmp);
19666 ++
19667 ++ if (err)
19668 ++ goto cleanup;
19669 ++
19670 ++ /* set nested subject list to null */
19671 ++ r_tmp->hash->first = NULL;
19672 ++
19673 ++ insert_acl_role_label(r_tmp);
19674 ++ }
19675 ++
19676 ++ goto return_err;
19677 ++ cleanup:
19678 ++ free_variables();
19679 ++ return_err:
19680 ++ return err;
19681 ++
19682 ++}
19683 ++
19684 ++static int
19685 ++gracl_init(struct gr_arg *args)
19686 ++{
19687 ++ int error = 0;
19688 ++
19689 ++ memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
19690 ++ memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
19691 ++
19692 ++ if (init_variables(args)) {
19693 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
19694 ++ error = -ENOMEM;
19695 ++ free_variables();
19696 ++ goto out;
19697 ++ }
19698 ++
19699 ++ error = copy_user_acl(args);
19700 ++ free_init_variables();
19701 ++ if (error) {
19702 ++ free_variables();
19703 ++ goto out;
19704 ++ }
19705 ++
19706 ++ if ((error = gr_set_acls(0))) {
19707 ++ free_variables();
19708 ++ goto out;
19709 ++ }
19710 ++
19711 ++ gr_status |= GR_READY;
19712 ++ out:
19713 ++ return error;
19714 ++}
19715 ++
19716 ++/* derived from glibc fnmatch() 0: match, 1: no match*/
19717 ++
19718 ++static int
19719 ++glob_match(const char *p, const char *n)
19720 ++{
19721 ++ char c;
19722 ++
19723 ++ while ((c = *p++) != '\0') {
19724 ++ switch (c) {
19725 ++ case '?':
19726 ++ if (*n == '\0')
19727 ++ return 1;
19728 ++ else if (*n == '/')
19729 ++ return 1;
19730 ++ break;
19731 ++ case '\\':
19732 ++ if (*n != c)
19733 ++ return 1;
19734 ++ break;
19735 ++ case '*':
19736 ++ for (c = *p++; c == '?' || c == '*'; c = *p++) {
19737 ++ if (*n == '/')
19738 ++ return 1;
19739 ++ else if (c == '?') {
19740 ++ if (*n == '\0')
19741 ++ return 1;
19742 ++ else
19743 ++ ++n;
19744 ++ }
19745 ++ }
19746 ++ if (c == '\0') {
19747 ++ return 0;
19748 ++ } else {
19749 ++ const char *endp;
19750 ++
19751 ++ if ((endp = strchr(n, '/')) == NULL)
19752 ++ endp = n + strlen(n);
19753 ++
19754 ++ if (c == '[') {
19755 ++ for (--p; n < endp; ++n)
19756 ++ if (!glob_match(p, n))
19757 ++ return 0;
19758 ++ } else if (c == '/') {
19759 ++ while (*n != '\0' && *n != '/')
19760 ++ ++n;
19761 ++ if (*n == '/' && !glob_match(p, n + 1))
19762 ++ return 0;
19763 ++ } else {
19764 ++ for (--p; n < endp; ++n)
19765 ++ if (*n == c && !glob_match(p, n))
19766 ++ return 0;
19767 ++ }
19768 ++
19769 ++ return 1;
19770 ++ }
19771 ++ case '[':
19772 ++ {
19773 ++ int not;
19774 ++ char cold;
19775 ++
19776 ++ if (*n == '\0' || *n == '/')
19777 ++ return 1;
19778 ++
19779 ++ not = (*p == '!' || *p == '^');
19780 ++ if (not)
19781 ++ ++p;
19782 ++
19783 ++ c = *p++;
19784 ++ for (;;) {
19785 ++ unsigned char fn = (unsigned char)*n;
19786 ++
19787 ++ if (c == '\0')
19788 ++ return 1;
19789 ++ else {
19790 ++ if (c == fn)
19791 ++ goto matched;
19792 ++ cold = c;
19793 ++ c = *p++;
19794 ++
19795 ++ if (c == '-' && *p != ']') {
19796 ++ unsigned char cend = *p++;
19797 ++
19798 ++ if (cend == '\0')
19799 ++ return 1;
19800 ++
19801 ++ if (cold <= fn && fn <= cend)
19802 ++ goto matched;
19803 ++
19804 ++ c = *p++;
19805 ++ }
19806 ++ }
19807 ++
19808 ++ if (c == ']')
19809 ++ break;
19810 ++ }
19811 ++ if (!not)
19812 ++ return 1;
19813 ++ break;
19814 ++ matched:
19815 ++ while (c != ']') {
19816 ++ if (c == '\0')
19817 ++ return 1;
19818 ++
19819 ++ c = *p++;
19820 ++ }
19821 ++ if (not)
19822 ++ return 1;
19823 ++ }
19824 ++ break;
19825 ++ default:
19826 ++ if (c != *n)
19827 ++ return 1;
19828 ++ }
19829 ++
19830 ++ ++n;
19831 ++ }
19832 ++
19833 ++ if (*n == '\0')
19834 ++ return 0;
19835 ++
19836 ++ if (*n == '/')
19837 ++ return 0;
19838 ++
19839 ++ return 1;
19840 ++}
19841 ++
19842 ++static struct acl_object_label *
19843 ++chk_glob_label(struct acl_object_label *globbed,
19844 ++ struct dentry *dentry, struct vfsmount *mnt, char **path)
19845 ++{
19846 ++ struct acl_object_label *tmp;
19847 ++
19848 ++ if (*path == NULL)
19849 ++ *path = gr_to_filename_nolock(dentry, mnt);
19850 ++
19851 ++ tmp = globbed;
19852 ++
19853 ++ while (tmp) {
19854 ++ if (!glob_match(tmp->filename, *path))
19855 ++ return tmp;
19856 ++ tmp = tmp->next;
19857 ++ }
19858 ++
19859 ++ return NULL;
19860 ++}
19861 ++
19862 ++static struct acl_object_label *
19863 ++__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
19864 ++ const ino_t curr_ino, const dev_t curr_dev,
19865 ++ const struct acl_subject_label *subj, char **path)
19866 ++{
19867 ++ struct acl_subject_label *tmpsubj;
19868 ++ struct acl_object_label *retval;
19869 ++ struct acl_object_label *retval2;
19870 ++
19871 ++ tmpsubj = (struct acl_subject_label *) subj;
19872 ++ read_lock(&gr_inode_lock);
19873 ++ do {
19874 ++ retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
19875 ++ if (retval) {
19876 ++ if (retval->globbed) {
19877 ++ retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
19878 ++ (struct vfsmount *)orig_mnt, path);
19879 ++ if (retval2)
19880 ++ retval = retval2;
19881 ++ }
19882 ++ break;
19883 ++ }
19884 ++ } while ((tmpsubj = tmpsubj->parent_subject));
19885 ++ read_unlock(&gr_inode_lock);
19886 ++
19887 ++ return retval;
19888 ++}
19889 ++
19890 ++static __inline__ struct acl_object_label *
19891 ++full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
19892 ++ const struct dentry *curr_dentry,
19893 ++ const struct acl_subject_label *subj, char **path)
19894 ++{
19895 ++ return __full_lookup(orig_dentry, orig_mnt,
19896 ++ curr_dentry->d_inode->i_ino,
19897 ++ curr_dentry->d_inode->i_sb->s_dev, subj, path);
19898 ++}
19899 ++
19900 ++static struct acl_object_label *
19901 ++__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
19902 ++ const struct acl_subject_label *subj, char *path)
19903 ++{
19904 ++ struct dentry *dentry = (struct dentry *) l_dentry;
19905 ++ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
19906 ++ struct acl_object_label *retval;
19907 ++
19908 ++ spin_lock(&dcache_lock);
19909 ++
19910 ++ if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt ||
19911 ++ /* ignore Eric Biederman */
19912 ++ IS_PRIVATE(l_dentry->d_inode))) {
19913 ++ retval = fakefs_obj;
19914 ++ goto out;
19915 ++ }
19916 ++
19917 ++ for (;;) {
19918 ++ if (dentry == real_root && mnt == real_root_mnt)
19919 ++ break;
19920 ++
19921 ++ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
19922 ++ if (mnt->mnt_parent == mnt)
19923 ++ break;
19924 ++
19925 ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
19926 ++ if (retval != NULL)
19927 ++ goto out;
19928 ++
19929 ++ dentry = mnt->mnt_mountpoint;
19930 ++ mnt = mnt->mnt_parent;
19931 ++ continue;
19932 ++ }
19933 ++
19934 ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
19935 ++ if (retval != NULL)
19936 ++ goto out;
19937 ++
19938 ++ dentry = dentry->d_parent;
19939 ++ }
19940 ++
19941 ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
19942 ++
19943 ++ if (retval == NULL)
19944 ++ retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
19945 ++out:
19946 ++ spin_unlock(&dcache_lock);
19947 ++ return retval;
19948 ++}
19949 ++
19950 ++static __inline__ struct acl_object_label *
19951 ++chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
19952 ++ const struct acl_subject_label *subj)
19953 ++{
19954 ++ char *path = NULL;
19955 ++ return __chk_obj_label(l_dentry, l_mnt, subj, path);
19956 ++}
19957 ++
19958 ++static __inline__ struct acl_object_label *
19959 ++chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
19960 ++ const struct acl_subject_label *subj, char *path)
19961 ++{
19962 ++ return __chk_obj_label(l_dentry, l_mnt, subj, path);
19963 ++}
19964 ++
19965 ++static struct acl_subject_label *
19966 ++chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
19967 ++ const struct acl_role_label *role)
19968 ++{
19969 ++ struct dentry *dentry = (struct dentry *) l_dentry;
19970 ++ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
19971 ++ struct acl_subject_label *retval;
19972 ++
19973 ++ spin_lock(&dcache_lock);
19974 ++
19975 ++ for (;;) {
19976 ++ if (dentry == real_root && mnt == real_root_mnt)
19977 ++ break;
19978 ++ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
19979 ++ if (mnt->mnt_parent == mnt)
19980 ++ break;
19981 ++
19982 ++ read_lock(&gr_inode_lock);
19983 ++ retval =
19984 ++ lookup_acl_subj_label(dentry->d_inode->i_ino,
19985 ++ dentry->d_inode->i_sb->s_dev, role);
19986 ++ read_unlock(&gr_inode_lock);
19987 ++ if (retval != NULL)
19988 ++ goto out;
19989 ++
19990 ++ dentry = mnt->mnt_mountpoint;
19991 ++ mnt = mnt->mnt_parent;
19992 ++ continue;
19993 ++ }
19994 ++
19995 ++ read_lock(&gr_inode_lock);
19996 ++ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
19997 ++ dentry->d_inode->i_sb->s_dev, role);
19998 ++ read_unlock(&gr_inode_lock);
19999 ++ if (retval != NULL)
20000 ++ goto out;
20001 ++
20002 ++ dentry = dentry->d_parent;
20003 ++ }
20004 ++
20005 ++ read_lock(&gr_inode_lock);
20006 ++ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
20007 ++ dentry->d_inode->i_sb->s_dev, role);
20008 ++ read_unlock(&gr_inode_lock);
20009 ++
20010 ++ if (unlikely(retval == NULL)) {
20011 ++ read_lock(&gr_inode_lock);
20012 ++ retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
20013 ++ real_root->d_inode->i_sb->s_dev, role);
20014 ++ read_unlock(&gr_inode_lock);
20015 ++ }
20016 ++out:
20017 ++ spin_unlock(&dcache_lock);
20018 ++
20019 ++ return retval;
20020 ++}
20021 ++
20022 ++static void
20023 ++gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
20024 ++{
20025 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
20026 ++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
20027 ++ task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
20028 ++ 1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
20029 ++
20030 ++ return;
20031 ++}
20032 ++
20033 ++static void
20034 ++gr_log_learn_sysctl(const struct task_struct *task, const char *path, const __u32 mode)
20035 ++{
20036 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
20037 ++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
20038 ++ task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
20039 ++ 1, 1, path, (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
20040 ++
20041 ++ return;
20042 ++}
20043 ++
20044 ++static void
20045 ++gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real,
20046 ++ const unsigned int effective, const unsigned int fs)
20047 ++{
20048 ++ security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
20049 ++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
20050 ++ task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
20051 ++ type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
20052 ++
20053 ++ return;
20054 ++}
20055 ++
20056 ++__u32
20057 ++gr_check_link(const struct dentry * new_dentry,
20058 ++ const struct dentry * parent_dentry,
20059 ++ const struct vfsmount * parent_mnt,
20060 ++ const struct dentry * old_dentry, const struct vfsmount * old_mnt)
20061 ++{
20062 ++ struct acl_object_label *obj;
20063 ++ __u32 oldmode, newmode;
20064 ++ __u32 needmode;
20065 ++
20066 ++ if (unlikely(!(gr_status & GR_READY)))
20067 ++ return (GR_CREATE | GR_LINK);
20068 ++
20069 ++ obj = chk_obj_label(old_dentry, old_mnt, current->acl);
20070 ++ oldmode = obj->mode;
20071 ++
20072 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
20073 ++ oldmode |= (GR_CREATE | GR_LINK);
20074 ++
20075 ++ needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
20076 ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
20077 ++ needmode |= GR_SETID | GR_AUDIT_SETID;
20078 ++
20079 ++ newmode =
20080 ++ gr_check_create(new_dentry, parent_dentry, parent_mnt,
20081 ++ oldmode | needmode);
20082 ++
20083 ++ needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
20084 ++ GR_SETID | GR_READ | GR_FIND | GR_DELETE |
20085 ++ GR_INHERIT | GR_AUDIT_INHERIT);
20086 ++
20087 ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
20088 ++ goto bad;
20089 ++
20090 ++ if ((oldmode & needmode) != needmode)
20091 ++ goto bad;
20092 ++
20093 ++ needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
20094 ++ if ((newmode & needmode) != needmode)
20095 ++ goto bad;
20096 ++
20097 ++ if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
20098 ++ return newmode;
20099 ++bad:
20100 ++ needmode = oldmode;
20101 ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
20102 ++ needmode |= GR_SETID;
20103 ++
20104 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
20105 ++ gr_log_learn(current, old_dentry, old_mnt, needmode);
20106 ++ return (GR_CREATE | GR_LINK);
20107 ++ } else if (newmode & GR_SUPPRESS)
20108 ++ return GR_SUPPRESS;
20109 ++ else
20110 ++ return 0;
20111 ++}
20112 ++
20113 ++__u32
20114 ++gr_search_file(const struct dentry * dentry, const __u32 mode,
20115 ++ const struct vfsmount * mnt)
20116 ++{
20117 ++ __u32 retval = mode;
20118 ++ struct acl_subject_label *curracl;
20119 ++ struct acl_object_label *currobj;
20120 ++
20121 ++ if (unlikely(!(gr_status & GR_READY)))
20122 ++ return (mode & ~GR_AUDITS);
20123 ++
20124 ++ curracl = current->acl;
20125 ++
20126 ++ currobj = chk_obj_label(dentry, mnt, curracl);
20127 ++ retval = currobj->mode & mode;
20128 ++
20129 ++ if (unlikely
20130 ++ ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
20131 ++ && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
20132 ++ __u32 new_mode = mode;
20133 ++
20134 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
20135 ++
20136 ++ retval = new_mode;
20137 ++
20138 ++ if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
20139 ++ new_mode |= GR_INHERIT;
20140 ++
20141 ++ if (!(mode & GR_NOLEARN))
20142 ++ gr_log_learn(current, dentry, mnt, new_mode);
20143 ++ }
20144 ++
20145 ++ return retval;
20146 ++}
20147 ++
20148 ++__u32
20149 ++gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
20150 ++ const struct vfsmount * mnt, const __u32 mode)
20151 ++{
20152 ++ struct name_entry *match;
20153 ++ struct acl_object_label *matchpo;
20154 ++ struct acl_subject_label *curracl;
20155 ++ char *path;
20156 ++ __u32 retval;
20157 ++
20158 ++ if (unlikely(!(gr_status & GR_READY)))
20159 ++ return (mode & ~GR_AUDITS);
20160 ++
20161 ++ preempt_disable();
20162 ++ path = gr_to_filename_rbac(new_dentry, mnt);
20163 ++ match = lookup_name_entry_create(path);
20164 ++
20165 ++ if (!match)
20166 ++ goto check_parent;
20167 ++
20168 ++ curracl = current->acl;
20169 ++
20170 ++ read_lock(&gr_inode_lock);
20171 ++ matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
20172 ++ read_unlock(&gr_inode_lock);
20173 ++
20174 ++ if (matchpo) {
20175 ++ if ((matchpo->mode & mode) !=
20176 ++ (mode & ~(GR_AUDITS | GR_SUPPRESS))
20177 ++ && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
20178 ++ __u32 new_mode = mode;
20179 ++
20180 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
20181 ++
20182 ++ gr_log_learn(current, new_dentry, mnt, new_mode);
20183 ++
20184 ++ preempt_enable();
20185 ++ return new_mode;
20186 ++ }
20187 ++ preempt_enable();
20188 ++ return (matchpo->mode & mode);
20189 ++ }
20190 ++
20191 ++ check_parent:
20192 ++ curracl = current->acl;
20193 ++
20194 ++ matchpo = chk_obj_create_label(parent, mnt, curracl, path);
20195 ++ retval = matchpo->mode & mode;
20196 ++
20197 ++ if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
20198 ++ && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
20199 ++ __u32 new_mode = mode;
20200 ++
20201 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
20202 ++
20203 ++ gr_log_learn(current, new_dentry, mnt, new_mode);
20204 ++ preempt_enable();
20205 ++ return new_mode;
20206 ++ }
20207 ++
20208 ++ preempt_enable();
20209 ++ return retval;
20210 ++}
20211 ++
20212 ++int
20213 ++gr_check_hidden_task(const struct task_struct *task)
20214 ++{
20215 ++ if (unlikely(!(gr_status & GR_READY)))
20216 ++ return 0;
20217 ++
20218 ++ if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
20219 ++ return 1;
20220 ++
20221 ++ return 0;
20222 ++}
20223 ++
20224 ++int
20225 ++gr_check_protected_task(const struct task_struct *task)
20226 ++{
20227 ++ if (unlikely(!(gr_status & GR_READY) || !task))
20228 ++ return 0;
20229 ++
20230 ++ if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
20231 ++ task->acl != current->acl)
20232 ++ return 1;
20233 ++
20234 ++ return 0;
20235 ++}
20236 ++
20237 ++void
20238 ++gr_copy_label(struct task_struct *tsk)
20239 ++{
20240 ++ tsk->signal->used_accept = 0;
20241 ++ tsk->acl_sp_role = 0;
20242 ++ tsk->acl_role_id = current->acl_role_id;
20243 ++ tsk->acl = current->acl;
20244 ++ tsk->role = current->role;
20245 ++ tsk->signal->curr_ip = current->signal->curr_ip;
20246 ++ if (current->exec_file)
20247 ++ get_file(current->exec_file);
20248 ++ tsk->exec_file = current->exec_file;
20249 ++ tsk->is_writable = current->is_writable;
20250 ++ if (unlikely(current->signal->used_accept))
20251 ++ current->signal->curr_ip = 0;
20252 ++
20253 ++ return;
20254 ++}
20255 ++
20256 ++static void
20257 ++gr_set_proc_res(struct task_struct *task)
20258 ++{
20259 ++ struct acl_subject_label *proc;
20260 ++ unsigned short i;
20261 ++
20262 ++ proc = task->acl;
20263 ++
20264 ++ if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
20265 ++ return;
20266 ++
20267 ++ for (i = 0; i < (GR_NLIMITS - 1); i++) {
20268 ++ if (!(proc->resmask & (1 << i)))
20269 ++ continue;
20270 ++
20271 ++ task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
20272 ++ task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
20273 ++ }
20274 ++
20275 ++ return;
20276 ++}
20277 ++
20278 ++int
20279 ++gr_check_user_change(int real, int effective, int fs)
20280 ++{
20281 ++ unsigned int i;
20282 ++ __u16 num;
20283 ++ uid_t *uidlist;
20284 ++ int curuid;
20285 ++ int realok = 0;
20286 ++ int effectiveok = 0;
20287 ++ int fsok = 0;
20288 ++
20289 ++ if (unlikely(!(gr_status & GR_READY)))
20290 ++ return 0;
20291 ++
20292 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
20293 ++ gr_log_learn_id_change(current, 'u', real, effective, fs);
20294 ++
20295 ++ num = current->acl->user_trans_num;
20296 ++ uidlist = current->acl->user_transitions;
20297 ++
20298 ++ if (uidlist == NULL)
20299 ++ return 0;
20300 ++
20301 ++ if (real == -1)
20302 ++ realok = 1;
20303 ++ if (effective == -1)
20304 ++ effectiveok = 1;
20305 ++ if (fs == -1)
20306 ++ fsok = 1;
20307 ++
20308 ++ if (current->acl->user_trans_type & GR_ID_ALLOW) {
20309 ++ for (i = 0; i < num; i++) {
20310 ++ curuid = (int)uidlist[i];
20311 ++ if (real == curuid)
20312 ++ realok = 1;
20313 ++ if (effective == curuid)
20314 ++ effectiveok = 1;
20315 ++ if (fs == curuid)
20316 ++ fsok = 1;
20317 ++ }
20318 ++ } else if (current->acl->user_trans_type & GR_ID_DENY) {
20319 ++ for (i = 0; i < num; i++) {
20320 ++ curuid = (int)uidlist[i];
20321 ++ if (real == curuid)
20322 ++ break;
20323 ++ if (effective == curuid)
20324 ++ break;
20325 ++ if (fs == curuid)
20326 ++ break;
20327 ++ }
20328 ++ /* not in deny list */
20329 ++ if (i == num) {
20330 ++ realok = 1;
20331 ++ effectiveok = 1;
20332 ++ fsok = 1;
20333 ++ }
20334 ++ }
20335 ++
20336 ++ if (realok && effectiveok && fsok)
20337 ++ return 0;
20338 ++ else {
20339 ++ gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
20340 ++ return 1;
20341 ++ }
20342 ++}
20343 ++
20344 ++int
20345 ++gr_check_group_change(int real, int effective, int fs)
20346 ++{
20347 ++ unsigned int i;
20348 ++ __u16 num;
20349 ++ gid_t *gidlist;
20350 ++ int curgid;
20351 ++ int realok = 0;
20352 ++ int effectiveok = 0;
20353 ++ int fsok = 0;
20354 ++
20355 ++ if (unlikely(!(gr_status & GR_READY)))
20356 ++ return 0;
20357 ++
20358 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
20359 ++ gr_log_learn_id_change(current, 'g', real, effective, fs);
20360 ++
20361 ++ num = current->acl->group_trans_num;
20362 ++ gidlist = current->acl->group_transitions;
20363 ++
20364 ++ if (gidlist == NULL)
20365 ++ return 0;
20366 ++
20367 ++ if (real == -1)
20368 ++ realok = 1;
20369 ++ if (effective == -1)
20370 ++ effectiveok = 1;
20371 ++ if (fs == -1)
20372 ++ fsok = 1;
20373 ++
20374 ++ if (current->acl->group_trans_type & GR_ID_ALLOW) {
20375 ++ for (i = 0; i < num; i++) {
20376 ++ curgid = (int)gidlist[i];
20377 ++ if (real == curgid)
20378 ++ realok = 1;
20379 ++ if (effective == curgid)
20380 ++ effectiveok = 1;
20381 ++ if (fs == curgid)
20382 ++ fsok = 1;
20383 ++ }
20384 ++ } else if (current->acl->group_trans_type & GR_ID_DENY) {
20385 ++ for (i = 0; i < num; i++) {
20386 ++ curgid = (int)gidlist[i];
20387 ++ if (real == curgid)
20388 ++ break;
20389 ++ if (effective == curgid)
20390 ++ break;
20391 ++ if (fs == curgid)
20392 ++ break;
20393 ++ }
20394 ++ /* not in deny list */
20395 ++ if (i == num) {
20396 ++ realok = 1;
20397 ++ effectiveok = 1;
20398 ++ fsok = 1;
20399 ++ }
20400 ++ }
20401 ++
20402 ++ if (realok && effectiveok && fsok)
20403 ++ return 0;
20404 ++ else {
20405 ++ gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
20406 ++ return 1;
20407 ++ }
20408 ++}
20409 ++
20410 ++void
20411 ++gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
20412 ++{
20413 ++ struct acl_role_label *role = task->role;
20414 ++ struct acl_subject_label *subj = NULL;
20415 ++ struct acl_object_label *obj;
20416 ++ struct file *filp;
20417 ++
20418 ++ if (unlikely(!(gr_status & GR_READY)))
20419 ++ return;
20420 ++
20421 ++ filp = task->exec_file;
20422 ++
20423 ++ /* kernel process, we'll give them the kernel role */
20424 ++ if (unlikely(!filp)) {
20425 ++ task->role = kernel_role;
20426 ++ task->acl = kernel_role->root_label;
20427 ++ return;
20428 ++ } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
20429 ++ role = lookup_acl_role_label(task, uid, gid);
20430 ++
20431 ++ /* perform subject lookup in possibly new role
20432 ++ we can use this result below in the case where role == task->role
20433 ++ */
20434 ++ subj = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, role);
20435 ++
20436 ++ /* if we changed uid/gid, but result in the same role
20437 ++ and are using inheritance, don't lose the inherited subject
20438 ++ if current subject is other than what normal lookup
20439 ++ would result in, we arrived via inheritance, don't
20440 ++ lose subject
20441 ++ */
20442 ++ if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
20443 ++ (subj == task->acl)))
20444 ++ task->acl = subj;
20445 ++
20446 ++ task->role = role;
20447 ++
20448 ++ task->is_writable = 0;
20449 ++
20450 ++ /* ignore additional mmap checks for processes that are writable
20451 ++ by the default ACL */
20452 ++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
20453 ++ if (unlikely(obj->mode & GR_WRITE))
20454 ++ task->is_writable = 1;
20455 ++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
20456 ++ if (unlikely(obj->mode & GR_WRITE))
20457 ++ task->is_writable = 1;
20458 ++
20459 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
20460 ++ printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
20461 ++#endif
20462 ++
20463 ++ gr_set_proc_res(task);
20464 ++
20465 ++ return;
20466 ++}
20467 ++
20468 ++int
20469 ++gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
20470 ++{
20471 ++ struct task_struct *task = current;
20472 ++ struct acl_subject_label *newacl;
20473 ++ struct acl_object_label *obj;
20474 ++ __u32 retmode;
20475 ++
20476 ++ if (unlikely(!(gr_status & GR_READY)))
20477 ++ return 0;
20478 ++
20479 ++ newacl = chk_subj_label(dentry, mnt, task->role);
20480 ++
20481 ++ task_lock(task);
20482 ++ if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
20483 ++ GR_POVERRIDE) && (task->acl != newacl) &&
20484 ++ !(task->role->roletype & GR_ROLE_GOD) &&
20485 ++ !gr_search_file(dentry, GR_PTRACERD, mnt) &&
20486 ++ !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
20487 ++ (atomic_read(&task->fs->count) > 1 ||
20488 ++ atomic_read(&task->files->count) > 1 ||
20489 ++ atomic_read(&task->sighand->count) > 1)) {
20490 ++ task_unlock(task);
20491 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
20492 ++ return -EACCES;
20493 ++ }
20494 ++ task_unlock(task);
20495 ++
20496 ++ obj = chk_obj_label(dentry, mnt, task->acl);
20497 ++ retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
20498 ++
20499 ++ if (!(task->acl->mode & GR_INHERITLEARN) &&
20500 ++ ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
20501 ++ if (obj->nested)
20502 ++ task->acl = obj->nested;
20503 ++ else
20504 ++ task->acl = newacl;
20505 ++ } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
20506 ++ gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
20507 ++
20508 ++ task->is_writable = 0;
20509 ++
20510 ++ /* ignore additional mmap checks for processes that are writable
20511 ++ by the default ACL */
20512 ++ obj = chk_obj_label(dentry, mnt, default_role->root_label);
20513 ++ if (unlikely(obj->mode & GR_WRITE))
20514 ++ task->is_writable = 1;
20515 ++ obj = chk_obj_label(dentry, mnt, task->role->root_label);
20516 ++ if (unlikely(obj->mode & GR_WRITE))
20517 ++ task->is_writable = 1;
20518 ++
20519 ++ gr_set_proc_res(task);
20520 ++
20521 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
20522 ++ printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
20523 ++#endif
20524 ++ return 0;
20525 ++}
20526 ++
20527 ++/* always called with valid inodev ptr */
20528 ++static void
20529 ++do_handle_delete(struct inodev_entry *inodev, const ino_t ino, const dev_t dev)
20530 ++{
20531 ++ struct acl_object_label *matchpo;
20532 ++ struct acl_subject_label *matchps;
20533 ++ struct acl_subject_label *subj;
20534 ++ struct acl_role_label *role;
20535 ++ unsigned int i, x;
20536 ++
20537 ++ FOR_EACH_ROLE_START(role, i)
20538 ++ FOR_EACH_SUBJECT_START(role, subj, x)
20539 ++ if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
20540 ++ matchpo->mode |= GR_DELETED;
20541 ++ FOR_EACH_SUBJECT_END(subj,x)
20542 ++ FOR_EACH_NESTED_SUBJECT_START(role, subj)
20543 ++ if (subj->inode == ino && subj->device == dev)
20544 ++ subj->mode |= GR_DELETED;
20545 ++ FOR_EACH_NESTED_SUBJECT_END(subj)
20546 ++ if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
20547 ++ matchps->mode |= GR_DELETED;
20548 ++ FOR_EACH_ROLE_END(role,i)
20549 ++
20550 ++ inodev->nentry->deleted = 1;
20551 ++
20552 ++ return;
20553 ++}
20554 ++
20555 ++void
20556 ++gr_handle_delete(const ino_t ino, const dev_t dev)
20557 ++{
20558 ++ struct inodev_entry *inodev;
20559 ++
20560 ++ if (unlikely(!(gr_status & GR_READY)))
20561 ++ return;
20562 ++
20563 ++ write_lock(&gr_inode_lock);
20564 ++ inodev = lookup_inodev_entry(ino, dev);
20565 ++ if (inodev != NULL)
20566 ++ do_handle_delete(inodev, ino, dev);
20567 ++ write_unlock(&gr_inode_lock);
20568 ++
20569 ++ return;
20570 ++}
20571 ++
20572 ++static void
20573 ++update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
20574 ++ const ino_t newinode, const dev_t newdevice,
20575 ++ struct acl_subject_label *subj)
20576 ++{
20577 ++ unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
20578 ++ struct acl_object_label *match;
20579 ++
20580 ++ match = subj->obj_hash[index];
20581 ++
20582 ++ while (match && (match->inode != oldinode ||
20583 ++ match->device != olddevice ||
20584 ++ !(match->mode & GR_DELETED)))
20585 ++ match = match->next;
20586 ++
20587 ++ if (match && (match->inode == oldinode)
20588 ++ && (match->device == olddevice)
20589 ++ && (match->mode & GR_DELETED)) {
20590 ++ if (match->prev == NULL) {
20591 ++ subj->obj_hash[index] = match->next;
20592 ++ if (match->next != NULL)
20593 ++ match->next->prev = NULL;
20594 ++ } else {
20595 ++ match->prev->next = match->next;
20596 ++ if (match->next != NULL)
20597 ++ match->next->prev = match->prev;
20598 ++ }
20599 ++ match->prev = NULL;
20600 ++ match->next = NULL;
20601 ++ match->inode = newinode;
20602 ++ match->device = newdevice;
20603 ++ match->mode &= ~GR_DELETED;
20604 ++
20605 ++ insert_acl_obj_label(match, subj);
20606 ++ }
20607 ++
20608 ++ return;
20609 ++}
20610 ++
20611 ++static void
20612 ++update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
20613 ++ const ino_t newinode, const dev_t newdevice,
20614 ++ struct acl_role_label *role)
20615 ++{
20616 ++ unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
20617 ++ struct acl_subject_label *match;
20618 ++
20619 ++ match = role->subj_hash[index];
20620 ++
20621 ++ while (match && (match->inode != oldinode ||
20622 ++ match->device != olddevice ||
20623 ++ !(match->mode & GR_DELETED)))
20624 ++ match = match->next;
20625 ++
20626 ++ if (match && (match->inode == oldinode)
20627 ++ && (match->device == olddevice)
20628 ++ && (match->mode & GR_DELETED)) {
20629 ++ if (match->prev == NULL) {
20630 ++ role->subj_hash[index] = match->next;
20631 ++ if (match->next != NULL)
20632 ++ match->next->prev = NULL;
20633 ++ } else {
20634 ++ match->prev->next = match->next;
20635 ++ if (match->next != NULL)
20636 ++ match->next->prev = match->prev;
20637 ++ }
20638 ++ match->prev = NULL;
20639 ++ match->next = NULL;
20640 ++ match->inode = newinode;
20641 ++ match->device = newdevice;
20642 ++ match->mode &= ~GR_DELETED;
20643 ++
20644 ++ insert_acl_subj_label(match, role);
20645 ++ }
20646 ++
20647 ++ return;
20648 ++}
20649 ++
20650 ++static void
20651 ++update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
20652 ++ const ino_t newinode, const dev_t newdevice)
20653 ++{
20654 ++ unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
20655 ++ struct inodev_entry *match;
20656 ++
20657 ++ match = inodev_set.i_hash[index];
20658 ++
20659 ++ while (match && (match->nentry->inode != oldinode ||
20660 ++ match->nentry->device != olddevice || !match->nentry->deleted))
20661 ++ match = match->next;
20662 ++
20663 ++ if (match && (match->nentry->inode == oldinode)
20664 ++ && (match->nentry->device == olddevice) &&
20665 ++ match->nentry->deleted) {
20666 ++ if (match->prev == NULL) {
20667 ++ inodev_set.i_hash[index] = match->next;
20668 ++ if (match->next != NULL)
20669 ++ match->next->prev = NULL;
20670 ++ } else {
20671 ++ match->prev->next = match->next;
20672 ++ if (match->next != NULL)
20673 ++ match->next->prev = match->prev;
20674 ++ }
20675 ++ match->prev = NULL;
20676 ++ match->next = NULL;
20677 ++ match->nentry->inode = newinode;
20678 ++ match->nentry->device = newdevice;
20679 ++ match->nentry->deleted = 0;
20680 ++
20681 ++ insert_inodev_entry(match);
20682 ++ }
20683 ++
20684 ++ return;
20685 ++}
20686 ++
20687 ++static void
20688 ++do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
20689 ++ const struct vfsmount *mnt)
20690 ++{
20691 ++ struct acl_subject_label *subj;
20692 ++ struct acl_role_label *role;
20693 ++ unsigned int i, x;
20694 ++
20695 ++ FOR_EACH_ROLE_START(role, i)
20696 ++ update_acl_subj_label(matchn->inode, matchn->device,
20697 ++ dentry->d_inode->i_ino,
20698 ++ dentry->d_inode->i_sb->s_dev, role);
20699 ++
20700 ++ FOR_EACH_NESTED_SUBJECT_START(role, subj)
20701 ++ if ((subj->inode == dentry->d_inode->i_ino) &&
20702 ++ (subj->device == dentry->d_inode->i_sb->s_dev)) {
20703 ++ subj->inode = dentry->d_inode->i_ino;
20704 ++ subj->device = dentry->d_inode->i_sb->s_dev;
20705 ++ }
20706 ++ FOR_EACH_NESTED_SUBJECT_END(subj)
20707 ++ FOR_EACH_SUBJECT_START(role, subj, x)
20708 ++ update_acl_obj_label(matchn->inode, matchn->device,
20709 ++ dentry->d_inode->i_ino,
20710 ++ dentry->d_inode->i_sb->s_dev, subj);
20711 ++ FOR_EACH_SUBJECT_END(subj,x)
20712 ++ FOR_EACH_ROLE_END(role,i)
20713 ++
20714 ++ update_inodev_entry(matchn->inode, matchn->device,
20715 ++ dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
20716 ++
20717 ++ return;
20718 ++}
20719 ++
20720 ++void
20721 ++gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
20722 ++{
20723 ++ struct name_entry *matchn;
20724 ++
20725 ++ if (unlikely(!(gr_status & GR_READY)))
20726 ++ return;
20727 ++
20728 ++ preempt_disable();
20729 ++ matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
20730 ++
20731 ++ if (unlikely((unsigned long)matchn)) {
20732 ++ write_lock(&gr_inode_lock);
20733 ++ do_handle_create(matchn, dentry, mnt);
20734 ++ write_unlock(&gr_inode_lock);
20735 ++ }
20736 ++ preempt_enable();
20737 ++
20738 ++ return;
20739 ++}
20740 ++
20741 ++void
20742 ++gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
20743 ++ struct dentry *old_dentry,
20744 ++ struct dentry *new_dentry,
20745 ++ struct vfsmount *mnt, const __u8 replace)
20746 ++{
20747 ++ struct name_entry *matchn;
20748 ++ struct inodev_entry *inodev;
20749 ++
20750 ++ /* vfs_rename swaps the name and parent link for old_dentry and
20751 ++ new_dentry
20752 ++ at this point, old_dentry has the new name, parent link, and inode
20753 ++ for the renamed file
20754 ++ if a file is being replaced by a rename, new_dentry has the inode
20755 ++ and name for the replaced file
20756 ++ */
20757 ++
20758 ++ if (unlikely(!(gr_status & GR_READY)))
20759 ++ return;
20760 ++
20761 ++ preempt_disable();
20762 ++ matchn = lookup_name_entry(gr_to_filename_rbac(old_dentry, mnt));
20763 ++
20764 ++ /* we wouldn't have to check d_inode if it weren't for
20765 ++ NFS silly-renaming
20766 ++ */
20767 ++
20768 ++ write_lock(&gr_inode_lock);
20769 ++ if (unlikely(replace && new_dentry->d_inode)) {
20770 ++ inodev = lookup_inodev_entry(new_dentry->d_inode->i_ino,
20771 ++ new_dentry->d_inode->i_sb->s_dev);
20772 ++ if (inodev != NULL && (new_dentry->d_inode->i_nlink <= 1))
20773 ++ do_handle_delete(inodev, new_dentry->d_inode->i_ino,
20774 ++ new_dentry->d_inode->i_sb->s_dev);
20775 ++ }
20776 ++
20777 ++ inodev = lookup_inodev_entry(old_dentry->d_inode->i_ino,
20778 ++ old_dentry->d_inode->i_sb->s_dev);
20779 ++ if (inodev != NULL && (old_dentry->d_inode->i_nlink <= 1))
20780 ++ do_handle_delete(inodev, old_dentry->d_inode->i_ino,
20781 ++ old_dentry->d_inode->i_sb->s_dev);
20782 ++
20783 ++ if (unlikely((unsigned long)matchn))
20784 ++ do_handle_create(matchn, old_dentry, mnt);
20785 ++
20786 ++ write_unlock(&gr_inode_lock);
20787 ++ preempt_enable();
20788 ++
20789 ++ return;
20790 ++}
20791 ++
20792 ++static int
20793 ++lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
20794 ++ unsigned char **sum)
20795 ++{
20796 ++ struct acl_role_label *r;
20797 ++ struct role_allowed_ip *ipp;
20798 ++ struct role_transition *trans;
20799 ++ unsigned int i;
20800 ++ int found = 0;
20801 ++
20802 ++ /* check transition table */
20803 ++
20804 ++ for (trans = current->role->transitions; trans; trans = trans->next) {
20805 ++ if (!strcmp(rolename, trans->rolename)) {
20806 ++ found = 1;
20807 ++ break;
20808 ++ }
20809 ++ }
20810 ++
20811 ++ if (!found)
20812 ++ return 0;
20813 ++
20814 ++ /* handle special roles that do not require authentication
20815 ++ and check ip */
20816 ++
20817 ++ FOR_EACH_ROLE_START(r, i)
20818 ++ if (!strcmp(rolename, r->rolename) &&
20819 ++ (r->roletype & GR_ROLE_SPECIAL)) {
20820 ++ found = 0;
20821 ++ if (r->allowed_ips != NULL) {
20822 ++ for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
20823 ++ if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
20824 ++ (ntohl(ipp->addr) & ipp->netmask))
20825 ++ found = 1;
20826 ++ }
20827 ++ } else
20828 ++ found = 2;
20829 ++ if (!found)
20830 ++ return 0;
20831 ++
20832 ++ if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
20833 ++ ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
20834 ++ *salt = NULL;
20835 ++ *sum = NULL;
20836 ++ return 1;
20837 ++ }
20838 ++ }
20839 ++ FOR_EACH_ROLE_END(r,i)
20840 ++
20841 ++ for (i = 0; i < num_sprole_pws; i++) {
20842 ++ if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
20843 ++ *salt = acl_special_roles[i]->salt;
20844 ++ *sum = acl_special_roles[i]->sum;
20845 ++ return 1;
20846 ++ }
20847 ++ }
20848 ++
20849 ++ return 0;
20850 ++}
20851 ++
20852 ++static void
20853 ++assign_special_role(char *rolename)
20854 ++{
20855 ++ struct acl_object_label *obj;
20856 ++ struct acl_role_label *r;
20857 ++ struct acl_role_label *assigned = NULL;
20858 ++ struct task_struct *tsk;
20859 ++ struct file *filp;
20860 ++ unsigned int i;
20861 ++
20862 ++ FOR_EACH_ROLE_START(r, i)
20863 ++ if (!strcmp(rolename, r->rolename) &&
20864 ++ (r->roletype & GR_ROLE_SPECIAL))
20865 ++ assigned = r;
20866 ++ FOR_EACH_ROLE_END(r,i)
20867 ++
20868 ++ if (!assigned)
20869 ++ return;
20870 ++
20871 ++ read_lock(&tasklist_lock);
20872 ++ read_lock(&grsec_exec_file_lock);
20873 ++
20874 ++ tsk = current->parent;
20875 ++ if (tsk == NULL)
20876 ++ goto out_unlock;
20877 ++
20878 ++ filp = tsk->exec_file;
20879 ++ if (filp == NULL)
20880 ++ goto out_unlock;
20881 ++
20882 ++ tsk->is_writable = 0;
20883 ++
20884 ++ tsk->acl_sp_role = 1;
20885 ++ tsk->acl_role_id = ++acl_sp_role_value;
20886 ++ tsk->role = assigned;
20887 ++ tsk->acl = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role);
20888 ++
20889 ++ /* ignore additional mmap checks for processes that are writable
20890 ++ by the default ACL */
20891 ++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
20892 ++ if (unlikely(obj->mode & GR_WRITE))
20893 ++ tsk->is_writable = 1;
20894 ++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label);
20895 ++ if (unlikely(obj->mode & GR_WRITE))
20896 ++ tsk->is_writable = 1;
20897 ++
20898 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
20899 ++ printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
20900 ++#endif
20901 ++
20902 ++out_unlock:
20903 ++ read_unlock(&grsec_exec_file_lock);
20904 ++ read_unlock(&tasklist_lock);
20905 ++ return;
20906 ++}
20907 ++
20908 ++int gr_check_secure_terminal(struct task_struct *task)
20909 ++{
20910 ++ struct task_struct *p, *p2, *p3;
20911 ++ struct files_struct *files;
20912 ++ struct fdtable *fdt;
20913 ++ struct file *our_file = NULL, *file;
20914 ++ int i;
20915 ++
20916 ++ if (task->signal->tty == NULL)
20917 ++ return 1;
20918 ++
20919 ++ files = get_files_struct(task);
20920 ++ if (files != NULL) {
20921 ++ rcu_read_lock();
20922 ++ fdt = files_fdtable(files);
20923 ++ for (i=0; i < fdt->max_fds; i++) {
20924 ++ file = fcheck_files(files, i);
20925 ++ if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
20926 ++ get_file(file);
20927 ++ our_file = file;
20928 ++ }
20929 ++ }
20930 ++ rcu_read_unlock();
20931 ++ put_files_struct(files);
20932 ++ }
20933 ++
20934 ++ if (our_file == NULL)
20935 ++ return 1;
20936 ++
20937 ++ read_lock(&tasklist_lock);
20938 ++ do_each_thread(p2, p) {
20939 ++ files = get_files_struct(p);
20940 ++ if (files == NULL ||
20941 ++ (p->signal && p->signal->tty == task->signal->tty)) {
20942 ++ if (files != NULL)
20943 ++ put_files_struct(files);
20944 ++ continue;
20945 ++ }
20946 ++ rcu_read_lock();
20947 ++ fdt = files_fdtable(files);
20948 ++ for (i=0; i < fdt->max_fds; i++) {
20949 ++ file = fcheck_files(files, i);
20950 ++ if (file && S_ISCHR(file->f_dentry->d_inode->i_mode) &&
20951 ++ file->f_dentry->d_inode->i_rdev == our_file->f_dentry->d_inode->i_rdev) {
20952 ++ p3 = task;
20953 ++ while (p3->pid > 0) {
20954 ++ if (p3 == p)
20955 ++ break;
20956 ++ p3 = p3->parent;
20957 ++ }
20958 ++ if (p3 == p)
20959 ++ break;
20960 ++ gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
20961 ++ gr_handle_alertkill(p);
20962 ++ rcu_read_unlock();
20963 ++ put_files_struct(files);
20964 ++ read_unlock(&tasklist_lock);
20965 ++ fput(our_file);
20966 ++ return 0;
20967 ++ }
20968 ++ }
20969 ++ rcu_read_unlock();
20970 ++ put_files_struct(files);
20971 ++ } while_each_thread(p2, p);
20972 ++ read_unlock(&tasklist_lock);
20973 ++
20974 ++ fput(our_file);
20975 ++ return 1;
20976 ++}
20977 ++
20978 ++ssize_t
20979 ++write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
20980 ++{
20981 ++ struct gr_arg_wrapper uwrap;
20982 ++ unsigned char *sprole_salt;
20983 ++ unsigned char *sprole_sum;
20984 ++ int error = sizeof (struct gr_arg_wrapper);
20985 ++ int error2 = 0;
20986 ++
20987 ++ down(&gr_dev_sem);
20988 ++
20989 ++ if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
20990 ++ error = -EPERM;
20991 ++ goto out;
20992 ++ }
20993 ++
20994 ++ if (count != sizeof (struct gr_arg_wrapper)) {
20995 ++ gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
20996 ++ error = -EINVAL;
20997 ++ goto out;
20998 ++ }
20999 ++
21000 ++
21001 ++ if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
21002 ++ gr_auth_expires = 0;
21003 ++ gr_auth_attempts = 0;
21004 ++ }
21005 ++
21006 ++ if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
21007 ++ error = -EFAULT;
21008 ++ goto out;
21009 ++ }
21010 ++
21011 ++ if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
21012 ++ error = -EINVAL;
21013 ++ goto out;
21014 ++ }
21015 ++
21016 ++ if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
21017 ++ error = -EFAULT;
21018 ++ goto out;
21019 ++ }
21020 ++
21021 ++ if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM &&
21022 ++ gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
21023 ++ time_after(gr_auth_expires, get_seconds())) {
21024 ++ error = -EBUSY;
21025 ++ goto out;
21026 ++ }
21027 ++
21028 ++ /* if non-root trying to do anything other than use a special role,
21029 ++ do not attempt authentication, do not count towards authentication
21030 ++ locking
21031 ++ */
21032 ++
21033 ++ if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS &&
21034 ++ gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM &&
21035 ++ current->uid) {
21036 ++ error = -EPERM;
21037 ++ goto out;
21038 ++ }
21039 ++
21040 ++ /* ensure pw and special role name are null terminated */
21041 ++
21042 ++ gr_usermode->pw[GR_PW_LEN - 1] = '\0';
21043 ++ gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
21044 ++
21045 ++ /* Okay.
21046 ++ * We have our enough of the argument structure..(we have yet
21047 ++ * to copy_from_user the tables themselves) . Copy the tables
21048 ++ * only if we need them, i.e. for loading operations. */
21049 ++
21050 ++ switch (gr_usermode->mode) {
21051 ++ case STATUS:
21052 ++ if (gr_status & GR_READY) {
21053 ++ error = 1;
21054 ++ if (!gr_check_secure_terminal(current))
21055 ++ error = 3;
21056 ++ } else
21057 ++ error = 2;
21058 ++ goto out;
21059 ++ case SHUTDOWN:
21060 ++ if ((gr_status & GR_READY)
21061 ++ && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
21062 ++ gr_status &= ~GR_READY;
21063 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
21064 ++ free_variables();
21065 ++ memset(gr_usermode, 0, sizeof (struct gr_arg));
21066 ++ memset(gr_system_salt, 0, GR_SALT_LEN);
21067 ++ memset(gr_system_sum, 0, GR_SHA_LEN);
21068 ++ } else if (gr_status & GR_READY) {
21069 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
21070 ++ error = -EPERM;
21071 ++ } else {
21072 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
21073 ++ error = -EAGAIN;
21074 ++ }
21075 ++ break;
21076 ++ case ENABLE:
21077 ++ if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
21078 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
21079 ++ else {
21080 ++ if (gr_status & GR_READY)
21081 ++ error = -EAGAIN;
21082 ++ else
21083 ++ error = error2;
21084 ++ gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
21085 ++ }
21086 ++ break;
21087 ++ case RELOAD:
21088 ++ if (!(gr_status & GR_READY)) {
21089 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
21090 ++ error = -EAGAIN;
21091 ++ } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
21092 ++ lock_kernel();
21093 ++ gr_status &= ~GR_READY;
21094 ++ free_variables();
21095 ++ if (!(error2 = gracl_init(gr_usermode))) {
21096 ++ unlock_kernel();
21097 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
21098 ++ } else {
21099 ++ unlock_kernel();
21100 ++ error = error2;
21101 ++ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
21102 ++ }
21103 ++ } else {
21104 ++ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
21105 ++ error = -EPERM;
21106 ++ }
21107 ++ break;
21108 ++ case SEGVMOD:
21109 ++ if (unlikely(!(gr_status & GR_READY))) {
21110 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
21111 ++ error = -EAGAIN;
21112 ++ break;
21113 ++ }
21114 ++
21115 ++ if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
21116 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
21117 ++ if (gr_usermode->segv_device && gr_usermode->segv_inode) {
21118 ++ struct acl_subject_label *segvacl;
21119 ++ segvacl =
21120 ++ lookup_acl_subj_label(gr_usermode->segv_inode,
21121 ++ gr_usermode->segv_device,
21122 ++ current->role);
21123 ++ if (segvacl) {
21124 ++ segvacl->crashes = 0;
21125 ++ segvacl->expires = 0;
21126 ++ }
21127 ++ } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
21128 ++ gr_remove_uid(gr_usermode->segv_uid);
21129 ++ }
21130 ++ } else {
21131 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
21132 ++ error = -EPERM;
21133 ++ }
21134 ++ break;
21135 ++ case SPROLE:
21136 ++ case SPROLEPAM:
21137 ++ if (unlikely(!(gr_status & GR_READY))) {
21138 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
21139 ++ error = -EAGAIN;
21140 ++ break;
21141 ++ }
21142 ++
21143 ++ if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
21144 ++ current->role->expires = 0;
21145 ++ current->role->auth_attempts = 0;
21146 ++ }
21147 ++
21148 ++ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
21149 ++ time_after(current->role->expires, get_seconds())) {
21150 ++ error = -EBUSY;
21151 ++ goto out;
21152 ++ }
21153 ++
21154 ++ if (lookup_special_role_auth
21155 ++ (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
21156 ++ && ((!sprole_salt && !sprole_sum)
21157 ++ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
21158 ++ char *p = "";
21159 ++ assign_special_role(gr_usermode->sp_role);
21160 ++ read_lock(&tasklist_lock);
21161 ++ if (current->parent)
21162 ++ p = current->parent->role->rolename;
21163 ++ read_unlock(&tasklist_lock);
21164 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
21165 ++ p, acl_sp_role_value);
21166 ++ } else {
21167 ++ gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
21168 ++ error = -EPERM;
21169 ++ if(!(current->role->auth_attempts++))
21170 ++ current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
21171 ++
21172 ++ goto out;
21173 ++ }
21174 ++ break;
21175 ++ case UNSPROLE:
21176 ++ if (unlikely(!(gr_status & GR_READY))) {
21177 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
21178 ++ error = -EAGAIN;
21179 ++ break;
21180 ++ }
21181 ++
21182 ++ if (current->role->roletype & GR_ROLE_SPECIAL) {
21183 ++ char *p = "";
21184 ++ int i = 0;
21185 ++
21186 ++ read_lock(&tasklist_lock);
21187 ++ if (current->parent) {
21188 ++ p = current->parent->role->rolename;
21189 ++ i = current->parent->acl_role_id;
21190 ++ }
21191 ++ read_unlock(&tasklist_lock);
21192 ++
21193 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
21194 ++ gr_set_acls(1);
21195 ++ } else {
21196 ++ gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
21197 ++ error = -EPERM;
21198 ++ goto out;
21199 ++ }
21200 ++ break;
21201 ++ default:
21202 ++ gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
21203 ++ error = -EINVAL;
21204 ++ break;
21205 ++ }
21206 ++
21207 ++ if (error != -EPERM)
21208 ++ goto out;
21209 ++
21210 ++ if(!(gr_auth_attempts++))
21211 ++ gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
21212 ++
21213 ++ out:
21214 ++ up(&gr_dev_sem);
21215 ++ return error;
21216 ++}
21217 ++
21218 ++int
21219 ++gr_set_acls(const int type)
21220 ++{
21221 ++ struct acl_object_label *obj;
21222 ++ struct task_struct *task, *task2;
21223 ++ struct file *filp;
21224 ++ struct acl_role_label *role = current->role;
21225 ++ __u16 acl_role_id = current->acl_role_id;
21226 ++
21227 ++ read_lock(&tasklist_lock);
21228 ++ read_lock(&grsec_exec_file_lock);
21229 ++ do_each_thread(task2, task) {
21230 ++ /* check to see if we're called from the exit handler,
21231 ++ if so, only replace ACLs that have inherited the admin
21232 ++ ACL */
21233 ++
21234 ++ if (type && (task->role != role ||
21235 ++ task->acl_role_id != acl_role_id))
21236 ++ continue;
21237 ++
21238 ++ task->acl_role_id = 0;
21239 ++ task->acl_sp_role = 0;
21240 ++
21241 ++ if ((filp = task->exec_file)) {
21242 ++ task->role = lookup_acl_role_label(task, task->uid, task->gid);
21243 ++
21244 ++ task->acl =
21245 ++ chk_subj_label(filp->f_dentry, filp->f_vfsmnt,
21246 ++ task->role);
21247 ++ if (task->acl) {
21248 ++ struct acl_subject_label *curr;
21249 ++ curr = task->acl;
21250 ++
21251 ++ task->is_writable = 0;
21252 ++ /* ignore additional mmap checks for processes that are writable
21253 ++ by the default ACL */
21254 ++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
21255 ++ if (unlikely(obj->mode & GR_WRITE))
21256 ++ task->is_writable = 1;
21257 ++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
21258 ++ if (unlikely(obj->mode & GR_WRITE))
21259 ++ task->is_writable = 1;
21260 ++
21261 ++ gr_set_proc_res(task);
21262 ++
21263 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
21264 ++ printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
21265 ++#endif
21266 ++ } else {
21267 ++ read_unlock(&grsec_exec_file_lock);
21268 ++ read_unlock(&tasklist_lock);
21269 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
21270 ++ return 1;
21271 ++ }
21272 ++ } else {
21273 ++ // it's a kernel process
21274 ++ task->role = kernel_role;
21275 ++ task->acl = kernel_role->root_label;
21276 ++#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
21277 ++ task->acl->mode &= ~GR_PROCFIND;
21278 ++#endif
21279 ++ }
21280 ++ } while_each_thread(task2, task);
21281 ++ read_unlock(&grsec_exec_file_lock);
21282 ++ read_unlock(&tasklist_lock);
21283 ++ return 0;
21284 ++}
21285 ++
21286 ++void
21287 ++gr_learn_resource(const struct task_struct *task,
21288 ++ const int res, const unsigned long wanted, const int gt)
21289 ++{
21290 ++ struct acl_subject_label *acl;
21291 ++
21292 ++ if (unlikely((gr_status & GR_READY) &&
21293 ++ task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
21294 ++ goto skip_reslog;
21295 ++
21296 ++#ifdef CONFIG_GRKERNSEC_RESLOG
21297 ++ gr_log_resource(task, res, wanted, gt);
21298 ++#endif
21299 ++ skip_reslog:
21300 ++
21301 ++ if (unlikely(!(gr_status & GR_READY) || !wanted))
21302 ++ return;
21303 ++
21304 ++ acl = task->acl;
21305 ++
21306 ++ if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
21307 ++ !(acl->resmask & (1 << (unsigned short) res))))
21308 ++ return;
21309 ++
21310 ++ if (wanted >= acl->res[res].rlim_cur) {
21311 ++ unsigned long res_add;
21312 ++
21313 ++ res_add = wanted;
21314 ++ switch (res) {
21315 ++ case RLIMIT_CPU:
21316 ++ res_add += GR_RLIM_CPU_BUMP;
21317 ++ break;
21318 ++ case RLIMIT_FSIZE:
21319 ++ res_add += GR_RLIM_FSIZE_BUMP;
21320 ++ break;
21321 ++ case RLIMIT_DATA:
21322 ++ res_add += GR_RLIM_DATA_BUMP;
21323 ++ break;
21324 ++ case RLIMIT_STACK:
21325 ++ res_add += GR_RLIM_STACK_BUMP;
21326 ++ break;
21327 ++ case RLIMIT_CORE:
21328 ++ res_add += GR_RLIM_CORE_BUMP;
21329 ++ break;
21330 ++ case RLIMIT_RSS:
21331 ++ res_add += GR_RLIM_RSS_BUMP;
21332 ++ break;
21333 ++ case RLIMIT_NPROC:
21334 ++ res_add += GR_RLIM_NPROC_BUMP;
21335 ++ break;
21336 ++ case RLIMIT_NOFILE:
21337 ++ res_add += GR_RLIM_NOFILE_BUMP;
21338 ++ break;
21339 ++ case RLIMIT_MEMLOCK:
21340 ++ res_add += GR_RLIM_MEMLOCK_BUMP;
21341 ++ break;
21342 ++ case RLIMIT_AS:
21343 ++ res_add += GR_RLIM_AS_BUMP;
21344 ++ break;
21345 ++ case RLIMIT_LOCKS:
21346 ++ res_add += GR_RLIM_LOCKS_BUMP;
21347 ++ break;
21348 ++ }
21349 ++
21350 ++ acl->res[res].rlim_cur = res_add;
21351 ++
21352 ++ if (wanted > acl->res[res].rlim_max)
21353 ++ acl->res[res].rlim_max = res_add;
21354 ++
21355 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
21356 ++ task->role->roletype, acl->filename,
21357 ++ acl->res[res].rlim_cur, acl->res[res].rlim_max,
21358 ++ "", (unsigned long) res);
21359 ++ }
21360 ++
21361 ++ return;
21362 ++}
21363 ++
21364 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
21365 ++void
21366 ++pax_set_initial_flags(struct linux_binprm *bprm)
21367 ++{
21368 ++ struct task_struct *task = current;
21369 ++ struct acl_subject_label *proc;
21370 ++ unsigned long flags;
21371 ++
21372 ++ if (unlikely(!(gr_status & GR_READY)))
21373 ++ return;
21374 ++
21375 ++ flags = pax_get_flags(task);
21376 ++
21377 ++ proc = task->acl;
21378 ++
21379 ++ if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
21380 ++ flags &= ~MF_PAX_PAGEEXEC;
21381 ++ if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
21382 ++ flags &= ~MF_PAX_SEGMEXEC;
21383 ++ if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
21384 ++ flags &= ~MF_PAX_RANDMMAP;
21385 ++ if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
21386 ++ flags &= ~MF_PAX_EMUTRAMP;
21387 ++ if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
21388 ++ flags &= ~MF_PAX_MPROTECT;
21389 ++
21390 ++ if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
21391 ++ flags |= MF_PAX_PAGEEXEC;
21392 ++ if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
21393 ++ flags |= MF_PAX_SEGMEXEC;
21394 ++ if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
21395 ++ flags |= MF_PAX_RANDMMAP;
21396 ++ if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
21397 ++ flags |= MF_PAX_EMUTRAMP;
21398 ++ if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
21399 ++ flags |= MF_PAX_MPROTECT;
21400 ++
21401 ++ pax_set_flags(task, flags);
21402 ++
21403 ++ return;
21404 ++}
21405 ++#endif
21406 ++
21407 ++#ifdef CONFIG_SYSCTL
21408 ++/* Eric Biederman likes breaking userland ABI and every inode-based security
21409 ++ system to save 35kb of memory */
21410 ++
21411 ++/* we modify the passed in filename, but adjust it back before returning */
21412 ++static struct acl_object_label *gr_lookup_by_name(char *name, unsigned int len)
21413 ++{
21414 ++ struct name_entry *nmatch;
21415 ++ char *p, *lastp = NULL;
21416 ++ struct acl_object_label *obj = NULL, *tmp;
21417 ++ struct acl_subject_label *tmpsubj;
21418 ++ int done = 0;
21419 ++ char c = '\0';
21420 ++
21421 ++ read_lock(&gr_inode_lock);
21422 ++
21423 ++ p = name + len - 1;
21424 ++ do {
21425 ++ nmatch = lookup_name_entry(name);
21426 ++ if (lastp != NULL)
21427 ++ *lastp = c;
21428 ++
21429 ++ if (nmatch == NULL)
21430 ++ goto next_component;
21431 ++ tmpsubj = current->acl;
21432 ++ do {
21433 ++ obj = lookup_acl_obj_label(nmatch->inode, nmatch->device, tmpsubj);
21434 ++ if (obj != NULL) {
21435 ++ tmp = obj->globbed;
21436 ++ while (tmp) {
21437 ++ if (!glob_match(tmp->filename, name)) {
21438 ++ obj = tmp;
21439 ++ goto found_obj;
21440 ++ }
21441 ++ tmp = tmp->next;
21442 ++ }
21443 ++ goto found_obj;
21444 ++ }
21445 ++ } while ((tmpsubj = tmpsubj->parent_subject));
21446 ++next_component:
21447 ++ /* end case */
21448 ++ if (p == name)
21449 ++ break;
21450 ++
21451 ++ while (*p != '/')
21452 ++ p--;
21453 ++ if (p == name)
21454 ++ lastp = p + 1;
21455 ++ else {
21456 ++ lastp = p;
21457 ++ p--;
21458 ++ }
21459 ++ c = *lastp;
21460 ++ *lastp = '\0';
21461 ++ } while (1);
21462 ++found_obj:
21463 ++ read_unlock(&gr_inode_lock);
21464 ++ /* obj returned will always be non-null */
21465 ++ return obj;
21466 ++}
21467 ++
21468 ++/* returns 0 when allowing, non-zero on error
21469 ++ op of 0 is used for readdir, so we don't log the names of hidden files
21470 ++*/
21471 ++__u32
21472 ++gr_handle_sysctl(const struct ctl_table *table, const int op)
21473 ++{
21474 ++ ctl_table *tmp;
21475 ++ struct nameidata nd;
21476 ++ const char *proc_sys = "/proc/sys";
21477 ++ char *path;
21478 ++ struct acl_object_label *obj;
21479 ++ unsigned short len = 0, pos = 0, depth = 0, i;
21480 ++ __u32 err = 0;
21481 ++ __u32 mode = 0;
21482 ++
21483 ++ if (unlikely(!(gr_status & GR_READY)))
21484 ++ return 0;
21485 ++
21486 ++ /* for now, ignore operations on non-sysctl entries if it's not a
21487 ++ readdir*/
21488 ++ if (table->child != NULL && op != 0)
21489 ++ return 0;
21490 ++
21491 ++ mode |= GR_FIND;
21492 ++ /* it's only a read if it's an entry, read on dirs is for readdir */
21493 ++ if (op & 004)
21494 ++ mode |= GR_READ;
21495 ++ if (op & 002)
21496 ++ mode |= GR_WRITE;
21497 ++
21498 ++ preempt_disable();
21499 ++
21500 ++ path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
21501 ++
21502 ++ /* it's only a read/write if it's an actual entry, not a dir
21503 ++ (which are opened for readdir)
21504 ++ */
21505 ++
21506 ++ /* convert the requested sysctl entry into a pathname */
21507 ++
21508 ++ for (tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
21509 ++ len += strlen(tmp->procname);
21510 ++ len++;
21511 ++ depth++;
21512 ++ }
21513 ++
21514 ++ if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE) {
21515 ++ /* deny */
21516 ++ goto out;
21517 ++ }
21518 ++
21519 ++ memset(path, 0, PAGE_SIZE);
21520 ++
21521 ++ memcpy(path, proc_sys, strlen(proc_sys));
21522 ++
21523 ++ pos += strlen(proc_sys);
21524 ++
21525 ++ for (; depth > 0; depth--) {
21526 ++ path[pos] = '/';
21527 ++ pos++;
21528 ++ for (i = 1, tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
21529 ++ if (depth == i) {
21530 ++ memcpy(path + pos, tmp->procname,
21531 ++ strlen(tmp->procname));
21532 ++ pos += strlen(tmp->procname);
21533 ++ }
21534 ++ i++;
21535 ++ }
21536 ++ }
21537 ++
21538 ++ obj = gr_lookup_by_name(path, pos);
21539 ++ err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
21540 ++
21541 ++ if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
21542 ++ ((err & mode) != mode))) {
21543 ++ __u32 new_mode = mode;
21544 ++
21545 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
21546 ++
21547 ++ err = 0;
21548 ++ gr_log_learn_sysctl(current, path, new_mode);
21549 ++ } else if (!(err & GR_FIND) && !(err & GR_SUPPRESS) && op != 0) {
21550 ++ gr_log_hidden_sysctl(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, path);
21551 ++ err = -ENOENT;
21552 ++ } else if (!(err & GR_FIND)) {
21553 ++ err = -ENOENT;
21554 ++ } else if (((err & mode) & ~GR_FIND) != (mode & ~GR_FIND) && !(err & GR_SUPPRESS)) {
21555 ++ gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
21556 ++ path, (mode & GR_READ) ? " reading" : "",
21557 ++ (mode & GR_WRITE) ? " writing" : "");
21558 ++ err = -EACCES;
21559 ++ } else if ((err & mode) != mode) {
21560 ++ err = -EACCES;
21561 ++ } else if ((((err & mode) & ~GR_FIND) == (mode & ~GR_FIND)) && (err & GR_AUDITS)) {
21562 ++ gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
21563 ++ path, (mode & GR_READ) ? " reading" : "",
21564 ++ (mode & GR_WRITE) ? " writing" : "");
21565 ++ err = 0;
21566 ++ } else
21567 ++ err = 0;
21568 ++
21569 ++ out:
21570 ++ preempt_enable();
21571 ++
21572 ++ return err;
21573 ++}
21574 ++#endif
21575 ++
21576 ++int
21577 ++gr_handle_proc_ptrace(struct task_struct *task)
21578 ++{
21579 ++ struct file *filp;
21580 ++ struct task_struct *tmp = task;
21581 ++ struct task_struct *curtemp = current;
21582 ++ __u32 retmode;
21583 ++
21584 ++ if (unlikely(!(gr_status & GR_READY)))
21585 ++ return 0;
21586 ++
21587 ++ read_lock(&tasklist_lock);
21588 ++ read_lock(&grsec_exec_file_lock);
21589 ++ filp = task->exec_file;
21590 ++
21591 ++ while (tmp->pid > 0) {
21592 ++ if (tmp == curtemp)
21593 ++ break;
21594 ++ tmp = tmp->parent;
21595 ++ }
21596 ++
21597 ++ if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
21598 ++ read_unlock(&grsec_exec_file_lock);
21599 ++ read_unlock(&tasklist_lock);
21600 ++ return 1;
21601 ++ }
21602 ++
21603 ++ retmode = gr_search_file(filp->f_dentry, GR_NOPTRACE, filp->f_vfsmnt);
21604 ++ read_unlock(&grsec_exec_file_lock);
21605 ++ read_unlock(&tasklist_lock);
21606 ++
21607 ++ if (retmode & GR_NOPTRACE)
21608 ++ return 1;
21609 ++
21610 ++ if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
21611 ++ && (current->acl != task->acl || (current->acl != current->role->root_label
21612 ++ && current->pid != task->pid)))
21613 ++ return 1;
21614 ++
21615 ++ return 0;
21616 ++}
21617 ++
21618 ++int
21619 ++gr_handle_ptrace(struct task_struct *task, const long request)
21620 ++{
21621 ++ struct task_struct *tmp = task;
21622 ++ struct task_struct *curtemp = current;
21623 ++ __u32 retmode;
21624 ++
21625 ++ if (unlikely(!(gr_status & GR_READY)))
21626 ++ return 0;
21627 ++
21628 ++ read_lock(&tasklist_lock);
21629 ++ while (tmp->pid > 0) {
21630 ++ if (tmp == curtemp)
21631 ++ break;
21632 ++ tmp = tmp->parent;
21633 ++ }
21634 ++
21635 ++ if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
21636 ++ read_unlock(&tasklist_lock);
21637 ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
21638 ++ return 1;
21639 ++ }
21640 ++ read_unlock(&tasklist_lock);
21641 ++
21642 ++ read_lock(&grsec_exec_file_lock);
21643 ++ if (unlikely(!task->exec_file)) {
21644 ++ read_unlock(&grsec_exec_file_lock);
21645 ++ return 0;
21646 ++ }
21647 ++
21648 ++ retmode = gr_search_file(task->exec_file->f_dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_vfsmnt);
21649 ++ read_unlock(&grsec_exec_file_lock);
21650 ++
21651 ++ if (retmode & GR_NOPTRACE) {
21652 ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
21653 ++ return 1;
21654 ++ }
21655 ++
21656 ++ if (retmode & GR_PTRACERD) {
21657 ++ switch (request) {
21658 ++ case PTRACE_POKETEXT:
21659 ++ case PTRACE_POKEDATA:
21660 ++ case PTRACE_POKEUSR:
21661 ++#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
21662 ++ case PTRACE_SETREGS:
21663 ++ case PTRACE_SETFPREGS:
21664 ++#endif
21665 ++#ifdef CONFIG_X86
21666 ++ case PTRACE_SETFPXREGS:
21667 ++#endif
21668 ++#ifdef CONFIG_ALTIVEC
21669 ++ case PTRACE_SETVRREGS:
21670 ++#endif
21671 ++ return 1;
21672 ++ default:
21673 ++ return 0;
21674 ++ }
21675 ++ } else if (!(current->acl->mode & GR_POVERRIDE) &&
21676 ++ !(current->role->roletype & GR_ROLE_GOD) &&
21677 ++ (current->acl != task->acl)) {
21678 ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
21679 ++ return 1;
21680 ++ }
21681 ++
21682 ++ return 0;
21683 ++}
21684 ++
21685 ++static int is_writable_mmap(const struct file *filp)
21686 ++{
21687 ++ struct task_struct *task = current;
21688 ++ struct acl_object_label *obj, *obj2;
21689 ++
21690 ++ if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
21691 ++ !task->is_writable && S_ISREG(filp->f_dentry->d_inode->i_mode)) {
21692 ++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
21693 ++ obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt,
21694 ++ task->role->root_label);
21695 ++ if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
21696 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_dentry, filp->f_vfsmnt);
21697 ++ return 1;
21698 ++ }
21699 ++ }
21700 ++ return 0;
21701 ++}
21702 ++
21703 ++int
21704 ++gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
21705 ++{
21706 ++ __u32 mode;
21707 ++
21708 ++ if (unlikely(!file || !(prot & PROT_EXEC)))
21709 ++ return 1;
21710 ++
21711 ++ if (is_writable_mmap(file))
21712 ++ return 0;
21713 ++
21714 ++ mode =
21715 ++ gr_search_file(file->f_dentry,
21716 ++ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
21717 ++ file->f_vfsmnt);
21718 ++
21719 ++ if (!gr_tpe_allow(file))
21720 ++ return 0;
21721 ++
21722 ++ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
21723 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
21724 ++ return 0;
21725 ++ } else if (unlikely(!(mode & GR_EXEC))) {
21726 ++ return 0;
21727 ++ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
21728 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
21729 ++ return 1;
21730 ++ }
21731 ++
21732 ++ return 1;
21733 ++}
21734 ++
21735 ++int
21736 ++gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
21737 ++{
21738 ++ __u32 mode;
21739 ++
21740 ++ if (unlikely(!file || !(prot & PROT_EXEC)))
21741 ++ return 1;
21742 ++
21743 ++ if (is_writable_mmap(file))
21744 ++ return 0;
21745 ++
21746 ++ mode =
21747 ++ gr_search_file(file->f_dentry,
21748 ++ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
21749 ++ file->f_vfsmnt);
21750 ++
21751 ++ if (!gr_tpe_allow(file))
21752 ++ return 0;
21753 ++
21754 ++ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
21755 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
21756 ++ return 0;
21757 ++ } else if (unlikely(!(mode & GR_EXEC))) {
21758 ++ return 0;
21759 ++ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
21760 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
21761 ++ return 1;
21762 ++ }
21763 ++
21764 ++ return 1;
21765 ++}
21766 ++
21767 ++void
21768 ++gr_acl_handle_psacct(struct task_struct *task, const long code)
21769 ++{
21770 ++ unsigned long runtime;
21771 ++ unsigned long cputime;
21772 ++ unsigned int wday, cday;
21773 ++ __u8 whr, chr;
21774 ++ __u8 wmin, cmin;
21775 ++ __u8 wsec, csec;
21776 ++
21777 ++ if (unlikely(!(gr_status & GR_READY) || !task->acl ||
21778 ++ !(task->acl->mode & GR_PROCACCT)))
21779 ++ return;
21780 ++
21781 ++ runtime = xtime.tv_sec - task->start_time.tv_sec;
21782 ++ wday = runtime / (3600 * 24);
21783 ++ runtime -= wday * (3600 * 24);
21784 ++ whr = runtime / 3600;
21785 ++ runtime -= whr * 3600;
21786 ++ wmin = runtime / 60;
21787 ++ runtime -= wmin * 60;
21788 ++ wsec = runtime;
21789 ++
21790 ++ cputime = (task->utime + task->stime) / HZ;
21791 ++ cday = cputime / (3600 * 24);
21792 ++ cputime -= cday * (3600 * 24);
21793 ++ chr = cputime / 3600;
21794 ++ cputime -= chr * 3600;
21795 ++ cmin = cputime / 60;
21796 ++ cputime -= cmin * 60;
21797 ++ csec = cputime;
21798 ++
21799 ++ gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
21800 ++
21801 ++ return;
21802 ++}
21803 ++
21804 ++void gr_set_kernel_label(struct task_struct *task)
21805 ++{
21806 ++ if (gr_status & GR_READY) {
21807 ++ task->role = kernel_role;
21808 ++ task->acl = kernel_role->root_label;
21809 ++ }
21810 ++ return;
21811 ++}
21812 ++
21813 ++int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
21814 ++{
21815 ++ struct task_struct *task = current;
21816 ++ struct dentry *dentry = file->f_dentry;
21817 ++ struct vfsmount *mnt = file->f_vfsmnt;
21818 ++ struct acl_object_label *obj, *tmp;
21819 ++ struct acl_subject_label *subj;
21820 ++ unsigned int bufsize;
21821 ++ int is_not_root;
21822 ++ char *path;
21823 ++
21824 ++ if (unlikely(!(gr_status & GR_READY)))
21825 ++ return 1;
21826 ++
21827 ++ if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
21828 ++ return 1;
21829 ++
21830 ++ /* ignore Eric Biederman */
21831 ++ if (IS_PRIVATE(dentry->d_inode))
21832 ++ return 1;
21833 ++
21834 ++ subj = task->acl;
21835 ++ do {
21836 ++ obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
21837 ++ if (obj != NULL)
21838 ++ return (obj->mode & GR_FIND) ? 1 : 0;
21839 ++ } while ((subj = subj->parent_subject));
21840 ++
21841 ++ obj = chk_obj_label(dentry, mnt, task->acl);
21842 ++ if (obj->globbed == NULL)
21843 ++ return (obj->mode & GR_FIND) ? 1 : 0;
21844 ++
21845 ++ is_not_root = ((obj->filename[0] == '/') &&
21846 ++ (obj->filename[1] == '\0')) ? 0 : 1;
21847 ++ bufsize = PAGE_SIZE - namelen - is_not_root;
21848 ++
21849 ++ /* check bufsize > PAGE_SIZE || bufsize == 0 */
21850 ++ if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
21851 ++ return 1;
21852 ++
21853 ++ preempt_disable();
21854 ++ path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
21855 ++ bufsize);
21856 ++
21857 ++ bufsize = strlen(path);
21858 ++
21859 ++ /* if base is "/", don't append an additional slash */
21860 ++ if (is_not_root)
21861 ++ *(path + bufsize) = '/';
21862 ++ memcpy(path + bufsize + is_not_root, name, namelen);
21863 ++ *(path + bufsize + namelen + is_not_root) = '\0';
21864 ++
21865 ++ tmp = obj->globbed;
21866 ++ while (tmp) {
21867 ++ if (!glob_match(tmp->filename, path)) {
21868 ++ preempt_enable();
21869 ++ return (tmp->mode & GR_FIND) ? 1 : 0;
21870 ++ }
21871 ++ tmp = tmp->next;
21872 ++ }
21873 ++ preempt_enable();
21874 ++ return (obj->mode & GR_FIND) ? 1 : 0;
21875 ++}
21876 ++
21877 ++EXPORT_SYMBOL(gr_learn_resource);
21878 ++EXPORT_SYMBOL(gr_set_kernel_label);
21879 ++#ifdef CONFIG_SECURITY
21880 ++EXPORT_SYMBOL(gr_check_user_change);
21881 ++EXPORT_SYMBOL(gr_check_group_change);
21882 ++#endif
21883 ++
21884 +diff -Nurp linux-2.6.23.15/grsecurity/gracl_alloc.c linux-2.6.23.15-grsec/grsecurity/gracl_alloc.c
21885 +--- linux-2.6.23.15/grsecurity/gracl_alloc.c 1970-01-01 01:00:00.000000000 +0100
21886 ++++ linux-2.6.23.15-grsec/grsecurity/gracl_alloc.c 2008-02-11 10:37:44.000000000 +0000
21887 +@@ -0,0 +1,91 @@
21888 ++#include <linux/kernel.h>
21889 ++#include <linux/mm.h>
21890 ++#include <linux/slab.h>
21891 ++#include <linux/vmalloc.h>
21892 ++#include <linux/gracl.h>
21893 ++#include <linux/grsecurity.h>
21894 ++
21895 ++static unsigned long alloc_stack_next = 1;
21896 ++static unsigned long alloc_stack_size = 1;
21897 ++static void **alloc_stack;
21898 ++
21899 ++static __inline__ int
21900 ++alloc_pop(void)
21901 ++{
21902 ++ if (alloc_stack_next == 1)
21903 ++ return 0;
21904 ++
21905 ++ kfree(alloc_stack[alloc_stack_next - 2]);
21906 ++
21907 ++ alloc_stack_next--;
21908 ++
21909 ++ return 1;
21910 ++}
21911 ++
21912 ++static __inline__ void
21913 ++alloc_push(void *buf)
21914 ++{
21915 ++ if (alloc_stack_next >= alloc_stack_size)
21916 ++ BUG();
21917 ++
21918 ++ alloc_stack[alloc_stack_next - 1] = buf;
21919 ++
21920 ++ alloc_stack_next++;
21921 ++
21922 ++ return;
21923 ++}
21924 ++
21925 ++void *
21926 ++acl_alloc(unsigned long len)
21927 ++{
21928 ++ void *ret;
21929 ++
21930 ++ if (len > PAGE_SIZE)
21931 ++ BUG();
21932 ++
21933 ++ ret = kmalloc(len, GFP_KERNEL);
21934 ++
21935 ++ if (ret)
21936 ++ alloc_push(ret);
21937 ++
21938 ++ return ret;
21939 ++}
21940 ++
21941 ++void
21942 ++acl_free_all(void)
21943 ++{
21944 ++ if (gr_acl_is_enabled() || !alloc_stack)
21945 ++ return;
21946 ++
21947 ++ while (alloc_pop()) ;
21948 ++
21949 ++ if (alloc_stack) {
21950 ++ if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
21951 ++ kfree(alloc_stack);
21952 ++ else
21953 ++ vfree(alloc_stack);
21954 ++ }
21955 ++
21956 ++ alloc_stack = NULL;
21957 ++ alloc_stack_size = 1;
21958 ++ alloc_stack_next = 1;
21959 ++
21960 ++ return;
21961 ++}
21962 ++
21963 ++int
21964 ++acl_alloc_stack_init(unsigned long size)
21965 ++{
21966 ++ if ((size * sizeof (void *)) <= PAGE_SIZE)
21967 ++ alloc_stack =
21968 ++ (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
21969 ++ else
21970 ++ alloc_stack = (void **) vmalloc(size * sizeof (void *));
21971 ++
21972 ++ alloc_stack_size = size;
21973 ++
21974 ++ if (!alloc_stack)
21975 ++ return 0;
21976 ++ else
21977 ++ return 1;
21978 ++}
21979 +diff -Nurp linux-2.6.23.15/grsecurity/gracl_cap.c linux-2.6.23.15-grsec/grsecurity/gracl_cap.c
21980 +--- linux-2.6.23.15/grsecurity/gracl_cap.c 1970-01-01 01:00:00.000000000 +0100
21981 ++++ linux-2.6.23.15-grsec/grsecurity/gracl_cap.c 2008-02-11 10:37:44.000000000 +0000
21982 +@@ -0,0 +1,112 @@
21983 ++#include <linux/kernel.h>
21984 ++#include <linux/module.h>
21985 ++#include <linux/sched.h>
21986 ++#include <linux/capability.h>
21987 ++#include <linux/gracl.h>
21988 ++#include <linux/grsecurity.h>
21989 ++#include <linux/grinternal.h>
21990 ++
21991 ++static const char *captab_log[] = {
21992 ++ "CAP_CHOWN",
21993 ++ "CAP_DAC_OVERRIDE",
21994 ++ "CAP_DAC_READ_SEARCH",
21995 ++ "CAP_FOWNER",
21996 ++ "CAP_FSETID",
21997 ++ "CAP_KILL",
21998 ++ "CAP_SETGID",
21999 ++ "CAP_SETUID",
22000 ++ "CAP_SETPCAP",
22001 ++ "CAP_LINUX_IMMUTABLE",
22002 ++ "CAP_NET_BIND_SERVICE",
22003 ++ "CAP_NET_BROADCAST",
22004 ++ "CAP_NET_ADMIN",
22005 ++ "CAP_NET_RAW",
22006 ++ "CAP_IPC_LOCK",
22007 ++ "CAP_IPC_OWNER",
22008 ++ "CAP_SYS_MODULE",
22009 ++ "CAP_SYS_RAWIO",
22010 ++ "CAP_SYS_CHROOT",
22011 ++ "CAP_SYS_PTRACE",
22012 ++ "CAP_SYS_PACCT",
22013 ++ "CAP_SYS_ADMIN",
22014 ++ "CAP_SYS_BOOT",
22015 ++ "CAP_SYS_NICE",
22016 ++ "CAP_SYS_RESOURCE",
22017 ++ "CAP_SYS_TIME",
22018 ++ "CAP_SYS_TTY_CONFIG",
22019 ++ "CAP_MKNOD",
22020 ++ "CAP_LEASE",
22021 ++ "CAP_AUDIT_WRITE",
22022 ++ "CAP_AUDIT_CONTROL"
22023 ++};
22024 ++
22025 ++EXPORT_SYMBOL(gr_task_is_capable);
22026 ++EXPORT_SYMBOL(gr_is_capable_nolog);
22027 ++
22028 ++int
22029 ++gr_task_is_capable(struct task_struct *task, const int cap)
22030 ++{
22031 ++ struct acl_subject_label *curracl;
22032 ++ __u32 cap_drop = 0, cap_mask = 0;
22033 ++
22034 ++ if (!gr_acl_is_enabled())
22035 ++ return 1;
22036 ++
22037 ++ curracl = task->acl;
22038 ++
22039 ++ cap_drop = curracl->cap_lower;
22040 ++ cap_mask = curracl->cap_mask;
22041 ++
22042 ++ while ((curracl = curracl->parent_subject)) {
22043 ++ if (!(cap_mask & (1 << cap)) && (curracl->cap_mask & (1 << cap)))
22044 ++ cap_drop |= curracl->cap_lower & (1 << cap);
22045 ++ cap_mask |= curracl->cap_mask;
22046 ++ }
22047 ++
22048 ++ if (!cap_raised(cap_drop, cap))
22049 ++ return 1;
22050 ++
22051 ++ curracl = task->acl;
22052 ++
22053 ++ if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
22054 ++ && cap_raised(task->cap_effective, cap)) {
22055 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
22056 ++ task->role->roletype, task->uid,
22057 ++ task->gid, task->exec_file ?
22058 ++ gr_to_filename(task->exec_file->f_dentry,
22059 ++ task->exec_file->f_vfsmnt) : curracl->filename,
22060 ++ curracl->filename, 0UL,
22061 ++ 0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
22062 ++ return 1;
22063 ++ }
22064 ++
22065 ++ if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap))
22066 ++ gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
22067 ++ return 0;
22068 ++}
22069 ++
22070 ++int
22071 ++gr_is_capable_nolog(const int cap)
22072 ++{
22073 ++ struct acl_subject_label *curracl;
22074 ++ __u32 cap_drop = 0, cap_mask = 0;
22075 ++
22076 ++ if (!gr_acl_is_enabled())
22077 ++ return 1;
22078 ++
22079 ++ curracl = current->acl;
22080 ++
22081 ++ cap_drop = curracl->cap_lower;
22082 ++ cap_mask = curracl->cap_mask;
22083 ++
22084 ++ while ((curracl = curracl->parent_subject)) {
22085 ++ cap_drop |= curracl->cap_lower & (cap_mask & ~curracl->cap_mask);
22086 ++ cap_mask |= curracl->cap_mask;
22087 ++ }
22088 ++
22089 ++ if (!cap_raised(cap_drop, cap))
22090 ++ return 1;
22091 ++
22092 ++ return 0;
22093 ++}
22094 ++
22095 +diff -Nurp linux-2.6.23.15/grsecurity/gracl_fs.c linux-2.6.23.15-grsec/grsecurity/gracl_fs.c
22096 +--- linux-2.6.23.15/grsecurity/gracl_fs.c 1970-01-01 01:00:00.000000000 +0100
22097 ++++ linux-2.6.23.15-grsec/grsecurity/gracl_fs.c 2008-02-11 10:37:44.000000000 +0000
22098 +@@ -0,0 +1,423 @@
22099 ++#include <linux/kernel.h>
22100 ++#include <linux/sched.h>
22101 ++#include <linux/types.h>
22102 ++#include <linux/fs.h>
22103 ++#include <linux/file.h>
22104 ++#include <linux/stat.h>
22105 ++#include <linux/grsecurity.h>
22106 ++#include <linux/grinternal.h>
22107 ++#include <linux/gracl.h>
22108 ++
22109 ++__u32
22110 ++gr_acl_handle_hidden_file(const struct dentry * dentry,
22111 ++ const struct vfsmount * mnt)
22112 ++{
22113 ++ __u32 mode;
22114 ++
22115 ++ if (unlikely(!dentry->d_inode))
22116 ++ return GR_FIND;
22117 ++
22118 ++ mode =
22119 ++ gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
22120 ++
22121 ++ if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
22122 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
22123 ++ return mode;
22124 ++ } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
22125 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
22126 ++ return 0;
22127 ++ } else if (unlikely(!(mode & GR_FIND)))
22128 ++ return 0;
22129 ++
22130 ++ return GR_FIND;
22131 ++}
22132 ++
22133 ++__u32
22134 ++gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
22135 ++ const int fmode)
22136 ++{
22137 ++ __u32 reqmode = GR_FIND;
22138 ++ __u32 mode;
22139 ++
22140 ++ if (unlikely(!dentry->d_inode))
22141 ++ return reqmode;
22142 ++
22143 ++ if (unlikely(fmode & O_APPEND))
22144 ++ reqmode |= GR_APPEND;
22145 ++ else if (unlikely(fmode & FMODE_WRITE))
22146 ++ reqmode |= GR_WRITE;
22147 ++ if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
22148 ++ reqmode |= GR_READ;
22149 ++
22150 ++ mode =
22151 ++ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
22152 ++ mnt);
22153 ++
22154 ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
22155 ++ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
22156 ++ reqmode & GR_READ ? " reading" : "",
22157 ++ reqmode & GR_WRITE ? " writing" : reqmode &
22158 ++ GR_APPEND ? " appending" : "");
22159 ++ return reqmode;
22160 ++ } else
22161 ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
22162 ++ {
22163 ++ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
22164 ++ reqmode & GR_READ ? " reading" : "",
22165 ++ reqmode & GR_WRITE ? " writing" : reqmode &
22166 ++ GR_APPEND ? " appending" : "");
22167 ++ return 0;
22168 ++ } else if (unlikely((mode & reqmode) != reqmode))
22169 ++ return 0;
22170 ++
22171 ++ return reqmode;
22172 ++}
22173 ++
22174 ++__u32
22175 ++gr_acl_handle_creat(const struct dentry * dentry,
22176 ++ const struct dentry * p_dentry,
22177 ++ const struct vfsmount * p_mnt, const int fmode,
22178 ++ const int imode)
22179 ++{
22180 ++ __u32 reqmode = GR_WRITE | GR_CREATE;
22181 ++ __u32 mode;
22182 ++
22183 ++ if (unlikely(fmode & O_APPEND))
22184 ++ reqmode |= GR_APPEND;
22185 ++ if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
22186 ++ reqmode |= GR_READ;
22187 ++ if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
22188 ++ reqmode |= GR_SETID;
22189 ++
22190 ++ mode =
22191 ++ gr_check_create(dentry, p_dentry, p_mnt,
22192 ++ reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
22193 ++
22194 ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
22195 ++ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
22196 ++ reqmode & GR_READ ? " reading" : "",
22197 ++ reqmode & GR_WRITE ? " writing" : reqmode &
22198 ++ GR_APPEND ? " appending" : "");
22199 ++ return reqmode;
22200 ++ } else
22201 ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
22202 ++ {
22203 ++ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
22204 ++ reqmode & GR_READ ? " reading" : "",
22205 ++ reqmode & GR_WRITE ? " writing" : reqmode &
22206 ++ GR_APPEND ? " appending" : "");
22207 ++ return 0;
22208 ++ } else if (unlikely((mode & reqmode) != reqmode))
22209 ++ return 0;
22210 ++
22211 ++ return reqmode;
22212 ++}
22213 ++
22214 ++__u32
22215 ++gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
22216 ++ const int fmode)
22217 ++{
22218 ++ __u32 mode, reqmode = GR_FIND;
22219 ++
22220 ++ if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
22221 ++ reqmode |= GR_EXEC;
22222 ++ if (fmode & S_IWOTH)
22223 ++ reqmode |= GR_WRITE;
22224 ++ if (fmode & S_IROTH)
22225 ++ reqmode |= GR_READ;
22226 ++
22227 ++ mode =
22228 ++ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
22229 ++ mnt);
22230 ++
22231 ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
22232 ++ gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
22233 ++ reqmode & GR_READ ? " reading" : "",
22234 ++ reqmode & GR_WRITE ? " writing" : "",
22235 ++ reqmode & GR_EXEC ? " executing" : "");
22236 ++ return reqmode;
22237 ++ } else
22238 ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
22239 ++ {
22240 ++ gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
22241 ++ reqmode & GR_READ ? " reading" : "",
22242 ++ reqmode & GR_WRITE ? " writing" : "",
22243 ++ reqmode & GR_EXEC ? " executing" : "");
22244 ++ return 0;
22245 ++ } else if (unlikely((mode & reqmode) != reqmode))
22246 ++ return 0;
22247 ++
22248 ++ return reqmode;
22249 ++}
22250 ++
22251 ++static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
22252 ++{
22253 ++ __u32 mode;
22254 ++
22255 ++ mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
22256 ++
22257 ++ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
22258 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
22259 ++ return mode;
22260 ++ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
22261 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
22262 ++ return 0;
22263 ++ } else if (unlikely((mode & (reqmode)) != (reqmode)))
22264 ++ return 0;
22265 ++
22266 ++ return (reqmode);
22267 ++}
22268 ++
22269 ++__u32
22270 ++gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
22271 ++{
22272 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
22273 ++}
22274 ++
22275 ++__u32
22276 ++gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
22277 ++{
22278 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
22279 ++}
22280 ++
22281 ++__u32
22282 ++gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
22283 ++{
22284 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
22285 ++}
22286 ++
22287 ++__u32
22288 ++gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
22289 ++{
22290 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
22291 ++}
22292 ++
22293 ++__u32
22294 ++gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
22295 ++ mode_t mode)
22296 ++{
22297 ++ if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
22298 ++ return 1;
22299 ++
22300 ++ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
22301 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
22302 ++ GR_FCHMOD_ACL_MSG);
22303 ++ } else {
22304 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
22305 ++ }
22306 ++}
22307 ++
22308 ++__u32
22309 ++gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
22310 ++ mode_t mode)
22311 ++{
22312 ++ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
22313 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
22314 ++ GR_CHMOD_ACL_MSG);
22315 ++ } else {
22316 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
22317 ++ }
22318 ++}
22319 ++
22320 ++__u32
22321 ++gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
22322 ++{
22323 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
22324 ++}
22325 ++
22326 ++__u32
22327 ++gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
22328 ++{
22329 ++ return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
22330 ++}
22331 ++
22332 ++__u32
22333 ++gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
22334 ++{
22335 ++ return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
22336 ++ GR_UNIXCONNECT_ACL_MSG);
22337 ++}
22338 ++
22339 ++/* hardlinks require at minimum create permission,
22340 ++ any additional privilege required is based on the
22341 ++ privilege of the file being linked to
22342 ++*/
22343 ++__u32
22344 ++gr_acl_handle_link(const struct dentry * new_dentry,
22345 ++ const struct dentry * parent_dentry,
22346 ++ const struct vfsmount * parent_mnt,
22347 ++ const struct dentry * old_dentry,
22348 ++ const struct vfsmount * old_mnt, const char *to)
22349 ++{
22350 ++ __u32 mode;
22351 ++ __u32 needmode = GR_CREATE | GR_LINK;
22352 ++ __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
22353 ++
22354 ++ mode =
22355 ++ gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
22356 ++ old_mnt);
22357 ++
22358 ++ if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
22359 ++ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
22360 ++ return mode;
22361 ++ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
22362 ++ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
22363 ++ return 0;
22364 ++ } else if (unlikely((mode & needmode) != needmode))
22365 ++ return 0;
22366 ++
22367 ++ return 1;
22368 ++}
22369 ++
22370 ++__u32
22371 ++gr_acl_handle_symlink(const struct dentry * new_dentry,
22372 ++ const struct dentry * parent_dentry,
22373 ++ const struct vfsmount * parent_mnt, const char *from)
22374 ++{
22375 ++ __u32 needmode = GR_WRITE | GR_CREATE;
22376 ++ __u32 mode;
22377 ++
22378 ++ mode =
22379 ++ gr_check_create(new_dentry, parent_dentry, parent_mnt,
22380 ++ GR_CREATE | GR_AUDIT_CREATE |
22381 ++ GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
22382 ++
22383 ++ if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
22384 ++ gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
22385 ++ return mode;
22386 ++ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
22387 ++ gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
22388 ++ return 0;
22389 ++ } else if (unlikely((mode & needmode) != needmode))
22390 ++ return 0;
22391 ++
22392 ++ return (GR_WRITE | GR_CREATE);
22393 ++}
22394 ++
22395 ++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)
22396 ++{
22397 ++ __u32 mode;
22398 ++
22399 ++ mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
22400 ++
22401 ++ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
22402 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
22403 ++ return mode;
22404 ++ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
22405 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
22406 ++ return 0;
22407 ++ } else if (unlikely((mode & (reqmode)) != (reqmode)))
22408 ++ return 0;
22409 ++
22410 ++ return (reqmode);
22411 ++}
22412 ++
22413 ++__u32
22414 ++gr_acl_handle_mknod(const struct dentry * new_dentry,
22415 ++ const struct dentry * parent_dentry,
22416 ++ const struct vfsmount * parent_mnt,
22417 ++ const int mode)
22418 ++{
22419 ++ __u32 reqmode = GR_WRITE | GR_CREATE;
22420 ++ if (unlikely(mode & (S_ISUID | S_ISGID)))
22421 ++ reqmode |= GR_SETID;
22422 ++
22423 ++ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
22424 ++ reqmode, GR_MKNOD_ACL_MSG);
22425 ++}
22426 ++
22427 ++__u32
22428 ++gr_acl_handle_mkdir(const struct dentry *new_dentry,
22429 ++ const struct dentry *parent_dentry,
22430 ++ const struct vfsmount *parent_mnt)
22431 ++{
22432 ++ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
22433 ++ GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
22434 ++}
22435 ++
22436 ++#define RENAME_CHECK_SUCCESS(old, new) \
22437 ++ (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
22438 ++ ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
22439 ++
22440 ++int
22441 ++gr_acl_handle_rename(struct dentry *new_dentry,
22442 ++ struct dentry *parent_dentry,
22443 ++ const struct vfsmount *parent_mnt,
22444 ++ struct dentry *old_dentry,
22445 ++ struct inode *old_parent_inode,
22446 ++ struct vfsmount *old_mnt, const char *newname)
22447 ++{
22448 ++ __u32 comp1, comp2;
22449 ++ int error = 0;
22450 ++
22451 ++ if (unlikely(!gr_acl_is_enabled()))
22452 ++ return 0;
22453 ++
22454 ++ if (!new_dentry->d_inode) {
22455 ++ comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
22456 ++ GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
22457 ++ GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
22458 ++ comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
22459 ++ GR_DELETE | GR_AUDIT_DELETE |
22460 ++ GR_AUDIT_READ | GR_AUDIT_WRITE |
22461 ++ GR_SUPPRESS, old_mnt);
22462 ++ } else {
22463 ++ comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
22464 ++ GR_CREATE | GR_DELETE |
22465 ++ GR_AUDIT_CREATE | GR_AUDIT_DELETE |
22466 ++ GR_AUDIT_READ | GR_AUDIT_WRITE |
22467 ++ GR_SUPPRESS, parent_mnt);
22468 ++ comp2 =
22469 ++ gr_search_file(old_dentry,
22470 ++ GR_READ | GR_WRITE | GR_AUDIT_READ |
22471 ++ GR_DELETE | GR_AUDIT_DELETE |
22472 ++ GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
22473 ++ }
22474 ++
22475 ++ if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
22476 ++ ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
22477 ++ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
22478 ++ else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
22479 ++ && !(comp2 & GR_SUPPRESS)) {
22480 ++ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
22481 ++ error = -EACCES;
22482 ++ } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
22483 ++ error = -EACCES;
22484 ++
22485 ++ return error;
22486 ++}
22487 ++
22488 ++void
22489 ++gr_acl_handle_exit(void)
22490 ++{
22491 ++ u16 id;
22492 ++ char *rolename;
22493 ++ struct file *exec_file;
22494 ++
22495 ++ if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
22496 ++ id = current->acl_role_id;
22497 ++ rolename = current->role->rolename;
22498 ++ gr_set_acls(1);
22499 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
22500 ++ }
22501 ++
22502 ++ write_lock(&grsec_exec_file_lock);
22503 ++ exec_file = current->exec_file;
22504 ++ current->exec_file = NULL;
22505 ++ write_unlock(&grsec_exec_file_lock);
22506 ++
22507 ++ if (exec_file)
22508 ++ fput(exec_file);
22509 ++}
22510 ++
22511 ++int
22512 ++gr_acl_handle_procpidmem(const struct task_struct *task)
22513 ++{
22514 ++ if (unlikely(!gr_acl_is_enabled()))
22515 ++ return 0;
22516 ++
22517 ++ if (task->acl->mode & GR_PROTPROCFD)
22518 ++ return -EACCES;
22519 ++
22520 ++ return 0;
22521 ++}
22522 +diff -Nurp linux-2.6.23.15/grsecurity/gracl_ip.c linux-2.6.23.15-grsec/grsecurity/gracl_ip.c
22523 +--- linux-2.6.23.15/grsecurity/gracl_ip.c 1970-01-01 01:00:00.000000000 +0100
22524 ++++ linux-2.6.23.15-grsec/grsecurity/gracl_ip.c 2008-02-11 10:37:44.000000000 +0000
22525 +@@ -0,0 +1,313 @@
22526 ++#include <linux/kernel.h>
22527 ++#include <asm/uaccess.h>
22528 ++#include <asm/errno.h>
22529 ++#include <net/sock.h>
22530 ++#include <linux/file.h>
22531 ++#include <linux/fs.h>
22532 ++#include <linux/net.h>
22533 ++#include <linux/in.h>
22534 ++#include <linux/skbuff.h>
22535 ++#include <linux/ip.h>
22536 ++#include <linux/udp.h>
22537 ++#include <linux/smp_lock.h>
22538 ++#include <linux/types.h>
22539 ++#include <linux/sched.h>
22540 ++#include <linux/netdevice.h>
22541 ++#include <linux/inetdevice.h>
22542 ++#include <linux/gracl.h>
22543 ++#include <linux/grsecurity.h>
22544 ++#include <linux/grinternal.h>
22545 ++
22546 ++#define GR_BIND 0x01
22547 ++#define GR_CONNECT 0x02
22548 ++#define GR_INVERT 0x04
22549 ++
22550 ++static const char * gr_protocols[256] = {
22551 ++ "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
22552 ++ "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
22553 ++ "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
22554 ++ "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
22555 ++ "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
22556 ++ "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
22557 ++ "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
22558 ++ "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
22559 ++ "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
22560 ++ "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
22561 ++ "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
22562 ++ "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
22563 ++ "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
22564 ++ "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
22565 ++ "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
22566 ++ "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
22567 ++ "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
22568 ++ "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
22569 ++ "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
22570 ++ "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
22571 ++ "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
22572 ++ "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
22573 ++ "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
22574 ++ "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
22575 ++ "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
22576 ++ "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
22577 ++ "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
22578 ++ "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
22579 ++ "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
22580 ++ "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
22581 ++ "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
22582 ++ "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
22583 ++ };
22584 ++
22585 ++static const char * gr_socktypes[11] = {
22586 ++ "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
22587 ++ "unknown:7", "unknown:8", "unknown:9", "packet"
22588 ++ };
22589 ++
22590 ++const char *
22591 ++gr_proto_to_name(unsigned char proto)
22592 ++{
22593 ++ return gr_protocols[proto];
22594 ++}
22595 ++
22596 ++const char *
22597 ++gr_socktype_to_name(unsigned char type)
22598 ++{
22599 ++ return gr_socktypes[type];
22600 ++}
22601 ++
22602 ++int
22603 ++gr_search_socket(const int domain, const int type, const int protocol)
22604 ++{
22605 ++ struct acl_subject_label *curr;
22606 ++
22607 ++ if (unlikely(!gr_acl_is_enabled()))
22608 ++ goto exit;
22609 ++
22610 ++ if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
22611 ++ || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
22612 ++ goto exit; // let the kernel handle it
22613 ++
22614 ++ curr = current->acl;
22615 ++
22616 ++ if (!curr->ips)
22617 ++ goto exit;
22618 ++
22619 ++ if ((curr->ip_type & (1 << type)) &&
22620 ++ (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
22621 ++ goto exit;
22622 ++
22623 ++ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
22624 ++ /* we don't place acls on raw sockets , and sometimes
22625 ++ dgram/ip sockets are opened for ioctl and not
22626 ++ bind/connect, so we'll fake a bind learn log */
22627 ++ if (type == SOCK_RAW || type == SOCK_PACKET) {
22628 ++ __u32 fakeip = 0;
22629 ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
22630 ++ current->role->roletype, current->uid,
22631 ++ current->gid, current->exec_file ?
22632 ++ gr_to_filename(current->exec_file->f_dentry,
22633 ++ current->exec_file->f_vfsmnt) :
22634 ++ curr->filename, curr->filename,
22635 ++ NIPQUAD(fakeip), 0, type,
22636 ++ protocol, GR_CONNECT,
22637 ++NIPQUAD(current->signal->curr_ip));
22638 ++ } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
22639 ++ __u32 fakeip = 0;
22640 ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
22641 ++ current->role->roletype, current->uid,
22642 ++ current->gid, current->exec_file ?
22643 ++ gr_to_filename(current->exec_file->f_dentry,
22644 ++ current->exec_file->f_vfsmnt) :
22645 ++ curr->filename, curr->filename,
22646 ++ NIPQUAD(fakeip), 0, type,
22647 ++ protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
22648 ++ }
22649 ++ /* we'll log when they use connect or bind */
22650 ++ goto exit;
22651 ++ }
22652 ++
22653 ++ gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet",
22654 ++ gr_socktype_to_name(type), gr_proto_to_name(protocol));
22655 ++
22656 ++ return 0;
22657 ++ exit:
22658 ++ return 1;
22659 ++}
22660 ++
22661 ++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)
22662 ++{
22663 ++ if ((ip->mode & mode) &&
22664 ++ (ip_port >= ip->low) &&
22665 ++ (ip_port <= ip->high) &&
22666 ++ ((ntohl(ip_addr) & our_netmask) ==
22667 ++ (ntohl(our_addr) & our_netmask))
22668 ++ && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
22669 ++ && (ip->type & (1 << type))) {
22670 ++ if (ip->mode & GR_INVERT)
22671 ++ return 2; // specifically denied
22672 ++ else
22673 ++ return 1; // allowed
22674 ++ }
22675 ++
22676 ++ return 0; // not specifically allowed, may continue parsing
22677 ++}
22678 ++
22679 ++static int
22680 ++gr_search_connectbind(const int mode, const struct sock *sk,
22681 ++ const struct sockaddr_in *addr, const int type)
22682 ++{
22683 ++ char iface[IFNAMSIZ] = {0};
22684 ++ struct acl_subject_label *curr;
22685 ++ struct acl_ip_label *ip;
22686 ++ struct net_device *dev;
22687 ++ struct in_device *idev;
22688 ++ unsigned long i;
22689 ++ int ret;
22690 ++ __u32 ip_addr = 0;
22691 ++ __u32 our_addr;
22692 ++ __u32 our_netmask;
22693 ++ char *p;
22694 ++ __u16 ip_port = 0;
22695 ++
22696 ++ if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
22697 ++ return 1;
22698 ++
22699 ++ curr = current->acl;
22700 ++
22701 ++ if (!curr->ips)
22702 ++ return 1;
22703 ++
22704 ++ ip_addr = addr->sin_addr.s_addr;
22705 ++ ip_port = ntohs(addr->sin_port);
22706 ++
22707 ++ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
22708 ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
22709 ++ current->role->roletype, current->uid,
22710 ++ current->gid, current->exec_file ?
22711 ++ gr_to_filename(current->exec_file->f_dentry,
22712 ++ current->exec_file->f_vfsmnt) :
22713 ++ curr->filename, curr->filename,
22714 ++ NIPQUAD(ip_addr), ip_port, type,
22715 ++ sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
22716 ++ return 1;
22717 ++ }
22718 ++
22719 ++ for (i = 0; i < curr->ip_num; i++) {
22720 ++ ip = *(curr->ips + i);
22721 ++ if (ip->iface != NULL) {
22722 ++ strncpy(iface, ip->iface, IFNAMSIZ - 1);
22723 ++ p = strchr(iface, ':');
22724 ++ if (p != NULL)
22725 ++ *p = '\0';
22726 ++ dev = dev_get_by_name(iface);
22727 ++ if (dev == NULL)
22728 ++ continue;
22729 ++ idev = in_dev_get(dev);
22730 ++ if (idev == NULL) {
22731 ++ dev_put(dev);
22732 ++ continue;
22733 ++ }
22734 ++ rcu_read_lock();
22735 ++ for_ifa(idev) {
22736 ++ if (!strcmp(ip->iface, ifa->ifa_label)) {
22737 ++ our_addr = ifa->ifa_address;
22738 ++ our_netmask = 0xffffffff;
22739 ++ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
22740 ++ if (ret == 1) {
22741 ++ rcu_read_unlock();
22742 ++ in_dev_put(idev);
22743 ++ dev_put(dev);
22744 ++ return 1;
22745 ++ } else if (ret == 2) {
22746 ++ rcu_read_unlock();
22747 ++ in_dev_put(idev);
22748 ++ dev_put(dev);
22749 ++ goto denied;
22750 ++ }
22751 ++ }
22752 ++ } endfor_ifa(idev);
22753 ++ rcu_read_unlock();
22754 ++ in_dev_put(idev);
22755 ++ dev_put(dev);
22756 ++ } else {
22757 ++ our_addr = ip->addr;
22758 ++ our_netmask = ip->netmask;
22759 ++ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
22760 ++ if (ret == 1)
22761 ++ return 1;
22762 ++ else if (ret == 2)
22763 ++ goto denied;
22764 ++ }
22765 ++ }
22766 ++
22767 ++denied:
22768 ++ if (mode == GR_BIND)
22769 ++ 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));
22770 ++ else if (mode == GR_CONNECT)
22771 ++ 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));
22772 ++
22773 ++ return 0;
22774 ++}
22775 ++
22776 ++int
22777 ++gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
22778 ++{
22779 ++ return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
22780 ++}
22781 ++
22782 ++int
22783 ++gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
22784 ++{
22785 ++ return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
22786 ++}
22787 ++
22788 ++int gr_search_listen(const struct socket *sock)
22789 ++{
22790 ++ struct sock *sk = sock->sk;
22791 ++ struct sockaddr_in addr;
22792 ++
22793 ++ addr.sin_addr.s_addr = inet_sk(sk)->saddr;
22794 ++ addr.sin_port = inet_sk(sk)->sport;
22795 ++
22796 ++ return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
22797 ++}
22798 ++
22799 ++int gr_search_accept(const struct socket *sock)
22800 ++{
22801 ++ struct sock *sk = sock->sk;
22802 ++ struct sockaddr_in addr;
22803 ++
22804 ++ addr.sin_addr.s_addr = inet_sk(sk)->saddr;
22805 ++ addr.sin_port = inet_sk(sk)->sport;
22806 ++
22807 ++ return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
22808 ++}
22809 ++
22810 ++int
22811 ++gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
22812 ++{
22813 ++ if (addr)
22814 ++ return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
22815 ++ else {
22816 ++ struct sockaddr_in sin;
22817 ++ const struct inet_sock *inet = inet_sk(sk);
22818 ++
22819 ++ sin.sin_addr.s_addr = inet->daddr;
22820 ++ sin.sin_port = inet->dport;
22821 ++
22822 ++ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
22823 ++ }
22824 ++}
22825 ++
22826 ++int
22827 ++gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
22828 ++{
22829 ++ struct sockaddr_in sin;
22830 ++
22831 ++ if (unlikely(skb->len < sizeof (struct udphdr)))
22832 ++ return 1; // skip this packet
22833 ++
22834 ++ sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
22835 ++ sin.sin_port = udp_hdr(skb)->source;
22836 ++
22837 ++ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
22838 ++}
22839 +diff -Nurp linux-2.6.23.15/grsecurity/gracl_learn.c linux-2.6.23.15-grsec/grsecurity/gracl_learn.c
22840 +--- linux-2.6.23.15/grsecurity/gracl_learn.c 1970-01-01 01:00:00.000000000 +0100
22841 ++++ linux-2.6.23.15-grsec/grsecurity/gracl_learn.c 2008-02-11 10:37:44.000000000 +0000
22842 +@@ -0,0 +1,211 @@
22843 ++#include <linux/kernel.h>
22844 ++#include <linux/mm.h>
22845 ++#include <linux/sched.h>
22846 ++#include <linux/poll.h>
22847 ++#include <linux/smp_lock.h>
22848 ++#include <linux/string.h>
22849 ++#include <linux/file.h>
22850 ++#include <linux/types.h>
22851 ++#include <linux/vmalloc.h>
22852 ++#include <linux/grinternal.h>
22853 ++
22854 ++extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
22855 ++ size_t count, loff_t *ppos);
22856 ++extern int gr_acl_is_enabled(void);
22857 ++
22858 ++static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
22859 ++static int gr_learn_attached;
22860 ++
22861 ++/* use a 512k buffer */
22862 ++#define LEARN_BUFFER_SIZE (512 * 1024)
22863 ++
22864 ++static spinlock_t gr_learn_lock = SPIN_LOCK_UNLOCKED;
22865 ++static DECLARE_MUTEX(gr_learn_user_sem);
22866 ++
22867 ++/* we need to maintain two buffers, so that the kernel context of grlearn
22868 ++ uses a semaphore around the userspace copying, and the other kernel contexts
22869 ++ use a spinlock when copying into the buffer, since they cannot sleep
22870 ++*/
22871 ++static char *learn_buffer;
22872 ++static char *learn_buffer_user;
22873 ++static int learn_buffer_len;
22874 ++static int learn_buffer_user_len;
22875 ++
22876 ++static ssize_t
22877 ++read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
22878 ++{
22879 ++ DECLARE_WAITQUEUE(wait, current);
22880 ++ ssize_t retval = 0;
22881 ++
22882 ++ add_wait_queue(&learn_wait, &wait);
22883 ++ set_current_state(TASK_INTERRUPTIBLE);
22884 ++ do {
22885 ++ down(&gr_learn_user_sem);
22886 ++ spin_lock(&gr_learn_lock);
22887 ++ if (learn_buffer_len)
22888 ++ break;
22889 ++ spin_unlock(&gr_learn_lock);
22890 ++ up(&gr_learn_user_sem);
22891 ++ if (file->f_flags & O_NONBLOCK) {
22892 ++ retval = -EAGAIN;
22893 ++ goto out;
22894 ++ }
22895 ++ if (signal_pending(current)) {
22896 ++ retval = -ERESTARTSYS;
22897 ++ goto out;
22898 ++ }
22899 ++
22900 ++ schedule();
22901 ++ } while (1);
22902 ++
22903 ++ memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
22904 ++ learn_buffer_user_len = learn_buffer_len;
22905 ++ retval = learn_buffer_len;
22906 ++ learn_buffer_len = 0;
22907 ++
22908 ++ spin_unlock(&gr_learn_lock);
22909 ++
22910 ++ if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
22911 ++ retval = -EFAULT;
22912 ++
22913 ++ up(&gr_learn_user_sem);
22914 ++out:
22915 ++ set_current_state(TASK_RUNNING);
22916 ++ remove_wait_queue(&learn_wait, &wait);
22917 ++ return retval;
22918 ++}
22919 ++
22920 ++static unsigned int
22921 ++poll_learn(struct file * file, poll_table * wait)
22922 ++{
22923 ++ poll_wait(file, &learn_wait, wait);
22924 ++
22925 ++ if (learn_buffer_len)
22926 ++ return (POLLIN | POLLRDNORM);
22927 ++
22928 ++ return 0;
22929 ++}
22930 ++
22931 ++void
22932 ++gr_clear_learn_entries(void)
22933 ++{
22934 ++ char *tmp;
22935 ++
22936 ++ down(&gr_learn_user_sem);
22937 ++ if (learn_buffer != NULL) {
22938 ++ spin_lock(&gr_learn_lock);
22939 ++ tmp = learn_buffer;
22940 ++ learn_buffer = NULL;
22941 ++ spin_unlock(&gr_learn_lock);
22942 ++ vfree(learn_buffer);
22943 ++ }
22944 ++ if (learn_buffer_user != NULL) {
22945 ++ vfree(learn_buffer_user);
22946 ++ learn_buffer_user = NULL;
22947 ++ }
22948 ++ learn_buffer_len = 0;
22949 ++ up(&gr_learn_user_sem);
22950 ++
22951 ++ return;
22952 ++}
22953 ++
22954 ++void
22955 ++gr_add_learn_entry(const char *fmt, ...)
22956 ++{
22957 ++ va_list args;
22958 ++ unsigned int len;
22959 ++
22960 ++ if (!gr_learn_attached)
22961 ++ return;
22962 ++
22963 ++ spin_lock(&gr_learn_lock);
22964 ++
22965 ++ /* leave a gap at the end so we know when it's "full" but don't have to
22966 ++ compute the exact length of the string we're trying to append
22967 ++ */
22968 ++ if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
22969 ++ spin_unlock(&gr_learn_lock);
22970 ++ wake_up_interruptible(&learn_wait);
22971 ++ return;
22972 ++ }
22973 ++ if (learn_buffer == NULL) {
22974 ++ spin_unlock(&gr_learn_lock);
22975 ++ return;
22976 ++ }
22977 ++
22978 ++ va_start(args, fmt);
22979 ++ len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
22980 ++ va_end(args);
22981 ++
22982 ++ learn_buffer_len += len + 1;
22983 ++
22984 ++ spin_unlock(&gr_learn_lock);
22985 ++ wake_up_interruptible(&learn_wait);
22986 ++
22987 ++ return;
22988 ++}
22989 ++
22990 ++static int
22991 ++open_learn(struct inode *inode, struct file *file)
22992 ++{
22993 ++ if (file->f_mode & FMODE_READ && gr_learn_attached)
22994 ++ return -EBUSY;
22995 ++ if (file->f_mode & FMODE_READ) {
22996 ++ int retval = 0;
22997 ++ down(&gr_learn_user_sem);
22998 ++ if (learn_buffer == NULL)
22999 ++ learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
23000 ++ if (learn_buffer_user == NULL)
23001 ++ learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
23002 ++ if (learn_buffer == NULL) {
23003 ++ retval = -ENOMEM;
23004 ++ goto out_error;
23005 ++ }
23006 ++ if (learn_buffer_user == NULL) {
23007 ++ retval = -ENOMEM;
23008 ++ goto out_error;
23009 ++ }
23010 ++ learn_buffer_len = 0;
23011 ++ learn_buffer_user_len = 0;
23012 ++ gr_learn_attached = 1;
23013 ++out_error:
23014 ++ up(&gr_learn_user_sem);
23015 ++ return retval;
23016 ++ }
23017 ++ return 0;
23018 ++}
23019 ++
23020 ++static int
23021 ++close_learn(struct inode *inode, struct file *file)
23022 ++{
23023 ++ char *tmp;
23024 ++
23025 ++ if (file->f_mode & FMODE_READ) {
23026 ++ down(&gr_learn_user_sem);
23027 ++ if (learn_buffer != NULL) {
23028 ++ spin_lock(&gr_learn_lock);
23029 ++ tmp = learn_buffer;
23030 ++ learn_buffer = NULL;
23031 ++ spin_unlock(&gr_learn_lock);
23032 ++ vfree(tmp);
23033 ++ }
23034 ++ if (learn_buffer_user != NULL) {
23035 ++ vfree(learn_buffer_user);
23036 ++ learn_buffer_user = NULL;
23037 ++ }
23038 ++ learn_buffer_len = 0;
23039 ++ learn_buffer_user_len = 0;
23040 ++ gr_learn_attached = 0;
23041 ++ up(&gr_learn_user_sem);
23042 ++ }
23043 ++
23044 ++ return 0;
23045 ++}
23046 ++
23047 ++struct file_operations grsec_fops = {
23048 ++ .read = read_learn,
23049 ++ .write = write_grsec_handler,
23050 ++ .open = open_learn,
23051 ++ .release = close_learn,
23052 ++ .poll = poll_learn,
23053 ++};
23054 +diff -Nurp linux-2.6.23.15/grsecurity/gracl_res.c linux-2.6.23.15-grsec/grsecurity/gracl_res.c
23055 +--- linux-2.6.23.15/grsecurity/gracl_res.c 1970-01-01 01:00:00.000000000 +0100
23056 ++++ linux-2.6.23.15-grsec/grsecurity/gracl_res.c 2008-02-11 10:37:44.000000000 +0000
23057 +@@ -0,0 +1,45 @@
23058 ++#include <linux/kernel.h>
23059 ++#include <linux/sched.h>
23060 ++#include <linux/gracl.h>
23061 ++#include <linux/grinternal.h>
23062 ++
23063 ++static const char *restab_log[] = {
23064 ++ [RLIMIT_CPU] = "RLIMIT_CPU",
23065 ++ [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
23066 ++ [RLIMIT_DATA] = "RLIMIT_DATA",
23067 ++ [RLIMIT_STACK] = "RLIMIT_STACK",
23068 ++ [RLIMIT_CORE] = "RLIMIT_CORE",
23069 ++ [RLIMIT_RSS] = "RLIMIT_RSS",
23070 ++ [RLIMIT_NPROC] = "RLIMIT_NPROC",
23071 ++ [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
23072 ++ [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
23073 ++ [RLIMIT_AS] = "RLIMIT_AS",
23074 ++ [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
23075 ++ [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH"
23076 ++};
23077 ++
23078 ++void
23079 ++gr_log_resource(const struct task_struct *task,
23080 ++ const int res, const unsigned long wanted, const int gt)
23081 ++{
23082 ++ if (res == RLIMIT_NPROC &&
23083 ++ (cap_raised(task->cap_effective, CAP_SYS_ADMIN) ||
23084 ++ cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
23085 ++ return;
23086 ++ else if (res == RLIMIT_MEMLOCK &&
23087 ++ cap_raised(task->cap_effective, CAP_IPC_LOCK))
23088 ++ return;
23089 ++
23090 ++ if (!gr_acl_is_enabled() && !grsec_resource_logging)
23091 ++ return;
23092 ++
23093 ++ preempt_disable();
23094 ++
23095 ++ if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
23096 ++ (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
23097 ++ task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
23098 ++ gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
23099 ++ preempt_enable_no_resched();
23100 ++
23101 ++ return;
23102 ++}
23103 +diff -Nurp linux-2.6.23.15/grsecurity/gracl_segv.c linux-2.6.23.15-grsec/grsecurity/gracl_segv.c
23104 +--- linux-2.6.23.15/grsecurity/gracl_segv.c 1970-01-01 01:00:00.000000000 +0100
23105 ++++ linux-2.6.23.15-grsec/grsecurity/gracl_segv.c 2008-02-11 10:37:44.000000000 +0000
23106 +@@ -0,0 +1,301 @@
23107 ++#include <linux/kernel.h>
23108 ++#include <linux/mm.h>
23109 ++#include <asm/uaccess.h>
23110 ++#include <asm/errno.h>
23111 ++#include <asm/mman.h>
23112 ++#include <net/sock.h>
23113 ++#include <linux/file.h>
23114 ++#include <linux/fs.h>
23115 ++#include <linux/net.h>
23116 ++#include <linux/in.h>
23117 ++#include <linux/smp_lock.h>
23118 ++#include <linux/slab.h>
23119 ++#include <linux/types.h>
23120 ++#include <linux/sched.h>
23121 ++#include <linux/timer.h>
23122 ++#include <linux/gracl.h>
23123 ++#include <linux/grsecurity.h>
23124 ++#include <linux/grinternal.h>
23125 ++
23126 ++static struct crash_uid *uid_set;
23127 ++static unsigned short uid_used;
23128 ++static spinlock_t gr_uid_lock = SPIN_LOCK_UNLOCKED;
23129 ++extern rwlock_t gr_inode_lock;
23130 ++extern struct acl_subject_label *
23131 ++ lookup_acl_subj_label(const ino_t inode, const dev_t dev,
23132 ++ struct acl_role_label *role);
23133 ++extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
23134 ++
23135 ++int
23136 ++gr_init_uidset(void)
23137 ++{
23138 ++ uid_set =
23139 ++ kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
23140 ++ uid_used = 0;
23141 ++
23142 ++ return uid_set ? 1 : 0;
23143 ++}
23144 ++
23145 ++void
23146 ++gr_free_uidset(void)
23147 ++{
23148 ++ if (uid_set)
23149 ++ kfree(uid_set);
23150 ++
23151 ++ return;
23152 ++}
23153 ++
23154 ++int
23155 ++gr_find_uid(const uid_t uid)
23156 ++{
23157 ++ struct crash_uid *tmp = uid_set;
23158 ++ uid_t buid;
23159 ++ int low = 0, high = uid_used - 1, mid;
23160 ++
23161 ++ while (high >= low) {
23162 ++ mid = (low + high) >> 1;
23163 ++ buid = tmp[mid].uid;
23164 ++ if (buid == uid)
23165 ++ return mid;
23166 ++ if (buid > uid)
23167 ++ high = mid - 1;
23168 ++ if (buid < uid)
23169 ++ low = mid + 1;
23170 ++ }
23171 ++
23172 ++ return -1;
23173 ++}
23174 ++
23175 ++static __inline__ void
23176 ++gr_insertsort(void)
23177 ++{
23178 ++ unsigned short i, j;
23179 ++ struct crash_uid index;
23180 ++
23181 ++ for (i = 1; i < uid_used; i++) {
23182 ++ index = uid_set[i];
23183 ++ j = i;
23184 ++ while ((j > 0) && uid_set[j - 1].uid > index.uid) {
23185 ++ uid_set[j] = uid_set[j - 1];
23186 ++ j--;
23187 ++ }
23188 ++ uid_set[j] = index;
23189 ++ }
23190 ++
23191 ++ return;
23192 ++}
23193 ++
23194 ++static __inline__ void
23195 ++gr_insert_uid(const uid_t uid, const unsigned long expires)
23196 ++{
23197 ++ int loc;
23198 ++
23199 ++ if (uid_used == GR_UIDTABLE_MAX)
23200 ++ return;
23201 ++
23202 ++ loc = gr_find_uid(uid);
23203 ++
23204 ++ if (loc >= 0) {
23205 ++ uid_set[loc].expires = expires;
23206 ++ return;
23207 ++ }
23208 ++
23209 ++ uid_set[uid_used].uid = uid;
23210 ++ uid_set[uid_used].expires = expires;
23211 ++ uid_used++;
23212 ++
23213 ++ gr_insertsort();
23214 ++
23215 ++ return;
23216 ++}
23217 ++
23218 ++void
23219 ++gr_remove_uid(const unsigned short loc)
23220 ++{
23221 ++ unsigned short i;
23222 ++
23223 ++ for (i = loc + 1; i < uid_used; i++)
23224 ++ uid_set[i - 1] = uid_set[i];
23225 ++
23226 ++ uid_used--;
23227 ++
23228 ++ return;
23229 ++}
23230 ++
23231 ++int
23232 ++gr_check_crash_uid(const uid_t uid)
23233 ++{
23234 ++ int loc;
23235 ++ int ret = 0;
23236 ++
23237 ++ if (unlikely(!gr_acl_is_enabled()))
23238 ++ return 0;
23239 ++
23240 ++ spin_lock(&gr_uid_lock);
23241 ++ loc = gr_find_uid(uid);
23242 ++
23243 ++ if (loc < 0)
23244 ++ goto out_unlock;
23245 ++
23246 ++ if (time_before_eq(uid_set[loc].expires, get_seconds()))
23247 ++ gr_remove_uid(loc);
23248 ++ else
23249 ++ ret = 1;
23250 ++
23251 ++out_unlock:
23252 ++ spin_unlock(&gr_uid_lock);
23253 ++ return ret;
23254 ++}
23255 ++
23256 ++static __inline__ int
23257 ++proc_is_setxid(const struct task_struct *task)
23258 ++{
23259 ++ if (task->uid != task->euid || task->uid != task->suid ||
23260 ++ task->uid != task->fsuid)
23261 ++ return 1;
23262 ++ if (task->gid != task->egid || task->gid != task->sgid ||
23263 ++ task->gid != task->fsgid)
23264 ++ return 1;
23265 ++
23266 ++ return 0;
23267 ++}
23268 ++static __inline__ int
23269 ++gr_fake_force_sig(int sig, struct task_struct *t)
23270 ++{
23271 ++ unsigned long int flags;
23272 ++ int ret, blocked, ignored;
23273 ++ struct k_sigaction *action;
23274 ++
23275 ++ spin_lock_irqsave(&t->sighand->siglock, flags);
23276 ++ action = &t->sighand->action[sig-1];
23277 ++ ignored = action->sa.sa_handler == SIG_IGN;
23278 ++ blocked = sigismember(&t->blocked, sig);
23279 ++ if (blocked || ignored) {
23280 ++ action->sa.sa_handler = SIG_DFL;
23281 ++ if (blocked) {
23282 ++ sigdelset(&t->blocked, sig);
23283 ++ recalc_sigpending_and_wake(t);
23284 ++ }
23285 ++ }
23286 ++ ret = specific_send_sig_info(sig, (void*)1L, t);
23287 ++ spin_unlock_irqrestore(&t->sighand->siglock, flags);
23288 ++
23289 ++ return ret;
23290 ++}
23291 ++
23292 ++void
23293 ++gr_handle_crash(struct task_struct *task, const int sig)
23294 ++{
23295 ++ struct acl_subject_label *curr;
23296 ++ struct acl_subject_label *curr2;
23297 ++ struct task_struct *tsk, *tsk2;
23298 ++
23299 ++ if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
23300 ++ return;
23301 ++
23302 ++ if (unlikely(!gr_acl_is_enabled()))
23303 ++ return;
23304 ++
23305 ++ curr = task->acl;
23306 ++
23307 ++ if (!(curr->resmask & (1 << GR_CRASH_RES)))
23308 ++ return;
23309 ++
23310 ++ if (time_before_eq(curr->expires, get_seconds())) {
23311 ++ curr->expires = 0;
23312 ++ curr->crashes = 0;
23313 ++ }
23314 ++
23315 ++ curr->crashes++;
23316 ++
23317 ++ if (!curr->expires)
23318 ++ curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
23319 ++
23320 ++ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
23321 ++ time_after(curr->expires, get_seconds())) {
23322 ++ if (task->uid && proc_is_setxid(task)) {
23323 ++ gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
23324 ++ spin_lock(&gr_uid_lock);
23325 ++ gr_insert_uid(task->uid, curr->expires);
23326 ++ spin_unlock(&gr_uid_lock);
23327 ++ curr->expires = 0;
23328 ++ curr->crashes = 0;
23329 ++ read_lock(&tasklist_lock);
23330 ++ do_each_thread(tsk2, tsk) {
23331 ++ if (tsk != task && tsk->uid == task->uid)
23332 ++ gr_fake_force_sig(SIGKILL, tsk);
23333 ++ } while_each_thread(tsk2, tsk);
23334 ++ read_unlock(&tasklist_lock);
23335 ++ } else {
23336 ++ gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
23337 ++ read_lock(&tasklist_lock);
23338 ++ do_each_thread(tsk2, tsk) {
23339 ++ if (likely(tsk != task)) {
23340 ++ curr2 = tsk->acl;
23341 ++
23342 ++ if (curr2->device == curr->device &&
23343 ++ curr2->inode == curr->inode)
23344 ++ gr_fake_force_sig(SIGKILL, tsk);
23345 ++ }
23346 ++ } while_each_thread(tsk2, tsk);
23347 ++ read_unlock(&tasklist_lock);
23348 ++ }
23349 ++ }
23350 ++
23351 ++ return;
23352 ++}
23353 ++
23354 ++int
23355 ++gr_check_crash_exec(const struct file *filp)
23356 ++{
23357 ++ struct acl_subject_label *curr;
23358 ++
23359 ++ if (unlikely(!gr_acl_is_enabled()))
23360 ++ return 0;
23361 ++
23362 ++ read_lock(&gr_inode_lock);
23363 ++ curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino,
23364 ++ filp->f_dentry->d_inode->i_sb->s_dev,
23365 ++ current->role);
23366 ++ read_unlock(&gr_inode_lock);
23367 ++
23368 ++ if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
23369 ++ (!curr->crashes && !curr->expires))
23370 ++ return 0;
23371 ++
23372 ++ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
23373 ++ time_after(curr->expires, get_seconds()))
23374 ++ return 1;
23375 ++ else if (time_before_eq(curr->expires, get_seconds())) {
23376 ++ curr->crashes = 0;
23377 ++ curr->expires = 0;
23378 ++ }
23379 ++
23380 ++ return 0;
23381 ++}
23382 ++
23383 ++void
23384 ++gr_handle_alertkill(struct task_struct *task)
23385 ++{
23386 ++ struct acl_subject_label *curracl;
23387 ++ __u32 curr_ip;
23388 ++ struct task_struct *p, *p2;
23389 ++
23390 ++ if (unlikely(!gr_acl_is_enabled()))
23391 ++ return;
23392 ++
23393 ++ curracl = task->acl;
23394 ++ curr_ip = task->signal->curr_ip;
23395 ++
23396 ++ if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
23397 ++ read_lock(&tasklist_lock);
23398 ++ do_each_thread(p2, p) {
23399 ++ if (p->signal->curr_ip == curr_ip)
23400 ++ gr_fake_force_sig(SIGKILL, p);
23401 ++ } while_each_thread(p2, p);
23402 ++ read_unlock(&tasklist_lock);
23403 ++ } else if (curracl->mode & GR_KILLPROC)
23404 ++ gr_fake_force_sig(SIGKILL, task);
23405 ++
23406 ++ return;
23407 ++}
23408 +diff -Nurp linux-2.6.23.15/grsecurity/gracl_shm.c linux-2.6.23.15-grsec/grsecurity/gracl_shm.c
23409 +--- linux-2.6.23.15/grsecurity/gracl_shm.c 1970-01-01 01:00:00.000000000 +0100
23410 ++++ linux-2.6.23.15-grsec/grsecurity/gracl_shm.c 2008-02-11 10:37:44.000000000 +0000
23411 +@@ -0,0 +1,33 @@
23412 ++#include <linux/kernel.h>
23413 ++#include <linux/mm.h>
23414 ++#include <linux/sched.h>
23415 ++#include <linux/file.h>
23416 ++#include <linux/ipc.h>
23417 ++#include <linux/gracl.h>
23418 ++#include <linux/grsecurity.h>
23419 ++#include <linux/grinternal.h>
23420 ++
23421 ++int
23422 ++gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
23423 ++ const time_t shm_createtime, const uid_t cuid, const int shmid)
23424 ++{
23425 ++ struct task_struct *task;
23426 ++
23427 ++ if (!gr_acl_is_enabled())
23428 ++ return 1;
23429 ++
23430 ++ task = find_task_by_pid(shm_cprid);
23431 ++
23432 ++ if (unlikely(!task))
23433 ++ task = find_task_by_pid(shm_lapid);
23434 ++
23435 ++ if (unlikely(task && (time_before((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
23436 ++ (task->pid == shm_lapid)) &&
23437 ++ (task->acl->mode & GR_PROTSHM) &&
23438 ++ (task->acl != current->acl))) {
23439 ++ gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
23440 ++ return 0;
23441 ++ }
23442 ++
23443 ++ return 1;
23444 ++}
23445 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_chdir.c linux-2.6.23.15-grsec/grsecurity/grsec_chdir.c
23446 +--- linux-2.6.23.15/grsecurity/grsec_chdir.c 1970-01-01 01:00:00.000000000 +0100
23447 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_chdir.c 2008-02-11 10:37:44.000000000 +0000
23448 +@@ -0,0 +1,19 @@
23449 ++#include <linux/kernel.h>
23450 ++#include <linux/sched.h>
23451 ++#include <linux/fs.h>
23452 ++#include <linux/file.h>
23453 ++#include <linux/grsecurity.h>
23454 ++#include <linux/grinternal.h>
23455 ++
23456 ++void
23457 ++gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
23458 ++{
23459 ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
23460 ++ if ((grsec_enable_chdir && grsec_enable_group &&
23461 ++ in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
23462 ++ !grsec_enable_group)) {
23463 ++ gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
23464 ++ }
23465 ++#endif
23466 ++ return;
23467 ++}
23468 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_chroot.c linux-2.6.23.15-grsec/grsecurity/grsec_chroot.c
23469 +--- linux-2.6.23.15/grsecurity/grsec_chroot.c 1970-01-01 01:00:00.000000000 +0100
23470 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_chroot.c 2008-02-11 10:37:44.000000000 +0000
23471 +@@ -0,0 +1,335 @@
23472 ++#include <linux/kernel.h>
23473 ++#include <linux/module.h>
23474 ++#include <linux/sched.h>
23475 ++#include <linux/file.h>
23476 ++#include <linux/fs.h>
23477 ++#include <linux/mount.h>
23478 ++#include <linux/types.h>
23479 ++#include <linux/pid_namespace.h>
23480 ++#include <linux/grsecurity.h>
23481 ++#include <linux/grinternal.h>
23482 ++
23483 ++int
23484 ++gr_handle_chroot_unix(const pid_t pid)
23485 ++{
23486 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
23487 ++ struct pid *spid = NULL;
23488 ++
23489 ++ if (unlikely(!grsec_enable_chroot_unix))
23490 ++ return 1;
23491 ++
23492 ++ if (likely(!proc_is_chrooted(current)))
23493 ++ return 1;
23494 ++
23495 ++ read_lock(&tasklist_lock);
23496 ++
23497 ++ spid = find_pid(pid);
23498 ++ if (spid) {
23499 ++ struct task_struct *p;
23500 ++ p = pid_task(spid, PIDTYPE_PID);
23501 ++ task_lock(p);
23502 ++ if (unlikely(!have_same_root(current, p))) {
23503 ++ task_unlock(p);
23504 ++ read_unlock(&tasklist_lock);
23505 ++ gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
23506 ++ return 0;
23507 ++ }
23508 ++ task_unlock(p);
23509 ++ }
23510 ++ read_unlock(&tasklist_lock);
23511 ++#endif
23512 ++ return 1;
23513 ++}
23514 ++
23515 ++int
23516 ++gr_handle_chroot_nice(void)
23517 ++{
23518 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
23519 ++ if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
23520 ++ gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
23521 ++ return -EPERM;
23522 ++ }
23523 ++#endif
23524 ++ return 0;
23525 ++}
23526 ++
23527 ++int
23528 ++gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
23529 ++{
23530 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
23531 ++ if (grsec_enable_chroot_nice && (niceval < task_nice(p))
23532 ++ && proc_is_chrooted(current)) {
23533 ++ gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
23534 ++ return -EACCES;
23535 ++ }
23536 ++#endif
23537 ++ return 0;
23538 ++}
23539 ++
23540 ++int
23541 ++gr_handle_chroot_rawio(const struct inode *inode)
23542 ++{
23543 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
23544 ++ if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
23545 ++ inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
23546 ++ return 1;
23547 ++#endif
23548 ++ return 0;
23549 ++}
23550 ++
23551 ++int
23552 ++gr_pid_is_chrooted(struct task_struct *p)
23553 ++{
23554 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
23555 ++ if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL)
23556 ++ return 0;
23557 ++
23558 ++ task_lock(p);
23559 ++ if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
23560 ++ !have_same_root(current, p)) {
23561 ++ task_unlock(p);
23562 ++ return 1;
23563 ++ }
23564 ++ task_unlock(p);
23565 ++#endif
23566 ++ return 0;
23567 ++}
23568 ++
23569 ++EXPORT_SYMBOL(gr_pid_is_chrooted);
23570 ++
23571 ++#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
23572 ++int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
23573 ++{
23574 ++ struct dentry *dentry = (struct dentry *)u_dentry;
23575 ++ struct vfsmount *mnt = (struct vfsmount *)u_mnt;
23576 ++ struct dentry *realroot;
23577 ++ struct vfsmount *realrootmnt;
23578 ++ struct dentry *currentroot;
23579 ++ struct vfsmount *currentmnt;
23580 ++ struct task_struct *reaper = child_reaper(current);
23581 ++ int ret = 1;
23582 ++
23583 ++ read_lock(&reaper->fs->lock);
23584 ++ realrootmnt = mntget(reaper->fs->rootmnt);
23585 ++ realroot = dget(reaper->fs->root);
23586 ++ read_unlock(&reaper->fs->lock);
23587 ++
23588 ++ read_lock(&current->fs->lock);
23589 ++ currentmnt = mntget(current->fs->rootmnt);
23590 ++ currentroot = dget(current->fs->root);
23591 ++ read_unlock(&current->fs->lock);
23592 ++
23593 ++ spin_lock(&dcache_lock);
23594 ++ for (;;) {
23595 ++ if (unlikely((dentry == realroot && mnt == realrootmnt)
23596 ++ || (dentry == currentroot && mnt == currentmnt)))
23597 ++ break;
23598 ++ if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
23599 ++ if (mnt->mnt_parent == mnt)
23600 ++ break;
23601 ++ dentry = mnt->mnt_mountpoint;
23602 ++ mnt = mnt->mnt_parent;
23603 ++ continue;
23604 ++ }
23605 ++ dentry = dentry->d_parent;
23606 ++ }
23607 ++ spin_unlock(&dcache_lock);
23608 ++
23609 ++ dput(currentroot);
23610 ++ mntput(currentmnt);
23611 ++
23612 ++ /* access is outside of chroot */
23613 ++ if (dentry == realroot && mnt == realrootmnt)
23614 ++ ret = 0;
23615 ++
23616 ++ dput(realroot);
23617 ++ mntput(realrootmnt);
23618 ++ return ret;
23619 ++}
23620 ++#endif
23621 ++
23622 ++int
23623 ++gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
23624 ++{
23625 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
23626 ++ if (!grsec_enable_chroot_fchdir)
23627 ++ return 1;
23628 ++
23629 ++ if (!proc_is_chrooted(current))
23630 ++ return 1;
23631 ++ else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
23632 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
23633 ++ return 0;
23634 ++ }
23635 ++#endif
23636 ++ return 1;
23637 ++}
23638 ++
23639 ++int
23640 ++gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
23641 ++ const time_t shm_createtime)
23642 ++{
23643 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
23644 ++ struct pid *pid = NULL;
23645 ++ time_t starttime;
23646 ++
23647 ++ if (unlikely(!grsec_enable_chroot_shmat))
23648 ++ return 1;
23649 ++
23650 ++ if (likely(!proc_is_chrooted(current)))
23651 ++ return 1;
23652 ++
23653 ++ read_lock(&tasklist_lock);
23654 ++
23655 ++ pid = find_pid(shm_cprid);
23656 ++ if (pid) {
23657 ++ struct task_struct *p;
23658 ++ p = pid_task(pid, PIDTYPE_PID);
23659 ++ task_lock(p);
23660 ++ starttime = p->start_time.tv_sec;
23661 ++ if (unlikely(!have_same_root(current, p) &&
23662 ++ time_before((unsigned long)starttime, (unsigned long)shm_createtime))) {
23663 ++ task_unlock(p);
23664 ++ read_unlock(&tasklist_lock);
23665 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
23666 ++ return 0;
23667 ++ }
23668 ++ task_unlock(p);
23669 ++ } else {
23670 ++ pid = find_pid(shm_lapid);
23671 ++ if (pid) {
23672 ++ struct task_struct *p;
23673 ++ p = pid_task(pid, PIDTYPE_PID);
23674 ++ task_lock(p);
23675 ++ if (unlikely(!have_same_root(current, p))) {
23676 ++ task_unlock(p);
23677 ++ read_unlock(&tasklist_lock);
23678 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
23679 ++ return 0;
23680 ++ }
23681 ++ task_unlock(p);
23682 ++ }
23683 ++ }
23684 ++
23685 ++ read_unlock(&tasklist_lock);
23686 ++#endif
23687 ++ return 1;
23688 ++}
23689 ++
23690 ++void
23691 ++gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
23692 ++{
23693 ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
23694 ++ if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
23695 ++ gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
23696 ++#endif
23697 ++ return;
23698 ++}
23699 ++
23700 ++int
23701 ++gr_handle_chroot_mknod(const struct dentry *dentry,
23702 ++ const struct vfsmount *mnt, const int mode)
23703 ++{
23704 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
23705 ++ if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) &&
23706 ++ proc_is_chrooted(current)) {
23707 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
23708 ++ return -EPERM;
23709 ++ }
23710 ++#endif
23711 ++ return 0;
23712 ++}
23713 ++
23714 ++int
23715 ++gr_handle_chroot_mount(const struct dentry *dentry,
23716 ++ const struct vfsmount *mnt, const char *dev_name)
23717 ++{
23718 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
23719 ++ if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
23720 ++ gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
23721 ++ return -EPERM;
23722 ++ }
23723 ++#endif
23724 ++ return 0;
23725 ++}
23726 ++
23727 ++int
23728 ++gr_handle_chroot_pivot(void)
23729 ++{
23730 ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
23731 ++ if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
23732 ++ gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
23733 ++ return -EPERM;
23734 ++ }
23735 ++#endif
23736 ++ return 0;
23737 ++}
23738 ++
23739 ++int
23740 ++gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
23741 ++{
23742 ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
23743 ++ if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
23744 ++ !gr_is_outside_chroot(dentry, mnt)) {
23745 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
23746 ++ return -EPERM;
23747 ++ }
23748 ++#endif
23749 ++ return 0;
23750 ++}
23751 ++
23752 ++void
23753 ++gr_handle_chroot_caps(struct task_struct *task)
23754 ++{
23755 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
23756 ++ if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
23757 ++ task->cap_permitted =
23758 ++ cap_drop(task->cap_permitted, GR_CHROOT_CAPS);
23759 ++ task->cap_inheritable =
23760 ++ cap_drop(task->cap_inheritable, GR_CHROOT_CAPS);
23761 ++ task->cap_effective =
23762 ++ cap_drop(task->cap_effective, GR_CHROOT_CAPS);
23763 ++ }
23764 ++#endif
23765 ++ return;
23766 ++}
23767 ++
23768 ++int
23769 ++gr_handle_chroot_sysctl(const int op)
23770 ++{
23771 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
23772 ++ if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
23773 ++ && (op & 002))
23774 ++ return -EACCES;
23775 ++#endif
23776 ++ return 0;
23777 ++}
23778 ++
23779 ++void
23780 ++gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt)
23781 ++{
23782 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
23783 ++ if (grsec_enable_chroot_chdir)
23784 ++ set_fs_pwd(current->fs, mnt, dentry);
23785 ++#endif
23786 ++ return;
23787 ++}
23788 ++
23789 ++int
23790 ++gr_handle_chroot_chmod(const struct dentry *dentry,
23791 ++ const struct vfsmount *mnt, const int mode)
23792 ++{
23793 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
23794 ++ if (grsec_enable_chroot_chmod &&
23795 ++ ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
23796 ++ proc_is_chrooted(current)) {
23797 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
23798 ++ return -EPERM;
23799 ++ }
23800 ++#endif
23801 ++ return 0;
23802 ++}
23803 ++
23804 ++#ifdef CONFIG_SECURITY
23805 ++EXPORT_SYMBOL(gr_handle_chroot_caps);
23806 ++#endif
23807 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_disabled.c linux-2.6.23.15-grsec/grsecurity/grsec_disabled.c
23808 +--- linux-2.6.23.15/grsecurity/grsec_disabled.c 1970-01-01 01:00:00.000000000 +0100
23809 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_disabled.c 2008-02-11 10:37:44.000000000 +0000
23810 +@@ -0,0 +1,418 @@
23811 ++#include <linux/kernel.h>
23812 ++#include <linux/module.h>
23813 ++#include <linux/sched.h>
23814 ++#include <linux/file.h>
23815 ++#include <linux/fs.h>
23816 ++#include <linux/kdev_t.h>
23817 ++#include <linux/net.h>
23818 ++#include <linux/in.h>
23819 ++#include <linux/ip.h>
23820 ++#include <linux/skbuff.h>
23821 ++#include <linux/sysctl.h>
23822 ++
23823 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
23824 ++void
23825 ++pax_set_initial_flags(struct linux_binprm *bprm)
23826 ++{
23827 ++ return;
23828 ++}
23829 ++#endif
23830 ++
23831 ++#ifdef CONFIG_SYSCTL
23832 ++__u32
23833 ++gr_handle_sysctl(const struct ctl_table * table, const int op)
23834 ++{
23835 ++ return 0;
23836 ++}
23837 ++#endif
23838 ++
23839 ++int
23840 ++gr_acl_is_enabled(void)
23841 ++{
23842 ++ return 0;
23843 ++}
23844 ++
23845 ++int
23846 ++gr_handle_rawio(const struct inode *inode)
23847 ++{
23848 ++ return 0;
23849 ++}
23850 ++
23851 ++void
23852 ++gr_acl_handle_psacct(struct task_struct *task, const long code)
23853 ++{
23854 ++ return;
23855 ++}
23856 ++
23857 ++int
23858 ++gr_handle_ptrace(struct task_struct *task, const long request)
23859 ++{
23860 ++ return 0;
23861 ++}
23862 ++
23863 ++int
23864 ++gr_handle_proc_ptrace(struct task_struct *task)
23865 ++{
23866 ++ return 0;
23867 ++}
23868 ++
23869 ++void
23870 ++gr_learn_resource(const struct task_struct *task,
23871 ++ const int res, const unsigned long wanted, const int gt)
23872 ++{
23873 ++ return;
23874 ++}
23875 ++
23876 ++int
23877 ++gr_set_acls(const int type)
23878 ++{
23879 ++ return 0;
23880 ++}
23881 ++
23882 ++int
23883 ++gr_check_hidden_task(const struct task_struct *tsk)
23884 ++{
23885 ++ return 0;
23886 ++}
23887 ++
23888 ++int
23889 ++gr_check_protected_task(const struct task_struct *task)
23890 ++{
23891 ++ return 0;
23892 ++}
23893 ++
23894 ++void
23895 ++gr_copy_label(struct task_struct *tsk)
23896 ++{
23897 ++ return;
23898 ++}
23899 ++
23900 ++void
23901 ++gr_set_pax_flags(struct task_struct *task)
23902 ++{
23903 ++ return;
23904 ++}
23905 ++
23906 ++int
23907 ++gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
23908 ++{
23909 ++ return 0;
23910 ++}
23911 ++
23912 ++void
23913 ++gr_handle_delete(const ino_t ino, const dev_t dev)
23914 ++{
23915 ++ return;
23916 ++}
23917 ++
23918 ++void
23919 ++gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
23920 ++{
23921 ++ return;
23922 ++}
23923 ++
23924 ++void
23925 ++gr_handle_crash(struct task_struct *task, const int sig)
23926 ++{
23927 ++ return;
23928 ++}
23929 ++
23930 ++int
23931 ++gr_check_crash_exec(const struct file *filp)
23932 ++{
23933 ++ return 0;
23934 ++}
23935 ++
23936 ++int
23937 ++gr_check_crash_uid(const uid_t uid)
23938 ++{
23939 ++ return 0;
23940 ++}
23941 ++
23942 ++void
23943 ++gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
23944 ++ struct dentry *old_dentry,
23945 ++ struct dentry *new_dentry,
23946 ++ struct vfsmount *mnt, const __u8 replace)
23947 ++{
23948 ++ return;
23949 ++}
23950 ++
23951 ++int
23952 ++gr_search_socket(const int family, const int type, const int protocol)
23953 ++{
23954 ++ return 1;
23955 ++}
23956 ++
23957 ++int
23958 ++gr_search_connectbind(const int mode, const struct socket *sock,
23959 ++ const struct sockaddr_in *addr)
23960 ++{
23961 ++ return 1;
23962 ++}
23963 ++
23964 ++int
23965 ++gr_task_is_capable(struct task_struct *task, const int cap)
23966 ++{
23967 ++ return 1;
23968 ++}
23969 ++
23970 ++int
23971 ++gr_is_capable_nolog(const int cap)
23972 ++{
23973 ++ return 1;
23974 ++}
23975 ++
23976 ++void
23977 ++gr_handle_alertkill(struct task_struct *task)
23978 ++{
23979 ++ return;
23980 ++}
23981 ++
23982 ++__u32
23983 ++gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
23984 ++{
23985 ++ return 1;
23986 ++}
23987 ++
23988 ++__u32
23989 ++gr_acl_handle_hidden_file(const struct dentry * dentry,
23990 ++ const struct vfsmount * mnt)
23991 ++{
23992 ++ return 1;
23993 ++}
23994 ++
23995 ++__u32
23996 ++gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
23997 ++ const int fmode)
23998 ++{
23999 ++ return 1;
24000 ++}
24001 ++
24002 ++__u32
24003 ++gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
24004 ++{
24005 ++ return 1;
24006 ++}
24007 ++
24008 ++__u32
24009 ++gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
24010 ++{
24011 ++ return 1;
24012 ++}
24013 ++
24014 ++int
24015 ++gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
24016 ++ unsigned int *vm_flags)
24017 ++{
24018 ++ return 1;
24019 ++}
24020 ++
24021 ++__u32
24022 ++gr_acl_handle_truncate(const struct dentry * dentry,
24023 ++ const struct vfsmount * mnt)
24024 ++{
24025 ++ return 1;
24026 ++}
24027 ++
24028 ++__u32
24029 ++gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
24030 ++{
24031 ++ return 1;
24032 ++}
24033 ++
24034 ++__u32
24035 ++gr_acl_handle_access(const struct dentry * dentry,
24036 ++ const struct vfsmount * mnt, const int fmode)
24037 ++{
24038 ++ return 1;
24039 ++}
24040 ++
24041 ++__u32
24042 ++gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
24043 ++ mode_t mode)
24044 ++{
24045 ++ return 1;
24046 ++}
24047 ++
24048 ++__u32
24049 ++gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
24050 ++ mode_t mode)
24051 ++{
24052 ++ return 1;
24053 ++}
24054 ++
24055 ++__u32
24056 ++gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
24057 ++{
24058 ++ return 1;
24059 ++}
24060 ++
24061 ++void
24062 ++grsecurity_init(void)
24063 ++{
24064 ++ return;
24065 ++}
24066 ++
24067 ++__u32
24068 ++gr_acl_handle_mknod(const struct dentry * new_dentry,
24069 ++ const struct dentry * parent_dentry,
24070 ++ const struct vfsmount * parent_mnt,
24071 ++ const int mode)
24072 ++{
24073 ++ return 1;
24074 ++}
24075 ++
24076 ++__u32
24077 ++gr_acl_handle_mkdir(const struct dentry * new_dentry,
24078 ++ const struct dentry * parent_dentry,
24079 ++ const struct vfsmount * parent_mnt)
24080 ++{
24081 ++ return 1;
24082 ++}
24083 ++
24084 ++__u32
24085 ++gr_acl_handle_symlink(const struct dentry * new_dentry,
24086 ++ const struct dentry * parent_dentry,
24087 ++ const struct vfsmount * parent_mnt, const char *from)
24088 ++{
24089 ++ return 1;
24090 ++}
24091 ++
24092 ++__u32
24093 ++gr_acl_handle_link(const struct dentry * new_dentry,
24094 ++ const struct dentry * parent_dentry,
24095 ++ const struct vfsmount * parent_mnt,
24096 ++ const struct dentry * old_dentry,
24097 ++ const struct vfsmount * old_mnt, const char *to)
24098 ++{
24099 ++ return 1;
24100 ++}
24101 ++
24102 ++int
24103 ++gr_acl_handle_rename(const struct dentry *new_dentry,
24104 ++ const struct dentry *parent_dentry,
24105 ++ const struct vfsmount *parent_mnt,
24106 ++ const struct dentry *old_dentry,
24107 ++ const struct inode *old_parent_inode,
24108 ++ const struct vfsmount *old_mnt, const char *newname)
24109 ++{
24110 ++ return 0;
24111 ++}
24112 ++
24113 ++int
24114 ++gr_acl_handle_filldir(const struct file *file, const char *name,
24115 ++ const int namelen, const ino_t ino)
24116 ++{
24117 ++ return 1;
24118 ++}
24119 ++
24120 ++int
24121 ++gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
24122 ++ const time_t shm_createtime, const uid_t cuid, const int shmid)
24123 ++{
24124 ++ return 1;
24125 ++}
24126 ++
24127 ++int
24128 ++gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
24129 ++{
24130 ++ return 1;
24131 ++}
24132 ++
24133 ++int
24134 ++gr_search_accept(const struct socket *sock)
24135 ++{
24136 ++ return 1;
24137 ++}
24138 ++
24139 ++int
24140 ++gr_search_listen(const struct socket *sock)
24141 ++{
24142 ++ return 1;
24143 ++}
24144 ++
24145 ++int
24146 ++gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
24147 ++{
24148 ++ return 1;
24149 ++}
24150 ++
24151 ++__u32
24152 ++gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
24153 ++{
24154 ++ return 1;
24155 ++}
24156 ++
24157 ++__u32
24158 ++gr_acl_handle_creat(const struct dentry * dentry,
24159 ++ const struct dentry * p_dentry,
24160 ++ const struct vfsmount * p_mnt, const int fmode,
24161 ++ const int imode)
24162 ++{
24163 ++ return 1;
24164 ++}
24165 ++
24166 ++void
24167 ++gr_acl_handle_exit(void)
24168 ++{
24169 ++ return;
24170 ++}
24171 ++
24172 ++int
24173 ++gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
24174 ++{
24175 ++ return 1;
24176 ++}
24177 ++
24178 ++void
24179 ++gr_set_role_label(const uid_t uid, const gid_t gid)
24180 ++{
24181 ++ return;
24182 ++}
24183 ++
24184 ++int
24185 ++gr_acl_handle_procpidmem(const struct task_struct *task)
24186 ++{
24187 ++ return 0;
24188 ++}
24189 ++
24190 ++int
24191 ++gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
24192 ++{
24193 ++ return 1;
24194 ++}
24195 ++
24196 ++int
24197 ++gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
24198 ++{
24199 ++ return 1;
24200 ++}
24201 ++
24202 ++void
24203 ++gr_set_kernel_label(struct task_struct *task)
24204 ++{
24205 ++ return;
24206 ++}
24207 ++
24208 ++int
24209 ++gr_check_user_change(int real, int effective, int fs)
24210 ++{
24211 ++ return 0;
24212 ++}
24213 ++
24214 ++int
24215 ++gr_check_group_change(int real, int effective, int fs)
24216 ++{
24217 ++ return 0;
24218 ++}
24219 ++
24220 ++
24221 ++EXPORT_SYMBOL(gr_task_is_capable);
24222 ++EXPORT_SYMBOL(gr_is_capable_nolog);
24223 ++EXPORT_SYMBOL(gr_learn_resource);
24224 ++EXPORT_SYMBOL(gr_set_kernel_label);
24225 ++#ifdef CONFIG_SECURITY
24226 ++EXPORT_SYMBOL(gr_check_user_change);
24227 ++EXPORT_SYMBOL(gr_check_group_change);
24228 ++#endif
24229 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_exec.c linux-2.6.23.15-grsec/grsecurity/grsec_exec.c
24230 +--- linux-2.6.23.15/grsecurity/grsec_exec.c 1970-01-01 01:00:00.000000000 +0100
24231 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_exec.c 2008-02-11 10:37:44.000000000 +0000
24232 +@@ -0,0 +1,88 @@
24233 ++#include <linux/kernel.h>
24234 ++#include <linux/sched.h>
24235 ++#include <linux/file.h>
24236 ++#include <linux/binfmts.h>
24237 ++#include <linux/smp_lock.h>
24238 ++#include <linux/fs.h>
24239 ++#include <linux/types.h>
24240 ++#include <linux/grdefs.h>
24241 ++#include <linux/grinternal.h>
24242 ++#include <linux/capability.h>
24243 ++
24244 ++#include <asm/uaccess.h>
24245 ++
24246 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
24247 ++static char gr_exec_arg_buf[132];
24248 ++static DECLARE_MUTEX(gr_exec_arg_sem);
24249 ++#endif
24250 ++
24251 ++int
24252 ++gr_handle_nproc(void)
24253 ++{
24254 ++#ifdef CONFIG_GRKERNSEC_EXECVE
24255 ++ if (grsec_enable_execve && current->user &&
24256 ++ (atomic_read(&current->user->processes) >
24257 ++ current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
24258 ++ !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
24259 ++ gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
24260 ++ return -EAGAIN;
24261 ++ }
24262 ++#endif
24263 ++ return 0;
24264 ++}
24265 ++
24266 ++void
24267 ++gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
24268 ++{
24269 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
24270 ++ char *grarg = gr_exec_arg_buf;
24271 ++ unsigned int i, x, execlen = 0;
24272 ++ char c;
24273 ++
24274 ++ if (!((grsec_enable_execlog && grsec_enable_group &&
24275 ++ in_group_p(grsec_audit_gid))
24276 ++ || (grsec_enable_execlog && !grsec_enable_group)))
24277 ++ return;
24278 ++
24279 ++ down(&gr_exec_arg_sem);
24280 ++ memset(grarg, 0, sizeof(gr_exec_arg_buf));
24281 ++
24282 ++ if (unlikely(argv == NULL))
24283 ++ goto log;
24284 ++
24285 ++ for (i = 0; i < bprm->argc && execlen < 128; i++) {
24286 ++ const char __user *p;
24287 ++ unsigned int len;
24288 ++
24289 ++ if (copy_from_user(&p, argv + i, sizeof(p)))
24290 ++ goto log;
24291 ++ if (!p)
24292 ++ goto log;
24293 ++ len = strnlen_user(p, 128 - execlen);
24294 ++ if (len > 128 - execlen)
24295 ++ len = 128 - execlen;
24296 ++ else if (len > 0)
24297 ++ len--;
24298 ++ if (copy_from_user(grarg + execlen, p, len))
24299 ++ goto log;
24300 ++
24301 ++ /* rewrite unprintable characters */
24302 ++ for (x = 0; x < len; x++) {
24303 ++ c = *(grarg + execlen + x);
24304 ++ if (c < 32 || c > 126)
24305 ++ *(grarg + execlen + x) = ' ';
24306 ++ }
24307 ++
24308 ++ execlen += len;
24309 ++ *(grarg + execlen) = ' ';
24310 ++ *(grarg + execlen + 1) = '\0';
24311 ++ execlen++;
24312 ++ }
24313 ++
24314 ++ log:
24315 ++ gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_dentry,
24316 ++ bprm->file->f_vfsmnt, grarg);
24317 ++ up(&gr_exec_arg_sem);
24318 ++#endif
24319 ++ return;
24320 ++}
24321 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_fifo.c linux-2.6.23.15-grsec/grsecurity/grsec_fifo.c
24322 +--- linux-2.6.23.15/grsecurity/grsec_fifo.c 1970-01-01 01:00:00.000000000 +0100
24323 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_fifo.c 2008-02-11 10:37:44.000000000 +0000
24324 +@@ -0,0 +1,22 @@
24325 ++#include <linux/kernel.h>
24326 ++#include <linux/sched.h>
24327 ++#include <linux/fs.h>
24328 ++#include <linux/file.h>
24329 ++#include <linux/grinternal.h>
24330 ++
24331 ++int
24332 ++gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
24333 ++ const struct dentry *dir, const int flag, const int acc_mode)
24334 ++{
24335 ++#ifdef CONFIG_GRKERNSEC_FIFO
24336 ++ if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
24337 ++ !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
24338 ++ (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
24339 ++ (current->fsuid != dentry->d_inode->i_uid)) {
24340 ++ if (!generic_permission(dentry->d_inode, acc_mode, NULL))
24341 ++ gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
24342 ++ return -EACCES;
24343 ++ }
24344 ++#endif
24345 ++ return 0;
24346 ++}
24347 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_fork.c linux-2.6.23.15-grsec/grsecurity/grsec_fork.c
24348 +--- linux-2.6.23.15/grsecurity/grsec_fork.c 1970-01-01 01:00:00.000000000 +0100
24349 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_fork.c 2008-02-11 10:37:44.000000000 +0000
24350 +@@ -0,0 +1,15 @@
24351 ++#include <linux/kernel.h>
24352 ++#include <linux/sched.h>
24353 ++#include <linux/grsecurity.h>
24354 ++#include <linux/grinternal.h>
24355 ++#include <linux/errno.h>
24356 ++
24357 ++void
24358 ++gr_log_forkfail(const int retval)
24359 ++{
24360 ++#ifdef CONFIG_GRKERNSEC_FORKFAIL
24361 ++ if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
24362 ++ gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
24363 ++#endif
24364 ++ return;
24365 ++}
24366 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_init.c linux-2.6.23.15-grsec/grsecurity/grsec_init.c
24367 +--- linux-2.6.23.15/grsecurity/grsec_init.c 1970-01-01 01:00:00.000000000 +0100
24368 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_init.c 2008-02-11 10:37:44.000000000 +0000
24369 +@@ -0,0 +1,230 @@
24370 ++#include <linux/kernel.h>
24371 ++#include <linux/sched.h>
24372 ++#include <linux/mm.h>
24373 ++#include <linux/smp_lock.h>
24374 ++#include <linux/gracl.h>
24375 ++#include <linux/slab.h>
24376 ++#include <linux/vmalloc.h>
24377 ++#include <linux/percpu.h>
24378 ++
24379 ++int grsec_enable_shm;
24380 ++int grsec_enable_link;
24381 ++int grsec_enable_dmesg;
24382 ++int grsec_enable_fifo;
24383 ++int grsec_enable_execve;
24384 ++int grsec_enable_execlog;
24385 ++int grsec_enable_signal;
24386 ++int grsec_enable_forkfail;
24387 ++int grsec_enable_time;
24388 ++int grsec_enable_audit_textrel;
24389 ++int grsec_enable_group;
24390 ++int grsec_audit_gid;
24391 ++int grsec_enable_chdir;
24392 ++int grsec_enable_audit_ipc;
24393 ++int grsec_enable_mount;
24394 ++int grsec_enable_chroot_findtask;
24395 ++int grsec_enable_chroot_mount;
24396 ++int grsec_enable_chroot_shmat;
24397 ++int grsec_enable_chroot_fchdir;
24398 ++int grsec_enable_chroot_double;
24399 ++int grsec_enable_chroot_pivot;
24400 ++int grsec_enable_chroot_chdir;
24401 ++int grsec_enable_chroot_chmod;
24402 ++int grsec_enable_chroot_mknod;
24403 ++int grsec_enable_chroot_nice;
24404 ++int grsec_enable_chroot_execlog;
24405 ++int grsec_enable_chroot_caps;
24406 ++int grsec_enable_chroot_sysctl;
24407 ++int grsec_enable_chroot_unix;
24408 ++int grsec_enable_tpe;
24409 ++int grsec_tpe_gid;
24410 ++int grsec_enable_tpe_all;
24411 ++int grsec_enable_socket_all;
24412 ++int grsec_socket_all_gid;
24413 ++int grsec_enable_socket_client;
24414 ++int grsec_socket_client_gid;
24415 ++int grsec_enable_socket_server;
24416 ++int grsec_socket_server_gid;
24417 ++int grsec_resource_logging;
24418 ++int grsec_lock;
24419 ++
24420 ++spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
24421 ++unsigned long grsec_alert_wtime = 0;
24422 ++unsigned long grsec_alert_fyet = 0;
24423 ++
24424 ++spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
24425 ++
24426 ++rwlock_t grsec_exec_file_lock = RW_LOCK_UNLOCKED;
24427 ++
24428 ++char *gr_shared_page[4];
24429 ++
24430 ++char *gr_alert_log_fmt;
24431 ++char *gr_audit_log_fmt;
24432 ++char *gr_alert_log_buf;
24433 ++char *gr_audit_log_buf;
24434 ++
24435 ++extern struct gr_arg *gr_usermode;
24436 ++extern unsigned char *gr_system_salt;
24437 ++extern unsigned char *gr_system_sum;
24438 ++
24439 ++void
24440 ++grsecurity_init(void)
24441 ++{
24442 ++ int j;
24443 ++ /* create the per-cpu shared pages */
24444 ++
24445 ++ for (j = 0; j < 4; j++) {
24446 ++ gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
24447 ++ if (gr_shared_page[j] == NULL) {
24448 ++ panic("Unable to allocate grsecurity shared page");
24449 ++ return;
24450 ++ }
24451 ++ }
24452 ++
24453 ++ /* allocate log buffers */
24454 ++ gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
24455 ++ if (!gr_alert_log_fmt) {
24456 ++ panic("Unable to allocate grsecurity alert log format buffer");
24457 ++ return;
24458 ++ }
24459 ++ gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
24460 ++ if (!gr_audit_log_fmt) {
24461 ++ panic("Unable to allocate grsecurity audit log format buffer");
24462 ++ return;
24463 ++ }
24464 ++ gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
24465 ++ if (!gr_alert_log_buf) {
24466 ++ panic("Unable to allocate grsecurity alert log buffer");
24467 ++ return;
24468 ++ }
24469 ++ gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
24470 ++ if (!gr_audit_log_buf) {
24471 ++ panic("Unable to allocate grsecurity audit log buffer");
24472 ++ return;
24473 ++ }
24474 ++
24475 ++ /* allocate memory for authentication structure */
24476 ++ gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
24477 ++ gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
24478 ++ gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
24479 ++
24480 ++ if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
24481 ++ panic("Unable to allocate grsecurity authentication structure");
24482 ++ return;
24483 ++ }
24484 ++
24485 ++#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
24486 ++#ifndef CONFIG_GRKERNSEC_SYSCTL
24487 ++ grsec_lock = 1;
24488 ++#endif
24489 ++#ifdef CONFIG_GRKERNSEC_SHM
24490 ++ grsec_enable_shm = 1;
24491 ++#endif
24492 ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
24493 ++ grsec_enable_audit_textrel = 1;
24494 ++#endif
24495 ++#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
24496 ++ grsec_enable_group = 1;
24497 ++ grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
24498 ++#endif
24499 ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
24500 ++ grsec_enable_chdir = 1;
24501 ++#endif
24502 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24503 ++ grsec_enable_audit_ipc = 1;
24504 ++#endif
24505 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
24506 ++ grsec_enable_mount = 1;
24507 ++#endif
24508 ++#ifdef CONFIG_GRKERNSEC_LINK
24509 ++ grsec_enable_link = 1;
24510 ++#endif
24511 ++#ifdef CONFIG_GRKERNSEC_DMESG
24512 ++ grsec_enable_dmesg = 1;
24513 ++#endif
24514 ++#ifdef CONFIG_GRKERNSEC_FIFO
24515 ++ grsec_enable_fifo = 1;
24516 ++#endif
24517 ++#ifdef CONFIG_GRKERNSEC_EXECVE
24518 ++ grsec_enable_execve = 1;
24519 ++#endif
24520 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
24521 ++ grsec_enable_execlog = 1;
24522 ++#endif
24523 ++#ifdef CONFIG_GRKERNSEC_SIGNAL
24524 ++ grsec_enable_signal = 1;
24525 ++#endif
24526 ++#ifdef CONFIG_GRKERNSEC_FORKFAIL
24527 ++ grsec_enable_forkfail = 1;
24528 ++#endif
24529 ++#ifdef CONFIG_GRKERNSEC_TIME
24530 ++ grsec_enable_time = 1;
24531 ++#endif
24532 ++#ifdef CONFIG_GRKERNSEC_RESLOG
24533 ++ grsec_resource_logging = 1;
24534 ++#endif
24535 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
24536 ++ grsec_enable_chroot_findtask = 1;
24537 ++#endif
24538 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
24539 ++ grsec_enable_chroot_unix = 1;
24540 ++#endif
24541 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
24542 ++ grsec_enable_chroot_mount = 1;
24543 ++#endif
24544 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
24545 ++ grsec_enable_chroot_fchdir = 1;
24546 ++#endif
24547 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
24548 ++ grsec_enable_chroot_shmat = 1;
24549 ++#endif
24550 ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
24551 ++ grsec_enable_chroot_double = 1;
24552 ++#endif
24553 ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
24554 ++ grsec_enable_chroot_pivot = 1;
24555 ++#endif
24556 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
24557 ++ grsec_enable_chroot_chdir = 1;
24558 ++#endif
24559 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
24560 ++ grsec_enable_chroot_chmod = 1;
24561 ++#endif
24562 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
24563 ++ grsec_enable_chroot_mknod = 1;
24564 ++#endif
24565 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
24566 ++ grsec_enable_chroot_nice = 1;
24567 ++#endif
24568 ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
24569 ++ grsec_enable_chroot_execlog = 1;
24570 ++#endif
24571 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
24572 ++ grsec_enable_chroot_caps = 1;
24573 ++#endif
24574 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
24575 ++ grsec_enable_chroot_sysctl = 1;
24576 ++#endif
24577 ++#ifdef CONFIG_GRKERNSEC_TPE
24578 ++ grsec_enable_tpe = 1;
24579 ++ grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
24580 ++#ifdef CONFIG_GRKERNSEC_TPE_ALL
24581 ++ grsec_enable_tpe_all = 1;
24582 ++#endif
24583 ++#endif
24584 ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
24585 ++ grsec_enable_socket_all = 1;
24586 ++ grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
24587 ++#endif
24588 ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
24589 ++ grsec_enable_socket_client = 1;
24590 ++ grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
24591 ++#endif
24592 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
24593 ++ grsec_enable_socket_server = 1;
24594 ++ grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
24595 ++#endif
24596 ++#endif
24597 ++
24598 ++ return;
24599 ++}
24600 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_ipc.c linux-2.6.23.15-grsec/grsecurity/grsec_ipc.c
24601 +--- linux-2.6.23.15/grsecurity/grsec_ipc.c 1970-01-01 01:00:00.000000000 +0100
24602 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_ipc.c 2008-02-11 10:37:44.000000000 +0000
24603 +@@ -0,0 +1,81 @@
24604 ++#include <linux/kernel.h>
24605 ++#include <linux/sched.h>
24606 ++#include <linux/types.h>
24607 ++#include <linux/ipc.h>
24608 ++#include <linux/grsecurity.h>
24609 ++#include <linux/grinternal.h>
24610 ++
24611 ++void
24612 ++gr_log_msgget(const int ret, const int msgflg)
24613 ++{
24614 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24615 ++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
24616 ++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
24617 ++ !grsec_enable_group)) && (ret >= 0)
24618 ++ && (msgflg & IPC_CREAT))
24619 ++ gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
24620 ++#endif
24621 ++ return;
24622 ++}
24623 ++
24624 ++void
24625 ++gr_log_msgrm(const uid_t uid, const uid_t cuid)
24626 ++{
24627 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24628 ++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
24629 ++ grsec_enable_audit_ipc) ||
24630 ++ (grsec_enable_audit_ipc && !grsec_enable_group))
24631 ++ gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
24632 ++#endif
24633 ++ return;
24634 ++}
24635 ++
24636 ++void
24637 ++gr_log_semget(const int err, const int semflg)
24638 ++{
24639 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24640 ++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
24641 ++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
24642 ++ !grsec_enable_group)) && (err >= 0)
24643 ++ && (semflg & IPC_CREAT))
24644 ++ gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
24645 ++#endif
24646 ++ return;
24647 ++}
24648 ++
24649 ++void
24650 ++gr_log_semrm(const uid_t uid, const uid_t cuid)
24651 ++{
24652 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24653 ++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
24654 ++ grsec_enable_audit_ipc) ||
24655 ++ (grsec_enable_audit_ipc && !grsec_enable_group))
24656 ++ gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
24657 ++#endif
24658 ++ return;
24659 ++}
24660 ++
24661 ++void
24662 ++gr_log_shmget(const int err, const int shmflg, const size_t size)
24663 ++{
24664 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24665 ++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
24666 ++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
24667 ++ !grsec_enable_group)) && (err >= 0)
24668 ++ && (shmflg & IPC_CREAT))
24669 ++ gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
24670 ++#endif
24671 ++ return;
24672 ++}
24673 ++
24674 ++void
24675 ++gr_log_shmrm(const uid_t uid, const uid_t cuid)
24676 ++{
24677 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24678 ++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
24679 ++ grsec_enable_audit_ipc) ||
24680 ++ (grsec_enable_audit_ipc && !grsec_enable_group))
24681 ++ gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
24682 ++#endif
24683 ++ return;
24684 ++}
24685 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_link.c linux-2.6.23.15-grsec/grsecurity/grsec_link.c
24686 +--- linux-2.6.23.15/grsecurity/grsec_link.c 1970-01-01 01:00:00.000000000 +0100
24687 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_link.c 2008-02-11 10:37:44.000000000 +0000
24688 +@@ -0,0 +1,39 @@
24689 ++#include <linux/kernel.h>
24690 ++#include <linux/sched.h>
24691 ++#include <linux/fs.h>
24692 ++#include <linux/file.h>
24693 ++#include <linux/grinternal.h>
24694 ++
24695 ++int
24696 ++gr_handle_follow_link(const struct inode *parent,
24697 ++ const struct inode *inode,
24698 ++ const struct dentry *dentry, const struct vfsmount *mnt)
24699 ++{
24700 ++#ifdef CONFIG_GRKERNSEC_LINK
24701 ++ if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
24702 ++ (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
24703 ++ (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
24704 ++ gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
24705 ++ return -EACCES;
24706 ++ }
24707 ++#endif
24708 ++ return 0;
24709 ++}
24710 ++
24711 ++int
24712 ++gr_handle_hardlink(const struct dentry *dentry,
24713 ++ const struct vfsmount *mnt,
24714 ++ struct inode *inode, const int mode, const char *to)
24715 ++{
24716 ++#ifdef CONFIG_GRKERNSEC_LINK
24717 ++ if (grsec_enable_link && current->fsuid != inode->i_uid &&
24718 ++ (!S_ISREG(mode) || (mode & S_ISUID) ||
24719 ++ ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
24720 ++ (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
24721 ++ !capable(CAP_FOWNER) && current->uid) {
24722 ++ gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
24723 ++ return -EPERM;
24724 ++ }
24725 ++#endif
24726 ++ return 0;
24727 ++}
24728 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_log.c linux-2.6.23.15-grsec/grsecurity/grsec_log.c
24729 +--- linux-2.6.23.15/grsecurity/grsec_log.c 1970-01-01 01:00:00.000000000 +0100
24730 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_log.c 2008-02-11 10:37:44.000000000 +0000
24731 +@@ -0,0 +1,269 @@
24732 ++#include <linux/kernel.h>
24733 ++#include <linux/sched.h>
24734 ++#include <linux/file.h>
24735 ++#include <linux/tty.h>
24736 ++#include <linux/fs.h>
24737 ++#include <linux/grinternal.h>
24738 ++
24739 ++#define BEGIN_LOCKS(x) \
24740 ++ read_lock(&tasklist_lock); \
24741 ++ read_lock(&grsec_exec_file_lock); \
24742 ++ if (x != GR_DO_AUDIT) \
24743 ++ spin_lock(&grsec_alert_lock); \
24744 ++ else \
24745 ++ spin_lock(&grsec_audit_lock)
24746 ++
24747 ++#define END_LOCKS(x) \
24748 ++ if (x != GR_DO_AUDIT) \
24749 ++ spin_unlock(&grsec_alert_lock); \
24750 ++ else \
24751 ++ spin_unlock(&grsec_audit_lock); \
24752 ++ read_unlock(&grsec_exec_file_lock); \
24753 ++ read_unlock(&tasklist_lock); \
24754 ++ if (x == GR_DONT_AUDIT) \
24755 ++ gr_handle_alertkill(current)
24756 ++
24757 ++enum {
24758 ++ FLOODING,
24759 ++ NO_FLOODING
24760 ++};
24761 ++
24762 ++extern char *gr_alert_log_fmt;
24763 ++extern char *gr_audit_log_fmt;
24764 ++extern char *gr_alert_log_buf;
24765 ++extern char *gr_audit_log_buf;
24766 ++
24767 ++static int gr_log_start(int audit)
24768 ++{
24769 ++ char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
24770 ++ char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
24771 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
24772 ++
24773 ++ if (audit == GR_DO_AUDIT)
24774 ++ goto set_fmt;
24775 ++
24776 ++ if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
24777 ++ grsec_alert_wtime = jiffies;
24778 ++ grsec_alert_fyet = 0;
24779 ++ } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
24780 ++ grsec_alert_fyet++;
24781 ++ } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
24782 ++ grsec_alert_wtime = jiffies;
24783 ++ grsec_alert_fyet++;
24784 ++ printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
24785 ++ return FLOODING;
24786 ++ } else return FLOODING;
24787 ++
24788 ++set_fmt:
24789 ++ memset(buf, 0, PAGE_SIZE);
24790 ++ if (current->signal->curr_ip && gr_acl_is_enabled()) {
24791 ++ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
24792 ++ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
24793 ++ } else if (current->signal->curr_ip) {
24794 ++ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
24795 ++ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
24796 ++ } else if (gr_acl_is_enabled()) {
24797 ++ sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
24798 ++ snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
24799 ++ } else {
24800 ++ sprintf(fmt, "%s%s", loglevel, "grsec: ");
24801 ++ strcpy(buf, fmt);
24802 ++ }
24803 ++
24804 ++ return NO_FLOODING;
24805 ++}
24806 ++
24807 ++static void gr_log_middle(int audit, const char *msg, va_list ap)
24808 ++{
24809 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
24810 ++ unsigned int len = strlen(buf);
24811 ++
24812 ++ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
24813 ++
24814 ++ return;
24815 ++}
24816 ++
24817 ++static void gr_log_middle_varargs(int audit, const char *msg, ...)
24818 ++{
24819 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
24820 ++ unsigned int len = strlen(buf);
24821 ++ va_list ap;
24822 ++
24823 ++ va_start(ap, msg);
24824 ++ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
24825 ++ va_end(ap);
24826 ++
24827 ++ return;
24828 ++}
24829 ++
24830 ++static void gr_log_end(int audit)
24831 ++{
24832 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
24833 ++ unsigned int len = strlen(buf);
24834 ++
24835 ++ snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
24836 ++ printk("%s\n", buf);
24837 ++
24838 ++ return;
24839 ++}
24840 ++
24841 ++void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
24842 ++{
24843 ++ int logtype;
24844 ++ char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
24845 ++ char *str1, *str2, *str3;
24846 ++ int num1, num2;
24847 ++ unsigned long ulong1, ulong2;
24848 ++ struct dentry *dentry;
24849 ++ struct vfsmount *mnt;
24850 ++ struct file *file;
24851 ++ struct task_struct *task;
24852 ++ va_list ap;
24853 ++
24854 ++ BEGIN_LOCKS(audit);
24855 ++ logtype = gr_log_start(audit);
24856 ++ if (logtype == FLOODING) {
24857 ++ END_LOCKS(audit);
24858 ++ return;
24859 ++ }
24860 ++ va_start(ap, argtypes);
24861 ++ switch (argtypes) {
24862 ++ case GR_TTYSNIFF:
24863 ++ task = va_arg(ap, struct task_struct *);
24864 ++ 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);
24865 ++ break;
24866 ++ case GR_SYSCTL_HIDDEN:
24867 ++ str1 = va_arg(ap, char *);
24868 ++ gr_log_middle_varargs(audit, msg, result, str1);
24869 ++ break;
24870 ++ case GR_RBAC:
24871 ++ dentry = va_arg(ap, struct dentry *);
24872 ++ mnt = va_arg(ap, struct vfsmount *);
24873 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
24874 ++ break;
24875 ++ case GR_RBAC_STR:
24876 ++ dentry = va_arg(ap, struct dentry *);
24877 ++ mnt = va_arg(ap, struct vfsmount *);
24878 ++ str1 = va_arg(ap, char *);
24879 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
24880 ++ break;
24881 ++ case GR_STR_RBAC:
24882 ++ str1 = va_arg(ap, char *);
24883 ++ dentry = va_arg(ap, struct dentry *);
24884 ++ mnt = va_arg(ap, struct vfsmount *);
24885 ++ gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
24886 ++ break;
24887 ++ case GR_RBAC_MODE2:
24888 ++ dentry = va_arg(ap, struct dentry *);
24889 ++ mnt = va_arg(ap, struct vfsmount *);
24890 ++ str1 = va_arg(ap, char *);
24891 ++ str2 = va_arg(ap, char *);
24892 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
24893 ++ break;
24894 ++ case GR_RBAC_MODE3:
24895 ++ dentry = va_arg(ap, struct dentry *);
24896 ++ mnt = va_arg(ap, struct vfsmount *);
24897 ++ str1 = va_arg(ap, char *);
24898 ++ str2 = va_arg(ap, char *);
24899 ++ str3 = va_arg(ap, char *);
24900 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
24901 ++ break;
24902 ++ case GR_FILENAME:
24903 ++ dentry = va_arg(ap, struct dentry *);
24904 ++ mnt = va_arg(ap, struct vfsmount *);
24905 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
24906 ++ break;
24907 ++ case GR_STR_FILENAME:
24908 ++ str1 = va_arg(ap, char *);
24909 ++ dentry = va_arg(ap, struct dentry *);
24910 ++ mnt = va_arg(ap, struct vfsmount *);
24911 ++ gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
24912 ++ break;
24913 ++ case GR_FILENAME_STR:
24914 ++ dentry = va_arg(ap, struct dentry *);
24915 ++ mnt = va_arg(ap, struct vfsmount *);
24916 ++ str1 = va_arg(ap, char *);
24917 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
24918 ++ break;
24919 ++ case GR_FILENAME_TWO_INT:
24920 ++ dentry = va_arg(ap, struct dentry *);
24921 ++ mnt = va_arg(ap, struct vfsmount *);
24922 ++ num1 = va_arg(ap, int);
24923 ++ num2 = va_arg(ap, int);
24924 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
24925 ++ break;
24926 ++ case GR_FILENAME_TWO_INT_STR:
24927 ++ dentry = va_arg(ap, struct dentry *);
24928 ++ mnt = va_arg(ap, struct vfsmount *);
24929 ++ num1 = va_arg(ap, int);
24930 ++ num2 = va_arg(ap, int);
24931 ++ str1 = va_arg(ap, char *);
24932 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
24933 ++ break;
24934 ++ case GR_TEXTREL:
24935 ++ file = va_arg(ap, struct file *);
24936 ++ ulong1 = va_arg(ap, unsigned long);
24937 ++ ulong2 = va_arg(ap, unsigned long);
24938 ++ gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_dentry, file->f_vfsmnt) : "<anonymous mapping>", ulong1, ulong2);
24939 ++ break;
24940 ++ case GR_PTRACE:
24941 ++ task = va_arg(ap, struct task_struct *);
24942 ++ gr_log_middle_varargs(audit, msg, task->exec_file ? gr_to_filename(task->exec_file->f_dentry, task->exec_file->f_vfsmnt) : "(none)", task->comm, task->pid);
24943 ++ break;
24944 ++ case GR_RESOURCE:
24945 ++ task = va_arg(ap, struct task_struct *);
24946 ++ ulong1 = va_arg(ap, unsigned long);
24947 ++ str1 = va_arg(ap, char *);
24948 ++ ulong2 = va_arg(ap, unsigned long);
24949 ++ 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);
24950 ++ break;
24951 ++ case GR_CAP:
24952 ++ task = va_arg(ap, struct task_struct *);
24953 ++ str1 = va_arg(ap, char *);
24954 ++ 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);
24955 ++ break;
24956 ++ case GR_SIG:
24957 ++ task = va_arg(ap, struct task_struct *);
24958 ++ num1 = va_arg(ap, int);
24959 ++ 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);
24960 ++ break;
24961 ++ case GR_CRASH1:
24962 ++ task = va_arg(ap, struct task_struct *);
24963 ++ ulong1 = va_arg(ap, unsigned long);
24964 ++ 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);
24965 ++ break;
24966 ++ case GR_CRASH2:
24967 ++ task = va_arg(ap, struct task_struct *);
24968 ++ ulong1 = va_arg(ap, unsigned long);
24969 ++ 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);
24970 ++ break;
24971 ++ case GR_PSACCT:
24972 ++ {
24973 ++ unsigned int wday, cday;
24974 ++ __u8 whr, chr;
24975 ++ __u8 wmin, cmin;
24976 ++ __u8 wsec, csec;
24977 ++ char cur_tty[64] = { 0 };
24978 ++ char parent_tty[64] = { 0 };
24979 ++
24980 ++ task = va_arg(ap, struct task_struct *);
24981 ++ wday = va_arg(ap, unsigned int);
24982 ++ cday = va_arg(ap, unsigned int);
24983 ++ whr = va_arg(ap, int);
24984 ++ chr = va_arg(ap, int);
24985 ++ wmin = va_arg(ap, int);
24986 ++ cmin = va_arg(ap, int);
24987 ++ wsec = va_arg(ap, int);
24988 ++ csec = va_arg(ap, int);
24989 ++ ulong1 = va_arg(ap, unsigned long);
24990 ++
24991 ++ 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);
24992 ++ }
24993 ++ break;
24994 ++ default:
24995 ++ gr_log_middle(audit, msg, ap);
24996 ++ }
24997 ++ va_end(ap);
24998 ++ gr_log_end(audit);
24999 ++ END_LOCKS(audit);
25000 ++}
25001 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_mem.c linux-2.6.23.15-grsec/grsecurity/grsec_mem.c
25002 +--- linux-2.6.23.15/grsecurity/grsec_mem.c 1970-01-01 01:00:00.000000000 +0100
25003 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_mem.c 2008-02-11 10:37:44.000000000 +0000
25004 +@@ -0,0 +1,71 @@
25005 ++#include <linux/kernel.h>
25006 ++#include <linux/sched.h>
25007 ++#include <linux/mm.h>
25008 ++#include <linux/mman.h>
25009 ++#include <linux/grinternal.h>
25010 ++
25011 ++void
25012 ++gr_handle_ioperm(void)
25013 ++{
25014 ++ gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
25015 ++ return;
25016 ++}
25017 ++
25018 ++void
25019 ++gr_handle_iopl(void)
25020 ++{
25021 ++ gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
25022 ++ return;
25023 ++}
25024 ++
25025 ++void
25026 ++gr_handle_mem_write(void)
25027 ++{
25028 ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
25029 ++ return;
25030 ++}
25031 ++
25032 ++void
25033 ++gr_handle_kmem_write(void)
25034 ++{
25035 ++ gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
25036 ++ return;
25037 ++}
25038 ++
25039 ++void
25040 ++gr_handle_open_port(void)
25041 ++{
25042 ++ gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
25043 ++ return;
25044 ++}
25045 ++
25046 ++int
25047 ++gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
25048 ++{
25049 ++ unsigned long start, end;
25050 ++
25051 ++ start = offset;
25052 ++ end = start + vma->vm_end - vma->vm_start;
25053 ++
25054 ++ if (start > end) {
25055 ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
25056 ++ return -EPERM;
25057 ++ }
25058 ++
25059 ++ /* allowed ranges : ISA I/O BIOS */
25060 ++ if ((start >= __pa(high_memory))
25061 ++#ifdef CONFIG_X86
25062 ++ || (start >= 0x000a0000 && end <= 0x00100000)
25063 ++ || (start >= 0x00000000 && end <= 0x00001000)
25064 ++#endif
25065 ++ )
25066 ++ return 0;
25067 ++
25068 ++ if (vma->vm_flags & VM_WRITE) {
25069 ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
25070 ++ return -EPERM;
25071 ++ } else
25072 ++ vma->vm_flags &= ~VM_MAYWRITE;
25073 ++
25074 ++ return 0;
25075 ++}
25076 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_mount.c linux-2.6.23.15-grsec/grsecurity/grsec_mount.c
25077 +--- linux-2.6.23.15/grsecurity/grsec_mount.c 1970-01-01 01:00:00.000000000 +0100
25078 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_mount.c 2008-02-11 10:37:44.000000000 +0000
25079 +@@ -0,0 +1,34 @@
25080 ++#include <linux/kernel.h>
25081 ++#include <linux/sched.h>
25082 ++#include <linux/grsecurity.h>
25083 ++#include <linux/grinternal.h>
25084 ++
25085 ++void
25086 ++gr_log_remount(const char *devname, const int retval)
25087 ++{
25088 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
25089 ++ if (grsec_enable_mount && (retval >= 0))
25090 ++ gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
25091 ++#endif
25092 ++ return;
25093 ++}
25094 ++
25095 ++void
25096 ++gr_log_unmount(const char *devname, const int retval)
25097 ++{
25098 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
25099 ++ if (grsec_enable_mount && (retval >= 0))
25100 ++ gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
25101 ++#endif
25102 ++ return;
25103 ++}
25104 ++
25105 ++void
25106 ++gr_log_mount(const char *from, const char *to, const int retval)
25107 ++{
25108 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
25109 ++ if (grsec_enable_mount && (retval >= 0))
25110 ++ gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
25111 ++#endif
25112 ++ return;
25113 ++}
25114 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_sig.c linux-2.6.23.15-grsec/grsecurity/grsec_sig.c
25115 +--- linux-2.6.23.15/grsecurity/grsec_sig.c 1970-01-01 01:00:00.000000000 +0100
25116 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_sig.c 2008-02-11 10:37:44.000000000 +0000
25117 +@@ -0,0 +1,59 @@
25118 ++#include <linux/kernel.h>
25119 ++#include <linux/sched.h>
25120 ++#include <linux/grsecurity.h>
25121 ++#include <linux/grinternal.h>
25122 ++
25123 ++void
25124 ++gr_log_signal(const int sig, const struct task_struct *t)
25125 ++{
25126 ++#ifdef CONFIG_GRKERNSEC_SIGNAL
25127 ++ if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
25128 ++ (sig == SIGABRT) || (sig == SIGBUS))) {
25129 ++ if (t->pid == current->pid) {
25130 ++ gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
25131 ++ } else {
25132 ++ gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
25133 ++ }
25134 ++ }
25135 ++#endif
25136 ++ return;
25137 ++}
25138 ++
25139 ++int
25140 ++gr_handle_signal(const struct task_struct *p, const int sig)
25141 ++{
25142 ++#ifdef CONFIG_GRKERNSEC
25143 ++ if (current->pid > 1 && gr_check_protected_task(p)) {
25144 ++ gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
25145 ++ return -EPERM;
25146 ++ } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
25147 ++ return -EPERM;
25148 ++ }
25149 ++#endif
25150 ++ return 0;
25151 ++}
25152 ++
25153 ++void gr_handle_brute_attach(struct task_struct *p)
25154 ++{
25155 ++#ifdef CONFIG_GRKERNSEC_BRUTE
25156 ++ read_lock(&tasklist_lock);
25157 ++ read_lock(&grsec_exec_file_lock);
25158 ++ if (p->parent && p->parent->exec_file == p->exec_file)
25159 ++ p->parent->brute = 1;
25160 ++ read_unlock(&grsec_exec_file_lock);
25161 ++ read_unlock(&tasklist_lock);
25162 ++#endif
25163 ++ return;
25164 ++}
25165 ++
25166 ++void gr_handle_brute_check(void)
25167 ++{
25168 ++#ifdef CONFIG_GRKERNSEC_BRUTE
25169 ++ if (current->brute) {
25170 ++ set_current_state(TASK_UNINTERRUPTIBLE);
25171 ++ schedule_timeout(30 * HZ);
25172 ++ }
25173 ++#endif
25174 ++ return;
25175 ++}
25176 ++
25177 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_sock.c linux-2.6.23.15-grsec/grsecurity/grsec_sock.c
25178 +--- linux-2.6.23.15/grsecurity/grsec_sock.c 1970-01-01 01:00:00.000000000 +0100
25179 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_sock.c 2008-02-11 10:37:44.000000000 +0000
25180 +@@ -0,0 +1,263 @@
25181 ++#include <linux/kernel.h>
25182 ++#include <linux/module.h>
25183 ++#include <linux/sched.h>
25184 ++#include <linux/file.h>
25185 ++#include <linux/net.h>
25186 ++#include <linux/in.h>
25187 ++#include <linux/ip.h>
25188 ++#include <net/sock.h>
25189 ++#include <net/inet_sock.h>
25190 ++#include <linux/grsecurity.h>
25191 ++#include <linux/grinternal.h>
25192 ++#include <linux/gracl.h>
25193 ++
25194 ++#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
25195 ++extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
25196 ++EXPORT_SYMBOL(udp_v4_lookup);
25197 ++#endif
25198 ++
25199 ++EXPORT_SYMBOL(gr_cap_rtnetlink);
25200 ++
25201 ++extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
25202 ++extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
25203 ++
25204 ++EXPORT_SYMBOL(gr_search_udp_recvmsg);
25205 ++EXPORT_SYMBOL(gr_search_udp_sendmsg);
25206 ++
25207 ++#ifdef CONFIG_UNIX_MODULE
25208 ++EXPORT_SYMBOL(gr_acl_handle_unix);
25209 ++EXPORT_SYMBOL(gr_acl_handle_mknod);
25210 ++EXPORT_SYMBOL(gr_handle_chroot_unix);
25211 ++EXPORT_SYMBOL(gr_handle_create);
25212 ++#endif
25213 ++
25214 ++#ifdef CONFIG_GRKERNSEC
25215 ++#define gr_conn_table_size 32749
25216 ++struct conn_table_entry {
25217 ++ struct conn_table_entry *next;
25218 ++ struct signal_struct *sig;
25219 ++};
25220 ++
25221 ++struct conn_table_entry *gr_conn_table[gr_conn_table_size];
25222 ++spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED;
25223 ++
25224 ++extern const char * gr_socktype_to_name(unsigned char type);
25225 ++extern const char * gr_proto_to_name(unsigned char proto);
25226 ++
25227 ++static __inline__ int
25228 ++conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
25229 ++{
25230 ++ return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
25231 ++}
25232 ++
25233 ++static __inline__ int
25234 ++conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr,
25235 ++ __u16 sport, __u16 dport)
25236 ++{
25237 ++ if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
25238 ++ sig->gr_sport == sport && sig->gr_dport == dport))
25239 ++ return 1;
25240 ++ else
25241 ++ return 0;
25242 ++}
25243 ++
25244 ++static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
25245 ++{
25246 ++ struct conn_table_entry **match;
25247 ++ unsigned int index;
25248 ++
25249 ++ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
25250 ++ sig->gr_sport, sig->gr_dport,
25251 ++ gr_conn_table_size);
25252 ++
25253 ++ newent->sig = sig;
25254 ++
25255 ++ match = &gr_conn_table[index];
25256 ++ newent->next = *match;
25257 ++ *match = newent;
25258 ++
25259 ++ return;
25260 ++}
25261 ++
25262 ++static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
25263 ++{
25264 ++ struct conn_table_entry *match, *last = NULL;
25265 ++ unsigned int index;
25266 ++
25267 ++ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
25268 ++ sig->gr_sport, sig->gr_dport,
25269 ++ gr_conn_table_size);
25270 ++
25271 ++ match = gr_conn_table[index];
25272 ++ while (match && !conn_match(match->sig,
25273 ++ sig->gr_saddr, sig->gr_daddr, sig->gr_sport,
25274 ++ sig->gr_dport)) {
25275 ++ last = match;
25276 ++ match = match->next;
25277 ++ }
25278 ++
25279 ++ if (match) {
25280 ++ if (last)
25281 ++ last->next = match->next;
25282 ++ else
25283 ++ gr_conn_table[index] = NULL;
25284 ++ kfree(match);
25285 ++ }
25286 ++
25287 ++ return;
25288 ++}
25289 ++
25290 ++static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
25291 ++ __u16 sport, __u16 dport)
25292 ++{
25293 ++ struct conn_table_entry *match;
25294 ++ unsigned int index;
25295 ++
25296 ++ index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
25297 ++
25298 ++ match = gr_conn_table[index];
25299 ++ while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
25300 ++ match = match->next;
25301 ++
25302 ++ if (match)
25303 ++ return match->sig;
25304 ++ else
25305 ++ return NULL;
25306 ++}
25307 ++
25308 ++#endif
25309 ++
25310 ++void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
25311 ++{
25312 ++#ifdef CONFIG_GRKERNSEC
25313 ++ struct signal_struct *sig = task->signal;
25314 ++ struct conn_table_entry *newent;
25315 ++
25316 ++ newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
25317 ++ if (newent == NULL)
25318 ++ return;
25319 ++ /* no bh lock needed since we are called with bh disabled */
25320 ++ spin_lock(&gr_conn_table_lock);
25321 ++ gr_del_task_from_ip_table_nolock(sig);
25322 ++ sig->gr_saddr = inet->rcv_saddr;
25323 ++ sig->gr_daddr = inet->daddr;
25324 ++ sig->gr_sport = inet->sport;
25325 ++ sig->gr_dport = inet->dport;
25326 ++ gr_add_to_task_ip_table_nolock(sig, newent);
25327 ++ spin_unlock(&gr_conn_table_lock);
25328 ++#endif
25329 ++ return;
25330 ++}
25331 ++
25332 ++void gr_del_task_from_ip_table(struct task_struct *task)
25333 ++{
25334 ++#ifdef CONFIG_GRKERNSEC
25335 ++ spin_lock(&gr_conn_table_lock);
25336 ++ gr_del_task_from_ip_table_nolock(task->signal);
25337 ++ spin_unlock(&gr_conn_table_lock);
25338 ++#endif
25339 ++ return;
25340 ++}
25341 ++
25342 ++void
25343 ++gr_attach_curr_ip(const struct sock *sk)
25344 ++{
25345 ++#ifdef CONFIG_GRKERNSEC
25346 ++ struct signal_struct *p, *set;
25347 ++ const struct inet_sock *inet = inet_sk(sk);
25348 ++
25349 ++ if (unlikely(sk->sk_protocol != IPPROTO_TCP))
25350 ++ return;
25351 ++
25352 ++ set = current->signal;
25353 ++
25354 ++ spin_lock_bh(&gr_conn_table_lock);
25355 ++ p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
25356 ++ inet->dport, inet->sport);
25357 ++ if (unlikely(p != NULL)) {
25358 ++ set->curr_ip = p->curr_ip;
25359 ++ set->used_accept = 1;
25360 ++ gr_del_task_from_ip_table_nolock(p);
25361 ++ spin_unlock_bh(&gr_conn_table_lock);
25362 ++ return;
25363 ++ }
25364 ++ spin_unlock_bh(&gr_conn_table_lock);
25365 ++
25366 ++ set->curr_ip = inet->daddr;
25367 ++ set->used_accept = 1;
25368 ++#endif
25369 ++ return;
25370 ++}
25371 ++
25372 ++int
25373 ++gr_handle_sock_all(const int family, const int type, const int protocol)
25374 ++{
25375 ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
25376 ++ if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
25377 ++ (family != AF_UNIX) && (family != AF_LOCAL)) {
25378 ++ gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
25379 ++ return -EACCES;
25380 ++ }
25381 ++#endif
25382 ++ return 0;
25383 ++}
25384 ++
25385 ++int
25386 ++gr_handle_sock_server(const struct sockaddr *sck)
25387 ++{
25388 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
25389 ++ if (grsec_enable_socket_server &&
25390 ++ in_group_p(grsec_socket_server_gid) &&
25391 ++ sck && (sck->sa_family != AF_UNIX) &&
25392 ++ (sck->sa_family != AF_LOCAL)) {
25393 ++ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
25394 ++ return -EACCES;
25395 ++ }
25396 ++#endif
25397 ++ return 0;
25398 ++}
25399 ++
25400 ++int
25401 ++gr_handle_sock_server_other(const struct sock *sck)
25402 ++{
25403 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
25404 ++ if (grsec_enable_socket_server &&
25405 ++ in_group_p(grsec_socket_server_gid) &&
25406 ++ sck && (sck->sk_family != AF_UNIX) &&
25407 ++ (sck->sk_family != AF_LOCAL)) {
25408 ++ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
25409 ++ return -EACCES;
25410 ++ }
25411 ++#endif
25412 ++ return 0;
25413 ++}
25414 ++
25415 ++int
25416 ++gr_handle_sock_client(const struct sockaddr *sck)
25417 ++{
25418 ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
25419 ++ if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
25420 ++ sck && (sck->sa_family != AF_UNIX) &&
25421 ++ (sck->sa_family != AF_LOCAL)) {
25422 ++ gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
25423 ++ return -EACCES;
25424 ++ }
25425 ++#endif
25426 ++ return 0;
25427 ++}
25428 ++
25429 ++__u32
25430 ++gr_cap_rtnetlink(void)
25431 ++{
25432 ++#ifdef CONFIG_GRKERNSEC
25433 ++ if (!gr_acl_is_enabled())
25434 ++ return current->cap_effective;
25435 ++ else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
25436 ++ gr_task_is_capable(current, CAP_NET_ADMIN))
25437 ++ return current->cap_effective;
25438 ++ else
25439 ++ return 0;
25440 ++#else
25441 ++ return current->cap_effective;
25442 ++#endif
25443 ++}
25444 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_sysctl.c linux-2.6.23.15-grsec/grsecurity/grsec_sysctl.c
25445 +--- linux-2.6.23.15/grsecurity/grsec_sysctl.c 1970-01-01 01:00:00.000000000 +0100
25446 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_sysctl.c 2008-02-11 10:37:44.000000000 +0000
25447 +@@ -0,0 +1,456 @@
25448 ++#include <linux/kernel.h>
25449 ++#include <linux/sched.h>
25450 ++#include <linux/sysctl.h>
25451 ++#include <linux/grsecurity.h>
25452 ++#include <linux/grinternal.h>
25453 ++
25454 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
25455 ++int grsec_modstop;
25456 ++#endif
25457 ++
25458 ++int
25459 ++gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
25460 ++{
25461 ++#ifdef CONFIG_GRKERNSEC_SYSCTL
25462 ++ if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
25463 ++ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
25464 ++ return -EACCES;
25465 ++ }
25466 ++#endif
25467 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
25468 ++ if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
25469 ++ grsec_modstop && (op & 002)) {
25470 ++ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
25471 ++ return -EACCES;
25472 ++ }
25473 ++#endif
25474 ++ return 0;
25475 ++}
25476 ++
25477 ++#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
25478 ++enum {GS_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL,
25479 ++GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, GS_CHROOT_UNIX, GS_CHROOT_MNT,
25480 ++GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM,
25481 ++GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS,
25482 ++GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL, GS_SIDCAPS,
25483 ++GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT,
25484 ++GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID,
25485 ++GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG,
25486 ++GS_TEXTREL, GS_FINDTASK, GS_SHM, GS_LOCK, GS_MODSTOP, GS_RESLOG};
25487 ++
25488 ++
25489 ++ctl_table grsecurity_table[] = {
25490 ++#ifdef CONFIG_GRKERNSEC_SYSCTL
25491 ++#ifdef CONFIG_GRKERNSEC_LINK
25492 ++ {
25493 ++ .ctl_name = GS_LINK,
25494 ++ .procname = "linking_restrictions",
25495 ++ .data = &grsec_enable_link,
25496 ++ .maxlen = sizeof(int),
25497 ++ .mode = 0600,
25498 ++ .proc_handler = &proc_dointvec,
25499 ++ },
25500 ++#endif
25501 ++#ifdef CONFIG_GRKERNSEC_FIFO
25502 ++ {
25503 ++ .ctl_name = GS_FIFO,
25504 ++ .procname = "fifo_restrictions",
25505 ++ .data = &grsec_enable_fifo,
25506 ++ .maxlen = sizeof(int),
25507 ++ .mode = 0600,
25508 ++ .proc_handler = &proc_dointvec,
25509 ++ },
25510 ++#endif
25511 ++#ifdef CONFIG_GRKERNSEC_EXECVE
25512 ++ {
25513 ++ .ctl_name = GS_EXECVE,
25514 ++ .procname = "execve_limiting",
25515 ++ .data = &grsec_enable_execve,
25516 ++ .maxlen = sizeof(int),
25517 ++ .mode = 0600,
25518 ++ .proc_handler = &proc_dointvec,
25519 ++ },
25520 ++#endif
25521 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
25522 ++ {
25523 ++ .ctl_name = GS_EXECLOG,
25524 ++ .procname = "exec_logging",
25525 ++ .data = &grsec_enable_execlog,
25526 ++ .maxlen = sizeof(int),
25527 ++ .mode = 0600,
25528 ++ .proc_handler = &proc_dointvec,
25529 ++ },
25530 ++#endif
25531 ++#ifdef CONFIG_GRKERNSEC_SIGNAL
25532 ++ {
25533 ++ .ctl_name = GS_SIGNAL,
25534 ++ .procname = "signal_logging",
25535 ++ .data = &grsec_enable_signal,
25536 ++ .maxlen = sizeof(int),
25537 ++ .mode = 0600,
25538 ++ .proc_handler = &proc_dointvec,
25539 ++ },
25540 ++#endif
25541 ++#ifdef CONFIG_GRKERNSEC_FORKFAIL
25542 ++ {
25543 ++ .ctl_name = GS_FORKFAIL,
25544 ++ .procname = "forkfail_logging",
25545 ++ .data = &grsec_enable_forkfail,
25546 ++ .maxlen = sizeof(int),
25547 ++ .mode = 0600,
25548 ++ .proc_handler = &proc_dointvec,
25549 ++ },
25550 ++#endif
25551 ++#ifdef CONFIG_GRKERNSEC_TIME
25552 ++ {
25553 ++ .ctl_name = GS_TIME,
25554 ++ .procname = "timechange_logging",
25555 ++ .data = &grsec_enable_time,
25556 ++ .maxlen = sizeof(int),
25557 ++ .mode = 0600,
25558 ++ .proc_handler = &proc_dointvec,
25559 ++ },
25560 ++#endif
25561 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
25562 ++ {
25563 ++ .ctl_name = GS_CHROOT_SHMAT,
25564 ++ .procname = "chroot_deny_shmat",
25565 ++ .data = &grsec_enable_chroot_shmat,
25566 ++ .maxlen = sizeof(int),
25567 ++ .mode = 0600,
25568 ++ .proc_handler = &proc_dointvec,
25569 ++ },
25570 ++#endif
25571 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
25572 ++ {
25573 ++ .ctl_name = GS_CHROOT_UNIX,
25574 ++ .procname = "chroot_deny_unix",
25575 ++ .data = &grsec_enable_chroot_unix,
25576 ++ .maxlen = sizeof(int),
25577 ++ .mode = 0600,
25578 ++ .proc_handler = &proc_dointvec,
25579 ++ },
25580 ++#endif
25581 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
25582 ++ {
25583 ++ .ctl_name = GS_CHROOT_MNT,
25584 ++ .procname = "chroot_deny_mount",
25585 ++ .data = &grsec_enable_chroot_mount,
25586 ++ .maxlen = sizeof(int),
25587 ++ .mode = 0600,
25588 ++ .proc_handler = &proc_dointvec,
25589 ++ },
25590 ++#endif
25591 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
25592 ++ {
25593 ++ .ctl_name = GS_CHROOT_FCHDIR,
25594 ++ .procname = "chroot_deny_fchdir",
25595 ++ .data = &grsec_enable_chroot_fchdir,
25596 ++ .maxlen = sizeof(int),
25597 ++ .mode = 0600,
25598 ++ .proc_handler = &proc_dointvec,
25599 ++ },
25600 ++#endif
25601 ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
25602 ++ {
25603 ++ .ctl_name = GS_CHROOT_DBL,
25604 ++ .procname = "chroot_deny_chroot",
25605 ++ .data = &grsec_enable_chroot_double,
25606 ++ .maxlen = sizeof(int),
25607 ++ .mode = 0600,
25608 ++ .proc_handler = &proc_dointvec,
25609 ++ },
25610 ++#endif
25611 ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
25612 ++ {
25613 ++ .ctl_name = GS_CHROOT_PVT,
25614 ++ .procname = "chroot_deny_pivot",
25615 ++ .data = &grsec_enable_chroot_pivot,
25616 ++ .maxlen = sizeof(int),
25617 ++ .mode = 0600,
25618 ++ .proc_handler = &proc_dointvec,
25619 ++ },
25620 ++#endif
25621 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
25622 ++ {
25623 ++ .ctl_name = GS_CHROOT_CD,
25624 ++ .procname = "chroot_enforce_chdir",
25625 ++ .data = &grsec_enable_chroot_chdir,
25626 ++ .maxlen = sizeof(int),
25627 ++ .mode = 0600,
25628 ++ .proc_handler = &proc_dointvec,
25629 ++ },
25630 ++#endif
25631 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
25632 ++ {
25633 ++ .ctl_name = GS_CHROOT_CM,
25634 ++ .procname = "chroot_deny_chmod",
25635 ++ .data = &grsec_enable_chroot_chmod,
25636 ++ .maxlen = sizeof(int),
25637 ++ .mode = 0600,
25638 ++ .proc_handler = &proc_dointvec,
25639 ++ },
25640 ++#endif
25641 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
25642 ++ {
25643 ++ .ctl_name = GS_CHROOT_MK,
25644 ++ .procname = "chroot_deny_mknod",
25645 ++ .data = &grsec_enable_chroot_mknod,
25646 ++ .maxlen = sizeof(int),
25647 ++ .mode = 0600,
25648 ++ .proc_handler = &proc_dointvec,
25649 ++ },
25650 ++#endif
25651 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
25652 ++ {
25653 ++ .ctl_name = GS_CHROOT_NI,
25654 ++ .procname = "chroot_restrict_nice",
25655 ++ .data = &grsec_enable_chroot_nice,
25656 ++ .maxlen = sizeof(int),
25657 ++ .mode = 0600,
25658 ++ .proc_handler = &proc_dointvec,
25659 ++ },
25660 ++#endif
25661 ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
25662 ++ {
25663 ++ .ctl_name = GS_CHROOT_EXECLOG,
25664 ++ .procname = "chroot_execlog",
25665 ++ .data = &grsec_enable_chroot_execlog,
25666 ++ .maxlen = sizeof(int),
25667 ++ .mode = 0600,
25668 ++ .proc_handler = &proc_dointvec,
25669 ++ },
25670 ++#endif
25671 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
25672 ++ {
25673 ++ .ctl_name = GS_CHROOT_CAPS,
25674 ++ .procname = "chroot_caps",
25675 ++ .data = &grsec_enable_chroot_caps,
25676 ++ .maxlen = sizeof(int),
25677 ++ .mode = 0600,
25678 ++ .proc_handler = &proc_dointvec,
25679 ++ },
25680 ++#endif
25681 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
25682 ++ {
25683 ++ .ctl_name = GS_CHROOT_SYSCTL,
25684 ++ .procname = "chroot_deny_sysctl",
25685 ++ .data = &grsec_enable_chroot_sysctl,
25686 ++ .maxlen = sizeof(int),
25687 ++ .mode = 0600,
25688 ++ .proc_handler = &proc_dointvec,
25689 ++ },
25690 ++#endif
25691 ++#ifdef CONFIG_GRKERNSEC_TPE
25692 ++ {
25693 ++ .ctl_name = GS_TPE,
25694 ++ .procname = "tpe",
25695 ++ .data = &grsec_enable_tpe,
25696 ++ .maxlen = sizeof(int),
25697 ++ .mode = 0600,
25698 ++ .proc_handler = &proc_dointvec,
25699 ++ },
25700 ++ {
25701 ++ .ctl_name = GS_TPE_GID,
25702 ++ .procname = "tpe_gid",
25703 ++ .data = &grsec_tpe_gid,
25704 ++ .maxlen = sizeof(int),
25705 ++ .mode = 0600,
25706 ++ .proc_handler = &proc_dointvec,
25707 ++ },
25708 ++#endif
25709 ++#ifdef CONFIG_GRKERNSEC_TPE_ALL
25710 ++ {
25711 ++ .ctl_name = GS_TPE_ALL,
25712 ++ .procname = "tpe_restrict_all",
25713 ++ .data = &grsec_enable_tpe_all,
25714 ++ .maxlen = sizeof(int),
25715 ++ .mode = 0600,
25716 ++ .proc_handler = &proc_dointvec,
25717 ++ },
25718 ++#endif
25719 ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
25720 ++ {
25721 ++ .ctl_name = GS_SOCKET_ALL,
25722 ++ .procname = "socket_all",
25723 ++ .data = &grsec_enable_socket_all,
25724 ++ .maxlen = sizeof(int),
25725 ++ .mode = 0600,
25726 ++ .proc_handler = &proc_dointvec,
25727 ++ },
25728 ++ {
25729 ++ .ctl_name = GS_SOCKET_ALL_GID,
25730 ++ .procname = "socket_all_gid",
25731 ++ .data = &grsec_socket_all_gid,
25732 ++ .maxlen = sizeof(int),
25733 ++ .mode = 0600,
25734 ++ .proc_handler = &proc_dointvec,
25735 ++ },
25736 ++#endif
25737 ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
25738 ++ {
25739 ++ .ctl_name = GS_SOCKET_CLIENT,
25740 ++ .procname = "socket_client",
25741 ++ .data = &grsec_enable_socket_client,
25742 ++ .maxlen = sizeof(int),
25743 ++ .mode = 0600,
25744 ++ .proc_handler = &proc_dointvec,
25745 ++ },
25746 ++ {
25747 ++ .ctl_name = GS_SOCKET_CLIENT_GID,
25748 ++ .procname = "socket_client_gid",
25749 ++ .data = &grsec_socket_client_gid,
25750 ++ .maxlen = sizeof(int),
25751 ++ .mode = 0600,
25752 ++ .proc_handler = &proc_dointvec,
25753 ++ },
25754 ++#endif
25755 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
25756 ++ {
25757 ++ .ctl_name = GS_SOCKET_SERVER,
25758 ++ .procname = "socket_server",
25759 ++ .data = &grsec_enable_socket_server,
25760 ++ .maxlen = sizeof(int),
25761 ++ .mode = 0600,
25762 ++ .proc_handler = &proc_dointvec,
25763 ++ },
25764 ++ {
25765 ++ .ctl_name = GS_SOCKET_SERVER_GID,
25766 ++ .procname = "socket_server_gid",
25767 ++ .data = &grsec_socket_server_gid,
25768 ++ .maxlen = sizeof(int),
25769 ++ .mode = 0600,
25770 ++ .proc_handler = &proc_dointvec,
25771 ++ },
25772 ++#endif
25773 ++#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
25774 ++ {
25775 ++ .ctl_name = GS_GROUP,
25776 ++ .procname = "audit_group",
25777 ++ .data = &grsec_enable_group,
25778 ++ .maxlen = sizeof(int),
25779 ++ .mode = 0600,
25780 ++ .proc_handler = &proc_dointvec,
25781 ++ },
25782 ++ {
25783 ++ .ctl_name = GS_GID,
25784 ++ .procname = "audit_gid",
25785 ++ .data = &grsec_audit_gid,
25786 ++ .maxlen = sizeof(int),
25787 ++ .mode = 0600,
25788 ++ .proc_handler = &proc_dointvec,
25789 ++ },
25790 ++#endif
25791 ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
25792 ++ {
25793 ++ .ctl_name = GS_ACHDIR,
25794 ++ .procname = "audit_chdir",
25795 ++ .data = &grsec_enable_chdir,
25796 ++ .maxlen = sizeof(int),
25797 ++ .mode = 0600,
25798 ++ .proc_handler = &proc_dointvec,
25799 ++ },
25800 ++#endif
25801 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
25802 ++ {
25803 ++ .ctl_name = GS_AMOUNT,
25804 ++ .procname = "audit_mount",
25805 ++ .data = &grsec_enable_mount,
25806 ++ .maxlen = sizeof(int),
25807 ++ .mode = 0600,
25808 ++ .proc_handler = &proc_dointvec,
25809 ++ },
25810 ++#endif
25811 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
25812 ++ {
25813 ++ .ctl_name = GS_AIPC,
25814 ++ .procname = "audit_ipc",
25815 ++ .data = &grsec_enable_audit_ipc,
25816 ++ .maxlen = sizeof(int),
25817 ++ .mode = 0600,
25818 ++ .proc_handler = &proc_dointvec,
25819 ++ },
25820 ++#endif
25821 ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
25822 ++ {
25823 ++ .ctl_name = GS_TEXTREL,
25824 ++ .procname = "audit_textrel",
25825 ++ .data = &grsec_enable_audit_textrel,
25826 ++ .maxlen = sizeof(int),
25827 ++ .mode = 0600,
25828 ++ .proc_handler = &proc_dointvec,
25829 ++ },
25830 ++#endif
25831 ++#ifdef CONFIG_GRKERNSEC_DMESG
25832 ++ {
25833 ++ .ctl_name = GS_DMSG,
25834 ++ .procname = "dmesg",
25835 ++ .data = &grsec_enable_dmesg,
25836 ++ .maxlen = sizeof(int),
25837 ++ .mode = 0600,
25838 ++ .proc_handler = &proc_dointvec,
25839 ++ },
25840 ++#endif
25841 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
25842 ++ {
25843 ++ .ctl_name = GS_FINDTASK,
25844 ++ .procname = "chroot_findtask",
25845 ++ .data = &grsec_enable_chroot_findtask,
25846 ++ .maxlen = sizeof(int),
25847 ++ .mode = 0600,
25848 ++ .proc_handler = &proc_dointvec,
25849 ++ },
25850 ++#endif
25851 ++#ifdef CONFIG_GRKERNSEC_SHM
25852 ++ {
25853 ++ .ctl_name = GS_SHM,
25854 ++ .procname = "destroy_unused_shm",
25855 ++ .data = &grsec_enable_shm,
25856 ++ .maxlen = sizeof(int),
25857 ++ .mode = 0600,
25858 ++ .proc_handler = &proc_dointvec,
25859 ++ },
25860 ++#endif
25861 ++#ifdef CONFIG_GRKERNSEC_RESLOG
25862 ++ {
25863 ++ .ctl_name = GS_RESLOG,
25864 ++ .procname = "resource_logging",
25865 ++ .data = &grsec_resource_logging,
25866 ++ .maxlen = sizeof(int),
25867 ++ .mode = 0600,
25868 ++ .proc_handler = &proc_dointvec,
25869 ++ },
25870 ++#endif
25871 ++ {
25872 ++ .ctl_name = GS_LOCK,
25873 ++ .procname = "grsec_lock",
25874 ++ .data = &grsec_lock,
25875 ++ .maxlen = sizeof(int),
25876 ++ .mode = 0600,
25877 ++ .proc_handler = &proc_dointvec,
25878 ++ },
25879 ++#endif
25880 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
25881 ++ {
25882 ++ .ctl_name = GS_MODSTOP,
25883 ++ .procname = "disable_modules",
25884 ++ .data = &grsec_modstop,
25885 ++ .maxlen = sizeof(int),
25886 ++ .mode = 0600,
25887 ++ .proc_handler = &proc_dointvec,
25888 ++ },
25889 ++#endif
25890 ++ { .ctl_name = 0 }
25891 ++};
25892 ++#endif
25893 ++
25894 ++int gr_check_modstop(void)
25895 ++{
25896 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
25897 ++ if (grsec_modstop == 1) {
25898 ++ gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
25899 ++ return 1;
25900 ++ }
25901 ++#endif
25902 ++ return 0;
25903 ++}
25904 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_textrel.c linux-2.6.23.15-grsec/grsecurity/grsec_textrel.c
25905 +--- linux-2.6.23.15/grsecurity/grsec_textrel.c 1970-01-01 01:00:00.000000000 +0100
25906 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_textrel.c 2008-02-11 10:37:44.000000000 +0000
25907 +@@ -0,0 +1,16 @@
25908 ++#include <linux/kernel.h>
25909 ++#include <linux/sched.h>
25910 ++#include <linux/mm.h>
25911 ++#include <linux/file.h>
25912 ++#include <linux/grinternal.h>
25913 ++#include <linux/grsecurity.h>
25914 ++
25915 ++void
25916 ++gr_log_textrel(struct vm_area_struct * vma)
25917 ++{
25918 ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
25919 ++ if (grsec_enable_audit_textrel)
25920 ++ gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
25921 ++#endif
25922 ++ return;
25923 ++}
25924 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_time.c linux-2.6.23.15-grsec/grsecurity/grsec_time.c
25925 +--- linux-2.6.23.15/grsecurity/grsec_time.c 1970-01-01 01:00:00.000000000 +0100
25926 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_time.c 2008-02-11 10:37:44.000000000 +0000
25927 +@@ -0,0 +1,13 @@
25928 ++#include <linux/kernel.h>
25929 ++#include <linux/sched.h>
25930 ++#include <linux/grinternal.h>
25931 ++
25932 ++void
25933 ++gr_log_timechange(void)
25934 ++{
25935 ++#ifdef CONFIG_GRKERNSEC_TIME
25936 ++ if (grsec_enable_time)
25937 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
25938 ++#endif
25939 ++ return;
25940 ++}
25941 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_tpe.c linux-2.6.23.15-grsec/grsecurity/grsec_tpe.c
25942 +--- linux-2.6.23.15/grsecurity/grsec_tpe.c 1970-01-01 01:00:00.000000000 +0100
25943 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_tpe.c 2008-02-11 10:37:44.000000000 +0000
25944 +@@ -0,0 +1,37 @@
25945 ++#include <linux/kernel.h>
25946 ++#include <linux/sched.h>
25947 ++#include <linux/file.h>
25948 ++#include <linux/fs.h>
25949 ++#include <linux/grinternal.h>
25950 ++
25951 ++extern int gr_acl_tpe_check(void);
25952 ++
25953 ++int
25954 ++gr_tpe_allow(const struct file *file)
25955 ++{
25956 ++#ifdef CONFIG_GRKERNSEC
25957 ++ struct inode *inode = file->f_dentry->d_parent->d_inode;
25958 ++
25959 ++ if (current->uid && ((grsec_enable_tpe &&
25960 ++#ifdef CONFIG_GRKERNSEC_TPE_INVERT
25961 ++ !in_group_p(grsec_tpe_gid)
25962 ++#else
25963 ++ in_group_p(grsec_tpe_gid)
25964 ++#endif
25965 ++ ) || gr_acl_tpe_check()) &&
25966 ++ (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
25967 ++ (inode->i_mode & S_IWOTH))))) {
25968 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
25969 ++ return 0;
25970 ++ }
25971 ++#ifdef CONFIG_GRKERNSEC_TPE_ALL
25972 ++ if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
25973 ++ ((inode->i_uid && (inode->i_uid != current->uid)) ||
25974 ++ (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
25975 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
25976 ++ return 0;
25977 ++ }
25978 ++#endif
25979 ++#endif
25980 ++ return 1;
25981 ++}
25982 +diff -Nurp linux-2.6.23.15/grsecurity/grsum.c linux-2.6.23.15-grsec/grsecurity/grsum.c
25983 +--- linux-2.6.23.15/grsecurity/grsum.c 1970-01-01 01:00:00.000000000 +0100
25984 ++++ linux-2.6.23.15-grsec/grsecurity/grsum.c 2008-02-11 10:37:44.000000000 +0000
25985 +@@ -0,0 +1,59 @@
25986 ++#include <linux/err.h>
25987 ++#include <linux/kernel.h>
25988 ++#include <linux/sched.h>
25989 ++#include <linux/mm.h>
25990 ++#include <linux/scatterlist.h>
25991 ++#include <linux/crypto.h>
25992 ++#include <linux/gracl.h>
25993 ++
25994 ++
25995 ++#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
25996 ++#error "crypto and sha256 must be built into the kernel"
25997 ++#endif
25998 ++
25999 ++int
26000 ++chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
26001 ++{
26002 ++ char *p;
26003 ++ struct crypto_hash *tfm;
26004 ++ struct hash_desc desc;
26005 ++ struct scatterlist sg;
26006 ++ unsigned char temp_sum[GR_SHA_LEN];
26007 ++ volatile int retval = 0;
26008 ++ volatile int dummy = 0;
26009 ++ unsigned int i;
26010 ++
26011 ++ tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
26012 ++ if (IS_ERR(tfm)) {
26013 ++ /* should never happen, since sha256 should be built in */
26014 ++ return 1;
26015 ++ }
26016 ++
26017 ++ desc.tfm = tfm;
26018 ++ desc.flags = 0;
26019 ++
26020 ++ crypto_hash_init(&desc);
26021 ++
26022 ++ p = salt;
26023 ++ sg_set_buf(&sg, p, GR_SALT_LEN);
26024 ++ crypto_hash_update(&desc, &sg, sg.length);
26025 ++
26026 ++ p = entry->pw;
26027 ++ sg_set_buf(&sg, p, strlen(p));
26028 ++
26029 ++ crypto_hash_update(&desc, &sg, sg.length);
26030 ++
26031 ++ crypto_hash_final(&desc, temp_sum);
26032 ++
26033 ++ memset(entry->pw, 0, GR_PW_LEN);
26034 ++
26035 ++ for (i = 0; i < GR_SHA_LEN; i++)
26036 ++ if (sum[i] != temp_sum[i])
26037 ++ retval = 1;
26038 ++ else
26039 ++ dummy = 1; // waste a cycle
26040 ++
26041 ++ crypto_free_hash(tfm);
26042 ++
26043 ++ return retval;
26044 ++}
26045 +diff -Nurp linux-2.6.23.15/include/asm-alpha/a.out.h linux-2.6.23.15-grsec/include/asm-alpha/a.out.h
26046 +--- linux-2.6.23.15/include/asm-alpha/a.out.h 2007-10-09 21:31:38.000000000 +0100
26047 ++++ linux-2.6.23.15-grsec/include/asm-alpha/a.out.h 2008-02-11 10:37:44.000000000 +0000
26048 +@@ -98,7 +98,7 @@ struct exec
26049 + set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000L \
26050 + ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
26051 +
26052 +-#define STACK_TOP \
26053 ++#define __STACK_TOP \
26054 + (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
26055 +
26056 + #define STACK_TOP_MAX 0x00120000000UL
26057 +diff -Nurp linux-2.6.23.15/include/asm-alpha/elf.h linux-2.6.23.15-grsec/include/asm-alpha/elf.h
26058 +--- linux-2.6.23.15/include/asm-alpha/elf.h 2007-10-09 21:31:38.000000000 +0100
26059 ++++ linux-2.6.23.15-grsec/include/asm-alpha/elf.h 2008-02-11 10:37:44.000000000 +0000
26060 +@@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
26061 +
26062 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
26063 +
26064 ++#ifdef CONFIG_PAX_ASLR
26065 ++#define PAX_ELF_ET_DYN_BASE (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
26066 ++
26067 ++#define PAX_DELTA_MMAP_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 28)
26068 ++#define PAX_DELTA_STACK_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 19)
26069 ++#endif
26070 ++
26071 + /* $0 is set by ld.so to a pointer to a function which might be
26072 + registered using atexit. This provides a mean for the dynamic
26073 + linker to call DT_FINI functions for shared libraries that have
26074 +diff -Nurp linux-2.6.23.15/include/asm-alpha/kmap_types.h linux-2.6.23.15-grsec/include/asm-alpha/kmap_types.h
26075 +--- linux-2.6.23.15/include/asm-alpha/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
26076 ++++ linux-2.6.23.15-grsec/include/asm-alpha/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
26077 +@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
26078 + D(10) KM_IRQ1,
26079 + D(11) KM_SOFTIRQ0,
26080 + D(12) KM_SOFTIRQ1,
26081 +-D(13) KM_TYPE_NR
26082 ++D(13) KM_CLEARPAGE,
26083 ++D(14) KM_TYPE_NR
26084 + };
26085 +
26086 + #undef D
26087 +diff -Nurp linux-2.6.23.15/include/asm-alpha/pgtable.h linux-2.6.23.15-grsec/include/asm-alpha/pgtable.h
26088 +--- linux-2.6.23.15/include/asm-alpha/pgtable.h 2007-10-09 21:31:38.000000000 +0100
26089 ++++ linux-2.6.23.15-grsec/include/asm-alpha/pgtable.h 2008-02-11 10:37:44.000000000 +0000
26090 +@@ -101,6 +101,17 @@ struct vm_area_struct;
26091 + #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
26092 + #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
26093 + #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
26094 ++
26095 ++#ifdef CONFIG_PAX_PAGEEXEC
26096 ++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
26097 ++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
26098 ++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
26099 ++#else
26100 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
26101 ++# define PAGE_COPY_NOEXEC PAGE_COPY
26102 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
26103 ++#endif
26104 ++
26105 + #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
26106 +
26107 + #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
26108 +diff -Nurp linux-2.6.23.15/include/asm-arm/a.out.h linux-2.6.23.15-grsec/include/asm-arm/a.out.h
26109 +--- linux-2.6.23.15/include/asm-arm/a.out.h 2007-10-09 21:31:38.000000000 +0100
26110 ++++ linux-2.6.23.15-grsec/include/asm-arm/a.out.h 2008-02-11 10:37:44.000000000 +0000
26111 +@@ -28,7 +28,7 @@ struct exec
26112 + #define M_ARM 103
26113 +
26114 + #ifdef __KERNEL__
26115 +-#define STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \
26116 ++#define __STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \
26117 + TASK_SIZE : TASK_SIZE_26)
26118 + #define STACK_TOP_MAX TASK_SIZE
26119 + #endif
26120 +diff -Nurp linux-2.6.23.15/include/asm-arm/elf.h linux-2.6.23.15-grsec/include/asm-arm/elf.h
26121 +--- linux-2.6.23.15/include/asm-arm/elf.h 2007-10-09 21:31:38.000000000 +0100
26122 ++++ linux-2.6.23.15-grsec/include/asm-arm/elf.h 2008-02-11 10:37:44.000000000 +0000
26123 +@@ -90,6 +90,13 @@ extern char elf_platform[];
26124 +
26125 + #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
26126 +
26127 ++#ifdef CONFIG_PAX_ASLR
26128 ++#define PAX_ELF_ET_DYN_BASE 0x00008000UL
26129 ++
26130 ++#define PAX_DELTA_MMAP_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
26131 ++#define PAX_DELTA_STACK_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
26132 ++#endif
26133 ++
26134 + /* When the program starts, a1 contains a pointer to a function to be
26135 + registered with atexit, as per the SVR4 ABI. A value of 0 means we
26136 + have no such handler. */
26137 +diff -Nurp linux-2.6.23.15/include/asm-arm/kmap_types.h linux-2.6.23.15-grsec/include/asm-arm/kmap_types.h
26138 +--- linux-2.6.23.15/include/asm-arm/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
26139 ++++ linux-2.6.23.15-grsec/include/asm-arm/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
26140 +@@ -18,6 +18,7 @@ enum km_type {
26141 + KM_IRQ1,
26142 + KM_SOFTIRQ0,
26143 + KM_SOFTIRQ1,
26144 ++ KM_CLEARPAGE,
26145 + KM_TYPE_NR
26146 + };
26147 +
26148 +diff -Nurp linux-2.6.23.15/include/asm-avr32/a.out.h linux-2.6.23.15-grsec/include/asm-avr32/a.out.h
26149 +--- linux-2.6.23.15/include/asm-avr32/a.out.h 2007-10-09 21:31:38.000000000 +0100
26150 ++++ linux-2.6.23.15-grsec/include/asm-avr32/a.out.h 2008-02-11 10:37:44.000000000 +0000
26151 +@@ -19,8 +19,8 @@ struct exec
26152 +
26153 + #ifdef __KERNEL__
26154 +
26155 +-#define STACK_TOP TASK_SIZE
26156 +-#define STACK_TOP_MAX STACK_TOP
26157 ++#define __STACK_TOP TASK_SIZE
26158 ++#define STACK_TOP_MAX __STACK_TOP
26159 +
26160 + #endif
26161 +
26162 +diff -Nurp linux-2.6.23.15/include/asm-avr32/elf.h linux-2.6.23.15-grsec/include/asm-avr32/elf.h
26163 +--- linux-2.6.23.15/include/asm-avr32/elf.h 2007-10-09 21:31:38.000000000 +0100
26164 ++++ linux-2.6.23.15-grsec/include/asm-avr32/elf.h 2008-02-11 10:37:44.000000000 +0000
26165 +@@ -85,8 +85,14 @@ typedef struct user_fpu_struct elf_fpreg
26166 + the loader. We need to make sure that it is out of the way of the program
26167 + that it will "exec", and that there is sufficient room for the brk. */
26168 +
26169 +-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
26170 ++#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
26171 +
26172 ++#ifdef CONFIG_PAX_ASLR
26173 ++#define PAX_ELF_ET_DYN_BASE 0x00001000UL
26174 ++
26175 ++#define PAX_DELTA_MMAP_LEN 15
26176 ++#define PAX_DELTA_STACK_LEN 15
26177 ++#endif
26178 +
26179 + /* This yields a mask that user programs can use to figure out what
26180 + instruction set this CPU supports. This could be done in user space,
26181 +diff -Nurp linux-2.6.23.15/include/asm-avr32/kmap_types.h linux-2.6.23.15-grsec/include/asm-avr32/kmap_types.h
26182 +--- linux-2.6.23.15/include/asm-avr32/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
26183 ++++ linux-2.6.23.15-grsec/include/asm-avr32/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
26184 +@@ -22,7 +22,8 @@ D(10) KM_IRQ0,
26185 + D(11) KM_IRQ1,
26186 + D(12) KM_SOFTIRQ0,
26187 + D(13) KM_SOFTIRQ1,
26188 +-D(14) KM_TYPE_NR
26189 ++D(14) KM_CLEARPAGE,
26190 ++D(15) KM_TYPE_NR
26191 + };
26192 +
26193 + #undef D
26194 +diff -Nurp linux-2.6.23.15/include/asm-blackfin/kmap_types.h linux-2.6.23.15-grsec/include/asm-blackfin/kmap_types.h
26195 +--- linux-2.6.23.15/include/asm-blackfin/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
26196 ++++ linux-2.6.23.15-grsec/include/asm-blackfin/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
26197 +@@ -15,6 +15,7 @@ enum km_type {
26198 + KM_IRQ1,
26199 + KM_SOFTIRQ0,
26200 + KM_SOFTIRQ1,
26201 ++ KM_CLEARPAGE,
26202 + KM_TYPE_NR
26203 + };
26204 +
26205 +diff -Nurp linux-2.6.23.15/include/asm-cris/kmap_types.h linux-2.6.23.15-grsec/include/asm-cris/kmap_types.h
26206 +--- linux-2.6.23.15/include/asm-cris/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
26207 ++++ linux-2.6.23.15-grsec/include/asm-cris/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
26208 +@@ -19,6 +19,7 @@ enum km_type {
26209 + KM_IRQ1,
26210 + KM_SOFTIRQ0,
26211 + KM_SOFTIRQ1,
26212 ++ KM_CLEARPAGE,
26213 + KM_TYPE_NR
26214 + };
26215 +
26216 +diff -Nurp linux-2.6.23.15/include/asm-frv/kmap_types.h linux-2.6.23.15-grsec/include/asm-frv/kmap_types.h
26217 +--- linux-2.6.23.15/include/asm-frv/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
26218 ++++ linux-2.6.23.15-grsec/include/asm-frv/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
26219 +@@ -23,6 +23,7 @@ enum km_type {
26220 + KM_IRQ1,
26221 + KM_SOFTIRQ0,
26222 + KM_SOFTIRQ1,
26223 ++ KM_CLEARPAGE,
26224 + KM_TYPE_NR
26225 + };
26226 +
26227 +diff -Nurp linux-2.6.23.15/include/asm-generic/futex.h linux-2.6.23.15-grsec/include/asm-generic/futex.h
26228 +--- linux-2.6.23.15/include/asm-generic/futex.h 2007-10-09 21:31:38.000000000 +0100
26229 ++++ linux-2.6.23.15-grsec/include/asm-generic/futex.h 2008-02-11 10:37:44.000000000 +0000
26230 +@@ -8,7 +8,7 @@
26231 + #include <asm/uaccess.h>
26232 +
26233 + static inline int
26234 +-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
26235 ++futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
26236 + {
26237 + int op = (encoded_op >> 28) & 7;
26238 + int cmp = (encoded_op >> 24) & 15;
26239 +@@ -50,7 +50,7 @@ futex_atomic_op_inuser (int encoded_op,
26240 + }
26241 +
26242 + static inline int
26243 +-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
26244 ++futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
26245 + {
26246 + return -ENOSYS;
26247 + }
26248 +diff -Nurp linux-2.6.23.15/include/asm-generic/vmlinux.lds.h linux-2.6.23.15-grsec/include/asm-generic/vmlinux.lds.h
26249 +--- linux-2.6.23.15/include/asm-generic/vmlinux.lds.h 2007-10-09 21:31:38.000000000 +0100
26250 ++++ linux-2.6.23.15-grsec/include/asm-generic/vmlinux.lds.h 2008-02-11 10:37:44.000000000 +0000
26251 +@@ -19,6 +19,7 @@
26252 + .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
26253 + VMLINUX_SYMBOL(__start_rodata) = .; \
26254 + *(.rodata) *(.rodata.*) \
26255 ++ *(.data.read_only) \
26256 + *(__vermagic) /* Kernel version magic */ \
26257 + } \
26258 + \
26259 +diff -Nurp linux-2.6.23.15/include/asm-h8300/kmap_types.h linux-2.6.23.15-grsec/include/asm-h8300/kmap_types.h
26260 +--- linux-2.6.23.15/include/asm-h8300/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
26261 ++++ linux-2.6.23.15-grsec/include/asm-h8300/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
26262 +@@ -15,6 +15,7 @@ enum km_type {
26263 + KM_IRQ1,
26264 + KM_SOFTIRQ0,
26265 + KM_SOFTIRQ1,
26266 ++ KM_CLEARPAGE,
26267 + KM_TYPE_NR
26268 + };
26269 +
26270 +diff -Nurp linux-2.6.23.15/include/asm-i386/a.out.h linux-2.6.23.15-grsec/include/asm-i386/a.out.h
26271 +--- linux-2.6.23.15/include/asm-i386/a.out.h 2007-10-09 21:31:38.000000000 +0100
26272 ++++ linux-2.6.23.15-grsec/include/asm-i386/a.out.h 2008-02-11 10:37:44.000000000 +0000
26273 +@@ -19,8 +19,13 @@ struct exec
26274 +
26275 + #ifdef __KERNEL__
26276 +
26277 +-#define STACK_TOP TASK_SIZE
26278 +-#define STACK_TOP_MAX STACK_TOP
26279 ++#ifdef CONFIG_PAX_SEGMEXEC
26280 ++#define __STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
26281 ++#else
26282 ++#define __STACK_TOP TASK_SIZE
26283 ++#endif
26284 ++
26285 ++#define STACK_TOP_MAX TASK_SIZE
26286 +
26287 + #endif
26288 +
26289 +diff -Nurp linux-2.6.23.15/include/asm-i386/alternative.h linux-2.6.23.15-grsec/include/asm-i386/alternative.h
26290 +--- linux-2.6.23.15/include/asm-i386/alternative.h 2007-10-09 21:31:38.000000000 +0100
26291 ++++ linux-2.6.23.15-grsec/include/asm-i386/alternative.h 2008-02-11 10:37:44.000000000 +0000
26292 +@@ -54,7 +54,7 @@ static inline void alternatives_smp_swit
26293 + " .byte 662b-661b\n" /* sourcelen */ \
26294 + " .byte 664f-663f\n" /* replacementlen */ \
26295 + ".previous\n" \
26296 +- ".section .altinstr_replacement,\"ax\"\n" \
26297 ++ ".section .altinstr_replacement,\"a\"\n" \
26298 + "663:\n\t" newinstr "\n664:\n" /* replacement */\
26299 + ".previous" :: "i" (feature) : "memory")
26300 +
26301 +@@ -78,7 +78,7 @@ static inline void alternatives_smp_swit
26302 + " .byte 662b-661b\n" /* sourcelen */ \
26303 + " .byte 664f-663f\n" /* replacementlen */ \
26304 + ".previous\n" \
26305 +- ".section .altinstr_replacement,\"ax\"\n" \
26306 ++ ".section .altinstr_replacement,\"a\"\n" \
26307 + "663:\n\t" newinstr "\n664:\n" /* replacement */\
26308 + ".previous" :: "i" (feature), ##input)
26309 +
26310 +@@ -93,7 +93,7 @@ static inline void alternatives_smp_swit
26311 + " .byte 662b-661b\n" /* sourcelen */ \
26312 + " .byte 664f-663f\n" /* replacementlen */ \
26313 + ".previous\n" \
26314 +- ".section .altinstr_replacement,\"ax\"\n" \
26315 ++ ".section .altinstr_replacement,\"a\"\n" \
26316 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
26317 + ".previous" : output : [feat] "i" (feature), ##input)
26318 +
26319 +diff -Nurp linux-2.6.23.15/include/asm-i386/apic.h linux-2.6.23.15-grsec/include/asm-i386/apic.h
26320 +--- linux-2.6.23.15/include/asm-i386/apic.h 2007-10-09 21:31:38.000000000 +0100
26321 ++++ linux-2.6.23.15-grsec/include/asm-i386/apic.h 2008-02-11 10:37:44.000000000 +0000
26322 +@@ -8,7 +8,7 @@
26323 + #include <asm/processor.h>
26324 + #include <asm/system.h>
26325 +
26326 +-#define Dprintk(x...)
26327 ++#define Dprintk(x...) do {} while (0)
26328 +
26329 + /*
26330 + * Debugging macros
26331 +diff -Nurp linux-2.6.23.15/include/asm-i386/cache.h linux-2.6.23.15-grsec/include/asm-i386/cache.h
26332 +--- linux-2.6.23.15/include/asm-i386/cache.h 2007-10-09 21:31:38.000000000 +0100
26333 ++++ linux-2.6.23.15-grsec/include/asm-i386/cache.h 2008-02-11 10:37:44.000000000 +0000
26334 +@@ -10,5 +10,6 @@
26335 + #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
26336 +
26337 + #define __read_mostly __attribute__((__section__(".data.read_mostly")))
26338 ++#define __read_only __attribute__((__section__(".data.read_only")))
26339 +
26340 + #endif
26341 +diff -Nurp linux-2.6.23.15/include/asm-i386/checksum.h linux-2.6.23.15-grsec/include/asm-i386/checksum.h
26342 +--- linux-2.6.23.15/include/asm-i386/checksum.h 2007-10-09 21:31:38.000000000 +0100
26343 ++++ linux-2.6.23.15-grsec/include/asm-i386/checksum.h 2008-02-11 10:37:44.000000000 +0000
26344 +@@ -30,6 +30,12 @@ asmlinkage __wsum csum_partial(const voi
26345 + asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst,
26346 + int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
26347 +
26348 ++asmlinkage __wsum csum_partial_copy_generic_to_user(const void *src, void *dst,
26349 ++ int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
26350 ++
26351 ++asmlinkage __wsum csum_partial_copy_generic_from_user(const void *src, void *dst,
26352 ++ int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
26353 ++
26354 + /*
26355 + * Note: when you get a NULL pointer exception here this means someone
26356 + * passed in an incorrect kernel address to one of these functions.
26357 +@@ -49,7 +55,7 @@ __wsum csum_partial_copy_from_user(const
26358 + int len, __wsum sum, int *err_ptr)
26359 + {
26360 + might_sleep();
26361 +- return csum_partial_copy_generic((__force void *)src, dst,
26362 ++ return csum_partial_copy_generic_from_user((__force void *)src, dst,
26363 + len, sum, err_ptr, NULL);
26364 + }
26365 +
26366 +@@ -180,7 +186,7 @@ static __inline__ __wsum csum_and_copy_t
26367 + {
26368 + might_sleep();
26369 + if (access_ok(VERIFY_WRITE, dst, len))
26370 +- return csum_partial_copy_generic(src, (__force void *)dst, len, sum, NULL, err_ptr);
26371 ++ return csum_partial_copy_generic_to_user(src, (__force void *)dst, len, sum, NULL, err_ptr);
26372 +
26373 + if (len)
26374 + *err_ptr = -EFAULT;
26375 +diff -Nurp linux-2.6.23.15/include/asm-i386/desc.h linux-2.6.23.15-grsec/include/asm-i386/desc.h
26376 +--- linux-2.6.23.15/include/asm-i386/desc.h 2007-10-09 21:31:38.000000000 +0100
26377 ++++ linux-2.6.23.15-grsec/include/asm-i386/desc.h 2008-02-11 10:37:44.000000000 +0000
26378 +@@ -7,26 +7,22 @@
26379 + #ifndef __ASSEMBLY__
26380 +
26381 + #include <linux/preempt.h>
26382 +-#include <linux/smp.h>
26383 + #include <linux/percpu.h>
26384 ++#include <linux/smp.h>
26385 +
26386 + #include <asm/mmu.h>
26387 +
26388 ++extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
26389 ++
26390 + struct Xgt_desc_struct {
26391 + unsigned short size;
26392 +- unsigned long address __attribute__((packed));
26393 ++ struct desc_struct *address __attribute__((packed));
26394 + unsigned short pad;
26395 + } __attribute__ ((packed));
26396 +
26397 +-struct gdt_page
26398 +-{
26399 +- struct desc_struct gdt[GDT_ENTRIES];
26400 +-} __attribute__((aligned(PAGE_SIZE)));
26401 +-DECLARE_PER_CPU(struct gdt_page, gdt_page);
26402 +-
26403 + static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
26404 + {
26405 +- return per_cpu(gdt_page, cpu).gdt;
26406 ++ return cpu_gdt_table[cpu];
26407 + }
26408 +
26409 + extern struct Xgt_desc_struct idt_descr;
26410 +@@ -81,8 +77,20 @@ static inline void pack_gate(__u32 *a, _
26411 + static inline void write_dt_entry(struct desc_struct *dt,
26412 + int entry, u32 entry_low, u32 entry_high)
26413 + {
26414 ++
26415 ++#ifdef CONFIG_PAX_KERNEXEC
26416 ++ unsigned long cr0;
26417 ++
26418 ++ pax_open_kernel(cr0);
26419 ++#endif
26420 ++
26421 + dt[entry].a = entry_low;
26422 + dt[entry].b = entry_high;
26423 ++
26424 ++#ifdef CONFIG_PAX_KERNEXEC
26425 ++ pax_close_kernel(cr0);
26426 ++#endif
26427 ++
26428 + }
26429 +
26430 + static inline void native_set_ldt(const void *addr, unsigned int entries)
26431 +@@ -139,8 +147,19 @@ static inline void native_load_tls(struc
26432 + unsigned int i;
26433 + struct desc_struct *gdt = get_cpu_gdt_table(cpu);
26434 +
26435 ++#ifdef CONFIG_PAX_KERNEXEC
26436 ++ unsigned long cr0;
26437 ++
26438 ++ pax_open_kernel(cr0);
26439 ++#endif
26440 ++
26441 + for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
26442 + gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
26443 ++
26444 ++#ifdef CONFIG_PAX_KERNEXEC
26445 ++ pax_close_kernel(cr0);
26446 ++#endif
26447 ++
26448 + }
26449 +
26450 + static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned short seg)
26451 +@@ -175,7 +194,7 @@ static inline void __set_tss_desc(unsign
26452 + ((info)->seg_32bit << 22) | \
26453 + ((info)->limit_in_pages << 23) | \
26454 + ((info)->useable << 20) | \
26455 +- 0x7000)
26456 ++ 0x7100)
26457 +
26458 + #define LDT_empty(info) (\
26459 + (info)->base_addr == 0 && \
26460 +@@ -207,15 +226,25 @@ static inline void load_LDT(mm_context_t
26461 + preempt_enable();
26462 + }
26463 +
26464 +-static inline unsigned long get_desc_base(unsigned long *desc)
26465 ++static inline unsigned long get_desc_base(struct desc_struct *desc)
26466 + {
26467 + unsigned long base;
26468 +- base = ((desc[0] >> 16) & 0x0000ffff) |
26469 +- ((desc[1] << 16) & 0x00ff0000) |
26470 +- (desc[1] & 0xff000000);
26471 ++ base = ((desc->a >> 16) & 0x0000ffff) |
26472 ++ ((desc->b << 16) & 0x00ff0000) |
26473 ++ (desc->b & 0xff000000);
26474 + return base;
26475 + }
26476 +
26477 ++static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
26478 ++{
26479 ++ __u32 a, b;
26480 ++
26481 ++ if (likely(limit))
26482 ++ limit = (limit - 1UL) >> PAGE_SHIFT;
26483 ++ pack_descriptor(&a, &b, base, limit, 0xFB, 0xC);
26484 ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, a, b);
26485 ++}
26486 ++
26487 + #else /* __ASSEMBLY__ */
26488 +
26489 + /*
26490 +diff -Nurp linux-2.6.23.15/include/asm-i386/elf.h linux-2.6.23.15-grsec/include/asm-i386/elf.h
26491 +--- linux-2.6.23.15/include/asm-i386/elf.h 2007-10-09 21:31:38.000000000 +0100
26492 ++++ linux-2.6.23.15-grsec/include/asm-i386/elf.h 2008-02-11 10:37:44.000000000 +0000
26493 +@@ -73,7 +73,18 @@ typedef struct user_fxsr_struct elf_fpxr
26494 + the loader. We need to make sure that it is out of the way of the program
26495 + that it will "exec", and that there is sufficient room for the brk. */
26496 +
26497 ++#ifdef CONFIG_PAX_SEGMEXEC
26498 ++#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
26499 ++#else
26500 + #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
26501 ++#endif
26502 ++
26503 ++#ifdef CONFIG_PAX_ASLR
26504 ++#define PAX_ELF_ET_DYN_BASE 0x10000000UL
26505 ++
26506 ++#define PAX_DELTA_MMAP_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
26507 ++#define PAX_DELTA_STACK_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
26508 ++#endif
26509 +
26510 + /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
26511 + now struct_user_regs, they are different) */
26512 +@@ -131,7 +142,7 @@ extern int dump_task_extended_fpu (struc
26513 + #define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) dump_task_extended_fpu(tsk, elf_xfpregs)
26514 +
26515 + #define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO))
26516 +-#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
26517 ++#define VDSO_CURRENT_BASE (current->mm->context.vdso)
26518 + #define VDSO_PRELINK 0
26519 +
26520 + #define VDSO_SYM(x) \
26521 +diff -Nurp linux-2.6.23.15/include/asm-i386/futex.h linux-2.6.23.15-grsec/include/asm-i386/futex.h
26522 +--- linux-2.6.23.15/include/asm-i386/futex.h 2007-10-09 21:31:38.000000000 +0100
26523 ++++ linux-2.6.23.15-grsec/include/asm-i386/futex.h 2008-02-11 10:37:44.000000000 +0000
26524 +@@ -11,8 +11,11 @@
26525 +
26526 + #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
26527 + __asm__ __volatile ( \
26528 ++ "movw %w6, %%ds\n"\
26529 + "1: " insn "\n" \
26530 +-"2: .section .fixup,\"ax\"\n\
26531 ++"2: pushl %%ss\n\
26532 ++ popl %%ds\n\
26533 ++ .section .fixup,\"ax\"\n\
26534 + 3: mov %3, %1\n\
26535 + jmp 2b\n\
26536 + .previous\n\
26537 +@@ -21,16 +24,19 @@
26538 + .long 1b,3b\n\
26539 + .previous" \
26540 + : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
26541 +- : "i" (-EFAULT), "0" (oparg), "1" (0))
26542 ++ : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS))
26543 +
26544 + #define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
26545 + __asm__ __volatile ( \
26546 +-"1: movl %2, %0\n\
26547 ++" movw %w7, %%es\n\
26548 ++1: movl %%es:%2, %0\n\
26549 + movl %0, %3\n" \
26550 + insn "\n" \
26551 +-"2: " LOCK_PREFIX "cmpxchgl %3, %2\n\
26552 ++"2: " LOCK_PREFIX "cmpxchgl %3, %%es:%2\n\
26553 + jnz 1b\n\
26554 +-3: .section .fixup,\"ax\"\n\
26555 ++3: pushl %%ss\n\
26556 ++ popl %%es\n\
26557 ++ .section .fixup,\"ax\"\n\
26558 + 4: mov %5, %1\n\
26559 + jmp 3b\n\
26560 + .previous\n\
26561 +@@ -40,10 +46,10 @@
26562 + .previous" \
26563 + : "=&a" (oldval), "=&r" (ret), "+m" (*uaddr), \
26564 + "=&r" (tem) \
26565 +- : "r" (oparg), "i" (-EFAULT), "1" (0))
26566 ++ : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS))
26567 +
26568 + static inline int
26569 +-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
26570 ++futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
26571 + {
26572 + int op = (encoded_op >> 28) & 7;
26573 + int cmp = (encoded_op >> 24) & 15;
26574 +@@ -59,7 +65,7 @@ futex_atomic_op_inuser (int encoded_op,
26575 + pagefault_disable();
26576 +
26577 + if (op == FUTEX_OP_SET)
26578 +- __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
26579 ++ __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg);
26580 + else {
26581 + #ifndef CONFIG_X86_BSWAP
26582 + if (boot_cpu_data.x86 == 3)
26583 +@@ -68,7 +74,7 @@ futex_atomic_op_inuser (int encoded_op,
26584 + #endif
26585 + switch (op) {
26586 + case FUTEX_OP_ADD:
26587 +- __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret,
26588 ++ __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %%ds:%2", ret,
26589 + oldval, uaddr, oparg);
26590 + break;
26591 + case FUTEX_OP_OR:
26592 +@@ -105,15 +111,17 @@ futex_atomic_op_inuser (int encoded_op,
26593 + }
26594 +
26595 + static inline int
26596 +-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
26597 ++futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
26598 + {
26599 + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
26600 + return -EFAULT;
26601 +
26602 + __asm__ __volatile__(
26603 +- "1: " LOCK_PREFIX "cmpxchgl %3, %1 \n"
26604 +-
26605 +- "2: .section .fixup, \"ax\" \n"
26606 ++ " movw %w5, %%ds \n"
26607 ++ "1: " LOCK_PREFIX "cmpxchgl %3, %%ds:%1 \n"
26608 ++ "2: pushl %%ss \n"
26609 ++ " popl %%ds \n"
26610 ++ " .section .fixup, \"ax\" \n"
26611 + "3: mov %2, %0 \n"
26612 + " jmp 2b \n"
26613 + " .previous \n"
26614 +@@ -124,7 +132,7 @@ futex_atomic_cmpxchg_inatomic(int __user
26615 + " .previous \n"
26616 +
26617 + : "=a" (oldval), "+m" (*uaddr)
26618 +- : "i" (-EFAULT), "r" (newval), "0" (oldval)
26619 ++ : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS)
26620 + : "memory"
26621 + );
26622 +
26623 +diff -Nurp linux-2.6.23.15/include/asm-i386/i387.h linux-2.6.23.15-grsec/include/asm-i386/i387.h
26624 +--- linux-2.6.23.15/include/asm-i386/i387.h 2007-10-09 21:31:38.000000000 +0100
26625 ++++ linux-2.6.23.15-grsec/include/asm-i386/i387.h 2008-02-11 10:37:44.000000000 +0000
26626 +@@ -40,13 +40,8 @@ extern void kernel_fpu_begin(void);
26627 + #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
26628 +
26629 + /* We need a safe address that is cheap to find and that is already
26630 +- in L1 during context switch. The best choices are unfortunately
26631 +- different for UP and SMP */
26632 +-#ifdef CONFIG_SMP
26633 +-#define safe_address (__per_cpu_offset[0])
26634 +-#else
26635 +-#define safe_address (kstat_cpu(0).cpustat.user)
26636 +-#endif
26637 ++ in L1 during context switch. */
26638 ++#define safe_address (init_tss[smp_processor_id()].x86_tss.esp0)
26639 +
26640 + /*
26641 + * These must be called with preempt disabled
26642 +diff -Nurp linux-2.6.23.15/include/asm-i386/irqflags.h linux-2.6.23.15-grsec/include/asm-i386/irqflags.h
26643 +--- linux-2.6.23.15/include/asm-i386/irqflags.h 2007-10-09 21:31:38.000000000 +0100
26644 ++++ linux-2.6.23.15-grsec/include/asm-i386/irqflags.h 2008-02-11 10:37:44.000000000 +0000
26645 +@@ -108,6 +108,8 @@ static inline unsigned long __raw_local_
26646 + #define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit
26647 + #define INTERRUPT_RETURN iret
26648 + #define GET_CR0_INTO_EAX movl %cr0, %eax
26649 ++#define GET_CR0_INTO_EDX movl %cr0, %edx
26650 ++#define SET_CR0_FROM_EDX movl %edx, %cr0
26651 + #endif /* __ASSEMBLY__ */
26652 + #endif /* CONFIG_PARAVIRT */
26653 +
26654 +diff -Nurp linux-2.6.23.15/include/asm-i386/kmap_types.h linux-2.6.23.15-grsec/include/asm-i386/kmap_types.h
26655 +--- linux-2.6.23.15/include/asm-i386/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
26656 ++++ linux-2.6.23.15-grsec/include/asm-i386/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
26657 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
26658 + D(10) KM_IRQ1,
26659 + D(11) KM_SOFTIRQ0,
26660 + D(12) KM_SOFTIRQ1,
26661 +-D(13) KM_TYPE_NR
26662 ++D(13) KM_CLEARPAGE,
26663 ++D(14) KM_TYPE_NR
26664 + };
26665 +
26666 + #undef D
26667 +diff -Nurp linux-2.6.23.15/include/asm-i386/mach-default/apm.h linux-2.6.23.15-grsec/include/asm-i386/mach-default/apm.h
26668 +--- linux-2.6.23.15/include/asm-i386/mach-default/apm.h 2007-10-09 21:31:38.000000000 +0100
26669 ++++ linux-2.6.23.15-grsec/include/asm-i386/mach-default/apm.h 2008-02-11 10:37:44.000000000 +0000
26670 +@@ -36,7 +36,7 @@ static inline void apm_bios_call_asm(u32
26671 + __asm__ __volatile__(APM_DO_ZERO_SEGS
26672 + "pushl %%edi\n\t"
26673 + "pushl %%ebp\n\t"
26674 +- "lcall *%%cs:apm_bios_entry\n\t"
26675 ++ "lcall *%%ss:apm_bios_entry\n\t"
26676 + "setc %%al\n\t"
26677 + "popl %%ebp\n\t"
26678 + "popl %%edi\n\t"
26679 +@@ -60,7 +60,7 @@ static inline u8 apm_bios_call_simple_as
26680 + __asm__ __volatile__(APM_DO_ZERO_SEGS
26681 + "pushl %%edi\n\t"
26682 + "pushl %%ebp\n\t"
26683 +- "lcall *%%cs:apm_bios_entry\n\t"
26684 ++ "lcall *%%ss:apm_bios_entry\n\t"
26685 + "setc %%bl\n\t"
26686 + "popl %%ebp\n\t"
26687 + "popl %%edi\n\t"
26688 +diff -Nurp linux-2.6.23.15/include/asm-i386/mman.h linux-2.6.23.15-grsec/include/asm-i386/mman.h
26689 +--- linux-2.6.23.15/include/asm-i386/mman.h 2007-10-09 21:31:38.000000000 +0100
26690 ++++ linux-2.6.23.15-grsec/include/asm-i386/mman.h 2008-02-11 10:37:44.000000000 +0000
26691 +@@ -14,4 +14,12 @@
26692 + #define MCL_CURRENT 1 /* lock all current mappings */
26693 + #define MCL_FUTURE 2 /* lock all future mappings */
26694 +
26695 ++#ifdef __KERNEL__
26696 ++#ifndef __ASSEMBLY__
26697 ++#define arch_mmap_check i386_mmap_check
26698 ++int i386_mmap_check(unsigned long addr, unsigned long len,
26699 ++ unsigned long flags);
26700 ++#endif
26701 ++#endif
26702 ++
26703 + #endif /* __I386_MMAN_H__ */
26704 +diff -Nurp linux-2.6.23.15/include/asm-i386/mmu.h linux-2.6.23.15-grsec/include/asm-i386/mmu.h
26705 +--- linux-2.6.23.15/include/asm-i386/mmu.h 2007-10-09 21:31:38.000000000 +0100
26706 ++++ linux-2.6.23.15-grsec/include/asm-i386/mmu.h 2008-02-11 10:37:44.000000000 +0000
26707 +@@ -11,8 +11,19 @@
26708 + typedef struct {
26709 + int size;
26710 + struct semaphore sem;
26711 +- void *ldt;
26712 +- void *vdso;
26713 ++ struct desc_struct *ldt;
26714 ++ unsigned long vdso;
26715 ++
26716 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
26717 ++ unsigned long user_cs_base;
26718 ++ unsigned long user_cs_limit;
26719 ++
26720 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
26721 ++ cpumask_t cpu_user_cs_mask;
26722 ++#endif
26723 ++
26724 ++#endif
26725 ++
26726 + } mm_context_t;
26727 +
26728 + #endif
26729 +diff -Nurp linux-2.6.23.15/include/asm-i386/mmu_context.h linux-2.6.23.15-grsec/include/asm-i386/mmu_context.h
26730 +--- linux-2.6.23.15/include/asm-i386/mmu_context.h 2007-10-09 21:31:38.000000000 +0100
26731 ++++ linux-2.6.23.15-grsec/include/asm-i386/mmu_context.h 2008-02-11 10:37:44.000000000 +0000
26732 +@@ -57,6 +57,22 @@ static inline void switch_mm(struct mm_s
26733 + */
26734 + if (unlikely(prev->context.ldt != next->context.ldt))
26735 + load_LDT_nolock(&next->context);
26736 ++
26737 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
26738 ++ if (!nx_enabled) {
26739 ++ smp_mb__before_clear_bit();
26740 ++ cpu_clear(cpu, prev->context.cpu_user_cs_mask);
26741 ++ smp_mb__after_clear_bit();
26742 ++ cpu_set(cpu, next->context.cpu_user_cs_mask);
26743 ++ }
26744 ++#endif
26745 ++
26746 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
26747 ++ if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
26748 ++ prev->context.user_cs_limit != next->context.user_cs_limit))
26749 ++ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
26750 ++#endif
26751 ++
26752 + }
26753 + #ifdef CONFIG_SMP
26754 + else {
26755 +@@ -69,6 +85,19 @@ static inline void switch_mm(struct mm_s
26756 + */
26757 + load_cr3(next->pgd);
26758 + load_LDT_nolock(&next->context);
26759 ++
26760 ++#ifdef CONFIG_PAX_PAGEEXEC
26761 ++ if (!nx_enabled)
26762 ++ cpu_set(cpu, next->context.cpu_user_cs_mask);
26763 ++#endif
26764 ++
26765 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
26766 ++#ifdef CONFIG_PAX_PAGEEXEC
26767 ++ if (!((next->pax_flags & MF_PAX_PAGEEXEC) && nx_enabled))
26768 ++#endif
26769 ++ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
26770 ++#endif
26771 ++
26772 + }
26773 + }
26774 + #endif
26775 +diff -Nurp linux-2.6.23.15/include/asm-i386/module.h linux-2.6.23.15-grsec/include/asm-i386/module.h
26776 +--- linux-2.6.23.15/include/asm-i386/module.h 2007-10-09 21:31:38.000000000 +0100
26777 ++++ linux-2.6.23.15-grsec/include/asm-i386/module.h 2008-02-11 10:37:44.000000000 +0000
26778 +@@ -70,6 +70,12 @@ struct mod_arch_specific
26779 + #define MODULE_STACKSIZE ""
26780 + #endif
26781 +
26782 +-#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
26783 ++#ifdef CONFIG_GRKERNSEC
26784 ++#define MODULE_GRSEC "GRSECURTY "
26785 ++#else
26786 ++#define MODULE_GRSEC ""
26787 ++#endif
26788 ++
26789 ++#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE MODULE_GRSEC
26790 +
26791 + #endif /* _ASM_I386_MODULE_H */
26792 +diff -Nurp linux-2.6.23.15/include/asm-i386/page.h linux-2.6.23.15-grsec/include/asm-i386/page.h
26793 +--- linux-2.6.23.15/include/asm-i386/page.h 2007-10-09 21:31:38.000000000 +0100
26794 ++++ linux-2.6.23.15-grsec/include/asm-i386/page.h 2008-02-11 10:37:44.000000000 +0000
26795 +@@ -10,6 +10,7 @@
26796 + #define LARGE_PAGE_SIZE (1UL << PMD_SHIFT)
26797 +
26798 + #ifdef __KERNEL__
26799 ++#include <asm/boot.h>
26800 + #ifndef __ASSEMBLY__
26801 +
26802 + #ifdef CONFIG_X86_USE_3DNOW
26803 +@@ -90,7 +91,6 @@ static inline pte_t native_make_pte(unsi
26804 + typedef struct { unsigned long pte_low; } pte_t;
26805 + typedef struct { unsigned long pgd; } pgd_t;
26806 + typedef struct { unsigned long pgprot; } pgprot_t;
26807 +-#define boot_pte_t pte_t /* or would you rather have a typedef */
26808 +
26809 + static inline unsigned long native_pgd_val(pgd_t pgd)
26810 + {
26811 +@@ -175,6 +175,18 @@ extern int page_is_ram(unsigned long pag
26812 + #define __PAGE_OFFSET ((unsigned long)CONFIG_PAGE_OFFSET)
26813 + #endif
26814 +
26815 ++#ifdef CONFIG_PAX_KERNEXEC
26816 ++#ifdef __ASSEMBLY__
26817 ++#define __KERNEL_TEXT_OFFSET (__PAGE_OFFSET + ((LOAD_PHYSICAL_ADDR + 6*1024*1024 - 1) & ~(4*1024*1024 - 1)))
26818 ++#else
26819 ++extern unsigned char KERNEL_TEXT_OFFSET[];
26820 ++#define __KERNEL_TEXT_OFFSET ((unsigned long)KERNEL_TEXT_OFFSET)
26821 ++extern unsigned char MODULES_VADDR[];
26822 ++extern unsigned char MODULES_END[];
26823 ++#endif
26824 ++#else
26825 ++#define __KERNEL_TEXT_OFFSET (0)
26826 ++#endif
26827 +
26828 + #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)
26829 + #define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE)
26830 +@@ -197,6 +209,10 @@ extern int page_is_ram(unsigned long pag
26831 + ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
26832 + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
26833 +
26834 ++#ifdef CONFIG_PAX_PAGEEXEC
26835 ++#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
26836 ++#endif
26837 ++
26838 + #include <asm-generic/memory_model.h>
26839 + #include <asm-generic/page.h>
26840 +
26841 +diff -Nurp linux-2.6.23.15/include/asm-i386/paravirt.h linux-2.6.23.15-grsec/include/asm-i386/paravirt.h
26842 +--- linux-2.6.23.15/include/asm-i386/paravirt.h 2007-10-09 21:31:38.000000000 +0100
26843 ++++ linux-2.6.23.15-grsec/include/asm-i386/paravirt.h 2008-02-11 10:37:44.000000000 +0000
26844 +@@ -1057,23 +1057,23 @@ static inline unsigned long __raw_local_
26845 +
26846 + #define INTERRUPT_RETURN \
26847 + PARA_SITE(PARA_PATCH(PARAVIRT_iret), CLBR_NONE, \
26848 +- jmp *%cs:paravirt_ops+PARAVIRT_iret)
26849 ++ jmp *%ss:paravirt_ops+PARAVIRT_iret)
26850 +
26851 + #define DISABLE_INTERRUPTS(clobbers) \
26852 + PARA_SITE(PARA_PATCH(PARAVIRT_irq_disable), clobbers, \
26853 + pushl %eax; pushl %ecx; pushl %edx; \
26854 +- call *%cs:paravirt_ops+PARAVIRT_irq_disable; \
26855 ++ call *%ss:paravirt_ops+PARAVIRT_irq_disable; \
26856 + popl %edx; popl %ecx; popl %eax) \
26857 +
26858 + #define ENABLE_INTERRUPTS(clobbers) \
26859 + PARA_SITE(PARA_PATCH(PARAVIRT_irq_enable), clobbers, \
26860 + pushl %eax; pushl %ecx; pushl %edx; \
26861 +- call *%cs:paravirt_ops+PARAVIRT_irq_enable; \
26862 ++ call *%ss:paravirt_ops+PARAVIRT_irq_enable; \
26863 + popl %edx; popl %ecx; popl %eax)
26864 +
26865 + #define ENABLE_INTERRUPTS_SYSEXIT \
26866 + PARA_SITE(PARA_PATCH(PARAVIRT_irq_enable_sysexit), CLBR_NONE, \
26867 +- jmp *%cs:paravirt_ops+PARAVIRT_irq_enable_sysexit)
26868 ++ jmp *%ss:paravirt_ops+PARAVIRT_irq_enable_sysexit)
26869 +
26870 + #define GET_CR0_INTO_EAX \
26871 + push %ecx; push %edx; \
26872 +diff -Nurp linux-2.6.23.15/include/asm-i386/percpu.h linux-2.6.23.15-grsec/include/asm-i386/percpu.h
26873 +--- linux-2.6.23.15/include/asm-i386/percpu.h 2007-10-09 21:31:38.000000000 +0100
26874 ++++ linux-2.6.23.15-grsec/include/asm-i386/percpu.h 2008-02-11 10:37:44.000000000 +0000
26875 +@@ -22,7 +22,7 @@
26876 + #define PER_CPU_VAR(var) %fs:per_cpu__##var
26877 + #else /* ! SMP */
26878 + #define PER_CPU(var, reg) \
26879 +- movl $per_cpu__##var, reg
26880 ++ movl per_cpu__##var, reg
26881 + #define PER_CPU_VAR(var) per_cpu__##var
26882 + #endif /* SMP */
26883 +
26884 +@@ -42,12 +42,12 @@
26885 + */
26886 + #ifdef CONFIG_SMP
26887 + /* Same as generic implementation except for optimized local access. */
26888 +-#define __GENERIC_PER_CPU
26889 +
26890 + /* This is used for other cpus to find our section. */
26891 + extern unsigned long __per_cpu_offset[];
26892 ++extern void setup_per_cpu_areas(void);
26893 +
26894 +-#define per_cpu_offset(x) (__per_cpu_offset[x])
26895 ++#define per_cpu_offset(x) (__per_cpu_offset[x] - (unsigned long)__per_cpu_start)
26896 +
26897 + /* Separate out the type, so (int[3], foo) works. */
26898 + #define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name
26899 +@@ -64,11 +64,11 @@ DECLARE_PER_CPU(unsigned long, this_cpu_
26900 +
26901 + /* var is in discarded region: offset to particular copy we want */
26902 + #define per_cpu(var, cpu) (*({ \
26903 +- extern int simple_indentifier_##var(void); \
26904 ++ extern int simple_identifier_##var(void); \
26905 + RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]); }))
26906 +
26907 + #define __raw_get_cpu_var(var) (*({ \
26908 +- extern int simple_indentifier_##var(void); \
26909 ++ extern int simple_identifier_##var(void); \
26910 + RELOC_HIDE(&per_cpu__##var, x86_read_percpu(this_cpu_off)); \
26911 + }))
26912 +
26913 +@@ -79,7 +79,7 @@ DECLARE_PER_CPU(unsigned long, this_cpu_
26914 + do { \
26915 + unsigned int __i; \
26916 + for_each_possible_cpu(__i) \
26917 +- memcpy((pcpudst)+__per_cpu_offset[__i], \
26918 ++ memcpy((pcpudst)+per_cpu_offset(__i), \
26919 + (src), (size)); \
26920 + } while (0)
26921 +
26922 +diff -Nurp linux-2.6.23.15/include/asm-i386/pgalloc.h linux-2.6.23.15-grsec/include/asm-i386/pgalloc.h
26923 +--- linux-2.6.23.15/include/asm-i386/pgalloc.h 2007-10-09 21:31:38.000000000 +0100
26924 ++++ linux-2.6.23.15-grsec/include/asm-i386/pgalloc.h 2008-02-11 10:37:44.000000000 +0000
26925 +@@ -15,11 +15,19 @@
26926 + #define paravirt_release_pd(pfn) do { } while (0)
26927 + #endif
26928 +
26929 ++#ifdef CONFIG_COMPAT_VDSO
26930 + #define pmd_populate_kernel(mm, pmd, pte) \
26931 + do { \
26932 + paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT); \
26933 + set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte))); \
26934 + } while (0)
26935 ++#else
26936 ++#define pmd_populate_kernel(mm, pmd, pte) \
26937 ++do { \
26938 ++ paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT); \
26939 ++ set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte))); \
26940 ++} while (0)
26941 ++#endif
26942 +
26943 + #define pmd_populate(mm, pmd, pte) \
26944 + do { \
26945 +diff -Nurp linux-2.6.23.15/include/asm-i386/pgtable-2level.h linux-2.6.23.15-grsec/include/asm-i386/pgtable-2level.h
26946 +--- linux-2.6.23.15/include/asm-i386/pgtable-2level.h 2007-10-09 21:31:38.000000000 +0100
26947 ++++ linux-2.6.23.15-grsec/include/asm-i386/pgtable-2level.h 2008-02-11 10:37:44.000000000 +0000
26948 +@@ -22,7 +22,19 @@ static inline void native_set_pte_at(str
26949 + }
26950 + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
26951 + {
26952 ++
26953 ++#ifdef CONFIG_PAX_KERNEXEC
26954 ++ unsigned long cr0;
26955 ++
26956 ++ pax_open_kernel(cr0);
26957 ++#endif
26958 ++
26959 + *pmdp = pmd;
26960 ++
26961 ++#ifdef CONFIG_PAX_KERNEXEC
26962 ++ pax_close_kernel(cr0);
26963 ++#endif
26964 ++
26965 + }
26966 + #ifndef CONFIG_PARAVIRT
26967 + #define set_pte(pteptr, pteval) native_set_pte(pteptr, pteval)
26968 +diff -Nurp linux-2.6.23.15/include/asm-i386/pgtable-3level.h linux-2.6.23.15-grsec/include/asm-i386/pgtable-3level.h
26969 +--- linux-2.6.23.15/include/asm-i386/pgtable-3level.h 2007-10-09 21:31:38.000000000 +0100
26970 ++++ linux-2.6.23.15-grsec/include/asm-i386/pgtable-3level.h 2008-02-11 10:37:44.000000000 +0000
26971 +@@ -67,11 +67,35 @@ static inline void native_set_pte_atomic
26972 + }
26973 + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
26974 + {
26975 ++
26976 ++#ifdef CONFIG_PAX_KERNEXEC
26977 ++ unsigned long cr0;
26978 ++
26979 ++ pax_open_kernel(cr0);
26980 ++#endif
26981 ++
26982 + set_64bit((unsigned long long *)(pmdp),native_pmd_val(pmd));
26983 ++
26984 ++#ifdef CONFIG_PAX_KERNEXEC
26985 ++ pax_close_kernel(cr0);
26986 ++#endif
26987 ++
26988 + }
26989 + static inline void native_set_pud(pud_t *pudp, pud_t pud)
26990 + {
26991 ++
26992 ++#ifdef CONFIG_PAX_KERNEXEC
26993 ++ unsigned long cr0;
26994 ++
26995 ++ pax_open_kernel(cr0);
26996 ++#endif
26997 ++
26998 + *pudp = pud;
26999 ++
27000 ++#ifdef CONFIG_PAX_KERNEXEC
27001 ++ pax_close_kernel(cr0);
27002 ++#endif
27003 ++
27004 + }
27005 +
27006 + /*
27007 +diff -Nurp linux-2.6.23.15/include/asm-i386/pgtable.h linux-2.6.23.15-grsec/include/asm-i386/pgtable.h
27008 +--- linux-2.6.23.15/include/asm-i386/pgtable.h 2007-10-09 21:31:38.000000000 +0100
27009 ++++ linux-2.6.23.15-grsec/include/asm-i386/pgtable.h 2008-02-11 10:37:44.000000000 +0000
27010 +@@ -34,7 +34,6 @@ struct vm_area_struct;
27011 + */
27012 + #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
27013 + extern unsigned long empty_zero_page[1024];
27014 +-extern pgd_t swapper_pg_dir[1024];
27015 + extern struct kmem_cache *pmd_cache;
27016 + extern spinlock_t pgd_lock;
27017 + extern struct page *pgd_list;
27018 +@@ -58,6 +57,11 @@ void paging_init(void);
27019 + # include <asm/pgtable-2level-defs.h>
27020 + #endif
27021 +
27022 ++extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
27023 ++#ifdef CONFIG_X86_PAE
27024 ++extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
27025 ++#endif
27026 ++
27027 + #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
27028 + #define PGDIR_MASK (~(PGDIR_SIZE-1))
27029 +
27030 +@@ -67,9 +71,11 @@ void paging_init(void);
27031 + #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
27032 + #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
27033 +
27034 ++#ifndef CONFIG_X86_PAE
27035 + #define TWOLEVEL_PGDIR_SHIFT 22
27036 + #define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
27037 + #define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS)
27038 ++#endif
27039 +
27040 + /* Just any arbitrary offset to the start of the vmalloc VM area: the
27041 + * current 8MB value just means that there will be a 8MB "hole" after the
27042 +@@ -136,7 +142,7 @@ void paging_init(void);
27043 + #define PAGE_NONE \
27044 + __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
27045 + #define PAGE_SHARED \
27046 +- __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
27047 ++ __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
27048 +
27049 + #define PAGE_SHARED_EXEC \
27050 + __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
27051 +@@ -202,7 +208,7 @@ extern unsigned long long __PAGE_KERNEL,
27052 + #undef TEST_ACCESS_OK
27053 +
27054 + /* The boot page tables (all created as a single array) */
27055 +-extern unsigned long pg0[];
27056 ++extern pte_t pg0[];
27057 +
27058 + #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
27059 +
27060 +@@ -218,30 +224,55 @@ extern unsigned long pg0[];
27061 + * The following only work if pte_present() is true.
27062 + * Undefined behaviour if not..
27063 + */
27064 ++static inline int pte_user(pte_t pte) { return (pte).pte_low & _PAGE_USER; }
27065 + static inline int pte_dirty(pte_t pte) { return (pte).pte_low & _PAGE_DIRTY; }
27066 + static inline int pte_young(pte_t pte) { return (pte).pte_low & _PAGE_ACCESSED; }
27067 + static inline int pte_write(pte_t pte) { return (pte).pte_low & _PAGE_RW; }
27068 + static inline int pte_huge(pte_t pte) { return (pte).pte_low & _PAGE_PSE; }
27069 +
27070 ++#ifdef CONFIG_X86_PAE
27071 ++# include <asm/pgtable-3level.h>
27072 ++#else
27073 ++# include <asm/pgtable-2level.h>
27074 ++#endif
27075 ++
27076 + /*
27077 + * The following only works if pte_present() is not true.
27078 + */
27079 + static inline int pte_file(pte_t pte) { return (pte).pte_low & _PAGE_FILE; }
27080 +
27081 ++static inline pte_t pte_exprotect(pte_t pte)
27082 ++{
27083 ++#ifdef CONFIG_X86_PAE
27084 ++ if (__supported_pte_mask & _PAGE_NX)
27085 ++ set_pte(&pte, __pte(pte_val(pte) | _PAGE_NX));
27086 ++ else
27087 ++#endif
27088 ++ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER));
27089 ++ return pte;
27090 ++}
27091 ++
27092 + static inline pte_t pte_mkclean(pte_t pte) { (pte).pte_low &= ~_PAGE_DIRTY; return pte; }
27093 + static inline pte_t pte_mkold(pte_t pte) { (pte).pte_low &= ~_PAGE_ACCESSED; return pte; }
27094 + static inline pte_t pte_wrprotect(pte_t pte) { (pte).pte_low &= ~_PAGE_RW; return pte; }
27095 ++static inline pte_t pte_mkread(pte_t pte) { (pte).pte_low |= _PAGE_USER; return pte; }
27096 ++
27097 ++static inline pte_t pte_mkexec(pte_t pte)
27098 ++{
27099 ++#ifdef CONFIG_X86_PAE
27100 ++ if (__supported_pte_mask & _PAGE_NX)
27101 ++ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX));
27102 ++ else
27103 ++#endif
27104 ++ set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER));
27105 ++ return pte;
27106 ++}
27107 ++
27108 + static inline pte_t pte_mkdirty(pte_t pte) { (pte).pte_low |= _PAGE_DIRTY; return pte; }
27109 + static inline pte_t pte_mkyoung(pte_t pte) { (pte).pte_low |= _PAGE_ACCESSED; return pte; }
27110 + static inline pte_t pte_mkwrite(pte_t pte) { (pte).pte_low |= _PAGE_RW; return pte; }
27111 + static inline pte_t pte_mkhuge(pte_t pte) { (pte).pte_low |= _PAGE_PSE; return pte; }
27112 +
27113 +-#ifdef CONFIG_X86_PAE
27114 +-# include <asm/pgtable-3level.h>
27115 +-#else
27116 +-# include <asm/pgtable-2level.h>
27117 +-#endif
27118 +-
27119 + #ifndef CONFIG_PARAVIRT
27120 + /*
27121 + * Rules for using pte_update - it must be called after any PTE update which
27122 +@@ -353,7 +384,19 @@ static inline void ptep_set_wrprotect(st
27123 + */
27124 + static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
27125 + {
27126 +- memcpy(dst, src, count * sizeof(pgd_t));
27127 ++
27128 ++#ifdef CONFIG_PAX_KERNEXEC
27129 ++ unsigned long cr0;
27130 ++
27131 ++ pax_open_kernel(cr0);
27132 ++#endif
27133 ++
27134 ++ memcpy(dst, src, count * sizeof(pgd_t));
27135 ++
27136 ++#ifdef CONFIG_PAX_KERNEXEC
27137 ++ pax_close_kernel(cr0);
27138 ++#endif
27139 ++
27140 + }
27141 +
27142 + /*
27143 +@@ -500,6 +543,9 @@ static inline void paravirt_pagetable_se
27144 +
27145 + #endif /* !__ASSEMBLY__ */
27146 +
27147 ++#define HAVE_ARCH_UNMAPPED_AREA
27148 ++#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
27149 ++
27150 + #ifdef CONFIG_FLATMEM
27151 + #define kern_addr_valid(addr) (1)
27152 + #endif /* CONFIG_FLATMEM */
27153 +diff -Nurp linux-2.6.23.15/include/asm-i386/processor.h linux-2.6.23.15-grsec/include/asm-i386/processor.h
27154 +--- linux-2.6.23.15/include/asm-i386/processor.h 2007-10-09 21:31:38.000000000 +0100
27155 ++++ linux-2.6.23.15-grsec/include/asm-i386/processor.h 2008-02-11 10:37:44.000000000 +0000
27156 +@@ -99,8 +99,6 @@ struct cpuinfo_x86 {
27157 +
27158 + extern struct cpuinfo_x86 boot_cpu_data;
27159 + extern struct cpuinfo_x86 new_cpu_data;
27160 +-extern struct tss_struct doublefault_tss;
27161 +-DECLARE_PER_CPU(struct tss_struct, init_tss);
27162 +
27163 + #ifdef CONFIG_SMP
27164 + extern struct cpuinfo_x86 cpu_data[];
27165 +@@ -209,11 +207,19 @@ extern int bootloader_type;
27166 + */
27167 + #define TASK_SIZE (PAGE_OFFSET)
27168 +
27169 ++#ifdef CONFIG_PAX_SEGMEXEC
27170 ++#define SEGMEXEC_TASK_SIZE (TASK_SIZE / 2)
27171 ++#endif
27172 ++
27173 + /* This decides where the kernel will search for a free chunk of vm
27174 + * space during mmap's.
27175 + */
27176 + #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
27177 +
27178 ++#ifdef CONFIG_PAX_SEGMEXEC
27179 ++#define SEGMEXEC_TASK_UNMAPPED_BASE (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3))
27180 ++#endif
27181 ++
27182 + #define HAVE_ARCH_PICK_MMAP_LAYOUT
27183 +
27184 + extern void hard_disable_TSC(void);
27185 +@@ -338,6 +344,9 @@ struct tss_struct {
27186 +
27187 + #define ARCH_MIN_TASKALIGN 16
27188 +
27189 ++extern struct tss_struct doublefault_tss;
27190 ++extern struct tss_struct init_tss[NR_CPUS];
27191 ++
27192 + struct thread_struct {
27193 + /* cached TLS descriptors. */
27194 + struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
27195 +@@ -366,7 +375,7 @@ struct thread_struct {
27196 + };
27197 +
27198 + #define INIT_THREAD { \
27199 +- .esp0 = sizeof(init_stack) + (long)&init_stack, \
27200 ++ .esp0 = sizeof(init_stack) + (long)&init_stack - 8, \
27201 + .vm86_info = NULL, \
27202 + .sysenter_cs = __KERNEL_CS, \
27203 + .io_bitmap_ptr = NULL, \
27204 +@@ -381,7 +390,7 @@ struct thread_struct {
27205 + */
27206 + #define INIT_TSS { \
27207 + .x86_tss = { \
27208 +- .esp0 = sizeof(init_stack) + (long)&init_stack, \
27209 ++ .esp0 = sizeof(init_stack) + (long)&init_stack - 8, \
27210 + .ss0 = __KERNEL_DS, \
27211 + .ss1 = __KERNEL_CS, \
27212 + .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
27213 +@@ -422,11 +431,7 @@ void show_trace(struct task_struct *task
27214 + unsigned long get_wchan(struct task_struct *p);
27215 +
27216 + #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
27217 +-#define KSTK_TOP(info) \
27218 +-({ \
27219 +- unsigned long *__ptr = (unsigned long *)(info); \
27220 +- (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
27221 +-})
27222 ++#define KSTK_TOP(info) ((info)->task.thread.esp0)
27223 +
27224 + /*
27225 + * The below -8 is to reserve 8 bytes on top of the ring0 stack.
27226 +@@ -441,7 +446,7 @@ unsigned long get_wchan(struct task_stru
27227 + #define task_pt_regs(task) \
27228 + ({ \
27229 + struct pt_regs *__regs__; \
27230 +- __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
27231 ++ __regs__ = (struct pt_regs *)((task)->thread.esp0); \
27232 + __regs__ - 1; \
27233 + })
27234 +
27235 +@@ -603,8 +608,8 @@ static inline void cpuid(unsigned int op
27236 + }
27237 +
27238 + /* Some CPUID calls want 'count' to be placed in ecx */
27239 +-static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx,
27240 +- int *edx)
27241 ++static inline void cpuid_count(unsigned int op, unsigned int count, unsigned int *eax, unsigned int *ebx, unsigned int *ecx,
27242 ++ unsigned int *edx)
27243 + {
27244 + *eax = op;
27245 + *ecx = count;
27246 +diff -Nurp linux-2.6.23.15/include/asm-i386/ptrace.h linux-2.6.23.15-grsec/include/asm-i386/ptrace.h
27247 +--- linux-2.6.23.15/include/asm-i386/ptrace.h 2007-10-09 21:31:38.000000000 +0100
27248 ++++ linux-2.6.23.15-grsec/include/asm-i386/ptrace.h 2008-02-11 10:37:44.000000000 +0000
27249 +@@ -35,17 +35,18 @@ struct task_struct;
27250 + extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code);
27251 +
27252 + /*
27253 +- * user_mode_vm(regs) determines whether a register set came from user mode.
27254 ++ * user_mode(regs) determines whether a register set came from user mode.
27255 + * This is true if V8086 mode was enabled OR if the register set was from
27256 + * protected mode with RPL-3 CS value. This tricky test checks that with
27257 + * one comparison. Many places in the kernel can bypass this full check
27258 +- * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
27259 ++ * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
27260 ++ * be used.
27261 + */
27262 +-static inline int user_mode(struct pt_regs *regs)
27263 ++static inline int user_mode_novm(struct pt_regs *regs)
27264 + {
27265 + return (regs->xcs & SEGMENT_RPL_MASK) == USER_RPL;
27266 + }
27267 +-static inline int user_mode_vm(struct pt_regs *regs)
27268 ++static inline int user_mode(struct pt_regs *regs)
27269 + {
27270 + return ((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= USER_RPL;
27271 + }
27272 +diff -Nurp linux-2.6.23.15/include/asm-i386/reboot.h linux-2.6.23.15-grsec/include/asm-i386/reboot.h
27273 +--- linux-2.6.23.15/include/asm-i386/reboot.h 2007-10-09 21:31:38.000000000 +0100
27274 ++++ linux-2.6.23.15-grsec/include/asm-i386/reboot.h 2008-02-11 10:37:44.000000000 +0000
27275 +@@ -15,6 +15,6 @@ struct machine_ops
27276 +
27277 + extern struct machine_ops machine_ops;
27278 +
27279 +-void machine_real_restart(unsigned char *code, int length);
27280 ++void machine_real_restart(const unsigned char *code, unsigned int length);
27281 +
27282 + #endif /* _ASM_REBOOT_H */
27283 +diff -Nurp linux-2.6.23.15/include/asm-i386/segment.h linux-2.6.23.15-grsec/include/asm-i386/segment.h
27284 +--- linux-2.6.23.15/include/asm-i386/segment.h 2007-10-09 21:31:38.000000000 +0100
27285 ++++ linux-2.6.23.15-grsec/include/asm-i386/segment.h 2008-02-11 10:37:44.000000000 +0000
27286 +@@ -81,6 +81,12 @@
27287 + #define __KERNEL_PERCPU 0
27288 + #endif
27289 +
27290 ++#define GDT_ENTRY_PCIBIOS_CS (GDT_ENTRY_KERNEL_BASE + 16)
27291 ++#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8)
27292 ++
27293 ++#define GDT_ENTRY_PCIBIOS_DS (GDT_ENTRY_KERNEL_BASE + 17)
27294 ++#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8)
27295 ++
27296 + #define GDT_ENTRY_DOUBLEFAULT_TSS 31
27297 +
27298 + /*
27299 +@@ -140,9 +146,9 @@
27300 + #define SEGMENT_IS_KERNEL_CODE(x) (((x) & 0xfc) == GDT_ENTRY_KERNEL_CS * 8)
27301 +
27302 + /* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */
27303 +-#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8)
27304 ++#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xFFFCU) == __KERNEL_CS || ((x) & 0xFFFCU) == __USER_CS)
27305 +
27306 + /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
27307 +-#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
27308 ++#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
27309 +
27310 + #endif
27311 +diff -Nurp linux-2.6.23.15/include/asm-i386/system.h linux-2.6.23.15-grsec/include/asm-i386/system.h
27312 +--- linux-2.6.23.15/include/asm-i386/system.h 2008-02-11 10:36:03.000000000 +0000
27313 ++++ linux-2.6.23.15-grsec/include/asm-i386/system.h 2008-02-11 10:37:44.000000000 +0000
27314 +@@ -183,6 +183,21 @@ static inline void native_wbinvd(void)
27315 + /* Set the 'TS' bit */
27316 + #define stts() write_cr0(8 | read_cr0())
27317 +
27318 ++#define pax_open_kernel(cr0) \
27319 ++do { \
27320 ++ typecheck(unsigned long, cr0); \
27321 ++ preempt_disable(); \
27322 ++ cr0 = read_cr0(); \
27323 ++ write_cr0(cr0 & ~X86_CR0_WP); \
27324 ++} while (0)
27325 ++
27326 ++#define pax_close_kernel(cr0) \
27327 ++do { \
27328 ++ typecheck(unsigned long, cr0); \
27329 ++ write_cr0(cr0); \
27330 ++ preempt_enable_no_resched(); \
27331 ++} while (0)
27332 ++
27333 + #endif /* __KERNEL__ */
27334 +
27335 + static inline unsigned long get_limit(unsigned long segment)
27336 +@@ -190,7 +205,7 @@ static inline unsigned long get_limit(un
27337 + unsigned long __limit;
27338 + __asm__("lsll %1,%0"
27339 + :"=r" (__limit):"r" (segment));
27340 +- return __limit+1;
27341 ++ return __limit;
27342 + }
27343 +
27344 + #define nop() __asm__ __volatile__ ("nop")
27345 +@@ -305,7 +320,7 @@ void enable_hlt(void);
27346 + extern int es7000_plat;
27347 + void cpu_idle_wait(void);
27348 +
27349 +-extern unsigned long arch_align_stack(unsigned long sp);
27350 ++#define arch_align_stack(x) (x)
27351 + extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
27352 +
27353 + void default_idle(void);
27354 +diff -Nurp linux-2.6.23.15/include/asm-i386/uaccess.h linux-2.6.23.15-grsec/include/asm-i386/uaccess.h
27355 +--- linux-2.6.23.15/include/asm-i386/uaccess.h 2007-10-09 21:31:38.000000000 +0100
27356 ++++ linux-2.6.23.15-grsec/include/asm-i386/uaccess.h 2008-02-11 10:37:44.000000000 +0000
27357 +@@ -9,6 +9,7 @@
27358 + #include <linux/prefetch.h>
27359 + #include <linux/string.h>
27360 + #include <asm/page.h>
27361 ++#include <asm/segment.h>
27362 +
27363 + #define VERIFY_READ 0
27364 + #define VERIFY_WRITE 1
27365 +@@ -29,7 +30,8 @@
27366 +
27367 + #define get_ds() (KERNEL_DS)
27368 + #define get_fs() (current_thread_info()->addr_limit)
27369 +-#define set_fs(x) (current_thread_info()->addr_limit = (x))
27370 ++void __set_fs(mm_segment_t x, int cpu);
27371 ++void set_fs(mm_segment_t x);
27372 +
27373 + #define segment_eq(a,b) ((a).seg == (b).seg)
27374 +
27375 +@@ -101,6 +103,7 @@ struct exception_table_entry
27376 + };
27377 +
27378 + extern int fixup_exception(struct pt_regs *regs);
27379 ++#define ARCH_HAS_SORT_EXTABLE
27380 +
27381 + /*
27382 + * These are the main single-value transfer routines. They automatically
27383 +@@ -280,9 +283,12 @@ extern void __put_user_8(void);
27384 +
27385 + #define __put_user_u64(x, addr, err) \
27386 + __asm__ __volatile__( \
27387 +- "1: movl %%eax,0(%2)\n" \
27388 +- "2: movl %%edx,4(%2)\n" \
27389 ++ " movw %w5,%%ds\n" \
27390 ++ "1: movl %%eax,%%ds:0(%2)\n" \
27391 ++ "2: movl %%edx,%%ds:4(%2)\n" \
27392 + "3:\n" \
27393 ++ " pushl %%ss\n" \
27394 ++ " popl %%ds\n" \
27395 + ".section .fixup,\"ax\"\n" \
27396 + "4: movl %3,%0\n" \
27397 + " jmp 3b\n" \
27398 +@@ -293,7 +299,8 @@ extern void __put_user_8(void);
27399 + " .long 2b,4b\n" \
27400 + ".previous" \
27401 + : "=r"(err) \
27402 +- : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err))
27403 ++ : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err), \
27404 ++ "r"(__USER_DS))
27405 +
27406 + #ifdef CONFIG_X86_WP_WORKS_OK
27407 +
27408 +@@ -332,8 +339,11 @@ struct __large_struct { unsigned long bu
27409 + */
27410 + #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
27411 + __asm__ __volatile__( \
27412 +- "1: mov"itype" %"rtype"1,%2\n" \
27413 ++ " movw %w5,%%ds\n" \
27414 ++ "1: mov"itype" %"rtype"1,%%ds:%2\n" \
27415 + "2:\n" \
27416 ++ " pushl %%ss\n" \
27417 ++ " popl %%ds\n" \
27418 + ".section .fixup,\"ax\"\n" \
27419 + "3: movl %3,%0\n" \
27420 + " jmp 2b\n" \
27421 +@@ -343,7 +353,8 @@ struct __large_struct { unsigned long bu
27422 + " .long 1b,3b\n" \
27423 + ".previous" \
27424 + : "=r"(err) \
27425 +- : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err))
27426 ++ : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err), \
27427 ++ "r"(__USER_DS))
27428 +
27429 +
27430 + #define __get_user_nocheck(x,ptr,size) \
27431 +@@ -371,8 +382,11 @@ do { \
27432 +
27433 + #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
27434 + __asm__ __volatile__( \
27435 +- "1: mov"itype" %2,%"rtype"1\n" \
27436 ++ " movw %w5,%%ds\n" \
27437 ++ "1: mov"itype" %%ds:%2,%"rtype"1\n" \
27438 + "2:\n" \
27439 ++ " pushl %%ss\n" \
27440 ++ " popl %%ds\n" \
27441 + ".section .fixup,\"ax\"\n" \
27442 + "3: movl %3,%0\n" \
27443 + " xor"itype" %"rtype"1,%"rtype"1\n" \
27444 +@@ -383,7 +397,7 @@ do { \
27445 + " .long 1b,3b\n" \
27446 + ".previous" \
27447 + : "=r"(err), ltype (x) \
27448 +- : "m"(__m(addr)), "i"(errret), "0"(err))
27449 ++ : "m"(__m(addr)), "i"(errret), "0"(err), "r"(__USER_DS))
27450 +
27451 +
27452 + unsigned long __must_check __copy_to_user_ll(void __user *to,
27453 +diff -Nurp linux-2.6.23.15/include/asm-ia64/elf.h linux-2.6.23.15-grsec/include/asm-ia64/elf.h
27454 +--- linux-2.6.23.15/include/asm-ia64/elf.h 2007-10-09 21:31:38.000000000 +0100
27455 ++++ linux-2.6.23.15-grsec/include/asm-ia64/elf.h 2008-02-11 10:37:44.000000000 +0000
27456 +@@ -162,7 +162,12 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
27457 + typedef struct ia64_fpreg elf_fpreg_t;
27458 + typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
27459 +
27460 ++#ifdef CONFIG_PAX_ASLR
27461 ++#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
27462 +
27463 ++#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
27464 ++#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
27465 ++#endif
27466 +
27467 + struct pt_regs; /* forward declaration... */
27468 + extern void ia64_elf_core_copy_regs (struct pt_regs *src, elf_gregset_t dst);
27469 +diff -Nurp linux-2.6.23.15/include/asm-ia64/kmap_types.h linux-2.6.23.15-grsec/include/asm-ia64/kmap_types.h
27470 +--- linux-2.6.23.15/include/asm-ia64/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
27471 ++++ linux-2.6.23.15-grsec/include/asm-ia64/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
27472 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
27473 + D(10) KM_IRQ1,
27474 + D(11) KM_SOFTIRQ0,
27475 + D(12) KM_SOFTIRQ1,
27476 +-D(13) KM_TYPE_NR
27477 ++D(13) KM_CLEARPAGE,
27478 ++D(14) KM_TYPE_NR
27479 + };
27480 +
27481 + #undef D
27482 +diff -Nurp linux-2.6.23.15/include/asm-ia64/pgtable.h linux-2.6.23.15-grsec/include/asm-ia64/pgtable.h
27483 +--- linux-2.6.23.15/include/asm-ia64/pgtable.h 2007-10-09 21:31:38.000000000 +0100
27484 ++++ linux-2.6.23.15-grsec/include/asm-ia64/pgtable.h 2008-02-11 10:37:44.000000000 +0000
27485 +@@ -143,6 +143,17 @@
27486 + #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
27487 + #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
27488 + #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
27489 ++
27490 ++#ifdef CONFIG_PAX_PAGEEXEC
27491 ++# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
27492 ++# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
27493 ++# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
27494 ++#else
27495 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
27496 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
27497 ++# define PAGE_COPY_NOEXEC PAGE_COPY
27498 ++#endif
27499 ++
27500 + #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
27501 + #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
27502 + #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
27503 +diff -Nurp linux-2.6.23.15/include/asm-ia64/processor.h linux-2.6.23.15-grsec/include/asm-ia64/processor.h
27504 +--- linux-2.6.23.15/include/asm-ia64/processor.h 2007-10-09 21:31:38.000000000 +0100
27505 ++++ linux-2.6.23.15-grsec/include/asm-ia64/processor.h 2008-02-11 10:37:44.000000000 +0000
27506 +@@ -275,7 +275,7 @@ struct thread_struct {
27507 + .on_ustack = 0, \
27508 + .ksp = 0, \
27509 + .map_base = DEFAULT_MAP_BASE, \
27510 +- .rbs_bot = STACK_TOP - DEFAULT_USER_STACK_SIZE, \
27511 ++ .rbs_bot = __STACK_TOP - DEFAULT_USER_STACK_SIZE, \
27512 + .task_size = DEFAULT_TASK_SIZE, \
27513 + .last_fph_cpu = -1, \
27514 + INIT_THREAD_IA32 \
27515 +diff -Nurp linux-2.6.23.15/include/asm-ia64/ustack.h linux-2.6.23.15-grsec/include/asm-ia64/ustack.h
27516 +--- linux-2.6.23.15/include/asm-ia64/ustack.h 2007-10-09 21:31:38.000000000 +0100
27517 ++++ linux-2.6.23.15-grsec/include/asm-ia64/ustack.h 2008-02-11 10:37:44.000000000 +0000
27518 +@@ -10,8 +10,8 @@
27519 +
27520 + /* The absolute hard limit for stack size is 1/2 of the mappable space in the region */
27521 + #define MAX_USER_STACK_SIZE (RGN_MAP_LIMIT/2)
27522 +-#define STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT)
27523 +-#define STACK_TOP_MAX STACK_TOP
27524 ++#define __STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT)
27525 ++#define STACK_TOP_MAX __STACK_TOP
27526 + #endif
27527 +
27528 + /* Make a default stack size of 2GiB */
27529 +diff -Nurp linux-2.6.23.15/include/asm-m32r/kmap_types.h linux-2.6.23.15-grsec/include/asm-m32r/kmap_types.h
27530 +--- linux-2.6.23.15/include/asm-m32r/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
27531 ++++ linux-2.6.23.15-grsec/include/asm-m32r/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
27532 +@@ -21,7 +21,8 @@ D(9) KM_IRQ0,
27533 + D(10) KM_IRQ1,
27534 + D(11) KM_SOFTIRQ0,
27535 + D(12) KM_SOFTIRQ1,
27536 +-D(13) KM_TYPE_NR
27537 ++D(13) KM_CLEARPAGE,
27538 ++D(14) KM_TYPE_NR
27539 + };
27540 +
27541 + #undef D
27542 +diff -Nurp linux-2.6.23.15/include/asm-m68k/kmap_types.h linux-2.6.23.15-grsec/include/asm-m68k/kmap_types.h
27543 +--- linux-2.6.23.15/include/asm-m68k/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
27544 ++++ linux-2.6.23.15-grsec/include/asm-m68k/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
27545 +@@ -15,6 +15,7 @@ enum km_type {
27546 + KM_IRQ1,
27547 + KM_SOFTIRQ0,
27548 + KM_SOFTIRQ1,
27549 ++ KM_CLEARPAGE,
27550 + KM_TYPE_NR
27551 + };
27552 +
27553 +diff -Nurp linux-2.6.23.15/include/asm-m68knommu/kmap_types.h linux-2.6.23.15-grsec/include/asm-m68knommu/kmap_types.h
27554 +--- linux-2.6.23.15/include/asm-m68knommu/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
27555 ++++ linux-2.6.23.15-grsec/include/asm-m68knommu/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
27556 +@@ -15,6 +15,7 @@ enum km_type {
27557 + KM_IRQ1,
27558 + KM_SOFTIRQ0,
27559 + KM_SOFTIRQ1,
27560 ++ KM_CLEARPAGE,
27561 + KM_TYPE_NR
27562 + };
27563 +
27564 +diff -Nurp linux-2.6.23.15/include/asm-mips/a.out.h linux-2.6.23.15-grsec/include/asm-mips/a.out.h
27565 +--- linux-2.6.23.15/include/asm-mips/a.out.h 2007-10-09 21:31:38.000000000 +0100
27566 ++++ linux-2.6.23.15-grsec/include/asm-mips/a.out.h 2008-02-11 10:37:44.000000000 +0000
27567 +@@ -35,10 +35,10 @@ struct exec
27568 + #ifdef __KERNEL__
27569 +
27570 + #ifdef CONFIG_32BIT
27571 +-#define STACK_TOP TASK_SIZE
27572 ++#define __STACK_TOP TASK_SIZE
27573 + #endif
27574 + #ifdef CONFIG_64BIT
27575 +-#define STACK_TOP \
27576 ++#define __STACK_TOP \
27577 + (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE)
27578 + #endif
27579 + #define STACK_TOP_MAX TASK_SIZE
27580 +diff -Nurp linux-2.6.23.15/include/asm-mips/elf.h linux-2.6.23.15-grsec/include/asm-mips/elf.h
27581 +--- linux-2.6.23.15/include/asm-mips/elf.h 2007-10-09 21:31:38.000000000 +0100
27582 ++++ linux-2.6.23.15-grsec/include/asm-mips/elf.h 2008-02-11 10:37:44.000000000 +0000
27583 +@@ -372,4 +372,11 @@ extern int dump_task_fpu(struct task_str
27584 + #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
27585 + #endif
27586 +
27587 ++#ifdef CONFIG_PAX_ASLR
27588 ++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
27589 ++
27590 ++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
27591 ++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
27592 ++#endif
27593 ++
27594 + #endif /* _ASM_ELF_H */
27595 +diff -Nurp linux-2.6.23.15/include/asm-mips/kmap_types.h linux-2.6.23.15-grsec/include/asm-mips/kmap_types.h
27596 +--- linux-2.6.23.15/include/asm-mips/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
27597 ++++ linux-2.6.23.15-grsec/include/asm-mips/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
27598 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
27599 + D(10) KM_IRQ1,
27600 + D(11) KM_SOFTIRQ0,
27601 + D(12) KM_SOFTIRQ1,
27602 +-D(13) KM_TYPE_NR
27603 ++D(13) KM_CLEARPAGE,
27604 ++D(14) KM_TYPE_NR
27605 + };
27606 +
27607 + #undef D
27608 +diff -Nurp linux-2.6.23.15/include/asm-mips/page.h linux-2.6.23.15-grsec/include/asm-mips/page.h
27609 +--- linux-2.6.23.15/include/asm-mips/page.h 2007-10-09 21:31:38.000000000 +0100
27610 ++++ linux-2.6.23.15-grsec/include/asm-mips/page.h 2008-02-11 10:37:44.000000000 +0000
27611 +@@ -82,7 +82,7 @@ extern void copy_user_highpage(struct pa
27612 + #ifdef CONFIG_CPU_MIPS32
27613 + typedef struct { unsigned long pte_low, pte_high; } pte_t;
27614 + #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
27615 +- #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
27616 ++ #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
27617 + #else
27618 + typedef struct { unsigned long long pte; } pte_t;
27619 + #define pte_val(x) ((x).pte)
27620 +diff -Nurp linux-2.6.23.15/include/asm-mips/system.h linux-2.6.23.15-grsec/include/asm-mips/system.h
27621 +--- linux-2.6.23.15/include/asm-mips/system.h 2007-10-09 21:31:38.000000000 +0100
27622 ++++ linux-2.6.23.15-grsec/include/asm-mips/system.h 2008-02-11 10:37:44.000000000 +0000
27623 +@@ -213,6 +213,6 @@ extern int stop_a_enabled;
27624 + */
27625 + #define __ARCH_WANT_UNLOCKED_CTXSW
27626 +
27627 +-extern unsigned long arch_align_stack(unsigned long sp);
27628 ++#define arch_align_stack(x) (x)
27629 +
27630 + #endif /* _ASM_SYSTEM_H */
27631 +diff -Nurp linux-2.6.23.15/include/asm-parisc/a.out.h linux-2.6.23.15-grsec/include/asm-parisc/a.out.h
27632 +--- linux-2.6.23.15/include/asm-parisc/a.out.h 2007-10-09 21:31:38.000000000 +0100
27633 ++++ linux-2.6.23.15-grsec/include/asm-parisc/a.out.h 2008-02-11 10:37:44.000000000 +0000
27634 +@@ -22,7 +22,7 @@ struct exec
27635 + /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
27636 + * prumpf */
27637 +
27638 +-#define STACK_TOP TASK_SIZE
27639 ++#define __STACK_TOP TASK_SIZE
27640 + #define STACK_TOP_MAX DEFAULT_TASK_SIZE
27641 +
27642 + #endif
27643 +diff -Nurp linux-2.6.23.15/include/asm-parisc/elf.h linux-2.6.23.15-grsec/include/asm-parisc/elf.h
27644 +--- linux-2.6.23.15/include/asm-parisc/elf.h 2007-10-09 21:31:38.000000000 +0100
27645 ++++ linux-2.6.23.15-grsec/include/asm-parisc/elf.h 2008-02-11 10:37:44.000000000 +0000
27646 +@@ -337,6 +337,13 @@ struct pt_regs; /* forward declaration..
27647 +
27648 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
27649 +
27650 ++#ifdef CONFIG_PAX_ASLR
27651 ++#define PAX_ELF_ET_DYN_BASE 0x10000UL
27652 ++
27653 ++#define PAX_DELTA_MMAP_LEN 16
27654 ++#define PAX_DELTA_STACK_LEN 16
27655 ++#endif
27656 ++
27657 + /* This yields a mask that user programs can use to figure out what
27658 + instruction set this CPU supports. This could be done in user space,
27659 + but it's not easy, and we've already done it here. */
27660 +diff -Nurp linux-2.6.23.15/include/asm-parisc/kmap_types.h linux-2.6.23.15-grsec/include/asm-parisc/kmap_types.h
27661 +--- linux-2.6.23.15/include/asm-parisc/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
27662 ++++ linux-2.6.23.15-grsec/include/asm-parisc/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
27663 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
27664 + D(10) KM_IRQ1,
27665 + D(11) KM_SOFTIRQ0,
27666 + D(12) KM_SOFTIRQ1,
27667 +-D(13) KM_TYPE_NR
27668 ++D(13) KM_CLEARPAGE,
27669 ++D(14) KM_TYPE_NR
27670 + };
27671 +
27672 + #undef D
27673 +diff -Nurp linux-2.6.23.15/include/asm-parisc/pgtable.h linux-2.6.23.15-grsec/include/asm-parisc/pgtable.h
27674 +--- linux-2.6.23.15/include/asm-parisc/pgtable.h 2007-10-09 21:31:38.000000000 +0100
27675 ++++ linux-2.6.23.15-grsec/include/asm-parisc/pgtable.h 2008-02-11 10:37:44.000000000 +0000
27676 +@@ -218,6 +218,17 @@ extern void *vmalloc_start;
27677 + #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
27678 + #define PAGE_COPY PAGE_EXECREAD
27679 + #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
27680 ++
27681 ++#ifdef CONFIG_PAX_PAGEEXEC
27682 ++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
27683 ++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
27684 ++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
27685 ++#else
27686 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
27687 ++# define PAGE_COPY_NOEXEC PAGE_COPY
27688 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
27689 ++#endif
27690 ++
27691 + #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
27692 + #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
27693 + #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
27694 +diff -Nurp linux-2.6.23.15/include/asm-powerpc/a.out.h linux-2.6.23.15-grsec/include/asm-powerpc/a.out.h
27695 +--- linux-2.6.23.15/include/asm-powerpc/a.out.h 2007-10-09 21:31:38.000000000 +0100
27696 ++++ linux-2.6.23.15-grsec/include/asm-powerpc/a.out.h 2008-02-11 10:37:44.000000000 +0000
27697 +@@ -23,15 +23,15 @@ struct exec
27698 + #define STACK_TOP_USER64 TASK_SIZE_USER64
27699 + #define STACK_TOP_USER32 TASK_SIZE_USER32
27700 +
27701 +-#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
27702 ++#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
27703 + STACK_TOP_USER32 : STACK_TOP_USER64)
27704 +
27705 + #define STACK_TOP_MAX STACK_TOP_USER64
27706 +
27707 + #else /* __powerpc64__ */
27708 +
27709 +-#define STACK_TOP TASK_SIZE
27710 +-#define STACK_TOP_MAX STACK_TOP
27711 ++#define __STACK_TOP TASK_SIZE
27712 ++#define STACK_TOP_MAX __STACK_TOP
27713 +
27714 + #endif /* __powerpc64__ */
27715 + #endif /* __KERNEL__ */
27716 +diff -Nurp linux-2.6.23.15/include/asm-powerpc/elf.h linux-2.6.23.15-grsec/include/asm-powerpc/elf.h
27717 +--- linux-2.6.23.15/include/asm-powerpc/elf.h 2007-10-09 21:31:38.000000000 +0100
27718 ++++ linux-2.6.23.15-grsec/include/asm-powerpc/elf.h 2008-02-11 10:37:44.000000000 +0000
27719 +@@ -159,6 +159,18 @@ typedef elf_vrreg_t elf_vrregset_t[ELF_N
27720 + typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
27721 + #endif
27722 +
27723 ++#ifdef CONFIG_PAX_ASLR
27724 ++#define PAX_ELF_ET_DYN_BASE (0x10000000UL)
27725 ++
27726 ++#ifdef __powerpc64__
27727 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
27728 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
27729 ++#else
27730 ++#define PAX_DELTA_MMAP_LEN 15
27731 ++#define PAX_DELTA_STACK_LEN 15
27732 ++#endif
27733 ++#endif
27734 ++
27735 + #ifdef __KERNEL__
27736 + /*
27737 + * This is used to ensure we don't load something for the wrong architecture.
27738 +diff -Nurp linux-2.6.23.15/include/asm-powerpc/kmap_types.h linux-2.6.23.15-grsec/include/asm-powerpc/kmap_types.h
27739 +--- linux-2.6.23.15/include/asm-powerpc/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
27740 ++++ linux-2.6.23.15-grsec/include/asm-powerpc/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
27741 +@@ -26,6 +26,7 @@ enum km_type {
27742 + KM_SOFTIRQ1,
27743 + KM_PPC_SYNC_PAGE,
27744 + KM_PPC_SYNC_ICACHE,
27745 ++ KM_CLEARPAGE,
27746 + KM_TYPE_NR
27747 + };
27748 +
27749 +diff -Nurp linux-2.6.23.15/include/asm-powerpc/page.h linux-2.6.23.15-grsec/include/asm-powerpc/page.h
27750 +--- linux-2.6.23.15/include/asm-powerpc/page.h 2007-10-09 21:31:38.000000000 +0100
27751 ++++ linux-2.6.23.15-grsec/include/asm-powerpc/page.h 2008-02-11 10:37:44.000000000 +0000
27752 +@@ -71,8 +71,9 @@
27753 + * and needs to be executable. This means the whole heap ends
27754 + * up being executable.
27755 + */
27756 +-#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
27757 +- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
27758 ++#define VM_DATA_DEFAULT_FLAGS32 \
27759 ++ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
27760 ++ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
27761 +
27762 + #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
27763 + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
27764 +diff -Nurp linux-2.6.23.15/include/asm-powerpc/page_64.h linux-2.6.23.15-grsec/include/asm-powerpc/page_64.h
27765 +--- linux-2.6.23.15/include/asm-powerpc/page_64.h 2007-10-09 21:31:38.000000000 +0100
27766 ++++ linux-2.6.23.15-grsec/include/asm-powerpc/page_64.h 2008-02-11 10:37:44.000000000 +0000
27767 +@@ -158,15 +158,18 @@ extern int is_hugepage_only_range(struct
27768 + * stack by default, so in the absense of a PT_GNU_STACK program header
27769 + * we turn execute permission off.
27770 + */
27771 +-#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
27772 +- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
27773 ++#define VM_STACK_DEFAULT_FLAGS32 \
27774 ++ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
27775 ++ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
27776 +
27777 + #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
27778 + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
27779 +
27780 ++#ifndef CONFIG_PAX_PAGEEXEC
27781 + #define VM_STACK_DEFAULT_FLAGS \
27782 + (test_thread_flag(TIF_32BIT) ? \
27783 + VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
27784 ++#endif
27785 +
27786 + #include <asm-generic/page.h>
27787 +
27788 +diff -Nurp linux-2.6.23.15/include/asm-ppc/mmu_context.h linux-2.6.23.15-grsec/include/asm-ppc/mmu_context.h
27789 +--- linux-2.6.23.15/include/asm-ppc/mmu_context.h 2007-10-09 21:31:38.000000000 +0100
27790 ++++ linux-2.6.23.15-grsec/include/asm-ppc/mmu_context.h 2008-02-11 10:37:44.000000000 +0000
27791 +@@ -145,7 +145,8 @@ static inline void get_mmu_context(struc
27792 + static inline int init_new_context(struct task_struct *t, struct mm_struct *mm)
27793 + {
27794 + mm->context.id = NO_CONTEXT;
27795 +- mm->context.vdso_base = 0;
27796 ++ if (t == current)
27797 ++ mm->context.vdso_base = ~0UL;
27798 + return 0;
27799 + }
27800 +
27801 +diff -Nurp linux-2.6.23.15/include/asm-ppc/pgtable.h linux-2.6.23.15-grsec/include/asm-ppc/pgtable.h
27802 +--- linux-2.6.23.15/include/asm-ppc/pgtable.h 2007-10-09 21:31:38.000000000 +0100
27803 ++++ linux-2.6.23.15-grsec/include/asm-ppc/pgtable.h 2008-02-11 10:37:44.000000000 +0000
27804 +@@ -440,11 +440,21 @@ extern unsigned long ioremap_bot, iorema
27805 +
27806 + #define PAGE_NONE __pgprot(_PAGE_BASE)
27807 + #define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
27808 +-#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
27809 ++#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
27810 + #define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
27811 +-#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
27812 ++#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
27813 + #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
27814 +-#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
27815 ++#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
27816 ++
27817 ++#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
27818 ++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
27819 ++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
27820 ++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
27821 ++#else
27822 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
27823 ++# define PAGE_COPY_NOEXEC PAGE_COPY
27824 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
27825 ++#endif
27826 +
27827 + #define PAGE_KERNEL __pgprot(_PAGE_RAM)
27828 + #define PAGE_KERNEL_NOCACHE __pgprot(_PAGE_IO)
27829 +@@ -456,21 +466,21 @@ extern unsigned long ioremap_bot, iorema
27830 + * This is the closest we can get..
27831 + */
27832 + #define __P000 PAGE_NONE
27833 +-#define __P001 PAGE_READONLY_X
27834 +-#define __P010 PAGE_COPY
27835 +-#define __P011 PAGE_COPY_X
27836 +-#define __P100 PAGE_READONLY
27837 ++#define __P001 PAGE_READONLY_NOEXEC
27838 ++#define __P010 PAGE_COPY_NOEXEC
27839 ++#define __P011 PAGE_COPY_NOEXEC
27840 ++#define __P100 PAGE_READONLY_X
27841 + #define __P101 PAGE_READONLY_X
27842 +-#define __P110 PAGE_COPY
27843 ++#define __P110 PAGE_COPY_X
27844 + #define __P111 PAGE_COPY_X
27845 +
27846 + #define __S000 PAGE_NONE
27847 +-#define __S001 PAGE_READONLY_X
27848 +-#define __S010 PAGE_SHARED
27849 +-#define __S011 PAGE_SHARED_X
27850 +-#define __S100 PAGE_READONLY
27851 ++#define __S001 PAGE_READONLY_NOEXEC
27852 ++#define __S010 PAGE_SHARED_NOEXEC
27853 ++#define __S011 PAGE_SHARED_NOEXEC
27854 ++#define __S100 PAGE_READONLY_X
27855 + #define __S101 PAGE_READONLY_X
27856 +-#define __S110 PAGE_SHARED
27857 ++#define __S110 PAGE_SHARED_X
27858 + #define __S111 PAGE_SHARED_X
27859 +
27860 + #ifndef __ASSEMBLY__
27861 +diff -Nurp linux-2.6.23.15/include/asm-s390/kmap_types.h linux-2.6.23.15-grsec/include/asm-s390/kmap_types.h
27862 +--- linux-2.6.23.15/include/asm-s390/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
27863 ++++ linux-2.6.23.15-grsec/include/asm-s390/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
27864 +@@ -16,6 +16,7 @@ enum km_type {
27865 + KM_IRQ1,
27866 + KM_SOFTIRQ0,
27867 + KM_SOFTIRQ1,
27868 ++ KM_CLEARPAGE,
27869 + KM_TYPE_NR
27870 + };
27871 +
27872 +diff -Nurp linux-2.6.23.15/include/asm-sh/kmap_types.h linux-2.6.23.15-grsec/include/asm-sh/kmap_types.h
27873 +--- linux-2.6.23.15/include/asm-sh/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
27874 ++++ linux-2.6.23.15-grsec/include/asm-sh/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
27875 +@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
27876 + D(10) KM_IRQ1,
27877 + D(11) KM_SOFTIRQ0,
27878 + D(12) KM_SOFTIRQ1,
27879 +-D(13) KM_TYPE_NR
27880 ++D(13) KM_CLEARPAGE,
27881 ++D(14) KM_TYPE_NR
27882 + };
27883 +
27884 + #undef D
27885 +diff -Nurp linux-2.6.23.15/include/asm-sparc/a.out.h linux-2.6.23.15-grsec/include/asm-sparc/a.out.h
27886 +--- linux-2.6.23.15/include/asm-sparc/a.out.h 2007-10-09 21:31:38.000000000 +0100
27887 ++++ linux-2.6.23.15-grsec/include/asm-sparc/a.out.h 2008-02-11 10:37:44.000000000 +0000
27888 +@@ -91,8 +91,8 @@ struct relocation_info /* used when head
27889 +
27890 + #include <asm/page.h>
27891 +
27892 +-#define STACK_TOP (PAGE_OFFSET - PAGE_SIZE)
27893 +-#define STACK_TOP_MAX STACK_TOP
27894 ++#define __STACK_TOP (PAGE_OFFSET - PAGE_SIZE)
27895 ++#define STACK_TOP_MAX __STACK_TOP
27896 +
27897 + #endif /* __KERNEL__ */
27898 +
27899 +diff -Nurp linux-2.6.23.15/include/asm-sparc/elf.h linux-2.6.23.15-grsec/include/asm-sparc/elf.h
27900 +--- linux-2.6.23.15/include/asm-sparc/elf.h 2007-10-09 21:31:38.000000000 +0100
27901 ++++ linux-2.6.23.15-grsec/include/asm-sparc/elf.h 2008-02-11 10:37:44.000000000 +0000
27902 +@@ -143,6 +143,13 @@ do { unsigned long *dest = &(__elf_regs[
27903 +
27904 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
27905 +
27906 ++#ifdef CONFIG_PAX_ASLR
27907 ++#define PAX_ELF_ET_DYN_BASE 0x10000UL
27908 ++
27909 ++#define PAX_DELTA_MMAP_LEN 16
27910 ++#define PAX_DELTA_STACK_LEN 16
27911 ++#endif
27912 ++
27913 + /* This yields a mask that user programs can use to figure out what
27914 + instruction set this cpu supports. This can NOT be done in userspace
27915 + on Sparc. */
27916 +diff -Nurp linux-2.6.23.15/include/asm-sparc/kmap_types.h linux-2.6.23.15-grsec/include/asm-sparc/kmap_types.h
27917 +--- linux-2.6.23.15/include/asm-sparc/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
27918 ++++ linux-2.6.23.15-grsec/include/asm-sparc/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
27919 +@@ -15,6 +15,7 @@ enum km_type {
27920 + KM_IRQ1,
27921 + KM_SOFTIRQ0,
27922 + KM_SOFTIRQ1,
27923 ++ KM_CLEARPAGE,
27924 + KM_TYPE_NR
27925 + };
27926 +
27927 +diff -Nurp linux-2.6.23.15/include/asm-sparc/pgtable.h linux-2.6.23.15-grsec/include/asm-sparc/pgtable.h
27928 +--- linux-2.6.23.15/include/asm-sparc/pgtable.h 2007-10-09 21:31:38.000000000 +0100
27929 ++++ linux-2.6.23.15-grsec/include/asm-sparc/pgtable.h 2008-02-11 10:37:44.000000000 +0000
27930 +@@ -69,6 +69,16 @@ extern pgprot_t PAGE_SHARED;
27931 + #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
27932 + #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
27933 +
27934 ++#ifdef CONFIG_PAX_PAGEEXEC
27935 ++extern pgprot_t PAGE_SHARED_NOEXEC;
27936 ++# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec))
27937 ++# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec))
27938 ++#else
27939 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
27940 ++# define PAGE_COPY_NOEXEC PAGE_COPY
27941 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
27942 ++#endif
27943 ++
27944 + extern unsigned long page_kernel;
27945 +
27946 + #ifdef MODULE
27947 +diff -Nurp linux-2.6.23.15/include/asm-sparc/pgtsrmmu.h linux-2.6.23.15-grsec/include/asm-sparc/pgtsrmmu.h
27948 +--- linux-2.6.23.15/include/asm-sparc/pgtsrmmu.h 2007-10-09 21:31:38.000000000 +0100
27949 ++++ linux-2.6.23.15-grsec/include/asm-sparc/pgtsrmmu.h 2008-02-11 10:37:44.000000000 +0000
27950 +@@ -115,6 +115,16 @@
27951 + SRMMU_EXEC | SRMMU_REF)
27952 + #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
27953 + SRMMU_EXEC | SRMMU_REF)
27954 ++
27955 ++#ifdef CONFIG_PAX_PAGEEXEC
27956 ++#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
27957 ++ SRMMU_WRITE | SRMMU_REF)
27958 ++#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
27959 ++ SRMMU_REF)
27960 ++#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
27961 ++ SRMMU_REF)
27962 ++#endif
27963 ++
27964 + #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
27965 + SRMMU_DIRTY | SRMMU_REF)
27966 +
27967 +diff -Nurp linux-2.6.23.15/include/asm-sparc/uaccess.h linux-2.6.23.15-grsec/include/asm-sparc/uaccess.h
27968 +--- linux-2.6.23.15/include/asm-sparc/uaccess.h 2007-10-09 21:31:38.000000000 +0100
27969 ++++ linux-2.6.23.15-grsec/include/asm-sparc/uaccess.h 2008-02-11 10:37:44.000000000 +0000
27970 +@@ -41,7 +41,7 @@
27971 + * No one can read/write anything from userland in the kernel space by setting
27972 + * large size and address near to PAGE_OFFSET - a fault will break his intentions.
27973 + */
27974 +-#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
27975 ++#define __user_ok(addr, size) ({ (void)(size); (addr) < __STACK_TOP; })
27976 + #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
27977 + #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
27978 + #define access_ok(type, addr, size) \
27979 +diff -Nurp linux-2.6.23.15/include/asm-sparc64/a.out.h linux-2.6.23.15-grsec/include/asm-sparc64/a.out.h
27980 +--- linux-2.6.23.15/include/asm-sparc64/a.out.h 2007-10-09 21:31:38.000000000 +0100
27981 ++++ linux-2.6.23.15-grsec/include/asm-sparc64/a.out.h 2008-02-11 10:37:44.000000000 +0000
27982 +@@ -98,7 +98,7 @@ struct relocation_info /* used when head
27983 + #define STACK_TOP32 ((1UL << 32UL) - PAGE_SIZE)
27984 + #define STACK_TOP64 (0x0000080000000000UL - (1UL << 32UL))
27985 +
27986 +-#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
27987 ++#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
27988 + STACK_TOP32 : STACK_TOP64)
27989 +
27990 + #define STACK_TOP_MAX STACK_TOP64
27991 +diff -Nurp linux-2.6.23.15/include/asm-sparc64/elf.h linux-2.6.23.15-grsec/include/asm-sparc64/elf.h
27992 +--- linux-2.6.23.15/include/asm-sparc64/elf.h 2007-10-09 21:31:38.000000000 +0100
27993 ++++ linux-2.6.23.15-grsec/include/asm-sparc64/elf.h 2008-02-11 10:37:44.000000000 +0000
27994 +@@ -143,6 +143,12 @@ typedef struct {
27995 + #define ELF_ET_DYN_BASE 0x0000010000000000UL
27996 + #endif
27997 +
27998 ++#ifdef CONFIG_PAX_ASLR
27999 ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
28000 ++
28001 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 14 : 28 )
28002 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 15 : 29 )
28003 ++#endif
28004 +
28005 + /* This yields a mask that user programs can use to figure out what
28006 + instruction set this cpu supports. */
28007 +diff -Nurp linux-2.6.23.15/include/asm-sparc64/kmap_types.h linux-2.6.23.15-grsec/include/asm-sparc64/kmap_types.h
28008 +--- linux-2.6.23.15/include/asm-sparc64/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
28009 ++++ linux-2.6.23.15-grsec/include/asm-sparc64/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
28010 +@@ -19,6 +19,7 @@ enum km_type {
28011 + KM_IRQ1,
28012 + KM_SOFTIRQ0,
28013 + KM_SOFTIRQ1,
28014 ++ KM_CLEARPAGE,
28015 + KM_TYPE_NR
28016 + };
28017 +
28018 +diff -Nurp linux-2.6.23.15/include/asm-um/kmap_types.h linux-2.6.23.15-grsec/include/asm-um/kmap_types.h
28019 +--- linux-2.6.23.15/include/asm-um/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
28020 ++++ linux-2.6.23.15-grsec/include/asm-um/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
28021 +@@ -23,6 +23,7 @@ enum km_type {
28022 + KM_IRQ1,
28023 + KM_SOFTIRQ0,
28024 + KM_SOFTIRQ1,
28025 ++ KM_CLEARPAGE,
28026 + KM_TYPE_NR
28027 + };
28028 +
28029 +diff -Nurp linux-2.6.23.15/include/asm-v850/kmap_types.h linux-2.6.23.15-grsec/include/asm-v850/kmap_types.h
28030 +--- linux-2.6.23.15/include/asm-v850/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
28031 ++++ linux-2.6.23.15-grsec/include/asm-v850/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
28032 +@@ -13,6 +13,7 @@ enum km_type {
28033 + KM_PTE1,
28034 + KM_IRQ0,
28035 + KM_IRQ1,
28036 ++ KM_CLEARPAGE,
28037 + KM_TYPE_NR
28038 + };
28039 +
28040 +diff -Nurp linux-2.6.23.15/include/asm-x86_64/a.out.h linux-2.6.23.15-grsec/include/asm-x86_64/a.out.h
28041 +--- linux-2.6.23.15/include/asm-x86_64/a.out.h 2007-10-09 21:31:38.000000000 +0100
28042 ++++ linux-2.6.23.15-grsec/include/asm-x86_64/a.out.h 2008-02-11 10:37:45.000000000 +0000
28043 +@@ -21,7 +21,7 @@ struct exec
28044 +
28045 + #ifdef __KERNEL__
28046 + #include <linux/thread_info.h>
28047 +-#define STACK_TOP TASK_SIZE
28048 ++#define __STACK_TOP TASK_SIZE
28049 + #define STACK_TOP_MAX TASK_SIZE64
28050 + #endif
28051 +
28052 +diff -Nurp linux-2.6.23.15/include/asm-x86_64/apic.h linux-2.6.23.15-grsec/include/asm-x86_64/apic.h
28053 +--- linux-2.6.23.15/include/asm-x86_64/apic.h 2007-10-09 21:31:38.000000000 +0100
28054 ++++ linux-2.6.23.15-grsec/include/asm-x86_64/apic.h 2008-02-11 10:37:45.000000000 +0000
28055 +@@ -7,7 +7,7 @@
28056 + #include <asm/apicdef.h>
28057 + #include <asm/system.h>
28058 +
28059 +-#define Dprintk(x...)
28060 ++#define Dprintk(x...) do {} while (0)
28061 +
28062 + /*
28063 + * Debugging macros
28064 +diff -Nurp linux-2.6.23.15/include/asm-x86_64/elf.h linux-2.6.23.15-grsec/include/asm-x86_64/elf.h
28065 +--- linux-2.6.23.15/include/asm-x86_64/elf.h 2007-10-09 21:31:38.000000000 +0100
28066 ++++ linux-2.6.23.15-grsec/include/asm-x86_64/elf.h 2008-02-11 10:37:45.000000000 +0000
28067 +@@ -92,6 +92,13 @@ typedef struct user_i387_struct elf_fpre
28068 +
28069 + #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
28070 +
28071 ++#ifdef CONFIG_PAX_ASLR
28072 ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_IA32) ? 0x08048000UL : 0x400000UL)
28073 ++
28074 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_IA32) ? 16 : 32)
28075 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_IA32) ? 16 : 32)
28076 ++#endif
28077 ++
28078 + /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
28079 + now struct_user_regs, they are different). Assumes current is the process
28080 + getting dumped. */
28081 +@@ -172,7 +179,7 @@ extern int vdso_enabled;
28082 +
28083 + #define ARCH_DLINFO \
28084 + do if (vdso_enabled) { \
28085 +- NEW_AUX_ENT(AT_SYSINFO_EHDR,(unsigned long)current->mm->context.vdso);\
28086 ++ NEW_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso);\
28087 + } while (0)
28088 +
28089 + #endif
28090 +diff -Nurp linux-2.6.23.15/include/asm-x86_64/futex.h linux-2.6.23.15-grsec/include/asm-x86_64/futex.h
28091 +--- linux-2.6.23.15/include/asm-x86_64/futex.h 2007-10-09 21:31:38.000000000 +0100
28092 ++++ linux-2.6.23.15-grsec/include/asm-x86_64/futex.h 2008-02-11 10:37:45.000000000 +0000
28093 +@@ -42,7 +42,7 @@
28094 + : "r" (oparg), "i" (-EFAULT), "m" (*uaddr), "1" (0))
28095 +
28096 + static inline int
28097 +-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
28098 ++futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
28099 + {
28100 + int op = (encoded_op >> 28) & 7;
28101 + int cmp = (encoded_op >> 24) & 15;
28102 +@@ -95,7 +95,7 @@ futex_atomic_op_inuser (int encoded_op,
28103 + }
28104 +
28105 + static inline int
28106 +-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
28107 ++futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
28108 + {
28109 + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
28110 + return -EFAULT;
28111 +diff -Nurp linux-2.6.23.15/include/asm-x86_64/ia32.h linux-2.6.23.15-grsec/include/asm-x86_64/ia32.h
28112 +--- linux-2.6.23.15/include/asm-x86_64/ia32.h 2007-10-09 21:31:38.000000000 +0100
28113 ++++ linux-2.6.23.15-grsec/include/asm-x86_64/ia32.h 2008-02-11 10:37:45.000000000 +0000
28114 +@@ -156,7 +156,13 @@ struct ustat32 {
28115 + char f_fpack[6];
28116 + };
28117 +
28118 +-#define IA32_STACK_TOP IA32_PAGE_OFFSET
28119 ++#ifdef CONFIG_PAX_RANDUSTACK
28120 ++#define IA32_DELTA_STACK (current->mm->delta_stack)
28121 ++#else
28122 ++#define IA32_DELTA_STACK 0UL
28123 ++#endif
28124 ++
28125 ++#define IA32_STACK_TOP (IA32_PAGE_OFFSET - IA32_DELTA_STACK)
28126 +
28127 + #ifdef __KERNEL__
28128 + struct user_desc;
28129 +diff -Nurp linux-2.6.23.15/include/asm-x86_64/kmap_types.h linux-2.6.23.15-grsec/include/asm-x86_64/kmap_types.h
28130 +--- linux-2.6.23.15/include/asm-x86_64/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
28131 ++++ linux-2.6.23.15-grsec/include/asm-x86_64/kmap_types.h 2008-02-11 10:37:45.000000000 +0000
28132 +@@ -13,6 +13,7 @@ enum km_type {
28133 + KM_IRQ1,
28134 + KM_SOFTIRQ0,
28135 + KM_SOFTIRQ1,
28136 ++ KM_CLEARPAGE,
28137 + KM_TYPE_NR
28138 + };
28139 +
28140 +diff -Nurp linux-2.6.23.15/include/asm-x86_64/mmu.h linux-2.6.23.15-grsec/include/asm-x86_64/mmu.h
28141 +--- linux-2.6.23.15/include/asm-x86_64/mmu.h 2007-10-09 21:31:38.000000000 +0100
28142 ++++ linux-2.6.23.15-grsec/include/asm-x86_64/mmu.h 2008-02-11 10:37:45.000000000 +0000
28143 +@@ -15,7 +15,7 @@ typedef struct {
28144 + rwlock_t ldtlock;
28145 + int size;
28146 + struct semaphore sem;
28147 +- void *vdso;
28148 ++ unsigned long vdso;
28149 + } mm_context_t;
28150 +
28151 + #endif
28152 +diff -Nurp linux-2.6.23.15/include/asm-x86_64/page.h linux-2.6.23.15-grsec/include/asm-x86_64/page.h
28153 +--- linux-2.6.23.15/include/asm-x86_64/page.h 2007-10-09 21:31:38.000000000 +0100
28154 ++++ linux-2.6.23.15-grsec/include/asm-x86_64/page.h 2008-02-11 10:37:45.000000000 +0000
28155 +@@ -94,6 +94,8 @@ extern unsigned long phys_base;
28156 + #define __START_KERNEL_map _AC(0xffffffff80000000, UL)
28157 + #define __PAGE_OFFSET _AC(0xffff810000000000, UL)
28158 +
28159 ++#define __KERNEL_TEXT_OFFSET (0)
28160 ++
28161 + /* to align the pointer to the (next) page boundary */
28162 + #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
28163 +
28164 +diff -Nurp linux-2.6.23.15/include/asm-x86_64/pgalloc.h linux-2.6.23.15-grsec/include/asm-x86_64/pgalloc.h
28165 +--- linux-2.6.23.15/include/asm-x86_64/pgalloc.h 2007-10-09 21:31:38.000000000 +0100
28166 ++++ linux-2.6.23.15-grsec/include/asm-x86_64/pgalloc.h 2008-02-11 10:37:45.000000000 +0000
28167 +@@ -6,7 +6,7 @@
28168 + #include <linux/mm.h>
28169 +
28170 + #define pmd_populate_kernel(mm, pmd, pte) \
28171 +- set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
28172 ++ set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(pte)))
28173 + #define pud_populate(mm, pud, pmd) \
28174 + set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd)))
28175 + #define pgd_populate(mm, pgd, pud) \
28176 +diff -Nurp linux-2.6.23.15/include/asm-x86_64/pgtable.h linux-2.6.23.15-grsec/include/asm-x86_64/pgtable.h
28177 +--- linux-2.6.23.15/include/asm-x86_64/pgtable.h 2007-10-09 21:31:38.000000000 +0100
28178 ++++ linux-2.6.23.15-grsec/include/asm-x86_64/pgtable.h 2008-02-11 10:37:45.000000000 +0000
28179 +@@ -179,6 +179,10 @@ static inline pte_t ptep_get_and_clear_f
28180 + #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
28181 + #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
28182 + #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
28183 ++
28184 ++#define PAGE_READONLY_NOEXEC PAGE_READONLY
28185 ++#define PAGE_SHARED_NOEXEC PAGE_SHARED
28186 ++
28187 + #define __PAGE_KERNEL \
28188 + (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
28189 + #define __PAGE_KERNEL_EXEC \
28190 +diff -Nurp linux-2.6.23.15/include/asm-x86_64/processor.h linux-2.6.23.15-grsec/include/asm-x86_64/processor.h
28191 +--- linux-2.6.23.15/include/asm-x86_64/processor.h 2007-10-09 21:31:38.000000000 +0100
28192 ++++ linux-2.6.23.15-grsec/include/asm-x86_64/processor.h 2008-02-11 10:37:45.000000000 +0000
28193 +@@ -140,7 +140,7 @@ static inline void clear_in_cr4 (unsigne
28194 + /* This decides where the kernel will search for a free chunk of vm
28195 + * space during mmap's.
28196 + */
28197 +-#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000)
28198 ++#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFf000)
28199 +
28200 + #define TASK_SIZE (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE64)
28201 + #define TASK_SIZE_OF(child) ((test_tsk_thread_flag(child, TIF_IA32)) ? IA32_PAGE_OFFSET : TASK_SIZE64)
28202 +diff -Nurp linux-2.6.23.15/include/asm-x86_64/system.h linux-2.6.23.15-grsec/include/asm-x86_64/system.h
28203 +--- linux-2.6.23.15/include/asm-x86_64/system.h 2008-02-11 10:36:03.000000000 +0000
28204 ++++ linux-2.6.23.15-grsec/include/asm-x86_64/system.h 2008-02-11 10:37:45.000000000 +0000
28205 +@@ -174,7 +174,7 @@ static inline void write_cr8(unsigned lo
28206 +
28207 + void cpu_idle_wait(void);
28208 +
28209 +-extern unsigned long arch_align_stack(unsigned long sp);
28210 ++#define arch_align_stack(x) (x)
28211 + extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
28212 +
28213 + #endif
28214 +diff -Nurp linux-2.6.23.15/include/asm-xtensa/kmap_types.h linux-2.6.23.15-grsec/include/asm-xtensa/kmap_types.h
28215 +--- linux-2.6.23.15/include/asm-xtensa/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
28216 ++++ linux-2.6.23.15-grsec/include/asm-xtensa/kmap_types.h 2008-02-11 10:37:45.000000000 +0000
28217 +@@ -25,6 +25,7 @@ enum km_type {
28218 + KM_IRQ1,
28219 + KM_SOFTIRQ0,
28220 + KM_SOFTIRQ1,
28221 ++ KM_CLEARPAGE,
28222 + KM_TYPE_NR
28223 + };
28224 +
28225 +diff -Nurp linux-2.6.23.15/include/linux/a.out.h linux-2.6.23.15-grsec/include/linux/a.out.h
28226 +--- linux-2.6.23.15/include/linux/a.out.h 2007-10-09 21:31:38.000000000 +0100
28227 ++++ linux-2.6.23.15-grsec/include/linux/a.out.h 2008-02-11 10:37:45.000000000 +0000
28228 +@@ -7,6 +7,16 @@
28229 +
28230 + #include <asm/a.out.h>
28231 +
28232 ++#ifdef CONFIG_PAX_RANDUSTACK
28233 ++#define __DELTA_STACK (current->mm->delta_stack)
28234 ++#else
28235 ++#define __DELTA_STACK 0UL
28236 ++#endif
28237 ++
28238 ++#ifndef STACK_TOP
28239 ++#define STACK_TOP (__STACK_TOP - __DELTA_STACK)
28240 ++#endif
28241 ++
28242 + #endif /* __STRUCT_EXEC_OVERRIDE__ */
28243 +
28244 + /* these go in the N_MACHTYPE field */
28245 +@@ -37,6 +47,14 @@ enum machine_type {
28246 + M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
28247 + };
28248 +
28249 ++/* Constants for the N_FLAGS field */
28250 ++#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
28251 ++#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
28252 ++#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
28253 ++#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
28254 ++/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
28255 ++#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
28256 ++
28257 + #if !defined (N_MAGIC)
28258 + #define N_MAGIC(exec) ((exec).a_info & 0xffff)
28259 + #endif
28260 +diff -Nurp linux-2.6.23.15/include/linux/binfmts.h linux-2.6.23.15-grsec/include/linux/binfmts.h
28261 +--- linux-2.6.23.15/include/linux/binfmts.h 2007-10-09 21:31:38.000000000 +0100
28262 ++++ linux-2.6.23.15-grsec/include/linux/binfmts.h 2008-02-11 10:37:45.000000000 +0000
28263 +@@ -48,6 +48,7 @@ struct linux_binprm{
28264 + unsigned interp_data;
28265 + unsigned long loader, exec;
28266 + unsigned long argv_len;
28267 ++ int misc;
28268 + };
28269 +
28270 + #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
28271 +@@ -99,5 +100,8 @@ extern void compute_creds(struct linux_b
28272 + extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
28273 + extern int set_binfmt(struct linux_binfmt *new);
28274 +
28275 ++void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
28276 ++void pax_report_insns(void *pc, void *sp);
28277 ++
28278 + #endif /* __KERNEL__ */
28279 + #endif /* _LINUX_BINFMTS_H */
28280 +diff -Nurp linux-2.6.23.15/include/linux/cache.h linux-2.6.23.15-grsec/include/linux/cache.h
28281 +--- linux-2.6.23.15/include/linux/cache.h 2007-10-09 21:31:38.000000000 +0100
28282 ++++ linux-2.6.23.15-grsec/include/linux/cache.h 2008-02-11 10:37:45.000000000 +0000
28283 +@@ -16,6 +16,10 @@
28284 + #define __read_mostly
28285 + #endif
28286 +
28287 ++#ifndef __read_only
28288 ++#define __read_only
28289 ++#endif
28290 ++
28291 + #ifndef ____cacheline_aligned
28292 + #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
28293 + #endif
28294 +diff -Nurp linux-2.6.23.15/include/linux/capability.h linux-2.6.23.15-grsec/include/linux/capability.h
28295 +--- linux-2.6.23.15/include/linux/capability.h 2007-10-09 21:31:38.000000000 +0100
28296 ++++ linux-2.6.23.15-grsec/include/linux/capability.h 2008-02-11 10:37:45.000000000 +0000
28297 +@@ -359,6 +359,7 @@ static inline kernel_cap_t cap_invert(ke
28298 + #define cap_is_fs_cap(c) (CAP_TO_MASK(c) & CAP_FS_MASK)
28299 +
28300 + int capable(int cap);
28301 ++int capable_nolog(int cap);
28302 + int __capable(struct task_struct *t, int cap);
28303 +
28304 + #endif /* __KERNEL__ */
28305 +diff -Nurp linux-2.6.23.15/include/linux/elf.h linux-2.6.23.15-grsec/include/linux/elf.h
28306 +--- linux-2.6.23.15/include/linux/elf.h 2007-10-09 21:31:38.000000000 +0100
28307 ++++ linux-2.6.23.15-grsec/include/linux/elf.h 2008-02-11 10:37:45.000000000 +0000
28308 +@@ -8,6 +8,10 @@
28309 +
28310 + struct file;
28311 +
28312 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
28313 ++#undef elf_read_implies_exec
28314 ++#endif
28315 ++
28316 + #ifndef elf_read_implies_exec
28317 + /* Executables for which elf_read_implies_exec() returns TRUE will
28318 + have the READ_IMPLIES_EXEC personality flag set automatically.
28319 +@@ -49,6 +53,16 @@ typedef __s64 Elf64_Sxword;
28320 +
28321 + #define PT_GNU_STACK (PT_LOOS + 0x474e551)
28322 +
28323 ++#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
28324 ++
28325 ++/* Constants for the e_flags field */
28326 ++#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
28327 ++#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
28328 ++#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
28329 ++#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
28330 ++/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
28331 ++#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
28332 ++
28333 + /* These constants define the different elf file types */
28334 + #define ET_NONE 0
28335 + #define ET_REL 1
28336 +@@ -83,6 +97,8 @@ typedef __s64 Elf64_Sxword;
28337 + #define DT_DEBUG 21
28338 + #define DT_TEXTREL 22
28339 + #define DT_JMPREL 23
28340 ++#define DT_FLAGS 30
28341 ++ #define DF_TEXTREL 0x00000004
28342 + #define DT_ENCODING 32
28343 + #define OLD_DT_LOOS 0x60000000
28344 + #define DT_LOOS 0x6000000d
28345 +@@ -229,6 +245,19 @@ typedef struct elf64_hdr {
28346 + #define PF_W 0x2
28347 + #define PF_X 0x1
28348 +
28349 ++#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */
28350 ++#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */
28351 ++#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */
28352 ++#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */
28353 ++#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */
28354 ++#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */
28355 ++/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */
28356 ++/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */
28357 ++#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */
28358 ++#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */
28359 ++#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */
28360 ++#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */
28361 ++
28362 + typedef struct elf32_phdr{
28363 + Elf32_Word p_type;
28364 + Elf32_Off p_offset;
28365 +@@ -321,6 +350,8 @@ typedef struct elf64_shdr {
28366 + #define EI_OSABI 7
28367 + #define EI_PAD 8
28368 +
28369 ++#define EI_PAX 14
28370 ++
28371 + #define ELFMAG0 0x7f /* EI_MAG */
28372 + #define ELFMAG1 'E'
28373 + #define ELFMAG2 'L'
28374 +@@ -378,6 +409,7 @@ extern Elf32_Dyn _DYNAMIC [];
28375 + #define elf_phdr elf32_phdr
28376 + #define elf_note elf32_note
28377 + #define elf_addr_t Elf32_Off
28378 ++#define elf_dyn Elf32_Dyn
28379 +
28380 + #else
28381 +
28382 +@@ -386,6 +418,7 @@ extern Elf64_Dyn _DYNAMIC [];
28383 + #define elf_phdr elf64_phdr
28384 + #define elf_note elf64_note
28385 + #define elf_addr_t Elf64_Off
28386 ++#define elf_dyn Elf64_Dyn
28387 +
28388 + #endif
28389 +
28390 +diff -Nurp linux-2.6.23.15/include/linux/ext4_fs_extents.h linux-2.6.23.15-grsec/include/linux/ext4_fs_extents.h
28391 +--- linux-2.6.23.15/include/linux/ext4_fs_extents.h 2007-10-09 21:31:38.000000000 +0100
28392 ++++ linux-2.6.23.15-grsec/include/linux/ext4_fs_extents.h 2008-02-11 10:37:45.000000000 +0000
28393 +@@ -50,7 +50,7 @@
28394 + #ifdef EXT_DEBUG
28395 + #define ext_debug(a...) printk(a)
28396 + #else
28397 +-#define ext_debug(a...)
28398 ++#define ext_debug(a...) do {} while (0)
28399 + #endif
28400 +
28401 + /*
28402 +diff -Nurp linux-2.6.23.15/include/linux/gracl.h linux-2.6.23.15-grsec/include/linux/gracl.h
28403 +--- linux-2.6.23.15/include/linux/gracl.h 1970-01-01 01:00:00.000000000 +0100
28404 ++++ linux-2.6.23.15-grsec/include/linux/gracl.h 2008-02-11 10:37:45.000000000 +0000
28405 +@@ -0,0 +1,317 @@
28406 ++#ifndef GR_ACL_H
28407 ++#define GR_ACL_H
28408 ++
28409 ++#include <linux/grdefs.h>
28410 ++#include <linux/resource.h>
28411 ++#include <linux/dcache.h>
28412 ++#include <asm/resource.h>
28413 ++
28414 ++/* Major status information */
28415 ++
28416 ++#define GR_VERSION "grsecurity 2.1.11"
28417 ++#define GRSECURITY_VERSION 0x2111
28418 ++
28419 ++enum {
28420 ++
28421 ++ SHUTDOWN = 0,
28422 ++ ENABLE = 1,
28423 ++ SPROLE = 2,
28424 ++ RELOAD = 3,
28425 ++ SEGVMOD = 4,
28426 ++ STATUS = 5,
28427 ++ UNSPROLE = 6,
28428 ++ PASSSET = 7,
28429 ++ SPROLEPAM = 8
28430 ++};
28431 ++
28432 ++/* Password setup definitions
28433 ++ * kernel/grhash.c */
28434 ++enum {
28435 ++ GR_PW_LEN = 128,
28436 ++ GR_SALT_LEN = 16,
28437 ++ GR_SHA_LEN = 32,
28438 ++};
28439 ++
28440 ++enum {
28441 ++ GR_SPROLE_LEN = 64,
28442 ++};
28443 ++
28444 ++#define GR_NLIMITS (RLIMIT_LOCKS + 2)
28445 ++
28446 ++/* Begin Data Structures */
28447 ++
28448 ++struct sprole_pw {
28449 ++ unsigned char *rolename;
28450 ++ unsigned char salt[GR_SALT_LEN];
28451 ++ unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
28452 ++};
28453 ++
28454 ++struct name_entry {
28455 ++ __u32 key;
28456 ++ ino_t inode;
28457 ++ dev_t device;
28458 ++ char *name;
28459 ++ __u16 len;
28460 ++ __u8 deleted;
28461 ++ struct name_entry *prev;
28462 ++ struct name_entry *next;
28463 ++};
28464 ++
28465 ++struct inodev_entry {
28466 ++ struct name_entry *nentry;
28467 ++ struct inodev_entry *prev;
28468 ++ struct inodev_entry *next;
28469 ++};
28470 ++
28471 ++struct acl_role_db {
28472 ++ struct acl_role_label **r_hash;
28473 ++ __u32 r_size;
28474 ++};
28475 ++
28476 ++struct inodev_db {
28477 ++ struct inodev_entry **i_hash;
28478 ++ __u32 i_size;
28479 ++};
28480 ++
28481 ++struct name_db {
28482 ++ struct name_entry **n_hash;
28483 ++ __u32 n_size;
28484 ++};
28485 ++
28486 ++struct crash_uid {
28487 ++ uid_t uid;
28488 ++ unsigned long expires;
28489 ++};
28490 ++
28491 ++struct gr_hash_struct {
28492 ++ void **table;
28493 ++ void **nametable;
28494 ++ void *first;
28495 ++ __u32 table_size;
28496 ++ __u32 used_size;
28497 ++ int type;
28498 ++};
28499 ++
28500 ++/* Userspace Grsecurity ACL data structures */
28501 ++
28502 ++struct acl_subject_label {
28503 ++ char *filename;
28504 ++ ino_t inode;
28505 ++ dev_t device;
28506 ++ __u32 mode;
28507 ++ __u32 cap_mask;
28508 ++ __u32 cap_lower;
28509 ++
28510 ++ struct rlimit res[GR_NLIMITS];
28511 ++ __u16 resmask;
28512 ++
28513 ++ __u8 user_trans_type;
28514 ++ __u8 group_trans_type;
28515 ++ uid_t *user_transitions;
28516 ++ gid_t *group_transitions;
28517 ++ __u16 user_trans_num;
28518 ++ __u16 group_trans_num;
28519 ++
28520 ++ __u32 ip_proto[8];
28521 ++ __u32 ip_type;
28522 ++ struct acl_ip_label **ips;
28523 ++ __u32 ip_num;
28524 ++
28525 ++ __u32 crashes;
28526 ++ unsigned long expires;
28527 ++
28528 ++ struct acl_subject_label *parent_subject;
28529 ++ struct gr_hash_struct *hash;
28530 ++ struct acl_subject_label *prev;
28531 ++ struct acl_subject_label *next;
28532 ++
28533 ++ struct acl_object_label **obj_hash;
28534 ++ __u32 obj_hash_size;
28535 ++ __u16 pax_flags;
28536 ++};
28537 ++
28538 ++struct role_allowed_ip {
28539 ++ __u32 addr;
28540 ++ __u32 netmask;
28541 ++
28542 ++ struct role_allowed_ip *prev;
28543 ++ struct role_allowed_ip *next;
28544 ++};
28545 ++
28546 ++struct role_transition {
28547 ++ char *rolename;
28548 ++
28549 ++ struct role_transition *prev;
28550 ++ struct role_transition *next;
28551 ++};
28552 ++
28553 ++struct acl_role_label {
28554 ++ char *rolename;
28555 ++ uid_t uidgid;
28556 ++ __u16 roletype;
28557 ++
28558 ++ __u16 auth_attempts;
28559 ++ unsigned long expires;
28560 ++
28561 ++ struct acl_subject_label *root_label;
28562 ++ struct gr_hash_struct *hash;
28563 ++
28564 ++ struct acl_role_label *prev;
28565 ++ struct acl_role_label *next;
28566 ++
28567 ++ struct role_transition *transitions;
28568 ++ struct role_allowed_ip *allowed_ips;
28569 ++ uid_t *domain_children;
28570 ++ __u16 domain_child_num;
28571 ++
28572 ++ struct acl_subject_label **subj_hash;
28573 ++ __u32 subj_hash_size;
28574 ++};
28575 ++
28576 ++struct user_acl_role_db {
28577 ++ struct acl_role_label **r_table;
28578 ++ __u32 num_pointers; /* Number of allocations to track */
28579 ++ __u32 num_roles; /* Number of roles */
28580 ++ __u32 num_domain_children; /* Number of domain children */
28581 ++ __u32 num_subjects; /* Number of subjects */
28582 ++ __u32 num_objects; /* Number of objects */
28583 ++};
28584 ++
28585 ++struct acl_object_label {
28586 ++ char *filename;
28587 ++ ino_t inode;
28588 ++ dev_t device;
28589 ++ __u32 mode;
28590 ++
28591 ++ struct acl_subject_label *nested;
28592 ++ struct acl_object_label *globbed;
28593 ++
28594 ++ /* next two structures not used */
28595 ++
28596 ++ struct acl_object_label *prev;
28597 ++ struct acl_object_label *next;
28598 ++};
28599 ++
28600 ++struct acl_ip_label {
28601 ++ char *iface;
28602 ++ __u32 addr;
28603 ++ __u32 netmask;
28604 ++ __u16 low, high;
28605 ++ __u8 mode;
28606 ++ __u32 type;
28607 ++ __u32 proto[8];
28608 ++
28609 ++ /* next two structures not used */
28610 ++
28611 ++ struct acl_ip_label *prev;
28612 ++ struct acl_ip_label *next;
28613 ++};
28614 ++
28615 ++struct gr_arg {
28616 ++ struct user_acl_role_db role_db;
28617 ++ unsigned char pw[GR_PW_LEN];
28618 ++ unsigned char salt[GR_SALT_LEN];
28619 ++ unsigned char sum[GR_SHA_LEN];
28620 ++ unsigned char sp_role[GR_SPROLE_LEN];
28621 ++ struct sprole_pw *sprole_pws;
28622 ++ dev_t segv_device;
28623 ++ ino_t segv_inode;
28624 ++ uid_t segv_uid;
28625 ++ __u16 num_sprole_pws;
28626 ++ __u16 mode;
28627 ++};
28628 ++
28629 ++struct gr_arg_wrapper {
28630 ++ struct gr_arg *arg;
28631 ++ __u32 version;
28632 ++ __u32 size;
28633 ++};
28634 ++
28635 ++struct subject_map {
28636 ++ struct acl_subject_label *user;
28637 ++ struct acl_subject_label *kernel;
28638 ++ struct subject_map *prev;
28639 ++ struct subject_map *next;
28640 ++};
28641 ++
28642 ++struct acl_subj_map_db {
28643 ++ struct subject_map **s_hash;
28644 ++ __u32 s_size;
28645 ++};
28646 ++
28647 ++/* End Data Structures Section */
28648 ++
28649 ++/* Hash functions generated by empirical testing by Brad Spengler
28650 ++ Makes good use of the low bits of the inode. Generally 0-1 times
28651 ++ in loop for successful match. 0-3 for unsuccessful match.
28652 ++ Shift/add algorithm with modulus of table size and an XOR*/
28653 ++
28654 ++static __inline__ unsigned int
28655 ++rhash(const uid_t uid, const __u16 type, const unsigned int sz)
28656 ++{
28657 ++ return (((uid << type) + (uid ^ type)) % sz);
28658 ++}
28659 ++
28660 ++ static __inline__ unsigned int
28661 ++shash(const struct acl_subject_label *userp, const unsigned int sz)
28662 ++{
28663 ++ return ((const unsigned long)userp % sz);
28664 ++}
28665 ++
28666 ++static __inline__ unsigned int
28667 ++fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
28668 ++{
28669 ++ return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
28670 ++}
28671 ++
28672 ++static __inline__ unsigned int
28673 ++nhash(const char *name, const __u16 len, const unsigned int sz)
28674 ++{
28675 ++ return full_name_hash(name, len) % sz;
28676 ++}
28677 ++
28678 ++#define FOR_EACH_ROLE_START(role,iter) \
28679 ++ role = NULL; \
28680 ++ iter = 0; \
28681 ++ while (iter < acl_role_set.r_size) { \
28682 ++ if (role == NULL) \
28683 ++ role = acl_role_set.r_hash[iter]; \
28684 ++ if (role == NULL) { \
28685 ++ iter++; \
28686 ++ continue; \
28687 ++ }
28688 ++
28689 ++#define FOR_EACH_ROLE_END(role,iter) \
28690 ++ role = role->next; \
28691 ++ if (role == NULL) \
28692 ++ iter++; \
28693 ++ }
28694 ++
28695 ++#define FOR_EACH_SUBJECT_START(role,subj,iter) \
28696 ++ subj = NULL; \
28697 ++ iter = 0; \
28698 ++ while (iter < role->subj_hash_size) { \
28699 ++ if (subj == NULL) \
28700 ++ subj = role->subj_hash[iter]; \
28701 ++ if (subj == NULL) { \
28702 ++ iter++; \
28703 ++ continue; \
28704 ++ }
28705 ++
28706 ++#define FOR_EACH_SUBJECT_END(subj,iter) \
28707 ++ subj = subj->next; \
28708 ++ if (subj == NULL) \
28709 ++ iter++; \
28710 ++ }
28711 ++
28712 ++
28713 ++#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
28714 ++ subj = role->hash->first; \
28715 ++ while (subj != NULL) {
28716 ++
28717 ++#define FOR_EACH_NESTED_SUBJECT_END(subj) \
28718 ++ subj = subj->next; \
28719 ++ }
28720 ++
28721 ++#endif
28722 ++
28723 +diff -Nurp linux-2.6.23.15/include/linux/gralloc.h linux-2.6.23.15-grsec/include/linux/gralloc.h
28724 +--- linux-2.6.23.15/include/linux/gralloc.h 1970-01-01 01:00:00.000000000 +0100
28725 ++++ linux-2.6.23.15-grsec/include/linux/gralloc.h 2008-02-11 10:37:45.000000000 +0000
28726 +@@ -0,0 +1,8 @@
28727 ++#ifndef __GRALLOC_H
28728 ++#define __GRALLOC_H
28729 ++
28730 ++void acl_free_all(void);
28731 ++int acl_alloc_stack_init(unsigned long size);
28732 ++void *acl_alloc(unsigned long len);
28733 ++
28734 ++#endif
28735 +diff -Nurp linux-2.6.23.15/include/linux/grdefs.h linux-2.6.23.15-grsec/include/linux/grdefs.h
28736 +--- linux-2.6.23.15/include/linux/grdefs.h 1970-01-01 01:00:00.000000000 +0100
28737 ++++ linux-2.6.23.15-grsec/include/linux/grdefs.h 2008-02-11 10:37:45.000000000 +0000
28738 +@@ -0,0 +1,131 @@
28739 ++#ifndef GRDEFS_H
28740 ++#define GRDEFS_H
28741 ++
28742 ++/* Begin grsecurity status declarations */
28743 ++
28744 ++enum {
28745 ++ GR_READY = 0x01,
28746 ++ GR_STATUS_INIT = 0x00 // disabled state
28747 ++};
28748 ++
28749 ++/* Begin ACL declarations */
28750 ++
28751 ++/* Role flags */
28752 ++
28753 ++enum {
28754 ++ GR_ROLE_USER = 0x0001,
28755 ++ GR_ROLE_GROUP = 0x0002,
28756 ++ GR_ROLE_DEFAULT = 0x0004,
28757 ++ GR_ROLE_SPECIAL = 0x0008,
28758 ++ GR_ROLE_AUTH = 0x0010,
28759 ++ GR_ROLE_NOPW = 0x0020,
28760 ++ GR_ROLE_GOD = 0x0040,
28761 ++ GR_ROLE_LEARN = 0x0080,
28762 ++ GR_ROLE_TPE = 0x0100,
28763 ++ GR_ROLE_DOMAIN = 0x0200,
28764 ++ GR_ROLE_PAM = 0x0400
28765 ++};
28766 ++
28767 ++/* ACL Subject and Object mode flags */
28768 ++enum {
28769 ++ GR_DELETED = 0x80000000
28770 ++};
28771 ++
28772 ++/* ACL Object-only mode flags */
28773 ++enum {
28774 ++ GR_READ = 0x00000001,
28775 ++ GR_APPEND = 0x00000002,
28776 ++ GR_WRITE = 0x00000004,
28777 ++ GR_EXEC = 0x00000008,
28778 ++ GR_FIND = 0x00000010,
28779 ++ GR_INHERIT = 0x00000020,
28780 ++ GR_SETID = 0x00000040,
28781 ++ GR_CREATE = 0x00000080,
28782 ++ GR_DELETE = 0x00000100,
28783 ++ GR_LINK = 0x00000200,
28784 ++ GR_AUDIT_READ = 0x00000400,
28785 ++ GR_AUDIT_APPEND = 0x00000800,
28786 ++ GR_AUDIT_WRITE = 0x00001000,
28787 ++ GR_AUDIT_EXEC = 0x00002000,
28788 ++ GR_AUDIT_FIND = 0x00004000,
28789 ++ GR_AUDIT_INHERIT= 0x00008000,
28790 ++ GR_AUDIT_SETID = 0x00010000,
28791 ++ GR_AUDIT_CREATE = 0x00020000,
28792 ++ GR_AUDIT_DELETE = 0x00040000,
28793 ++ GR_AUDIT_LINK = 0x00080000,
28794 ++ GR_PTRACERD = 0x00100000,
28795 ++ GR_NOPTRACE = 0x00200000,
28796 ++ GR_SUPPRESS = 0x00400000,
28797 ++ GR_NOLEARN = 0x00800000
28798 ++};
28799 ++
28800 ++#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
28801 ++ GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
28802 ++ GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
28803 ++
28804 ++/* ACL subject-only mode flags */
28805 ++enum {
28806 ++ GR_KILL = 0x00000001,
28807 ++ GR_VIEW = 0x00000002,
28808 ++ GR_PROTECTED = 0x00000004,
28809 ++ GR_LEARN = 0x00000008,
28810 ++ GR_OVERRIDE = 0x00000010,
28811 ++ /* just a placeholder, this mode is only used in userspace */
28812 ++ GR_DUMMY = 0x00000020,
28813 ++ GR_PROTSHM = 0x00000040,
28814 ++ GR_KILLPROC = 0x00000080,
28815 ++ GR_KILLIPPROC = 0x00000100,
28816 ++ /* just a placeholder, this mode is only used in userspace */
28817 ++ GR_NOTROJAN = 0x00000200,
28818 ++ GR_PROTPROCFD = 0x00000400,
28819 ++ GR_PROCACCT = 0x00000800,
28820 ++ GR_RELAXPTRACE = 0x00001000,
28821 ++ GR_NESTED = 0x00002000,
28822 ++ GR_INHERITLEARN = 0x00004000,
28823 ++ GR_PROCFIND = 0x00008000,
28824 ++ GR_POVERRIDE = 0x00010000,
28825 ++ GR_KERNELAUTH = 0x00020000,
28826 ++};
28827 ++
28828 ++enum {
28829 ++ GR_PAX_ENABLE_SEGMEXEC = 0x0001,
28830 ++ GR_PAX_ENABLE_PAGEEXEC = 0x0002,
28831 ++ GR_PAX_ENABLE_MPROTECT = 0x0004,
28832 ++ GR_PAX_ENABLE_RANDMMAP = 0x0008,
28833 ++ GR_PAX_ENABLE_EMUTRAMP = 0x0010,
28834 ++ GR_PAX_DISABLE_SEGMEXEC = 0x0100,
28835 ++ GR_PAX_DISABLE_PAGEEXEC = 0x0200,
28836 ++ GR_PAX_DISABLE_MPROTECT = 0x0400,
28837 ++ GR_PAX_DISABLE_RANDMMAP = 0x0800,
28838 ++ GR_PAX_DISABLE_EMUTRAMP = 0x1000,
28839 ++};
28840 ++
28841 ++enum {
28842 ++ GR_ID_USER = 0x01,
28843 ++ GR_ID_GROUP = 0x02,
28844 ++};
28845 ++
28846 ++enum {
28847 ++ GR_ID_ALLOW = 0x01,
28848 ++ GR_ID_DENY = 0x02,
28849 ++};
28850 ++
28851 ++#define GR_CRASH_RES 11
28852 ++#define GR_UIDTABLE_MAX 500
28853 ++
28854 ++/* begin resource learning section */
28855 ++enum {
28856 ++ GR_RLIM_CPU_BUMP = 60,
28857 ++ GR_RLIM_FSIZE_BUMP = 50000,
28858 ++ GR_RLIM_DATA_BUMP = 10000,
28859 ++ GR_RLIM_STACK_BUMP = 1000,
28860 ++ GR_RLIM_CORE_BUMP = 10000,
28861 ++ GR_RLIM_RSS_BUMP = 500000,
28862 ++ GR_RLIM_NPROC_BUMP = 1,
28863 ++ GR_RLIM_NOFILE_BUMP = 5,
28864 ++ GR_RLIM_MEMLOCK_BUMP = 50000,
28865 ++ GR_RLIM_AS_BUMP = 500000,
28866 ++ GR_RLIM_LOCKS_BUMP = 2
28867 ++};
28868 ++
28869 ++#endif
28870 +diff -Nurp linux-2.6.23.15/include/linux/grinternal.h linux-2.6.23.15-grsec/include/linux/grinternal.h
28871 +--- linux-2.6.23.15/include/linux/grinternal.h 1970-01-01 01:00:00.000000000 +0100
28872 ++++ linux-2.6.23.15-grsec/include/linux/grinternal.h 2008-02-11 10:37:45.000000000 +0000
28873 +@@ -0,0 +1,210 @@
28874 ++#ifndef __GRINTERNAL_H
28875 ++#define __GRINTERNAL_H
28876 ++
28877 ++#ifdef CONFIG_GRKERNSEC
28878 ++
28879 ++#include <linux/fs.h>
28880 ++#include <linux/gracl.h>
28881 ++#include <linux/grdefs.h>
28882 ++#include <linux/grmsg.h>
28883 ++
28884 ++void gr_add_learn_entry(const char *fmt, ...);
28885 ++__u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
28886 ++ const struct vfsmount *mnt);
28887 ++__u32 gr_check_create(const struct dentry *new_dentry,
28888 ++ const struct dentry *parent,
28889 ++ const struct vfsmount *mnt, const __u32 mode);
28890 ++int gr_check_protected_task(const struct task_struct *task);
28891 ++__u32 to_gr_audit(const __u32 reqmode);
28892 ++int gr_set_acls(const int type);
28893 ++
28894 ++int gr_acl_is_enabled(void);
28895 ++char gr_roletype_to_char(void);
28896 ++
28897 ++void gr_handle_alertkill(struct task_struct *task);
28898 ++char *gr_to_filename(const struct dentry *dentry,
28899 ++ const struct vfsmount *mnt);
28900 ++char *gr_to_filename1(const struct dentry *dentry,
28901 ++ const struct vfsmount *mnt);
28902 ++char *gr_to_filename2(const struct dentry *dentry,
28903 ++ const struct vfsmount *mnt);
28904 ++char *gr_to_filename3(const struct dentry *dentry,
28905 ++ const struct vfsmount *mnt);
28906 ++
28907 ++extern int grsec_enable_link;
28908 ++extern int grsec_enable_fifo;
28909 ++extern int grsec_enable_execve;
28910 ++extern int grsec_enable_shm;
28911 ++extern int grsec_enable_execlog;
28912 ++extern int grsec_enable_signal;
28913 ++extern int grsec_enable_forkfail;
28914 ++extern int grsec_enable_time;
28915 ++extern int grsec_enable_chroot_shmat;
28916 ++extern int grsec_enable_chroot_findtask;
28917 ++extern int grsec_enable_chroot_mount;
28918 ++extern int grsec_enable_chroot_double;
28919 ++extern int grsec_enable_chroot_pivot;
28920 ++extern int grsec_enable_chroot_chdir;
28921 ++extern int grsec_enable_chroot_chmod;
28922 ++extern int grsec_enable_chroot_mknod;
28923 ++extern int grsec_enable_chroot_fchdir;
28924 ++extern int grsec_enable_chroot_nice;
28925 ++extern int grsec_enable_chroot_execlog;
28926 ++extern int grsec_enable_chroot_caps;
28927 ++extern int grsec_enable_chroot_sysctl;
28928 ++extern int grsec_enable_chroot_unix;
28929 ++extern int grsec_enable_tpe;
28930 ++extern int grsec_tpe_gid;
28931 ++extern int grsec_enable_tpe_all;
28932 ++extern int grsec_enable_sidcaps;
28933 ++extern int grsec_enable_socket_all;
28934 ++extern int grsec_socket_all_gid;
28935 ++extern int grsec_enable_socket_client;
28936 ++extern int grsec_socket_client_gid;
28937 ++extern int grsec_enable_socket_server;
28938 ++extern int grsec_socket_server_gid;
28939 ++extern int grsec_audit_gid;
28940 ++extern int grsec_enable_group;
28941 ++extern int grsec_enable_audit_ipc;
28942 ++extern int grsec_enable_audit_textrel;
28943 ++extern int grsec_enable_mount;
28944 ++extern int grsec_enable_chdir;
28945 ++extern int grsec_resource_logging;
28946 ++extern int grsec_lock;
28947 ++
28948 ++extern spinlock_t grsec_alert_lock;
28949 ++extern unsigned long grsec_alert_wtime;
28950 ++extern unsigned long grsec_alert_fyet;
28951 ++
28952 ++extern spinlock_t grsec_audit_lock;
28953 ++
28954 ++extern rwlock_t grsec_exec_file_lock;
28955 ++
28956 ++#define gr_task_fullpath(tsk) (tsk->exec_file ? \
28957 ++ gr_to_filename2(tsk->exec_file->f_dentry, \
28958 ++ tsk->exec_file->f_vfsmnt) : "/")
28959 ++
28960 ++#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
28961 ++ gr_to_filename3(tsk->parent->exec_file->f_dentry, \
28962 ++ tsk->parent->exec_file->f_vfsmnt) : "/")
28963 ++
28964 ++#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
28965 ++ gr_to_filename(tsk->exec_file->f_dentry, \
28966 ++ tsk->exec_file->f_vfsmnt) : "/")
28967 ++
28968 ++#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
28969 ++ gr_to_filename1(tsk->parent->exec_file->f_dentry, \
28970 ++ tsk->parent->exec_file->f_vfsmnt) : "/")
28971 ++
28972 ++#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
28973 ++ ((tsk_a->fs->root->d_inode->i_sb->s_dev != \
28974 ++ child_reaper(tsk_a)->fs->root->d_inode->i_sb->s_dev) || \
28975 ++ (tsk_a->fs->root->d_inode->i_ino != \
28976 ++ child_reaper(tsk_a)->fs->root->d_inode->i_ino)))
28977 ++
28978 ++#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
28979 ++ (tsk_a->fs->root->d_inode->i_sb->s_dev == \
28980 ++ tsk_b->fs->root->d_inode->i_sb->s_dev) && \
28981 ++ (tsk_a->fs->root->d_inode->i_ino == \
28982 ++ tsk_b->fs->root->d_inode->i_ino))
28983 ++
28984 ++#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
28985 ++ task->pid, task->uid, \
28986 ++ task->euid, task->gid, task->egid, \
28987 ++ gr_parent_task_fullpath(task), \
28988 ++ task->parent->comm, task->parent->pid, \
28989 ++ task->parent->uid, task->parent->euid, \
28990 ++ task->parent->gid, task->parent->egid
28991 ++
28992 ++#define GR_CHROOT_CAPS ( \
28993 ++ CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
28994 ++ CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
28995 ++ CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
28996 ++ CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
28997 ++ CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
28998 ++ CAP_TO_MASK(CAP_IPC_OWNER))
28999 ++
29000 ++#define security_learn(normal_msg,args...) \
29001 ++({ \
29002 ++ read_lock(&grsec_exec_file_lock); \
29003 ++ gr_add_learn_entry(normal_msg "\n", ## args); \
29004 ++ read_unlock(&grsec_exec_file_lock); \
29005 ++})
29006 ++
29007 ++enum {
29008 ++ GR_DO_AUDIT,
29009 ++ GR_DONT_AUDIT,
29010 ++ GR_DONT_AUDIT_GOOD
29011 ++};
29012 ++
29013 ++enum {
29014 ++ GR_TTYSNIFF,
29015 ++ GR_RBAC,
29016 ++ GR_RBAC_STR,
29017 ++ GR_STR_RBAC,
29018 ++ GR_RBAC_MODE2,
29019 ++ GR_RBAC_MODE3,
29020 ++ GR_FILENAME,
29021 ++ GR_SYSCTL_HIDDEN,
29022 ++ GR_NOARGS,
29023 ++ GR_ONE_INT,
29024 ++ GR_ONE_INT_TWO_STR,
29025 ++ GR_ONE_STR,
29026 ++ GR_STR_INT,
29027 ++ GR_TWO_INT,
29028 ++ GR_THREE_INT,
29029 ++ GR_FIVE_INT_TWO_STR,
29030 ++ GR_TWO_STR,
29031 ++ GR_THREE_STR,
29032 ++ GR_FOUR_STR,
29033 ++ GR_STR_FILENAME,
29034 ++ GR_FILENAME_STR,
29035 ++ GR_FILENAME_TWO_INT,
29036 ++ GR_FILENAME_TWO_INT_STR,
29037 ++ GR_TEXTREL,
29038 ++ GR_PTRACE,
29039 ++ GR_RESOURCE,
29040 ++ GR_CAP,
29041 ++ GR_SIG,
29042 ++ GR_CRASH1,
29043 ++ GR_CRASH2,
29044 ++ GR_PSACCT
29045 ++};
29046 ++
29047 ++#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str)
29048 ++#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
29049 ++#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
29050 ++#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
29051 ++#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
29052 ++#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
29053 ++#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)
29054 ++#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
29055 ++#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
29056 ++#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
29057 ++#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
29058 ++#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
29059 ++#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
29060 ++#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
29061 ++#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
29062 ++#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)
29063 ++#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
29064 ++#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
29065 ++#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
29066 ++#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
29067 ++#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
29068 ++#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
29069 ++#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)
29070 ++#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
29071 ++#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
29072 ++#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
29073 ++#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
29074 ++#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
29075 ++#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
29076 ++#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
29077 ++#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)
29078 ++
29079 ++void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
29080 ++
29081 ++#endif
29082 ++
29083 ++#endif
29084 +diff -Nurp linux-2.6.23.15/include/linux/grmsg.h linux-2.6.23.15-grsec/include/linux/grmsg.h
29085 +--- linux-2.6.23.15/include/linux/grmsg.h 1970-01-01 01:00:00.000000000 +0100
29086 ++++ linux-2.6.23.15-grsec/include/linux/grmsg.h 2008-02-11 10:37:45.000000000 +0000
29087 +@@ -0,0 +1,108 @@
29088 ++#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"
29089 ++#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"
29090 ++#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
29091 ++#define GR_STOPMOD_MSG "denied modification of module state by "
29092 ++#define GR_IOPERM_MSG "denied use of ioperm() by "
29093 ++#define GR_IOPL_MSG "denied use of iopl() by "
29094 ++#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
29095 ++#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
29096 ++#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
29097 ++#define GR_KMEM_MSG "denied write of /dev/kmem by "
29098 ++#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
29099 ++#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
29100 ++#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
29101 ++#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
29102 ++#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"
29103 ++#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"
29104 ++#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
29105 ++#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
29106 ++#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
29107 ++#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
29108 ++#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
29109 ++#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
29110 ++#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
29111 ++#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
29112 ++#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
29113 ++#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
29114 ++#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
29115 ++#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
29116 ++#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
29117 ++#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
29118 ++#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
29119 ++#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
29120 ++#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
29121 ++#define GR_NPROC_MSG "denied overstep of process limit by "
29122 ++#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
29123 ++#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
29124 ++#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
29125 ++#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
29126 ++#define GR_MOUNT_CHROOT_MSG "denied mount of %.30s as %.930s from chroot by "
29127 ++#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
29128 ++#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
29129 ++#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
29130 ++#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
29131 ++#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
29132 ++#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
29133 ++#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
29134 ++#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
29135 ++#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
29136 ++#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
29137 ++#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
29138 ++#define GR_INITF_ACL_MSG "init_variables() failed %s by "
29139 ++#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"
29140 ++#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
29141 ++#define GR_SHUTS_ACL_MSG "shutdown auth success for "
29142 ++#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
29143 ++#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
29144 ++#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
29145 ++#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
29146 ++#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
29147 ++#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
29148 ++#define GR_ENABLEF_ACL_MSG "unable to load %s for "
29149 ++#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
29150 ++#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
29151 ++#define GR_RELOADF_ACL_MSG "failed reload of %s for "
29152 ++#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
29153 ++#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
29154 ++#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
29155 ++#define GR_SPROLEF_ACL_MSG "special role %s failure for "
29156 ++#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
29157 ++#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
29158 ++#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
29159 ++#define GR_INVMODE_ACL_MSG "invalid mode %d by "
29160 ++#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
29161 ++#define GR_FAILFORK_MSG "failed fork with errno %d by "
29162 ++#define GR_NICE_CHROOT_MSG "denied priority change by "
29163 ++#define GR_UNISIGLOG_MSG "signal %d sent to "
29164 ++#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
29165 ++#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
29166 ++#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
29167 ++#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
29168 ++#define GR_TIME_MSG "time set by "
29169 ++#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
29170 ++#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
29171 ++#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
29172 ++#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
29173 ++#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
29174 ++#define GR_BIND_MSG "denied bind() by "
29175 ++#define GR_CONNECT_MSG "denied connect() by "
29176 ++#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
29177 ++#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
29178 ++#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"
29179 ++#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
29180 ++#define GR_CAP_ACL_MSG "use of %s denied for "
29181 ++#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
29182 ++#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
29183 ++#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by "
29184 ++#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by "
29185 ++#define GR_MOUNT_AUDIT_MSG "mount of %.30s to %.64s by "
29186 ++#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
29187 ++#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
29188 ++#define GR_MSGQ_AUDIT_MSG "message queue created by "
29189 ++#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
29190 ++#define GR_SEM_AUDIT_MSG "semaphore created by "
29191 ++#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
29192 ++#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
29193 ++#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
29194 ++#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
29195 ++#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
29196 +diff -Nurp linux-2.6.23.15/include/linux/grsecurity.h linux-2.6.23.15-grsec/include/linux/grsecurity.h
29197 +--- linux-2.6.23.15/include/linux/grsecurity.h 1970-01-01 01:00:00.000000000 +0100
29198 ++++ linux-2.6.23.15-grsec/include/linux/grsecurity.h 2008-02-11 10:37:45.000000000 +0000
29199 +@@ -0,0 +1,193 @@
29200 ++#ifndef GR_SECURITY_H
29201 ++#define GR_SECURITY_H
29202 ++#include <linux/fs.h>
29203 ++#include <linux/binfmts.h>
29204 ++#include <linux/gracl.h>
29205 ++
29206 ++void gr_handle_brute_attach(struct task_struct *p);
29207 ++void gr_handle_brute_check(void);
29208 ++
29209 ++char gr_roletype_to_char(void);
29210 ++
29211 ++int gr_check_user_change(int real, int effective, int fs);
29212 ++int gr_check_group_change(int real, int effective, int fs);
29213 ++
29214 ++void gr_del_task_from_ip_table(struct task_struct *p);
29215 ++
29216 ++int gr_pid_is_chrooted(struct task_struct *p);
29217 ++int gr_handle_chroot_nice(void);
29218 ++int gr_handle_chroot_sysctl(const int op);
29219 ++int gr_handle_chroot_setpriority(struct task_struct *p,
29220 ++ const int niceval);
29221 ++int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
29222 ++int gr_handle_chroot_chroot(const struct dentry *dentry,
29223 ++ const struct vfsmount *mnt);
29224 ++void gr_handle_chroot_caps(struct task_struct *task);
29225 ++void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt);
29226 ++int gr_handle_chroot_chmod(const struct dentry *dentry,
29227 ++ const struct vfsmount *mnt, const int mode);
29228 ++int gr_handle_chroot_mknod(const struct dentry *dentry,
29229 ++ const struct vfsmount *mnt, const int mode);
29230 ++int gr_handle_chroot_mount(const struct dentry *dentry,
29231 ++ const struct vfsmount *mnt,
29232 ++ const char *dev_name);
29233 ++int gr_handle_chroot_pivot(void);
29234 ++int gr_handle_chroot_unix(const pid_t pid);
29235 ++
29236 ++int gr_handle_rawio(const struct inode *inode);
29237 ++int gr_handle_nproc(void);
29238 ++
29239 ++void gr_handle_ioperm(void);
29240 ++void gr_handle_iopl(void);
29241 ++
29242 ++int gr_tpe_allow(const struct file *file);
29243 ++
29244 ++int gr_random_pid(void);
29245 ++
29246 ++void gr_log_forkfail(const int retval);
29247 ++void gr_log_timechange(void);
29248 ++void gr_log_signal(const int sig, const struct task_struct *t);
29249 ++void gr_log_chdir(const struct dentry *dentry,
29250 ++ const struct vfsmount *mnt);
29251 ++void gr_log_chroot_exec(const struct dentry *dentry,
29252 ++ const struct vfsmount *mnt);
29253 ++void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
29254 ++void gr_log_remount(const char *devname, const int retval);
29255 ++void gr_log_unmount(const char *devname, const int retval);
29256 ++void gr_log_mount(const char *from, const char *to, const int retval);
29257 ++void gr_log_msgget(const int ret, const int msgflg);
29258 ++void gr_log_msgrm(const uid_t uid, const uid_t cuid);
29259 ++void gr_log_semget(const int err, const int semflg);
29260 ++void gr_log_semrm(const uid_t uid, const uid_t cuid);
29261 ++void gr_log_shmget(const int err, const int shmflg, const size_t size);
29262 ++void gr_log_shmrm(const uid_t uid, const uid_t cuid);
29263 ++void gr_log_textrel(struct vm_area_struct *vma);
29264 ++
29265 ++int gr_handle_follow_link(const struct inode *parent,
29266 ++ const struct inode *inode,
29267 ++ const struct dentry *dentry,
29268 ++ const struct vfsmount *mnt);
29269 ++int gr_handle_fifo(const struct dentry *dentry,
29270 ++ const struct vfsmount *mnt,
29271 ++ const struct dentry *dir, const int flag,
29272 ++ const int acc_mode);
29273 ++int gr_handle_hardlink(const struct dentry *dentry,
29274 ++ const struct vfsmount *mnt,
29275 ++ struct inode *inode,
29276 ++ const int mode, const char *to);
29277 ++
29278 ++int gr_task_is_capable(struct task_struct *task, const int cap);
29279 ++int gr_is_capable_nolog(const int cap);
29280 ++void gr_learn_resource(const struct task_struct *task, const int limit,
29281 ++ const unsigned long wanted, const int gt);
29282 ++void gr_copy_label(struct task_struct *tsk);
29283 ++void gr_handle_crash(struct task_struct *task, const int sig);
29284 ++int gr_handle_signal(const struct task_struct *p, const int sig);
29285 ++int gr_check_crash_uid(const uid_t uid);
29286 ++int gr_check_protected_task(const struct task_struct *task);
29287 ++int gr_acl_handle_mmap(const struct file *file,
29288 ++ const unsigned long prot);
29289 ++int gr_acl_handle_mprotect(const struct file *file,
29290 ++ const unsigned long prot);
29291 ++int gr_check_hidden_task(const struct task_struct *tsk);
29292 ++__u32 gr_acl_handle_truncate(const struct dentry *dentry,
29293 ++ const struct vfsmount *mnt);
29294 ++__u32 gr_acl_handle_utime(const struct dentry *dentry,
29295 ++ const struct vfsmount *mnt);
29296 ++__u32 gr_acl_handle_access(const struct dentry *dentry,
29297 ++ const struct vfsmount *mnt, const int fmode);
29298 ++__u32 gr_acl_handle_fchmod(const struct dentry *dentry,
29299 ++ const struct vfsmount *mnt, mode_t mode);
29300 ++__u32 gr_acl_handle_chmod(const struct dentry *dentry,
29301 ++ const struct vfsmount *mnt, mode_t mode);
29302 ++__u32 gr_acl_handle_chown(const struct dentry *dentry,
29303 ++ const struct vfsmount *mnt);
29304 ++int gr_handle_ptrace(struct task_struct *task, const long request);
29305 ++int gr_handle_proc_ptrace(struct task_struct *task);
29306 ++__u32 gr_acl_handle_execve(const struct dentry *dentry,
29307 ++ const struct vfsmount *mnt);
29308 ++int gr_check_crash_exec(const struct file *filp);
29309 ++int gr_acl_is_enabled(void);
29310 ++void gr_set_kernel_label(struct task_struct *task);
29311 ++void gr_set_role_label(struct task_struct *task, const uid_t uid,
29312 ++ const gid_t gid);
29313 ++int gr_set_proc_label(const struct dentry *dentry,
29314 ++ const struct vfsmount *mnt);
29315 ++__u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
29316 ++ const struct vfsmount *mnt);
29317 ++__u32 gr_acl_handle_open(const struct dentry *dentry,
29318 ++ const struct vfsmount *mnt, const int fmode);
29319 ++__u32 gr_acl_handle_creat(const struct dentry *dentry,
29320 ++ const struct dentry *p_dentry,
29321 ++ const struct vfsmount *p_mnt, const int fmode,
29322 ++ const int imode);
29323 ++void gr_handle_create(const struct dentry *dentry,
29324 ++ const struct vfsmount *mnt);
29325 ++__u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
29326 ++ const struct dentry *parent_dentry,
29327 ++ const struct vfsmount *parent_mnt,
29328 ++ const int mode);
29329 ++__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
29330 ++ const struct dentry *parent_dentry,
29331 ++ const struct vfsmount *parent_mnt);
29332 ++__u32 gr_acl_handle_rmdir(const struct dentry *dentry,
29333 ++ const struct vfsmount *mnt);
29334 ++void gr_handle_delete(const ino_t ino, const dev_t dev);
29335 ++__u32 gr_acl_handle_unlink(const struct dentry *dentry,
29336 ++ const struct vfsmount *mnt);
29337 ++__u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
29338 ++ const struct dentry *parent_dentry,
29339 ++ const struct vfsmount *parent_mnt,
29340 ++ const char *from);
29341 ++__u32 gr_acl_handle_link(const struct dentry *new_dentry,
29342 ++ const struct dentry *parent_dentry,
29343 ++ const struct vfsmount *parent_mnt,
29344 ++ const struct dentry *old_dentry,
29345 ++ const struct vfsmount *old_mnt, const char *to);
29346 ++int gr_acl_handle_rename(struct dentry *new_dentry,
29347 ++ struct dentry *parent_dentry,
29348 ++ const struct vfsmount *parent_mnt,
29349 ++ struct dentry *old_dentry,
29350 ++ struct inode *old_parent_inode,
29351 ++ struct vfsmount *old_mnt, const char *newname);
29352 ++void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
29353 ++ struct dentry *old_dentry,
29354 ++ struct dentry *new_dentry,
29355 ++ struct vfsmount *mnt, const __u8 replace);
29356 ++__u32 gr_check_link(const struct dentry *new_dentry,
29357 ++ const struct dentry *parent_dentry,
29358 ++ const struct vfsmount *parent_mnt,
29359 ++ const struct dentry *old_dentry,
29360 ++ const struct vfsmount *old_mnt);
29361 ++int gr_acl_handle_filldir(const struct file *file, const char *name,
29362 ++ const unsigned int namelen, const ino_t ino);
29363 ++
29364 ++__u32 gr_acl_handle_unix(const struct dentry *dentry,
29365 ++ const struct vfsmount *mnt);
29366 ++void gr_acl_handle_exit(void);
29367 ++void gr_acl_handle_psacct(struct task_struct *task, const long code);
29368 ++int gr_acl_handle_procpidmem(const struct task_struct *task);
29369 ++__u32 gr_cap_rtnetlink(void);
29370 ++
29371 ++#ifdef CONFIG_SYSVIPC
29372 ++void gr_shm_exit(struct task_struct *task);
29373 ++#else
29374 ++static inline void gr_shm_exit(struct task_struct *task)
29375 ++{
29376 ++ return;
29377 ++}
29378 ++#endif
29379 ++
29380 ++#ifdef CONFIG_GRKERNSEC
29381 ++void gr_handle_mem_write(void);
29382 ++void gr_handle_kmem_write(void);
29383 ++void gr_handle_open_port(void);
29384 ++int gr_handle_mem_mmap(const unsigned long offset,
29385 ++ struct vm_area_struct *vma);
29386 ++
29387 ++extern int grsec_enable_dmesg;
29388 ++extern int grsec_enable_randsrc;
29389 ++extern int grsec_enable_shm;
29390 ++#endif
29391 ++
29392 ++#endif
29393 +diff -Nurp linux-2.6.23.15/include/linux/highmem.h linux-2.6.23.15-grsec/include/linux/highmem.h
29394 +--- linux-2.6.23.15/include/linux/highmem.h 2007-10-09 21:31:38.000000000 +0100
29395 ++++ linux-2.6.23.15-grsec/include/linux/highmem.h 2008-02-11 10:37:45.000000000 +0000
29396 +@@ -124,6 +124,13 @@ static inline void clear_highpage(struct
29397 + kunmap_atomic(kaddr, KM_USER0);
29398 + }
29399 +
29400 ++static inline void sanitize_highpage(struct page *page)
29401 ++{
29402 ++ void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
29403 ++ clear_page(kaddr);
29404 ++ kunmap_atomic(kaddr, KM_CLEARPAGE);
29405 ++}
29406 ++
29407 + /*
29408 + * Same but also flushes aliased cache contents to RAM.
29409 + *
29410 +@@ -132,14 +139,14 @@ static inline void clear_highpage(struct
29411 + */
29412 + #define zero_user_page(page, offset, size, km_type) \
29413 + do { \
29414 +- void *kaddr; \
29415 ++ void *__kaddr; \
29416 + \
29417 + BUG_ON((offset) + (size) > PAGE_SIZE); \
29418 + \
29419 +- kaddr = kmap_atomic(page, km_type); \
29420 +- memset((char *)kaddr + (offset), 0, (size)); \
29421 ++ __kaddr = kmap_atomic(page, km_type); \
29422 ++ memset((char *)__kaddr + (offset), 0, (size)); \
29423 + flush_dcache_page(page); \
29424 +- kunmap_atomic(kaddr, (km_type)); \
29425 ++ kunmap_atomic(__kaddr, (km_type)); \
29426 + } while (0)
29427 +
29428 + static inline void __deprecated memclear_highpage_flush(struct page *page,
29429 +diff -Nurp linux-2.6.23.15/include/linux/irqflags.h linux-2.6.23.15-grsec/include/linux/irqflags.h
29430 +--- linux-2.6.23.15/include/linux/irqflags.h 2007-10-09 21:31:38.000000000 +0100
29431 ++++ linux-2.6.23.15-grsec/include/linux/irqflags.h 2008-02-11 10:37:45.000000000 +0000
29432 +@@ -84,10 +84,10 @@
29433 +
29434 + #define irqs_disabled() \
29435 + ({ \
29436 +- unsigned long flags; \
29437 ++ unsigned long __flags; \
29438 + \
29439 +- raw_local_save_flags(flags); \
29440 +- raw_irqs_disabled_flags(flags); \
29441 ++ raw_local_save_flags(__flags); \
29442 ++ raw_irqs_disabled_flags(__flags); \
29443 + })
29444 +
29445 + #define irqs_disabled_flags(flags) raw_irqs_disabled_flags(flags)
29446 +diff -Nurp linux-2.6.23.15/include/linux/jbd.h linux-2.6.23.15-grsec/include/linux/jbd.h
29447 +--- linux-2.6.23.15/include/linux/jbd.h 2007-10-09 21:31:38.000000000 +0100
29448 ++++ linux-2.6.23.15-grsec/include/linux/jbd.h 2008-02-11 10:37:45.000000000 +0000
29449 +@@ -68,7 +68,7 @@ extern int journal_enable_debug;
29450 + } \
29451 + } while (0)
29452 + #else
29453 +-#define jbd_debug(f, a...) /**/
29454 ++#define jbd_debug(f, a...) do {} while (0)
29455 + #endif
29456 +
29457 + extern void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
29458 +diff -Nurp linux-2.6.23.15/include/linux/jbd2.h linux-2.6.23.15-grsec/include/linux/jbd2.h
29459 +--- linux-2.6.23.15/include/linux/jbd2.h 2007-10-09 21:31:38.000000000 +0100
29460 ++++ linux-2.6.23.15-grsec/include/linux/jbd2.h 2008-02-11 10:37:45.000000000 +0000
29461 +@@ -68,7 +68,7 @@ extern u8 jbd2_journal_enable_debug;
29462 + } \
29463 + } while (0)
29464 + #else
29465 +-#define jbd_debug(f, a...) /**/
29466 ++#define jbd_debug(f, a...) do {} while (0)
29467 + #endif
29468 +
29469 + extern void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
29470 +diff -Nurp linux-2.6.23.15/include/linux/libata.h linux-2.6.23.15-grsec/include/linux/libata.h
29471 +--- linux-2.6.23.15/include/linux/libata.h 2008-02-11 10:36:03.000000000 +0000
29472 ++++ linux-2.6.23.15-grsec/include/linux/libata.h 2008-02-11 10:37:45.000000000 +0000
29473 +@@ -63,11 +63,11 @@
29474 + #ifdef ATA_VERBOSE_DEBUG
29475 + #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
29476 + #else
29477 +-#define VPRINTK(fmt, args...)
29478 ++#define VPRINTK(fmt, args...) do {} while (0)
29479 + #endif /* ATA_VERBOSE_DEBUG */
29480 + #else
29481 +-#define DPRINTK(fmt, args...)
29482 +-#define VPRINTK(fmt, args...)
29483 ++#define DPRINTK(fmt, args...) do {} while (0)
29484 ++#define VPRINTK(fmt, args...) do {} while (0)
29485 + #endif /* ATA_DEBUG */
29486 +
29487 + #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
29488 +diff -Nurp linux-2.6.23.15/include/linux/mm.h linux-2.6.23.15-grsec/include/linux/mm.h
29489 +--- linux-2.6.23.15/include/linux/mm.h 2007-10-09 21:31:38.000000000 +0100
29490 ++++ linux-2.6.23.15-grsec/include/linux/mm.h 2008-02-11 10:37:45.000000000 +0000
29491 +@@ -38,6 +38,7 @@ extern int sysctl_legacy_va_layout;
29492 + #include <asm/page.h>
29493 + #include <asm/pgtable.h>
29494 + #include <asm/processor.h>
29495 ++#include <asm/mman.h>
29496 +
29497 + #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
29498 +
29499 +@@ -111,6 +112,8 @@ struct vm_area_struct {
29500 + #ifdef CONFIG_NUMA
29501 + struct mempolicy *vm_policy; /* NUMA policy for the VMA */
29502 + #endif
29503 ++
29504 ++ struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */
29505 + };
29506 +
29507 + extern struct kmem_cache *vm_area_cachep;
29508 +@@ -171,6 +174,14 @@ extern unsigned int kobjsize(const void
29509 +
29510 + #define VM_CAN_NONLINEAR 0x08000000 /* Has ->fault & does nonlinear pages */
29511 +
29512 ++#ifdef CONFIG_PAX_PAGEEXEC
29513 ++#define VM_PAGEEXEC 0x10000000 /* vma->vm_page_prot needs special handling */
29514 ++#endif
29515 ++
29516 ++#ifdef CONFIG_PAX_MPROTECT
29517 ++#define VM_MAYNOTWRITE 0x20000000 /* vma cannot be granted VM_WRITE any more */
29518 ++#endif
29519 ++
29520 + #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
29521 + #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
29522 + #endif
29523 +@@ -862,6 +873,8 @@ struct shrinker {
29524 + extern void register_shrinker(struct shrinker *);
29525 + extern void unregister_shrinker(struct shrinker *);
29526 +
29527 ++pgprot_t vm_get_page_prot(unsigned long vm_flags);
29528 ++
29529 + int vma_wants_writenotify(struct vm_area_struct *vma);
29530 +
29531 + extern pte_t *FASTCALL(get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl));
29532 +@@ -1088,6 +1101,7 @@ out:
29533 + }
29534 +
29535 + extern int do_munmap(struct mm_struct *, unsigned long, size_t);
29536 ++extern int __do_munmap(struct mm_struct *, unsigned long, size_t);
29537 +
29538 + extern unsigned long do_brk(unsigned long, unsigned long);
29539 +
29540 +@@ -1142,6 +1156,10 @@ extern struct vm_area_struct * find_vma(
29541 + extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
29542 + struct vm_area_struct **pprev);
29543 +
29544 ++extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma);
29545 ++extern void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma);
29546 ++extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl);
29547 ++
29548 + /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
29549 + NULL if none. Assume start_addr < end_addr. */
29550 + static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
29551 +@@ -1158,7 +1176,6 @@ static inline unsigned long vma_pages(st
29552 + return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
29553 + }
29554 +
29555 +-pgprot_t vm_get_page_prot(unsigned long vm_flags);
29556 + struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
29557 + struct page *vmalloc_to_page(void *addr);
29558 + unsigned long vmalloc_to_pfn(void *addr);
29559 +@@ -1218,5 +1235,11 @@ extern int randomize_va_space;
29560 +
29561 + const char * arch_vma_name(struct vm_area_struct *vma);
29562 +
29563 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
29564 ++extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
29565 ++#else
29566 ++static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
29567 ++#endif
29568 ++
29569 + #endif /* __KERNEL__ */
29570 + #endif /* _LINUX_MM_H */
29571 +diff -Nurp linux-2.6.23.15/include/linux/module.h linux-2.6.23.15-grsec/include/linux/module.h
29572 +--- linux-2.6.23.15/include/linux/module.h 2007-10-09 21:31:38.000000000 +0100
29573 ++++ linux-2.6.23.15-grsec/include/linux/module.h 2008-02-11 10:37:45.000000000 +0000
29574 +@@ -295,16 +295,16 @@ struct module
29575 + int (*init)(void);
29576 +
29577 + /* If this is non-NULL, vfree after init() returns */
29578 +- void *module_init;
29579 ++ void *module_init_rx, *module_init_rw;
29580 +
29581 + /* Here is the actual code + data, vfree'd on unload. */
29582 +- void *module_core;
29583 ++ void *module_core_rx, *module_core_rw;
29584 +
29585 + /* Here are the sizes of the init and core sections */
29586 +- unsigned long init_size, core_size;
29587 ++ unsigned long init_size_rw, core_size_rw;
29588 +
29589 + /* The size of the executable code in each section. */
29590 +- unsigned long init_text_size, core_text_size;
29591 ++ unsigned long init_size_rx, core_size_rx;
29592 +
29593 + /* The handle returned from unwind_add_table. */
29594 + void *unwind_info;
29595 +diff -Nurp linux-2.6.23.15/include/linux/moduleloader.h linux-2.6.23.15-grsec/include/linux/moduleloader.h
29596 +--- linux-2.6.23.15/include/linux/moduleloader.h 2007-10-09 21:31:38.000000000 +0100
29597 ++++ linux-2.6.23.15-grsec/include/linux/moduleloader.h 2008-02-11 10:37:45.000000000 +0000
29598 +@@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
29599 + sections. Returns NULL on failure. */
29600 + void *module_alloc(unsigned long size);
29601 +
29602 ++#ifdef CONFIG_PAX_KERNEXEC
29603 ++void *module_alloc_exec(unsigned long size);
29604 ++#else
29605 ++#define module_alloc_exec(x) module_alloc(x)
29606 ++#endif
29607 ++
29608 + /* Free memory returned from module_alloc. */
29609 + void module_free(struct module *mod, void *module_region);
29610 +
29611 ++#ifdef CONFIG_PAX_KERNEXEC
29612 ++void module_free_exec(struct module *mod, void *module_region);
29613 ++#else
29614 ++#define module_free_exec(x, y) module_free(x, y)
29615 ++#endif
29616 ++
29617 + /* Apply the given relocation to the (simplified) ELF. Return -error
29618 + or 0. */
29619 + int apply_relocate(Elf_Shdr *sechdrs,
29620 +diff -Nurp linux-2.6.23.15/include/linux/percpu.h linux-2.6.23.15-grsec/include/linux/percpu.h
29621 +--- linux-2.6.23.15/include/linux/percpu.h 2007-10-09 21:31:38.000000000 +0100
29622 ++++ linux-2.6.23.15-grsec/include/linux/percpu.h 2008-02-11 10:37:45.000000000 +0000
29623 +@@ -18,7 +18,7 @@
29624 + #endif
29625 +
29626 + #define PERCPU_ENOUGH_ROOM \
29627 +- (__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE)
29628 ++ ((unsigned long)(__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE))
29629 + #endif /* PERCPU_ENOUGH_ROOM */
29630 +
29631 + /*
29632 +diff -Nurp linux-2.6.23.15/include/linux/random.h linux-2.6.23.15-grsec/include/linux/random.h
29633 +--- linux-2.6.23.15/include/linux/random.h 2007-10-09 21:31:38.000000000 +0100
29634 ++++ linux-2.6.23.15-grsec/include/linux/random.h 2008-02-11 10:37:45.000000000 +0000
29635 +@@ -72,6 +72,11 @@ unsigned long randomize_range(unsigned l
29636 + u32 random32(void);
29637 + void srandom32(u32 seed);
29638 +
29639 ++static inline unsigned long pax_get_random_long(void)
29640 ++{
29641 ++ return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0);
29642 ++}
29643 ++
29644 + #endif /* __KERNEL___ */
29645 +
29646 + #endif /* _LINUX_RANDOM_H */
29647 +diff -Nurp linux-2.6.23.15/include/linux/sched.h linux-2.6.23.15-grsec/include/linux/sched.h
29648 +--- linux-2.6.23.15/include/linux/sched.h 2008-02-11 10:36:03.000000000 +0000
29649 ++++ linux-2.6.23.15-grsec/include/linux/sched.h 2008-02-11 10:37:45.000000000 +0000
29650 +@@ -92,6 +92,7 @@ struct sched_param {
29651 + struct exec_domain;
29652 + struct futex_pi_state;
29653 + struct bio;
29654 ++struct linux_binprm;
29655 +
29656 + /*
29657 + * List of flags we want to share for kernel threads,
29658 +@@ -432,6 +433,24 @@ struct mm_struct {
29659 + /* aio bits */
29660 + rwlock_t ioctx_list_lock;
29661 + struct kioctx *ioctx_list;
29662 ++
29663 ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
29664 ++ unsigned long pax_flags;
29665 ++#endif
29666 ++
29667 ++#ifdef CONFIG_PAX_DLRESOLVE
29668 ++ unsigned long call_dl_resolve;
29669 ++#endif
29670 ++
29671 ++#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
29672 ++ unsigned long call_syscall;
29673 ++#endif
29674 ++
29675 ++#ifdef CONFIG_PAX_ASLR
29676 ++ unsigned long delta_mmap; /* randomized offset */
29677 ++ unsigned long delta_stack; /* randomized offset */
29678 ++#endif
29679 ++
29680 + };
29681 +
29682 + struct sighand_struct {
29683 +@@ -556,6 +575,15 @@ struct signal_struct {
29684 + unsigned audit_tty;
29685 + struct tty_audit_buf *tty_audit_buf;
29686 + #endif
29687 ++
29688 ++#ifdef CONFIG_GRKERNSEC
29689 ++ u32 curr_ip;
29690 ++ u32 gr_saddr;
29691 ++ u32 gr_daddr;
29692 ++ u16 gr_sport;
29693 ++ u16 gr_dport;
29694 ++ u8 used_accept:1;
29695 ++#endif
29696 + };
29697 +
29698 + /* Context switch must be unlocked if interrupts are to be enabled */
29699 +@@ -1017,8 +1045,8 @@ struct task_struct {
29700 + struct list_head thread_group;
29701 +
29702 + struct completion *vfork_done; /* for vfork() */
29703 +- int __user *set_child_tid; /* CLONE_CHILD_SETTID */
29704 +- int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
29705 ++ pid_t __user *set_child_tid; /* CLONE_CHILD_SETTID */
29706 ++ pid_t __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
29707 +
29708 + unsigned int rt_priority;
29709 + cputime_t utime, stime;
29710 +@@ -1183,6 +1211,17 @@ struct task_struct {
29711 + struct list_head pi_state_list;
29712 + struct futex_pi_state *pi_state_cache;
29713 +
29714 ++#ifdef CONFIG_GRKERNSEC
29715 ++ /* grsecurity */
29716 ++ struct acl_subject_label *acl;
29717 ++ struct acl_role_label *role;
29718 ++ struct file *exec_file;
29719 ++ u16 acl_role_id;
29720 ++ u8 acl_sp_role:1;
29721 ++ u8 is_writable:1;
29722 ++ u8 brute:1;
29723 ++#endif
29724 ++
29725 + atomic_t fs_excl; /* holding fs exclusive resources */
29726 + struct rcu_head rcu;
29727 +
29728 +@@ -1198,6 +1237,46 @@ struct task_struct {
29729 + #endif
29730 + };
29731 +
29732 ++#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
29733 ++#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
29734 ++#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
29735 ++#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
29736 ++/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */
29737 ++#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
29738 ++
29739 ++#ifdef CONFIG_PAX_SOFTMODE
29740 ++extern unsigned int pax_softmode;
29741 ++#endif
29742 ++
29743 ++extern int pax_check_flags(unsigned long *);
29744 ++
29745 ++/* if tsk != current then task_lock must be held on it */
29746 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
29747 ++static inline unsigned long pax_get_flags(struct task_struct *tsk)
29748 ++{
29749 ++ if (likely(tsk->mm))
29750 ++ return tsk->mm->pax_flags;
29751 ++ else
29752 ++ return 0UL;
29753 ++}
29754 ++
29755 ++/* if tsk != current then task_lock must be held on it */
29756 ++static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
29757 ++{
29758 ++ if (likely(tsk->mm)) {
29759 ++ tsk->mm->pax_flags = flags;
29760 ++ return 0;
29761 ++ }
29762 ++ return -EINVAL;
29763 ++}
29764 ++#endif
29765 ++
29766 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
29767 ++extern void pax_set_initial_flags(struct linux_binprm *bprm);
29768 ++#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
29769 ++extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
29770 ++#endif
29771 ++
29772 + /*
29773 + * Priority of a process goes from 0..MAX_PRIO-1, valid RT
29774 + * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
29775 +@@ -1831,6 +1910,12 @@ extern void arch_pick_mmap_layout(struct
29776 + static inline void arch_pick_mmap_layout(struct mm_struct *mm)
29777 + {
29778 + mm->mmap_base = TASK_UNMAPPED_BASE;
29779 ++
29780 ++#ifdef CONFIG_PAX_RANDMMAP
29781 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
29782 ++ mm->mmap_base += mm->delta_mmap;
29783 ++#endif
29784 ++
29785 + mm->get_unmapped_area = arch_get_unmapped_area;
29786 + mm->unmap_area = arch_unmap_area;
29787 + }
29788 +diff -Nurp linux-2.6.23.15/include/linux/screen_info.h linux-2.6.23.15-grsec/include/linux/screen_info.h
29789 +--- linux-2.6.23.15/include/linux/screen_info.h 2007-10-09 21:31:38.000000000 +0100
29790 ++++ linux-2.6.23.15-grsec/include/linux/screen_info.h 2008-02-11 10:37:45.000000000 +0000
29791 +@@ -42,7 +42,8 @@ struct screen_info {
29792 + u16 pages; /* 0x32 */
29793 + u16 vesa_attributes; /* 0x34 */
29794 + u32 capabilities; /* 0x36 */
29795 +- u8 _reserved[6]; /* 0x3a */
29796 ++ u16 vesapm_size; /* 0x3a */
29797 ++ u8 _reserved[4]; /* 0x3c */
29798 + } __attribute__((packed));
29799 +
29800 + extern struct screen_info screen_info;
29801 +diff -Nurp linux-2.6.23.15/include/linux/security.h linux-2.6.23.15-grsec/include/linux/security.h
29802 +--- linux-2.6.23.15/include/linux/security.h 2007-10-09 21:31:38.000000000 +0100
29803 ++++ linux-2.6.23.15-grsec/include/linux/security.h 2008-02-11 10:37:45.000000000 +0000
29804 +@@ -2796,7 +2796,7 @@ static inline struct dentry *securityfs_
29805 + mode_t mode,
29806 + struct dentry *parent,
29807 + void *data,
29808 +- struct file_operations *fops)
29809 ++ const struct file_operations *fops)
29810 + {
29811 + return ERR_PTR(-ENODEV);
29812 + }
29813 +diff -Nurp linux-2.6.23.15/include/linux/shm.h linux-2.6.23.15-grsec/include/linux/shm.h
29814 +--- linux-2.6.23.15/include/linux/shm.h 2007-10-09 21:31:38.000000000 +0100
29815 ++++ linux-2.6.23.15-grsec/include/linux/shm.h 2008-02-11 10:37:45.000000000 +0000
29816 +@@ -86,6 +86,10 @@ struct shmid_kernel /* private to the ke
29817 + pid_t shm_cprid;
29818 + pid_t shm_lprid;
29819 + struct user_struct *mlock_user;
29820 ++#ifdef CONFIG_GRKERNSEC
29821 ++ time_t shm_createtime;
29822 ++ pid_t shm_lapid;
29823 ++#endif
29824 + };
29825 +
29826 + /* shm_mode upper byte flags */
29827 +diff -Nurp linux-2.6.23.15/include/linux/skbuff.h linux-2.6.23.15-grsec/include/linux/skbuff.h
29828 +--- linux-2.6.23.15/include/linux/skbuff.h 2008-02-11 10:36:03.000000000 +0000
29829 ++++ linux-2.6.23.15-grsec/include/linux/skbuff.h 2008-02-11 10:37:45.000000000 +0000
29830 +@@ -385,7 +385,7 @@ extern void skb_truesize_bug(struc
29831 +
29832 + static inline void skb_truesize_check(struct sk_buff *skb)
29833 + {
29834 +- if (unlikely((int)skb->truesize < sizeof(struct sk_buff) + skb->len))
29835 ++ if (unlikely(skb->truesize < sizeof(struct sk_buff) + skb->len))
29836 + skb_truesize_bug(skb);
29837 + }
29838 +
29839 +diff -Nurp linux-2.6.23.15/include/linux/sysctl.h linux-2.6.23.15-grsec/include/linux/sysctl.h
29840 +--- linux-2.6.23.15/include/linux/sysctl.h 2008-02-11 10:36:24.000000000 +0000
29841 ++++ linux-2.6.23.15-grsec/include/linux/sysctl.h 2008-02-11 10:37:45.000000000 +0000
29842 +@@ -168,9 +168,22 @@ enum
29843 + #ifdef CONFIG_ALPHA_UAC_SYSCTL
29844 + KERN_UAC_POLICY=78, /* int: Alpha unaligned access control policy flags */
29845 + #endif /* CONFIG_ALPHA_UAC_SYSCTL */
29846 +-};
29847 +
29848 ++#ifdef CONFIG_GRKERNSEC
29849 ++ KERN_GRSECURITY=98, /* grsecurity */
29850 ++#endif
29851 ++
29852 ++#ifdef CONFIG_PAX_SOFTMODE
29853 ++ KERN_PAX=99, /* PaX control */
29854 ++#endif
29855 ++
29856 ++};
29857 +
29858 ++#ifdef CONFIG_PAX_SOFTMODE
29859 ++enum {
29860 ++ PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */
29861 ++};
29862 ++#endif
29863 +
29864 + /* CTL_VM names: */
29865 + enum
29866 +diff -Nurp linux-2.6.23.15/include/linux/uaccess.h linux-2.6.23.15-grsec/include/linux/uaccess.h
29867 +--- linux-2.6.23.15/include/linux/uaccess.h 2007-10-09 21:31:38.000000000 +0100
29868 ++++ linux-2.6.23.15-grsec/include/linux/uaccess.h 2008-02-11 10:37:45.000000000 +0000
29869 +@@ -76,11 +76,11 @@ static inline unsigned long __copy_from_
29870 + long ret; \
29871 + mm_segment_t old_fs = get_fs(); \
29872 + \
29873 +- set_fs(KERNEL_DS); \
29874 + pagefault_disable(); \
29875 ++ set_fs(KERNEL_DS); \
29876 + ret = __get_user(retval, (__force typeof(retval) __user *)(addr)); \
29877 +- pagefault_enable(); \
29878 + set_fs(old_fs); \
29879 ++ pagefault_enable(); \
29880 + ret; \
29881 + })
29882 +
29883 +diff -Nurp linux-2.6.23.15/include/linux/udf_fs.h linux-2.6.23.15-grsec/include/linux/udf_fs.h
29884 +--- linux-2.6.23.15/include/linux/udf_fs.h 2007-10-09 21:31:38.000000000 +0100
29885 ++++ linux-2.6.23.15-grsec/include/linux/udf_fs.h 2008-02-11 10:37:45.000000000 +0000
29886 +@@ -45,7 +45,7 @@
29887 + printk (f, ##a); \
29888 + }
29889 + #else
29890 +-#define udf_debug(f, a...) /**/
29891 ++#define udf_debug(f, a...) do {} while (0)
29892 + #endif
29893 +
29894 + #define udf_info(f, a...) \
29895 +diff -Nurp linux-2.6.23.15/include/net/sctp/sctp.h linux-2.6.23.15-grsec/include/net/sctp/sctp.h
29896 +--- linux-2.6.23.15/include/net/sctp/sctp.h 2007-10-09 21:31:38.000000000 +0100
29897 ++++ linux-2.6.23.15-grsec/include/net/sctp/sctp.h 2008-02-11 10:37:45.000000000 +0000
29898 +@@ -317,8 +317,8 @@ extern int sctp_debug_flag;
29899 +
29900 + #else /* SCTP_DEBUG */
29901 +
29902 +-#define SCTP_DEBUG_PRINTK(whatever...)
29903 +-#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
29904 ++#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
29905 ++#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
29906 + #define SCTP_ENABLE_DEBUG
29907 + #define SCTP_DISABLE_DEBUG
29908 + #define SCTP_ASSERT(expr, str, func)
29909 +diff -Nurp linux-2.6.23.15/include/sound/core.h linux-2.6.23.15-grsec/include/sound/core.h
29910 +--- linux-2.6.23.15/include/sound/core.h 2007-10-09 21:31:38.000000000 +0100
29911 ++++ linux-2.6.23.15-grsec/include/sound/core.h 2008-02-11 10:37:45.000000000 +0000
29912 +@@ -396,9 +396,9 @@ void snd_verbose_printd(const char *file
29913 +
29914 + #else /* !CONFIG_SND_DEBUG */
29915 +
29916 +-#define snd_printd(fmt, args...) /* nothing */
29917 ++#define snd_printd(fmt, args...) do {} while (0)
29918 + #define snd_assert(expr, args...) (void)(expr)
29919 +-#define snd_BUG() /* nothing */
29920 ++#define snd_BUG() do {} while (0)
29921 +
29922 + #endif /* CONFIG_SND_DEBUG */
29923 +
29924 +@@ -412,7 +412,7 @@ void snd_verbose_printd(const char *file
29925 + */
29926 + #define snd_printdd(format, args...) snd_printk(format, ##args)
29927 + #else
29928 +-#define snd_printdd(format, args...) /* nothing */
29929 ++#define snd_printdd(format, args...) do {} while (0)
29930 + #endif
29931 +
29932 +
29933 +diff -Nurp linux-2.6.23.15/init/Kconfig linux-2.6.23.15-grsec/init/Kconfig
29934 +--- linux-2.6.23.15/init/Kconfig 2007-10-09 21:31:38.000000000 +0100
29935 ++++ linux-2.6.23.15-grsec/init/Kconfig 2008-02-11 10:37:45.000000000 +0000
29936 +@@ -384,6 +384,7 @@ config SYSCTL_SYSCALL
29937 + config KALLSYMS
29938 + bool "Load all symbols for debugging/ksymoops" if EMBEDDED
29939 + default y
29940 ++ depends on !GRKERNSEC_HIDESYM
29941 + help
29942 + Say Y here to let the kernel print out symbolic crash information and
29943 + symbolic stack backtraces. This increases the size of the kernel
29944 +diff -Nurp linux-2.6.23.15/init/do_mounts.c linux-2.6.23.15-grsec/init/do_mounts.c
29945 +--- linux-2.6.23.15/init/do_mounts.c 2007-10-09 21:31:38.000000000 +0100
29946 ++++ linux-2.6.23.15-grsec/init/do_mounts.c 2008-02-11 10:37:45.000000000 +0000
29947 +@@ -68,11 +68,12 @@ static dev_t try_name(char *name, int pa
29948 +
29949 + /* read device number from .../dev */
29950 +
29951 +- sprintf(path, "/sys/block/%s/dev", name);
29952 +- fd = sys_open(path, 0, 0);
29953 ++ if (sizeof path <= snprintf(path, sizeof path, "/sys/block/%s/dev", name))
29954 ++ goto fail;
29955 ++ fd = sys_open((char __user *)path, 0, 0);
29956 + if (fd < 0)
29957 + goto fail;
29958 +- len = sys_read(fd, buf, 32);
29959 ++ len = sys_read(fd, (char __user *)buf, 32);
29960 + sys_close(fd);
29961 + if (len <= 0 || len == 32 || buf[len - 1] != '\n')
29962 + goto fail;
29963 +@@ -98,11 +99,12 @@ static dev_t try_name(char *name, int pa
29964 + return res;
29965 +
29966 + /* otherwise read range from .../range */
29967 +- sprintf(path, "/sys/block/%s/range", name);
29968 +- fd = sys_open(path, 0, 0);
29969 ++ if (sizeof path <= snprintf(path, sizeof path, "/sys/block/%s/range", name))
29970 ++ goto fail;
29971 ++ fd = sys_open((char __user *)path, 0, 0);
29972 + if (fd < 0)
29973 + goto fail;
29974 +- len = sys_read(fd, buf, 32);
29975 ++ len = sys_read(fd, (char __user *)buf, 32);
29976 + sys_close(fd);
29977 + if (len <= 0 || len == 32 || buf[len - 1] != '\n')
29978 + goto fail;
29979 +@@ -145,8 +147,8 @@ dev_t name_to_dev_t(char *name)
29980 + int part;
29981 +
29982 + #ifdef CONFIG_SYSFS
29983 +- int mkdir_err = sys_mkdir("/sys", 0700);
29984 +- if (sys_mount("sysfs", "/sys", "sysfs", 0, NULL) < 0)
29985 ++ int mkdir_err = sys_mkdir((char __user *)"/sys", 0700);
29986 ++ if (sys_mount((char __user *)"sysfs", (char __user *)"/sys", (char __user *)"sysfs", 0, NULL) < 0)
29987 + goto out;
29988 + #endif
29989 +
29990 +@@ -198,10 +200,10 @@ dev_t name_to_dev_t(char *name)
29991 + res = try_name(s, part);
29992 + done:
29993 + #ifdef CONFIG_SYSFS
29994 +- sys_umount("/sys", 0);
29995 ++ sys_umount((char __user *)"/sys", 0);
29996 + out:
29997 + if (!mkdir_err)
29998 +- sys_rmdir("/sys");
29999 ++ sys_rmdir((char __user *)"/sys");
30000 + #endif
30001 + return res;
30002 + fail:
30003 +@@ -281,11 +283,11 @@ static void __init get_fs_names(char *pa
30004 +
30005 + static int __init do_mount_root(char *name, char *fs, int flags, void *data)
30006 + {
30007 +- int err = sys_mount(name, "/root", fs, flags, data);
30008 ++ int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data);
30009 + if (err)
30010 + return err;
30011 +
30012 +- sys_chdir("/root");
30013 ++ sys_chdir((char __user *)"/root");
30014 + ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
30015 + printk("VFS: Mounted root (%s filesystem)%s.\n",
30016 + current->fs->pwdmnt->mnt_sb->s_type->name,
30017 +@@ -371,18 +373,18 @@ void __init change_floppy(char *fmt, ...
30018 + va_start(args, fmt);
30019 + vsprintf(buf, fmt, args);
30020 + va_end(args);
30021 +- fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
30022 ++ fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
30023 + if (fd >= 0) {
30024 + sys_ioctl(fd, FDEJECT, 0);
30025 + sys_close(fd);
30026 + }
30027 + printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
30028 +- fd = sys_open("/dev/console", O_RDWR, 0);
30029 ++ fd = sys_open((char __user *)"/dev/console", O_RDWR, 0);
30030 + if (fd >= 0) {
30031 + sys_ioctl(fd, TCGETS, (long)&termios);
30032 + termios.c_lflag &= ~ICANON;
30033 + sys_ioctl(fd, TCSETSF, (long)&termios);
30034 +- sys_read(fd, &c, 1);
30035 ++ sys_read(fd, (char __user *)&c, 1);
30036 + termios.c_lflag |= ICANON;
30037 + sys_ioctl(fd, TCSETSF, (long)&termios);
30038 + sys_close(fd);
30039 +@@ -468,8 +470,8 @@ void __init prepare_namespace(void)
30040 +
30041 + mount_root();
30042 + out:
30043 +- sys_mount(".", "/", NULL, MS_MOVE, NULL);
30044 +- sys_chroot(".");
30045 ++ sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
30046 ++ sys_chroot((char __user *)".");
30047 + security_sb_post_mountroot();
30048 + }
30049 +
30050 +diff -Nurp linux-2.6.23.15/init/do_mounts.h linux-2.6.23.15-grsec/init/do_mounts.h
30051 +--- linux-2.6.23.15/init/do_mounts.h 2007-10-09 21:31:38.000000000 +0100
30052 ++++ linux-2.6.23.15-grsec/init/do_mounts.h 2008-02-11 10:37:45.000000000 +0000
30053 +@@ -15,15 +15,15 @@ extern char *root_device_name;
30054 +
30055 + static inline int create_dev(char *name, dev_t dev)
30056 + {
30057 +- sys_unlink(name);
30058 +- return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
30059 ++ sys_unlink((char __user *)name);
30060 ++ return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
30061 + }
30062 +
30063 + #if BITS_PER_LONG == 32
30064 + static inline u32 bstat(char *name)
30065 + {
30066 + struct stat64 stat;
30067 +- if (sys_stat64(name, &stat) != 0)
30068 ++ if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0)
30069 + return 0;
30070 + if (!S_ISBLK(stat.st_mode))
30071 + return 0;
30072 +diff -Nurp linux-2.6.23.15/init/do_mounts_md.c linux-2.6.23.15-grsec/init/do_mounts_md.c
30073 +--- linux-2.6.23.15/init/do_mounts_md.c 2007-10-09 21:31:38.000000000 +0100
30074 ++++ linux-2.6.23.15-grsec/init/do_mounts_md.c 2008-02-11 10:37:45.000000000 +0000
30075 +@@ -167,7 +167,7 @@ static void __init md_setup_drive(void)
30076 + partitioned ? "_d" : "", minor,
30077 + md_setup_args[ent].device_names);
30078 +
30079 +- fd = sys_open(name, 0, 0);
30080 ++ fd = sys_open((char __user *)name, 0, 0);
30081 + if (fd < 0) {
30082 + printk(KERN_ERR "md: open failed - cannot start "
30083 + "array %s\n", name);
30084 +@@ -230,7 +230,7 @@ static void __init md_setup_drive(void)
30085 + * array without it
30086 + */
30087 + sys_close(fd);
30088 +- fd = sys_open(name, 0, 0);
30089 ++ fd = sys_open((char __user *)name, 0, 0);
30090 + sys_ioctl(fd, BLKRRPART, 0);
30091 + }
30092 + sys_close(fd);
30093 +@@ -271,7 +271,7 @@ void __init md_run_setup(void)
30094 + if (raid_noautodetect)
30095 + printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
30096 + else {
30097 +- int fd = sys_open("/dev/md0", 0, 0);
30098 ++ int fd = sys_open((char __user *)"/dev/md0", 0, 0);
30099 + if (fd >= 0) {
30100 + sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
30101 + sys_close(fd);
30102 +diff -Nurp linux-2.6.23.15/init/initramfs.c linux-2.6.23.15-grsec/init/initramfs.c
30103 +--- linux-2.6.23.15/init/initramfs.c 2007-10-09 21:31:38.000000000 +0100
30104 ++++ linux-2.6.23.15-grsec/init/initramfs.c 2008-02-11 10:37:45.000000000 +0000
30105 +@@ -240,7 +240,7 @@ static int __init maybe_link(void)
30106 + if (nlink >= 2) {
30107 + char *old = find_link(major, minor, ino, mode, collected);
30108 + if (old)
30109 +- return (sys_link(old, collected) < 0) ? -1 : 1;
30110 ++ return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1;
30111 + }
30112 + return 0;
30113 + }
30114 +@@ -249,11 +249,11 @@ static void __init clean_path(char *path
30115 + {
30116 + struct stat st;
30117 +
30118 +- if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
30119 ++ if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
30120 + if (S_ISDIR(st.st_mode))
30121 +- sys_rmdir(path);
30122 ++ sys_rmdir((char __user *)path);
30123 + else
30124 +- sys_unlink(path);
30125 ++ sys_unlink((char __user *)path);
30126 + }
30127 + }
30128 +
30129 +@@ -276,7 +276,7 @@ static int __init do_name(void)
30130 + int openflags = O_WRONLY|O_CREAT;
30131 + if (ml != 1)
30132 + openflags |= O_TRUNC;
30133 +- wfd = sys_open(collected, openflags, mode);
30134 ++ wfd = sys_open((char __user *)collected, openflags, mode);
30135 +
30136 + if (wfd >= 0) {
30137 + sys_fchown(wfd, uid, gid);
30138 +@@ -285,15 +285,15 @@ static int __init do_name(void)
30139 + }
30140 + }
30141 + } else if (S_ISDIR(mode)) {
30142 +- sys_mkdir(collected, mode);
30143 +- sys_chown(collected, uid, gid);
30144 +- sys_chmod(collected, mode);
30145 ++ sys_mkdir((char __user *)collected, mode);
30146 ++ sys_chown((char __user *)collected, uid, gid);
30147 ++ sys_chmod((char __user *)collected, mode);
30148 + } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
30149 + S_ISFIFO(mode) || S_ISSOCK(mode)) {
30150 + if (maybe_link() == 0) {
30151 +- sys_mknod(collected, mode, rdev);
30152 +- sys_chown(collected, uid, gid);
30153 +- sys_chmod(collected, mode);
30154 ++ sys_mknod((char __user *)collected, mode, rdev);
30155 ++ sys_chown((char __user *)collected, uid, gid);
30156 ++ sys_chmod((char __user *)collected, mode);
30157 + }
30158 + }
30159 + return 0;
30160 +@@ -302,13 +302,13 @@ static int __init do_name(void)
30161 + static int __init do_copy(void)
30162 + {
30163 + if (count >= body_len) {
30164 +- sys_write(wfd, victim, body_len);
30165 ++ sys_write(wfd, (char __user *)victim, body_len);
30166 + sys_close(wfd);
30167 + eat(body_len);
30168 + state = SkipIt;
30169 + return 0;
30170 + } else {
30171 +- sys_write(wfd, victim, count);
30172 ++ sys_write(wfd, (char __user *)victim, count);
30173 + body_len -= count;
30174 + eat(count);
30175 + return 1;
30176 +@@ -319,8 +319,8 @@ static int __init do_symlink(void)
30177 + {
30178 + collected[N_ALIGN(name_len) + body_len] = '\0';
30179 + clean_path(collected, 0);
30180 +- sys_symlink(collected + N_ALIGN(name_len), collected);
30181 +- sys_lchown(collected, uid, gid);
30182 ++ sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected);
30183 ++ sys_lchown((char __user *)collected, uid, gid);
30184 + state = SkipIt;
30185 + next_state = Reset;
30186 + return 0;
30187 +diff -Nurp linux-2.6.23.15/init/main.c linux-2.6.23.15-grsec/init/main.c
30188 +--- linux-2.6.23.15/init/main.c 2007-10-09 21:31:38.000000000 +0100
30189 ++++ linux-2.6.23.15-grsec/init/main.c 2008-02-11 10:37:45.000000000 +0000
30190 +@@ -107,6 +107,7 @@ static inline void mark_rodata_ro(void)
30191 + #ifdef CONFIG_TC
30192 + extern void tc_init(void);
30193 + #endif
30194 ++extern void grsecurity_init(void);
30195 +
30196 + enum system_states system_state;
30197 + EXPORT_SYMBOL(system_state);
30198 +@@ -193,6 +194,17 @@ static int __init set_reset_devices(char
30199 +
30200 + __setup("reset_devices", set_reset_devices);
30201 +
30202 ++#ifdef CONFIG_PAX_SOFTMODE
30203 ++unsigned int pax_softmode;
30204 ++
30205 ++static int __init setup_pax_softmode(char *str)
30206 ++{
30207 ++ get_option(&str, &pax_softmode);
30208 ++ return 1;
30209 ++}
30210 ++__setup("pax_softmode=", setup_pax_softmode);
30211 ++#endif
30212 ++
30213 + static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
30214 + char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
30215 + static const char *panic_later, *panic_param;
30216 +@@ -854,6 +866,8 @@ static int __init kernel_init(void * unu
30217 + prepare_namespace();
30218 + }
30219 +
30220 ++ grsecurity_init();
30221 ++
30222 + /*
30223 + * Ok, we have completed the initial bootup, and
30224 + * we're essentially up and running. Get rid of the
30225 +diff -Nurp linux-2.6.23.15/init/noinitramfs.c linux-2.6.23.15-grsec/init/noinitramfs.c
30226 +--- linux-2.6.23.15/init/noinitramfs.c 2007-10-09 21:31:38.000000000 +0100
30227 ++++ linux-2.6.23.15-grsec/init/noinitramfs.c 2008-02-11 10:37:45.000000000 +0000
30228 +@@ -29,7 +29,7 @@ static int __init default_rootfs(void)
30229 + {
30230 + int err;
30231 +
30232 +- err = sys_mkdir("/dev", 0755);
30233 ++ err = sys_mkdir((const char __user *)"/dev", 0755);
30234 + if (err < 0)
30235 + goto out;
30236 +
30237 +@@ -39,7 +39,7 @@ static int __init default_rootfs(void)
30238 + if (err < 0)
30239 + goto out;
30240 +
30241 +- err = sys_mkdir("/root", 0700);
30242 ++ err = sys_mkdir((const char __user *)"/root", 0700);
30243 + if (err < 0)
30244 + goto out;
30245 +
30246 +diff -Nurp linux-2.6.23.15/ipc/ipc_sysctl.c linux-2.6.23.15-grsec/ipc/ipc_sysctl.c
30247 +--- linux-2.6.23.15/ipc/ipc_sysctl.c 2007-10-09 21:31:38.000000000 +0100
30248 ++++ linux-2.6.23.15-grsec/ipc/ipc_sysctl.c 2008-02-11 10:37:45.000000000 +0000
30249 +@@ -161,7 +161,7 @@ static struct ctl_table ipc_kern_table[]
30250 + .proc_handler = proc_ipc_dointvec,
30251 + .strategy = sysctl_ipc_data,
30252 + },
30253 +- {}
30254 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
30255 + };
30256 +
30257 + static struct ctl_table ipc_root_table[] = {
30258 +@@ -171,7 +171,7 @@ static struct ctl_table ipc_root_table[]
30259 + .mode = 0555,
30260 + .child = ipc_kern_table,
30261 + },
30262 +- {}
30263 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
30264 + };
30265 +
30266 + static int __init ipc_sysctl_init(void)
30267 +diff -Nurp linux-2.6.23.15/ipc/msg.c linux-2.6.23.15-grsec/ipc/msg.c
30268 +--- linux-2.6.23.15/ipc/msg.c 2007-10-09 21:31:38.000000000 +0100
30269 ++++ linux-2.6.23.15-grsec/ipc/msg.c 2008-02-11 10:37:45.000000000 +0000
30270 +@@ -36,6 +36,7 @@
30271 + #include <linux/seq_file.h>
30272 + #include <linux/mutex.h>
30273 + #include <linux/nsproxy.h>
30274 ++#include <linux/grsecurity.h>
30275 +
30276 + #include <asm/current.h>
30277 + #include <asm/uaccess.h>
30278 +@@ -286,6 +287,8 @@ asmlinkage long sys_msgget(key_t key, in
30279 + }
30280 + mutex_unlock(&msg_ids(ns).mutex);
30281 +
30282 ++ gr_log_msgget(ret, msgflg);
30283 ++
30284 + return ret;
30285 + }
30286 +
30287 +@@ -552,6 +555,7 @@ asmlinkage long sys_msgctl(int msqid, in
30288 + break;
30289 + }
30290 + case IPC_RMID:
30291 ++ gr_log_msgrm(ipcp->uid, ipcp->cuid);
30292 + freeque(ns, msq, msqid);
30293 + break;
30294 + }
30295 +diff -Nurp linux-2.6.23.15/ipc/sem.c linux-2.6.23.15-grsec/ipc/sem.c
30296 +--- linux-2.6.23.15/ipc/sem.c 2007-10-09 21:31:38.000000000 +0100
30297 ++++ linux-2.6.23.15-grsec/ipc/sem.c 2008-02-11 10:37:45.000000000 +0000
30298 +@@ -82,6 +82,7 @@
30299 + #include <linux/seq_file.h>
30300 + #include <linux/mutex.h>
30301 + #include <linux/nsproxy.h>
30302 ++#include <linux/grsecurity.h>
30303 +
30304 + #include <asm/uaccess.h>
30305 + #include "util.h"
30306 +@@ -293,6 +294,9 @@ asmlinkage long sys_semget (key_t key, i
30307 + }
30308 +
30309 + mutex_unlock(&sem_ids(ns).mutex);
30310 ++
30311 ++ gr_log_semget(err, semflg);
30312 ++
30313 + return err;
30314 + }
30315 +
30316 +@@ -894,6 +898,7 @@ static int semctl_down(struct ipc_namesp
30317 +
30318 + switch(cmd){
30319 + case IPC_RMID:
30320 ++ gr_log_semrm(ipcp->uid, ipcp->cuid);
30321 + freeary(ns, sma, semid);
30322 + err = 0;
30323 + break;
30324 +diff -Nurp linux-2.6.23.15/ipc/shm.c linux-2.6.23.15-grsec/ipc/shm.c
30325 +--- linux-2.6.23.15/ipc/shm.c 2007-10-09 21:31:38.000000000 +0100
30326 ++++ linux-2.6.23.15-grsec/ipc/shm.c 2008-02-11 10:37:45.000000000 +0000
30327 +@@ -38,6 +38,7 @@
30328 + #include <linux/mutex.h>
30329 + #include <linux/nsproxy.h>
30330 + #include <linux/mount.h>
30331 ++#include <linux/grsecurity.h>
30332 +
30333 + #include <asm/uaccess.h>
30334 +
30335 +@@ -77,6 +78,14 @@ static void shm_destroy (struct ipc_name
30336 + static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
30337 + #endif
30338 +
30339 ++#ifdef CONFIG_GRKERNSEC
30340 ++extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
30341 ++ const time_t shm_createtime, const uid_t cuid,
30342 ++ const int shmid);
30343 ++extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
30344 ++ const time_t shm_createtime);
30345 ++#endif
30346 ++
30347 + static void __shm_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
30348 + {
30349 + ns->ids[IPC_SHM_IDS] = ids;
30350 +@@ -89,6 +98,8 @@ static void __shm_init_ns(struct ipc_nam
30351 +
30352 + static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp)
30353 + {
30354 ++ gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
30355 ++
30356 + if (shp->shm_nattch){
30357 + shp->shm_perm.mode |= SHM_DEST;
30358 + /* Do not find it any more */
30359 +@@ -216,6 +227,17 @@ static void shm_close(struct vm_area_str
30360 + shp->shm_lprid = current->tgid;
30361 + shp->shm_dtim = get_seconds();
30362 + shp->shm_nattch--;
30363 ++#ifdef CONFIG_GRKERNSEC_SHM
30364 ++ if (grsec_enable_shm) {
30365 ++ if (shp->shm_nattch == 0) {
30366 ++ shp->shm_perm.mode |= SHM_DEST;
30367 ++ shm_destroy(ns, shp);
30368 ++ } else
30369 ++ shm_unlock(shp);
30370 ++ mutex_unlock(&shm_ids(ns).mutex);
30371 ++ return;
30372 ++ }
30373 ++#endif
30374 + if(shp->shm_nattch == 0 &&
30375 + shp->shm_perm.mode & SHM_DEST)
30376 + shm_destroy(ns, shp);
30377 +@@ -395,6 +417,9 @@ static int newseg (struct ipc_namespace
30378 + shp->shm_lprid = 0;
30379 + shp->shm_atim = shp->shm_dtim = 0;
30380 + shp->shm_ctim = get_seconds();
30381 ++#ifdef CONFIG_GRKERNSEC
30382 ++ shp->shm_createtime = get_seconds();
30383 ++#endif
30384 + shp->shm_segsz = size;
30385 + shp->shm_nattch = 0;
30386 + shp->id = shm_buildid(ns, id, shp->shm_perm.seq);
30387 +@@ -452,6 +477,8 @@ asmlinkage long sys_shmget (key_t key, s
30388 + }
30389 + mutex_unlock(&shm_ids(ns).mutex);
30390 +
30391 ++ gr_log_shmget(err, shmflg, size);
30392 ++
30393 + return err;
30394 + }
30395 +
30396 +@@ -905,9 +932,21 @@ long do_shmat(int shmid, char __user *sh
30397 + if (err)
30398 + goto out_unlock;
30399 +
30400 ++#ifdef CONFIG_GRKERNSEC
30401 ++ if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
30402 ++ shp->shm_perm.cuid, shmid) ||
30403 ++ !gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
30404 ++ err = -EACCES;
30405 ++ goto out_unlock;
30406 ++ }
30407 ++#endif
30408 ++
30409 + path.dentry = dget(shp->shm_file->f_path.dentry);
30410 + path.mnt = mntget(shp->shm_file->f_path.mnt);
30411 + shp->shm_nattch++;
30412 ++#ifdef CONFIG_GRKERNSEC
30413 ++ shp->shm_lapid = current->pid;
30414 ++#endif
30415 + size = i_size_read(path.dentry->d_inode);
30416 + shm_unlock(shp);
30417 +
30418 +@@ -1111,3 +1150,27 @@ static int sysvipc_shm_proc_show(struct
30419 + shp->shm_ctim);
30420 + }
30421 + #endif
30422 ++
30423 ++void gr_shm_exit(struct task_struct *task)
30424 ++{
30425 ++#ifdef CONFIG_GRKERNSEC_SHM
30426 ++ int i;
30427 ++ struct shmid_kernel *shp;
30428 ++ struct ipc_namespace *ns;
30429 ++
30430 ++ ns = current->nsproxy->ipc_ns;
30431 ++
30432 ++ if (!grsec_enable_shm)
30433 ++ return;
30434 ++
30435 ++ for (i = 0; i <= shm_ids(ns).max_id; i++) {
30436 ++ shp = shm_get(ns, i);
30437 ++ if (shp && (shp->shm_cprid == task->pid) &&
30438 ++ (shp->shm_nattch <= 0)) {
30439 ++ shp->shm_perm.mode |= SHM_DEST;
30440 ++ shm_destroy(ns, shp);
30441 ++ }
30442 ++ }
30443 ++#endif
30444 ++ return;
30445 ++}
30446 +diff -Nurp linux-2.6.23.15/kernel/acct.c linux-2.6.23.15-grsec/kernel/acct.c
30447 +--- linux-2.6.23.15/kernel/acct.c 2007-10-09 21:31:38.000000000 +0100
30448 ++++ linux-2.6.23.15-grsec/kernel/acct.c 2008-02-11 10:37:45.000000000 +0000
30449 +@@ -511,7 +511,7 @@ static void do_acct_process(struct file
30450 + */
30451 + flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
30452 + current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
30453 +- file->f_op->write(file, (char *)&ac,
30454 ++ file->f_op->write(file, (char __user *)&ac,
30455 + sizeof(acct_t), &file->f_pos);
30456 + current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
30457 + set_fs(fs);
30458 +diff -Nurp linux-2.6.23.15/kernel/capability.c linux-2.6.23.15-grsec/kernel/capability.c
30459 +--- linux-2.6.23.15/kernel/capability.c 2007-10-09 21:31:38.000000000 +0100
30460 ++++ linux-2.6.23.15-grsec/kernel/capability.c 2008-02-11 10:37:45.000000000 +0000
30461 +@@ -12,6 +12,7 @@
30462 + #include <linux/module.h>
30463 + #include <linux/security.h>
30464 + #include <linux/syscalls.h>
30465 ++#include <linux/grsecurity.h>
30466 + #include <asm/uaccess.h>
30467 +
30468 + unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
30469 +@@ -236,14 +237,25 @@ out:
30470 + return ret;
30471 + }
30472 +
30473 ++extern int gr_task_is_capable(struct task_struct *task, const int cap);
30474 ++extern int gr_is_capable_nolog(const int cap);
30475 ++
30476 + int __capable(struct task_struct *t, int cap)
30477 + {
30478 +- if (security_capable(t, cap) == 0) {
30479 ++ if ((security_capable(t, cap) == 0) && gr_task_is_capable(t, cap)) {
30480 + t->flags |= PF_SUPERPRIV;
30481 + return 1;
30482 + }
30483 + return 0;
30484 + }
30485 ++int capable_nolog(int cap)
30486 ++{
30487 ++ if ((security_capable(current, cap) == 0) && gr_is_capable_nolog(cap)) {
30488 ++ current->flags |= PF_SUPERPRIV;
30489 ++ return 1;
30490 ++ }
30491 ++ return 0;
30492 ++}
30493 + EXPORT_SYMBOL(__capable);
30494 +
30495 + int capable(int cap)
30496 +@@ -251,3 +263,4 @@ int capable(int cap)
30497 + return __capable(current, cap);
30498 + }
30499 + EXPORT_SYMBOL(capable);
30500 ++EXPORT_SYMBOL(capable_nolog);
30501 +diff -Nurp linux-2.6.23.15/kernel/configs.c linux-2.6.23.15-grsec/kernel/configs.c
30502 +--- linux-2.6.23.15/kernel/configs.c 2007-10-09 21:31:38.000000000 +0100
30503 ++++ linux-2.6.23.15-grsec/kernel/configs.c 2008-02-11 10:37:45.000000000 +0000
30504 +@@ -79,8 +79,16 @@ static int __init ikconfig_init(void)
30505 + struct proc_dir_entry *entry;
30506 +
30507 + /* create the current config file */
30508 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
30509 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
30510 ++ entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root);
30511 ++#elif CONFIG_GRKERNSEC_PROC_USERGROUP
30512 ++ entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root);
30513 ++#endif
30514 ++#else
30515 + entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
30516 + &proc_root);
30517 ++#endif
30518 + if (!entry)
30519 + return -ENOMEM;
30520 +
30521 +diff -Nurp linux-2.6.23.15/kernel/exit.c linux-2.6.23.15-grsec/kernel/exit.c
30522 +--- linux-2.6.23.15/kernel/exit.c 2008-02-11 10:36:03.000000000 +0000
30523 ++++ linux-2.6.23.15-grsec/kernel/exit.c 2008-02-11 10:37:45.000000000 +0000
30524 +@@ -45,6 +45,11 @@
30525 + #include <linux/blkdev.h>
30526 + #include <linux/task_io_accounting_ops.h>
30527 + #include <linux/freezer.h>
30528 ++#include <linux/grsecurity.h>
30529 ++
30530 ++#ifdef CONFIG_GRKERNSEC
30531 ++extern rwlock_t grsec_exec_file_lock;
30532 ++#endif
30533 +
30534 + #include <asm/uaccess.h>
30535 + #include <asm/unistd.h>
30536 +@@ -123,6 +128,7 @@ static void __exit_signal(struct task_st
30537 +
30538 + __unhash_process(tsk);
30539 +
30540 ++ gr_del_task_from_ip_table(tsk);
30541 + tsk->signal = NULL;
30542 + tsk->sighand = NULL;
30543 + spin_unlock(&sighand->siglock);
30544 +@@ -274,12 +280,23 @@ static void reparent_to_kthreadd(void)
30545 + {
30546 + write_lock_irq(&tasklist_lock);
30547 +
30548 ++#ifdef CONFIG_GRKERNSEC
30549 ++ write_lock(&grsec_exec_file_lock);
30550 ++ if (current->exec_file) {
30551 ++ fput(current->exec_file);
30552 ++ current->exec_file = NULL;
30553 ++ }
30554 ++ write_unlock(&grsec_exec_file_lock);
30555 ++#endif
30556 ++
30557 + ptrace_unlink(current);
30558 + /* Reparent to init */
30559 + remove_parent(current);
30560 + current->real_parent = current->parent = kthreadd_task;
30561 + add_parent(current);
30562 +
30563 ++ gr_set_kernel_label(current);
30564 ++
30565 + /* Set the exit signal to SIGCHLD so we signal init on exit */
30566 + current->exit_signal = SIGCHLD;
30567 +
30568 +@@ -374,6 +391,17 @@ void daemonize(const char *name, ...)
30569 + vsnprintf(current->comm, sizeof(current->comm), name, args);
30570 + va_end(args);
30571 +
30572 ++#ifdef CONFIG_GRKERNSEC
30573 ++ write_lock(&grsec_exec_file_lock);
30574 ++ if (current->exec_file) {
30575 ++ fput(current->exec_file);
30576 ++ current->exec_file = NULL;
30577 ++ }
30578 ++ write_unlock(&grsec_exec_file_lock);
30579 ++#endif
30580 ++
30581 ++ gr_set_kernel_label(current);
30582 ++
30583 + /*
30584 + * If we were started as result of loading a module, close all of the
30585 + * user space pages. We don't need them, and if we didn't close them
30586 +@@ -969,11 +997,15 @@ fastcall NORET_TYPE void do_exit(long co
30587 + tsk->exit_code = code;
30588 + taskstats_exit(tsk, group_dead);
30589 +
30590 ++ gr_acl_handle_psacct(tsk, code);
30591 ++ gr_acl_handle_exit();
30592 ++
30593 + exit_mm(tsk);
30594 +
30595 + if (group_dead)
30596 + acct_process();
30597 + exit_sem(tsk);
30598 ++ gr_shm_exit(tsk);
30599 + __exit_files(tsk);
30600 + __exit_fs(tsk);
30601 + check_stack_usage();
30602 +@@ -1174,7 +1206,7 @@ static int wait_task_zombie(struct task_
30603 + pid_t pid = p->pid;
30604 + uid_t uid = p->uid;
30605 + int exit_code = p->exit_code;
30606 +- int why, status;
30607 ++ int why;
30608 +
30609 + if (unlikely(p->exit_state != EXIT_ZOMBIE))
30610 + return 0;
30611 +diff -Nurp linux-2.6.23.15/kernel/fork.c linux-2.6.23.15-grsec/kernel/fork.c
30612 +--- linux-2.6.23.15/kernel/fork.c 2008-02-11 10:36:03.000000000 +0000
30613 ++++ linux-2.6.23.15-grsec/kernel/fork.c 2008-02-11 10:37:45.000000000 +0000
30614 +@@ -50,6 +50,7 @@
30615 + #include <linux/taskstats_kern.h>
30616 + #include <linux/random.h>
30617 + #include <linux/tty.h>
30618 ++#include <linux/grsecurity.h>
30619 +
30620 + #include <asm/pgtable.h>
30621 + #include <asm/pgalloc.h>
30622 +@@ -181,7 +182,7 @@ static struct task_struct *dup_task_stru
30623 + setup_thread_stack(tsk, orig);
30624 +
30625 + #ifdef CONFIG_CC_STACKPROTECTOR
30626 +- tsk->stack_canary = get_random_int();
30627 ++ tsk->stack_canary = pax_get_random_long();
30628 + #endif
30629 +
30630 + /* One for us, one for whoever does the "release_task()" (usually parent) */
30631 +@@ -203,6 +204,10 @@ static inline int dup_mmap(struct mm_str
30632 + unsigned long charge;
30633 + struct mempolicy *pol;
30634 +
30635 ++#ifdef CONFIG_PAX_SEGMEXEC
30636 ++ struct vm_area_struct *mpnt_m;
30637 ++#endif
30638 ++
30639 + down_write(&oldmm->mmap_sem);
30640 + flush_cache_dup_mm(oldmm);
30641 + /*
30642 +@@ -213,8 +218,8 @@ static inline int dup_mmap(struct mm_str
30643 + mm->locked_vm = 0;
30644 + mm->mmap = NULL;
30645 + mm->mmap_cache = NULL;
30646 +- mm->free_area_cache = oldmm->mmap_base;
30647 +- mm->cached_hole_size = ~0UL;
30648 ++ mm->free_area_cache = oldmm->free_area_cache;
30649 ++ mm->cached_hole_size = oldmm->cached_hole_size;
30650 + mm->map_count = 0;
30651 + cpus_clear(mm->cpu_vm_mask);
30652 + mm->mm_rb = RB_ROOT;
30653 +@@ -233,6 +238,7 @@ static inline int dup_mmap(struct mm_str
30654 + continue;
30655 + }
30656 + charge = 0;
30657 ++
30658 + if (mpnt->vm_flags & VM_ACCOUNT) {
30659 + unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
30660 + if (security_vm_enough_memory(len))
30661 +@@ -251,6 +257,7 @@ static inline int dup_mmap(struct mm_str
30662 + tmp->vm_flags &= ~VM_LOCKED;
30663 + tmp->vm_mm = mm;
30664 + tmp->vm_next = NULL;
30665 ++ tmp->vm_mirror = NULL;
30666 + anon_vma_link(tmp);
30667 + file = tmp->vm_file;
30668 + if (file) {
30669 +@@ -287,6 +294,29 @@ static inline int dup_mmap(struct mm_str
30670 + if (retval)
30671 + goto out;
30672 + }
30673 ++
30674 ++#ifdef CONFIG_PAX_SEGMEXEC
30675 ++ if (oldmm->pax_flags & MF_PAX_SEGMEXEC) {
30676 ++ for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) {
30677 ++ BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm);
30678 ++
30679 ++ if (!mpnt->vm_mirror)
30680 ++ continue;
30681 ++
30682 ++ if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) {
30683 ++ BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt);
30684 ++ mpnt->vm_mirror = mpnt_m;
30685 ++ } else {
30686 ++ BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm);
30687 ++ mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror;
30688 ++ mpnt_m->vm_mirror->vm_mirror = mpnt_m;
30689 ++ mpnt->vm_mirror->vm_mirror = mpnt;
30690 ++ }
30691 ++ }
30692 ++ BUG_ON(mpnt_m);
30693 ++ }
30694 ++#endif
30695 ++
30696 + /* a new mm has just been created */
30697 + arch_dup_mmap(oldmm, mm);
30698 + retval = 0;
30699 +@@ -464,7 +494,7 @@ void mm_release(struct task_struct *tsk,
30700 + if (tsk->clear_child_tid
30701 + && !(tsk->flags & PF_SIGNALED)
30702 + && atomic_read(&mm->mm_users) > 1) {
30703 +- u32 __user * tidptr = tsk->clear_child_tid;
30704 ++ pid_t __user * tidptr = tsk->clear_child_tid;
30705 + tsk->clear_child_tid = NULL;
30706 +
30707 + /*
30708 +@@ -472,7 +502,7 @@ void mm_release(struct task_struct *tsk,
30709 + * not set up a proper pointer then tough luck.
30710 + */
30711 + put_user(0, tidptr);
30712 +- sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
30713 ++ sys_futex((u32 __user *)tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
30714 + }
30715 + }
30716 +
30717 +@@ -1001,6 +1031,9 @@ static struct task_struct *copy_process(
30718 + DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
30719 + #endif
30720 + retval = -EAGAIN;
30721 ++
30722 ++ gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
30723 ++
30724 + if (atomic_read(&p->user->processes) >=
30725 + p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
30726 + if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
30727 +@@ -1140,6 +1173,8 @@ static struct task_struct *copy_process(
30728 + if (retval)
30729 + goto bad_fork_cleanup_namespaces;
30730 +
30731 ++ gr_copy_label(p);
30732 ++
30733 + p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
30734 + /*
30735 + * Clear TID on mm_release()?
30736 +@@ -1318,6 +1353,8 @@ bad_fork_cleanup_count:
30737 + bad_fork_free:
30738 + free_task(p);
30739 + fork_out:
30740 ++ gr_log_forkfail(retval);
30741 ++
30742 + return ERR_PTR(retval);
30743 + }
30744 +
30745 +@@ -1391,6 +1428,8 @@ long do_fork(unsigned long clone_flags,
30746 + if (!IS_ERR(p)) {
30747 + struct completion vfork;
30748 +
30749 ++ gr_handle_brute_check();
30750 ++
30751 + if (clone_flags & CLONE_VFORK) {
30752 + p->vfork_done = &vfork;
30753 + init_completion(&vfork);
30754 +diff -Nurp linux-2.6.23.15/kernel/futex.c linux-2.6.23.15-grsec/kernel/futex.c
30755 +--- linux-2.6.23.15/kernel/futex.c 2008-02-11 10:36:03.000000000 +0000
30756 ++++ linux-2.6.23.15-grsec/kernel/futex.c 2008-02-11 10:37:45.000000000 +0000
30757 +@@ -186,6 +186,11 @@ int get_futex_key(u32 __user *uaddr, str
30758 + struct page *page;
30759 + int err;
30760 +
30761 ++#ifdef CONFIG_PAX_SEGMEXEC
30762 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && address >= SEGMEXEC_TASK_SIZE)
30763 ++ return -EFAULT;
30764 ++#endif
30765 ++
30766 + /*
30767 + * The futex address must be "naturally" aligned.
30768 + */
30769 +@@ -212,8 +217,8 @@ int get_futex_key(u32 __user *uaddr, str
30770 + * The futex is hashed differently depending on whether
30771 + * it's in a shared or private mapping. So check vma first.
30772 + */
30773 +- vma = find_extend_vma(mm, address);
30774 +- if (unlikely(!vma))
30775 ++ vma = find_vma(mm, address);
30776 ++ if (unlikely(!vma || address < vma->vm_start))
30777 + return -EFAULT;
30778 +
30779 + /*
30780 +@@ -1922,7 +1927,7 @@ retry:
30781 + */
30782 + static inline int fetch_robust_entry(struct robust_list __user **entry,
30783 + struct robust_list __user * __user *head,
30784 +- int *pi)
30785 ++ unsigned int *pi)
30786 + {
30787 + unsigned long uentry;
30788 +
30789 +diff -Nurp linux-2.6.23.15/kernel/irq/handle.c linux-2.6.23.15-grsec/kernel/irq/handle.c
30790 +--- linux-2.6.23.15/kernel/irq/handle.c 2007-10-09 21:31:38.000000000 +0100
30791 ++++ linux-2.6.23.15-grsec/kernel/irq/handle.c 2008-02-11 10:37:45.000000000 +0000
30792 +@@ -55,7 +55,8 @@ struct irq_desc irq_desc[NR_IRQS] __cach
30793 + .depth = 1,
30794 + .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
30795 + #ifdef CONFIG_SMP
30796 +- .affinity = CPU_MASK_ALL
30797 ++ .affinity = CPU_MASK_ALL,
30798 ++ .cpu = 0,
30799 + #endif
30800 + }
30801 + };
30802 +diff -Nurp linux-2.6.23.15/kernel/kallsyms.c linux-2.6.23.15-grsec/kernel/kallsyms.c
30803 +--- linux-2.6.23.15/kernel/kallsyms.c 2007-10-09 21:31:38.000000000 +0100
30804 ++++ linux-2.6.23.15-grsec/kernel/kallsyms.c 2008-02-11 10:37:45.000000000 +0000
30805 +@@ -65,6 +65,19 @@ static inline int is_kernel_text(unsigne
30806 +
30807 + static inline int is_kernel(unsigned long addr)
30808 + {
30809 ++
30810 ++#ifdef CONFIG_PAX_KERNEXEC
30811 ++
30812 ++#ifdef CONFIG_MODULES
30813 ++ if ((unsigned long)MODULES_VADDR <= addr + __KERNEL_TEXT_OFFSET &&
30814 ++ addr + __KERNEL_TEXT_OFFSET < (unsigned long)MODULES_END)
30815 ++ return 0;
30816 ++#endif
30817 ++
30818 ++ if (is_kernel_inittext(addr))
30819 ++ return 1;
30820 ++#endif
30821 ++
30822 + if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
30823 + return 1;
30824 + return in_gate_area_no_task(addr);
30825 +@@ -373,7 +386,6 @@ static unsigned long get_ksymbol_core(st
30826 +
30827 + static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
30828 + {
30829 +- iter->name[0] = '\0';
30830 + iter->nameoff = get_symbol_offset(new_pos);
30831 + iter->pos = new_pos;
30832 + }
30833 +@@ -457,7 +469,7 @@ static int kallsyms_open(struct inode *i
30834 + struct kallsym_iter *iter;
30835 + int ret;
30836 +
30837 +- iter = kmalloc(sizeof(*iter), GFP_KERNEL);
30838 ++ iter = kzalloc(sizeof(*iter), GFP_KERNEL);
30839 + if (!iter)
30840 + return -ENOMEM;
30841 + reset_iter(iter, 0);
30842 +@@ -481,7 +493,15 @@ static int __init kallsyms_init(void)
30843 + {
30844 + struct proc_dir_entry *entry;
30845 +
30846 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
30847 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
30848 ++ entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL);
30849 ++#elif CONFIG_GRKERNSEC_PROC_USERGROUP
30850 ++ entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL);
30851 ++#endif
30852 ++#else
30853 + entry = create_proc_entry("kallsyms", 0444, NULL);
30854 ++#endif
30855 + if (entry)
30856 + entry->proc_fops = &kallsyms_operations;
30857 + return 0;
30858 +diff -Nurp linux-2.6.23.15/kernel/kprobes.c linux-2.6.23.15-grsec/kernel/kprobes.c
30859 +--- linux-2.6.23.15/kernel/kprobes.c 2007-10-09 21:31:38.000000000 +0100
30860 ++++ linux-2.6.23.15-grsec/kernel/kprobes.c 2008-02-11 10:37:45.000000000 +0000
30861 +@@ -168,7 +168,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
30862 + * kernel image and loaded module images reside. This is required
30863 + * so x86_64 can correctly handle the %rip-relative fixups.
30864 + */
30865 +- kip->insns = module_alloc(PAGE_SIZE);
30866 ++ kip->insns = module_alloc_exec(PAGE_SIZE);
30867 + if (!kip->insns) {
30868 + kfree(kip);
30869 + return NULL;
30870 +@@ -200,7 +200,7 @@ static int __kprobes collect_one_slot(st
30871 + hlist_add_head(&kip->hlist,
30872 + &kprobe_insn_pages);
30873 + } else {
30874 +- module_free(NULL, kip->insns);
30875 ++ module_free_exec(NULL, kip->insns);
30876 + kfree(kip);
30877 + }
30878 + return 1;
30879 +diff -Nurp linux-2.6.23.15/kernel/module.c linux-2.6.23.15-grsec/kernel/module.c
30880 +--- linux-2.6.23.15/kernel/module.c 2007-10-09 21:31:38.000000000 +0100
30881 ++++ linux-2.6.23.15-grsec/kernel/module.c 2008-02-11 10:37:45.000000000 +0000
30882 +@@ -44,6 +44,11 @@
30883 + #include <asm/uaccess.h>
30884 + #include <asm/semaphore.h>
30885 + #include <asm/cacheflush.h>
30886 ++
30887 ++#ifdef CONFIG_PAX_KERNEXEC
30888 ++#include <asm/desc.h>
30889 ++#endif
30890 ++
30891 + #include <linux/license.h>
30892 +
30893 + extern int module_sysfs_initialized;
30894 +@@ -68,6 +73,8 @@ static LIST_HEAD(modules);
30895 +
30896 + static BLOCKING_NOTIFIER_HEAD(module_notify_list);
30897 +
30898 ++extern int gr_check_modstop(void);
30899 ++
30900 + int register_module_notifier(struct notifier_block * nb)
30901 + {
30902 + return blocking_notifier_chain_register(&module_notify_list, nb);
30903 +@@ -347,7 +354,7 @@ static void *percpu_modalloc(unsigned lo
30904 + unsigned int i;
30905 + void *ptr;
30906 +
30907 +- if (align > PAGE_SIZE) {
30908 ++ if (align-1 >= PAGE_SIZE) {
30909 + printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
30910 + name, align, PAGE_SIZE);
30911 + align = PAGE_SIZE;
30912 +@@ -660,6 +667,9 @@ sys_delete_module(const char __user *nam
30913 + char name[MODULE_NAME_LEN];
30914 + int ret, forced = 0;
30915 +
30916 ++ if (gr_check_modstop())
30917 ++ return -EPERM;
30918 ++
30919 + if (!capable(CAP_SYS_MODULE))
30920 + return -EPERM;
30921 +
30922 +@@ -1209,16 +1219,19 @@ static void free_module(struct module *m
30923 + module_unload_free(mod);
30924 +
30925 + /* This may be NULL, but that's OK */
30926 +- module_free(mod, mod->module_init);
30927 ++ module_free(mod, mod->module_init_rw);
30928 ++ module_free_exec(mod, mod->module_init_rx);
30929 + kfree(mod->args);
30930 + if (mod->percpu)
30931 + percpu_modfree(mod->percpu);
30932 +
30933 + /* Free lock-classes: */
30934 +- lockdep_free_key_range(mod->module_core, mod->core_size);
30935 ++ lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
30936 ++ lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
30937 +
30938 + /* Finally, free the core (containing the module structure) */
30939 +- module_free(mod, mod->module_core);
30940 ++ module_free_exec(mod, mod->module_core_rx);
30941 ++ module_free(mod, mod->module_core_rw);
30942 + }
30943 +
30944 + void *__symbol_get(const char *symbol)
30945 +@@ -1279,10 +1292,14 @@ static int simplify_symbols(Elf_Shdr *se
30946 + struct module *mod)
30947 + {
30948 + Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
30949 +- unsigned long secbase;
30950 ++ unsigned long secbase, symbol;
30951 + unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
30952 + int ret = 0;
30953 +
30954 ++#ifdef CONFIG_PAX_KERNEXEC
30955 ++ unsigned long cr0;
30956 ++#endif
30957 ++
30958 + for (i = 1; i < n; i++) {
30959 + switch (sym[i].st_shndx) {
30960 + case SHN_COMMON:
30961 +@@ -1301,10 +1318,19 @@ static int simplify_symbols(Elf_Shdr *se
30962 + break;
30963 +
30964 + case SHN_UNDEF:
30965 +- sym[i].st_value
30966 +- = resolve_symbol(sechdrs, versindex,
30967 ++ symbol = resolve_symbol(sechdrs, versindex,
30968 + strtab + sym[i].st_name, mod);
30969 +
30970 ++#ifdef CONFIG_PAX_KERNEXEC
30971 ++ pax_open_kernel(cr0);
30972 ++#endif
30973 ++
30974 ++ sym[i].st_value = symbol;
30975 ++
30976 ++#ifdef CONFIG_PAX_KERNEXEC
30977 ++ pax_close_kernel(cr0);
30978 ++#endif
30979 ++
30980 + /* Ok if resolved. */
30981 + if (sym[i].st_value != 0)
30982 + break;
30983 +@@ -1319,11 +1345,27 @@ static int simplify_symbols(Elf_Shdr *se
30984 +
30985 + default:
30986 + /* Divert to percpu allocation if a percpu var. */
30987 +- if (sym[i].st_shndx == pcpuindex)
30988 ++ if (sym[i].st_shndx == pcpuindex) {
30989 ++
30990 ++#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
30991 ++ secbase = (unsigned long)mod->percpu - (unsigned long)__per_cpu_start;
30992 ++#else
30993 + secbase = (unsigned long)mod->percpu;
30994 +- else
30995 ++#endif
30996 ++
30997 ++ } else
30998 + secbase = sechdrs[sym[i].st_shndx].sh_addr;
30999 ++
31000 ++#ifdef CONFIG_PAX_KERNEXEC
31001 ++ pax_open_kernel(cr0);
31002 ++#endif
31003 ++
31004 + sym[i].st_value += secbase;
31005 ++
31006 ++#ifdef CONFIG_PAX_KERNEXEC
31007 ++ pax_close_kernel(cr0);
31008 ++#endif
31009 ++
31010 + break;
31011 + }
31012 + }
31013 +@@ -1375,11 +1417,14 @@ static void layout_sections(struct modul
31014 + || strncmp(secstrings + s->sh_name,
31015 + ".init", 5) == 0)
31016 + continue;
31017 +- s->sh_entsize = get_offset(&mod->core_size, s);
31018 ++ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
31019 ++ s->sh_entsize = get_offset(&mod->core_size_rw, s);
31020 ++ else
31021 ++ s->sh_entsize = get_offset(&mod->core_size_rx, s);
31022 + DEBUGP("\t%s\n", secstrings + s->sh_name);
31023 + }
31024 + if (m == 0)
31025 +- mod->core_text_size = mod->core_size;
31026 ++ mod->core_size_rx = mod->core_size_rx;
31027 + }
31028 +
31029 + DEBUGP("Init section allocation order:\n");
31030 +@@ -1393,12 +1438,15 @@ static void layout_sections(struct modul
31031 + || strncmp(secstrings + s->sh_name,
31032 + ".init", 5) != 0)
31033 + continue;
31034 +- s->sh_entsize = (get_offset(&mod->init_size, s)
31035 +- | INIT_OFFSET_MASK);
31036 ++ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
31037 ++ s->sh_entsize = get_offset(&mod->init_size_rw, s);
31038 ++ else
31039 ++ s->sh_entsize = get_offset(&mod->init_size_rx, s);
31040 ++ s->sh_entsize |= INIT_OFFSET_MASK;
31041 + DEBUGP("\t%s\n", secstrings + s->sh_name);
31042 + }
31043 + if (m == 0)
31044 +- mod->init_text_size = mod->init_size;
31045 ++ mod->init_size_rx = mod->init_size_rx;
31046 + }
31047 + }
31048 +
31049 +@@ -1525,14 +1573,31 @@ static void add_kallsyms(struct module *
31050 + {
31051 + unsigned int i;
31052 +
31053 ++#ifdef CONFIG_PAX_KERNEXEC
31054 ++ unsigned long cr0;
31055 ++#endif
31056 ++
31057 + mod->symtab = (void *)sechdrs[symindex].sh_addr;
31058 + mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
31059 + mod->strtab = (void *)sechdrs[strindex].sh_addr;
31060 +
31061 + /* Set types up while we still have access to sections. */
31062 +- for (i = 0; i < mod->num_symtab; i++)
31063 +- mod->symtab[i].st_info
31064 +- = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
31065 ++
31066 ++ for (i = 0; i < mod->num_symtab; i++) {
31067 ++ char type = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
31068 ++
31069 ++#ifdef CONFIG_PAX_KERNEXEC
31070 ++ pax_open_kernel(cr0);
31071 ++#endif
31072 ++
31073 ++ mod->symtab[i].st_info = type;
31074 ++
31075 ++#ifdef CONFIG_PAX_KERNEXEC
31076 ++ pax_close_kernel(cr0);
31077 ++#endif
31078 ++
31079 ++ }
31080 ++
31081 + }
31082 + #else
31083 + static inline void add_kallsyms(struct module *mod,
31084 +@@ -1580,6 +1645,10 @@ static struct module *load_module(void _
31085 + struct exception_table_entry *extable;
31086 + mm_segment_t old_fs;
31087 +
31088 ++#ifdef CONFIG_PAX_KERNEXEC
31089 ++ unsigned long cr0;
31090 ++#endif
31091 ++
31092 + DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
31093 + umod, len, uargs);
31094 + if (len < sizeof(*hdr))
31095 +@@ -1738,21 +1807,57 @@ static struct module *load_module(void _
31096 + layout_sections(mod, hdr, sechdrs, secstrings);
31097 +
31098 + /* Do the allocs. */
31099 +- ptr = module_alloc(mod->core_size);
31100 ++ ptr = module_alloc(mod->core_size_rw);
31101 + if (!ptr) {
31102 + err = -ENOMEM;
31103 + goto free_percpu;
31104 + }
31105 +- memset(ptr, 0, mod->core_size);
31106 +- mod->module_core = ptr;
31107 ++ memset(ptr, 0, mod->core_size_rw);
31108 ++ mod->module_core_rw = ptr;
31109 ++
31110 ++ ptr = module_alloc(mod->init_size_rw);
31111 ++ if (!ptr && mod->init_size_rw) {
31112 ++ err = -ENOMEM;
31113 ++ goto free_core_rw;
31114 ++ }
31115 ++ memset(ptr, 0, mod->init_size_rw);
31116 ++ mod->module_init_rw = ptr;
31117 ++
31118 ++ ptr = module_alloc_exec(mod->core_size_rx);
31119 ++ if (!ptr) {
31120 ++ err = -ENOMEM;
31121 ++ goto free_init_rw;
31122 ++ }
31123 ++
31124 ++#ifdef CONFIG_PAX_KERNEXEC
31125 ++ pax_open_kernel(cr0);
31126 ++#endif
31127 +
31128 +- ptr = module_alloc(mod->init_size);
31129 +- if (!ptr && mod->init_size) {
31130 ++ memset(ptr, 0, mod->core_size_rx);
31131 ++
31132 ++#ifdef CONFIG_PAX_KERNEXEC
31133 ++ pax_close_kernel(cr0);
31134 ++#endif
31135 ++
31136 ++ mod->module_core_rx = ptr;
31137 ++
31138 ++ ptr = module_alloc_exec(mod->init_size_rx);
31139 ++ if (!ptr && mod->init_size_rx) {
31140 + err = -ENOMEM;
31141 +- goto free_core;
31142 ++ goto free_core_rx;
31143 + }
31144 +- memset(ptr, 0, mod->init_size);
31145 +- mod->module_init = ptr;
31146 ++
31147 ++#ifdef CONFIG_PAX_KERNEXEC
31148 ++ pax_open_kernel(cr0);
31149 ++#endif
31150 ++
31151 ++ memset(ptr, 0, mod->init_size_rx);
31152 ++
31153 ++#ifdef CONFIG_PAX_KERNEXEC
31154 ++ pax_close_kernel(cr0);
31155 ++#endif
31156 ++
31157 ++ mod->module_init_rx = ptr;
31158 +
31159 + /* Transfer each section which specifies SHF_ALLOC */
31160 + DEBUGP("final section addresses:\n");
31161 +@@ -1762,17 +1867,41 @@ static struct module *load_module(void _
31162 + if (!(sechdrs[i].sh_flags & SHF_ALLOC))
31163 + continue;
31164 +
31165 +- if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
31166 +- dest = mod->module_init
31167 +- + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
31168 +- else
31169 +- dest = mod->module_core + sechdrs[i].sh_entsize;
31170 ++ if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
31171 ++ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
31172 ++ dest = mod->module_init_rw
31173 ++ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
31174 ++ else
31175 ++ dest = mod->module_init_rx
31176 ++ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
31177 ++ } else {
31178 ++ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
31179 ++ dest = mod->module_core_rw + sechdrs[i].sh_entsize;
31180 ++ else
31181 ++ dest = mod->module_core_rx + sechdrs[i].sh_entsize;
31182 ++ }
31183 ++
31184 ++ if (sechdrs[i].sh_type != SHT_NOBITS) {
31185 +
31186 +- if (sechdrs[i].sh_type != SHT_NOBITS)
31187 +- memcpy(dest, (void *)sechdrs[i].sh_addr,
31188 +- sechdrs[i].sh_size);
31189 ++#ifdef CONFIG_PAX_KERNEXEC
31190 ++ if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC)) {
31191 ++ pax_open_kernel(cr0);
31192 ++ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
31193 ++ pax_close_kernel(cr0);
31194 ++ } else
31195 ++#endif
31196 ++
31197 ++ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
31198 ++ }
31199 + /* Update sh_addr to point to copy in image. */
31200 +- sechdrs[i].sh_addr = (unsigned long)dest;
31201 ++
31202 ++#ifdef CONFIG_PAX_KERNEXEC
31203 ++ if (sechdrs[i].sh_flags & SHF_EXECINSTR)
31204 ++ sechdrs[i].sh_addr = (unsigned long)dest - __KERNEL_TEXT_OFFSET;
31205 ++ else
31206 ++#endif
31207 ++
31208 ++ sechdrs[i].sh_addr = (unsigned long)dest;
31209 + DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
31210 + }
31211 + /* Module has been moved. */
31212 +@@ -1892,12 +2021,12 @@ static struct module *load_module(void _
31213 + * Do it before processing of module parameters, so the module
31214 + * can provide parameter accessor functions of its own.
31215 + */
31216 +- if (mod->module_init)
31217 +- flush_icache_range((unsigned long)mod->module_init,
31218 +- (unsigned long)mod->module_init
31219 +- + mod->init_size);
31220 +- flush_icache_range((unsigned long)mod->module_core,
31221 +- (unsigned long)mod->module_core + mod->core_size);
31222 ++ if (mod->module_init_rx)
31223 ++ flush_icache_range((unsigned long)mod->module_init_rx,
31224 ++ (unsigned long)mod->module_init_rx
31225 ++ + mod->init_size_rx);
31226 ++ flush_icache_range((unsigned long)mod->module_core_rx,
31227 ++ (unsigned long)mod->module_core_rx + mod->core_size_rx);
31228 +
31229 + set_fs(old_fs);
31230 +
31231 +@@ -1940,9 +2069,13 @@ static struct module *load_module(void _
31232 + module_arch_cleanup(mod);
31233 + cleanup:
31234 + module_unload_free(mod);
31235 +- module_free(mod, mod->module_init);
31236 +- free_core:
31237 +- module_free(mod, mod->module_core);
31238 ++ module_free_exec(mod, mod->module_init_rx);
31239 ++ free_core_rx:
31240 ++ module_free_exec(mod, mod->module_core_rx);
31241 ++ free_init_rw:
31242 ++ module_free(mod, mod->module_init_rw);
31243 ++ free_core_rw:
31244 ++ module_free(mod, mod->module_core_rw);
31245 + free_percpu:
31246 + if (percpu)
31247 + percpu_modfree(percpu);
31248 +@@ -1978,6 +2111,9 @@ sys_init_module(void __user *umod,
31249 + struct module *mod;
31250 + int ret = 0;
31251 +
31252 ++ if (gr_check_modstop())
31253 ++ return -EPERM;
31254 ++
31255 + /* Must have permission */
31256 + if (!capable(CAP_SYS_MODULE))
31257 + return -EPERM;
31258 +@@ -2029,10 +2165,12 @@ sys_init_module(void __user *umod,
31259 + /* Drop initial reference. */
31260 + module_put(mod);
31261 + unwind_remove_table(mod->unwind_info, 1);
31262 +- module_free(mod, mod->module_init);
31263 +- mod->module_init = NULL;
31264 +- mod->init_size = 0;
31265 +- mod->init_text_size = 0;
31266 ++ module_free(mod, mod->module_init_rw);
31267 ++ module_free_exec(mod, mod->module_init_rx);
31268 ++ mod->module_init_rw = NULL;
31269 ++ mod->module_init_rx = NULL;
31270 ++ mod->init_size_rw = 0;
31271 ++ mod->init_size_rx = 0;
31272 + mutex_unlock(&module_mutex);
31273 +
31274 + return 0;
31275 +@@ -2040,6 +2178,13 @@ sys_init_module(void __user *umod,
31276 +
31277 + static inline int within(unsigned long addr, void *start, unsigned long size)
31278 + {
31279 ++
31280 ++#ifdef CONFIG_PAX_KERNEXEC
31281 ++ if (addr + __KERNEL_TEXT_OFFSET >= (unsigned long)start &&
31282 ++ addr + __KERNEL_TEXT_OFFSET < (unsigned long)start + size)
31283 ++ return 1;
31284 ++#endif
31285 ++
31286 + return ((void *)addr >= start && (void *)addr < start + size);
31287 + }
31288 +
31289 +@@ -2063,10 +2208,14 @@ static const char *get_ksymbol(struct mo
31290 + unsigned long nextval;
31291 +
31292 + /* At worse, next value is at end of module */
31293 +- if (within(addr, mod->module_init, mod->init_size))
31294 +- nextval = (unsigned long)mod->module_init+mod->init_text_size;
31295 +- else
31296 +- nextval = (unsigned long)mod->module_core+mod->core_text_size;
31297 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx))
31298 ++ nextval = (unsigned long)mod->module_init_rx+mod->init_size_rx;
31299 ++ else if (within(addr, mod->module_init_rw, mod->init_size_rw))
31300 ++ nextval = (unsigned long)mod->module_init_rw+mod->init_size_rw;
31301 ++ else if (within(addr, mod->module_core_rx, mod->core_size_rx))
31302 ++ nextval = (unsigned long)mod->module_core_rx+mod->core_size_rx;
31303 ++ else
31304 ++ nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
31305 +
31306 + /* Scan for closest preceeding symbol, and next symbol. (ELF
31307 + starts real symbols at 1). */
31308 +@@ -2109,8 +2258,10 @@ const char *module_address_lookup(unsign
31309 + struct module *mod;
31310 +
31311 + list_for_each_entry(mod, &modules, list) {
31312 +- if (within(addr, mod->module_init, mod->init_size)
31313 +- || within(addr, mod->module_core, mod->core_size)) {
31314 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
31315 ++ within(addr, mod->module_init_rw, mod->init_size_rw) ||
31316 ++ within(addr, mod->module_core_rx, mod->core_size_rx) ||
31317 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
31318 + if (modname)
31319 + *modname = mod->name;
31320 + return get_ksymbol(mod, addr, size, offset);
31321 +@@ -2125,8 +2276,10 @@ int lookup_module_symbol_name(unsigned l
31322 +
31323 + mutex_lock(&module_mutex);
31324 + list_for_each_entry(mod, &modules, list) {
31325 +- if (within(addr, mod->module_init, mod->init_size) ||
31326 +- within(addr, mod->module_core, mod->core_size)) {
31327 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
31328 ++ within(addr, mod->module_init_rw, mod->init_size_rw) ||
31329 ++ within(addr, mod->module_core_rx, mod->core_size_rx) ||
31330 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
31331 + const char *sym;
31332 +
31333 + sym = get_ksymbol(mod, addr, NULL, NULL);
31334 +@@ -2149,8 +2302,10 @@ int lookup_module_symbol_attrs(unsigned
31335 +
31336 + mutex_lock(&module_mutex);
31337 + list_for_each_entry(mod, &modules, list) {
31338 +- if (within(addr, mod->module_init, mod->init_size) ||
31339 +- within(addr, mod->module_core, mod->core_size)) {
31340 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
31341 ++ within(addr, mod->module_init_rw, mod->init_size_rw) ||
31342 ++ within(addr, mod->module_core_rx, mod->core_size_rx) ||
31343 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
31344 + const char *sym;
31345 +
31346 + sym = get_ksymbol(mod, addr, size, offset);
31347 +@@ -2270,7 +2425,7 @@ static int m_show(struct seq_file *m, vo
31348 + char buf[8];
31349 +
31350 + seq_printf(m, "%s %lu",
31351 +- mod->name, mod->init_size + mod->core_size);
31352 ++ mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
31353 + print_unload_info(m, mod);
31354 +
31355 + /* Informative for users. */
31356 +@@ -2279,7 +2434,7 @@ static int m_show(struct seq_file *m, vo
31357 + mod->state == MODULE_STATE_COMING ? "Loading":
31358 + "Live");
31359 + /* Used by oprofile and other similar tools. */
31360 +- seq_printf(m, " 0x%p", mod->module_core);
31361 ++ seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
31362 +
31363 + /* Taints info */
31364 + if (mod->taints)
31365 +@@ -2335,7 +2490,8 @@ int is_module_address(unsigned long addr
31366 + preempt_disable();
31367 +
31368 + list_for_each_entry(mod, &modules, list) {
31369 +- if (within(addr, mod->module_core, mod->core_size)) {
31370 ++ if (within(addr, mod->module_core_rx, mod->core_size_rx) ||
31371 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
31372 + preempt_enable();
31373 + return 1;
31374 + }
31375 +@@ -2353,8 +2509,8 @@ struct module *__module_text_address(uns
31376 + struct module *mod;
31377 +
31378 + list_for_each_entry(mod, &modules, list)
31379 +- if (within(addr, mod->module_init, mod->init_text_size)
31380 +- || within(addr, mod->module_core, mod->core_text_size))
31381 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx)
31382 ++ || within(addr, mod->module_core_rx, mod->core_size_rx))
31383 + return mod;
31384 + return NULL;
31385 + }
31386 +diff -Nurp linux-2.6.23.15/kernel/mutex.c linux-2.6.23.15-grsec/kernel/mutex.c
31387 +--- linux-2.6.23.15/kernel/mutex.c 2007-10-09 21:31:38.000000000 +0100
31388 ++++ linux-2.6.23.15-grsec/kernel/mutex.c 2008-02-11 10:37:45.000000000 +0000
31389 +@@ -81,7 +81,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou
31390 + *
31391 + * This function is similar to (but not equivalent to) down().
31392 + */
31393 +-void inline fastcall __sched mutex_lock(struct mutex *lock)
31394 ++inline void fastcall __sched mutex_lock(struct mutex *lock)
31395 + {
31396 + might_sleep();
31397 + /*
31398 +diff -Nurp linux-2.6.23.15/kernel/params.c linux-2.6.23.15-grsec/kernel/params.c
31399 +--- linux-2.6.23.15/kernel/params.c 2008-02-11 10:36:03.000000000 +0000
31400 ++++ linux-2.6.23.15-grsec/kernel/params.c 2008-02-11 10:37:45.000000000 +0000
31401 +@@ -275,7 +275,7 @@ static int param_array(const char *name,
31402 + unsigned int min, unsigned int max,
31403 + void *elem, int elemsize,
31404 + int (*set)(const char *, struct kernel_param *kp),
31405 +- int *num)
31406 ++ unsigned int *num)
31407 + {
31408 + int ret;
31409 + struct kernel_param kp;
31410 +diff -Nurp linux-2.6.23.15/kernel/pid.c linux-2.6.23.15-grsec/kernel/pid.c
31411 +--- linux-2.6.23.15/kernel/pid.c 2007-10-09 21:31:38.000000000 +0100
31412 ++++ linux-2.6.23.15-grsec/kernel/pid.c 2008-02-11 10:37:45.000000000 +0000
31413 +@@ -28,6 +28,7 @@
31414 + #include <linux/hash.h>
31415 + #include <linux/pid_namespace.h>
31416 + #include <linux/init_task.h>
31417 ++#include <linux/grsecurity.h>
31418 +
31419 + #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
31420 + static struct hlist_head *pid_hash;
31421 +@@ -37,7 +38,7 @@ struct pid init_struct_pid = INIT_STRUCT
31422 +
31423 + int pid_max = PID_MAX_DEFAULT;
31424 +
31425 +-#define RESERVED_PIDS 300
31426 ++#define RESERVED_PIDS 500
31427 +
31428 + int pid_max_min = RESERVED_PIDS + 1;
31429 + int pid_max_max = PID_MAX_LIMIT;
31430 +@@ -309,7 +310,14 @@ struct task_struct * fastcall pid_task(s
31431 + */
31432 + struct task_struct *find_task_by_pid_type(int type, int nr)
31433 + {
31434 +- return pid_task(find_pid(nr), type);
31435 ++ struct task_struct *task;
31436 ++
31437 ++ task = pid_task(find_pid(nr), type);
31438 ++
31439 ++ if (gr_pid_is_chrooted(task))
31440 ++ return NULL;
31441 ++
31442 ++ return task;
31443 + }
31444 +
31445 + EXPORT_SYMBOL(find_task_by_pid_type);
31446 +diff -Nurp linux-2.6.23.15/kernel/posix-cpu-timers.c linux-2.6.23.15-grsec/kernel/posix-cpu-timers.c
31447 +--- linux-2.6.23.15/kernel/posix-cpu-timers.c 2007-10-09 21:31:38.000000000 +0100
31448 ++++ linux-2.6.23.15-grsec/kernel/posix-cpu-timers.c 2008-02-11 10:37:45.000000000 +0000
31449 +@@ -6,6 +6,7 @@
31450 + #include <linux/posix-timers.h>
31451 + #include <asm/uaccess.h>
31452 + #include <linux/errno.h>
31453 ++#include <linux/grsecurity.h>
31454 +
31455 + static int check_clock(const clockid_t which_clock)
31456 + {
31457 +@@ -1144,6 +1145,7 @@ static void check_process_timers(struct
31458 + __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
31459 + return;
31460 + }
31461 ++ gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1);
31462 + if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
31463 + /*
31464 + * At the soft limit, send a SIGXCPU every second.
31465 +diff -Nurp linux-2.6.23.15/kernel/power/poweroff.c linux-2.6.23.15-grsec/kernel/power/poweroff.c
31466 +--- linux-2.6.23.15/kernel/power/poweroff.c 2007-10-09 21:31:38.000000000 +0100
31467 ++++ linux-2.6.23.15-grsec/kernel/power/poweroff.c 2008-02-11 10:37:45.000000000 +0000
31468 +@@ -35,7 +35,7 @@ static struct sysrq_key_op sysrq_powerof
31469 + .enable_mask = SYSRQ_ENABLE_BOOT,
31470 + };
31471 +
31472 +-static int pm_sysrq_init(void)
31473 ++static int __init pm_sysrq_init(void)
31474 + {
31475 + register_sysrq_key('o', &sysrq_poweroff_op);
31476 + return 0;
31477 +diff -Nurp linux-2.6.23.15/kernel/printk.c linux-2.6.23.15-grsec/kernel/printk.c
31478 +--- linux-2.6.23.15/kernel/printk.c 2007-10-09 21:31:38.000000000 +0100
31479 ++++ linux-2.6.23.15-grsec/kernel/printk.c 2008-02-11 10:37:45.000000000 +0000
31480 +@@ -31,6 +31,7 @@
31481 + #include <linux/bootmem.h>
31482 + #include <linux/syscalls.h>
31483 + #include <linux/jiffies.h>
31484 ++#include <linux/grsecurity.h>
31485 +
31486 + #include <asm/uaccess.h>
31487 +
31488 +@@ -184,6 +185,11 @@ int do_syslog(int type, char __user *buf
31489 + char c;
31490 + int error = 0;
31491 +
31492 ++#ifdef CONFIG_GRKERNSEC_DMESG
31493 ++ if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
31494 ++ return -EPERM;
31495 ++#endif
31496 ++
31497 + error = security_syslog(type);
31498 + if (error)
31499 + return error;
31500 +diff -Nurp linux-2.6.23.15/kernel/ptrace.c linux-2.6.23.15-grsec/kernel/ptrace.c
31501 +--- linux-2.6.23.15/kernel/ptrace.c 2007-10-09 21:31:38.000000000 +0100
31502 ++++ linux-2.6.23.15-grsec/kernel/ptrace.c 2008-02-11 10:37:45.000000000 +0000
31503 +@@ -19,6 +19,7 @@
31504 + #include <linux/security.h>
31505 + #include <linux/signal.h>
31506 + #include <linux/audit.h>
31507 ++#include <linux/grsecurity.h>
31508 +
31509 + #include <asm/pgtable.h>
31510 + #include <asm/uaccess.h>
31511 +@@ -138,12 +139,12 @@ static int may_attach(struct task_struct
31512 + (current->uid != task->uid) ||
31513 + (current->gid != task->egid) ||
31514 + (current->gid != task->sgid) ||
31515 +- (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
31516 ++ (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
31517 + return -EPERM;
31518 + smp_rmb();
31519 + if (task->mm)
31520 + dumpable = get_dumpable(task->mm);
31521 +- if (!dumpable && !capable(CAP_SYS_PTRACE))
31522 ++ if (!dumpable && !capable_nolog(CAP_SYS_PTRACE))
31523 + return -EPERM;
31524 +
31525 + return security_ptrace(current, task);
31526 +@@ -480,6 +481,11 @@ asmlinkage long sys_ptrace(long request,
31527 + if (ret < 0)
31528 + goto out_put_task_struct;
31529 +
31530 ++ if (gr_handle_ptrace(child, request)) {
31531 ++ ret = -EPERM;
31532 ++ goto out_put_task_struct;
31533 ++ }
31534 ++
31535 + ret = arch_ptrace(child, request, addr, data);
31536 + if (ret < 0)
31537 + goto out_put_task_struct;
31538 +diff -Nurp linux-2.6.23.15/kernel/rcupdate.c linux-2.6.23.15-grsec/kernel/rcupdate.c
31539 +--- linux-2.6.23.15/kernel/rcupdate.c 2007-10-09 21:31:38.000000000 +0100
31540 ++++ linux-2.6.23.15-grsec/kernel/rcupdate.c 2008-02-11 10:37:45.000000000 +0000
31541 +@@ -63,11 +63,11 @@ static struct rcu_ctrlblk rcu_bh_ctrlblk
31542 + .cpumask = CPU_MASK_NONE,
31543 + };
31544 +
31545 +-DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L };
31546 +-DEFINE_PER_CPU(struct rcu_data, rcu_bh_data) = { 0L };
31547 ++DEFINE_PER_CPU(struct rcu_data, rcu_data);
31548 ++DEFINE_PER_CPU(struct rcu_data, rcu_bh_data);
31549 +
31550 + /* Fake initialization required by compiler */
31551 +-static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL};
31552 ++static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet);
31553 + static int blimit = 10;
31554 + static int qhimark = 10000;
31555 + static int qlowmark = 100;
31556 +diff -Nurp linux-2.6.23.15/kernel/relay.c linux-2.6.23.15-grsec/kernel/relay.c
31557 +--- linux-2.6.23.15/kernel/relay.c 2008-02-11 10:36:03.000000000 +0000
31558 ++++ linux-2.6.23.15-grsec/kernel/relay.c 2008-02-11 10:37:45.000000000 +0000
31559 +@@ -1140,7 +1140,7 @@ static int subbuf_splice_actor(struct fi
31560 + return 0;
31561 +
31562 + ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
31563 +- if (ret < 0 || ret < total_len)
31564 ++ if ((int)ret < 0 || ret < total_len)
31565 + return ret;
31566 +
31567 + if (read_start + ret == nonpad_end)
31568 +diff -Nurp linux-2.6.23.15/kernel/resource.c linux-2.6.23.15-grsec/kernel/resource.c
31569 +--- linux-2.6.23.15/kernel/resource.c 2007-10-09 21:31:38.000000000 +0100
31570 ++++ linux-2.6.23.15-grsec/kernel/resource.c 2008-02-11 10:37:45.000000000 +0000
31571 +@@ -133,10 +133,27 @@ static int __init ioresources_init(void)
31572 + {
31573 + struct proc_dir_entry *entry;
31574 +
31575 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
31576 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
31577 ++ entry = create_proc_entry("ioports", S_IRUSR, NULL);
31578 ++#elif CONFIG_GRKERNSEC_PROC_USERGROUP
31579 ++ entry = create_proc_entry("ioports", S_IRUSR | S_IRGRP, NULL);
31580 ++#endif
31581 ++#else
31582 + entry = create_proc_entry("ioports", 0, NULL);
31583 ++#endif
31584 + if (entry)
31585 + entry->proc_fops = &proc_ioports_operations;
31586 ++
31587 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
31588 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
31589 ++ entry = create_proc_entry("iomem", S_IRUSR, NULL);
31590 ++#elif CONFIG_GRKERNSEC_PROC_USERGROUP
31591 ++ entry = create_proc_entry("iomem", S_IRUSR | S_IRGRP, NULL);
31592 ++#endif
31593 ++#else
31594 + entry = create_proc_entry("iomem", 0, NULL);
31595 ++#endif
31596 + if (entry)
31597 + entry->proc_fops = &proc_iomem_operations;
31598 + return 0;
31599 +diff -Nurp linux-2.6.23.15/kernel/sched.c linux-2.6.23.15-grsec/kernel/sched.c
31600 +--- linux-2.6.23.15/kernel/sched.c 2008-02-11 10:36:03.000000000 +0000
31601 ++++ linux-2.6.23.15-grsec/kernel/sched.c 2008-02-11 10:37:45.000000000 +0000
31602 +@@ -61,6 +61,7 @@
31603 + #include <linux/delayacct.h>
31604 + #include <linux/reciprocal_div.h>
31605 + #include <linux/unistd.h>
31606 ++#include <linux/grsecurity.h>
31607 +
31608 + #include <asm/tlb.h>
31609 +
31610 +@@ -3470,7 +3471,7 @@ pick_next_task(struct rq *rq, struct tas
31611 + asmlinkage void __sched schedule(void)
31612 + {
31613 + struct task_struct *prev, *next;
31614 +- long *switch_count;
31615 ++ unsigned long *switch_count;
31616 + struct rq *rq;
31617 + int cpu;
31618 +
31619 +@@ -4079,7 +4080,8 @@ asmlinkage long sys_nice(int increment)
31620 + if (nice > 19)
31621 + nice = 19;
31622 +
31623 +- if (increment < 0 && !can_nice(current, nice))
31624 ++ if (increment < 0 && (!can_nice(current, nice) ||
31625 ++ gr_handle_chroot_nice()))
31626 + return -EPERM;
31627 +
31628 + retval = security_task_setnice(current, nice);
31629 +@@ -5267,7 +5269,7 @@ static struct ctl_table sd_ctl_dir[] = {
31630 + .procname = "sched_domain",
31631 + .mode = 0555,
31632 + },
31633 +- {0,},
31634 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL },
31635 + };
31636 +
31637 + static struct ctl_table sd_ctl_root[] = {
31638 +@@ -5277,7 +5279,7 @@ static struct ctl_table sd_ctl_root[] =
31639 + .mode = 0555,
31640 + .child = sd_ctl_dir,
31641 + },
31642 +- {0,},
31643 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL },
31644 + };
31645 +
31646 + static struct ctl_table *sd_alloc_ctl_entry(int n)
31647 +diff -Nurp linux-2.6.23.15/kernel/signal.c linux-2.6.23.15-grsec/kernel/signal.c
31648 +--- linux-2.6.23.15/kernel/signal.c 2007-10-09 21:31:38.000000000 +0100
31649 ++++ linux-2.6.23.15-grsec/kernel/signal.c 2008-02-11 10:37:45.000000000 +0000
31650 +@@ -25,6 +25,7 @@
31651 + #include <linux/capability.h>
31652 + #include <linux/freezer.h>
31653 + #include <linux/pid_namespace.h>
31654 ++#include <linux/grsecurity.h>
31655 + #include <linux/nsproxy.h>
31656 +
31657 + #include <asm/param.h>
31658 +@@ -541,7 +542,9 @@ static int check_kill_permission(int sig
31659 + && (current->euid ^ t->suid) && (current->euid ^ t->uid)
31660 + && (current->uid ^ t->suid) && (current->uid ^ t->uid)
31661 + && !capable(CAP_KILL))
31662 +- return error;
31663 ++ return error;
31664 ++ if (gr_handle_signal(t, sig))
31665 ++ return error;
31666 + }
31667 +
31668 + return security_task_kill(t, info, sig, 0);
31669 +@@ -758,7 +761,7 @@ static int __init setup_print_fatal_sign
31670 +
31671 + __setup("print-fatal-signals=", setup_print_fatal_signals);
31672 +
31673 +-static int
31674 ++int
31675 + specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
31676 + {
31677 + int ret = 0;
31678 +@@ -812,8 +815,12 @@ force_sig_info(int sig, struct siginfo *
31679 + }
31680 + }
31681 + ret = specific_send_sig_info(sig, info, t);
31682 ++
31683 + spin_unlock_irqrestore(&t->sighand->siglock, flags);
31684 +
31685 ++ gr_log_signal(sig, t);
31686 ++ gr_handle_crash(t, sig);
31687 ++
31688 + return ret;
31689 + }
31690 +
31691 +diff -Nurp linux-2.6.23.15/kernel/softirq.c linux-2.6.23.15-grsec/kernel/softirq.c
31692 +--- linux-2.6.23.15/kernel/softirq.c 2007-10-09 21:31:38.000000000 +0100
31693 ++++ linux-2.6.23.15-grsec/kernel/softirq.c 2008-02-11 10:37:45.000000000 +0000
31694 +@@ -471,9 +471,9 @@ void tasklet_kill(struct tasklet_struct
31695 + printk("Attempt to kill tasklet from interrupt\n");
31696 +
31697 + while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
31698 +- do
31699 ++ do {
31700 + yield();
31701 +- while (test_bit(TASKLET_STATE_SCHED, &t->state));
31702 ++ } while (test_bit(TASKLET_STATE_SCHED, &t->state));
31703 + }
31704 + tasklet_unlock_wait(t);
31705 + clear_bit(TASKLET_STATE_SCHED, &t->state);
31706 +diff -Nurp linux-2.6.23.15/kernel/sys.c linux-2.6.23.15-grsec/kernel/sys.c
31707 +--- linux-2.6.23.15/kernel/sys.c 2007-10-09 21:31:38.000000000 +0100
31708 ++++ linux-2.6.23.15-grsec/kernel/sys.c 2008-02-11 10:37:45.000000000 +0000
31709 +@@ -33,6 +33,7 @@
31710 + #include <linux/task_io_accounting_ops.h>
31711 + #include <linux/seccomp.h>
31712 + #include <linux/cpu.h>
31713 ++#include <linux/grsecurity.h>
31714 +
31715 + #include <linux/compat.h>
31716 + #include <linux/syscalls.h>
31717 +@@ -651,6 +652,12 @@ static int set_one_prio(struct task_stru
31718 + error = -EACCES;
31719 + goto out;
31720 + }
31721 ++
31722 ++ if (gr_handle_chroot_setpriority(p, niceval)) {
31723 ++ error = -EACCES;
31724 ++ goto out;
31725 ++ }
31726 ++
31727 + no_nice = security_task_setnice(p, niceval);
31728 + if (no_nice) {
31729 + error = no_nice;
31730 +@@ -707,10 +714,10 @@ asmlinkage long sys_setpriority(int whic
31731 + if ((who != current->uid) && !(user = find_user(who)))
31732 + goto out_unlock; /* No processes for this user */
31733 +
31734 +- do_each_thread(g, p)
31735 ++ do_each_thread(g, p) {
31736 + if (p->uid == who)
31737 + error = set_one_prio(p, niceval, error);
31738 +- while_each_thread(g, p);
31739 ++ } while_each_thread(g, p);
31740 + if (who != current->uid)
31741 + free_uid(user); /* For find_user() */
31742 + break;
31743 +@@ -769,13 +776,13 @@ asmlinkage long sys_getpriority(int whic
31744 + if ((who != current->uid) && !(user = find_user(who)))
31745 + goto out_unlock; /* No processes for this user */
31746 +
31747 +- do_each_thread(g, p)
31748 ++ do_each_thread(g, p) {
31749 + if (p->uid == who) {
31750 + niceval = 20 - task_nice(p);
31751 + if (niceval > retval)
31752 + retval = niceval;
31753 + }
31754 +- while_each_thread(g, p);
31755 ++ } while_each_thread(g, p);
31756 + if (who != current->uid)
31757 + free_uid(user); /* for find_user() */
31758 + break;
31759 +@@ -1047,6 +1054,9 @@ asmlinkage long sys_setregid(gid_t rgid,
31760 + if (rgid != (gid_t) -1 ||
31761 + (egid != (gid_t) -1 && egid != old_rgid))
31762 + current->sgid = new_egid;
31763 ++
31764 ++ gr_set_role_label(current, current->uid, new_rgid);
31765 ++
31766 + current->fsgid = new_egid;
31767 + current->egid = new_egid;
31768 + current->gid = new_rgid;
31769 +@@ -1074,6 +1084,9 @@ asmlinkage long sys_setgid(gid_t gid)
31770 + set_dumpable(current->mm, suid_dumpable);
31771 + smp_wmb();
31772 + }
31773 ++
31774 ++ gr_set_role_label(current, current->uid, gid);
31775 ++
31776 + current->gid = current->egid = current->sgid = current->fsgid = gid;
31777 + } else if ((gid == current->gid) || (gid == current->sgid)) {
31778 + if (old_egid != gid) {
31779 +@@ -1111,6 +1124,9 @@ static int set_user(uid_t new_ruid, int
31780 + set_dumpable(current->mm, suid_dumpable);
31781 + smp_wmb();
31782 + }
31783 ++
31784 ++ gr_set_role_label(current, new_ruid, current->gid);
31785 ++
31786 + current->uid = new_ruid;
31787 + return 0;
31788 + }
31789 +@@ -1213,6 +1229,9 @@ asmlinkage long sys_setuid(uid_t uid)
31790 + } else if ((uid != current->uid) && (uid != new_suid))
31791 + return -EPERM;
31792 +
31793 ++ if (gr_check_crash_uid(uid))
31794 ++ return -EPERM;
31795 ++
31796 + if (old_euid != uid) {
31797 + set_dumpable(current->mm, suid_dumpable);
31798 + smp_wmb();
31799 +@@ -1315,8 +1334,10 @@ asmlinkage long sys_setresgid(gid_t rgid
31800 + current->egid = egid;
31801 + }
31802 + current->fsgid = current->egid;
31803 +- if (rgid != (gid_t) -1)
31804 ++ if (rgid != (gid_t) -1) {
31805 ++ gr_set_role_label(current, current->uid, rgid);
31806 + current->gid = rgid;
31807 ++ }
31808 + if (sgid != (gid_t) -1)
31809 + current->sgid = sgid;
31810 +
31811 +@@ -1463,7 +1484,10 @@ asmlinkage long sys_setpgid(pid_t pid, p
31812 + write_lock_irq(&tasklist_lock);
31813 +
31814 + err = -ESRCH;
31815 +- p = find_task_by_pid(pid);
31816 ++ /* grsec: replaced find_task_by_pid with equivalent call
31817 ++ which lacks the chroot restriction
31818 ++ */
31819 ++ p = pid_task(find_pid(pid), PIDTYPE_PID);
31820 + if (!p)
31821 + goto out;
31822 +
31823 +@@ -2183,7 +2207,7 @@ asmlinkage long sys_prctl(int option, un
31824 + error = get_dumpable(current->mm);
31825 + break;
31826 + case PR_SET_DUMPABLE:
31827 +- if (arg2 < 0 || arg2 > 1) {
31828 ++ if (arg2 > 1) {
31829 + error = -EINVAL;
31830 + break;
31831 + }
31832 +diff -Nurp linux-2.6.23.15/kernel/sysctl.c linux-2.6.23.15-grsec/kernel/sysctl.c
31833 +--- linux-2.6.23.15/kernel/sysctl.c 2008-02-11 10:36:24.000000000 +0000
31834 ++++ linux-2.6.23.15-grsec/kernel/sysctl.c 2008-02-11 10:37:45.000000000 +0000
31835 +@@ -56,6 +56,13 @@
31836 + #endif
31837 +
31838 + #if defined(CONFIG_SYSCTL)
31839 ++#include <linux/grsecurity.h>
31840 ++#include <linux/grinternal.h>
31841 ++
31842 ++extern __u32 gr_handle_sysctl(const ctl_table *table, const int op);
31843 ++extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
31844 ++ const int op);
31845 ++extern int gr_handle_chroot_sysctl(const int op);
31846 +
31847 + /* External variables not in a header file. */
31848 + extern int C_A_D;
31849 +@@ -141,7 +148,7 @@ static int proc_dointvec_taint(ctl_table
31850 +
31851 + static ctl_table root_table[];
31852 + static struct ctl_table_header root_table_header =
31853 +- { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) };
31854 ++ { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry), 0, NULL };
31855 +
31856 + static ctl_table kern_table[];
31857 + static ctl_table vm_table[];
31858 +@@ -158,11 +165,27 @@ extern ctl_table inotify_table[];
31859 + #ifdef CONFIG_ALPHA_UAC_SYSCTL
31860 + extern ctl_table uac_table[];
31861 + #endif
31862 ++extern ctl_table grsecurity_table[];
31863 +
31864 + #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
31865 + int sysctl_legacy_va_layout;
31866 + #endif
31867 +
31868 ++#ifdef CONFIG_PAX_SOFTMODE
31869 ++static ctl_table pax_table[] = {
31870 ++ {
31871 ++ .ctl_name = CTL_UNNUMBERED,
31872 ++ .procname = "softmode",
31873 ++ .data = &pax_softmode,
31874 ++ .maxlen = sizeof(unsigned int),
31875 ++ .mode = 0600,
31876 ++ .proc_handler = &proc_dointvec,
31877 ++ },
31878 ++
31879 ++ { .ctl_name = 0 }
31880 ++};
31881 ++#endif
31882 ++
31883 + extern int prove_locking;
31884 + extern int lock_stat;
31885 +
31886 +@@ -207,6 +230,16 @@ static ctl_table root_table[] = {
31887 + .mode = 0555,
31888 + .child = dev_table,
31889 + },
31890 ++
31891 ++#ifdef CONFIG_PAX_SOFTMODE
31892 ++ {
31893 ++ .ctl_name = CTL_UNNUMBERED,
31894 ++ .procname = "pax",
31895 ++ .mode = 0500,
31896 ++ .child = pax_table,
31897 ++ },
31898 ++#endif
31899 ++
31900 + /*
31901 + * NOTE: do not add new entries to this table unless you have read
31902 + * Documentation/sysctl/ctl_unnumbered.txt
31903 +@@ -777,6 +810,14 @@ static ctl_table kern_table[] = {
31904 + .proc_handler = &proc_dostring,
31905 + .strategy = &sysctl_string,
31906 + },
31907 ++#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
31908 ++ {
31909 ++ .ctl_name = KERN_GRSECURITY,
31910 ++ .procname = "grsecurity",
31911 ++ .mode = 0500,
31912 ++ .child = grsecurity_table,
31913 ++ },
31914 ++#endif
31915 + /*
31916 + * NOTE: do not add new entries to this table unless you have read
31917 + * Documentation/sysctl/ctl_unnumbered.txt
31918 +@@ -1388,6 +1429,25 @@ static int test_perm(int mode, int op)
31919 + int sysctl_perm(ctl_table *table, int op)
31920 + {
31921 + int error;
31922 ++ if (table->parent != NULL && table->parent->procname != NULL &&
31923 ++ table->procname != NULL &&
31924 ++ gr_handle_sysctl_mod(table->parent->procname, table->procname, op))
31925 ++ return -EACCES;
31926 ++ if (gr_handle_chroot_sysctl(op))
31927 ++ return -EACCES;
31928 ++ error = gr_handle_sysctl(table, op);
31929 ++ if (error)
31930 ++ return error;
31931 ++ error = security_sysctl(table, op);
31932 ++ if (error)
31933 ++ return error;
31934 ++ return test_perm(table->mode, op);
31935 ++}
31936 ++
31937 ++int sysctl_perm_nochk(ctl_table *table, int op)
31938 ++{
31939 ++ int error;
31940 ++
31941 + error = security_sysctl(table, op);
31942 + if (error)
31943 + return error;
31944 +@@ -1412,13 +1472,14 @@ repeat:
31945 + if (n == table->ctl_name) {
31946 + int error;
31947 + if (table->child) {
31948 +- if (sysctl_perm(table, 001))
31949 ++ if (sysctl_perm_nochk(table, 001))
31950 + return -EPERM;
31951 + name++;
31952 + nlen--;
31953 + table = table->child;
31954 + goto repeat;
31955 + }
31956 ++
31957 + error = do_sysctl_strategy(table, name, nlen,
31958 + oldval, oldlenp,
31959 + newval, newlen);
31960 +diff -Nurp linux-2.6.23.15/kernel/time.c linux-2.6.23.15-grsec/kernel/time.c
31961 +--- linux-2.6.23.15/kernel/time.c 2007-10-09 21:31:38.000000000 +0100
31962 ++++ linux-2.6.23.15-grsec/kernel/time.c 2008-02-11 10:37:45.000000000 +0000
31963 +@@ -35,6 +35,7 @@
31964 + #include <linux/security.h>
31965 + #include <linux/fs.h>
31966 + #include <linux/module.h>
31967 ++#include <linux/grsecurity.h>
31968 +
31969 + #include <asm/uaccess.h>
31970 + #include <asm/unistd.h>
31971 +@@ -92,6 +93,9 @@ asmlinkage long sys_stime(time_t __user
31972 + return err;
31973 +
31974 + do_settimeofday(&tv);
31975 ++
31976 ++ gr_log_timechange();
31977 ++
31978 + return 0;
31979 + }
31980 +
31981 +@@ -197,6 +201,8 @@ asmlinkage long sys_settimeofday(struct
31982 + return -EFAULT;
31983 + }
31984 +
31985 ++ gr_log_timechange();
31986 ++
31987 + return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
31988 + }
31989 +
31990 +@@ -235,7 +241,7 @@ EXPORT_SYMBOL(current_fs_time);
31991 + * Avoid unnecessary multiplications/divisions in the
31992 + * two most common HZ cases:
31993 + */
31994 +-unsigned int inline jiffies_to_msecs(const unsigned long j)
31995 ++inline unsigned int jiffies_to_msecs(const unsigned long j)
31996 + {
31997 + #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
31998 + return (MSEC_PER_SEC / HZ) * j;
31999 +@@ -247,7 +253,7 @@ unsigned int inline jiffies_to_msecs(con
32000 + }
32001 + EXPORT_SYMBOL(jiffies_to_msecs);
32002 +
32003 +-unsigned int inline jiffies_to_usecs(const unsigned long j)
32004 ++inline unsigned int jiffies_to_usecs(const unsigned long j)
32005 + {
32006 + #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
32007 + return (USEC_PER_SEC / HZ) * j;
32008 +diff -Nurp linux-2.6.23.15/kernel/utsname_sysctl.c linux-2.6.23.15-grsec/kernel/utsname_sysctl.c
32009 +--- linux-2.6.23.15/kernel/utsname_sysctl.c 2007-10-09 21:31:38.000000000 +0100
32010 ++++ linux-2.6.23.15-grsec/kernel/utsname_sysctl.c 2008-02-11 10:37:45.000000000 +0000
32011 +@@ -121,7 +121,7 @@ static struct ctl_table uts_kern_table[]
32012 + .proc_handler = proc_do_uts_string,
32013 + .strategy = sysctl_uts_string,
32014 + },
32015 +- {}
32016 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
32017 + };
32018 +
32019 + static struct ctl_table uts_root_table[] = {
32020 +@@ -131,7 +131,7 @@ static struct ctl_table uts_root_table[]
32021 + .mode = 0555,
32022 + .child = uts_kern_table,
32023 + },
32024 +- {}
32025 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
32026 + };
32027 +
32028 + static int __init utsname_sysctl_init(void)
32029 +diff -Nurp linux-2.6.23.15/lib/radix-tree.c linux-2.6.23.15-grsec/lib/radix-tree.c
32030 +--- linux-2.6.23.15/lib/radix-tree.c 2007-10-09 21:31:38.000000000 +0100
32031 ++++ linux-2.6.23.15-grsec/lib/radix-tree.c 2008-02-11 10:37:45.000000000 +0000
32032 +@@ -76,7 +76,7 @@ struct radix_tree_preload {
32033 + int nr;
32034 + struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
32035 + };
32036 +-DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
32037 ++DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, {NULL} };
32038 +
32039 + static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
32040 + {
32041 +diff -Nurp linux-2.6.23.15/mm/filemap.c linux-2.6.23.15-grsec/mm/filemap.c
32042 +--- linux-2.6.23.15/mm/filemap.c 2008-02-11 10:36:03.000000000 +0000
32043 ++++ linux-2.6.23.15-grsec/mm/filemap.c 2008-02-11 10:37:45.000000000 +0000
32044 +@@ -30,6 +30,7 @@
32045 + #include <linux/security.h>
32046 + #include <linux/syscalls.h>
32047 + #include <linux/cpuset.h>
32048 ++#include <linux/grsecurity.h>
32049 + #include "filemap.h"
32050 + #include "internal.h"
32051 +
32052 +@@ -1461,7 +1462,7 @@ int generic_file_mmap(struct file * file
32053 + struct address_space *mapping = file->f_mapping;
32054 +
32055 + if (!mapping->a_ops->readpage)
32056 +- return -ENOEXEC;
32057 ++ return -ENODEV;
32058 + file_accessed(file);
32059 + vma->vm_ops = &generic_file_vm_ops;
32060 + vma->vm_flags |= VM_CAN_NONLINEAR;
32061 +@@ -1726,6 +1727,7 @@ inline int generic_write_checks(struct f
32062 + *pos = i_size_read(inode);
32063 +
32064 + if (limit != RLIM_INFINITY) {
32065 ++ gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
32066 + if (*pos >= limit) {
32067 + send_sig(SIGXFSZ, current, 0);
32068 + return -EFBIG;
32069 +diff -Nurp linux-2.6.23.15/mm/fremap.c linux-2.6.23.15-grsec/mm/fremap.c
32070 +--- linux-2.6.23.15/mm/fremap.c 2007-10-09 21:31:38.000000000 +0100
32071 ++++ linux-2.6.23.15-grsec/mm/fremap.c 2008-02-11 10:37:45.000000000 +0000
32072 +@@ -148,6 +148,13 @@ asmlinkage long sys_remap_file_pages(uns
32073 + retry:
32074 + vma = find_vma(mm, start);
32075 +
32076 ++#ifdef CONFIG_PAX_SEGMEXEC
32077 ++ if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC)) {
32078 ++ up_read(&mm->mmap_sem);
32079 ++ return err;
32080 ++ }
32081 ++#endif
32082 ++
32083 + /*
32084 + * Make sure the vma is shared, that it supports prefaulting,
32085 + * and that the remapped range is valid and fully within
32086 +diff -Nurp linux-2.6.23.15/mm/hugetlb.c linux-2.6.23.15-grsec/mm/hugetlb.c
32087 +--- linux-2.6.23.15/mm/hugetlb.c 2007-10-09 21:31:38.000000000 +0100
32088 ++++ linux-2.6.23.15-grsec/mm/hugetlb.c 2008-02-11 10:37:45.000000000 +0000
32089 +@@ -460,6 +460,26 @@ void unmap_hugepage_range(struct vm_area
32090 + }
32091 + }
32092 +
32093 ++#ifdef CONFIG_PAX_SEGMEXEC
32094 ++static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m)
32095 ++{
32096 ++ struct mm_struct *mm = vma->vm_mm;
32097 ++ struct vm_area_struct *vma_m;
32098 ++ unsigned long address_m;
32099 ++ pte_t *ptep_m;
32100 ++
32101 ++ vma_m = pax_find_mirror_vma(vma);
32102 ++ if (!vma_m)
32103 ++ return;
32104 ++
32105 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
32106 ++ address_m = address + SEGMEXEC_TASK_SIZE;
32107 ++ ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK);
32108 ++ get_page(page_m);
32109 ++ set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0));
32110 ++}
32111 ++#endif
32112 ++
32113 + static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
32114 + unsigned long address, pte_t *ptep, pte_t pte)
32115 + {
32116 +@@ -493,6 +513,11 @@ static int hugetlb_cow(struct mm_struct
32117 + /* Break COW */
32118 + set_huge_pte_at(mm, address, ptep,
32119 + make_huge_pte(vma, new_page, 1));
32120 ++
32121 ++#ifdef CONFIG_PAX_SEGMEXEC
32122 ++ pax_mirror_huge_pte(vma, address, new_page);
32123 ++#endif
32124 ++
32125 + /* Make the old page be freed below */
32126 + new_page = old_page;
32127 + }
32128 +@@ -563,6 +588,10 @@ retry:
32129 + && (vma->vm_flags & VM_SHARED)));
32130 + set_huge_pte_at(mm, address, ptep, new_pte);
32131 +
32132 ++#ifdef CONFIG_PAX_SEGMEXEC
32133 ++ pax_mirror_huge_pte(vma, address, page);
32134 ++#endif
32135 ++
32136 + if (write_access && !(vma->vm_flags & VM_SHARED)) {
32137 + /* Optimization, do the COW without a second fault */
32138 + ret = hugetlb_cow(mm, vma, address, ptep, new_pte);
32139 +@@ -589,6 +618,27 @@ int hugetlb_fault(struct mm_struct *mm,
32140 + int ret;
32141 + static DEFINE_MUTEX(hugetlb_instantiation_mutex);
32142 +
32143 ++#ifdef CONFIG_PAX_SEGMEXEC
32144 ++ struct vm_area_struct *vma_m;
32145 ++
32146 ++ vma_m = pax_find_mirror_vma(vma);
32147 ++ if (vma_m) {
32148 ++ unsigned long address_m;
32149 ++
32150 ++ if (vma->vm_start > vma_m->vm_start) {
32151 ++ address_m = address;
32152 ++ address -= SEGMEXEC_TASK_SIZE;
32153 ++ vma = vma_m;
32154 ++ } else
32155 ++ address_m = address + SEGMEXEC_TASK_SIZE;
32156 ++
32157 ++ if (!huge_pte_alloc(mm, address_m))
32158 ++ return VM_FAULT_OOM;
32159 ++ address_m &= HPAGE_MASK;
32160 ++ unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE);
32161 ++ }
32162 ++#endif
32163 ++
32164 + ptep = huge_pte_alloc(mm, address);
32165 + if (!ptep)
32166 + return VM_FAULT_OOM;
32167 +diff -Nurp linux-2.6.23.15/mm/madvise.c linux-2.6.23.15-grsec/mm/madvise.c
32168 +--- linux-2.6.23.15/mm/madvise.c 2007-10-09 21:31:38.000000000 +0100
32169 ++++ linux-2.6.23.15-grsec/mm/madvise.c 2008-02-11 10:37:45.000000000 +0000
32170 +@@ -43,6 +43,10 @@ static long madvise_behavior(struct vm_a
32171 + pgoff_t pgoff;
32172 + int new_flags = vma->vm_flags;
32173 +
32174 ++#ifdef CONFIG_PAX_SEGMEXEC
32175 ++ struct vm_area_struct *vma_m;
32176 ++#endif
32177 ++
32178 + switch (behavior) {
32179 + case MADV_NORMAL:
32180 + new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
32181 +@@ -92,6 +96,13 @@ success:
32182 + /*
32183 + * vm_flags is protected by the mmap_sem held in write mode.
32184 + */
32185 ++
32186 ++#ifdef CONFIG_PAX_SEGMEXEC
32187 ++ vma_m = pax_find_mirror_vma(vma);
32188 ++ if (vma_m)
32189 ++ vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT);
32190 ++#endif
32191 ++
32192 + vma->vm_flags = new_flags;
32193 +
32194 + out:
32195 +@@ -236,6 +247,17 @@ madvise_vma(struct vm_area_struct *vma,
32196 +
32197 + case MADV_DONTNEED:
32198 + error = madvise_dontneed(vma, prev, start, end);
32199 ++
32200 ++#ifdef CONFIG_PAX_SEGMEXEC
32201 ++ if (!error) {
32202 ++ struct vm_area_struct *vma_m, *prev_m;
32203 ++
32204 ++ vma_m = pax_find_mirror_vma(vma);
32205 ++ if (vma_m)
32206 ++ error = madvise_dontneed(vma_m, &prev_m, start + SEGMEXEC_TASK_SIZE, end + SEGMEXEC_TASK_SIZE);
32207 ++ }
32208 ++#endif
32209 ++
32210 + break;
32211 +
32212 + default:
32213 +@@ -308,6 +330,16 @@ asmlinkage long sys_madvise(unsigned lon
32214 + if (end < start)
32215 + goto out;
32216 +
32217 ++#ifdef CONFIG_PAX_SEGMEXEC
32218 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
32219 ++ if (end > SEGMEXEC_TASK_SIZE)
32220 ++ goto out;
32221 ++ } else
32222 ++#endif
32223 ++
32224 ++ if (end > TASK_SIZE)
32225 ++ goto out;
32226 ++
32227 + error = 0;
32228 + if (end == start)
32229 + goto out;
32230 +diff -Nurp linux-2.6.23.15/mm/memory.c linux-2.6.23.15-grsec/mm/memory.c
32231 +--- linux-2.6.23.15/mm/memory.c 2007-10-09 21:31:38.000000000 +0100
32232 ++++ linux-2.6.23.15-grsec/mm/memory.c 2008-02-11 10:37:45.000000000 +0000
32233 +@@ -50,6 +50,7 @@
32234 + #include <linux/delayacct.h>
32235 + #include <linux/init.h>
32236 + #include <linux/writeback.h>
32237 ++#include <linux/grsecurity.h>
32238 +
32239 + #include <asm/pgalloc.h>
32240 + #include <asm/uaccess.h>
32241 +@@ -993,7 +994,7 @@ int get_user_pages(struct task_struct *t
32242 + struct vm_area_struct *vma;
32243 + unsigned int foll_flags;
32244 +
32245 +- vma = find_extend_vma(mm, start);
32246 ++ vma = find_vma(mm, start);
32247 + if (!vma && in_gate_area(tsk, start)) {
32248 + unsigned long pg = start & PAGE_MASK;
32249 + struct vm_area_struct *gate_vma = get_gate_vma(tsk);
32250 +@@ -1033,7 +1034,7 @@ int get_user_pages(struct task_struct *t
32251 + continue;
32252 + }
32253 +
32254 +- if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP))
32255 ++ if (!vma || start < vma->vm_start || (vma->vm_flags & (VM_IO | VM_PFNMAP))
32256 + || !(vm_flags & vma->vm_flags))
32257 + return i ? : -EFAULT;
32258 +
32259 +@@ -1614,6 +1615,195 @@ static inline void cow_user_page(struct
32260 + copy_user_highpage(dst, src, va, vma);
32261 + }
32262 +
32263 ++#ifdef CONFIG_PAX_SEGMEXEC
32264 ++static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd)
32265 ++{
32266 ++ struct mm_struct *mm = vma->vm_mm;
32267 ++ spinlock_t *ptl;
32268 ++ pte_t *pte, entry;
32269 ++
32270 ++ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
32271 ++ entry = *pte;
32272 ++ if (!pte_present(entry)) {
32273 ++ if (!pte_none(entry)) {
32274 ++ BUG_ON(pte_file(entry));
32275 ++ free_swap_and_cache(pte_to_swp_entry(entry));
32276 ++ pte_clear_not_present_full(mm, address, pte, 0);
32277 ++ }
32278 ++ } else {
32279 ++ struct page *page;
32280 ++
32281 ++ page = vm_normal_page(vma, address, entry);
32282 ++ if (page) {
32283 ++ flush_cache_page(vma, address, pte_pfn(entry));
32284 ++ flush_icache_page(vma, page);
32285 ++ }
32286 ++ ptep_clear_flush(vma, address, pte);
32287 ++ BUG_ON(pte_dirty(entry));
32288 ++ if (page) {
32289 ++ update_hiwater_rss(mm);
32290 ++ if (PageAnon(page))
32291 ++ dec_mm_counter(mm, anon_rss);
32292 ++ else
32293 ++ dec_mm_counter(mm, file_rss);
32294 ++ page_remove_rmap(page, vma);
32295 ++ page_cache_release(page);
32296 ++ }
32297 ++ }
32298 ++ pte_unmap_unlock(pte, ptl);
32299 ++}
32300 ++
32301 ++/* PaX: if vma is mirrored, synchronize the mirror's PTE
32302 ++ *
32303 ++ * the ptl of the lower mapped page is held on entry and is not released on exit
32304 ++ * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
32305 ++ */
32306 ++static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
32307 ++{
32308 ++ struct mm_struct *mm = vma->vm_mm;
32309 ++ unsigned long address_m;
32310 ++ spinlock_t *ptl_m;
32311 ++ struct vm_area_struct *vma_m;
32312 ++ pmd_t *pmd_m;
32313 ++ pte_t *pte_m, entry_m;
32314 ++
32315 ++ BUG_ON(!page_m || !PageAnon(page_m));
32316 ++
32317 ++ vma_m = pax_find_mirror_vma(vma);
32318 ++ if (!vma_m)
32319 ++ return;
32320 ++
32321 ++ BUG_ON(!PageLocked(page_m));
32322 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
32323 ++ address_m = address + SEGMEXEC_TASK_SIZE;
32324 ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
32325 ++ pte_m = pte_offset_map_nested(pmd_m, address_m);
32326 ++ ptl_m = pte_lockptr(mm, pmd_m);
32327 ++ if (ptl != ptl_m) {
32328 ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
32329 ++ if (!pte_none(*pte_m)) {
32330 ++ spin_unlock(ptl_m);
32331 ++ pte_unmap_nested(pte_m);
32332 ++ unlock_page(page_m);
32333 ++ return;
32334 ++ }
32335 ++ }
32336 ++
32337 ++ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
32338 ++ page_cache_get(page_m);
32339 ++ page_add_anon_rmap(page_m, vma_m, address_m);
32340 ++ inc_mm_counter(mm, anon_rss);
32341 ++ set_pte_at(mm, address_m, pte_m, entry_m);
32342 ++ update_mmu_cache(vma_m, address_m, entry_m);
32343 ++ lazy_mmu_prot_update(entry_m);
32344 ++ if (ptl != ptl_m)
32345 ++ spin_unlock(ptl_m);
32346 ++ pte_unmap_nested(pte_m);
32347 ++ unlock_page(page_m);
32348 ++}
32349 ++
32350 ++void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
32351 ++{
32352 ++ struct mm_struct *mm = vma->vm_mm;
32353 ++ unsigned long address_m;
32354 ++ spinlock_t *ptl_m;
32355 ++ struct vm_area_struct *vma_m;
32356 ++ pmd_t *pmd_m;
32357 ++ pte_t *pte_m, entry_m;
32358 ++
32359 ++ BUG_ON(!page_m || PageAnon(page_m));
32360 ++
32361 ++ vma_m = pax_find_mirror_vma(vma);
32362 ++ if (!vma_m)
32363 ++ return;
32364 ++
32365 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
32366 ++ address_m = address + SEGMEXEC_TASK_SIZE;
32367 ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
32368 ++ pte_m = pte_offset_map_nested(pmd_m, address_m);
32369 ++ ptl_m = pte_lockptr(mm, pmd_m);
32370 ++ if (ptl != ptl_m) {
32371 ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
32372 ++ if (!pte_none(*pte_m)) {
32373 ++ spin_unlock(ptl_m);
32374 ++ pte_unmap_nested(pte_m);
32375 ++ return;
32376 ++ }
32377 ++ }
32378 ++
32379 ++ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
32380 ++ page_cache_get(page_m);
32381 ++ page_add_file_rmap(page_m);
32382 ++ inc_mm_counter(mm, file_rss);
32383 ++ set_pte_at(mm, address_m, pte_m, entry_m);
32384 ++ update_mmu_cache(vma_m, address_m, entry_m);
32385 ++ lazy_mmu_prot_update(entry_m);
32386 ++ if (ptl != ptl_m)
32387 ++ spin_unlock(ptl_m);
32388 ++ pte_unmap_nested(pte_m);
32389 ++}
32390 ++
32391 ++static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl)
32392 ++{
32393 ++ struct mm_struct *mm = vma->vm_mm;
32394 ++ unsigned long address_m;
32395 ++ spinlock_t *ptl_m;
32396 ++ struct vm_area_struct *vma_m;
32397 ++ pmd_t *pmd_m;
32398 ++ pte_t *pte_m, entry_m;
32399 ++
32400 ++ vma_m = pax_find_mirror_vma(vma);
32401 ++ if (!vma_m)
32402 ++ return;
32403 ++
32404 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
32405 ++ address_m = address + SEGMEXEC_TASK_SIZE;
32406 ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
32407 ++ pte_m = pte_offset_map_nested(pmd_m, address_m);
32408 ++ ptl_m = pte_lockptr(mm, pmd_m);
32409 ++ if (ptl != ptl_m) {
32410 ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
32411 ++ if (!pte_none(*pte_m)) {
32412 ++ spin_unlock(ptl_m);
32413 ++ pte_unmap_nested(pte_m);
32414 ++ return;
32415 ++ }
32416 ++ }
32417 ++
32418 ++ entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
32419 ++ set_pte_at(mm, address_m, pte_m, entry_m);
32420 ++ if (ptl != ptl_m)
32421 ++ spin_unlock(ptl_m);
32422 ++ pte_unmap_nested(pte_m);
32423 ++}
32424 ++
32425 ++static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, spinlock_t *ptl)
32426 ++{
32427 ++ struct page *page_m;
32428 ++ pte_t entry;
32429 ++
32430 ++ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC))
32431 ++ return;
32432 ++
32433 ++ entry = *pte;
32434 ++ page_m = vm_normal_page(vma, address, entry);
32435 ++ if (!page_m)
32436 ++ pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl);
32437 ++ else if (PageAnon(page_m)) {
32438 ++ if (pax_find_mirror_vma(vma)) {
32439 ++ spin_unlock(ptl);
32440 ++ lock_page(page_m);
32441 ++ spin_lock(ptl);
32442 ++ if (pte_same(entry, *pte))
32443 ++ pax_mirror_anon_pte(vma, address, page_m, ptl);
32444 ++ else
32445 ++ unlock_page(page_m);
32446 ++ }
32447 ++ } else
32448 ++ pax_mirror_file_pte(vma, address, page_m, ptl);
32449 ++}
32450 ++#endif
32451 ++
32452 + /*
32453 + * This routine handles present pages, when users try to write
32454 + * to a shared page. It is done by copying the page to a new address
32455 +@@ -1733,6 +1923,12 @@ gotten:
32456 + */
32457 + page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
32458 + if (likely(pte_same(*page_table, orig_pte))) {
32459 ++
32460 ++#ifdef CONFIG_PAX_SEGMEXEC
32461 ++ if (pax_find_mirror_vma(vma))
32462 ++ BUG_ON(TestSetPageLocked(new_page));
32463 ++#endif
32464 ++
32465 + if (old_page) {
32466 + page_remove_rmap(old_page, vma);
32467 + if (!PageAnon(old_page)) {
32468 +@@ -1757,6 +1953,10 @@ gotten:
32469 + lru_cache_add_active(new_page);
32470 + page_add_new_anon_rmap(new_page, vma, address);
32471 +
32472 ++#ifdef CONFIG_PAX_SEGMEXEC
32473 ++ pax_mirror_anon_pte(vma, address, new_page, ptl);
32474 ++#endif
32475 ++
32476 + /* Free the old page.. */
32477 + new_page = old_page;
32478 + ret |= VM_FAULT_WRITE;
32479 +@@ -2034,6 +2234,7 @@ int vmtruncate(struct inode * inode, lof
32480 +
32481 + do_expand:
32482 + limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
32483 ++ gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
32484 + if (limit != RLIM_INFINITY && offset > limit)
32485 + goto out_sig;
32486 + if (offset > inode->i_sb->s_maxbytes)
32487 +@@ -2216,6 +2417,11 @@ static int do_swap_page(struct mm_struct
32488 + swap_free(entry);
32489 + if (vm_swap_full())
32490 + remove_exclusive_swap_page(page);
32491 ++
32492 ++#ifdef CONFIG_PAX_SEGMEXEC
32493 ++ if (write_access || !pax_find_mirror_vma(vma))
32494 ++#endif
32495 ++
32496 + unlock_page(page);
32497 +
32498 + if (write_access) {
32499 +@@ -2228,6 +2434,11 @@ static int do_swap_page(struct mm_struct
32500 +
32501 + /* No need to invalidate - it was non-present before */
32502 + update_mmu_cache(vma, address, pte);
32503 ++
32504 ++#ifdef CONFIG_PAX_SEGMEXEC
32505 ++ pax_mirror_anon_pte(vma, address, page, ptl);
32506 ++#endif
32507 ++
32508 + unlock:
32509 + pte_unmap_unlock(page_table, ptl);
32510 + out:
32511 +@@ -2268,6 +2479,12 @@ static int do_anonymous_page(struct mm_s
32512 + page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
32513 + if (!pte_none(*page_table))
32514 + goto release;
32515 ++
32516 ++#ifdef CONFIG_PAX_SEGMEXEC
32517 ++ if (pax_find_mirror_vma(vma))
32518 ++ BUG_ON(TestSetPageLocked(page));
32519 ++#endif
32520 ++
32521 + inc_mm_counter(mm, anon_rss);
32522 + lru_cache_add_active(page);
32523 + page_add_new_anon_rmap(page, vma, address);
32524 +@@ -2290,6 +2507,14 @@ static int do_anonymous_page(struct mm_s
32525 + /* No need to invalidate - it was non-present before */
32526 + update_mmu_cache(vma, address, entry);
32527 + lazy_mmu_prot_update(entry);
32528 ++
32529 ++#ifdef CONFIG_PAX_SEGMEXEC
32530 ++ if (write_access)
32531 ++ pax_mirror_anon_pte(vma, address, page, ptl);
32532 ++ else
32533 ++ pax_mirror_file_pte(vma, address, page, ptl);
32534 ++#endif
32535 ++
32536 + unlock:
32537 + pte_unmap_unlock(page_table, ptl);
32538 + return 0;
32539 +@@ -2422,6 +2647,12 @@ static int __do_fault(struct mm_struct *
32540 + */
32541 + /* Only go through if we didn't race with anybody else... */
32542 + if (likely(pte_same(*page_table, orig_pte))) {
32543 ++
32544 ++#ifdef CONFIG_PAX_SEGMEXEC
32545 ++ if (anon && pax_find_mirror_vma(vma))
32546 ++ BUG_ON(TestSetPageLocked(page));
32547 ++#endif
32548 ++
32549 + flush_icache_page(vma, page);
32550 + entry = mk_pte(page, vma->vm_page_prot);
32551 + if (flags & FAULT_FLAG_WRITE)
32552 +@@ -2443,6 +2674,14 @@ static int __do_fault(struct mm_struct *
32553 + /* no need to invalidate: a not-present page won't be cached */
32554 + update_mmu_cache(vma, address, entry);
32555 + lazy_mmu_prot_update(entry);
32556 ++
32557 ++#ifdef CONFIG_PAX_SEGMEXEC
32558 ++ if (anon)
32559 ++ pax_mirror_anon_pte(vma, address, page, ptl);
32560 ++ else
32561 ++ pax_mirror_file_pte(vma, address, page, ptl);
32562 ++#endif
32563 ++
32564 + } else {
32565 + if (anon)
32566 + page_cache_release(page);
32567 +@@ -2522,6 +2761,11 @@ static noinline int do_no_pfn(struct mm_
32568 + if (write_access)
32569 + entry = maybe_mkwrite(pte_mkdirty(entry), vma);
32570 + set_pte_at(mm, address, page_table, entry);
32571 ++
32572 ++#ifdef CONFIG_PAX_SEGMEXEC
32573 ++ pax_mirror_pfn_pte(vma, address, pfn, ptl);
32574 ++#endif
32575 ++
32576 + }
32577 + pte_unmap_unlock(page_table, ptl);
32578 + return 0;
32579 +@@ -2625,6 +2869,11 @@ static inline int handle_pte_fault(struc
32580 + if (write_access)
32581 + flush_tlb_page(vma, address);
32582 + }
32583 ++
32584 ++#ifdef CONFIG_PAX_SEGMEXEC
32585 ++ pax_mirror_pte(vma, address, pte, ptl);
32586 ++#endif
32587 ++
32588 + unlock:
32589 + pte_unmap_unlock(pte, ptl);
32590 + return 0;
32591 +@@ -2641,6 +2890,10 @@ int handle_mm_fault(struct mm_struct *mm
32592 + pmd_t *pmd;
32593 + pte_t *pte;
32594 +
32595 ++#ifdef CONFIG_PAX_SEGMEXEC
32596 ++ struct vm_area_struct *vma_m;
32597 ++#endif
32598 ++
32599 + __set_current_state(TASK_RUNNING);
32600 +
32601 + count_vm_event(PGFAULT);
32602 +@@ -2648,6 +2901,34 @@ int handle_mm_fault(struct mm_struct *mm
32603 + if (unlikely(is_vm_hugetlb_page(vma)))
32604 + return hugetlb_fault(mm, vma, address, write_access);
32605 +
32606 ++#ifdef CONFIG_PAX_SEGMEXEC
32607 ++ vma_m = pax_find_mirror_vma(vma);
32608 ++ if (vma_m) {
32609 ++ unsigned long address_m;
32610 ++ pgd_t *pgd_m;
32611 ++ pud_t *pud_m;
32612 ++ pmd_t *pmd_m;
32613 ++
32614 ++ if (vma->vm_start > vma_m->vm_start) {
32615 ++ address_m = address;
32616 ++ address -= SEGMEXEC_TASK_SIZE;
32617 ++ vma = vma_m;
32618 ++ } else
32619 ++ address_m = address + SEGMEXEC_TASK_SIZE;
32620 ++
32621 ++ pgd_m = pgd_offset(mm, address_m);
32622 ++ pud_m = pud_alloc(mm, pgd_m, address_m);
32623 ++ if (!pud_m)
32624 ++ return VM_FAULT_OOM;
32625 ++ pmd_m = pmd_alloc(mm, pud_m, address_m);
32626 ++ if (!pmd_m)
32627 ++ return VM_FAULT_OOM;
32628 ++ if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
32629 ++ return VM_FAULT_OOM;
32630 ++ pax_unmap_mirror_pte(vma_m, address_m, pmd_m);
32631 ++ }
32632 ++#endif
32633 ++
32634 + pgd = pgd_offset(mm, address);
32635 + pud = pud_alloc(mm, pgd, address);
32636 + if (!pud)
32637 +@@ -2781,7 +3062,7 @@ static int __init gate_vma_init(void)
32638 + gate_vma.vm_start = FIXADDR_USER_START;
32639 + gate_vma.vm_end = FIXADDR_USER_END;
32640 + gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
32641 +- gate_vma.vm_page_prot = __P101;
32642 ++ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
32643 + /*
32644 + * Make sure the vDSO gets into every core dump.
32645 + * Dumping its contents makes post-mortem fully interpretable later
32646 +diff -Nurp linux-2.6.23.15/mm/mempolicy.c linux-2.6.23.15-grsec/mm/mempolicy.c
32647 +--- linux-2.6.23.15/mm/mempolicy.c 2007-10-09 21:31:38.000000000 +0100
32648 ++++ linux-2.6.23.15-grsec/mm/mempolicy.c 2008-02-11 10:37:45.000000000 +0000
32649 +@@ -401,6 +401,10 @@ static int mbind_range(struct vm_area_st
32650 + struct vm_area_struct *next;
32651 + int err;
32652 +
32653 ++#ifdef CONFIG_PAX_SEGMEXEC
32654 ++ struct vm_area_struct *vma_m;
32655 ++#endif
32656 ++
32657 + err = 0;
32658 + for (; vma && vma->vm_start < end; vma = next) {
32659 + next = vma->vm_next;
32660 +@@ -412,6 +416,16 @@ static int mbind_range(struct vm_area_st
32661 + err = policy_vma(vma, new);
32662 + if (err)
32663 + break;
32664 ++
32665 ++#ifdef CONFIG_PAX_SEGMEXEC
32666 ++ vma_m = pax_find_mirror_vma(vma);
32667 ++ if (vma_m) {
32668 ++ err = policy_vma(vma_m, new);
32669 ++ if (err)
32670 ++ break;
32671 ++ }
32672 ++#endif
32673 ++
32674 + }
32675 + return err;
32676 + }
32677 +@@ -732,7 +746,7 @@ static struct page *new_vma_page(struct
32678 + }
32679 + #endif
32680 +
32681 +-long do_mbind(unsigned long start, unsigned long len,
32682 ++static long do_mbind(unsigned long start, unsigned long len,
32683 + unsigned long mode, nodemask_t *nmask, unsigned long flags)
32684 + {
32685 + struct vm_area_struct *vma;
32686 +@@ -760,6 +774,17 @@ long do_mbind(unsigned long start, unsig
32687 +
32688 + if (end < start)
32689 + return -EINVAL;
32690 ++
32691 ++#ifdef CONFIG_PAX_SEGMEXEC
32692 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC) {
32693 ++ if (end > SEGMEXEC_TASK_SIZE)
32694 ++ return -EINVAL;
32695 ++ } else
32696 ++#endif
32697 ++
32698 ++ if (end > TASK_SIZE)
32699 ++ return -EINVAL;
32700 ++
32701 + if (end == start)
32702 + return 0;
32703 +
32704 +diff -Nurp linux-2.6.23.15/mm/mlock.c linux-2.6.23.15-grsec/mm/mlock.c
32705 +--- linux-2.6.23.15/mm/mlock.c 2007-10-09 21:31:38.000000000 +0100
32706 ++++ linux-2.6.23.15-grsec/mm/mlock.c 2008-02-11 10:37:45.000000000 +0000
32707 +@@ -12,6 +12,7 @@
32708 + #include <linux/syscalls.h>
32709 + #include <linux/sched.h>
32710 + #include <linux/module.h>
32711 ++#include <linux/grsecurity.h>
32712 +
32713 + int can_do_mlock(void)
32714 + {
32715 +@@ -95,6 +96,17 @@ static int do_mlock(unsigned long start,
32716 + return -EINVAL;
32717 + if (end == start)
32718 + return 0;
32719 ++
32720 ++#ifdef CONFIG_PAX_SEGMEXEC
32721 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
32722 ++ if (end > SEGMEXEC_TASK_SIZE)
32723 ++ return -EINVAL;
32724 ++ } else
32725 ++#endif
32726 ++
32727 ++ if (end > TASK_SIZE)
32728 ++ return -EINVAL;
32729 ++
32730 + vma = find_vma_prev(current->mm, start, &prev);
32731 + if (!vma || vma->vm_start > start)
32732 + return -ENOMEM;
32733 +@@ -152,6 +164,7 @@ asmlinkage long sys_mlock(unsigned long
32734 + lock_limit >>= PAGE_SHIFT;
32735 +
32736 + /* check against resource limits */
32737 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
32738 + if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
32739 + error = do_mlock(start, len, 1);
32740 + up_write(&current->mm->mmap_sem);
32741 +@@ -173,10 +186,10 @@ asmlinkage long sys_munlock(unsigned lon
32742 + static int do_mlockall(int flags)
32743 + {
32744 + struct vm_area_struct * vma, * prev = NULL;
32745 +- unsigned int def_flags = 0;
32746 ++ unsigned int def_flags = current->mm->def_flags & ~VM_LOCKED;
32747 +
32748 + if (flags & MCL_FUTURE)
32749 +- def_flags = VM_LOCKED;
32750 ++ def_flags |= VM_LOCKED;
32751 + current->mm->def_flags = def_flags;
32752 + if (flags == MCL_FUTURE)
32753 + goto out;
32754 +@@ -184,6 +197,12 @@ static int do_mlockall(int flags)
32755 + for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
32756 + unsigned int newflags;
32757 +
32758 ++#ifdef CONFIG_PAX_SEGMEXEC
32759 ++ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
32760 ++ break;
32761 ++#endif
32762 ++
32763 ++ BUG_ON(vma->vm_end > TASK_SIZE);
32764 + newflags = vma->vm_flags | VM_LOCKED;
32765 + if (!(flags & MCL_CURRENT))
32766 + newflags &= ~VM_LOCKED;
32767 +@@ -213,6 +232,7 @@ asmlinkage long sys_mlockall(int flags)
32768 + lock_limit >>= PAGE_SHIFT;
32769 +
32770 + ret = -ENOMEM;
32771 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
32772 + if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
32773 + capable(CAP_IPC_LOCK))
32774 + ret = do_mlockall(flags);
32775 +diff -Nurp linux-2.6.23.15/mm/mmap.c linux-2.6.23.15-grsec/mm/mmap.c
32776 +--- linux-2.6.23.15/mm/mmap.c 2008-02-11 10:36:03.000000000 +0000
32777 ++++ linux-2.6.23.15-grsec/mm/mmap.c 2008-02-11 10:43:32.000000000 +0000
32778 +@@ -25,6 +25,7 @@
32779 + #include <linux/mount.h>
32780 + #include <linux/mempolicy.h>
32781 + #include <linux/rmap.h>
32782 ++#include <linux/grsecurity.h>
32783 +
32784 + #include <asm/uaccess.h>
32785 + #include <asm/cacheflush.h>
32786 +@@ -35,6 +36,16 @@
32787 + #define arch_mmap_check(addr, len, flags) (0)
32788 + #endif
32789 +
32790 ++static inline void verify_mm_writelocked(struct mm_struct *mm)
32791 ++{
32792 ++#if defined(CONFIG_DEBUG_VM) || defined(CONFIG_PAX)
32793 ++ if (unlikely(down_read_trylock(&mm->mmap_sem))) {
32794 ++ up_read(&mm->mmap_sem);
32795 ++ BUG();
32796 ++ }
32797 ++#endif
32798 ++}
32799 ++
32800 + static void unmap_region(struct mm_struct *mm,
32801 + struct vm_area_struct *vma, struct vm_area_struct *prev,
32802 + unsigned long start, unsigned long end);
32803 +@@ -60,15 +71,23 @@ static void unmap_region(struct mm_struc
32804 + * x: (no) no x: (no) yes x: (no) yes x: (yes) yes
32805 + *
32806 + */
32807 +-pgprot_t protection_map[16] = {
32808 ++pgprot_t protection_map[16] __read_only = {
32809 + __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
32810 + __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
32811 + };
32812 +
32813 + pgprot_t vm_get_page_prot(unsigned long vm_flags)
32814 + {
32815 +- return protection_map[vm_flags &
32816 +- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
32817 ++ pgprot_t prot = protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
32818 ++
32819 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
32820 ++ if (!nx_enabled &&
32821 ++ (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC &&
32822 ++ (vm_flags & (VM_READ | VM_WRITE)))
32823 ++ prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot)))));
32824 ++#endif
32825 ++
32826 ++ return prot;
32827 + }
32828 + EXPORT_SYMBOL(vm_get_page_prot);
32829 +
32830 +@@ -225,6 +244,7 @@ static struct vm_area_struct *remove_vma
32831 + struct vm_area_struct *next = vma->vm_next;
32832 +
32833 + might_sleep();
32834 ++ BUG_ON(vma->vm_mirror);
32835 + if (vma->vm_ops && vma->vm_ops->close)
32836 + vma->vm_ops->close(vma);
32837 + if (vma->vm_file)
32838 +@@ -252,6 +272,7 @@ asmlinkage unsigned long sys_brk(unsigne
32839 + * not page aligned -Ram Gupta
32840 + */
32841 + rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
32842 ++ gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data, 1);
32843 + if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
32844 + goto out;
32845 +
32846 +@@ -352,8 +373,12 @@ find_vma_prepare(struct mm_struct *mm, u
32847 +
32848 + if (vma_tmp->vm_end > addr) {
32849 + vma = vma_tmp;
32850 +- if (vma_tmp->vm_start <= addr)
32851 +- return vma;
32852 ++ if (vma_tmp->vm_start <= addr) {
32853 ++//printk("PAX: prep: %08lx-%08lx %08lx pr:%p l:%p pa:%p ",
32854 ++//vma->vm_start, vma->vm_end, addr, *pprev, *rb_link, *rb_parent);
32855 ++//__print_symbol("%s\n", __builtin_extract_return_addr(__builtin_return_address(0)));
32856 ++ break;
32857 ++ }
32858 + __rb_link = &__rb_parent->rb_left;
32859 + } else {
32860 + rb_prev = __rb_parent;
32861 +@@ -677,6 +702,12 @@ static int
32862 + can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
32863 + struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
32864 + {
32865 ++
32866 ++#ifdef CONFIG_PAX_SEGMEXEC
32867 ++ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE)
32868 ++ return 0;
32869 ++#endif
32870 ++
32871 + if (is_mergeable_vma(vma, file, vm_flags) &&
32872 + is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
32873 + if (vma->vm_pgoff == vm_pgoff)
32874 +@@ -696,6 +727,12 @@ static int
32875 + can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
32876 + struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
32877 + {
32878 ++
32879 ++#ifdef CONFIG_PAX_SEGMEXEC
32880 ++ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE)
32881 ++ return 0;
32882 ++#endif
32883 ++
32884 + if (is_mergeable_vma(vma, file, vm_flags) &&
32885 + is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
32886 + pgoff_t vm_pglen;
32887 +@@ -738,12 +775,19 @@ can_vma_merge_after(struct vm_area_struc
32888 + struct vm_area_struct *vma_merge(struct mm_struct *mm,
32889 + struct vm_area_struct *prev, unsigned long addr,
32890 + unsigned long end, unsigned long vm_flags,
32891 +- struct anon_vma *anon_vma, struct file *file,
32892 ++ struct anon_vma *anon_vma, struct file *file,
32893 + pgoff_t pgoff, struct mempolicy *policy)
32894 + {
32895 + pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
32896 + struct vm_area_struct *area, *next;
32897 +
32898 ++#ifdef CONFIG_PAX_SEGMEXEC
32899 ++ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE;
32900 ++ struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL;
32901 ++
32902 ++ BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end);
32903 ++#endif
32904 ++
32905 + /*
32906 + * We later require that vma->vm_flags == vm_flags,
32907 + * so this tests vma->vm_flags & VM_SPECIAL, too.
32908 +@@ -759,6 +803,15 @@ struct vm_area_struct *vma_merge(struct
32909 + if (next && next->vm_end == end) /* cases 6, 7, 8 */
32910 + next = next->vm_next;
32911 +
32912 ++#ifdef CONFIG_PAX_SEGMEXEC
32913 ++ if (prev)
32914 ++ prev_m = pax_find_mirror_vma(prev);
32915 ++ if (area)
32916 ++ area_m = pax_find_mirror_vma(area);
32917 ++ if (next)
32918 ++ next_m = pax_find_mirror_vma(next);
32919 ++#endif
32920 ++
32921 + /*
32922 + * Can it merge with the predecessor?
32923 + */
32924 +@@ -778,9 +831,24 @@ struct vm_area_struct *vma_merge(struct
32925 + /* cases 1, 6 */
32926 + vma_adjust(prev, prev->vm_start,
32927 + next->vm_end, prev->vm_pgoff, NULL);
32928 +- } else /* cases 2, 5, 7 */
32929 ++
32930 ++#ifdef CONFIG_PAX_SEGMEXEC
32931 ++ if (prev_m)
32932 ++ vma_adjust(prev_m, prev_m->vm_start,
32933 ++ next_m->vm_end, prev_m->vm_pgoff, NULL);
32934 ++#endif
32935 ++
32936 ++ } else { /* cases 2, 5, 7 */
32937 + vma_adjust(prev, prev->vm_start,
32938 + end, prev->vm_pgoff, NULL);
32939 ++
32940 ++#ifdef CONFIG_PAX_SEGMEXEC
32941 ++ if (prev_m)
32942 ++ vma_adjust(prev_m, prev_m->vm_start,
32943 ++ end_m, prev_m->vm_pgoff, NULL);
32944 ++#endif
32945 ++
32946 ++ }
32947 + return prev;
32948 + }
32949 +
32950 +@@ -791,12 +859,27 @@ struct vm_area_struct *vma_merge(struct
32951 + mpol_equal(policy, vma_policy(next)) &&
32952 + can_vma_merge_before(next, vm_flags,
32953 + anon_vma, file, pgoff+pglen)) {
32954 +- if (prev && addr < prev->vm_end) /* case 4 */
32955 ++ if (prev && addr < prev->vm_end) { /* case 4 */
32956 + vma_adjust(prev, prev->vm_start,
32957 + addr, prev->vm_pgoff, NULL);
32958 +- else /* cases 3, 8 */
32959 ++
32960 ++#ifdef CONFIG_PAX_SEGMEXEC
32961 ++ if (prev_m)
32962 ++ vma_adjust(prev_m, prev_m->vm_start,
32963 ++ addr_m, prev_m->vm_pgoff, NULL);
32964 ++#endif
32965 ++
32966 ++ } else { /* cases 3, 8 */
32967 + vma_adjust(area, addr, next->vm_end,
32968 + next->vm_pgoff - pglen, NULL);
32969 ++
32970 ++#ifdef CONFIG_PAX_SEGMEXEC
32971 ++ if (area_m)
32972 ++ vma_adjust(area_m, addr_m, next_m->vm_end,
32973 ++ next_m->vm_pgoff - pglen, NULL);
32974 ++#endif
32975 ++
32976 ++ }
32977 + return area;
32978 + }
32979 +
32980 +@@ -871,14 +954,11 @@ none:
32981 + void vm_stat_account(struct mm_struct *mm, unsigned long flags,
32982 + struct file *file, long pages)
32983 + {
32984 +- const unsigned long stack_flags
32985 +- = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
32986 +-
32987 + if (file) {
32988 + mm->shared_vm += pages;
32989 + if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
32990 + mm->exec_vm += pages;
32991 +- } else if (flags & stack_flags)
32992 ++ } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
32993 + mm->stack_vm += pages;
32994 + if (flags & (VM_RESERVED|VM_IO))
32995 + mm->reserved_vm += pages;
32996 +@@ -906,22 +986,22 @@ unsigned long do_mmap_pgoff(struct file
32997 + * (the exception is when the underlying filesystem is noexec
32998 + * mounted, in which case we dont add PROT_EXEC.)
32999 + */
33000 +- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
33001 ++ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
33002 + if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
33003 + prot |= PROT_EXEC;
33004 +
33005 + if (!len)
33006 + return -EINVAL;
33007 +
33008 +- error = arch_mmap_check(addr, len, flags);
33009 +- if (error)
33010 +- return error;
33011 +-
33012 + /* Careful about overflows.. */
33013 + len = PAGE_ALIGN(len);
33014 + if (!len || len > TASK_SIZE)
33015 + return -ENOMEM;
33016 +
33017 ++ error = arch_mmap_check(addr, len, flags);
33018 ++ if (error)
33019 ++ return error;
33020 ++
33021 + /* offset overflow? */
33022 + if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
33023 + return -EOVERFLOW;
33024 +@@ -933,7 +1013,7 @@ unsigned long do_mmap_pgoff(struct file
33025 + /* Obtain the address to map to. we verify (or select) it and ensure
33026 + * that it represents a valid section of the address space.
33027 + */
33028 +- addr = get_unmapped_area(file, addr, len, pgoff, flags);
33029 ++ addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
33030 + if (addr & ~PAGE_MASK)
33031 + return addr;
33032 +
33033 +@@ -944,6 +1024,26 @@ unsigned long do_mmap_pgoff(struct file
33034 + vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
33035 + mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
33036 +
33037 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
33038 ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
33039 ++
33040 ++#ifdef CONFIG_PAX_MPROTECT
33041 ++ if (mm->pax_flags & MF_PAX_MPROTECT) {
33042 ++ if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
33043 ++ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
33044 ++ else
33045 ++ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
33046 ++ }
33047 ++#endif
33048 ++
33049 ++ }
33050 ++#endif
33051 ++
33052 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
33053 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file)
33054 ++ vm_flags &= ~VM_PAGEEXEC;
33055 ++#endif
33056 ++
33057 + if (flags & MAP_LOCKED) {
33058 + if (!can_do_mlock())
33059 + return -EPERM;
33060 +@@ -956,6 +1056,7 @@ unsigned long do_mmap_pgoff(struct file
33061 + locked += mm->locked_vm;
33062 + lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
33063 + lock_limit >>= PAGE_SHIFT;
33064 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
33065 + if (locked > lock_limit && !capable(CAP_IPC_LOCK))
33066 + return -EAGAIN;
33067 + }
33068 +@@ -1024,6 +1125,9 @@ unsigned long do_mmap_pgoff(struct file
33069 + if (error)
33070 + return error;
33071 +
33072 ++ if (!gr_acl_handle_mmap(file, prot))
33073 ++ return -EACCES;
33074 ++
33075 + return mmap_region(file, addr, len, flags, vm_flags, pgoff,
33076 + accountable);
33077 + }
33078 +@@ -1037,10 +1141,10 @@ EXPORT_SYMBOL(do_mmap_pgoff);
33079 + */
33080 + int vma_wants_writenotify(struct vm_area_struct *vma)
33081 + {
33082 +- unsigned int vm_flags = vma->vm_flags;
33083 ++ unsigned long vm_flags = vma->vm_flags;
33084 +
33085 + /* If it was private or non-writable, the write bit is already clear */
33086 +- if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED)))
33087 ++ if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED))
33088 + return 0;
33089 +
33090 + /* The backer wishes to know when pages are first written to? */
33091 +@@ -1049,8 +1153,7 @@ int vma_wants_writenotify(struct vm_area
33092 +
33093 + /* The open routine did something to the protections already? */
33094 + if (pgprot_val(vma->vm_page_prot) !=
33095 +- pgprot_val(protection_map[vm_flags &
33096 +- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]))
33097 ++ pgprot_val(vm_get_page_prot(vm_flags)))
33098 + return 0;
33099 +
33100 + /* Specialty mapping? */
33101 +@@ -1076,14 +1179,24 @@ unsigned long mmap_region(struct file *f
33102 + unsigned long charged = 0;
33103 + struct inode *inode = file ? file->f_path.dentry->d_inode : NULL;
33104 +
33105 ++#ifdef CONFIG_PAX_SEGMEXEC
33106 ++ struct vm_area_struct *vma_m = NULL;
33107 ++#endif
33108 ++
33109 ++ /*
33110 ++ * mm->mmap_sem is required to protect against another thread
33111 ++ * changing the mappings in case we sleep.
33112 ++ */
33113 ++ verify_mm_writelocked(mm);
33114 ++
33115 + /* Clear old maps */
33116 + error = -ENOMEM;
33117 +-munmap_back:
33118 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
33119 + if (vma && vma->vm_start < addr + len) {
33120 + if (do_munmap(mm, addr, len))
33121 + return -ENOMEM;
33122 +- goto munmap_back;
33123 ++ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
33124 ++ BUG_ON(vma && vma->vm_start < addr + len);
33125 + }
33126 +
33127 + /* Check against address space limit. */
33128 +@@ -1127,12 +1240,22 @@ munmap_back:
33129 + goto unacct_error;
33130 + }
33131 +
33132 ++#ifdef CONFIG_PAX_SEGMEXEC
33133 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) {
33134 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
33135 ++ if (!vma_m) {
33136 ++ kmem_cache_free(vm_area_cachep, vma);
33137 ++ error = -ENOMEM;
33138 ++ goto unacct_error;
33139 ++ }
33140 ++ }
33141 ++#endif
33142 ++
33143 + vma->vm_mm = mm;
33144 + vma->vm_start = addr;
33145 + vma->vm_end = addr + len;
33146 + vma->vm_flags = vm_flags;
33147 +- vma->vm_page_prot = protection_map[vm_flags &
33148 +- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
33149 ++ vma->vm_page_prot = vm_get_page_prot(vm_flags);
33150 + vma->vm_pgoff = pgoff;
33151 +
33152 + if (file) {
33153 +@@ -1150,6 +1273,14 @@ munmap_back:
33154 + error = file->f_op->mmap(file, vma);
33155 + if (error)
33156 + goto unmap_and_free_vma;
33157 ++
33158 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
33159 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) {
33160 ++ vma->vm_flags |= VM_PAGEEXEC;
33161 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
33162 ++ }
33163 ++#endif
33164 ++
33165 + } else if (vm_flags & VM_SHARED) {
33166 + error = shmem_zero_setup(vma);
33167 + if (error)
33168 +@@ -1174,13 +1305,18 @@ munmap_back:
33169 + vm_flags = vma->vm_flags;
33170 +
33171 + if (vma_wants_writenotify(vma))
33172 +- vma->vm_page_prot =
33173 +- protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
33174 ++ vma->vm_page_prot = vm_get_page_prot(vm_flags & ~VM_SHARED);
33175 +
33176 + if (!file || !vma_merge(mm, prev, addr, vma->vm_end,
33177 + vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) {
33178 + file = vma->vm_file;
33179 + vma_link(mm, vma, prev, rb_link, rb_parent);
33180 ++
33181 ++#ifdef CONFIG_PAX_SEGMEXEC
33182 ++ if (vma_m)
33183 ++ pax_mirror_vma(vma_m, vma);
33184 ++#endif
33185 ++
33186 + if (correct_wcount)
33187 + atomic_inc(&inode->i_writecount);
33188 + } else {
33189 +@@ -1191,10 +1327,12 @@ munmap_back:
33190 + }
33191 + mpol_free(vma_policy(vma));
33192 + kmem_cache_free(vm_area_cachep, vma);
33193 ++ vma = NULL;
33194 + }
33195 + out:
33196 + mm->total_vm += len >> PAGE_SHIFT;
33197 + vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
33198 ++ track_exec_limit(mm, addr, addr + len, vm_flags);
33199 + if (vm_flags & VM_LOCKED) {
33200 + mm->locked_vm += len >> PAGE_SHIFT;
33201 + make_pages_present(addr, addr + len);
33202 +@@ -1213,6 +1351,12 @@ unmap_and_free_vma:
33203 + unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
33204 + charged = 0;
33205 + free_vma:
33206 ++
33207 ++#ifdef CONFIG_PAX_SEGMEXEC
33208 ++ if (vma_m)
33209 ++ kmem_cache_free(vm_area_cachep, vma_m);
33210 ++#endif
33211 ++
33212 + kmem_cache_free(vm_area_cachep, vma);
33213 + unacct_error:
33214 + if (charged)
33215 +@@ -1246,6 +1390,10 @@ arch_get_unmapped_area(struct file *filp
33216 + if (flags & MAP_FIXED)
33217 + return addr;
33218 +
33219 ++#ifdef CONFIG_PAX_RANDMMAP
33220 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
33221 ++#endif
33222 ++
33223 + if (addr) {
33224 + addr = PAGE_ALIGN(addr);
33225 + vma = find_vma(mm, addr);
33226 +@@ -1254,10 +1402,10 @@ arch_get_unmapped_area(struct file *filp
33227 + return addr;
33228 + }
33229 + if (len > mm->cached_hole_size) {
33230 +- start_addr = addr = mm->free_area_cache;
33231 ++ start_addr = addr = mm->free_area_cache;
33232 + } else {
33233 +- start_addr = addr = TASK_UNMAPPED_BASE;
33234 +- mm->cached_hole_size = 0;
33235 ++ start_addr = addr = mm->mmap_base;
33236 ++ mm->cached_hole_size = 0;
33237 + }
33238 +
33239 + full_search:
33240 +@@ -1268,9 +1416,8 @@ full_search:
33241 + * Start a new search - just in case we missed
33242 + * some holes.
33243 + */
33244 +- if (start_addr != TASK_UNMAPPED_BASE) {
33245 +- addr = TASK_UNMAPPED_BASE;
33246 +- start_addr = addr;
33247 ++ if (start_addr != mm->mmap_base) {
33248 ++ start_addr = addr = mm->mmap_base;
33249 + mm->cached_hole_size = 0;
33250 + goto full_search;
33251 + }
33252 +@@ -1292,10 +1439,16 @@ full_search:
33253 +
33254 + void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
33255 + {
33256 ++
33257 ++#ifdef CONFIG_PAX_SEGMEXEC
33258 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
33259 ++ return;
33260 ++#endif
33261 ++
33262 + /*
33263 + * Is this a new hole at the lowest possible address?
33264 + */
33265 +- if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
33266 ++ if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
33267 + mm->free_area_cache = addr;
33268 + mm->cached_hole_size = ~0UL;
33269 + }
33270 +@@ -1313,7 +1466,7 @@ arch_get_unmapped_area_topdown(struct fi
33271 + {
33272 + struct vm_area_struct *vma;
33273 + struct mm_struct *mm = current->mm;
33274 +- unsigned long addr = addr0;
33275 ++ unsigned long base = mm->mmap_base, addr = addr0;
33276 +
33277 + /* requested length too big for entire address space */
33278 + if (len > TASK_SIZE)
33279 +@@ -1322,6 +1475,10 @@ arch_get_unmapped_area_topdown(struct fi
33280 + if (flags & MAP_FIXED)
33281 + return addr;
33282 +
33283 ++#ifdef CONFIG_PAX_RANDMMAP
33284 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
33285 ++#endif
33286 ++
33287 + /* requesting a specific address */
33288 + if (addr) {
33289 + addr = PAGE_ALIGN(addr);
33290 +@@ -1379,13 +1536,21 @@ bottomup:
33291 + * can happen with large stack limits and large mmap()
33292 + * allocations.
33293 + */
33294 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
33295 ++
33296 ++#ifdef CONFIG_PAX_RANDMMAP
33297 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
33298 ++ mm->mmap_base += mm->delta_mmap;
33299 ++#endif
33300 ++
33301 ++ mm->free_area_cache = mm->mmap_base;
33302 + mm->cached_hole_size = ~0UL;
33303 +- mm->free_area_cache = TASK_UNMAPPED_BASE;
33304 + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
33305 + /*
33306 + * Restore the topdown base:
33307 + */
33308 +- mm->free_area_cache = mm->mmap_base;
33309 ++ mm->mmap_base = base;
33310 ++ mm->free_area_cache = base;
33311 + mm->cached_hole_size = ~0UL;
33312 +
33313 + return addr;
33314 +@@ -1394,6 +1559,12 @@ bottomup:
33315 +
33316 + void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
33317 + {
33318 ++
33319 ++#ifdef CONFIG_PAX_SEGMEXEC
33320 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
33321 ++ return;
33322 ++#endif
33323 ++
33324 + /*
33325 + * Is this a new hole at the highest possible address?
33326 + */
33327 +@@ -1401,8 +1572,10 @@ void arch_unmap_area_topdown(struct mm_s
33328 + mm->free_area_cache = addr;
33329 +
33330 + /* dont allow allocations above current base */
33331 +- if (mm->free_area_cache > mm->mmap_base)
33332 ++ if (mm->free_area_cache > mm->mmap_base) {
33333 + mm->free_area_cache = mm->mmap_base;
33334 ++ mm->cached_hole_size = ~0UL;
33335 ++ }
33336 + }
33337 +
33338 + unsigned long
33339 +@@ -1502,6 +1675,32 @@ out:
33340 + return prev ? prev->vm_next : vma;
33341 + }
33342 +
33343 ++#ifdef CONFIG_PAX_SEGMEXEC
33344 ++struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
33345 ++{
33346 ++ struct vm_area_struct *vma_m;
33347 ++
33348 ++ BUG_ON(!vma || vma->vm_start >= vma->vm_end);
33349 ++ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) {
33350 ++ BUG_ON(vma->vm_mirror);
33351 ++ return NULL;
33352 ++ }
33353 ++ BUG_ON(vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < vma->vm_start - SEGMEXEC_TASK_SIZE - 1);
33354 ++ vma_m = vma->vm_mirror;
33355 ++ BUG_ON(!vma_m || vma_m->vm_mirror != vma);
33356 ++ BUG_ON(vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start);
33357 ++ BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff || vma->anon_vma != vma_m->anon_vma);
33358 ++
33359 ++#ifdef CONFIG_PAX_MPROTECT
33360 ++ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED | VM_MAYNOTWRITE));
33361 ++#else
33362 ++ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED));
33363 ++#endif
33364 ++
33365 ++ return vma_m;
33366 ++}
33367 ++#endif
33368 ++
33369 + /*
33370 + * Verify that the stack growth is acceptable and
33371 + * update accounting. This is shared with both the
33372 +@@ -1518,6 +1717,7 @@ static int acct_stack_growth(struct vm_a
33373 + return -ENOMEM;
33374 +
33375 + /* Stack limit test */
33376 ++ gr_learn_resource(current, RLIMIT_STACK, size, 1);
33377 + if (size > rlim[RLIMIT_STACK].rlim_cur)
33378 + return -ENOMEM;
33379 +
33380 +@@ -1527,6 +1727,7 @@ static int acct_stack_growth(struct vm_a
33381 + unsigned long limit;
33382 + locked = mm->locked_vm + grow;
33383 + limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
33384 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
33385 + if (locked > limit && !capable(CAP_IPC_LOCK))
33386 + return -ENOMEM;
33387 + }
33388 +@@ -1562,35 +1763,40 @@ static inline
33389 + #endif
33390 + int expand_upwards(struct vm_area_struct *vma, unsigned long address)
33391 + {
33392 +- int error;
33393 ++ int error, locknext;
33394 +
33395 + if (!(vma->vm_flags & VM_GROWSUP))
33396 + return -EFAULT;
33397 +
33398 ++ /* Also guard against wrapping around to address 0. */
33399 ++ if (address < PAGE_ALIGN(address+1))
33400 ++ address = PAGE_ALIGN(address+1);
33401 ++ else
33402 ++ return -ENOMEM;
33403 ++
33404 + /*
33405 + * We must make sure the anon_vma is allocated
33406 + * so that the anon_vma locking is not a noop.
33407 + */
33408 + if (unlikely(anon_vma_prepare(vma)))
33409 + return -ENOMEM;
33410 ++ locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN);
33411 ++ if (locknext && unlikely(anon_vma_prepare(vma->vm_next)))
33412 ++ return -ENOMEM;
33413 + anon_vma_lock(vma);
33414 ++ if (locknext)
33415 ++ anon_vma_lock(vma->vm_next);
33416 +
33417 + /*
33418 + * vma->vm_start/vm_end cannot change under us because the caller
33419 + * is required to hold the mmap_sem in read mode. We need the
33420 +- * anon_vma lock to serialize against concurrent expand_stacks.
33421 +- * Also guard against wrapping around to address 0.
33422 ++ * anon_vma locks to serialize against concurrent expand_stacks
33423 ++ * and expand_upwards.
33424 + */
33425 +- if (address < PAGE_ALIGN(address+4))
33426 +- address = PAGE_ALIGN(address+4);
33427 +- else {
33428 +- anon_vma_unlock(vma);
33429 +- return -ENOMEM;
33430 +- }
33431 + error = 0;
33432 +
33433 + /* Somebody else might have raced and expanded it already */
33434 +- if (address > vma->vm_end) {
33435 ++ if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) {
33436 + unsigned long size, grow;
33437 +
33438 + size = address - vma->vm_start;
33439 +@@ -1600,6 +1806,8 @@ int expand_upwards(struct vm_area_struct
33440 + if (!error)
33441 + vma->vm_end = address;
33442 + }
33443 ++ if (locknext)
33444 ++ anon_vma_unlock(vma->vm_next);
33445 + anon_vma_unlock(vma);
33446 + return error;
33447 + }
33448 +@@ -1611,7 +1819,8 @@ int expand_upwards(struct vm_area_struct
33449 + static inline int expand_downwards(struct vm_area_struct *vma,
33450 + unsigned long address)
33451 + {
33452 +- int error;
33453 ++ int error, lockprev = 0;
33454 ++ struct vm_area_struct *prev = NULL;
33455 +
33456 + /*
33457 + * We must make sure the anon_vma is allocated
33458 +@@ -1625,6 +1834,15 @@ static inline int expand_downwards(struc
33459 + if (error)
33460 + return error;
33461 +
33462 ++#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
33463 ++ find_vma_prev(address, &prev);
33464 ++ lockprev = prev && (prev->vm_flags & VM_GROWSUP);
33465 ++#endif
33466 ++ if (lockprev && unlikely(anon_vma_prepare(prev)))
33467 ++ return -ENOMEM;
33468 ++ if (lockprev)
33469 ++ anon_vma_lock(prev);
33470 ++
33471 + anon_vma_lock(vma);
33472 +
33473 + /*
33474 +@@ -1634,9 +1852,15 @@ static inline int expand_downwards(struc
33475 + */
33476 +
33477 + /* Somebody else might have raced and expanded it already */
33478 +- if (address < vma->vm_start) {
33479 ++ if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) {
33480 + unsigned long size, grow;
33481 +
33482 ++#ifdef CONFIG_PAX_SEGMEXEC
33483 ++ struct vm_area_struct *vma_m;
33484 ++
33485 ++ vma_m = pax_find_mirror_vma(vma);
33486 ++#endif
33487 ++
33488 + size = vma->vm_end - address;
33489 + grow = (vma->vm_start - address) >> PAGE_SHIFT;
33490 +
33491 +@@ -1644,9 +1868,20 @@ static inline int expand_downwards(struc
33492 + if (!error) {
33493 + vma->vm_start = address;
33494 + vma->vm_pgoff -= grow;
33495 ++ track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
33496 ++
33497 ++#ifdef CONFIG_PAX_SEGMEXEC
33498 ++ if (vma_m) {
33499 ++ vma_m->vm_start -= grow << PAGE_SHIFT;
33500 ++ vma_m->vm_pgoff -= grow;
33501 ++ }
33502 ++#endif
33503 ++
33504 + }
33505 + }
33506 + anon_vma_unlock(vma);
33507 ++ if (lockprev)
33508 ++ anon_vma_unlock(prev);
33509 + return error;
33510 + }
33511 +
33512 +@@ -1718,6 +1953,13 @@ static void remove_vma_list(struct mm_st
33513 + do {
33514 + long nrpages = vma_pages(vma);
33515 +
33516 ++#ifdef CONFIG_PAX_SEGMEXEC
33517 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) {
33518 ++ vma = remove_vma(vma);
33519 ++ continue;
33520 ++ }
33521 ++#endif
33522 ++
33523 + mm->total_vm -= nrpages;
33524 + if (vma->vm_flags & VM_LOCKED)
33525 + mm->locked_vm -= nrpages;
33526 +@@ -1764,6 +2006,16 @@ detach_vmas_to_be_unmapped(struct mm_str
33527 +
33528 + insertion_point = (prev ? &prev->vm_next : &mm->mmap);
33529 + do {
33530 ++
33531 ++#ifdef CONFIG_PAX_SEGMEXEC
33532 ++ if (vma->vm_mirror) {
33533 ++ BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma);
33534 ++ vma->vm_mirror->vm_mirror = NULL;
33535 ++ vma->vm_mirror->vm_flags &= ~VM_EXEC;
33536 ++ vma->vm_mirror = NULL;
33537 ++ }
33538 ++#endif
33539 ++
33540 + rb_erase(&vma->vm_rb, &mm->mm_rb);
33541 + mm->map_count--;
33542 + tail_vma = vma;
33543 +@@ -1783,6 +2035,112 @@ detach_vmas_to_be_unmapped(struct mm_str
33544 + * Split a vma into two pieces at address 'addr', a new vma is allocated
33545 + * either for the first part or the tail.
33546 + */
33547 ++
33548 ++#ifdef CONFIG_PAX_SEGMEXEC
33549 ++int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
33550 ++ unsigned long addr, int new_below)
33551 ++{
33552 ++ struct mempolicy *pol, *pol_m;
33553 ++ struct vm_area_struct *new, *vma_m, *new_m = NULL;
33554 ++ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE;
33555 ++
33556 ++ if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK))
33557 ++ return -EINVAL;
33558 ++
33559 ++ vma_m = pax_find_mirror_vma(vma);
33560 ++ if (vma_m) {
33561 ++ BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE);
33562 ++ if (mm->map_count >= sysctl_max_map_count-1)
33563 ++ return -ENOMEM;
33564 ++ } else if (mm->map_count >= sysctl_max_map_count)
33565 ++ return -ENOMEM;
33566 ++
33567 ++ new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
33568 ++ if (!new)
33569 ++ return -ENOMEM;
33570 ++
33571 ++ if (vma_m) {
33572 ++ new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
33573 ++ if (!new_m) {
33574 ++ kmem_cache_free(vm_area_cachep, new);
33575 ++ return -ENOMEM;
33576 ++ }
33577 ++ }
33578 ++
33579 ++ /* most fields are the same, copy all, and then fixup */
33580 ++ *new = *vma;
33581 ++
33582 ++ if (new_below)
33583 ++ new->vm_end = addr;
33584 ++ else {
33585 ++ new->vm_start = addr;
33586 ++ new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
33587 ++ }
33588 ++
33589 ++ if (vma_m) {
33590 ++ *new_m = *vma_m;
33591 ++ new_m->vm_mirror = new;
33592 ++ new->vm_mirror = new_m;
33593 ++
33594 ++ if (new_below)
33595 ++ new_m->vm_end = addr_m;
33596 ++ else {
33597 ++ new_m->vm_start = addr_m;
33598 ++ new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT);
33599 ++ }
33600 ++ }
33601 ++
33602 ++ pol = mpol_copy(vma_policy(vma));
33603 ++ if (IS_ERR(pol)) {
33604 ++ if (new_m)
33605 ++ kmem_cache_free(vm_area_cachep, new_m);
33606 ++ kmem_cache_free(vm_area_cachep, new);
33607 ++ return PTR_ERR(pol);
33608 ++ }
33609 ++
33610 ++ if (vma_m) {
33611 ++ pol_m = mpol_copy(vma_policy(vma_m));
33612 ++ if (IS_ERR(pol_m)) {
33613 ++ mpol_free(pol);
33614 ++ kmem_cache_free(vm_area_cachep, new_m);
33615 ++ kmem_cache_free(vm_area_cachep, new);
33616 ++ return PTR_ERR(pol);
33617 ++ }
33618 ++ }
33619 ++
33620 ++ vma_set_policy(new, pol);
33621 ++
33622 ++ if (new->vm_file)
33623 ++ get_file(new->vm_file);
33624 ++
33625 ++ if (new->vm_ops && new->vm_ops->open)
33626 ++ new->vm_ops->open(new);
33627 ++
33628 ++ if (new_below)
33629 ++ vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
33630 ++ ((addr - new->vm_start) >> PAGE_SHIFT), new);
33631 ++ else
33632 ++ vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
33633 ++
33634 ++ if (vma_m) {
33635 ++ vma_set_policy(new_m, pol_m);
33636 ++
33637 ++ if (new_m->vm_file)
33638 ++ get_file(new_m->vm_file);
33639 ++
33640 ++ if (new_m->vm_ops && new_m->vm_ops->open)
33641 ++ new_m->vm_ops->open(new_m);
33642 ++
33643 ++ if (new_below)
33644 ++ vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff +
33645 ++ ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m);
33646 ++ else
33647 ++ vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m);
33648 ++ }
33649 ++
33650 ++ return 0;
33651 ++}
33652 ++#else
33653 + int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
33654 + unsigned long addr, int new_below)
33655 + {
33656 +@@ -1830,17 +2188,37 @@ int split_vma(struct mm_struct * mm, str
33657 +
33658 + return 0;
33659 + }
33660 ++#endif
33661 +
33662 + /* Munmap is split into 2 main parts -- this part which finds
33663 + * what needs doing, and the areas themselves, which do the
33664 + * work. This now handles partial unmappings.
33665 + * Jeremy Fitzhardinge <jeremy@××××.org>
33666 + */
33667 ++#ifdef CONFIG_PAX_SEGMEXEC
33668 + int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
33669 + {
33670 ++ int ret = __do_munmap(mm, start, len);
33671 ++ if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC))
33672 ++ return ret;
33673 ++
33674 ++ return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
33675 ++}
33676 ++
33677 ++int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
33678 ++#else
33679 ++int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
33680 ++#endif
33681 ++{
33682 + unsigned long end;
33683 + struct vm_area_struct *vma, *prev, *last;
33684 +
33685 ++ /*
33686 ++ * mm->mmap_sem is required to protect against another thread
33687 ++ * changing the mappings in case we sleep.
33688 ++ */
33689 ++ verify_mm_writelocked(mm);
33690 ++
33691 + if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
33692 + return -EINVAL;
33693 +
33694 +@@ -1890,6 +2268,8 @@ int do_munmap(struct mm_struct *mm, unsi
33695 + /* Fix up all other VM information */
33696 + remove_vma_list(mm, vma);
33697 +
33698 ++ track_exec_limit(mm, start, end, 0UL);
33699 ++
33700 + return 0;
33701 + }
33702 +
33703 +@@ -1902,22 +2282,18 @@ asmlinkage long sys_munmap(unsigned long
33704 +
33705 + profile_munmap(addr);
33706 +
33707 ++#ifdef CONFIG_PAX_SEGMEXEC
33708 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
33709 ++ (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
33710 ++ return -EINVAL;
33711 ++#endif
33712 ++
33713 + down_write(&mm->mmap_sem);
33714 + ret = do_munmap(mm, addr, len);
33715 + up_write(&mm->mmap_sem);
33716 + return ret;
33717 + }
33718 +
33719 +-static inline void verify_mm_writelocked(struct mm_struct *mm)
33720 +-{
33721 +-#ifdef CONFIG_DEBUG_VM
33722 +- if (unlikely(down_read_trylock(&mm->mmap_sem))) {
33723 +- WARN_ON(1);
33724 +- up_read(&mm->mmap_sem);
33725 +- }
33726 +-#endif
33727 +-}
33728 +-
33729 + /*
33730 + * this is really a simplified "do_mmap". it only handles
33731 + * anonymous maps. eventually we may be able to do some
33732 +@@ -1931,6 +2307,11 @@ unsigned long do_brk(unsigned long addr,
33733 + struct rb_node ** rb_link, * rb_parent;
33734 + pgoff_t pgoff = addr >> PAGE_SHIFT;
33735 + int error;
33736 ++ unsigned long charged;
33737 ++
33738 ++#ifdef CONFIG_PAX_SEGMEXEC
33739 ++ struct vm_area_struct *vma_m = NULL;
33740 ++#endif
33741 +
33742 + len = PAGE_ALIGN(len);
33743 + if (!len)
33744 +@@ -1948,19 +2329,34 @@ unsigned long do_brk(unsigned long addr,
33745 +
33746 + flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
33747 +
33748 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
33749 ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
33750 ++ flags &= ~VM_EXEC;
33751 ++
33752 ++#ifdef CONFIG_PAX_MPROTECT
33753 ++ if (mm->pax_flags & MF_PAX_MPROTECT)
33754 ++ flags &= ~VM_MAYEXEC;
33755 ++#endif
33756 ++
33757 ++ }
33758 ++#endif
33759 ++
33760 + error = arch_mmap_check(addr, len, flags);
33761 + if (error)
33762 + return error;
33763 +
33764 ++ charged = len >> PAGE_SHIFT;
33765 ++
33766 + /*
33767 + * mlock MCL_FUTURE?
33768 + */
33769 + if (mm->def_flags & VM_LOCKED) {
33770 + unsigned long locked, lock_limit;
33771 +- locked = len >> PAGE_SHIFT;
33772 ++ locked = charged;
33773 + locked += mm->locked_vm;
33774 + lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
33775 + lock_limit >>= PAGE_SHIFT;
33776 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
33777 + if (locked > lock_limit && !capable(CAP_IPC_LOCK))
33778 + return -EAGAIN;
33779 + }
33780 +@@ -1974,22 +2370,22 @@ unsigned long do_brk(unsigned long addr,
33781 + /*
33782 + * Clear old maps. this also does some error checking for us
33783 + */
33784 +- munmap_back:
33785 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
33786 + if (vma && vma->vm_start < addr + len) {
33787 + if (do_munmap(mm, addr, len))
33788 + return -ENOMEM;
33789 +- goto munmap_back;
33790 ++ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
33791 ++ BUG_ON(vma && vma->vm_start < addr + len);
33792 + }
33793 +
33794 + /* Check against address space limits *after* clearing old maps... */
33795 +- if (!may_expand_vm(mm, len >> PAGE_SHIFT))
33796 ++ if (!may_expand_vm(mm, charged))
33797 + return -ENOMEM;
33798 +
33799 + if (mm->map_count > sysctl_max_map_count)
33800 + return -ENOMEM;
33801 +
33802 +- if (security_vm_enough_memory(len >> PAGE_SHIFT))
33803 ++ if (security_vm_enough_memory(charged))
33804 + return -ENOMEM;
33805 +
33806 + /* Can we just expand an old private anonymous mapping? */
33807 +@@ -2002,24 +2398,41 @@ unsigned long do_brk(unsigned long addr,
33808 + */
33809 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
33810 + if (!vma) {
33811 +- vm_unacct_memory(len >> PAGE_SHIFT);
33812 ++ vm_unacct_memory(charged);
33813 + return -ENOMEM;
33814 + }
33815 +
33816 ++#ifdef CONFIG_PAX_SEGMEXEC
33817 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (flags & VM_EXEC)) {
33818 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
33819 ++ if (!vma_m) {
33820 ++ kmem_cache_free(vm_area_cachep, vma);
33821 ++ vm_unacct_memory(charged);
33822 ++ return -ENOMEM;
33823 ++ }
33824 ++ }
33825 ++#endif
33826 ++
33827 + vma->vm_mm = mm;
33828 + vma->vm_start = addr;
33829 + vma->vm_end = addr + len;
33830 + vma->vm_pgoff = pgoff;
33831 + vma->vm_flags = flags;
33832 +- vma->vm_page_prot = protection_map[flags &
33833 +- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
33834 ++ vma->vm_page_prot = vm_get_page_prot(flags);
33835 + vma_link(mm, vma, prev, rb_link, rb_parent);
33836 ++
33837 ++#ifdef CONFIG_PAX_SEGMEXEC
33838 ++ if (vma_m)
33839 ++ pax_mirror_vma(vma_m, vma);
33840 ++#endif
33841 ++
33842 + out:
33843 +- mm->total_vm += len >> PAGE_SHIFT;
33844 ++ mm->total_vm += charged;
33845 + if (flags & VM_LOCKED) {
33846 +- mm->locked_vm += len >> PAGE_SHIFT;
33847 ++ mm->locked_vm += charged;
33848 + make_pages_present(addr, addr + len);
33849 + }
33850 ++ track_exec_limit(mm, addr, addr + len, flags);
33851 + return addr;
33852 + }
33853 +
33854 +@@ -2050,8 +2463,10 @@ void exit_mmap(struct mm_struct *mm)
33855 + * Walk the list again, actually closing and freeing it,
33856 + * with preemption enabled, without holding any MM locks.
33857 + */
33858 +- while (vma)
33859 ++ while (vma) {
33860 ++ vma->vm_mirror = NULL;
33861 + vma = remove_vma(vma);
33862 ++ }
33863 +
33864 + BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
33865 + }
33866 +@@ -2065,6 +2480,10 @@ int insert_vm_struct(struct mm_struct *
33867 + struct vm_area_struct * __vma, * prev;
33868 + struct rb_node ** rb_link, * rb_parent;
33869 +
33870 ++#ifdef CONFIG_PAX_SEGMEXEC
33871 ++ struct vm_area_struct *vma_m = NULL;
33872 ++#endif
33873 ++
33874 + /*
33875 + * The vm_pgoff of a purely anonymous vma should be irrelevant
33876 + * until its first write fault, when page's anon_vma and index
33877 +@@ -2087,7 +2506,22 @@ int insert_vm_struct(struct mm_struct *
33878 + if ((vma->vm_flags & VM_ACCOUNT) &&
33879 + security_vm_enough_memory_mm(mm, vma_pages(vma)))
33880 + return -ENOMEM;
33881 ++
33882 ++#ifdef CONFIG_PAX_SEGMEXEC
33883 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) {
33884 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
33885 ++ if (!vma_m)
33886 ++ return -ENOMEM;
33887 ++ }
33888 ++#endif
33889 ++
33890 + vma_link(mm, vma, prev, rb_link, rb_parent);
33891 ++
33892 ++#ifdef CONFIG_PAX_SEGMEXEC
33893 ++ if (vma_m)
33894 ++ pax_mirror_vma(vma_m, vma);
33895 ++#endif
33896 ++
33897 + return 0;
33898 + }
33899 +
33900 +@@ -2145,6 +2579,30 @@ struct vm_area_struct *copy_vma(struct v
33901 + return new_vma;
33902 + }
33903 +
33904 ++#ifdef CONFIG_PAX_SEGMEXEC
33905 ++void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma)
33906 ++{
33907 ++ struct vm_area_struct *prev_m;
33908 ++ struct rb_node **rb_link_m, *rb_parent_m;
33909 ++
33910 ++ BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC));
33911 ++ BUG_ON(vma->vm_mirror || vma_m->vm_mirror || vma_policy(vma));
33912 ++ *vma_m = *vma;
33913 ++ vma_m->vm_start += SEGMEXEC_TASK_SIZE;
33914 ++ vma_m->vm_end += SEGMEXEC_TASK_SIZE;
33915 ++ vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED);
33916 ++ vma_m->vm_page_prot = vm_get_page_prot(vma_m->vm_flags);
33917 ++ if (vma_m->vm_file)
33918 ++ get_file(vma_m->vm_file);
33919 ++ if (vma_m->vm_ops && vma_m->vm_ops->open)
33920 ++ vma_m->vm_ops->open(vma_m);
33921 ++ find_vma_prepare(vma->vm_mm, vma_m->vm_start, &prev_m, &rb_link_m, &rb_parent_m);
33922 ++ vma_link(vma->vm_mm, vma_m, prev_m, rb_link_m, rb_parent_m);
33923 ++ vma_m->vm_mirror = vma;
33924 ++ vma->vm_mirror = vma_m;
33925 ++}
33926 ++#endif
33927 ++
33928 + /*
33929 + * Return true if the calling process may expand its vm space by the passed
33930 + * number of pages
33931 +@@ -2155,7 +2613,7 @@ int may_expand_vm(struct mm_struct *mm,
33932 + unsigned long lim;
33933 +
33934 + lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
33935 +-
33936 ++ gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
33937 + if (cur + npages > lim)
33938 + return 0;
33939 + return 1;
33940 +@@ -2167,7 +2625,7 @@ static struct page *special_mapping_nopa
33941 + {
33942 + struct page **pages;
33943 +
33944 +- BUG_ON(address < vma->vm_start || address >= vma->vm_end);
33945 ++ BUG_ON(address < vma->vm_start || address >= vma->vm_end || (address & ~PAGE_MASK));
33946 +
33947 + address -= vma->vm_start;
33948 + for (pages = vma->vm_private_data; address > 0 && *pages; ++pages)
33949 +@@ -2217,8 +2675,17 @@ int install_special_mapping(struct mm_st
33950 + vma->vm_start = addr;
33951 + vma->vm_end = addr + len;
33952 +
33953 ++#ifdef CONFIG_PAX_MPROTECT
33954 ++ if (mm->pax_flags & MF_PAX_MPROTECT) {
33955 ++ if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC)
33956 ++ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
33957 ++ else
33958 ++ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
33959 ++ }
33960 ++#endif
33961 ++
33962 + vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
33963 +- vma->vm_page_prot = protection_map[vma->vm_flags & 7];
33964 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
33965 +
33966 + vma->vm_ops = &special_mapping_vmops;
33967 + vma->vm_private_data = pages;
33968 +diff -Nurp linux-2.6.23.15/mm/mprotect.c linux-2.6.23.15-grsec/mm/mprotect.c
33969 +--- linux-2.6.23.15/mm/mprotect.c 2007-10-09 21:31:38.000000000 +0100
33970 ++++ linux-2.6.23.15-grsec/mm/mprotect.c 2008-02-11 10:37:45.000000000 +0000
33971 +@@ -21,10 +21,17 @@
33972 + #include <linux/syscalls.h>
33973 + #include <linux/swap.h>
33974 + #include <linux/swapops.h>
33975 ++#include <linux/grsecurity.h>
33976 ++
33977 ++#ifdef CONFIG_PAX_MPROTECT
33978 ++#include <linux/elf.h>
33979 ++#endif
33980 ++
33981 + #include <asm/uaccess.h>
33982 + #include <asm/pgtable.h>
33983 + #include <asm/cacheflush.h>
33984 + #include <asm/tlbflush.h>
33985 ++#include <asm/mmu_context.h>
33986 +
33987 + static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
33988 + unsigned long addr, unsigned long end, pgprot_t newprot,
33989 +@@ -128,6 +135,48 @@ static void change_protection(struct vm_
33990 + flush_tlb_range(vma, start, end);
33991 + }
33992 +
33993 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
33994 ++/* called while holding the mmap semaphor for writing except stack expansion */
33995 ++void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
33996 ++{
33997 ++ unsigned long oldlimit, newlimit = 0UL;
33998 ++
33999 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || nx_enabled)
34000 ++ return;
34001 ++
34002 ++ spin_lock(&mm->page_table_lock);
34003 ++ oldlimit = mm->context.user_cs_limit;
34004 ++ if ((prot & VM_EXEC) && oldlimit < end)
34005 ++ /* USER_CS limit moved up */
34006 ++ newlimit = end;
34007 ++ else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
34008 ++ /* USER_CS limit moved down */
34009 ++ newlimit = start;
34010 ++
34011 ++ if (newlimit) {
34012 ++ mm->context.user_cs_limit = newlimit;
34013 ++
34014 ++#ifdef CONFIG_SMP
34015 ++ wmb();
34016 ++ cpus_clear(mm->context.cpu_user_cs_mask);
34017 ++ cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
34018 ++#endif
34019 ++
34020 ++ set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
34021 ++ }
34022 ++ spin_unlock(&mm->page_table_lock);
34023 ++ if (newlimit == end) {
34024 ++ struct vm_area_struct *vma = find_vma(mm, oldlimit);
34025 ++
34026 ++ for (; vma && vma->vm_start < end; vma = vma->vm_next)
34027 ++ if (is_vm_hugetlb_page(vma))
34028 ++ hugetlb_change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
34029 ++ else
34030 ++ change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
34031 ++ }
34032 ++}
34033 ++#endif
34034 ++
34035 + int
34036 + mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
34037 + unsigned long start, unsigned long end, unsigned long newflags)
34038 +@@ -140,11 +189,39 @@ mprotect_fixup(struct vm_area_struct *vm
34039 + int error;
34040 + int dirty_accountable = 0;
34041 +
34042 ++#ifdef CONFIG_PAX_SEGMEXEC
34043 ++ struct vm_area_struct *vma_m = NULL;
34044 ++ unsigned long start_m, end_m;
34045 ++
34046 ++ start_m = start + SEGMEXEC_TASK_SIZE;
34047 ++ end_m = end + SEGMEXEC_TASK_SIZE;
34048 ++#endif
34049 ++
34050 + if (newflags == oldflags) {
34051 + *pprev = vma;
34052 + return 0;
34053 + }
34054 +
34055 ++#ifdef CONFIG_PAX_SEGMEXEC
34056 ++ if (pax_find_mirror_vma(vma) && !(newflags & VM_EXEC)) {
34057 ++ if (start != vma->vm_start) {
34058 ++ error = split_vma(mm, vma, start, 1);
34059 ++ if (error)
34060 ++ return -ENOMEM;
34061 ++ }
34062 ++
34063 ++ if (end != vma->vm_end) {
34064 ++ error = split_vma(mm, vma, end, 0);
34065 ++ if (error)
34066 ++ return -ENOMEM;
34067 ++ }
34068 ++
34069 ++ error = __do_munmap(mm, start_m, end_m - start_m);
34070 ++ if (error)
34071 ++ return -ENOMEM;
34072 ++ }
34073 ++#endif
34074 ++
34075 + /*
34076 + * If we make a private mapping writable we increase our commit;
34077 + * but (without finer accounting) cannot reduce our commit if we
34078 +@@ -187,17 +264,25 @@ mprotect_fixup(struct vm_area_struct *vm
34079 + goto fail;
34080 + }
34081 +
34082 ++#ifdef CONFIG_PAX_SEGMEXEC
34083 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(oldflags & VM_EXEC) && (newflags & VM_EXEC)) {
34084 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
34085 ++ if (!vma_m) {
34086 ++ error = -ENOMEM;
34087 ++ goto fail;
34088 ++ }
34089 ++ }
34090 ++#endif
34091 ++
34092 + success:
34093 + /*
34094 + * vm_flags and vm_page_prot are protected by the mmap_sem
34095 + * held in write mode.
34096 + */
34097 + vma->vm_flags = newflags;
34098 +- vma->vm_page_prot = protection_map[newflags &
34099 +- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
34100 ++ vma->vm_page_prot = vm_get_page_prot(newflags);
34101 + if (vma_wants_writenotify(vma)) {
34102 +- vma->vm_page_prot = protection_map[newflags &
34103 +- (VM_READ|VM_WRITE|VM_EXEC)];
34104 ++ vma->vm_page_prot = vm_get_page_prot(newflags & ~VM_SHARED);
34105 + dirty_accountable = 1;
34106 + }
34107 +
34108 +@@ -205,6 +290,12 @@ success:
34109 + hugetlb_change_protection(vma, start, end, vma->vm_page_prot);
34110 + else
34111 + change_protection(vma, start, end, vma->vm_page_prot, dirty_accountable);
34112 ++
34113 ++#ifdef CONFIG_PAX_SEGMEXEC
34114 ++ if (vma_m)
34115 ++ pax_mirror_vma(vma_m, vma);
34116 ++#endif
34117 ++
34118 + vm_stat_account(mm, oldflags, vma->vm_file, -nrpages);
34119 + vm_stat_account(mm, newflags, vma->vm_file, nrpages);
34120 + return 0;
34121 +@@ -214,6 +305,70 @@ fail:
34122 + return error;
34123 + }
34124 +
34125 ++#ifdef CONFIG_PAX_MPROTECT
34126 ++/* PaX: non-PIC ELF libraries need relocations on their executable segments
34127 ++ * therefore we'll grant them VM_MAYWRITE once during their life.
34128 ++ *
34129 ++ * The checks favour ld-linux.so behaviour which operates on a per ELF segment
34130 ++ * basis because we want to allow the common case and not the special ones.
34131 ++ */
34132 ++static inline void pax_handle_maywrite(struct vm_area_struct *vma, unsigned long start)
34133 ++{
34134 ++ struct elfhdr elf_h;
34135 ++ struct elf_phdr elf_p;
34136 ++ elf_addr_t dyn_offset = 0UL;
34137 ++ elf_dyn dyn;
34138 ++ unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
34139 ++
34140 ++#ifndef CONFIG_PAX_NOELFRELOCS
34141 ++ if ((vma->vm_start != start) ||
34142 ++ !vma->vm_file ||
34143 ++ !(vma->vm_flags & VM_MAYEXEC) ||
34144 ++ (vma->vm_flags & VM_MAYNOTWRITE))
34145 ++#endif
34146 ++
34147 ++ return;
34148 ++
34149 ++ if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) ||
34150 ++ memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
34151 ++
34152 ++#ifdef CONFIG_PAX_ETEXECRELOCS
34153 ++ (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
34154 ++#else
34155 ++ elf_h.e_type != ET_DYN ||
34156 ++#endif
34157 ++
34158 ++ !elf_check_arch(&elf_h) ||
34159 ++ elf_h.e_phentsize != sizeof(struct elf_phdr) ||
34160 ++ elf_h.e_phnum > j)
34161 ++ return;
34162 ++
34163 ++ for (i = 0UL; i < elf_h.e_phnum; i++) {
34164 ++ if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p)))
34165 ++ return;
34166 ++ if (elf_p.p_type == PT_DYNAMIC) {
34167 ++ dyn_offset = elf_p.p_offset;
34168 ++ j = i;
34169 ++ }
34170 ++ }
34171 ++ if (elf_h.e_phnum <= j)
34172 ++ return;
34173 ++
34174 ++ i = 0UL;
34175 ++ do {
34176 ++ if (sizeof(dyn) != kernel_read(vma->vm_file, dyn_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn)))
34177 ++ return;
34178 ++ if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
34179 ++ vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
34180 ++ gr_log_textrel(vma);
34181 ++ return;
34182 ++ }
34183 ++ i++;
34184 ++ } while (dyn.d_tag != DT_NULL);
34185 ++ return;
34186 ++}
34187 ++#endif
34188 ++
34189 + asmlinkage long
34190 + sys_mprotect(unsigned long start, size_t len, unsigned long prot)
34191 + {
34192 +@@ -233,6 +388,17 @@ sys_mprotect(unsigned long start, size_t
34193 + end = start + len;
34194 + if (end <= start)
34195 + return -ENOMEM;
34196 ++
34197 ++#ifdef CONFIG_PAX_SEGMEXEC
34198 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
34199 ++ if (end > SEGMEXEC_TASK_SIZE)
34200 ++ return -EINVAL;
34201 ++ } else
34202 ++#endif
34203 ++
34204 ++ if (end > TASK_SIZE)
34205 ++ return -EINVAL;
34206 ++
34207 + if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
34208 + return -EINVAL;
34209 +
34210 +@@ -240,7 +406,7 @@ sys_mprotect(unsigned long start, size_t
34211 + /*
34212 + * Does the application expect PROT_READ to imply PROT_EXEC:
34213 + */
34214 +- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
34215 ++ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
34216 + prot |= PROT_EXEC;
34217 +
34218 + vm_flags = calc_vm_prot_bits(prot);
34219 +@@ -272,6 +438,16 @@ sys_mprotect(unsigned long start, size_t
34220 + if (start > vma->vm_start)
34221 + prev = vma;
34222 +
34223 ++ if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
34224 ++ error = -EACCES;
34225 ++ goto out;
34226 ++ }
34227 ++
34228 ++#ifdef CONFIG_PAX_MPROTECT
34229 ++ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
34230 ++ pax_handle_maywrite(vma, start);
34231 ++#endif
34232 ++
34233 + for (nstart = start ; ; ) {
34234 + unsigned long newflags;
34235 +
34236 +@@ -285,6 +461,12 @@ sys_mprotect(unsigned long start, size_t
34237 + goto out;
34238 + }
34239 +
34240 ++#ifdef CONFIG_PAX_MPROTECT
34241 ++ /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
34242 ++ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
34243 ++ newflags &= ~VM_MAYWRITE;
34244 ++#endif
34245 ++
34246 + error = security_file_mprotect(vma, reqprot, prot);
34247 + if (error)
34248 + goto out;
34249 +@@ -295,6 +477,9 @@ sys_mprotect(unsigned long start, size_t
34250 + error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
34251 + if (error)
34252 + goto out;
34253 ++
34254 ++ track_exec_limit(current->mm, nstart, tmp, vm_flags);
34255 ++
34256 + nstart = tmp;
34257 +
34258 + if (nstart < prev->vm_end)
34259 +diff -Nurp linux-2.6.23.15/mm/mremap.c linux-2.6.23.15-grsec/mm/mremap.c
34260 +--- linux-2.6.23.15/mm/mremap.c 2007-10-09 21:31:38.000000000 +0100
34261 ++++ linux-2.6.23.15-grsec/mm/mremap.c 2008-02-11 10:37:45.000000000 +0000
34262 +@@ -106,6 +106,12 @@ static void move_ptes(struct vm_area_str
34263 + continue;
34264 + pte = ptep_clear_flush(vma, old_addr, old_pte);
34265 + pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
34266 ++
34267 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
34268 ++ if (!nx_enabled && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC)
34269 ++ pte = pte_exprotect(pte);
34270 ++#endif
34271 ++
34272 + set_pte_at(mm, new_addr, new_pte, pte);
34273 + }
34274 +
34275 +@@ -254,6 +260,7 @@ unsigned long do_mremap(unsigned long ad
34276 + struct vm_area_struct *vma;
34277 + unsigned long ret = -EINVAL;
34278 + unsigned long charged = 0;
34279 ++ unsigned long task_size = TASK_SIZE;
34280 +
34281 + if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
34282 + goto out;
34283 +@@ -272,6 +279,15 @@ unsigned long do_mremap(unsigned long ad
34284 + if (!new_len)
34285 + goto out;
34286 +
34287 ++#ifdef CONFIG_PAX_SEGMEXEC
34288 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
34289 ++ task_size = SEGMEXEC_TASK_SIZE;
34290 ++#endif
34291 ++
34292 ++ if (new_len > task_size || addr > task_size-new_len ||
34293 ++ old_len > task_size || addr > task_size-old_len)
34294 ++ goto out;
34295 ++
34296 + /* new_addr is only valid if MREMAP_FIXED is specified */
34297 + if (flags & MREMAP_FIXED) {
34298 + if (new_addr & ~PAGE_MASK)
34299 +@@ -279,16 +295,13 @@ unsigned long do_mremap(unsigned long ad
34300 + if (!(flags & MREMAP_MAYMOVE))
34301 + goto out;
34302 +
34303 +- if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
34304 ++ if (new_addr > task_size - new_len)
34305 + goto out;
34306 +
34307 + /* Check if the location we're moving into overlaps the
34308 + * old location at all, and fail if it does.
34309 + */
34310 +- if ((new_addr <= addr) && (new_addr+new_len) > addr)
34311 +- goto out;
34312 +-
34313 +- if ((addr <= new_addr) && (addr+old_len) > new_addr)
34314 ++ if (addr + old_len > new_addr && new_addr + new_len > addr)
34315 + goto out;
34316 +
34317 + ret = security_file_mmap(0, 0, 0, 0, new_addr, 1);
34318 +@@ -326,6 +339,14 @@ unsigned long do_mremap(unsigned long ad
34319 + ret = -EINVAL;
34320 + goto out;
34321 + }
34322 ++
34323 ++#ifdef CONFIG_PAX_SEGMEXEC
34324 ++ if (pax_find_mirror_vma(vma)) {
34325 ++ ret = -EINVAL;
34326 ++ goto out;
34327 ++ }
34328 ++#endif
34329 ++
34330 + /* We can't remap across vm area boundaries */
34331 + if (old_len > vma->vm_end - addr)
34332 + goto out;
34333 +@@ -359,7 +380,7 @@ unsigned long do_mremap(unsigned long ad
34334 + if (old_len == vma->vm_end - addr &&
34335 + !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
34336 + (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
34337 +- unsigned long max_addr = TASK_SIZE;
34338 ++ unsigned long max_addr = task_size;
34339 + if (vma->vm_next)
34340 + max_addr = vma->vm_next->vm_start;
34341 + /* can we just expand the current mapping? */
34342 +@@ -377,6 +398,7 @@ unsigned long do_mremap(unsigned long ad
34343 + addr + new_len);
34344 + }
34345 + ret = addr;
34346 ++ track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
34347 + goto out;
34348 + }
34349 + }
34350 +@@ -387,8 +409,8 @@ unsigned long do_mremap(unsigned long ad
34351 + */
34352 + ret = -ENOMEM;
34353 + if (flags & MREMAP_MAYMOVE) {
34354 ++ unsigned long map_flags = 0;
34355 + if (!(flags & MREMAP_FIXED)) {
34356 +- unsigned long map_flags = 0;
34357 + if (vma->vm_flags & VM_MAYSHARE)
34358 + map_flags |= MAP_SHARED;
34359 +
34360 +@@ -403,7 +425,12 @@ unsigned long do_mremap(unsigned long ad
34361 + if (ret)
34362 + goto out;
34363 + }
34364 ++ map_flags = vma->vm_flags;
34365 + ret = move_vma(vma, addr, old_len, new_len, new_addr);
34366 ++ if (!(ret & ~PAGE_MASK)) {
34367 ++ track_exec_limit(current->mm, addr, addr + old_len, 0UL);
34368 ++ track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
34369 ++ }
34370 + }
34371 + out:
34372 + if (ret & ~PAGE_MASK)
34373 +diff -Nurp linux-2.6.23.15/mm/nommu.c linux-2.6.23.15-grsec/mm/nommu.c
34374 +--- linux-2.6.23.15/mm/nommu.c 2007-10-09 21:31:38.000000000 +0100
34375 ++++ linux-2.6.23.15-grsec/mm/nommu.c 2008-02-11 10:37:45.000000000 +0000
34376 +@@ -376,15 +376,6 @@ struct vm_area_struct *find_vma(struct m
34377 + }
34378 + EXPORT_SYMBOL(find_vma);
34379 +
34380 +-/*
34381 +- * find a VMA
34382 +- * - we don't extend stack VMAs under NOMMU conditions
34383 +- */
34384 +-struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
34385 +-{
34386 +- return find_vma(mm, addr);
34387 +-}
34388 +-
34389 + int expand_stack(struct vm_area_struct *vma, unsigned long address)
34390 + {
34391 + return -ENOMEM;
34392 +diff -Nurp linux-2.6.23.15/mm/page_alloc.c linux-2.6.23.15-grsec/mm/page_alloc.c
34393 +--- linux-2.6.23.15/mm/page_alloc.c 2007-10-09 21:31:38.000000000 +0100
34394 ++++ linux-2.6.23.15-grsec/mm/page_alloc.c 2008-02-11 10:37:45.000000000 +0000
34395 +@@ -402,7 +402,7 @@ static inline int page_is_buddy(struct p
34396 + static inline void __free_one_page(struct page *page,
34397 + struct zone *zone, unsigned int order)
34398 + {
34399 +- unsigned long page_idx;
34400 ++ unsigned long page_idx, index;
34401 + int order_size = 1 << order;
34402 +
34403 + if (unlikely(PageCompound(page)))
34404 +@@ -413,6 +413,11 @@ static inline void __free_one_page(struc
34405 + VM_BUG_ON(page_idx & (order_size - 1));
34406 + VM_BUG_ON(bad_range(zone, page));
34407 +
34408 ++#ifdef CONFIG_PAX_MEMORY_SANITIZE
34409 ++ for (index = order_size; index; --index)
34410 ++ sanitize_highpage(page + index - 1);
34411 ++#endif
34412 ++
34413 + __mod_zone_page_state(zone, NR_FREE_PAGES, order_size);
34414 + while (order < MAX_ORDER-1) {
34415 + unsigned long combined_idx;
34416 +diff -Nurp linux-2.6.23.15/mm/rmap.c linux-2.6.23.15-grsec/mm/rmap.c
34417 +--- linux-2.6.23.15/mm/rmap.c 2007-10-09 21:31:38.000000000 +0100
34418 ++++ linux-2.6.23.15-grsec/mm/rmap.c 2008-02-11 10:37:45.000000000 +0000
34419 +@@ -63,6 +63,10 @@ int anon_vma_prepare(struct vm_area_stru
34420 + struct mm_struct *mm = vma->vm_mm;
34421 + struct anon_vma *allocated, *locked;
34422 +
34423 ++#ifdef CONFIG_PAX_SEGMEXEC
34424 ++ struct vm_area_struct *vma_m;
34425 ++#endif
34426 ++
34427 + anon_vma = find_mergeable_anon_vma(vma);
34428 + if (anon_vma) {
34429 + allocated = NULL;
34430 +@@ -79,6 +83,15 @@ int anon_vma_prepare(struct vm_area_stru
34431 + /* page_table_lock to protect against threads */
34432 + spin_lock(&mm->page_table_lock);
34433 + if (likely(!vma->anon_vma)) {
34434 ++
34435 ++#ifdef CONFIG_PAX_SEGMEXEC
34436 ++ vma_m = pax_find_mirror_vma(vma);
34437 ++ if (vma_m) {
34438 ++ vma_m->anon_vma = anon_vma;
34439 ++ __anon_vma_link(vma_m);
34440 ++ }
34441 ++#endif
34442 ++
34443 + vma->anon_vma = anon_vma;
34444 + list_add_tail(&vma->anon_vma_node, &anon_vma->head);
34445 + allocated = NULL;
34446 +diff -Nurp linux-2.6.23.15/mm/shmem.c linux-2.6.23.15-grsec/mm/shmem.c
34447 +--- linux-2.6.23.15/mm/shmem.c 2008-02-11 10:36:03.000000000 +0000
34448 ++++ linux-2.6.23.15-grsec/mm/shmem.c 2008-02-11 10:37:45.000000000 +0000
34449 +@@ -2452,7 +2452,7 @@ static struct file_system_type tmpfs_fs_
34450 + .get_sb = shmem_get_sb,
34451 + .kill_sb = kill_litter_super,
34452 + };
34453 +-static struct vfsmount *shm_mnt;
34454 ++struct vfsmount *shm_mnt;
34455 +
34456 + static int __init init_tmpfs(void)
34457 + {
34458 +diff -Nurp linux-2.6.23.15/mm/slab.c linux-2.6.23.15-grsec/mm/slab.c
34459 +--- linux-2.6.23.15/mm/slab.c 2007-10-09 21:31:38.000000000 +0100
34460 ++++ linux-2.6.23.15-grsec/mm/slab.c 2008-02-11 10:37:45.000000000 +0000
34461 +@@ -306,7 +306,7 @@ struct kmem_list3 {
34462 + * Need this for bootstrapping a per node allocator.
34463 + */
34464 + #define NUM_INIT_LISTS (2 * MAX_NUMNODES + 1)
34465 +-struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
34466 ++struct kmem_list3 initkmem_list3[NUM_INIT_LISTS];
34467 + #define CACHE_CACHE 0
34468 + #define SIZE_AC 1
34469 + #define SIZE_L3 (1 + MAX_NUMNODES)
34470 +@@ -655,14 +655,14 @@ struct cache_names {
34471 + static struct cache_names __initdata cache_names[] = {
34472 + #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
34473 + #include <linux/kmalloc_sizes.h>
34474 +- {NULL,}
34475 ++ {NULL, NULL}
34476 + #undef CACHE
34477 + };
34478 +
34479 + static struct arraycache_init initarray_cache __initdata =
34480 +- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
34481 ++ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
34482 + static struct arraycache_init initarray_generic =
34483 +- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
34484 ++ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
34485 +
34486 + /* internal cache of cache description objs */
34487 + static struct kmem_cache cache_cache = {
34488 +@@ -2980,7 +2980,7 @@ retry:
34489 + * there must be at least one object available for
34490 + * allocation.
34491 + */
34492 +- BUG_ON(slabp->inuse < 0 || slabp->inuse >= cachep->num);
34493 ++ BUG_ON(slabp->inuse >= cachep->num);
34494 +
34495 + while (slabp->inuse < cachep->num && batchcount--) {
34496 + STATS_INC_ALLOCED(cachep);
34497 +diff -Nurp linux-2.6.23.15/mm/slub.c linux-2.6.23.15-grsec/mm/slub.c
34498 +--- linux-2.6.23.15/mm/slub.c 2008-02-11 10:36:03.000000000 +0000
34499 ++++ linux-2.6.23.15-grsec/mm/slub.c 2008-02-11 10:37:45.000000000 +0000
34500 +@@ -1530,7 +1530,7 @@ debug:
34501 + *
34502 + * Otherwise we can simply pick the next object from the lockless free list.
34503 + */
34504 +-static void __always_inline *slab_alloc(struct kmem_cache *s,
34505 ++static __always_inline void *slab_alloc(struct kmem_cache *s,
34506 + gfp_t gfpflags, int node, void *addr)
34507 + {
34508 + struct page *page;
34509 +@@ -1639,7 +1639,7 @@ debug:
34510 + * If fastpath is not possible then fall back to __slab_free where we deal
34511 + * with all sorts of special processing.
34512 + */
34513 +-static void __always_inline slab_free(struct kmem_cache *s,
34514 ++static __always_inline void slab_free(struct kmem_cache *s,
34515 + struct page *page, void *x, void *addr)
34516 + {
34517 + void **object = (void *)x;
34518 +diff -Nurp linux-2.6.23.15/mm/swap.c linux-2.6.23.15-grsec/mm/swap.c
34519 +--- linux-2.6.23.15/mm/swap.c 2007-10-09 21:31:38.000000000 +0100
34520 ++++ linux-2.6.23.15-grsec/mm/swap.c 2008-02-11 10:37:45.000000000 +0000
34521 +@@ -174,8 +174,8 @@ EXPORT_SYMBOL(mark_page_accessed);
34522 + * lru_cache_add: add a page to the page lists
34523 + * @page: the page to add
34524 + */
34525 +-static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, };
34526 +-static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, };
34527 ++static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, 0, {NULL} };
34528 ++static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, 0, {NULL} };
34529 +
34530 + void fastcall lru_cache_add(struct page *page)
34531 + {
34532 +diff -Nurp linux-2.6.23.15/mm/tiny-shmem.c linux-2.6.23.15-grsec/mm/tiny-shmem.c
34533 +--- linux-2.6.23.15/mm/tiny-shmem.c 2007-10-09 21:31:38.000000000 +0100
34534 ++++ linux-2.6.23.15-grsec/mm/tiny-shmem.c 2008-02-11 10:37:45.000000000 +0000
34535 +@@ -26,7 +26,7 @@ static struct file_system_type tmpfs_fs_
34536 + .kill_sb = kill_litter_super,
34537 + };
34538 +
34539 +-static struct vfsmount *shm_mnt;
34540 ++struct vfsmount *shm_mnt;
34541 +
34542 + static int __init init_tmpfs(void)
34543 + {
34544 +diff -Nurp linux-2.6.23.15/mm/vmalloc.c linux-2.6.23.15-grsec/mm/vmalloc.c
34545 +--- linux-2.6.23.15/mm/vmalloc.c 2007-10-09 21:31:38.000000000 +0100
34546 ++++ linux-2.6.23.15-grsec/mm/vmalloc.c 2008-02-11 10:37:45.000000000 +0000
34547 +@@ -201,6 +201,8 @@ static struct vm_struct *__get_vm_area_n
34548 +
34549 + write_lock(&vmlist_lock);
34550 + for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) {
34551 ++ if (addr > end - size)
34552 ++ goto out;
34553 + if ((unsigned long)tmp->addr < addr) {
34554 + if((unsigned long)tmp->addr + tmp->size >= addr)
34555 + addr = ALIGN(tmp->size +
34556 +@@ -212,8 +214,6 @@ static struct vm_struct *__get_vm_area_n
34557 + if (size + addr <= (unsigned long)tmp->addr)
34558 + goto found;
34559 + addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
34560 +- if (addr > end - size)
34561 +- goto out;
34562 + }
34563 +
34564 + found:
34565 +diff -Nurp linux-2.6.23.15/net/core/flow.c linux-2.6.23.15-grsec/net/core/flow.c
34566 +--- linux-2.6.23.15/net/core/flow.c 2007-10-09 21:31:38.000000000 +0100
34567 ++++ linux-2.6.23.15-grsec/net/core/flow.c 2008-02-11 10:37:45.000000000 +0000
34568 +@@ -40,7 +40,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT(
34569 +
34570 + static u32 flow_hash_shift;
34571 + #define flow_hash_size (1 << flow_hash_shift)
34572 +-static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL };
34573 ++static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables);
34574 +
34575 + #define flow_table(cpu) (per_cpu(flow_tables, cpu))
34576 +
34577 +@@ -53,7 +53,7 @@ struct flow_percpu_info {
34578 + u32 hash_rnd;
34579 + int count;
34580 + } ____cacheline_aligned;
34581 +-static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 };
34582 ++static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info);
34583 +
34584 + #define flow_hash_rnd_recalc(cpu) \
34585 + (per_cpu(flow_hash_info, cpu).hash_rnd_recalc)
34586 +@@ -70,7 +70,7 @@ struct flow_flush_info {
34587 + atomic_t cpuleft;
34588 + struct completion completion;
34589 + };
34590 +-static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL };
34591 ++static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets);
34592 +
34593 + #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu))
34594 +
34595 +diff -Nurp linux-2.6.23.15/net/dccp/ccids/ccid3.c linux-2.6.23.15-grsec/net/dccp/ccids/ccid3.c
34596 +--- linux-2.6.23.15/net/dccp/ccids/ccid3.c 2007-10-09 21:31:38.000000000 +0100
34597 ++++ linux-2.6.23.15-grsec/net/dccp/ccids/ccid3.c 2008-02-11 10:37:45.000000000 +0000
34598 +@@ -44,7 +44,7 @@
34599 + static int ccid3_debug;
34600 + #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
34601 + #else
34602 +-#define ccid3_pr_debug(format, a...)
34603 ++#define ccid3_pr_debug(format, a...) do {} while (0)
34604 + #endif
34605 +
34606 + static struct dccp_tx_hist *ccid3_tx_hist;
34607 +diff -Nurp linux-2.6.23.15/net/dccp/dccp.h linux-2.6.23.15-grsec/net/dccp/dccp.h
34608 +--- linux-2.6.23.15/net/dccp/dccp.h 2007-10-09 21:31:38.000000000 +0100
34609 ++++ linux-2.6.23.15-grsec/net/dccp/dccp.h 2008-02-11 10:37:45.000000000 +0000
34610 +@@ -42,8 +42,8 @@ extern int dccp_debug;
34611 + #define dccp_pr_debug(format, a...) DCCP_PR_DEBUG(dccp_debug, format, ##a)
34612 + #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a)
34613 + #else
34614 +-#define dccp_pr_debug(format, a...)
34615 +-#define dccp_pr_debug_cat(format, a...)
34616 ++#define dccp_pr_debug(format, a...) do {} while (0)
34617 ++#define dccp_pr_debug_cat(format, a...) do {} while (0)
34618 + #endif
34619 +
34620 + extern struct inet_hashinfo dccp_hashinfo;
34621 +diff -Nurp linux-2.6.23.15/net/ipv4/inet_connection_sock.c linux-2.6.23.15-grsec/net/ipv4/inet_connection_sock.c
34622 +--- linux-2.6.23.15/net/ipv4/inet_connection_sock.c 2007-10-09 21:31:38.000000000 +0100
34623 ++++ linux-2.6.23.15-grsec/net/ipv4/inet_connection_sock.c 2008-02-11 10:37:45.000000000 +0000
34624 +@@ -15,6 +15,7 @@
34625 +
34626 + #include <linux/module.h>
34627 + #include <linux/jhash.h>
34628 ++#include <linux/grsecurity.h>
34629 +
34630 + #include <net/inet_connection_sock.h>
34631 + #include <net/inet_hashtables.h>
34632 +diff -Nurp linux-2.6.23.15/net/ipv4/inet_hashtables.c linux-2.6.23.15-grsec/net/ipv4/inet_hashtables.c
34633 +--- linux-2.6.23.15/net/ipv4/inet_hashtables.c 2007-10-09 21:31:38.000000000 +0100
34634 ++++ linux-2.6.23.15-grsec/net/ipv4/inet_hashtables.c 2008-02-11 10:37:45.000000000 +0000
34635 +@@ -18,11 +18,14 @@
34636 + #include <linux/sched.h>
34637 + #include <linux/slab.h>
34638 + #include <linux/wait.h>
34639 ++#include <linux/grsecurity.h>
34640 +
34641 + #include <net/inet_connection_sock.h>
34642 + #include <net/inet_hashtables.h>
34643 + #include <net/ip.h>
34644 +
34645 ++extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
34646 ++
34647 + /*
34648 + * Allocate and initialize a new local port bind bucket.
34649 + * The bindhash mutex for snum's hash chain must be held here.
34650 +@@ -338,6 +341,8 @@ ok:
34651 + }
34652 + spin_unlock(&head->lock);
34653 +
34654 ++ gr_update_task_in_ip_table(current, inet_sk(sk));
34655 ++
34656 + if (tw) {
34657 + inet_twsk_deschedule(tw, death_row);
34658 + inet_twsk_put(tw);
34659 +diff -Nurp linux-2.6.23.15/net/ipv4/netfilter/Kconfig linux-2.6.23.15-grsec/net/ipv4/netfilter/Kconfig
34660 +--- linux-2.6.23.15/net/ipv4/netfilter/Kconfig 2007-10-09 21:31:38.000000000 +0100
34661 ++++ linux-2.6.23.15-grsec/net/ipv4/netfilter/Kconfig 2008-02-11 10:37:45.000000000 +0000
34662 +@@ -130,6 +130,21 @@ config IP_NF_MATCH_ADDRTYPE
34663 + If you want to compile it as a module, say M here and read
34664 + <file:Documentation/modules.txt>. If unsure, say `N'.
34665 +
34666 ++config IP_NF_MATCH_STEALTH
34667 ++ tristate "stealth match support"
34668 ++ depends on IP_NF_IPTABLES
34669 ++ help
34670 ++ Enabling this option will drop all syn packets coming to unserved tcp
34671 ++ ports as well as all packets coming to unserved udp ports. If you
34672 ++ are using your system to route any type of packets (ie. via NAT)
34673 ++ you should put this module at the end of your ruleset, since it will
34674 ++ drop packets that aren't going to ports that are listening on your
34675 ++ machine itself, it doesn't take into account that the packet might be
34676 ++ destined for someone on your internal network if you're using NAT for
34677 ++ instance.
34678 ++
34679 ++ To compile it as a module, choose M here. If unsure, say N.
34680 ++
34681 + # `filter', generic and specific targets
34682 + config IP_NF_FILTER
34683 + tristate "Packet filtering"
34684 +@@ -403,4 +418,3 @@ config IP_NF_ARP_MANGLE
34685 + hardware and network addresses.
34686 +
34687 + endmenu
34688 +-
34689 +diff -Nurp linux-2.6.23.15/net/ipv4/netfilter/Makefile linux-2.6.23.15-grsec/net/ipv4/netfilter/Makefile
34690 +--- linux-2.6.23.15/net/ipv4/netfilter/Makefile 2007-10-09 21:31:38.000000000 +0100
34691 ++++ linux-2.6.23.15-grsec/net/ipv4/netfilter/Makefile 2008-02-11 10:37:45.000000000 +0000
34692 +@@ -49,6 +49,7 @@ obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn
34693 + obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
34694 + obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
34695 + obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
34696 ++obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
34697 +
34698 + # targets
34699 + obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
34700 +diff -Nurp linux-2.6.23.15/net/ipv4/netfilter/ipt_stealth.c linux-2.6.23.15-grsec/net/ipv4/netfilter/ipt_stealth.c
34701 +--- linux-2.6.23.15/net/ipv4/netfilter/ipt_stealth.c 1970-01-01 01:00:00.000000000 +0100
34702 ++++ linux-2.6.23.15-grsec/net/ipv4/netfilter/ipt_stealth.c 2008-02-11 10:37:45.000000000 +0000
34703 +@@ -0,0 +1,114 @@
34704 ++/* Kernel module to add stealth support.
34705 ++ *
34706 ++ * Copyright (C) 2002-2006 Brad Spengler <spender@××××××××××.net>
34707 ++ *
34708 ++ */
34709 ++
34710 ++#include <linux/kernel.h>
34711 ++#include <linux/module.h>
34712 ++#include <linux/skbuff.h>
34713 ++#include <linux/net.h>
34714 ++#include <linux/sched.h>
34715 ++#include <linux/inet.h>
34716 ++#include <linux/stddef.h>
34717 ++
34718 ++#include <net/ip.h>
34719 ++#include <net/sock.h>
34720 ++#include <net/tcp.h>
34721 ++#include <net/udp.h>
34722 ++#include <net/route.h>
34723 ++#include <net/inet_common.h>
34724 ++
34725 ++#include <linux/netfilter_ipv4/ip_tables.h>
34726 ++
34727 ++MODULE_LICENSE("GPL");
34728 ++
34729 ++extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
34730 ++
34731 ++static int
34732 ++match(const struct sk_buff *skb,
34733 ++ const struct net_device *in,
34734 ++ const struct net_device *out,
34735 ++ const struct xt_match *match,
34736 ++ const void *matchinfo,
34737 ++ int offset,
34738 ++ unsigned int protoff,
34739 ++ int *hotdrop)
34740 ++{
34741 ++ struct iphdr *ip = ip_hdr(skb);
34742 ++ struct tcphdr th;
34743 ++ struct udphdr uh;
34744 ++ struct sock *sk = NULL;
34745 ++
34746 ++ if (!ip || offset) return 0;
34747 ++
34748 ++ switch(ip->protocol) {
34749 ++ case IPPROTO_TCP:
34750 ++ if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &th, sizeof(th)) < 0) {
34751 ++ *hotdrop = 1;
34752 ++ return 0;
34753 ++ }
34754 ++ if (!(th.syn && !th.ack)) return 0;
34755 ++ sk = inet_lookup_listener(&tcp_hashinfo, ip->daddr, th.dest, inet_iif(skb));
34756 ++ break;
34757 ++ case IPPROTO_UDP:
34758 ++ if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &uh, sizeof(uh)) < 0) {
34759 ++ *hotdrop = 1;
34760 ++ return 0;
34761 ++ }
34762 ++ sk = udp_v4_lookup(ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
34763 ++ break;
34764 ++ default:
34765 ++ return 0;
34766 ++ }
34767 ++
34768 ++ if(!sk) // port is being listened on, match this
34769 ++ return 1;
34770 ++ else {
34771 ++ sock_put(sk);
34772 ++ return 0;
34773 ++ }
34774 ++}
34775 ++
34776 ++/* Called when user tries to insert an entry of this type. */
34777 ++static int
34778 ++checkentry(const char *tablename,
34779 ++ const void *nip,
34780 ++ const struct xt_match *match,
34781 ++ void *matchinfo,
34782 ++ unsigned int hook_mask)
34783 ++{
34784 ++ const struct ipt_ip *ip = (const struct ipt_ip *)nip;
34785 ++
34786 ++ if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
34787 ++ ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
34788 ++ && (hook_mask & (1 << NF_IP_LOCAL_IN)))
34789 ++ return 1;
34790 ++
34791 ++ printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
34792 ++
34793 ++ return 0;
34794 ++}
34795 ++
34796 ++
34797 ++static struct xt_match stealth_match = {
34798 ++ .name = "stealth",
34799 ++ .family = AF_INET,
34800 ++ .match = match,
34801 ++ .checkentry = checkentry,
34802 ++ .destroy = NULL,
34803 ++ .me = THIS_MODULE
34804 ++};
34805 ++
34806 ++static int __init init(void)
34807 ++{
34808 ++ return xt_register_match(&stealth_match);
34809 ++}
34810 ++
34811 ++static void __exit fini(void)
34812 ++{
34813 ++ xt_unregister_match(&stealth_match);
34814 ++}
34815 ++
34816 ++module_init(init);
34817 ++module_exit(fini);
34818 +diff -Nurp linux-2.6.23.15/net/ipv4/tcp.c linux-2.6.23.15-grsec/net/ipv4/tcp.c
34819 +--- linux-2.6.23.15/net/ipv4/tcp.c 2007-10-09 21:31:38.000000000 +0100
34820 ++++ linux-2.6.23.15-grsec/net/ipv4/tcp.c 2008-02-11 10:37:45.000000000 +0000
34821 +@@ -1053,7 +1053,8 @@ int tcp_read_sock(struct sock *sk, read_
34822 + return -ENOTCONN;
34823 + while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) {
34824 + if (offset < skb->len) {
34825 +- size_t used, len;
34826 ++ int used;
34827 ++ size_t len;
34828 +
34829 + len = skb->len - offset;
34830 + /* Stop reading if we hit a patch of urgent data */
34831 +diff -Nurp linux-2.6.23.15/net/ipv4/tcp_ipv4.c linux-2.6.23.15-grsec/net/ipv4/tcp_ipv4.c
34832 +--- linux-2.6.23.15/net/ipv4/tcp_ipv4.c 2007-10-09 21:31:38.000000000 +0100
34833 ++++ linux-2.6.23.15-grsec/net/ipv4/tcp_ipv4.c 2008-02-11 10:37:45.000000000 +0000
34834 +@@ -61,6 +61,7 @@
34835 + #include <linux/jhash.h>
34836 + #include <linux/init.h>
34837 + #include <linux/times.h>
34838 ++#include <linux/grsecurity.h>
34839 +
34840 + #include <net/icmp.h>
34841 + #include <net/inet_hashtables.h>
34842 +diff -Nurp linux-2.6.23.15/net/ipv4/udp.c linux-2.6.23.15-grsec/net/ipv4/udp.c
34843 +--- linux-2.6.23.15/net/ipv4/udp.c 2007-10-09 21:31:38.000000000 +0100
34844 ++++ linux-2.6.23.15-grsec/net/ipv4/udp.c 2008-02-11 10:37:45.000000000 +0000
34845 +@@ -98,12 +98,19 @@
34846 + #include <linux/skbuff.h>
34847 + #include <linux/proc_fs.h>
34848 + #include <linux/seq_file.h>
34849 ++#include <linux/grsecurity.h>
34850 + #include <net/icmp.h>
34851 + #include <net/route.h>
34852 + #include <net/checksum.h>
34853 + #include <net/xfrm.h>
34854 + #include "udp_impl.h"
34855 +
34856 ++extern int gr_search_udp_recvmsg(const struct sock *sk,
34857 ++ const struct sk_buff *skb);
34858 ++extern int gr_search_udp_sendmsg(const struct sock *sk,
34859 ++ const struct sockaddr_in *addr);
34860 ++
34861 ++
34862 + /*
34863 + * Snmp MIB for the UDP layer
34864 + */
34865 +@@ -287,6 +294,13 @@ static struct sock *__udp4_lib_lookup(__
34866 + return result;
34867 + }
34868 +
34869 ++struct sock *udp_v4_lookup(__be32 saddr, __be16 sport,
34870 ++ __be32 daddr, __be16 dport, int dif)
34871 ++{
34872 ++ return __udp4_lib_lookup(saddr, sport, daddr, dport, dif, udp_hash);
34873 ++}
34874 ++
34875 ++
34876 + static inline struct sock *udp_v4_mcast_next(struct sock *sk,
34877 + __be16 loc_port, __be32 loc_addr,
34878 + __be16 rmt_port, __be32 rmt_addr,
34879 +@@ -572,9 +586,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
34880 + dport = usin->sin_port;
34881 + if (dport == 0)
34882 + return -EINVAL;
34883 ++
34884 ++ if (!gr_search_udp_sendmsg(sk, usin))
34885 ++ return -EPERM;
34886 + } else {
34887 + if (sk->sk_state != TCP_ESTABLISHED)
34888 + return -EDESTADDRREQ;
34889 ++
34890 ++ if (!gr_search_udp_sendmsg(sk, NULL))
34891 ++ return -EPERM;
34892 ++
34893 + daddr = inet->daddr;
34894 + dport = inet->dport;
34895 + /* Open fast path for connected socket.
34896 +@@ -834,6 +855,11 @@ try_again:
34897 + if (!skb)
34898 + goto out;
34899 +
34900 ++ if (!gr_search_udp_recvmsg(sk, skb)) {
34901 ++ err = -EPERM;
34902 ++ goto out_free;
34903 ++ }
34904 ++
34905 + ulen = skb->len - sizeof(struct udphdr);
34906 + copied = len;
34907 + if (copied > ulen)
34908 +diff -Nurp linux-2.6.23.15/net/ipv6/exthdrs.c linux-2.6.23.15-grsec/net/ipv6/exthdrs.c
34909 +--- linux-2.6.23.15/net/ipv6/exthdrs.c 2007-10-09 21:31:38.000000000 +0100
34910 ++++ linux-2.6.23.15-grsec/net/ipv6/exthdrs.c 2008-02-11 10:37:45.000000000 +0000
34911 +@@ -645,7 +645,7 @@ static struct tlvtype_proc tlvprochopopt
34912 + .type = IPV6_TLV_JUMBO,
34913 + .func = ipv6_hop_jumbo,
34914 + },
34915 +- { -1, }
34916 ++ { -1, NULL }
34917 + };
34918 +
34919 + int ipv6_parse_hopopts(struct sk_buff **skbp)
34920 +diff -Nurp linux-2.6.23.15/net/ipv6/raw.c linux-2.6.23.15-grsec/net/ipv6/raw.c
34921 +--- linux-2.6.23.15/net/ipv6/raw.c 2007-10-09 21:31:38.000000000 +0100
34922 ++++ linux-2.6.23.15-grsec/net/ipv6/raw.c 2008-02-11 10:37:45.000000000 +0000
34923 +@@ -577,7 +577,7 @@ out:
34924 + return err;
34925 + }
34926 +
34927 +-static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
34928 ++static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
34929 + struct flowi *fl, struct rt6_info *rt,
34930 + unsigned int flags)
34931 + {
34932 +diff -Nurp linux-2.6.23.15/net/irda/ircomm/ircomm_tty.c linux-2.6.23.15-grsec/net/irda/ircomm/ircomm_tty.c
34933 +--- linux-2.6.23.15/net/irda/ircomm/ircomm_tty.c 2007-10-09 21:31:38.000000000 +0100
34934 ++++ linux-2.6.23.15-grsec/net/irda/ircomm/ircomm_tty.c 2008-02-11 10:37:45.000000000 +0000
34935 +@@ -371,7 +371,7 @@ static int ircomm_tty_open(struct tty_st
34936 + IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
34937 +
34938 + line = tty->index;
34939 +- if ((line < 0) || (line >= IRCOMM_TTY_PORTS)) {
34940 ++ if (line >= IRCOMM_TTY_PORTS) {
34941 + return -ENODEV;
34942 + }
34943 +
34944 +diff -Nurp linux-2.6.23.15/net/mac80211/ieee80211.c linux-2.6.23.15-grsec/net/mac80211/ieee80211.c
34945 +--- linux-2.6.23.15/net/mac80211/ieee80211.c 2008-02-11 10:36:03.000000000 +0000
34946 ++++ linux-2.6.23.15-grsec/net/mac80211/ieee80211.c 2008-02-11 10:37:45.000000000 +0000
34947 +@@ -1260,7 +1260,7 @@ __ieee80211_parse_tx_radiotap(
34948 + }
34949 +
34950 +
34951 +-static ieee80211_txrx_result inline
34952 ++static inline ieee80211_txrx_result
34953 + __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
34954 + struct sk_buff *skb,
34955 + struct net_device *dev,
34956 +@@ -1332,7 +1332,7 @@ __ieee80211_tx_prepare(struct ieee80211_
34957 + return res;
34958 + }
34959 +
34960 +-static int inline is_ieee80211_device(struct net_device *dev,
34961 ++static inline int is_ieee80211_device(struct net_device *dev,
34962 + struct net_device *master)
34963 + {
34964 + return (wdev_priv(dev->ieee80211_ptr) ==
34965 +@@ -1341,7 +1341,7 @@ static int inline is_ieee80211_device(st
34966 +
34967 + /* Device in tx->dev has a reference added; use dev_put(tx->dev) when
34968 + * finished with it. */
34969 +-static int inline ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
34970 ++static inline int ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
34971 + struct sk_buff *skb,
34972 + struct net_device *mdev,
34973 + struct ieee80211_tx_control *control)
34974 +diff -Nurp linux-2.6.23.15/net/mac80211/regdomain.c linux-2.6.23.15-grsec/net/mac80211/regdomain.c
34975 +--- linux-2.6.23.15/net/mac80211/regdomain.c 2007-10-09 21:31:38.000000000 +0100
34976 ++++ linux-2.6.23.15-grsec/net/mac80211/regdomain.c 2008-02-11 10:37:45.000000000 +0000
34977 +@@ -61,14 +61,14 @@ static const struct ieee80211_channel_ra
34978 + { 5180, 5240, 17, 6 } /* IEEE 802.11a, channels 36..48 */,
34979 + { 5260, 5320, 23, 6 } /* IEEE 802.11a, channels 52..64 */,
34980 + { 5745, 5825, 30, 6 } /* IEEE 802.11a, channels 149..165, outdoor */,
34981 +- { 0 }
34982 ++ { 0, 0, 0, 0 }
34983 + };
34984 +
34985 + static const struct ieee80211_channel_range ieee80211_mkk_channels[] = {
34986 + { 2412, 2472, 20, 6 } /* IEEE 802.11b/g, channels 1..13 */,
34987 + { 5170, 5240, 20, 6 } /* IEEE 802.11a, channels 34..48 */,
34988 + { 5260, 5320, 20, 6 } /* IEEE 802.11a, channels 52..64 */,
34989 +- { 0 }
34990 ++ { 0, 0, 0, 0 }
34991 + };
34992 +
34993 +
34994 +diff -Nurp linux-2.6.23.15/net/sctp/socket.c linux-2.6.23.15-grsec/net/sctp/socket.c
34995 +--- linux-2.6.23.15/net/sctp/socket.c 2007-10-09 21:31:38.000000000 +0100
34996 ++++ linux-2.6.23.15-grsec/net/sctp/socket.c 2008-02-11 10:37:45.000000000 +0000
34997 +@@ -1370,7 +1370,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
34998 + struct sctp_sndrcvinfo *sinfo;
34999 + struct sctp_initmsg *sinit;
35000 + sctp_assoc_t associd = 0;
35001 +- sctp_cmsgs_t cmsgs = { NULL };
35002 ++ sctp_cmsgs_t cmsgs = { NULL, NULL };
35003 + int err;
35004 + sctp_scope_t scope;
35005 + long timeo;
35006 +diff -Nurp linux-2.6.23.15/net/socket.c linux-2.6.23.15-grsec/net/socket.c
35007 +--- linux-2.6.23.15/net/socket.c 2008-02-11 10:36:03.000000000 +0000
35008 ++++ linux-2.6.23.15-grsec/net/socket.c 2008-02-11 10:37:45.000000000 +0000
35009 +@@ -84,6 +84,7 @@
35010 + #include <linux/kmod.h>
35011 + #include <linux/audit.h>
35012 + #include <linux/wireless.h>
35013 ++#include <linux/in.h>
35014 +
35015 + #include <asm/uaccess.h>
35016 + #include <asm/unistd.h>
35017 +@@ -93,6 +94,21 @@
35018 + #include <net/sock.h>
35019 + #include <linux/netfilter.h>
35020 +
35021 ++extern void gr_attach_curr_ip(const struct sock *sk);
35022 ++extern int gr_handle_sock_all(const int family, const int type,
35023 ++ const int protocol);
35024 ++extern int gr_handle_sock_server(const struct sockaddr *sck);
35025 ++extern int gr_handle_sock_server_other(const struct socket *sck);
35026 ++extern int gr_handle_sock_client(const struct sockaddr *sck);
35027 ++extern int gr_search_connect(const struct socket * sock,
35028 ++ const struct sockaddr_in * addr);
35029 ++extern int gr_search_bind(const struct socket * sock,
35030 ++ const struct sockaddr_in * addr);
35031 ++extern int gr_search_listen(const struct socket * sock);
35032 ++extern int gr_search_accept(const struct socket * sock);
35033 ++extern int gr_search_socket(const int domain, const int type,
35034 ++ const int protocol);
35035 ++
35036 + static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
35037 + static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
35038 + unsigned long nr_segs, loff_t pos);
35039 +@@ -292,7 +308,7 @@ static int sockfs_get_sb(struct file_sys
35040 + mnt);
35041 + }
35042 +
35043 +-static struct vfsmount *sock_mnt __read_mostly;
35044 ++struct vfsmount *sock_mnt __read_mostly;
35045 +
35046 + static struct file_system_type sock_fs_type = {
35047 + .name = "sockfs",
35048 +@@ -1199,6 +1215,16 @@ asmlinkage long sys_socket(int family, i
35049 + int retval;
35050 + struct socket *sock;
35051 +
35052 ++ if(!gr_search_socket(family, type, protocol)) {
35053 ++ retval = -EACCES;
35054 ++ goto out;
35055 ++ }
35056 ++
35057 ++ if (gr_handle_sock_all(family, type, protocol)) {
35058 ++ retval = -EACCES;
35059 ++ goto out;
35060 ++ }
35061 ++
35062 + retval = sock_create(family, type, protocol, &sock);
35063 + if (retval < 0)
35064 + goto out;
35065 +@@ -1329,6 +1355,12 @@ asmlinkage long sys_bind(int fd, struct
35066 + if (sock) {
35067 + err = move_addr_to_kernel(umyaddr, addrlen, address);
35068 + if (err >= 0) {
35069 ++ if (!gr_search_bind(sock, (struct sockaddr_in *)address) ||
35070 ++ gr_handle_sock_server((struct sockaddr *)address)) {
35071 ++ err = -EACCES;
35072 ++ goto error;
35073 ++ }
35074 ++
35075 + err = security_socket_bind(sock,
35076 + (struct sockaddr *)address,
35077 + addrlen);
35078 +@@ -1337,6 +1369,7 @@ asmlinkage long sys_bind(int fd, struct
35079 + (struct sockaddr *)
35080 + address, addrlen);
35081 + }
35082 ++error:
35083 + fput_light(sock->file, fput_needed);
35084 + }
35085 + return err;
35086 +@@ -1360,10 +1393,17 @@ asmlinkage long sys_listen(int fd, int b
35087 + if ((unsigned)backlog > sysctl_somaxconn)
35088 + backlog = sysctl_somaxconn;
35089 +
35090 ++ if (gr_handle_sock_server_other(sock) ||
35091 ++ !gr_search_listen(sock)) {
35092 ++ err = -EPERM;
35093 ++ goto error;
35094 ++ }
35095 ++
35096 + err = security_socket_listen(sock, backlog);
35097 + if (!err)
35098 + err = sock->ops->listen(sock, backlog);
35099 +
35100 ++error:
35101 + fput_light(sock->file, fput_needed);
35102 + }
35103 + return err;
35104 +@@ -1400,6 +1440,13 @@ asmlinkage long sys_accept(int fd, struc
35105 + newsock->type = sock->type;
35106 + newsock->ops = sock->ops;
35107 +
35108 ++ if (gr_handle_sock_server_other(sock) ||
35109 ++ !gr_search_accept(sock)) {
35110 ++ err = -EPERM;
35111 ++ sock_release(newsock);
35112 ++ goto out_put;
35113 ++ }
35114 ++
35115 + /*
35116 + * We don't need try_module_get here, as the listening socket (sock)
35117 + * has the protocol module (sock->ops->owner) held.
35118 +@@ -1443,6 +1490,7 @@ asmlinkage long sys_accept(int fd, struc
35119 + err = newfd;
35120 +
35121 + security_socket_post_accept(sock, newsock);
35122 ++ gr_attach_curr_ip(newsock->sk);
35123 +
35124 + out_put:
35125 + fput_light(sock->file, fput_needed);
35126 +@@ -1476,6 +1524,7 @@ asmlinkage long sys_connect(int fd, stru
35127 + {
35128 + struct socket *sock;
35129 + char address[MAX_SOCK_ADDR];
35130 ++ struct sockaddr *sck;
35131 + int err, fput_needed;
35132 +
35133 + sock = sockfd_lookup_light(fd, &err, &fput_needed);
35134 +@@ -1485,6 +1534,13 @@ asmlinkage long sys_connect(int fd, stru
35135 + if (err < 0)
35136 + goto out_put;
35137 +
35138 ++ sck = (struct sockaddr *)address;
35139 ++ if (!gr_search_connect(sock, (struct sockaddr_in *)sck) ||
35140 ++ gr_handle_sock_client(sck)) {
35141 ++ err = -EACCES;
35142 ++ goto out_put;
35143 ++ }
35144 ++
35145 + err =
35146 + security_socket_connect(sock, (struct sockaddr *)address, addrlen);
35147 + if (err)
35148 +@@ -1762,6 +1818,7 @@ asmlinkage long sys_shutdown(int fd, int
35149 + err = sock->ops->shutdown(sock, how);
35150 + fput_light(sock->file, fput_needed);
35151 + }
35152 ++
35153 + return err;
35154 + }
35155 +
35156 +diff -Nurp linux-2.6.23.15/net/unix/af_unix.c linux-2.6.23.15-grsec/net/unix/af_unix.c
35157 +--- linux-2.6.23.15/net/unix/af_unix.c 2008-02-11 10:36:03.000000000 +0000
35158 ++++ linux-2.6.23.15-grsec/net/unix/af_unix.c 2008-02-11 10:37:45.000000000 +0000
35159 +@@ -115,6 +115,7 @@
35160 + #include <linux/mount.h>
35161 + #include <net/checksum.h>
35162 + #include <linux/security.h>
35163 ++#include <linux/grsecurity.h>
35164 +
35165 + int sysctl_unix_max_dgram_qlen __read_mostly = 10;
35166 +
35167 +@@ -733,6 +734,11 @@ static struct sock *unix_find_other(stru
35168 + if (err)
35169 + goto put_fail;
35170 +
35171 ++ if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) {
35172 ++ err = -EACCES;
35173 ++ goto put_fail;
35174 ++ }
35175 ++
35176 + err = -ECONNREFUSED;
35177 + if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
35178 + goto put_fail;
35179 +@@ -756,6 +762,13 @@ static struct sock *unix_find_other(stru
35180 + if (u) {
35181 + struct dentry *dentry;
35182 + dentry = unix_sk(u)->dentry;
35183 ++
35184 ++ if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
35185 ++ err = -EPERM;
35186 ++ sock_put(u);
35187 ++ goto fail;
35188 ++ }
35189 ++
35190 + if (dentry)
35191 + touch_atime(unix_sk(u)->mnt, dentry);
35192 + } else
35193 +@@ -834,9 +847,18 @@ static int unix_bind(struct socket *sock
35194 + */
35195 + mode = S_IFSOCK |
35196 + (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
35197 ++
35198 ++ if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
35199 ++ err = -EACCES;
35200 ++ goto out_mknod_dput;
35201 ++ }
35202 ++
35203 + err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
35204 + if (err)
35205 + goto out_mknod_dput;
35206 ++
35207 ++ gr_handle_create(dentry, nd.mnt);
35208 ++
35209 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
35210 + dput(nd.dentry);
35211 + nd.dentry = dentry;
35212 +@@ -854,6 +876,10 @@ static int unix_bind(struct socket *sock
35213 + goto out_unlock;
35214 + }
35215 +
35216 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
35217 ++ sk->sk_peercred.pid = current->pid;
35218 ++#endif
35219 ++
35220 + list = &unix_socket_table[addr->hash];
35221 + } else {
35222 + list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
35223 +diff -Nurp linux-2.6.23.15/scripts/pnmtologo.c linux-2.6.23.15-grsec/scripts/pnmtologo.c
35224 +--- linux-2.6.23.15/scripts/pnmtologo.c 2007-10-09 21:31:38.000000000 +0100
35225 ++++ linux-2.6.23.15-grsec/scripts/pnmtologo.c 2008-02-11 10:37:45.000000000 +0000
35226 +@@ -237,14 +237,14 @@ static void write_header(void)
35227 + fprintf(out, " * Linux logo %s\n", logoname);
35228 + fputs(" */\n\n", out);
35229 + fputs("#include <linux/linux_logo.h>\n\n", out);
35230 +- fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
35231 ++ fprintf(out, "static unsigned char %s_data[] = {\n",
35232 + logoname);
35233 + }
35234 +
35235 + static void write_footer(void)
35236 + {
35237 + fputs("\n};\n\n", out);
35238 +- fprintf(out, "struct linux_logo %s __initdata = {\n", logoname);
35239 ++ fprintf(out, "struct linux_logo %s = {\n", logoname);
35240 + fprintf(out, " .type\t= %s,\n", logo_types[logo_type]);
35241 + fprintf(out, " .width\t= %d,\n", logo_width);
35242 + fprintf(out, " .height\t= %d,\n", logo_height);
35243 +@@ -374,7 +374,7 @@ static void write_logo_clut224(void)
35244 + fputs("\n};\n\n", out);
35245 +
35246 + /* write logo clut */
35247 +- fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
35248 ++ fprintf(out, "static unsigned char %s_clut[] = {\n",
35249 + logoname);
35250 + write_hex_cnt = 0;
35251 + for (i = 0; i < logo_clutsize; i++) {
35252 +diff -Nurp linux-2.6.23.15/security/Kconfig linux-2.6.23.15-grsec/security/Kconfig
35253 +--- linux-2.6.23.15/security/Kconfig 2007-10-09 21:31:38.000000000 +0100
35254 ++++ linux-2.6.23.15-grsec/security/Kconfig 2008-02-11 10:37:45.000000000 +0000
35255 +@@ -4,6 +4,429 @@
35256 +
35257 + menu "Security options"
35258 +
35259 ++source grsecurity/Kconfig
35260 ++
35261 ++menu "PaX"
35262 ++
35263 ++config PAX
35264 ++ bool "Enable various PaX features"
35265 ++ depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
35266 ++ help
35267 ++ This allows you to enable various PaX features. PaX adds
35268 ++ intrusion prevention mechanisms to the kernel that reduce
35269 ++ the risks posed by exploitable memory corruption bugs.
35270 ++
35271 ++menu "PaX Control"
35272 ++ depends on PAX
35273 ++
35274 ++config PAX_SOFTMODE
35275 ++ bool 'Support soft mode'
35276 ++ help
35277 ++ Enabling this option will allow you to run PaX in soft mode, that
35278 ++ is, PaX features will not be enforced by default, only on executables
35279 ++ marked explicitly. You must also enable PT_PAX_FLAGS support as it
35280 ++ is the only way to mark executables for soft mode use.
35281 ++
35282 ++ Soft mode can be activated by using the "pax_softmode=1" kernel command
35283 ++ line option on boot. Furthermore you can control various PaX features
35284 ++ at runtime via the entries in /proc/sys/kernel/pax.
35285 ++
35286 ++config PAX_EI_PAX
35287 ++ bool 'Use legacy ELF header marking'
35288 ++ help
35289 ++ Enabling this option will allow you to control PaX features on
35290 ++ a per executable basis via the 'chpax' utility available at
35291 ++ http://pax.grsecurity.net/. The control flags will be read from
35292 ++ an otherwise reserved part of the ELF header. This marking has
35293 ++ numerous drawbacks (no support for soft-mode, toolchain does not
35294 ++ know about the non-standard use of the ELF header) therefore it
35295 ++ has been deprecated in favour of PT_PAX_FLAGS support.
35296 ++
35297 ++ If you have applications not marked by the PT_PAX_FLAGS ELF
35298 ++ program header then you MUST enable this option otherwise they
35299 ++ will not get any protection.
35300 ++
35301 ++ Note that if you enable PT_PAX_FLAGS marking support as well,
35302 ++ the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
35303 ++
35304 ++config PAX_PT_PAX_FLAGS
35305 ++ bool 'Use ELF program header marking'
35306 ++ help
35307 ++ Enabling this option will allow you to control PaX features on
35308 ++ a per executable basis via the 'paxctl' utility available at
35309 ++ http://pax.grsecurity.net/. The control flags will be read from
35310 ++ a PaX specific ELF program header (PT_PAX_FLAGS). This marking
35311 ++ has the benefits of supporting both soft mode and being fully
35312 ++ integrated into the toolchain (the binutils patch is available
35313 ++ from http://pax.grsecurity.net).
35314 ++
35315 ++ If you have applications not marked by the PT_PAX_FLAGS ELF
35316 ++ program header then you MUST enable the EI_PAX marking support
35317 ++ otherwise they will not get any protection.
35318 ++
35319 ++ Note that if you enable the legacy EI_PAX marking support as well,
35320 ++ the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
35321 ++
35322 ++choice
35323 ++ prompt 'MAC system integration'
35324 ++ default PAX_HAVE_ACL_FLAGS
35325 ++ help
35326 ++ Mandatory Access Control systems have the option of controlling
35327 ++ PaX flags on a per executable basis, choose the method supported
35328 ++ by your particular system.
35329 ++
35330 ++ - "none": if your MAC system does not interact with PaX,
35331 ++ - "direct": if your MAC system defines pax_set_initial_flags() itself,
35332 ++ - "hook": if your MAC system uses the pax_set_initial_flags_func callback.
35333 ++
35334 ++ NOTE: this option is for developers/integrators only.
35335 ++
35336 ++ config PAX_NO_ACL_FLAGS
35337 ++ bool 'none'
35338 ++
35339 ++ config PAX_HAVE_ACL_FLAGS
35340 ++ bool 'direct'
35341 ++
35342 ++ config PAX_HOOK_ACL_FLAGS
35343 ++ bool 'hook'
35344 ++endchoice
35345 ++
35346 ++endmenu
35347 ++
35348 ++menu "Non-executable pages"
35349 ++ depends on PAX
35350 ++
35351 ++config PAX_NOEXEC
35352 ++ bool "Enforce non-executable pages"
35353 ++ depends on (PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS) && (ALPHA || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
35354 ++ help
35355 ++ By design some architectures do not allow for protecting memory
35356 ++ pages against execution or even if they do, Linux does not make
35357 ++ use of this feature. In practice this means that if a page is
35358 ++ readable (such as the stack or heap) it is also executable.
35359 ++
35360 ++ There is a well known exploit technique that makes use of this
35361 ++ fact and a common programming mistake where an attacker can
35362 ++ introduce code of his choice somewhere in the attacked program's
35363 ++ memory (typically the stack or the heap) and then execute it.
35364 ++
35365 ++ If the attacked program was running with different (typically
35366 ++ higher) privileges than that of the attacker, then he can elevate
35367 ++ his own privilege level (e.g. get a root shell, write to files for
35368 ++ which he does not have write access to, etc).
35369 ++
35370 ++ Enabling this option will let you choose from various features
35371 ++ that prevent the injection and execution of 'foreign' code in
35372 ++ a program.
35373 ++
35374 ++ This will also break programs that rely on the old behaviour and
35375 ++ expect that dynamically allocated memory via the malloc() family
35376 ++ of functions is executable (which it is not). Notable examples
35377 ++ are the XFree86 4.x server, the java runtime and wine.
35378 ++
35379 ++config PAX_PAGEEXEC
35380 ++ bool "Paging based non-executable pages"
35381 ++ depends on !COMPAT_VDSO && PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MPENTIUM4 || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2)
35382 ++ help
35383 ++ This implementation is based on the paging feature of the CPU.
35384 ++ On i386 without hardware non-executable bit support there is a
35385 ++ variable but usually low performance impact, however on Intel's
35386 ++ P4 core based CPUs it is very high so you should not enable this
35387 ++ for kernels meant to be used on such CPUs.
35388 ++
35389 ++ On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386
35390 ++ with hardware non-executable bit support there is no performance
35391 ++ impact, on ppc the impact is negligible.
35392 ++
35393 ++ Note that several architectures require various emulations due to
35394 ++ badly designed userland ABIs, this will cause a performance impact
35395 ++ but will disappear as soon as userland is fixed (e.g., ppc users
35396 ++ can make use of the secure-plt feature found in binutils).
35397 ++
35398 ++config PAX_SEGMEXEC
35399 ++ bool "Segmentation based non-executable pages"
35400 ++ depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32
35401 ++ help
35402 ++ This implementation is based on the segmentation feature of the
35403 ++ CPU and has a very small performance impact, however applications
35404 ++ will be limited to a 1.5 GB address space instead of the normal
35405 ++ 3 GB.
35406 ++
35407 ++config PAX_EMUTRAMP
35408 ++ bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86)
35409 ++ default y if PARISC || PPC32
35410 ++ help
35411 ++ There are some programs and libraries that for one reason or
35412 ++ another attempt to execute special small code snippets from
35413 ++ non-executable memory pages. Most notable examples are the
35414 ++ signal handler return code generated by the kernel itself and
35415 ++ the GCC trampolines.
35416 ++
35417 ++ If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
35418 ++ such programs will no longer work under your kernel.
35419 ++
35420 ++ As a remedy you can say Y here and use the 'chpax' or 'paxctl'
35421 ++ utilities to enable trampoline emulation for the affected programs
35422 ++ yet still have the protection provided by the non-executable pages.
35423 ++
35424 ++ On parisc and ppc you MUST enable this option and EMUSIGRT as
35425 ++ well, otherwise your system will not even boot.
35426 ++
35427 ++ Alternatively you can say N here and use the 'chpax' or 'paxctl'
35428 ++ utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
35429 ++ for the affected files.
35430 ++
35431 ++ NOTE: enabling this feature *may* open up a loophole in the
35432 ++ protection provided by non-executable pages that an attacker
35433 ++ could abuse. Therefore the best solution is to not have any
35434 ++ files on your system that would require this option. This can
35435 ++ be achieved by not using libc5 (which relies on the kernel
35436 ++ signal handler return code) and not using or rewriting programs
35437 ++ that make use of the nested function implementation of GCC.
35438 ++ Skilled users can just fix GCC itself so that it implements
35439 ++ nested function calls in a way that does not interfere with PaX.
35440 ++
35441 ++config PAX_EMUSIGRT
35442 ++ bool "Automatically emulate sigreturn trampolines"
35443 ++ depends on PAX_EMUTRAMP && (PARISC || PPC32)
35444 ++ default y
35445 ++ help
35446 ++ Enabling this option will have the kernel automatically detect
35447 ++ and emulate signal return trampolines executing on the stack
35448 ++ that would otherwise lead to task termination.
35449 ++
35450 ++ This solution is intended as a temporary one for users with
35451 ++ legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
35452 ++ Modula-3 runtime, etc) or executables linked to such, basically
35453 ++ everything that does not specify its own SA_RESTORER function in
35454 ++ normal executable memory like glibc 2.1+ does.
35455 ++
35456 ++ On parisc and ppc you MUST enable this option, otherwise your
35457 ++ system will not even boot.
35458 ++
35459 ++ NOTE: this feature cannot be disabled on a per executable basis
35460 ++ and since it *does* open up a loophole in the protection provided
35461 ++ by non-executable pages, the best solution is to not have any
35462 ++ files on your system that would require this option.
35463 ++
35464 ++config PAX_MPROTECT
35465 ++ bool "Restrict mprotect()"
35466 ++ depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
35467 ++ help
35468 ++ Enabling this option will prevent programs from
35469 ++ - changing the executable status of memory pages that were
35470 ++ not originally created as executable,
35471 ++ - making read-only executable pages writable again,
35472 ++ - creating executable pages from anonymous memory.
35473 ++
35474 ++ You should say Y here to complete the protection provided by
35475 ++ the enforcement of non-executable pages.
35476 ++
35477 ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
35478 ++ this feature on a per file basis.
35479 ++
35480 ++config PAX_NOELFRELOCS
35481 ++ bool "Disallow ELF text relocations"
35482 ++ depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86 || X86_64)
35483 ++ help
35484 ++ Non-executable pages and mprotect() restrictions are effective
35485 ++ in preventing the introduction of new executable code into an
35486 ++ attacked task's address space. There remain only two venues
35487 ++ for this kind of attack: if the attacker can execute already
35488 ++ existing code in the attacked task then he can either have it
35489 ++ create and mmap() a file containing his code or have it mmap()
35490 ++ an already existing ELF library that does not have position
35491 ++ independent code in it and use mprotect() on it to make it
35492 ++ writable and copy his code there. While protecting against
35493 ++ the former approach is beyond PaX, the latter can be prevented
35494 ++ by having only PIC ELF libraries on one's system (which do not
35495 ++ need to relocate their code). If you are sure this is your case,
35496 ++ then enable this option otherwise be careful as you may not even
35497 ++ be able to boot or log on your system (for example, some PAM
35498 ++ modules are erroneously compiled as non-PIC by default).
35499 ++
35500 ++ NOTE: if you are using dynamic ELF executables (as suggested
35501 ++ when using ASLR) then you must have made sure that you linked
35502 ++ your files using the PIC version of crt1 (the et_dyn.tar.gz package
35503 ++ referenced there has already been updated to support this).
35504 ++
35505 ++config PAX_ETEXECRELOCS
35506 ++ bool "Allow ELF ET_EXEC text relocations"
35507 ++ depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
35508 ++ default y
35509 ++ help
35510 ++ On some architectures there are incorrectly created applications
35511 ++ that require text relocations and would not work without enabling
35512 ++ this option. If you are an alpha, ia64 or parisc user, you should
35513 ++ enable this option and disable it once you have made sure that
35514 ++ none of your applications need it.
35515 ++
35516 ++config PAX_EMUPLT
35517 ++ bool "Automatically emulate ELF PLT"
35518 ++ depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
35519 ++ default y
35520 ++ help
35521 ++ Enabling this option will have the kernel automatically detect
35522 ++ and emulate the Procedure Linkage Table entries in ELF files.
35523 ++ On some architectures such entries are in writable memory, and
35524 ++ become non-executable leading to task termination. Therefore
35525 ++ it is mandatory that you enable this option on alpha, parisc,
35526 ++ ppc (if secure-plt is not used throughout in userland), sparc
35527 ++ and sparc64, otherwise your system would not even boot.
35528 ++
35529 ++ NOTE: this feature *does* open up a loophole in the protection
35530 ++ provided by the non-executable pages, therefore the proper
35531 ++ solution is to modify the toolchain to produce a PLT that does
35532 ++ not need to be writable.
35533 ++
35534 ++config PAX_DLRESOLVE
35535 ++ bool
35536 ++ depends on PAX_EMUPLT && (SPARC32 || SPARC64)
35537 ++ default y
35538 ++
35539 ++config PAX_SYSCALL
35540 ++ bool
35541 ++ depends on PAX_PAGEEXEC && PPC32
35542 ++ default y
35543 ++
35544 ++config PAX_KERNEXEC
35545 ++ bool "Enforce non-executable kernel pages"
35546 ++ depends on PAX_NOEXEC && X86_32 && !EFI && !COMPAT_VDSO && X86_WP_WORKS_OK && !PARAVIRT
35547 ++ help
35548 ++ This is the kernel land equivalent of PAGEEXEC and MPROTECT,
35549 ++ that is, enabling this option will make it harder to inject
35550 ++ and execute 'foreign' code in kernel memory itself.
35551 ++
35552 ++endmenu
35553 ++
35554 ++menu "Address Space Layout Randomization"
35555 ++ depends on PAX
35556 ++
35557 ++config PAX_ASLR
35558 ++ bool "Address Space Layout Randomization"
35559 ++ depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
35560 ++ help
35561 ++ Many if not most exploit techniques rely on the knowledge of
35562 ++ certain addresses in the attacked program. The following options
35563 ++ will allow the kernel to apply a certain amount of randomization
35564 ++ to specific parts of the program thereby forcing an attacker to
35565 ++ guess them in most cases. Any failed guess will most likely crash
35566 ++ the attacked program which allows the kernel to detect such attempts
35567 ++ and react on them. PaX itself provides no reaction mechanisms,
35568 ++ instead it is strongly encouraged that you make use of Nergal's
35569 ++ segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
35570 ++ (http://www.grsecurity.net/) built-in crash detection features or
35571 ++ develop one yourself.
35572 ++
35573 ++ By saying Y here you can choose to randomize the following areas:
35574 ++ - top of the task's kernel stack
35575 ++ - top of the task's userland stack
35576 ++ - base address for mmap() requests that do not specify one
35577 ++ (this includes all libraries)
35578 ++ - base address of the main executable
35579 ++
35580 ++ It is strongly recommended to say Y here as address space layout
35581 ++ randomization has negligible impact on performance yet it provides
35582 ++ a very effective protection.
35583 ++
35584 ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
35585 ++ this feature on a per file basis.
35586 ++
35587 ++config PAX_RANDKSTACK
35588 ++ bool "Randomize kernel stack base"
35589 ++ depends on PAX_ASLR && X86_TSC && X86_32
35590 ++ help
35591 ++ By saying Y here the kernel will randomize every task's kernel
35592 ++ stack on every system call. This will not only force an attacker
35593 ++ to guess it but also prevent him from making use of possible
35594 ++ leaked information about it.
35595 ++
35596 ++ Since the kernel stack is a rather scarce resource, randomization
35597 ++ may cause unexpected stack overflows, therefore you should very
35598 ++ carefully test your system. Note that once enabled in the kernel
35599 ++ configuration, this feature cannot be disabled on a per file basis.
35600 ++
35601 ++config PAX_RANDUSTACK
35602 ++ bool "Randomize user stack base"
35603 ++ depends on PAX_ASLR
35604 ++ help
35605 ++ By saying Y here the kernel will randomize every task's userland
35606 ++ stack. The randomization is done in two steps where the second
35607 ++ one may apply a big amount of shift to the top of the stack and
35608 ++ cause problems for programs that want to use lots of memory (more
35609 ++ than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
35610 ++ For this reason the second step can be controlled by 'chpax' or
35611 ++ 'paxctl' on a per file basis.
35612 ++
35613 ++config PAX_RANDMMAP
35614 ++ bool "Randomize mmap() base"
35615 ++ depends on PAX_ASLR
35616 ++ help
35617 ++ By saying Y here the kernel will use a randomized base address for
35618 ++ mmap() requests that do not specify one themselves. As a result
35619 ++ all dynamically loaded libraries will appear at random addresses
35620 ++ and therefore be harder to exploit by a technique where an attacker
35621 ++ attempts to execute library code for his purposes (e.g. spawn a
35622 ++ shell from an exploited program that is running at an elevated
35623 ++ privilege level).
35624 ++
35625 ++ Furthermore, if a program is relinked as a dynamic ELF file, its
35626 ++ base address will be randomized as well, completing the full
35627 ++ randomization of the address space layout. Attacking such programs
35628 ++ becomes a guess game. You can find an example of doing this at
35629 ++ http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
35630 ++ http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
35631 ++
35632 ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
35633 ++ feature on a per file basis.
35634 ++
35635 ++endmenu
35636 ++
35637 ++menu "Miscellaneous hardening features"
35638 ++
35639 ++config PAX_MEMORY_SANITIZE
35640 ++ bool "Sanitize all freed memory"
35641 ++ help
35642 ++ By saying Y here the kernel will erase memory pages as soon as they
35643 ++ are freed. This in turn reduces the lifetime of data stored in the
35644 ++ pages, making it less likely that sensitive information such as
35645 ++ passwords, cryptographic secrets, etc stay in memory for too long.
35646 ++
35647 ++ This is especially useful for programs whose runtime is short, long
35648 ++ lived processes and the kernel itself benefit from this as long as
35649 ++ they operate on whole memory pages and ensure timely freeing of pages
35650 ++ that may hold sensitive information.
35651 ++
35652 ++ The tradeoff is performance impact, on a single CPU system kernel
35653 ++ compilation sees a 3% slowdown, other systems and workloads may vary
35654 ++ and you are advised to test this feature on your expected workload
35655 ++ before deploying it.
35656 ++
35657 ++ Note that this feature does not protect data stored in live pages,
35658 ++ e.g., process memory swapped to disk may stay there for a long time.
35659 ++
35660 ++config PAX_MEMORY_UDEREF
35661 ++ bool "Prevent invalid userland pointer dereference"
35662 ++ depends on X86_32 && !COMPAT_VDSO
35663 ++ help
35664 ++ By saying Y here the kernel will be prevented from dereferencing
35665 ++ userland pointers in contexts where the kernel expects only kernel
35666 ++ pointers. This is both a useful runtime debugging feature and a
35667 ++ security measure that prevents exploiting a class of kernel bugs.
35668 ++
35669 ++ The tradeoff is that some virtualization solutions may experience
35670 ++ a huge slowdown and therefore you should not enable this feature
35671 ++ for kernels meant to run in such environments. Whether a given VM
35672 ++ solution is affected or not is best determined by simply trying it
35673 ++ out, the performance impact will be obvious right on boot as this
35674 ++ mechanism engages from very early on. A good rule of thumb is that
35675 ++ VMs running on CPUs without hardware virtualization support (i.e.,
35676 ++ the majority of IA-32 CPUs) will likely experience the slowdown.
35677 ++
35678 ++endmenu
35679 ++
35680 ++endmenu
35681 ++
35682 + config KEYS
35683 + bool "Enable access key retention support"
35684 + help
35685 +diff -Nurp linux-2.6.23.15/security/commoncap.c linux-2.6.23.15-grsec/security/commoncap.c
35686 +--- linux-2.6.23.15/security/commoncap.c 2007-10-09 21:31:38.000000000 +0100
35687 ++++ linux-2.6.23.15-grsec/security/commoncap.c 2008-02-11 10:37:45.000000000 +0000
35688 +@@ -22,10 +22,11 @@
35689 + #include <linux/ptrace.h>
35690 + #include <linux/xattr.h>
35691 + #include <linux/hugetlb.h>
35692 ++#include <linux/grsecurity.h>
35693 +
35694 + int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
35695 + {
35696 +- NETLINK_CB(skb).eff_cap = current->cap_effective;
35697 ++ NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink();
35698 + return 0;
35699 + }
35700 +
35701 +@@ -43,7 +44,15 @@ EXPORT_SYMBOL(cap_netlink_recv);
35702 + int cap_capable (struct task_struct *tsk, int cap)
35703 + {
35704 + /* Derived from include/linux/sched.h:capable. */
35705 +- if (cap_raised(tsk->cap_effective, cap))
35706 ++ if (cap_raised (tsk->cap_effective, cap))
35707 ++ return 0;
35708 ++ return -EPERM;
35709 ++}
35710 ++
35711 ++int cap_capable_nolog (struct task_struct *tsk, int cap)
35712 ++{
35713 ++ /* tsk = current for all callers */
35714 ++ if (cap_raised(tsk->cap_effective, cap) && gr_is_capable_nolog(cap))
35715 + return 0;
35716 + return -EPERM;
35717 + }
35718 +@@ -162,8 +171,11 @@ void cap_bprm_apply_creds (struct linux_
35719 + }
35720 + }
35721 +
35722 +- current->suid = current->euid = current->fsuid = bprm->e_uid;
35723 +- current->sgid = current->egid = current->fsgid = bprm->e_gid;
35724 ++ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
35725 ++ current->suid = current->euid = current->fsuid = bprm->e_uid;
35726 ++
35727 ++ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
35728 ++ current->sgid = current->egid = current->fsgid = bprm->e_gid;
35729 +
35730 + /* For init, we want to retain the capabilities set
35731 + * in the init_task struct. Thus we skip the usual
35732 +@@ -174,6 +186,8 @@ void cap_bprm_apply_creds (struct linux_
35733 + cap_intersect (new_permitted, bprm->cap_effective);
35734 + }
35735 +
35736 ++ gr_handle_chroot_caps(current);
35737 ++
35738 + /* AUD: Audit candidate if current->cap_effective is set */
35739 +
35740 + current->keep_capabilities = 0;
35741 +@@ -319,12 +333,13 @@ int cap_vm_enough_memory(struct mm_struc
35742 + {
35743 + int cap_sys_admin = 0;
35744 +
35745 +- if (cap_capable(current, CAP_SYS_ADMIN) == 0)
35746 ++ if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
35747 + cap_sys_admin = 1;
35748 + return __vm_enough_memory(mm, pages, cap_sys_admin);
35749 + }
35750 +
35751 + EXPORT_SYMBOL(cap_capable);
35752 ++EXPORT_SYMBOL(cap_capable_nolog);
35753 + EXPORT_SYMBOL(cap_settime);
35754 + EXPORT_SYMBOL(cap_ptrace);
35755 + EXPORT_SYMBOL(cap_capget);
35756 +diff -Nurp linux-2.6.23.15/security/dummy.c linux-2.6.23.15-grsec/security/dummy.c
35757 +--- linux-2.6.23.15/security/dummy.c 2007-10-09 21:31:38.000000000 +0100
35758 ++++ linux-2.6.23.15-grsec/security/dummy.c 2008-02-11 10:37:45.000000000 +0000
35759 +@@ -28,6 +28,7 @@
35760 + #include <linux/hugetlb.h>
35761 + #include <linux/ptrace.h>
35762 + #include <linux/file.h>
35763 ++#include <linux/grsecurity.h>
35764 +
35765 + static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
35766 + {
35767 +@@ -138,8 +139,11 @@ static void dummy_bprm_apply_creds (stru
35768 + }
35769 + }
35770 +
35771 +- current->suid = current->euid = current->fsuid = bprm->e_uid;
35772 +- current->sgid = current->egid = current->fsgid = bprm->e_gid;
35773 ++ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
35774 ++ current->suid = current->euid = current->fsuid = bprm->e_uid;
35775 ++
35776 ++ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
35777 ++ current->sgid = current->egid = current->fsgid = bprm->e_gid;
35778 +
35779 + dummy_capget(current, &current->cap_effective, &current->cap_inheritable, &current->cap_permitted);
35780 + }
35781 +diff -Nurp linux-2.6.23.15/sound/core/oss/pcm_oss.c linux-2.6.23.15-grsec/sound/core/oss/pcm_oss.c
35782 +--- linux-2.6.23.15/sound/core/oss/pcm_oss.c 2007-10-09 21:31:38.000000000 +0100
35783 ++++ linux-2.6.23.15-grsec/sound/core/oss/pcm_oss.c 2008-02-11 10:37:45.000000000 +0000
35784 +@@ -2880,8 +2880,8 @@ static void snd_pcm_oss_proc_done(struct
35785 + }
35786 + }
35787 + #else /* !CONFIG_SND_VERBOSE_PROCFS */
35788 +-#define snd_pcm_oss_proc_init(pcm)
35789 +-#define snd_pcm_oss_proc_done(pcm)
35790 ++#define snd_pcm_oss_proc_init(pcm) do {} while (0)
35791 ++#define snd_pcm_oss_proc_done(pcm) do {} while (0)
35792 + #endif /* CONFIG_SND_VERBOSE_PROCFS */
35793 +
35794 + /*
35795 +diff -Nurp linux-2.6.23.15/sound/core/seq/seq_lock.h linux-2.6.23.15-grsec/sound/core/seq/seq_lock.h
35796 +--- linux-2.6.23.15/sound/core/seq/seq_lock.h 2007-10-09 21:31:38.000000000 +0100
35797 ++++ linux-2.6.23.15-grsec/sound/core/seq/seq_lock.h 2008-02-11 10:37:45.000000000 +0000
35798 +@@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo
35799 + #else /* SMP || CONFIG_SND_DEBUG */
35800 +
35801 + typedef spinlock_t snd_use_lock_t; /* dummy */
35802 +-#define snd_use_lock_init(lockp) /**/
35803 +-#define snd_use_lock_use(lockp) /**/
35804 +-#define snd_use_lock_free(lockp) /**/
35805 +-#define snd_use_lock_sync(lockp) /**/
35806 ++#define snd_use_lock_init(lockp) do {} while (0)
35807 ++#define snd_use_lock_use(lockp) do {} while (0)
35808 ++#define snd_use_lock_free(lockp) do {} while (0)
35809 ++#define snd_use_lock_sync(lockp) do {} while (0)
35810 +
35811 + #endif /* SMP || CONFIG_SND_DEBUG */
35812 +
35813 +diff -Nurp linux-2.6.23.15/sound/pci/ac97/ac97_patch.c linux-2.6.23.15-grsec/sound/pci/ac97/ac97_patch.c
35814 +--- linux-2.6.23.15/sound/pci/ac97/ac97_patch.c 2007-10-09 21:31:38.000000000 +0100
35815 ++++ linux-2.6.23.15-grsec/sound/pci/ac97/ac97_patch.c 2008-02-11 10:37:45.000000000 +0000
35816 +@@ -1415,7 +1415,7 @@ static const struct snd_ac97_res_table a
35817 + { AC97_VIDEO, 0x9f1f },
35818 + { AC97_AUX, 0x9f1f },
35819 + { AC97_PCM, 0x9f1f },
35820 +- { } /* terminator */
35821 ++ { 0, 0 } /* terminator */
35822 + };
35823 +
35824 + static int patch_ad1819(struct snd_ac97 * ac97)
35825 +@@ -3489,7 +3489,7 @@ static struct snd_ac97_res_table lm4550_
35826 + { AC97_AUX, 0x1f1f },
35827 + { AC97_PCM, 0x1f1f },
35828 + { AC97_REC_GAIN, 0x0f0f },
35829 +- { } /* terminator */
35830 ++ { 0, 0 } /* terminator */
35831 + };
35832 +
35833 + static int patch_lm4550(struct snd_ac97 *ac97)
35834 +diff -Nurp linux-2.6.23.15/sound/pci/ens1370.c linux-2.6.23.15-grsec/sound/pci/ens1370.c
35835 +--- linux-2.6.23.15/sound/pci/ens1370.c 2007-10-09 21:31:38.000000000 +0100
35836 ++++ linux-2.6.23.15-grsec/sound/pci/ens1370.c 2008-02-11 10:37:45.000000000 +0000
35837 +@@ -453,7 +453,7 @@ static struct pci_device_id snd_audiopci
35838 + { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1373 - CT5880 */
35839 + { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ectiva EV1938 */
35840 + #endif
35841 +- { 0, }
35842 ++ { 0, 0, 0, 0, 0, 0, 0 }
35843 + };
35844 +
35845 + MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
35846 +diff -Nurp linux-2.6.23.15/sound/pci/intel8x0.c linux-2.6.23.15-grsec/sound/pci/intel8x0.c
35847 +--- linux-2.6.23.15/sound/pci/intel8x0.c 2007-10-09 21:31:38.000000000 +0100
35848 ++++ linux-2.6.23.15-grsec/sound/pci/intel8x0.c 2008-02-11 10:37:45.000000000 +0000
35849 +@@ -436,7 +436,7 @@ static struct pci_device_id snd_intel8x0
35850 + { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
35851 + { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
35852 + { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
35853 +- { 0, }
35854 ++ { 0, 0, 0, 0, 0, 0, 0 }
35855 + };
35856 +
35857 + MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
35858 +@@ -2044,7 +2044,7 @@ static struct ac97_quirk ac97_quirks[] _
35859 + .type = AC97_TUNE_HP_ONLY
35860 + },
35861 + #endif
35862 +- { } /* terminator */
35863 ++ { 0, 0, 0, 0, NULL, 0 } /* terminator */
35864 + };
35865 +
35866 + static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
35867 +diff -Nurp linux-2.6.23.15/sound/pci/intel8x0m.c linux-2.6.23.15-grsec/sound/pci/intel8x0m.c
35868 +--- linux-2.6.23.15/sound/pci/intel8x0m.c 2007-10-09 21:31:38.000000000 +0100
35869 ++++ linux-2.6.23.15-grsec/sound/pci/intel8x0m.c 2008-02-11 10:37:45.000000000 +0000
35870 +@@ -240,7 +240,7 @@ static struct pci_device_id snd_intel8x0
35871 + { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
35872 + { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
35873 + #endif
35874 +- { 0, }
35875 ++ { 0, 0, 0, 0, 0, 0, 0 }
35876 + };
35877 +
35878 + MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
35879 +@@ -1261,7 +1261,7 @@ static struct shortname_table {
35880 + { 0x5455, "ALi M5455" },
35881 + { 0x746d, "AMD AMD8111" },
35882 + #endif
35883 +- { 0 },
35884 ++ { 0, NULL },
35885 + };
35886 +
35887 + static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
35888
35889 Added: hardened-sources/2.6/tags/2.6.23-7/4435_grsec-2.1.10-mute-warnings.patch
35890 ===================================================================
35891 --- hardened-sources/2.6/tags/2.6.23-7/4435_grsec-2.1.10-mute-warnings.patch (rev 0)
35892 +++ hardened-sources/2.6/tags/2.6.23-7/4435_grsec-2.1.10-mute-warnings.patch 2008-04-30 11:42:53 UTC (rev 97)
35893 @@ -0,0 +1,23 @@
35894 +From: Alexander Gabert <gaberta@××××××××.de>
35895 +
35896 +This patch removes the warnings introduced by grsec patch 2.1.9 and later.
35897 +It removes the -W options added by the patch and restores the original
35898 +warning flags of vanilla kernel versions.
35899 +
35900 +Acked-by: Christian Heim <phreak@g.o>
35901 +
35902 +---
35903 + Makefile | 5 +++--
35904 + 1 file changed, 3 insertions(+), 2 deletions(-)
35905 +
35906 +--- a/Makefile
35907 ++++ b/Makefile
35908 +@@ -312,7 +312,7 @@ LINUXINCLUDE := -Iinclude \
35909 +
35910 + CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE)
35911 +
35912 +-CFLAGS := -Wall -W -Wno-unused -Wno-sign-compare -Wundef -Wstrict-prototypes -Wno-trigraphs \
35913 ++CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
35914 + -fno-strict-aliasing -fno-common \
35915 + -Werror-implicit-function-declaration
35916 + AFLAGS := -D__ASSEMBLY__
35917
35918 Added: hardened-sources/2.6/tags/2.6.23-7/4440_grsec-2.1.10-pax_curr_ip-fixes.patch
35919 ===================================================================
35920 --- hardened-sources/2.6/tags/2.6.23-7/4440_grsec-2.1.10-pax_curr_ip-fixes.patch (rev 0)
35921 +++ hardened-sources/2.6/tags/2.6.23-7/4440_grsec-2.1.10-pax_curr_ip-fixes.patch 2008-04-30 11:42:53 UTC (rev 97)
35922 @@ -0,0 +1,46 @@
35923 +---
35924 + arch/i386/mm/fault.c | 2 ++
35925 + fs/exec.c | 2 ++
35926 + security/Kconfig | 2 +-
35927 + 3 files changed, 5 insertions(+), 1 deletion(-)
35928 +
35929 +--- a/arch/i386/mm/fault.c
35930 ++++ b/arch/i386/mm/fault.c
35931 +@@ -722,10 +722,12 @@ no_context:
35932 + #else
35933 + else if (init_mm.start_code <= address && address < init_mm.end_code)
35934 + #endif
35935 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
35936 + if (tsk->signal->curr_ip)
35937 + printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
35938 + NIPQUAD(tsk->signal->curr_ip), tsk->comm, tsk->pid, tsk->uid, tsk->euid);
35939 + else
35940 ++#endif
35941 + printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
35942 + tsk->comm, tsk->pid, tsk->uid, tsk->euid);
35943 + #endif
35944 +--- a/fs/exec.c
35945 ++++ b/fs/exec.c
35946 +@@ -1733,9 +1733,11 @@ void pax_report_fault(struct pt_regs *re
35947 + }
35948 + up_read(&mm->mmap_sem);
35949 + }
35950 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
35951 + if (tsk->signal->curr_ip)
35952 + 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);
35953 + else
35954 ++#endif
35955 + printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
35956 + printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
35957 + "PC: %p, SP: %p\n", path_exec, tsk->comm, tsk->pid,
35958 +--- a/security/Kconfig
35959 ++++ b/security/Kconfig
35960 +@@ -10,7 +10,7 @@ menu "PaX"
35961 +
35962 + config PAX
35963 + bool "Enable various PaX features"
35964 +- depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
35965 ++ depends on (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
35966 + help
35967 + This allows you to enable various PaX features. PaX adds
35968 + intrusion prevention mechanisms to the kernel that reduce
35969
35970 Added: hardened-sources/2.6/tags/2.6.23-7/4445_grsec-kconfig-gentoo.patch
35971 ===================================================================
35972 --- hardened-sources/2.6/tags/2.6.23-7/4445_grsec-kconfig-gentoo.patch (rev 0)
35973 +++ hardened-sources/2.6/tags/2.6.23-7/4445_grsec-kconfig-gentoo.patch 2008-04-30 11:42:53 UTC (rev 97)
35974 @@ -0,0 +1,115 @@
35975 +From: Kerin Millar <kerframil@×××××.com>
35976 +
35977 +Add a Hardened Gentoo target to the list of security levels. It's
35978 +designed to provide a comparitively high level of security and to be
35979 +generally suitable for as great a majority of the userbase as possible
35980 +(particularly new users). The patch was originally contributed by Ned
35981 +Ludd <solar@g.o>. This instance was revised by the author with
35982 +contributions from Gordon Malm <bugs-gentoo-org-02@××××××.org> for the
35983 +hardened-sources-2.6.23-r9 release where it is now a default.
35984 +
35985 +--- a/grsecurity/Kconfig 2008-03-20 12:18:37.000000000 +0000
35986 ++++ b/grsecurity/Kconfig 2008-03-20 12:19:16.000000000 +0000
35987 +@@ -18,7 +18,7 @@
35988 + choice
35989 + prompt "Security Level"
35990 + depends GRKERNSEC
35991 +- default GRKERNSEC_CUSTOM
35992 ++ default GRKERNSEC_HARDENED
35993 +
35994 + config GRKERNSEC_LOW
35995 + bool "Low"
35996 +@@ -182,6 +182,93 @@
35997 + - Kernel symbol hiding
35998 + - Destroy unused shared memory
35999 + - Prevention of memory exhaustion-based exploits
36000 ++
36001 ++config GRKERNSEC_HARDENED
36002 ++ bool "Hardened [Gentoo]"
36003 ++ select GRKERNSEC_KMEM
36004 ++ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
36005 ++ select GRKERNSEC_BRUTE
36006 ++ select GRKERNSEC_MODSTOP if (MODULES)
36007 ++ select GRKERNSEC_HIDESYM
36008 ++ select GRKERNSEC_PROC
36009 ++ select GRKERNSEC_PROC_USER
36010 ++ select GRKERNSEC_PROC_ADD
36011 ++ select GRKERNSEC_LINK
36012 ++ select GRKERNSEC_FIFO
36013 ++ select GRKERNSEC_CHROOT
36014 ++ select GRKERNSEC_CHROOT_MOUNT
36015 ++ select GRKERNSEC_CHROOT_DOUBLE
36016 ++ select GRKERNSEC_CHROOT_PIVOT
36017 ++ select GRKERNSEC_CHROOT_CHDIR
36018 ++ select GRKERNSEC_CHROOT_CHMOD
36019 ++ select GRKERNSEC_CHROOT_FCHDIR
36020 ++ select GRKERNSEC_CHROOT_MKNOD
36021 ++ select GRKERNSEC_CHROOT_SHMAT
36022 ++ select GRKERNSEC_CHROOT_UNIX
36023 ++ select GRKERNSEC_CHROOT_FINDTASK
36024 ++ select GRKERNSEC_CHROOT_NICE
36025 ++ select GRKERNSEC_CHROOT_SYSCTL
36026 ++ select GRKERNSEC_CHROOT_CAPS
36027 ++ select GRKERNSEC_RESLOG
36028 ++ select GRKERNSEC_SIGNAL
36029 ++ select GRKERNSEC_FORKFAIL
36030 ++ select GRKERNSEC_TIME
36031 ++ select GRKERNSEC_PROC_IPADDR
36032 ++ select GRKERNSEC_EXECVE
36033 ++ select GRKERNSEC_SHM if (SYSVIPC)
36034 ++ select GRKERNSEC_DMESG
36035 ++ select GRKERNSEC_RANDNET
36036 ++ select GRKERNSEC_SYSCTL
36037 ++ select GRKERNSEC_SYSCTL_ON
36038 ++ select PAX
36039 ++ select PAX_EI_PAX
36040 ++ select PAX_PT_PAX_FLAGS
36041 ++ select PAX_HAVE_ACL_FLAGS
36042 ++ select PAX_NOEXEC
36043 ++ select PAX_PAGEEXEC
36044 ++ select PAX_SEGMEXEC if (X86 && !X86_64)
36045 ++ select PAX_EMUTRAMP if (PARISC)
36046 ++ select PAX_EMUSIGRT if (PARISC)
36047 ++ select PAX_MPROTECT
36048 ++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
36049 ++ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
36050 ++ select PAX_DLRESOLVE if (SPARC32 || SPARC64)
36051 ++ select PAX_SYSCALL if (PPC32)
36052 ++ select PAX_KERNEXEC if (X86 && !X86_64 && !EFI && !COMPAT_VDSO && !PARAVIRT && X86_WP_WORKS_OK)
36053 ++ select PAX_ASLR
36054 ++ select PAX_RANDKSTACK if (X86_TSC && !X86_64)
36055 ++ select PAX_RANDUSTACK
36056 ++ select PAX_RANDMMAP
36057 ++ select PAX_MEMORY_SANITIZE
36058 ++ select PAX_MEMORY_UDEREF if (X86_32 && !COMPAT_VDSO)
36059 ++ help
36060 ++ If you say Y here, a configuration will be used that is endorsed by the
36061 ++ Hardened Gentoo project. It is designed to provide a high level of
36062 ++ security whilst minimizing the chance of incompatibilities with rare
36063 ++ software on your machine. As such, many of the features of grsecurity
36064 ++ and PaX will be enabled. For further information, you should view
36065 ++ <http://grsecurity.net> and <http://pax.grsecurity.net> as well as the
36066 ++ Hardened Gentoo Primer at
36067 ++ <http://gentoo.org/proj/en/hardened/primer.xml>.
36068 ++
36069 ++ You may wish to emerge paxctl which will allow you to toggle specific
36070 ++ PaX features on problematic binaries. If you need to exert the same
36071 ++ degree of control over proprietary binaries (and/or binaries that were
36072 ++ not built using a hardened toolchain) then you should also emerge chpax.
36073 ++
36074 ++ When this level is selected, some options cannot be changed. However,
36075 ++ you may opt to fully customize the options that are selected by choosing
36076 ++ "Custom" in the Security Level menu. You may find it helpful to inherit
36077 ++ the options selected by the "Hardened [Gentoo]" level as a starting
36078 ++ point for further configuration. To accomplish this, select this level
36079 ++ then exit the menuconfig interface, saving changes when prompted. Next,
36080 ++ run make menuconfig again and select the "Custom" level.
36081 ++
36082 ++ Please note that this security level is not designed to be used in
36083 ++ virtualized environments. If you intend to run the kernel in a virtual
36084 ++ machine then you will probably need to disable the PAX_MEMORY_UDEREF
36085 ++ option in order to avoid an unacceptable impact upon performance.
36086 ++
36087 + config GRKERNSEC_CUSTOM
36088 + bool "Custom"
36089 + help
36090
36091 Added: hardened-sources/2.6/tags/2.6.23-7/4450_selinux-avc_audit-log-curr_ip.patch
36092 ===================================================================
36093 --- hardened-sources/2.6/tags/2.6.23-7/4450_selinux-avc_audit-log-curr_ip.patch (rev 0)
36094 +++ hardened-sources/2.6/tags/2.6.23-7/4450_selinux-avc_audit-log-curr_ip.patch 2008-04-30 11:42:53 UTC (rev 97)
36095 @@ -0,0 +1,26 @@
36096 +
36097 +Provides support for a new field ipaddr within the SELinux
36098 +AVC audit log, relying in task_struct->curr_ip (ipv4 only)
36099 +provided by grSecurity patch to be applied before.
36100 +
36101 +Signed-off-by: Lorenzo Hernandez Garcia-Hierro <lorenzo@×××.org>
36102 +---
36103 +
36104 + security/selinux/avc.c | 6 ++++++
36105 + 1 file changed, 6 insertions(+)
36106 +
36107 +--- a/security/selinux/avc.c
36108 ++++ b/security/selinux/avc.c
36109 +@@ -202,6 +202,12 @@ static void avc_dump_query(struct audit_
36110 + char *scontext;
36111 + u32 scontext_len;
36112 +
36113 ++/* CONFIG_PROC_IPADDR if task-signal-curr_ip patch from lorenzo@×××.org is present */
36114 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
36115 ++ if (current->signal->curr_ip)
36116 ++ audit_log_format(ab, "ipaddr=%u.%u.%u.%u ", NIPQUAD(current->signal->curr_ip));
36117 ++#endif /* CONFIG_GRKERNSEC_PROC_IPADDR */
36118 ++
36119 + rc = security_sid_to_context(ssid, &scontext, &scontext_len);
36120 + if (rc)
36121 + audit_log_format(ab, "ssid=%d", ssid);
36122
36123 Added: hardened-sources/2.6/tags/2.6.23-7/4455_disable-compat_vdso.patch
36124 ===================================================================
36125 --- hardened-sources/2.6/tags/2.6.23-7/4455_disable-compat_vdso.patch (rev 0)
36126 +++ hardened-sources/2.6/tags/2.6.23-7/4455_disable-compat_vdso.patch 2008-04-30 11:42:53 UTC (rev 97)
36127 @@ -0,0 +1,29 @@
36128 +From: Kerin Millar <kerframil@×××××.com>
36129 +
36130 +Disable CONFIG_COMPAT_VDSO entirely. It is inappropriate for any Gentoo
36131 +user to activate this option. Moreover, it prevents users from selecting
36132 +a number of important PaX options - notably PAX_PAGEEXEC and
36133 +PAX_SEGMEXEC. Under these circumstances, it is impossible for the user
36134 +to enforce non-executable pages. Unfortunately, this is far from obvious
36135 +to first-time users. Closes bug 210138.
36136 +
36137 +--- a/arch/i386/Kconfig 2008-02-14 17:46:47.000000000 +0000
36138 ++++ b/arch/i386/Kconfig 2008-02-14 17:57:03.000000000 +0000
36139 +@@ -915,16 +915,8 @@
36140 + /sys/devices/system/cpu.
36141 +
36142 + config COMPAT_VDSO
36143 +- bool "Compat VDSO support"
36144 ++ bool
36145 + default n
36146 +- help
36147 +- Map the VDSO to the predictable old-style address too.
36148 +- ---help---
36149 +- Say N here if you are running a sufficiently recent glibc
36150 +- version (2.3.3 or later), to remove the high-mapped
36151 +- VDSO mapping and to exclusively use the randomized VDSO.
36152 +-
36153 +- If unsure, say Y.
36154 +
36155 + endmenu
36156 +
36157
36158 Added: hardened-sources/2.6/tags/2.6.23-7/4460_pax-hook-build-error.patch
36159 ===================================================================
36160 --- hardened-sources/2.6/tags/2.6.23-7/4460_pax-hook-build-error.patch (rev 0)
36161 +++ hardened-sources/2.6/tags/2.6.23-7/4460_pax-hook-build-error.patch 2008-04-30 11:42:53 UTC (rev 97)
36162 @@ -0,0 +1,33 @@
36163 +From: Kerin Millar <kerframil@×××××.com>
36164 +
36165 +Fix build error where PAX_HOOK_ACL_FLAGS is enabled along with 32-bit
36166 +ELF support on x86_64/ia64 platforms. Closes gentoo bug 208331.
36167 +
36168 +--- a/fs/binfmt_elf.c 2008-02-09 00:01:18.000000000 +0100
36169 ++++ b/fs/binfmt_elf.c 2008-03-08 01:49:25.000000000 +0100
36170 +@@ -47,11 +47,6 @@
36171 + #include <asm/desc.h>
36172 + #endif
36173 +
36174 +-#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
36175 +-void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
36176 +-EXPORT_SYMBOL(pax_set_initial_flags_func);
36177 +-#endif
36178 +-
36179 + static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
36180 + static int load_elf_library(struct file *);
36181 + static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int);
36182 +--- a/fs/exec.c 2008-02-09 00:01:18.000000000 +0100
36183 ++++ b/fs/exec.c 2008-03-08 01:49:02.000000000 +0100
36184 +@@ -61,6 +61,11 @@
36185 + #include <linux/kmod.h>
36186 + #endif
36187 +
36188 ++#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
36189 ++void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
36190 ++EXPORT_SYMBOL(pax_set_initial_flags_func);
36191 ++#endif
36192 ++
36193 + int core_uses_pid;
36194 + char core_pattern[CORENAME_MAX_SIZE] = "core";
36195 + int suid_dumpable = 0;
36196 \ No newline at end of file
36197
36198 Added: hardened-sources/2.6/tags/2.6.23-7/4465_acct_stack_growth-null-deref.patch
36199 ===================================================================
36200 --- hardened-sources/2.6/tags/2.6.23-7/4465_acct_stack_growth-null-deref.patch (rev 0)
36201 +++ hardened-sources/2.6/tags/2.6.23-7/4465_acct_stack_growth-null-deref.patch 2008-04-30 11:42:53 UTC (rev 97)
36202 @@ -0,0 +1,42 @@
36203 +At some point the execve() code was changed in terms of how it sets up
36204 +the new task's address space, in particular, how the initial stack was
36205 +initialized, allowing "unlimited" number of args/env/etc. This was done
36206 +by making use of the already present and established mm struct of the
36207 +new task and the normal VM logic that deals with automatic userland
36208 +stack expansion.
36209 +
36210 +However, this broke assumptions elsewhere in the kernel where
36211 +current->mm was used in accounting code and which happened to be NULL
36212 +for kernel threads. In this case, acct_stack_growth() wasn't making use
36213 +of the new security_vm_enough_memory_mm() function as needed. This is
36214 +pertinent to PaX users because only PaX performs "sub-page" stack
36215 +randomization, so it can cause the one page of the initial stack to run
36216 +out and trigger a stack expansion. Unfortunately, it may be a kernel
36217 +thread that does this.
36218 +
36219 +This patch closes bug 210022. For further information:
36220 +
36221 + http://bugs.gentoo.org/show_bug.cgi?id=210022 and
36222 + http://forums.grsecurity.net/viewtopic.php?f=3&t=1873
36223 +
36224 +Thanks to cilly <cilly@××××××××××.nu> for raising the matter and tracking down
36225 +the appropriate patch.
36226 +
36227 +This patch is present in upstream grsecurity patches as of
36228 +pax-linux-2.6.24-test9.patch. This patch can be dropped for any
36229 +hardened-sources-2.6.24 based upon pax-linux-2.6.24-test9.patch or
36230 +later.
36231 +
36232 +Acked-by: Kerin Millar <kerframil@×××××.com>
36233 +
36234 +--- a/mm/mmap.c 2008-02-14 20:14:52.000000000 +0000
36235 ++++ b/mm/mmap.c 2008-02-14 20:40:19.000000000 +0000
36236 +@@ -1742,7 +1742,7 @@ static int acct_stack_growth(struct vm_a
36237 + * Overcommit.. This must be the final test, as it will
36238 + * update security statistics.
36239 + */
36240 +- if (security_vm_enough_memory(grow))
36241 ++ if (security_vm_enough_memory_mm(mm, grow))
36242 + return -ENOMEM;
36243 +
36244 + /* Ok, everything looks good - let it rip */
36245
36246 Added: hardened-sources/2.6/tags/2.6.23-7/4470_pax-vma-mirroring-fixes.patch
36247 ===================================================================
36248 --- hardened-sources/2.6/tags/2.6.23-7/4470_pax-vma-mirroring-fixes.patch (rev 0)
36249 +++ hardened-sources/2.6/tags/2.6.23-7/4470_pax-vma-mirroring-fixes.patch 2008-04-30 11:42:53 UTC (rev 97)
36250 @@ -0,0 +1,190 @@
36251 +From: Gordon Malm <bugs-gentoo-org-02@××××××.org>
36252 +
36253 +Backport of various fixes for vma mirroring bugs in SEGMEXEC from 2.6.24
36254 +branch. Closes gentoo bug 198051.
36255 +
36256 +These patches are present in upstream grsecurity patches as of
36257 +pax-linux-2.6.24.2-test29.patch. This patch can be dropped for any
36258 +hardened-sources-2.6.24 based upon pax-linux-2.6.24.2-test29.patch or
36259 +later.
36260 +
36261 +Acked-by: Kerin Millar <kerframil@×××××.com>
36262 +
36263 +diff -urP linux-2.6.23-hardened-r7-orig/mm/memory.c linux-2.6.23-hardened-r7-allfixes-r2/mm/memory.c
36264 +--- linux-2.6.23-hardened-r7-orig/mm/memory.c
36265 ++++ linux-2.6.23-hardened-r7-allfixes-r2/mm/memory.c
36266 +@@ -1777,13 +1777,13 @@
36267 + pte_unmap_nested(pte_m);
36268 + }
36269 +
36270 +-static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, spinlock_t *ptl)
36271 ++static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, pmd_t *pmd, spinlock_t *ptl)
36272 + {
36273 + struct page *page_m;
36274 + pte_t entry;
36275 +
36276 + if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC))
36277 +- return;
36278 ++ goto out;
36279 +
36280 + entry = *pte;
36281 + page_m = vm_normal_page(vma, address, entry);
36282 +@@ -1791,9 +1791,9 @@
36283 + pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl);
36284 + else if (PageAnon(page_m)) {
36285 + if (pax_find_mirror_vma(vma)) {
36286 +- spin_unlock(ptl);
36287 ++ pte_unmap_unlock(pte, ptl);
36288 + lock_page(page_m);
36289 +- spin_lock(ptl);
36290 ++ pte = pte_offset_map_lock(vma->vm_mm, pmd, address, &ptl);
36291 + if (pte_same(entry, *pte))
36292 + pax_mirror_anon_pte(vma, address, page_m, ptl);
36293 + else
36294 +@@ -1801,6 +1801,9 @@
36295 + }
36296 + } else
36297 + pax_mirror_file_pte(vma, address, page_m, ptl);
36298 ++
36299 ++out:
36300 ++ pte_unmap_unlock(pte, ptl);
36301 + }
36302 + #endif
36303 +
36304 +@@ -2871,7 +2874,8 @@
36305 + }
36306 +
36307 + #ifdef CONFIG_PAX_SEGMEXEC
36308 +- pax_mirror_pte(vma, address, pte, ptl);
36309 ++ pax_mirror_pte(vma, address, pte, pmd, ptl);
36310 ++ return 0;
36311 + #endif
36312 +
36313 + unlock:
36314 +diff -urP linux-2.6.23-hardened-r7-orig/mm/mmap.c linux-2.6.23-hardened-r7-allfixes-r2/mm/mmap.c
36315 +--- linux-2.6.23-hardened-r7-orig/mm/mmap.c
36316 ++++ linux-2.6.23-hardened-r7-allfixes-r2/mm/mmap.c
36317 +@@ -877,6 +877,19 @@
36318 + if (area_m)
36319 + vma_adjust(area_m, addr_m, next_m->vm_end,
36320 + next_m->vm_pgoff - pglen, NULL);
36321 ++ else if (next_m) {
36322 ++ vma_adjust(next_m, addr_m, next_m->vm_end,
36323 ++ next_m->vm_pgoff - pglen, NULL);
36324 ++ BUG_ON(area == next);
36325 ++ BUG_ON(area->vm_mirror);
36326 ++ BUG_ON(next_m->anon_vma && next_m->anon_vma != area->anon_vma);
36327 ++ area->vm_mirror = next_m;
36328 ++ next_m->vm_mirror = area;
36329 ++ if (area->anon_vma && !next_m->anon_vma) {
36330 ++ next_m->anon_vma = area->anon_vma;
36331 ++ anon_vma_link(next_m);
36332 ++ }
36333 ++ }
36334 + #endif
36335 +
36336 + }
36337 +@@ -1244,9 +1257,8 @@
36338 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) {
36339 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
36340 + if (!vma_m) {
36341 +- kmem_cache_free(vm_area_cachep, vma);
36342 + error = -ENOMEM;
36343 +- goto unacct_error;
36344 ++ goto free_vma;
36345 + }
36346 + }
36347 + #endif
36348 +@@ -1274,6 +1286,19 @@
36349 + if (error)
36350 + goto unmap_and_free_vma;
36351 +
36352 ++#ifdef CONFIG_PAX_SEGMEXEC
36353 ++ if (vma_m) {
36354 ++ struct mempolicy *pol;
36355 ++
36356 ++ pol = mpol_copy(vma_policy(vma));
36357 ++ if (IS_ERR(pol)) {
36358 ++ mpol_free(vma_policy(vma));
36359 ++ goto unmap_and_free_vma;
36360 ++ }
36361 ++ vma_set_policy(vma_m, pol);
36362 ++ }
36363 ++#endif
36364 ++
36365 + #if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
36366 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) {
36367 + vma->vm_flags |= VM_PAGEEXEC;
36368 +@@ -1328,6 +1353,14 @@
36369 + mpol_free(vma_policy(vma));
36370 + kmem_cache_free(vm_area_cachep, vma);
36371 + vma = NULL;
36372 ++
36373 ++#ifdef CONFIG_PAX_SEGMEXEC
36374 ++ if (vma_m) {
36375 ++ mpol_free(vma_policy(vma_m));
36376 ++ kmem_cache_free(vm_area_cachep, vma_m);
36377 ++ }
36378 ++#endif
36379 ++
36380 + }
36381 + out:
36382 + mm->total_vm += len >> PAGE_SHIFT;
36383 +@@ -2539,6 +2572,8 @@
36384 + struct rb_node **rb_link, *rb_parent;
36385 + struct mempolicy *pol;
36386 +
36387 ++ BUG_ON(vma->vm_mirror);
36388 ++
36389 + /*
36390 + * If anonymous vma has not yet been faulted, update new pgoff
36391 + * to match new location, to increase its chance of merging.
36392 +@@ -2584,10 +2619,14 @@
36393 + {
36394 + struct vm_area_struct *prev_m;
36395 + struct rb_node **rb_link_m, *rb_parent_m;
36396 ++ struct mempolicy *pol_m;
36397 +
36398 + BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC));
36399 +- BUG_ON(vma->vm_mirror || vma_m->vm_mirror || vma_policy(vma));
36400 ++ BUG_ON(vma->vm_mirror || vma_m->vm_mirror);
36401 ++ BUG_ON(!vma_mpol_equal(vma, vma_m));
36402 ++ pol_m = vma_policy(vma_m);
36403 + *vma_m = *vma;
36404 ++ vma_set_policy(vma_m, pol_m);
36405 + vma_m->vm_start += SEGMEXEC_TASK_SIZE;
36406 + vma_m->vm_end += SEGMEXEC_TASK_SIZE;
36407 + vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED);
36408 +diff -urP linux-2.6.23-hardened-r7-orig/mm/mprotect.c linux-2.6.23-hardened-r7-allfixes-r2/mm/mprotect.c
36409 +--- linux-2.6.23-hardened-r7-orig/mm/mprotect.c
36410 ++++ linux-2.6.23-hardened-r7-allfixes-r2/mm/mprotect.c
36411 +@@ -208,6 +208,8 @@
36412 + error = split_vma(mm, vma, start, 1);
36413 + if (error)
36414 + return -ENOMEM;
36415 ++ BUG_ON(!*pprev || (*pprev)->vm_next == vma);
36416 ++ *pprev = (*pprev)->vm_next;
36417 + }
36418 +
36419 + if (end != vma->vm_end) {
36420 +@@ -266,11 +268,20 @@
36421 +
36422 + #ifdef CONFIG_PAX_SEGMEXEC
36423 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(oldflags & VM_EXEC) && (newflags & VM_EXEC)) {
36424 ++ struct mempolicy *pol;
36425 ++
36426 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
36427 + if (!vma_m) {
36428 + error = -ENOMEM;
36429 + goto fail;
36430 + }
36431 ++ pol = mpol_copy(vma_policy(vma));
36432 ++ if (IS_ERR(pol)) {
36433 ++ kmem_cache_free(vm_area_cachep, vma_m);
36434 ++ error = -ENOMEM;
36435 ++ goto fail;
36436 ++ }
36437 ++ vma_set_policy(vma_m, pol);
36438 + }
36439 + #endif
36440 +
36441
36442 Added: hardened-sources/2.6/tags/2.6.23-7/4475_vesafb-pmi-kernexec-fix.patch
36443 ===================================================================
36444 --- hardened-sources/2.6/tags/2.6.23-7/4475_vesafb-pmi-kernexec-fix.patch (rev 0)
36445 +++ hardened-sources/2.6/tags/2.6.23-7/4475_vesafb-pmi-kernexec-fix.patch 2008-04-30 11:42:53 UTC (rev 97)
36446 @@ -0,0 +1,60 @@
36447 +From: Kerin Millar <kerframil@×××××.com>
36448 +
36449 +Disable the use of pmi in the vesafb framebuffer driver where the kernel
36450 +is non-modular and PAX_KERNEXEC is enabled, thus resolving a compile
36451 +error. Closes bug 197626.
36452 +
36453 +This patch is present in upstream grsecurity patches as of
36454 +pax-linux-2.6.24.2-test24.patch. This patch can be dropped for any
36455 +hardened-sources-2.6.24 based upon pax-linux-2.6.24.2-test24.patch or
36456 +later.
36457 +
36458 +--- a/drivers/video/vesafb.c 2008-02-14 20:14:52.000000000 +0000
36459 ++++ b/drivers/video/vesafb.c 2008-02-17 21:37:44.000000000 +0000
36460 +@@ -302,10 +302,10 @@ static int __init vesafb_probe(struct pl
36461 +
36462 + #ifdef __i386__
36463 +
36464 +-#ifdef CONFIG_PAX_KERNEXEC
36465 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
36466 + pmi_code = module_alloc_exec(screen_info.vesapm_size);
36467 + if (!pmi_code)
36468 +-#else
36469 ++#elif !defined(CONFIG_PAX_KERNEXEC)
36470 + if (0)
36471 + #endif
36472 +
36473 +@@ -323,13 +323,13 @@ static int __init vesafb_probe(struct pl
36474 + if (ypan || pmi_setpal) {
36475 + unsigned short *pmi_base;
36476 +
36477 +-#ifdef CONFIG_PAX_KERNEXEC
36478 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
36479 + unsigned long cr0;
36480 + #endif
36481 +
36482 + pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
36483 +
36484 +-#ifdef CONFIG_PAX_KERNEXEC
36485 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
36486 + pax_open_kernel(cr0);
36487 + memcpy(pmi_code, pmi_base, screen_info.vesapm_size);
36488 + pax_close_kernel(cr0);
36489 +@@ -340,7 +340,7 @@ static int __init vesafb_probe(struct pl
36490 + pmi_start = (void*)((char*)pmi_code + pmi_base[1]);
36491 + pmi_pal = (void*)((char*)pmi_code + pmi_base[2]);
36492 +
36493 +-#ifdef CONFIG_PAX_KERNEXEC
36494 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
36495 + pmi_start -= __KERNEL_TEXT_OFFSET;
36496 + pmi_pal -= __KERNEL_TEXT_OFFSET;
36497 + #endif
36498 +@@ -487,7 +487,7 @@ static int __init vesafb_probe(struct pl
36499 + return 0;
36500 + err:
36501 +
36502 +-#ifdef CONFIG_PAX_KERNEXEC
36503 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
36504 + module_free_exec(NULL, pmi_code);
36505 + #endif
36506 +
36507
36508 Added: hardened-sources/2.6/tags/2.6.23-7/4480_deselect-kernexec-on-unsupported-arches.patch
36509 ===================================================================
36510 --- hardened-sources/2.6/tags/2.6.23-7/4480_deselect-kernexec-on-unsupported-arches.patch (rev 0)
36511 +++ hardened-sources/2.6/tags/2.6.23-7/4480_deselect-kernexec-on-unsupported-arches.patch 2008-04-30 11:42:53 UTC (rev 97)
36512 @@ -0,0 +1,30 @@
36513 +From: nixnut <nixnut@g.o>
36514 +
36515 +KERNEXEC should probably only be enabled on x86 because otherwise
36516 +module.c will look for a header file that doesn't exist on most arches:
36517 +
36518 +#ifdef CONFIG_PAX_KERNEXEC
36519 +#include <asm/desc.h>
36520 +#endif
36521 +
36522 +Currently it is also enabled on ppc if the security level is set to
36523 +'high' (GRKERNSEC_HIGH).
36524 +
36525 +KERNEXEC is supported on amd64/x86-64 in grsecurity upstream for
36526 +linux kernel 2.6.24.2. This patch should therefore probably be
36527 +dropped for any hardened-sources-2.6.24 based upon grsecurity
36528 +patches for linux kernel 2.6.24.2.
36529 +
36530 +Acked-by: Kerin Millar <kerframil@×××××.com>
36531 +
36532 +--- a/grsecurity/Kconfig 2008-02-14 22:07:34.000000000 +0100
36533 ++++ b/grsecurity/Kconfig 2008-02-15 17:34:37.000000000 +0100
36534 +@@ -143,7 +143,7 @@
36535 + select PAX_EI_PAX
36536 + select PAX_PT_PAX_FLAGS
36537 + select PAX_HAVE_ACL_FLAGS
36538 +- select PAX_KERNEXEC if (!X86_64 && !EFI && !COMPAT_VDSO && !PARAVIRT && X86_WP_WORKS_OK)
36539 ++ select PAX_KERNEXEC if (X86 && !X86_64 && !EFI && !COMPAT_VDSO && !PARAVIRT && X86_WP_WORKS_OK)
36540 + select PAX_MEMORY_UDEREF if (!X86_64 && !COMPAT_VDSO)
36541 + select PAX_RANDKSTACK if (X86_TSC && !X86_64)
36542 + select PAX_SEGMEXEC if (X86 && !X86_64)
36543
36544 Added: hardened-sources/2.6/tags/2.6.23-7/4485_ia64-modular-kernel-compile-fix.patch
36545 ===================================================================
36546 --- hardened-sources/2.6/tags/2.6.23-7/4485_ia64-modular-kernel-compile-fix.patch (rev 0)
36547 +++ hardened-sources/2.6/tags/2.6.23-7/4485_ia64-modular-kernel-compile-fix.patch 2008-04-30 11:42:53 UTC (rev 97)
36548 @@ -0,0 +1,22 @@
36549 +From: Gordon Malm <bugs-gentoo-org-02@××××××.org>
36550 +
36551 +ia64: Fix kernel compile failure with loadable module support enabled.
36552 +
36553 +This patch is present in upstream grsecurity patches as of
36554 +pax-linux-2.6.24.1-test12.patch. This patch can be dropped for any
36555 +hardened-sources-2.6.24 based upon pax-linux-2.6.24.1-test12.patch or
36556 +later.
36557 +
36558 +Acked-by: Kerin Millar <kerframil@×××××.com>
36559 +
36560 +--- a/arch/ia64/kernel/module.c
36561 ++++ b/arch/ia64/kernel/module.c
36562 +@@ -531,7 +531,7 @@ in_core_rw (const struct module *mod, ui
36563 + static inline int
36564 + in_core (const struct module *mod, uint64_t addr)
36565 + {
36566 +- return in_core_rx(mod, value) || in_core_rw(mod, value);
36567 ++ return in_core_rx(mod, addr) || in_core_rw(mod, addr);
36568 + }
36569 +
36570 + static inline int
36571
36572 Added: hardened-sources/2.6/tags/2.6.23-7/4490_grsec-ptrace-recursive-lock-fix.patch
36573 ===================================================================
36574 --- hardened-sources/2.6/tags/2.6.23-7/4490_grsec-ptrace-recursive-lock-fix.patch (rev 0)
36575 +++ hardened-sources/2.6/tags/2.6.23-7/4490_grsec-ptrace-recursive-lock-fix.patch 2008-04-30 11:42:53 UTC (rev 97)
36576 @@ -0,0 +1,22 @@
36577 +From: Gordon Malm <bugs-gentoo-org-02@××××××.org>
36578 +
36579 +Fix a recursive lock -- call to capable() within ptrace_attach().
36580 +
36581 +This patch is present in upstream grsecurity patches as of
36582 +grsecurity-2.1.11-2.6.24.3-200803131725.patch. This patch can
36583 +be dropped for any hardened-sources-2.6.24 based on
36584 +grsecurity-2.1.11-2.6.24.3-200803131725.patch or later.
36585 +
36586 +Acked-by: Kerin Millar <kerframil@×××××.com>
36587 +
36588 +--- a/kernel/ptrace.c
36589 ++++ b/kernel/ptrace.c
36590 +@@ -203,7 +203,7 @@ repeat:
36591 + /* Go */
36592 + task->ptrace |= PT_PTRACED | ((task->real_parent != current)
36593 + ? PT_ATTACHED : 0);
36594 +- if (capable(CAP_SYS_PTRACE))
36595 ++ if (capable_nolog(CAP_SYS_PTRACE))
36596 + task->ptrace |= PT_PTRACE_CAP;
36597 +
36598 + __ptrace_link(task, current);
36599
36600 Added: hardened-sources/2.6/tags/2.6.23-7/4495_grsec-netlink-security-fixes.patch
36601 ===================================================================
36602 --- hardened-sources/2.6/tags/2.6.23-7/4495_grsec-netlink-security-fixes.patch (rev 0)
36603 +++ hardened-sources/2.6/tags/2.6.23-7/4495_grsec-netlink-security-fixes.patch 2008-04-30 11:42:53 UTC (rev 97)
36604 @@ -0,0 +1,162 @@
36605 +From: Gordon Malm <bugs-gentoo-org-02@××××××.org>
36606 +
36607 +Fix bug that allows audit and iscsi operations to be controlled
36608 +via netlink; it should be disallowed by grsec.
36609 +
36610 +More info @ https://bugs.gentoo.org/show_bug.cgi?id=213254
36611 +
36612 +This is grsecurity upstreams' version of the patch submitted
36613 +in the aforementioned bug.
36614 +
36615 +Thanks to cilly <cilly@××××××××××.nu> for bringing the patch to
36616 +our attention. Thanks to Kerin Millar <kerframil@×××××.com> for
36617 +following up with the author of the original patch and reporting
36618 +the matter upstream.
36619 +
36620 +This patch is present in upstream grsecurity patches as of
36621 +grsecurity-2.1.11-2.6.24.3-200803172136.patch. This patch can
36622 +be dropped for any hardened-sources-2.6.24 based on
36623 +grsecurity-2.1.11-2.6.24.3-200803172136.patch or later.
36624 +
36625 +Acked-by: Kerin Millar <kerframil@×××××.com>
36626 +
36627 +--- a/drivers/pci/proc.c
36628 ++++ b/drivers/pci/proc.c
36629 +@@ -469,7 +469,7 @@ static int __init pci_proc_init(void)
36630 + #ifdef CONFIG_GRKERNSEC_PROC_ADD
36631 + #ifdef CONFIG_GRKERNSEC_PROC_USER
36632 + proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus);
36633 +-#elif CONFIG_GRKERNSEC_PROC_USERGROUP
36634 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
36635 + proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus);
36636 + #endif
36637 + #else
36638 +--- a/fs/proc/base.c
36639 ++++ b/fs/proc/base.c
36640 +@@ -1102,7 +1102,7 @@ static int pid_getattr(struct vfsmount *
36641 + if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
36642 + #ifdef CONFIG_GRKERNSEC_PROC_USER
36643 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
36644 +-#elif CONFIG_GRKERNSEC_PROC_USERGROUP
36645 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
36646 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
36647 + #endif
36648 + task_dumpable(task)) {
36649 +@@ -1144,7 +1144,7 @@ static int pid_revalidate(struct dentry
36650 + if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
36651 + #ifdef CONFIG_GRKERNSEC_PROC_USER
36652 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
36653 +-#elif CONFIG_GRKERNSEC_PROC_USERGROUP
36654 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
36655 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
36656 + #endif
36657 + task_dumpable(task)) {
36658 +@@ -2265,7 +2265,7 @@ static struct dentry *proc_pid_instantia
36659 +
36660 + #ifdef CONFIG_GRKERNSEC_PROC_USER
36661 + inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
36662 +-#elif CONFIG_GRKERNSEC_PROC_USERGROUP
36663 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
36664 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
36665 + inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP;
36666 + #else
36667 +--- a/grsecurity/grsec_sock.c
36668 ++++ b/grsecurity/grsec_sock.c
36669 +@@ -16,6 +16,7 @@ extern struct sock *udp_v4_lookup(u32 sa
36670 + EXPORT_SYMBOL(udp_v4_lookup);
36671 + #endif
36672 +
36673 ++__u32 gr_cap_rtnetlink(struct sock *sock);
36674 + EXPORT_SYMBOL(gr_cap_rtnetlink);
36675 +
36676 + extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
36677 +@@ -247,11 +248,21 @@ gr_handle_sock_client(const struct socka
36678 + }
36679 +
36680 + __u32
36681 +-gr_cap_rtnetlink(void)
36682 ++gr_cap_rtnetlink(struct sock *sock)
36683 + {
36684 + #ifdef CONFIG_GRKERNSEC
36685 + if (!gr_acl_is_enabled())
36686 + return current->cap_effective;
36687 ++ else if (sock->sk_protocol == NETLINK_ISCSI &&
36688 ++ cap_raised(current->cap_effective, CAP_SYS_ADMIN) &&
36689 ++ gr_task_is_capable(current, CAP_SYS_ADMIN))
36690 ++ return current->cap_effective;
36691 ++ else if (sock->sk_protocol == NETLINK_AUDIT &&
36692 ++ cap_raised(current->cap_effective, CAP_AUDIT_WRITE) &&
36693 ++ gr_task_is_capable(current, CAP_AUDIT_WRITE) &&
36694 ++ cap_raised(current->cap_effective, CAP_AUDIT_CONTROL) &&
36695 ++ gr_task_is_capable(current, CAP_AUDIT_CONTROL))
36696 ++ return current->cap_effective;
36697 + else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
36698 + gr_task_is_capable(current, CAP_NET_ADMIN))
36699 + return current->cap_effective;
36700 +--- a/include/linux/grsecurity.h
36701 ++++ b/include/linux/grsecurity.h
36702 +@@ -167,7 +167,6 @@ __u32 gr_acl_handle_unix(const struct de
36703 + void gr_acl_handle_exit(void);
36704 + void gr_acl_handle_psacct(struct task_struct *task, const long code);
36705 + int gr_acl_handle_procpidmem(const struct task_struct *task);
36706 +-__u32 gr_cap_rtnetlink(void);
36707 +
36708 + #ifdef CONFIG_SYSVIPC
36709 + void gr_shm_exit(struct task_struct *task);
36710 +--- a/kernel/configs.c
36711 ++++ b/kernel/configs.c
36712 +@@ -82,7 +82,7 @@ static int __init ikconfig_init(void)
36713 + #ifdef CONFIG_GRKERNSEC_PROC_ADD
36714 + #ifdef CONFIG_GRKERNSEC_PROC_USER
36715 + entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root);
36716 +-#elif CONFIG_GRKERNSEC_PROC_USERGROUP
36717 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
36718 + entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root);
36719 + #endif
36720 + #else
36721 +--- a/kernel/kallsyms.c
36722 ++++ b/kernel/kallsyms.c
36723 +@@ -496,7 +496,7 @@ static int __init kallsyms_init(void)
36724 + #ifdef CONFIG_GRKERNSEC_PROC_ADD
36725 + #ifdef CONFIG_GRKERNSEC_PROC_USER
36726 + entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL);
36727 +-#elif CONFIG_GRKERNSEC_PROC_USERGROUP
36728 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
36729 + entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL);
36730 + #endif
36731 + #else
36732 +--- a/kernel/resource.c
36733 ++++ b/kernel/resource.c
36734 +@@ -136,7 +136,7 @@ static int __init ioresources_init(void)
36735 + #ifdef CONFIG_GRKERNSEC_PROC_ADD
36736 + #ifdef CONFIG_GRKERNSEC_PROC_USER
36737 + entry = create_proc_entry("ioports", S_IRUSR, NULL);
36738 +-#elif CONFIG_GRKERNSEC_PROC_USERGROUP
36739 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
36740 + entry = create_proc_entry("ioports", S_IRUSR | S_IRGRP, NULL);
36741 + #endif
36742 + #else
36743 +@@ -148,7 +148,7 @@ static int __init ioresources_init(void)
36744 + #ifdef CONFIG_GRKERNSEC_PROC_ADD
36745 + #ifdef CONFIG_GRKERNSEC_PROC_USER
36746 + entry = create_proc_entry("iomem", S_IRUSR, NULL);
36747 +-#elif CONFIG_GRKERNSEC_PROC_USERGROUP
36748 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
36749 + entry = create_proc_entry("iomem", S_IRUSR | S_IRGRP, NULL);
36750 + #endif
36751 + #else
36752 +--- a/security/commoncap.c
36753 ++++ b/security/commoncap.c
36754 +@@ -24,9 +24,11 @@
36755 + #include <linux/hugetlb.h>
36756 + #include <linux/grsecurity.h>
36757 +
36758 ++extern __u32 gr_cap_rtnetlink(struct sock *sk);
36759 ++
36760 + int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
36761 + {
36762 +- NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink();
36763 ++ NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink(sk);
36764 + return 0;
36765 + }
36766 +
36767
36768 --
36769 gentoo-commits@l.g.o mailing list