Gentoo Archives: gentoo-commits

From: "Gordon Malm (gengor)" <gengor@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] linux-patches r1479 - in hardened/2.6/tags: . 2.6.26-9
Date: Tue, 20 Jan 2009 21:33:02
Message-Id: E1LPOAW-0004pF-3d@stork.gentoo.org
1 Author: gengor
2 Date: 2009-01-20 21:29:55 +0000 (Tue, 20 Jan 2009)
3 New Revision: 1479
4
5 Added:
6 hardened/2.6/tags/2.6.26-9/
7 hardened/2.6/tags/2.6.26-9/0000_README
8 hardened/2.6/tags/2.6.26-9/1401_cgroups-fix-invalid-cgrp-dentry-before-cgroup-has-been-completely-removed.patch
9 hardened/2.6/tags/2.6.26-9/1402_cpqarry-fix-return-value-of-cpqarray_init.patch
10 hardened/2.6/tags/2.6.26-9/1403_ext3-wait-on-all-pending-commits-in-ext3_sync_fs.patch
11 hardened/2.6/tags/2.6.26-9/1404_hid-fix-incorrent-length-condition-in-hidraw_write.patch
12 hardened/2.6/tags/2.6.26-9/1405_i-oat-fix-async_tx.callback-checking.patch
13 hardened/2.6/tags/2.6.26-9/1406_i-oat-fix-channel-resources-free-for-not-allocated-channels.patch
14 hardened/2.6/tags/2.6.26-9/1407_i-oat-fix-dma_pin_iovec_pages-error-handling.patch
15 hardened/2.6/tags/2.6.26-9/1408_jffs2-fix-lack-of-locking-in-thread_should_wake.patch
16 hardened/2.6/tags/2.6.26-9/1409_jffs2-fix-race-condition-in-jffs2_lzo_compress.patch
17 hardened/2.6/tags/2.6.26-9/1410_keys-make-request-key-instantiate-the-per-user-keyrings.patch
18 hardened/2.6/tags/2.6.26-9/1411_md-linear-fix-a-division-by-zero-bug-for-very-small-arrays.patch
19 hardened/2.6/tags/2.6.26-9/1412_mmc-increase-sd-write-timeout-for-crappy-cards.patch
20 hardened/2.6/tags/2.6.26-9/1413_net-unix-fix-inflight-counting-bug-in-garbage-collector.patch
21 hardened/2.6/tags/2.6.26-9/1414_acpi-avoid-empty-file-name-in-sysfs.patch
22 hardened/2.6/tags/2.6.26-9/1415_block-fix-nr_phys_segments-miscalculation-bug.patch
23 hardened/2.6/tags/2.6.26-9/1416_dm-raid1-flush-workqueue-before-destruction.patch
24 hardened/2.6/tags/2.6.26-9/1417_net-fix-proc-net-snmp-as-memory-corruptor.patch
25 hardened/2.6/tags/2.6.26-9/1418_touch_mnt_namespace-when-the-mount-flags-change.patch
26 hardened/2.6/tags/2.6.26-9/1419_usb-don-t-register-endpoints-for-interfaces-that-are-going-away.patch
27 hardened/2.6/tags/2.6.26-9/1420_usb-ehci-fix-divide-by-zero-bug.patch
28 hardened/2.6/tags/2.6.26-9/1421_usb-ehci-fix-handling-of-dead-controllers.patch
29 hardened/2.6/tags/2.6.26-9/1422_usb-fix-ps3-usb-shutdown-problems.patch
30 hardened/2.6/tags/2.6.26-9/1423_v4l-dvb-cve-2008-5033-fix-oops-on-tvaudio-when-controlling-bass-treble.patch
31 hardened/2.6/tags/2.6.26-9/1424_atm-cve-2008-5079-duplicate-listen-on-socket-corrupts-the-vcc-table.patch
32 hardened/2.6/tags/2.6.26-9/1425_enforce-a-minimum-sg_io-timeout.patch
33 hardened/2.6/tags/2.6.26-9/1506_sctp-avoid_memory_overflow_with_bad_stream_ID.patch
34 hardened/2.6/tags/2.6.26-9/4420_grsec-2.1.12-2.6.26.6-200810131006.patch
35 hardened/2.6/tags/2.6.26-9/4421_grsec-remove-localversion-grsec.patch
36 hardened/2.6/tags/2.6.26-9/4422_grsec-mute-warnings.patch
37 hardened/2.6/tags/2.6.26-9/4425_grsec-pax-without-grsec.patch
38 hardened/2.6/tags/2.6.26-9/4430_grsec-kconfig-default-gids.patch
39 hardened/2.6/tags/2.6.26-9/4435_grsec-kconfig-gentoo.patch
40 hardened/2.6/tags/2.6.26-9/4440_selinux-avc_audit-log-curr_ip.patch
41 hardened/2.6/tags/2.6.26-9/4445_disable-compat_vdso.patch
42 hardened/2.6/tags/2.6.26-9/4450_pax-2.6.26.7-test32-to-test33.patch
43 hardened/2.6/tags/2.6.26-9/4455_grsec-make-PAX_REFCOUNT-conditional-on-x86.patch
44 hardened/2.6/tags/2.6.26-9/4460_pax-fix-mmap-BUG_ON-task-size-check.patch
45 hardened/2.6/tags/2.6.26-9/4465_pax-fix-false-RLIMIT_STACK-warnings.patch
46 Log:
47 Tag 2.6.26-9 hardened-extras patchset
48
49 Added: hardened/2.6/tags/2.6.26-9/0000_README
50 ===================================================================
51 --- hardened/2.6/tags/2.6.26-9/0000_README (rev 0)
52 +++ hardened/2.6/tags/2.6.26-9/0000_README 2009-01-20 21:29:55 UTC (rev 1479)
53 @@ -0,0 +1,78 @@
54 +README
55 +-----------------------------------------------------------------------------
56 +
57 +Individual Patch Descriptions:
58 +-----------------------------------------------------------------------------
59 +Patch: 1401* -> 1413*
60 +From: http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git;
61 + a=commit;h=ff413e9814b3914ddf3d4634e9a6cc1c6b21e787
62 +Desc: Backported subset of 2.6.27.6 -stable release patches
63 +
64 +Patch: 1414* -> 1423*
65 +From: http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git;
66 + a=commit;h=526550b7f86d9d395ee1b27ed804e6ffc3feb17c
67 +Desc: Backported subset of 2.6.27.7 -stable release patches
68 +
69 +Patch: 1424* -> 1425*
70 +From: http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git;
71 + a=commit;h=2ef6627be7502193f7c42f694a651fa710507089
72 +Desc: Backported subset of 2.6.27.9 -stable release patches
73 +
74 +Patch: 1506_sctp-avoid_memory_overflow_with_bad_stream_ID.patch
75 +From: Wei Yongjun <yjwei@××××××××××.com>
76 +Desc: Avoid memory overflow while FWD-TSN chunk received with bad stream ID
77 + (bug #254907)
78 +
79 +Patch: 4420_grsec-2.1.12-2.6.26.6-200810131006.patch
80 +From: http://www.grsecurity.net
81 +Desc: hardened-sources base patch from upstream grsecurity
82 +
83 +Patch: 4421_grsec-remove-localversion-grsec.patch
84 +From: Kerin Millar <kerframil@×××××.com>
85 +Desc: Removes grsecurity's localversion-grsec file
86 +
87 +Patch: 4422_grsec-mute-warnings.patch
88 +From: Alexander Gabert <gaberta@××××××××.de>
89 + Gordon Malm <gengor@g.o>
90 +Desc: Removes verbose compile warning settings from grsecurity, restores
91 + mainline Linux kernel behavior
92 +
93 +Patch: 4425_grsec-pax-without-grsec.patch
94 +From: Gordon Malm <gengor@g.o>
95 +Desc: Allows PaX features to be selected without enabling GRKERNSEC
96 +
97 +Patch: 4430_grsec-kconfig-default-gids.patch
98 +From: Kerin Millar <kerframil@×××××.com>
99 +Desc: Sets sane(r) default GIDs on various grsecurity group-dependent
100 + features
101 +
102 +Patch: 4435_grsec-kconfig-gentoo.patch
103 +From: Gordon Malm <gengor@g.o>
104 + Kerin Millar <kerframil@×××××.com>
105 +Desc: Adds Hardened Gentoo [server/workstation] security levels, sets
106 + Hardened Gentoo [workstation] as default
107 +
108 +Patch: 4440_selinux-avc_audit-log-curr_ip.patch
109 +From: Gordon Malm <gengor@g.o>
110 +Desc: Configurable option to add src IP address to SELinux log messages
111 +
112 +Patch: 4445_disable-compat_vdso.patch
113 +From: Gordon Malm <gengor@g.o>
114 + Kerin Millar <kerframil@×××××.com>
115 +Desc: Disables VDSO_COMPAT operation completely
116 +
117 +Patch: 4450_pax-2.6.26.7-test32-to-test33.patch
118 +From: Gordon Malm <gengor@g.o>
119 +Desc: Adds PaX changes from pax-2.6.26.7-test33
120 +
121 +Patch: 4455_grsec-make-PAX_REFCOUNT-conditional-on-x86.patch
122 +From: Gordon Malm <gengor@g.o>
123 +Desc: Make selection of PAX_REFCOUNT depend on X86 (bug #246763)
124 +
125 +Patch: 4460_pax-fix-mmap-BUG_ON-task-size-check.patch
126 +From: Gordon Malm <gengor@g.o>
127 +Desc: Fix incorrect vma task size check under SEGMEXEC
128 +
129 +Patch: 4465_pax-fix-false-RLIMIT_STACK-warnings.patch
130 +From: Gordon Malm <gengor@g.o>
131 +Desc: Fix false-positive RLIMIT_STACK warnings
132
133 Added: hardened/2.6/tags/2.6.26-9/1401_cgroups-fix-invalid-cgrp-dentry-before-cgroup-has-been-completely-removed.patch
134 ===================================================================
135 --- hardened/2.6/tags/2.6.26-9/1401_cgroups-fix-invalid-cgrp-dentry-before-cgroup-has-been-completely-removed.patch (rev 0)
136 +++ hardened/2.6/tags/2.6.26-9/1401_cgroups-fix-invalid-cgrp-dentry-before-cgroup-has-been-completely-removed.patch 2009-01-20 21:29:55 UTC (rev 1479)
137 @@ -0,0 +1,65 @@
138 +Added-By: Gordon Malm <gengor@g.o>
139 +
140 +---
141 +
142 +From jejb@××××××.org Mon Nov 10 15:14:35 2008
143 +From: Li Zefan <lizf@××××××××××.com>
144 +Date: Fri, 7 Nov 2008 00:05:48 GMT
145 +Subject: cgroups: fix invalid cgrp->dentry before cgroup has been completely removed
146 +To: stable@××××××.org
147 +Message-ID: <200811070005.mA705mbU003066@×××××××××××.org>
148 +
149 +From: Li Zefan <lizf@××××××××××.com>
150 +
151 +commit 24eb089950ce44603b30a3145a2c8520e2b55bb1 upstream
152 +
153 +This fixes an oops when reading /proc/sched_debug.
154 +
155 +A cgroup won't be removed completely until finishing cgroup_diput(), so we
156 +shouldn't invalidate cgrp->dentry in cgroup_rmdir(). Otherwise, when a
157 +group is being removed while cgroup_path() gets called, we may trigger
158 +NULL dereference BUG.
159 +
160 +The bug can be reproduced:
161 +
162 + # cat test.sh
163 + #!/bin/sh
164 + mount -t cgroup -o cpu xxx /mnt
165 + for (( ; ; ))
166 + {
167 + mkdir /mnt/sub
168 + rmdir /mnt/sub
169 + }
170 + # ./test.sh &
171 + # cat /proc/sched_debug
172 +
173 +BUG: unable to handle kernel NULL pointer dereference at 00000038
174 +IP: [<c045a47f>] cgroup_path+0x39/0x90
175 +..
176 +Call Trace:
177 + [<c0420344>] ? print_cfs_rq+0x6e/0x75d
178 + [<c0421160>] ? sched_debug_show+0x72d/0xc1e
179 +..
180 +
181 +Signed-off-by: Li Zefan <lizf@××××××××××.com>
182 +Acked-by: Paul Menage <menage@××××××.com>
183 +Cc: Peter Zijlstra <a.p.zijlstra@××××××.nl>
184 +Cc: Ingo Molnar <mingo@××××.hu>
185 +Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org>
186 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
187 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
188 +
189 +---
190 + kernel/cgroup.c | 1 -
191 + 1 file changed, 1 deletion(-)
192 +
193 +--- a/kernel/cgroup.c
194 ++++ b/kernel/cgroup.c
195 +@@ -2443,7 +2443,6 @@ static int cgroup_rmdir(struct inode *un
196 + list_del(&cgrp->sibling);
197 + spin_lock(&cgrp->dentry->d_lock);
198 + d = dget(cgrp->dentry);
199 +- cgrp->dentry = NULL;
200 + spin_unlock(&d->d_lock);
201 +
202 + cgroup_d_remove_dir(d);
203
204 Added: hardened/2.6/tags/2.6.26-9/1402_cpqarry-fix-return-value-of-cpqarray_init.patch
205 ===================================================================
206 --- hardened/2.6/tags/2.6.26-9/1402_cpqarry-fix-return-value-of-cpqarray_init.patch (rev 0)
207 +++ hardened/2.6/tags/2.6.26-9/1402_cpqarry-fix-return-value-of-cpqarray_init.patch 2009-01-20 21:29:55 UTC (rev 1479)
208 @@ -0,0 +1,55 @@
209 +Added-By: Gordon Malm <gengor@g.o>
210 +
211 +---
212 +
213 +From 2197d18ded232ef6eef63cce57b6b21eddf1b7b6 Mon Sep 17 00:00:00 2001
214 +From: Andrey Borzenkov <arvidjaar@××××.ru>
215 +Date: Thu, 6 Nov 2008 12:53:15 -0800
216 +Subject: cpqarry: fix return value of cpqarray_init()
217 +
218 +From: Andrey Borzenkov <arvidjaar@××××.ru>
219 +
220 +commit 2197d18ded232ef6eef63cce57b6b21eddf1b7b6 upstream.
221 +
222 +As reported by Dick Gevers on Compaq ProLiant:
223 +
224 +Oct 13 18:06:51 dvgcpl kernel: Compaq SMART2 Driver (v 2.6.0)
225 +Oct 13 18:06:51 dvgcpl kernel: sys_init_module: 'cpqarray'->init
226 +suspiciously returned 1, it should follow 0/-E convention
227 +Oct 13 18:06:51 dvgcpl kernel: sys_init_module: loading module anyway...
228 +Oct 13 18:06:51 dvgcpl kernel: Pid: 315, comm: modprobe Not tainted
229 +2.6.27-desktop-0.rc8.2mnb #1
230 +Oct 13 18:06:51 dvgcpl kernel: [<c0380612>] ? printk+0x18/0x1e
231 +Oct 13 18:06:51 dvgcpl kernel: [<c0158f85>] sys_init_module+0x155/0x1c0
232 +Oct 13 18:06:51 dvgcpl kernel: [<c0103f06>] syscall_call+0x7/0xb
233 +Oct 13 18:06:51 dvgcpl kernel: =======================
234 +
235 +Make it return 0 on success and -ENODEV if no array was found.
236 +
237 +Reported-by: Dick Gevers <dvgevers@××××××.nl>
238 +Signed-off-by: Andrey Borzenkov <arvidjaar@××××.ru>
239 +Cc: Jens Axboe <jens.axboe@××××××.com>
240 +Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org>
241 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
242 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
243 +
244 +---
245 + drivers/block/cpqarray.c | 7 ++++++-
246 + 1 file changed, 6 insertions(+), 1 deletion(-)
247 +
248 +--- a/drivers/block/cpqarray.c
249 ++++ b/drivers/block/cpqarray.c
250 +@@ -567,7 +567,12 @@ static int __init cpqarray_init(void)
251 + num_cntlrs_reg++;
252 + }
253 +
254 +- return(num_cntlrs_reg);
255 ++ if (num_cntlrs_reg)
256 ++ return 0;
257 ++ else {
258 ++ pci_unregister_driver(&cpqarray_pci_driver);
259 ++ return -ENODEV;
260 ++ }
261 + }
262 +
263 + /* Function to find the first free pointer into our hba[] array */
264
265 Added: hardened/2.6/tags/2.6.26-9/1403_ext3-wait-on-all-pending-commits-in-ext3_sync_fs.patch
266 ===================================================================
267 --- hardened/2.6/tags/2.6.26-9/1403_ext3-wait-on-all-pending-commits-in-ext3_sync_fs.patch (rev 0)
268 +++ hardened/2.6/tags/2.6.26-9/1403_ext3-wait-on-all-pending-commits-in-ext3_sync_fs.patch 2009-01-20 21:29:55 UTC (rev 1479)
269 @@ -0,0 +1,82 @@
270 +Added-By: Gordon Malm <gengor@g.o>
271 +
272 +---
273 +
274 +From jejb@××××××.org Mon Nov 10 15:08:55 2008
275 +From: Arthur Jones <ajones@××××××××.com>
276 +Date: Fri, 7 Nov 2008 00:05:17 GMT
277 +Subject: ext3: wait on all pending commits in ext3_sync_fs
278 +To: stable@××××××.org
279 +Message-ID: <200811070005.mA705Htq002320@×××××××××××.org>
280 +
281 +From: Arthur Jones <ajones@××××××××.com>
282 +
283 +commit c87591b719737b4e91eb1a9fa8fd55a4ff1886d6 upstream
284 +
285 +In ext3_sync_fs, we only wait for a commit to finish if we started it, but
286 +there may be one already in progress which will not be synced.
287 +
288 +In the case of a data=ordered umount with pending long symlinks which are
289 +delayed due to a long list of other I/O on the backing block device, this
290 +causes the buffer associated with the long symlinks to not be moved to the
291 +inode dirty list in the second phase of fsync_super. Then, before they
292 +can be dirtied again, kjournald exits, seeing the UMOUNT flag and the
293 +dirty pages are never written to the backing block device, causing long
294 +symlink corruption and exposing new or previously freed block data to
295 +userspace.
296 +
297 +This can be reproduced with a script created
298 +by Eric Sandeen <sandeen@××××××.com>:
299 +
300 + #!/bin/bash
301 +
302 + umount /mnt/test2
303 + mount /dev/sdb4 /mnt/test2
304 + rm -f /mnt/test2/*
305 + dd if=/dev/zero of=/mnt/test2/bigfile bs=1M count=512
306 + touch
307 + /mnt/test2/thisisveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryverylongfilename
308 + ln -s
309 + /mnt/test2/thisisveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryverylongfilename
310 + /mnt/test2/link
311 + umount /mnt/test2
312 + mount /dev/sdb4 /mnt/test2
313 + ls /mnt/test2/
314 + umount /mnt/test2
315 +
316 +To ensure all commits are synced, we flush all journal commits now when
317 +sync_fs'ing ext3.
318 +
319 +Signed-off-by: Arthur Jones <ajones@××××××××.com>
320 +Cc: Eric Sandeen <sandeen@××××××.com>
321 +Cc: Theodore Ts'o <tytso@×××.edu>
322 +Cc: <linux-ext4@×××××××××××.org>
323 +Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org>
324 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
325 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
326 +
327 +---
328 + fs/ext3/super.c | 11 +++++------
329 + 1 file changed, 5 insertions(+), 6 deletions(-)
330 +
331 +--- a/fs/ext3/super.c
332 ++++ b/fs/ext3/super.c
333 +@@ -2365,13 +2365,12 @@ static void ext3_write_super (struct sup
334 +
335 + static int ext3_sync_fs(struct super_block *sb, int wait)
336 + {
337 +- tid_t target;
338 +-
339 + sb->s_dirt = 0;
340 +- if (journal_start_commit(EXT3_SB(sb)->s_journal, &target)) {
341 +- if (wait)
342 +- log_wait_commit(EXT3_SB(sb)->s_journal, target);
343 +- }
344 ++ if (wait)
345 ++ ext3_force_commit(sb);
346 ++ else
347 ++ journal_start_commit(EXT3_SB(sb)->s_journal, NULL);
348 ++
349 + return 0;
350 + }
351 +
352
353 Added: hardened/2.6/tags/2.6.26-9/1404_hid-fix-incorrent-length-condition-in-hidraw_write.patch
354 ===================================================================
355 --- hardened/2.6/tags/2.6.26-9/1404_hid-fix-incorrent-length-condition-in-hidraw_write.patch (rev 0)
356 +++ hardened/2.6/tags/2.6.26-9/1404_hid-fix-incorrent-length-condition-in-hidraw_write.patch 2009-01-20 21:29:55 UTC (rev 1479)
357 @@ -0,0 +1,48 @@
358 +Added-By: Gordon Malm <gengor@g.o>
359 +
360 +---
361 +
362 +From jkosina@××××.cz Tue Nov 11 15:52:41 2008
363 +From: Jiri Kosina <jkosina@××××.cz>
364 +Date: Tue, 11 Nov 2008 23:45:38 +0100 (CET)
365 +Subject: HID: fix incorrent length condition in hidraw_write()
366 +To: stable@××××××.org
367 +Cc: Paul Stoffregen <paul@××××.com>
368 +Message-ID: <alpine.LNX.1.10.0811112344180.24889@××××××××××.cz>
369 +
370 +From: Jiri Kosina <jkosina@××××.cz>
371 +
372 +upstream commit 2b107d629dc0c35de606bb7b010b829cd247a93a
373 +
374 +From: Jiri Kosina <jkosina@××××.cz>
375 +
376 +The bound check on the buffer length
377 +
378 + if (count > HID_MIN_BUFFER_SIZE)
379 +
380 +is of course incorrent, the proper check is
381 +
382 + if (count > HID_MAX_BUFFER_SIZE)
383 +
384 +Fix it.
385 +
386 +Reported-by: Jerry Ryle <jerry@×××××××××.com>
387 +Signed-off-by: Jiri Kosina <jkosina@××××.cz>
388 +Cc: Paul Stoffregen <paul@××××.com>
389 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
390 +
391 +---
392 + drivers/hid/hidraw.c | 2 +-
393 + 1 file changed, 1 insertion(+), 1 deletion(-)
394 +
395 +--- a/drivers/hid/hidraw.c
396 ++++ b/drivers/hid/hidraw.c
397 +@@ -113,7 +113,7 @@ static ssize_t hidraw_write(struct file
398 + if (!dev->hid_output_raw_report)
399 + return -ENODEV;
400 +
401 +- if (count > HID_MIN_BUFFER_SIZE) {
402 ++ if (count > HID_MAX_BUFFER_SIZE) {
403 + printk(KERN_WARNING "hidraw: pid %d passed too large report\n",
404 + task_pid_nr(current));
405 + return -EINVAL;
406
407 Added: hardened/2.6/tags/2.6.26-9/1405_i-oat-fix-async_tx.callback-checking.patch
408 ===================================================================
409 --- hardened/2.6/tags/2.6.26-9/1405_i-oat-fix-async_tx.callback-checking.patch (rev 0)
410 +++ hardened/2.6/tags/2.6.26-9/1405_i-oat-fix-async_tx.callback-checking.patch 2009-01-20 21:29:55 UTC (rev 1479)
411 @@ -0,0 +1,48 @@
412 +Added-By: Gordon Malm <gengor@g.o>
413 +
414 +Note: Backported to earlier kernels. Original message included below.
415 +
416 +---
417 +
418 +From jejb@××××××.org Tue Nov 11 10:17:05 2008
419 +From: Maciej Sosnowski <maciej.sosnowski@×××××.com>
420 +Date: Tue, 11 Nov 2008 17:50:05 GMT
421 +Subject: I/OAT: fix async_tx.callback checking
422 +To: jejb@××××××.org, stable@××××××.org
423 +Message-ID: <200811111750.mABHo5Ai025612@×××××××××××.org>
424 +
425 +From: Maciej Sosnowski <maciej.sosnowski@×××××.com>
426 +
427 +commit 12ccea24e309d815d058cdc6ee8bf2c4b85f0c5f upstream
428 +
429 +async_tx.callback should be checked for the first
430 +not the last descriptor in the chain.
431 +
432 +Signed-off-by: Maciej Sosnowski <maciej.sosnowski@×××××.com>
433 +Signed-off-by: David S. Miller <davem@×××××××××.net>
434 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
435 +
436 +---
437 + drivers/dma/ioat_dma.c | 4 ++--
438 + 1 file changed, 2 insertions(+), 2 deletions(-)
439 +
440 +--- a/drivers/dma/ioat_dma.c
441 ++++ b/drivers/dma/ioat_dma.c
442 +@@ -251,7 +251,7 @@ static dma_cookie_t ioat1_tx_submit(stru
443 + } while (len && (new = ioat1_dma_get_next_descriptor(ioat_chan)));
444 +
445 + hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
446 +- if (new->async_tx.callback) {
447 ++ if (first->async_tx.callback) {
448 + hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN;
449 + if (first != new) {
450 + /* move callback into to last desc */
451 +@@ -336,7 +336,7 @@ static dma_cookie_t ioat2_tx_submit(stru
452 + } while (len && (new = ioat2_dma_get_next_descriptor(ioat_chan)));
453 +
454 + hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
455 +- if (new->async_tx.callback) {
456 ++ if (first->async_tx.callback) {
457 + hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN;
458 + if (first != new) {
459 + /* move callback into to last desc */
460
461 Added: hardened/2.6/tags/2.6.26-9/1406_i-oat-fix-channel-resources-free-for-not-allocated-channels.patch
462 ===================================================================
463 --- hardened/2.6/tags/2.6.26-9/1406_i-oat-fix-channel-resources-free-for-not-allocated-channels.patch (rev 0)
464 +++ hardened/2.6/tags/2.6.26-9/1406_i-oat-fix-channel-resources-free-for-not-allocated-channels.patch 2009-01-20 21:29:55 UTC (rev 1479)
465 @@ -0,0 +1,54 @@
466 +Added-By: Gordon Malm <gengor@g.o>
467 +
468 +Note: Backported to earlier kernels. Original message below.
469 +
470 +---
471 +
472 +From jejb@××××××.org Tue Nov 11 10:15:37 2008
473 +From: Maciej Sosnowski <maciej.sosnowski@×××××.com>
474 +Date: Tue, 11 Nov 2008 17:50:09 GMT
475 +Subject: I/OAT: fix channel resources free for not allocated channels
476 +To: stable@××××××.org
477 +Message-ID: <200811111750.mABHo9IU025655@×××××××××××.org>
478 +
479 +From: Maciej Sosnowski <maciej.sosnowski@×××××.com>
480 +
481 +commit c3d4f44f50b65b0b0290e357f8739cfb3f4bcaca upstream
482 +
483 +If the ioatdma driver is loaded but not used it does not allocate descriptors.
484 +Before it frees channel resources it should first be sure
485 +that they have been previously allocated.
486 +
487 +Signed-off-by: Maciej Sosnowski <maciej.sosnowski@×××××.com>
488 +Tested-by: Tom Picard <tom.s.picard@×××××.com>
489 +Signed-off-by: Dan Williams <dan.j.williams@×××××.com>
490 +Signed-off-by: David S. Miller <davem@×××××××××.net>
491 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
492 +
493 +---
494 + drivers/dma/ioat_dma.c | 7 +++++++
495 + 1 file changed, 7 insertions(+)
496 +
497 +--- a/drivers/dma/ioat_dma.c
498 ++++ b/drivers/dma/ioat_dma.c
499 +@@ -524,6 +524,12 @@ static void ioat_dma_free_chan_resources
500 + struct ioat_desc_sw *desc, *_desc;
501 + int in_use_descs = 0;
502 +
503 ++ /* Before freeing channel resources first check
504 ++ * if they have been previously allocated for this channel.
505 ++ */
506 ++ if (ioat_chan->desccount == 0)
507 ++ return;
508 ++
509 + tasklet_disable(&ioat_chan->cleanup_task);
510 + ioat_dma_memcpy_cleanup(ioat_chan);
511 +
512 +@@ -585,6 +591,7 @@ static void ioat_dma_free_chan_resources
513 + ioat_chan->last_completion = ioat_chan->completion_addr = 0;
514 + ioat_chan->pending = 0;
515 + ioat_chan->dmacount = 0;
516 ++ ioat_chan->desccount = 0;
517 + }
518 +
519 + /**
520
521 Added: hardened/2.6/tags/2.6.26-9/1407_i-oat-fix-dma_pin_iovec_pages-error-handling.patch
522 ===================================================================
523 --- hardened/2.6/tags/2.6.26-9/1407_i-oat-fix-dma_pin_iovec_pages-error-handling.patch (rev 0)
524 +++ hardened/2.6/tags/2.6.26-9/1407_i-oat-fix-dma_pin_iovec_pages-error-handling.patch 2009-01-20 21:29:55 UTC (rev 1479)
525 @@ -0,0 +1,89 @@
526 +Added-By: Gordon Malm <gengor@g.o>
527 +
528 +---
529 +
530 +From jejb@××××××.org Tue Nov 11 10:16:31 2008
531 +From: Maciej Sosnowski <maciej.sosnowski@×××××.com>
532 +Date: Tue, 11 Nov 2008 17:50:07 GMT
533 +Subject: I/OAT: fix dma_pin_iovec_pages() error handling
534 +To: stable@××××××.org
535 +Message-ID: <200811111750.mABHo7v5025633@×××××××××××.org>
536 +
537 +From: Maciej Sosnowski <maciej.sosnowski@×××××.com>
538 +
539 +commit c2c0b4c5434c0a25f7f7796b29155d53805909f5 upstream
540 +
541 +Error handling needs to be modified in dma_pin_iovec_pages().
542 +It should return NULL instead of ERR_PTR
543 +(pinned_list is checked for NULL in tcp_recvmsg() to determine
544 +if iovec pages have been successfully pinned down).
545 +In case of error for the first iovec,
546 +local_list->nr_iovecs needs to be initialized.
547 +
548 +Signed-off-by: Maciej Sosnowski <maciej.sosnowski@×××××.com>
549 +Signed-off-by: David S. Miller <davem@×××××××××.net>
550 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
551 +
552 +---
553 + drivers/dma/iovlock.c | 17 ++++++-----------
554 + 1 file changed, 6 insertions(+), 11 deletions(-)
555 +
556 +--- a/drivers/dma/iovlock.c
557 ++++ b/drivers/dma/iovlock.c
558 +@@ -55,7 +55,6 @@ struct dma_pinned_list *dma_pin_iovec_pa
559 + int nr_iovecs = 0;
560 + int iovec_len_used = 0;
561 + int iovec_pages_used = 0;
562 +- long err;
563 +
564 + /* don't pin down non-user-based iovecs */
565 + if (segment_eq(get_fs(), KERNEL_DS))
566 +@@ -72,23 +71,21 @@ struct dma_pinned_list *dma_pin_iovec_pa
567 + local_list = kmalloc(sizeof(*local_list)
568 + + (nr_iovecs * sizeof (struct dma_page_list))
569 + + (iovec_pages_used * sizeof (struct page*)), GFP_KERNEL);
570 +- if (!local_list) {
571 +- err = -ENOMEM;
572 ++ if (!local_list)
573 + goto out;
574 +- }
575 +
576 + /* list of pages starts right after the page list array */
577 + pages = (struct page **) &local_list->page_list[nr_iovecs];
578 +
579 ++ local_list->nr_iovecs = 0;
580 ++
581 + for (i = 0; i < nr_iovecs; i++) {
582 + struct dma_page_list *page_list = &local_list->page_list[i];
583 +
584 + len -= iov[i].iov_len;
585 +
586 +- if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len)) {
587 +- err = -EFAULT;
588 ++ if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len))
589 + goto unpin;
590 +- }
591 +
592 + page_list->nr_pages = num_pages_spanned(&iov[i]);
593 + page_list->base_address = iov[i].iov_base;
594 +@@ -109,10 +106,8 @@ struct dma_pinned_list *dma_pin_iovec_pa
595 + NULL);
596 + up_read(&current->mm->mmap_sem);
597 +
598 +- if (ret != page_list->nr_pages) {
599 +- err = -ENOMEM;
600 ++ if (ret != page_list->nr_pages)
601 + goto unpin;
602 +- }
603 +
604 + local_list->nr_iovecs = i + 1;
605 + }
606 +@@ -122,7 +117,7 @@ struct dma_pinned_list *dma_pin_iovec_pa
607 + unpin:
608 + dma_unpin_iovec_pages(local_list);
609 + out:
610 +- return ERR_PTR(err);
611 ++ return NULL;
612 + }
613 +
614 + void dma_unpin_iovec_pages(struct dma_pinned_list *pinned_list)
615
616 Added: hardened/2.6/tags/2.6.26-9/1408_jffs2-fix-lack-of-locking-in-thread_should_wake.patch
617 ===================================================================
618 --- hardened/2.6/tags/2.6.26-9/1408_jffs2-fix-lack-of-locking-in-thread_should_wake.patch (rev 0)
619 +++ hardened/2.6/tags/2.6.26-9/1408_jffs2-fix-lack-of-locking-in-thread_should_wake.patch 2009-01-20 21:29:55 UTC (rev 1479)
620 @@ -0,0 +1,51 @@
621 +Added-By: Gordon Malm <gengor@g.o>
622 +
623 +---
624 +
625 +From jejb@××××××.org Tue Nov 11 09:53:44 2008
626 +From: David Woodhouse <David.Woodhouse@×××××.com>
627 +Date: Fri, 7 Nov 2008 00:08:59 GMT
628 +Subject: JFFS2: Fix lack of locking in thread_should_wake()
629 +To: stable@××××××.org
630 +Message-ID: <200811070008.mA708xQE008191@×××××××××××.org>
631 +
632 +From: David Woodhouse <David.Woodhouse@×××××.com>
633 +
634 +commit b27cf88e9592953ae292d05324887f2f44979433 upstream
635 +
636 +The thread_should_wake() function trawls through the list of 'very
637 +dirty' eraseblocks, determining whether the background GC thread should
638 +wake. Doing this without holding the appropriate locks is a bad idea.
639 +
640 +OLPC Trac #8615
641 +
642 +Signed-off-by: David Woodhouse <David.Woodhouse@×××××.com>
643 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
644 +
645 +---
646 + fs/jffs2/background.c | 10 +++++-----
647 + 1 file changed, 5 insertions(+), 5 deletions(-)
648 +
649 +--- a/fs/jffs2/background.c
650 ++++ b/fs/jffs2/background.c
651 +@@ -85,15 +85,15 @@ static int jffs2_garbage_collect_thread(
652 + for (;;) {
653 + allow_signal(SIGHUP);
654 + again:
655 ++ spin_lock(&c->erase_completion_lock);
656 + if (!jffs2_thread_should_wake(c)) {
657 + set_current_state (TASK_INTERRUPTIBLE);
658 ++ spin_unlock(&c->erase_completion_lock);
659 + D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread sleeping...\n"));
660 +- /* Yes, there's a race here; we checked jffs2_thread_should_wake()
661 +- before setting current->state to TASK_INTERRUPTIBLE. But it doesn't
662 +- matter - We don't care if we miss a wakeup, because the GC thread
663 +- is only an optimisation anyway. */
664 + schedule();
665 +- }
666 ++ } else
667 ++ spin_unlock(&c->erase_completion_lock);
668 ++
669 +
670 + /* This thread is purely an optimisation. But if it runs when
671 + other things could be running, it actually makes things a
672
673 Added: hardened/2.6/tags/2.6.26-9/1409_jffs2-fix-race-condition-in-jffs2_lzo_compress.patch
674 ===================================================================
675 --- hardened/2.6/tags/2.6.26-9/1409_jffs2-fix-race-condition-in-jffs2_lzo_compress.patch (rev 0)
676 +++ hardened/2.6/tags/2.6.26-9/1409_jffs2-fix-race-condition-in-jffs2_lzo_compress.patch 2009-01-20 21:29:55 UTC (rev 1479)
677 @@ -0,0 +1,70 @@
678 +Added-By: Gordon Malm <gengor@g.o>
679 +
680 +---
681 +
682 +From jejb@××××××.org Tue Nov 11 09:53:08 2008
683 +From: Geert Uytterhoeven <Geert.Uytterhoeven@×××××××.com>
684 +Date: Fri, 7 Nov 2008 00:08:19 GMT
685 +Subject: JFFS2: fix race condition in jffs2_lzo_compress()
686 +To: stable@××××××.org
687 +Message-ID: <200811070008.mA708Jdo007031@×××××××××××.org>
688 +
689 +From: Geert Uytterhoeven <Geert.Uytterhoeven@×××××××.com>
690 +
691 +commit dc8a0843a435b2c0891e7eaea64faaf1ebec9b11 upstream
692 +
693 +deflate_mutex protects the globals lzo_mem and lzo_compress_buf. However,
694 +jffs2_lzo_compress() unlocks deflate_mutex _before_ it has copied out the
695 +compressed data from lzo_compress_buf. Correct this by moving the mutex
696 +unlock after the copy.
697 +
698 +In addition, document what deflate_mutex actually protects.
699 +
700 +Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@×××××××.com>
701 +Acked-by: Richard Purdie <rpurdie@××××××××××.com>
702 +Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org>
703 +Signed-off-by: David Woodhouse <David.Woodhouse@×××××.com>
704 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
705 +
706 +---
707 + fs/jffs2/compr_lzo.c | 15 +++++++++------
708 + 1 file changed, 9 insertions(+), 6 deletions(-)
709 +
710 +--- a/fs/jffs2/compr_lzo.c
711 ++++ b/fs/jffs2/compr_lzo.c
712 +@@ -19,7 +19,7 @@
713 +
714 + static void *lzo_mem;
715 + static void *lzo_compress_buf;
716 +-static DEFINE_MUTEX(deflate_mutex);
717 ++static DEFINE_MUTEX(deflate_mutex); /* for lzo_mem and lzo_compress_buf */
718 +
719 + static void free_workspace(void)
720 + {
721 +@@ -49,18 +49,21 @@ static int jffs2_lzo_compress(unsigned c
722 +
723 + mutex_lock(&deflate_mutex);
724 + ret = lzo1x_1_compress(data_in, *sourcelen, lzo_compress_buf, &compress_size, lzo_mem);
725 +- mutex_unlock(&deflate_mutex);
726 +-
727 + if (ret != LZO_E_OK)
728 +- return -1;
729 ++ goto fail;
730 +
731 + if (compress_size > *dstlen)
732 +- return -1;
733 ++ goto fail;
734 +
735 + memcpy(cpage_out, lzo_compress_buf, compress_size);
736 +- *dstlen = compress_size;
737 ++ mutex_unlock(&deflate_mutex);
738 +
739 ++ *dstlen = compress_size;
740 + return 0;
741 ++
742 ++ fail:
743 ++ mutex_unlock(&deflate_mutex);
744 ++ return -1;
745 + }
746 +
747 + static int jffs2_lzo_decompress(unsigned char *data_in, unsigned char *cpage_out,
748
749 Added: hardened/2.6/tags/2.6.26-9/1410_keys-make-request-key-instantiate-the-per-user-keyrings.patch
750 ===================================================================
751 --- hardened/2.6/tags/2.6.26-9/1410_keys-make-request-key-instantiate-the-per-user-keyrings.patch (rev 0)
752 +++ hardened/2.6/tags/2.6.26-9/1410_keys-make-request-key-instantiate-the-per-user-keyrings.patch 2009-01-20 21:29:55 UTC (rev 1479)
753 @@ -0,0 +1,63 @@
754 +Added-By: Gordon Malm <gengor@g.o>
755 +
756 +---
757 +
758 +From 1f8f5cf6e4f038552a3e47b66085452c08556d71 Mon Sep 17 00:00:00 2001
759 +From: David Howells <dhowells@××××××.com>
760 +Date: Mon, 10 Nov 2008 19:00:05 +0000
761 +Subject: KEYS: Make request key instantiate the per-user keyrings
762 +
763 +From: David Howells <dhowells@××××××.com>
764 +
765 +commit 1f8f5cf6e4f038552a3e47b66085452c08556d71 upstream
766 +
767 +Make request_key() instantiate the per-user keyrings so that it doesn't oops
768 +if it needs to get hold of the user session keyring because there isn't a
769 +session keyring in place.
770 +
771 +Signed-off-by: David Howells <dhowells@××××××.com>
772 +Tested-by: Steve French <smfrench@×××××.com>
773 +Tested-by: Rutger Nijlunsing <rutger.nijlunsing@×××××.com>
774 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
775 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
776 +
777 +---
778 + security/keys/internal.h | 1 +
779 + security/keys/process_keys.c | 2 +-
780 + security/keys/request_key.c | 4 ++++
781 + 3 files changed, 6 insertions(+), 1 deletion(-)
782 +
783 +--- a/security/keys/internal.h
784 ++++ b/security/keys/internal.h
785 +@@ -107,6 +107,7 @@ extern key_ref_t search_process_keyrings
786 +
787 + extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check);
788 +
789 ++extern int install_user_keyrings(struct task_struct *tsk);
790 + extern int install_thread_keyring(struct task_struct *tsk);
791 + extern int install_process_keyring(struct task_struct *tsk);
792 +
793 +--- a/security/keys/process_keys.c
794 ++++ b/security/keys/process_keys.c
795 +@@ -40,7 +40,7 @@ struct key_user root_key_user = {
796 + /*
797 + * install user and user session keyrings for a particular UID
798 + */
799 +-static int install_user_keyrings(struct task_struct *tsk)
800 ++int install_user_keyrings(struct task_struct *tsk)
801 + {
802 + struct user_struct *user = tsk->user;
803 + struct key *uid_keyring, *session_keyring;
804 +--- a/security/keys/request_key.c
805 ++++ b/security/keys/request_key.c
806 +@@ -74,6 +74,10 @@ static int call_sbin_request_key(struct
807 +
808 + kenter("{%d},{%d},%s", key->serial, authkey->serial, op);
809 +
810 ++ ret = install_user_keyrings(tsk);
811 ++ if (ret < 0)
812 ++ goto error_alloc;
813 ++
814 + /* allocate a new session keyring */
815 + sprintf(desc, "_req.%u", key->serial);
816 +
817
818 Added: hardened/2.6/tags/2.6.26-9/1411_md-linear-fix-a-division-by-zero-bug-for-very-small-arrays.patch
819 ===================================================================
820 --- hardened/2.6/tags/2.6.26-9/1411_md-linear-fix-a-division-by-zero-bug-for-very-small-arrays.patch (rev 0)
821 +++ hardened/2.6/tags/2.6.26-9/1411_md-linear-fix-a-division-by-zero-bug-for-very-small-arrays.patch 2009-01-20 21:29:55 UTC (rev 1479)
822 @@ -0,0 +1,51 @@
823 +Added-By: Gordon Malm <gengor@g.o>
824 +
825 +Note: Changed patch slightly to eliminate fuzz.
826 +
827 +---
828 +
829 +From jejb@××××××.org Tue Nov 11 09:47:32 2008
830 +From: Andre Noll <maan@×××××××××××.org>
831 +Date: Fri, 7 Nov 2008 00:07:46 GMT
832 +Subject: md: linear: Fix a division by zero bug for very small arrays.
833 +To: stable@××××××.org
834 +Message-ID: <200811070007.mA707k6d006270@×××××××××××.org>
835 +
836 +From: Andre Noll <maan@×××××××××××.org>
837 +
838 +commit f1cd14ae52985634d0389e934eba25b5ecf24565 upstream
839 +
840 +Date: Thu, 6 Nov 2008 19:41:24 +1100
841 +Subject: md: linear: Fix a division by zero bug for very small arrays.
842 +
843 +We currently oops with a divide error on starting a linear software
844 +raid array consisting of at least two very small (< 500K) devices.
845 +
846 +The bug is caused by the calculation of the hash table size which
847 +tries to compute sector_div(sz, base) with "base" being zero due to
848 +the small size of the component devices of the array.
849 +
850 +Fix this by requiring the hash spacing to be at least one which
851 +implies that also "base" is non-zero.
852 +
853 +This bug has existed since about 2.6.14.
854 +
855 +Signed-off-by: Andre Noll <maan@×××××××××××.org>
856 +Signed-off-by: NeilBrown <neilb@××××.de>
857 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
858 +
859 +---
860 + drivers/md/linear.c | 2 ++
861 + 1 file changed, 2 insertions(+)
862 +
863 +--- a/drivers/md/linear.c
864 ++++ b/drivers/md/linear.c
865 +@@ -157,6 +157,8 @@ static linear_conf_t *linear_conf(mddev_
866 +
867 + min_spacing = conf->array_size;
868 + sector_div(min_spacing, PAGE_SIZE/sizeof(struct dev_info *));
869 ++ if (min_spacing == 0)
870 ++ min_spacing = 1;
871 +
872 + /* min_spacing is the minimum spacing that will fit the hash
873 + * table in one PAGE. This may be much smaller than needed.
874
875 Added: hardened/2.6/tags/2.6.26-9/1412_mmc-increase-sd-write-timeout-for-crappy-cards.patch
876 ===================================================================
877 --- hardened/2.6/tags/2.6.26-9/1412_mmc-increase-sd-write-timeout-for-crappy-cards.patch (rev 0)
878 +++ hardened/2.6/tags/2.6.26-9/1412_mmc-increase-sd-write-timeout-for-crappy-cards.patch 2009-01-20 21:29:55 UTC (rev 1479)
879 @@ -0,0 +1,42 @@
880 +Added-By: Gordon Malm <gengor@g.o>
881 +
882 +---
883 +
884 +From 493890e75d98810a3470b4aae23be628ee5e9667 Mon Sep 17 00:00:00 2001
885 +From: Pierre Ossman <drzeus@××××××.cx>
886 +Date: Sun, 26 Oct 2008 12:37:25 +0100
887 +Subject: mmc: increase SD write timeout for crappy cards
888 +
889 +From: Pierre Ossman <drzeus@××××××.cx>
890 +
891 +commit 493890e75d98810a3470b4aae23be628ee5e9667 upstream.
892 +
893 +It seems that some cards are slightly out of spec and occasionally
894 +will not be able to complete a write in the alloted 250 ms [1].
895 +Incease the timeout slightly to allow even these cards to function
896 +properly.
897 +
898 +[1] http://lkml.org/lkml/2008/9/23/390
899 +
900 +Signed-off-by: Pierre Ossman <drzeus@××××××.cx>
901 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
902 +
903 +---
904 + drivers/mmc/core/core.c | 6 +++++-
905 + 1 file changed, 5 insertions(+), 1 deletion(-)
906 +
907 +--- a/drivers/mmc/core/core.c
908 ++++ b/drivers/mmc/core/core.c
909 +@@ -280,7 +280,11 @@ void mmc_set_data_timeout(struct mmc_dat
910 + (card->host->ios.clock / 1000);
911 +
912 + if (data->flags & MMC_DATA_WRITE)
913 +- limit_us = 250000;
914 ++ /*
915 ++ * The limit is really 250 ms, but that is
916 ++ * insufficient for some crappy cards.
917 ++ */
918 ++ limit_us = 300000;
919 + else
920 + limit_us = 100000;
921 +
922
923 Added: hardened/2.6/tags/2.6.26-9/1413_net-unix-fix-inflight-counting-bug-in-garbage-collector.patch
924 ===================================================================
925 --- hardened/2.6/tags/2.6.26-9/1413_net-unix-fix-inflight-counting-bug-in-garbage-collector.patch (rev 0)
926 +++ hardened/2.6/tags/2.6.26-9/1413_net-unix-fix-inflight-counting-bug-in-garbage-collector.patch 2009-01-20 21:29:55 UTC (rev 1479)
927 @@ -0,0 +1,213 @@
928 +Added-By: Gordon Malm <gengor@g.o>
929 +
930 +Backported to earlier kernels. Original message included below.
931 +
932 +---
933 +
934 +From jejb@××××××.org Tue Nov 11 09:59:05 2008
935 +From: Miklos Szeredi <mszeredi@××××.cz>
936 +Date: Sun, 9 Nov 2008 19:50:02 GMT
937 +Subject: net: unix: fix inflight counting bug in garbage collector
938 +To: stable@××××××.org
939 +Message-ID: <200811091950.mA9Jo2iL003804@×××××××××××.org>
940 +
941 +From: Miklos Szeredi <mszeredi@××××.cz>
942 +
943 +commit 6209344f5a3795d34b7f2c0061f49802283b6bdd upstream
944 +
945 +Previously I assumed that the receive queues of candidates don't
946 +change during the GC. This is only half true, nothing can be received
947 +from the queues (see comment in unix_gc()), but buffers could be added
948 +through the other half of the socket pair, which may still have file
949 +descriptors referring to it.
950 +
951 +This can result in inc_inflight_move_tail() erronously increasing the
952 +"inflight" counter for a unix socket for which dec_inflight() wasn't
953 +previously called. This in turn can trigger the "BUG_ON(total_refs <
954 +inflight_refs)" in a later garbage collection run.
955 +
956 +Fix this by only manipulating the "inflight" counter for sockets which
957 +are candidates themselves. Duplicating the file references in
958 +unix_attach_fds() is also needed to prevent a socket becoming a
959 +candidate for GC while the skb that contains it is not yet queued.
960 +
961 +Reported-by: Andrea Bittau <a.bittau@×××××××××.uk>
962 +Signed-off-by: Miklos Szeredi <mszeredi@××××.cz>
963 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
964 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
965 +
966 +---
967 + include/net/af_unix.h | 1 +
968 + net/unix/af_unix.c | 31 ++++++++++++++++++++++++-------
969 + net/unix/garbage.c | 49 +++++++++++++++++++++++++++++++++++++------------
970 + 3 files changed, 62 insertions(+), 19 deletions(-)
971 +
972 +--- a/include/net/af_unix.h
973 ++++ b/include/net/af_unix.h
974 +@@ -54,6 +54,7 @@ struct unix_sock {
975 + atomic_t inflight;
976 + spinlock_t lock;
977 + unsigned int gc_candidate : 1;
978 ++ unsigned int gc_maybe_cycle : 1;
979 + wait_queue_head_t peer_wait;
980 + };
981 + #define unix_sk(__sk) ((struct unix_sock *)__sk)
982 +--- a/net/unix/af_unix.c
983 ++++ b/net/unix/af_unix.c
984 +@@ -1302,14 +1302,23 @@ static void unix_destruct_fds(struct sk_
985 + sock_wfree(skb);
986 + }
987 +
988 +-static void unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
989 ++static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
990 + {
991 + int i;
992 ++
993 ++ /*
994 ++ * Need to duplicate file references for the sake of garbage
995 ++ * collection. Otherwise a socket in the fps might become a
996 ++ * candidate for GC while the skb is not yet queued.
997 ++ */
998 ++ UNIXCB(skb).fp = scm_fp_dup(scm->fp);
999 ++ if (!UNIXCB(skb).fp)
1000 ++ return -ENOMEM;
1001 ++
1002 + for (i=scm->fp->count-1; i>=0; i--)
1003 + unix_inflight(scm->fp->fp[i]);
1004 +- UNIXCB(skb).fp = scm->fp;
1005 + skb->destructor = unix_destruct_fds;
1006 +- scm->fp = NULL;
1007 ++ return 0;
1008 + }
1009 +
1010 + /*
1011 +@@ -1368,8 +1377,11 @@ static int unix_dgram_sendmsg(struct kio
1012 + goto out;
1013 +
1014 + memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
1015 +- if (siocb->scm->fp)
1016 +- unix_attach_fds(siocb->scm, skb);
1017 ++ if (siocb->scm->fp) {
1018 ++ err = unix_attach_fds(siocb->scm, skb);
1019 ++ if (err)
1020 ++ goto out_free;
1021 ++ }
1022 + unix_get_secdata(siocb->scm, skb);
1023 +
1024 + skb_reset_transport_header(skb);
1025 +@@ -1538,8 +1550,13 @@ static int unix_stream_sendmsg(struct ki
1026 + size = min_t(int, size, skb_tailroom(skb));
1027 +
1028 + memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
1029 +- if (siocb->scm->fp)
1030 +- unix_attach_fds(siocb->scm, skb);
1031 ++ if (siocb->scm->fp) {
1032 ++ err = unix_attach_fds(siocb->scm, skb);
1033 ++ if (err) {
1034 ++ kfree_skb(skb);
1035 ++ goto out_err;
1036 ++ }
1037 ++ }
1038 +
1039 + if ((err = memcpy_fromiovec(skb_put(skb,size), msg->msg_iov, size)) != 0) {
1040 + kfree_skb(skb);
1041 +--- a/net/unix/garbage.c
1042 ++++ b/net/unix/garbage.c
1043 +@@ -186,8 +186,17 @@ static void scan_inflight(struct sock *x
1044 + */
1045 + struct sock *sk = unix_get_socket(*fp++);
1046 + if (sk) {
1047 +- hit = true;
1048 +- func(unix_sk(sk));
1049 ++ struct unix_sock *u = unix_sk(sk);
1050 ++
1051 ++ /*
1052 ++ * Ignore non-candidates, they could
1053 ++ * have been added to the queues after
1054 ++ * starting the garbage collection
1055 ++ */
1056 ++ if (u->gc_candidate) {
1057 ++ hit = true;
1058 ++ func(u);
1059 ++ }
1060 + }
1061 + }
1062 + if (hit && hitlist != NULL) {
1063 +@@ -249,11 +258,11 @@ static void inc_inflight_move_tail(struc
1064 + {
1065 + atomic_inc(&u->inflight);
1066 + /*
1067 +- * If this is still a candidate, move it to the end of the
1068 +- * list, so that it's checked even if it was already passed
1069 +- * over
1070 ++ * If this still might be part of a cycle, move it to the end
1071 ++ * of the list, so that it's checked even if it was already
1072 ++ * passed over
1073 + */
1074 +- if (u->gc_candidate)
1075 ++ if (u->gc_maybe_cycle)
1076 + list_move_tail(&u->link, &gc_candidates);
1077 + }
1078 +
1079 +@@ -267,6 +276,7 @@ void unix_gc(void)
1080 + struct unix_sock *next;
1081 + struct sk_buff_head hitlist;
1082 + struct list_head cursor;
1083 ++ LIST_HEAD(not_cycle_list);
1084 +
1085 + spin_lock(&unix_gc_lock);
1086 +
1087 +@@ -282,10 +292,14 @@ void unix_gc(void)
1088 + *
1089 + * Holding unix_gc_lock will protect these candidates from
1090 + * being detached, and hence from gaining an external
1091 +- * reference. This also means, that since there are no
1092 +- * possible receivers, the receive queues of these sockets are
1093 +- * static during the GC, even though the dequeue is done
1094 +- * before the detach without atomicity guarantees.
1095 ++ * reference. Since there are no possible receivers, all
1096 ++ * buffers currently on the candidates' queues stay there
1097 ++ * during the garbage collection.
1098 ++ *
1099 ++ * We also know that no new candidate can be added onto the
1100 ++ * receive queues. Other, non candidate sockets _can_ be
1101 ++ * added to queue, so we must make sure only to touch
1102 ++ * candidates.
1103 + */
1104 + list_for_each_entry_safe(u, next, &gc_inflight_list, link) {
1105 + int total_refs;
1106 +@@ -299,6 +313,7 @@ void unix_gc(void)
1107 + if (total_refs == inflight_refs) {
1108 + list_move_tail(&u->link, &gc_candidates);
1109 + u->gc_candidate = 1;
1110 ++ u->gc_maybe_cycle = 1;
1111 + }
1112 + }
1113 +
1114 +@@ -325,14 +340,24 @@ void unix_gc(void)
1115 + list_move(&cursor, &u->link);
1116 +
1117 + if (atomic_read(&u->inflight) > 0) {
1118 +- list_move_tail(&u->link, &gc_inflight_list);
1119 +- u->gc_candidate = 0;
1120 ++ list_move_tail(&u->link, &not_cycle_list);
1121 ++ u->gc_maybe_cycle = 0;
1122 + scan_children(&u->sk, inc_inflight_move_tail, NULL);
1123 + }
1124 + }
1125 + list_del(&cursor);
1126 +
1127 + /*
1128 ++ * not_cycle_list contains those sockets which do not make up a
1129 ++ * cycle. Restore these to the inflight list.
1130 ++ */
1131 ++ while (!list_empty(&not_cycle_list)) {
1132 ++ u = list_entry(not_cycle_list.next, struct unix_sock, link);
1133 ++ u->gc_candidate = 0;
1134 ++ list_move_tail(&u->link, &gc_inflight_list);
1135 ++ }
1136 ++
1137 ++ /*
1138 + * Now gc_candidates contains only garbage. Restore original
1139 + * inflight counters for these as well, and remove the skbuffs
1140 + * which are creating the cycle(s).
1141
1142 Added: hardened/2.6/tags/2.6.26-9/1414_acpi-avoid-empty-file-name-in-sysfs.patch
1143 ===================================================================
1144 --- hardened/2.6/tags/2.6.26-9/1414_acpi-avoid-empty-file-name-in-sysfs.patch (rev 0)
1145 +++ hardened/2.6/tags/2.6.26-9/1414_acpi-avoid-empty-file-name-in-sysfs.patch 2009-01-20 21:29:55 UTC (rev 1479)
1146 @@ -0,0 +1,81 @@
1147 +Added-By: Gordon Malm <gengor@g.o>
1148 +
1149 +---
1150 +
1151 +From 4feba70a2c1a1a0c96909f657f48b2e11e682370 Mon Sep 17 00:00:00 2001
1152 +From: Peter Gruber <nokos@×××.net>
1153 +Date: Mon, 27 Oct 2008 23:59:36 -0400
1154 +Subject: ACPI: avoid empty file name in sysfs
1155 +
1156 +From: Peter Gruber <nokos@×××.net>
1157 +
1158 +commit 4feba70a2c1a1a0c96909f657f48b2e11e682370 upstream.
1159 +
1160 +Since commit bc45b1d39a925b56796bebf8a397a0491489d85c acpi tables are
1161 +allowed to have an empty signature and /sys/firmware/acpi/tables uses the
1162 +signature as filename. Applications using naive recursion through /sys
1163 +loop forever. A possible solution would be: (replacing the zero length
1164 +filename with the string "NULL")
1165 +
1166 +http://bugzilla.kernel.org/show_bug.cgi?id=11539
1167 +
1168 +Acked-by: Zhang Rui <rui.zhang@×××××.com>
1169 +Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org>
1170 +Signed-off-by: Len Brown <len.brown@×××××.com>
1171 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
1172 +
1173 +---
1174 + drivers/acpi/system.c | 25 +++++++++++++++++--------
1175 + 1 file changed, 17 insertions(+), 8 deletions(-)
1176 +
1177 +--- a/drivers/acpi/system.c
1178 ++++ b/drivers/acpi/system.c
1179 +@@ -78,9 +78,15 @@ static ssize_t acpi_table_show(struct ko
1180 + container_of(bin_attr, struct acpi_table_attr, attr);
1181 + struct acpi_table_header *table_header = NULL;
1182 + acpi_status status;
1183 ++ char name[ACPI_NAME_SIZE];
1184 ++
1185 ++ if (strncmp(table_attr->name, "NULL", 4))
1186 ++ memcpy(name, table_attr->name, ACPI_NAME_SIZE);
1187 ++ else
1188 ++ memcpy(name, "\0\0\0\0", 4);
1189 +
1190 + status =
1191 +- acpi_get_table(table_attr->name, table_attr->instance,
1192 ++ acpi_get_table(name, table_attr->instance,
1193 + &table_header);
1194 + if (ACPI_FAILURE(status))
1195 + return -ENODEV;
1196 +@@ -95,21 +101,24 @@ static void acpi_table_attr_init(struct
1197 + struct acpi_table_header *header = NULL;
1198 + struct acpi_table_attr *attr = NULL;
1199 +
1200 +- memcpy(table_attr->name, table_header->signature, ACPI_NAME_SIZE);
1201 ++ if (table_header->signature[0] != '\0')
1202 ++ memcpy(table_attr->name, table_header->signature,
1203 ++ ACPI_NAME_SIZE);
1204 ++ else
1205 ++ memcpy(table_attr->name, "NULL", 4);
1206 +
1207 + list_for_each_entry(attr, &acpi_table_attr_list, node) {
1208 +- if (!memcmp(table_header->signature, attr->name,
1209 +- ACPI_NAME_SIZE))
1210 ++ if (!memcmp(table_attr->name, attr->name, ACPI_NAME_SIZE))
1211 + if (table_attr->instance < attr->instance)
1212 + table_attr->instance = attr->instance;
1213 + }
1214 + table_attr->instance++;
1215 +
1216 + if (table_attr->instance > 1 || (table_attr->instance == 1 &&
1217 +- !acpi_get_table(table_header->
1218 +- signature, 2,
1219 +- &header)))
1220 +- sprintf(table_attr->name + 4, "%d", table_attr->instance);
1221 ++ !acpi_get_table
1222 ++ (table_header->signature, 2, &header)))
1223 ++ sprintf(table_attr->name + ACPI_NAME_SIZE, "%d",
1224 ++ table_attr->instance);
1225 +
1226 + table_attr->attr.size = 0;
1227 + table_attr->attr.read = acpi_table_show;
1228
1229 Added: hardened/2.6/tags/2.6.26-9/1415_block-fix-nr_phys_segments-miscalculation-bug.patch
1230 ===================================================================
1231 --- hardened/2.6/tags/2.6.26-9/1415_block-fix-nr_phys_segments-miscalculation-bug.patch (rev 0)
1232 +++ hardened/2.6/tags/2.6.26-9/1415_block-fix-nr_phys_segments-miscalculation-bug.patch 2009-01-20 21:29:55 UTC (rev 1479)
1233 @@ -0,0 +1,126 @@
1234 +Added-By: Gordon Malm <gengor@g.o>
1235 +
1236 +---
1237 +
1238 +From knikanth@××××.de Thu Nov 13 14:07:47 2008
1239 +From: FUJITA Tomonori <fujita.tomonori@××××××××××.jp>
1240 +Date: Wed, 12 Nov 2008 11:33:54 +0530
1241 +Subject: block: fix nr_phys_segments miscalculation bug
1242 +To: Greg KH <greg@×××××.com>
1243 +Cc: stable@××××××.org, FUJITA Tomonori <fujita.tomonori@××××××××××.jp>
1244 +Message-ID: <200811121133.55404.knikanth@××××.de>
1245 +Content-Disposition: inline
1246 +
1247 +From: FUJITA Tomonori <fujita.tomonori@××××××××××.jp>
1248 +
1249 +commit 8677142710516d986d932d6f1fba7be8382c1fec upstream
1250 +backported by Nikanth Karthikesan <knikanth@××××.de> to the 2.6.27.y tree.
1251 +
1252 +block: fix nr_phys_segments miscalculation bug
1253 +
1254 +This fixes the bug reported by Nikanth Karthikesan <knikanth@××××.de>:
1255 +
1256 +http://lkml.org/lkml/2008/10/2/203
1257 +
1258 +The root cause of the bug is that blk_phys_contig_segment
1259 +miscalculates q->max_segment_size.
1260 +
1261 +blk_phys_contig_segment checks:
1262 +
1263 +req->biotail->bi_size + next_req->bio->bi_size > q->max_segment_size
1264 +
1265 +But blk_recalc_rq_segments might expect that req->biotail and the
1266 +previous bio in the req are supposed be merged into one
1267 +segment. blk_recalc_rq_segments might also expect that next_req->bio
1268 +and the next bio in the next_req are supposed be merged into one
1269 +segment. In such case, we merge two requests that can't be merged
1270 +here. Later, blk_rq_map_sg gives more segments than it should.
1271 +
1272 +We need to keep track of segment size in blk_recalc_rq_segments and
1273 +use it to see if two requests can be merged. This patch implements it
1274 +in the similar way that we used to do for hw merging (virtual
1275 +merging).
1276 +
1277 +Signed-off-by: FUJITA Tomonori <fujita.tomonori@××××××××××.jp>
1278 +Signed-off-by: Jens Axboe <jens.axboe@××××××.com>
1279 +Cc: Nikanth Karthikesan <knikanth@××××.de>
1280 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
1281 +
1282 +---
1283 + block/blk-merge.c | 19 +++++++++++++++++--
1284 + include/linux/bio.h | 7 +++++++
1285 + 2 files changed, 24 insertions(+), 2 deletions(-)
1286 +
1287 +--- a/block/blk-merge.c
1288 ++++ b/block/blk-merge.c
1289 +@@ -95,6 +95,9 @@ new_hw_segment:
1290 + nr_hw_segs++;
1291 + }
1292 +
1293 ++ if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
1294 ++ rq->bio->bi_seg_front_size = seg_size;
1295 ++
1296 + nr_phys_segs++;
1297 + bvprv = bv;
1298 + seg_size = bv->bv_len;
1299 +@@ -106,6 +109,10 @@ new_hw_segment:
1300 + rq->bio->bi_hw_front_size = hw_seg_size;
1301 + if (hw_seg_size > rq->biotail->bi_hw_back_size)
1302 + rq->biotail->bi_hw_back_size = hw_seg_size;
1303 ++ if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
1304 ++ rq->bio->bi_seg_front_size = seg_size;
1305 ++ if (seg_size > rq->biotail->bi_seg_back_size)
1306 ++ rq->biotail->bi_seg_back_size = seg_size;
1307 + rq->nr_phys_segments = nr_phys_segs;
1308 + rq->nr_hw_segments = nr_hw_segs;
1309 + }
1310 +@@ -133,7 +140,8 @@ static int blk_phys_contig_segment(struc
1311 +
1312 + if (!BIOVEC_PHYS_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)))
1313 + return 0;
1314 +- if (bio->bi_size + nxt->bi_size > q->max_segment_size)
1315 ++ if (bio->bi_seg_back_size + nxt->bi_seg_front_size >
1316 ++ q->max_segment_size)
1317 + return 0;
1318 +
1319 + /*
1320 +@@ -377,6 +385,8 @@ static int ll_merge_requests_fn(struct r
1321 + {
1322 + int total_phys_segments;
1323 + int total_hw_segments;
1324 ++ unsigned int seg_size =
1325 ++ req->biotail->bi_seg_back_size + next->bio->bi_seg_front_size;
1326 +
1327 + /*
1328 + * First check if the either of the requests are re-queued
1329 +@@ -392,8 +402,13 @@ static int ll_merge_requests_fn(struct r
1330 + return 0;
1331 +
1332 + total_phys_segments = req->nr_phys_segments + next->nr_phys_segments;
1333 +- if (blk_phys_contig_segment(q, req->biotail, next->bio))
1334 ++ if (blk_phys_contig_segment(q, req->biotail, next->bio)) {
1335 ++ if (req->nr_phys_segments == 1)
1336 ++ req->bio->bi_seg_front_size = seg_size;
1337 ++ if (next->nr_phys_segments == 1)
1338 ++ next->biotail->bi_seg_back_size = seg_size;
1339 + total_phys_segments--;
1340 ++ }
1341 +
1342 + if (total_phys_segments > q->max_phys_segments)
1343 + return 0;
1344 +--- a/include/linux/bio.h
1345 ++++ b/include/linux/bio.h
1346 +@@ -98,6 +98,13 @@ struct bio {
1347 + unsigned int bi_size; /* residual I/O count */
1348 +
1349 + /*
1350 ++ * To keep track of the max segment size, we account for the
1351 ++ * sizes of the first and last mergeable segments in this bio.
1352 ++ */
1353 ++ unsigned int bi_seg_front_size;
1354 ++ unsigned int bi_seg_back_size;
1355 ++
1356 ++ /*
1357 + * To keep track of the max hw size, we account for the
1358 + * sizes of the first and last virtually mergeable segments
1359 + * in this bio
1360
1361 Added: hardened/2.6/tags/2.6.26-9/1416_dm-raid1-flush-workqueue-before-destruction.patch
1362 ===================================================================
1363 --- hardened/2.6/tags/2.6.26-9/1416_dm-raid1-flush-workqueue-before-destruction.patch (rev 0)
1364 +++ hardened/2.6/tags/2.6.26-9/1416_dm-raid1-flush-workqueue-before-destruction.patch 2009-01-20 21:29:55 UTC (rev 1479)
1365 @@ -0,0 +1,34 @@
1366 +Added-By: Gordon Malm <gengor@g.o>
1367 +
1368 +---
1369 +
1370 +From 18776c7316545482a02bfaa2629a2aa1afc48357 Mon Sep 17 00:00:00 2001
1371 +From: Mikulas Patocka <mpatocka@××××××.com>
1372 +Date: Thu, 13 Nov 2008 23:38:52 +0000
1373 +Subject: dm raid1: flush workqueue before destruction
1374 +
1375 +From: Mikulas Patocka <mpatocka@××××××.com>
1376 +
1377 +commit 18776c7316545482a02bfaa2629a2aa1afc48357 upstream.
1378 +
1379 +We queue work on keventd queue --- so this queue must be flushed in the
1380 +destructor. Otherwise, keventd could access mirror_set after it was freed.
1381 +
1382 +Signed-off-by: Mikulas Patocka <mpatocka@××××××.com>
1383 +Signed-off-by: Alasdair G Kergon <agk@××××××.com>
1384 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
1385 +
1386 +---
1387 + drivers/md/dm-raid1.c | 1 +
1388 + 1 file changed, 1 insertion(+)
1389 +
1390 +--- a/drivers/md/dm-raid1.c
1391 ++++ b/drivers/md/dm-raid1.c
1392 +@@ -1598,6 +1598,7 @@ static void mirror_dtr(struct dm_target
1393 +
1394 + del_timer_sync(&ms->timer);
1395 + flush_workqueue(ms->kmirrord_wq);
1396 ++ flush_scheduled_work();
1397 + dm_kcopyd_client_destroy(ms->kcopyd_client);
1398 + destroy_workqueue(ms->kmirrord_wq);
1399 + free_context(ms, ti, ms->nr_mirrors);
1400
1401 Added: hardened/2.6/tags/2.6.26-9/1417_net-fix-proc-net-snmp-as-memory-corruptor.patch
1402 ===================================================================
1403 --- hardened/2.6/tags/2.6.26-9/1417_net-fix-proc-net-snmp-as-memory-corruptor.patch (rev 0)
1404 +++ hardened/2.6/tags/2.6.26-9/1417_net-fix-proc-net-snmp-as-memory-corruptor.patch 2009-01-20 21:29:55 UTC (rev 1479)
1405 @@ -0,0 +1,104 @@
1406 +Added-By: Gordon Malm <gengor@g.o>
1407 +
1408 +Note: Backported to earlier kernels. Original message included below.
1409 +
1410 +---
1411 +
1412 +From b971e7ac834e9f4bda96d5a96ae9abccd01c1dd8 Mon Sep 17 00:00:00 2001
1413 +From: Eric Dumazet <dada1@×××××××××.com>
1414 +Date: Mon, 10 Nov 2008 21:43:08 -0800
1415 +Subject: net: fix /proc/net/snmp as memory corruptor
1416 +
1417 +From: Eric Dumazet <dada1@×××××××××.com>
1418 +
1419 +commit b971e7ac834e9f4bda96d5a96ae9abccd01c1dd8 upstream.
1420 +
1421 +icmpmsg_put() can happily corrupt kernel memory, using a static
1422 +table and forgetting to reset an array index in a loop.
1423 +
1424 +Remove the static array since its not safe without proper locking.
1425 +
1426 +Signed-off-by: Alexey Dobriyan <adobriyan@×××××.com>
1427 +Signed-off-by: Eric Dumazet <dada1@×××××××××.com>
1428 +Signed-off-by: David S. Miller <davem@×××××××××.net>
1429 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
1430 +
1431 +---
1432 + net/ipv4/proc.c | 58 ++++++++++++++++++++++++++++----------------------------
1433 + 1 file changed, 30 insertions(+), 28 deletions(-)
1434 +
1435 +--- a/net/ipv4/proc.c
1436 ++++ b/net/ipv4/proc.c
1437 +@@ -262,42 +262,44 @@ static const struct snmp_mib snmp4_net_l
1438 + SNMP_MIB_SENTINEL
1439 + };
1440 +
1441 +-static void icmpmsg_put(struct seq_file *seq)
1442 ++static void icmpmsg_put_line(struct seq_file *seq, unsigned long *vals,
1443 ++ unsigned short *type, int count)
1444 + {
1445 +-#define PERLINE 16
1446 +-
1447 +- int j, i, count;
1448 +- static int out[PERLINE];
1449 +-
1450 +- count = 0;
1451 +- for (i = 0; i < ICMPMSG_MIB_MAX; i++) {
1452 +-
1453 +- if (snmp_fold_field((void **) icmpmsg_statistics, i))
1454 +- out[count++] = i;
1455 +- if (count < PERLINE)
1456 +- continue;
1457 ++ int j;
1458 +
1459 +- seq_printf(seq, "\nIcmpMsg:");
1460 +- for (j = 0; j < PERLINE; ++j)
1461 +- seq_printf(seq, " %sType%u", i & 0x100 ? "Out" : "In",
1462 +- i & 0xff);
1463 +- seq_printf(seq, "\nIcmpMsg: ");
1464 +- for (j = 0; j < PERLINE; ++j)
1465 +- seq_printf(seq, " %lu",
1466 +- snmp_fold_field((void **) icmpmsg_statistics,
1467 +- out[j]));
1468 +- seq_putc(seq, '\n');
1469 +- }
1470 + if (count) {
1471 + seq_printf(seq, "\nIcmpMsg:");
1472 + for (j = 0; j < count; ++j)
1473 +- seq_printf(seq, " %sType%u", out[j] & 0x100 ? "Out" :
1474 +- "In", out[j] & 0xff);
1475 ++ seq_printf(seq, " %sType%u",
1476 ++ type[j] & 0x100 ? "Out" : "In",
1477 ++ type[j] & 0xff);
1478 + seq_printf(seq, "\nIcmpMsg:");
1479 + for (j = 0; j < count; ++j)
1480 +- seq_printf(seq, " %lu", snmp_fold_field((void **)
1481 +- icmpmsg_statistics, out[j]));
1482 ++ seq_printf(seq, " %lu", vals[j]);
1483 ++ }
1484 ++}
1485 ++
1486 ++static void icmpmsg_put(struct seq_file *seq)
1487 ++{
1488 ++#define PERLINE 16
1489 ++
1490 ++ int i, count;
1491 ++ unsigned short type[PERLINE];
1492 ++ unsigned long vals[PERLINE], val;
1493 ++
1494 ++ count = 0;
1495 ++ for (i = 0; i < ICMPMSG_MIB_MAX; i++) {
1496 ++ val = snmp_fold_field((void **) icmpmsg_statistics, i);
1497 ++ if (val) {
1498 ++ type[count] = i;
1499 ++ vals[count++] = val;
1500 ++ }
1501 ++ if (count == PERLINE) {
1502 ++ icmpmsg_put_line(seq, vals, type, count);
1503 ++ count = 0;
1504 ++ }
1505 + }
1506 ++ icmpmsg_put_line(seq, vals, type, count);
1507 +
1508 + #undef PERLINE
1509 + }
1510
1511 Added: hardened/2.6/tags/2.6.26-9/1418_touch_mnt_namespace-when-the-mount-flags-change.patch
1512 ===================================================================
1513 --- hardened/2.6/tags/2.6.26-9/1418_touch_mnt_namespace-when-the-mount-flags-change.patch (rev 0)
1514 +++ hardened/2.6/tags/2.6.26-9/1418_touch_mnt_namespace-when-the-mount-flags-change.patch 2009-01-20 21:29:55 UTC (rev 1479)
1515 @@ -0,0 +1,43 @@
1516 +Added-By: Gordon Malm <gengor@g.o>
1517 +
1518 +---
1519 +
1520 +From 0e55a7cca4b66f625d67b292f80b6a976e77c51b Mon Sep 17 00:00:00 2001
1521 +From: Dan Williams <dan.j.williams@×××××.com>
1522 +Date: Fri, 26 Sep 2008 19:01:20 -0700
1523 +Subject: touch_mnt_namespace when the mount flags change
1524 +
1525 +From: Dan Williams <dan.j.williams@×××××.com>
1526 +
1527 +commit 0e55a7cca4b66f625d67b292f80b6a976e77c51b upstream
1528 +
1529 +Daemons that need to be launched while the rootfs is read-only can now
1530 +poll /proc/mounts to be notified when their O_RDWR requests may no
1531 +longer end in EROFS.
1532 +
1533 +Cc: Kay Sievers <kay.sievers@××××.org>
1534 +Cc: Neil Brown <neilb@××××.de>
1535 +Signed-off-by: Dan Williams <dan.j.williams@×××××.com>
1536 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
1537 +
1538 +---
1539 + fs/namespace.c | 7 ++++++-
1540 + 1 file changed, 6 insertions(+), 1 deletion(-)
1541 +
1542 +--- a/fs/namespace.c
1543 ++++ b/fs/namespace.c
1544 +@@ -1553,8 +1553,13 @@ static noinline int do_remount(struct na
1545 + if (!err)
1546 + nd->path.mnt->mnt_flags = mnt_flags;
1547 + up_write(&sb->s_umount);
1548 +- if (!err)
1549 ++ if (!err) {
1550 + security_sb_post_remount(nd->path.mnt, flags, data);
1551 ++
1552 ++ spin_lock(&vfsmount_lock);
1553 ++ touch_mnt_namespace(nd->path.mnt->mnt_ns);
1554 ++ spin_unlock(&vfsmount_lock);
1555 ++ }
1556 + return err;
1557 + }
1558 +
1559
1560 Added: hardened/2.6/tags/2.6.26-9/1419_usb-don-t-register-endpoints-for-interfaces-that-are-going-away.patch
1561 ===================================================================
1562 --- hardened/2.6/tags/2.6.26-9/1419_usb-don-t-register-endpoints-for-interfaces-that-are-going-away.patch (rev 0)
1563 +++ hardened/2.6/tags/2.6.26-9/1419_usb-don-t-register-endpoints-for-interfaces-that-are-going-away.patch 2009-01-20 21:29:55 UTC (rev 1479)
1564 @@ -0,0 +1,75 @@
1565 +Added-By: Gordon Malm <gengor@g.o>
1566 +
1567 +Note: Backported to kernel 2.6.26. Original message included below.
1568 +
1569 +---
1570 +
1571 +From 352d026338378b1f13f044e33c1047da6e470056 Mon Sep 17 00:00:00 2001
1572 +From: Alan Stern <stern@×××××××××××××××.edu>
1573 +Date: Wed, 29 Oct 2008 15:16:58 -0400
1574 +Subject: USB: don't register endpoints for interfaces that are going away
1575 +
1576 +From: Alan Stern <stern@×××××××××××××××.edu>
1577 +
1578 +commit 352d026338378b1f13f044e33c1047da6e470056 upstream.
1579 +
1580 +This patch (as1155) fixes a bug in usbcore. When interfaces are
1581 +deleted, either because the device was disconnected or because of a
1582 +configuration change, the extra attribute files and child endpoint
1583 +devices may get left behind. This is because the core removes them
1584 +before calling device_del(). But during device_del(), after the
1585 +driver is unbound the core will reinstall altsetting 0 and recreate
1586 +those extra attributes and children.
1587 +
1588 +The patch prevents this by adding a flag to record when the interface
1589 +is in the midst of being unregistered. When the flag is set, the
1590 +attribute files and child devices will not be created.
1591 +
1592 +Signed-off-by: Alan Stern <stern@×××××××××××××××.edu>
1593 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
1594 +
1595 +---
1596 + drivers/usb/core/message.c | 1 +
1597 + drivers/usb/core/sysfs.c | 2 +-
1598 + include/linux/usb.h | 2 ++
1599 + 3 files changed, 4 insertions(+), 1 deletion(-)
1600 +
1601 +--- a/drivers/usb/core/message.c
1602 ++++ b/drivers/usb/core/message.c
1603 +@@ -1091,6 +1091,7 @@ void usb_disable_device(struct usb_devic
1604 + continue;
1605 + dev_dbg(&dev->dev, "unregistering interface %s\n",
1606 + interface->dev.bus_id);
1607 ++ interface->unregistering = 1;
1608 + usb_remove_sysfs_intf_files(interface);
1609 + device_del(&interface->dev);
1610 + }
1611 +--- a/drivers/usb/core/sysfs.c
1612 ++++ b/drivers/usb/core/sysfs.c
1613 +@@ -816,7 +816,7 @@ int usb_create_sysfs_intf_files(struct u
1614 + struct usb_host_interface *alt = intf->cur_altsetting;
1615 + int retval;
1616 +
1617 +- if (intf->sysfs_files_created)
1618 ++ if (intf->sysfs_files_created || intf->unregistering)
1619 + return 0;
1620 +
1621 + /* The interface string may be present in some altsettings
1622 +--- a/include/linux/usb.h
1623 ++++ b/include/linux/usb.h
1624 +@@ -108,6 +108,7 @@ enum usb_interface_condition {
1625 + * (in probe()), bound to a driver, or unbinding (in disconnect())
1626 + * @is_active: flag set when the interface is bound and not suspended.
1627 + * @sysfs_files_created: sysfs attributes exist
1628 ++ * @unregistering: flag set when the interface is being unregistered
1629 + * @needs_remote_wakeup: flag set when the driver requires remote-wakeup
1630 + * capability during autosuspend.
1631 + * @dev: driver model's view of this device
1632 +@@ -159,6 +160,7 @@ struct usb_interface {
1633 + enum usb_interface_condition condition; /* state of binding */
1634 + unsigned is_active:1; /* the interface is not suspended */
1635 + unsigned sysfs_files_created:1; /* the sysfs attributes exist */
1636 ++ unsigned unregistering:1; /* unregistration is in progress */
1637 + unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */
1638 +
1639 + struct device dev; /* interface specific device info */
1640
1641 Added: hardened/2.6/tags/2.6.26-9/1420_usb-ehci-fix-divide-by-zero-bug.patch
1642 ===================================================================
1643 --- hardened/2.6/tags/2.6.26-9/1420_usb-ehci-fix-divide-by-zero-bug.patch (rev 0)
1644 +++ hardened/2.6/tags/2.6.26-9/1420_usb-ehci-fix-divide-by-zero-bug.patch 2009-01-20 21:29:55 UTC (rev 1479)
1645 @@ -0,0 +1,46 @@
1646 +Added-By: Gordon Malm <gengor@g.o>
1647 +
1648 +---
1649 +
1650 +From 372dd6e8ed924e876f3beb598721e813ad7fa323 Mon Sep 17 00:00:00 2001
1651 +From: Alan Stern <stern@×××××××××××××××.edu>
1652 +Date: Wed, 12 Nov 2008 17:02:57 -0500
1653 +Subject: USB: EHCI: fix divide-by-zero bug
1654 +
1655 +From: Alan Stern <stern@×××××××××××××××.edu>
1656 +
1657 +commit 372dd6e8ed924e876f3beb598721e813ad7fa323 upstream.
1658 +
1659 +This patch (as1164) fixes a bug in the EHCI scheduler. The interval
1660 +value it uses is already in linear format, not logarithmically coded.
1661 +The existing code can sometimes crash the system by trying to divide
1662 +by zero.
1663 +
1664 +Signed-off-by: Alan Stern <stern@×××××××××××××××.edu>
1665 +Cc: David Brownell <david-b@×××××××.net>
1666 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
1667 +
1668 +---
1669 + drivers/usb/host/ehci-sched.c | 4 ++--
1670 + 1 file changed, 2 insertions(+), 2 deletions(-)
1671 +
1672 +--- a/drivers/usb/host/ehci-sched.c
1673 ++++ b/drivers/usb/host/ehci-sched.c
1674 +@@ -918,7 +918,7 @@ iso_stream_init (
1675 + */
1676 + stream->usecs = HS_USECS_ISO (maxp);
1677 + bandwidth = stream->usecs * 8;
1678 +- bandwidth /= 1 << (interval - 1);
1679 ++ bandwidth /= interval;
1680 +
1681 + } else {
1682 + u32 addr;
1683 +@@ -951,7 +951,7 @@ iso_stream_init (
1684 + } else
1685 + stream->raw_mask = smask_out [hs_transfers - 1];
1686 + bandwidth = stream->usecs + stream->c_usecs;
1687 +- bandwidth /= 1 << (interval + 2);
1688 ++ bandwidth /= interval << 3;
1689 +
1690 + /* stream->splits gets created from raw_mask later */
1691 + stream->address = cpu_to_hc32(ehci, addr);
1692
1693 Added: hardened/2.6/tags/2.6.26-9/1421_usb-ehci-fix-handling-of-dead-controllers.patch
1694 ===================================================================
1695 --- hardened/2.6/tags/2.6.26-9/1421_usb-ehci-fix-handling-of-dead-controllers.patch (rev 0)
1696 +++ hardened/2.6/tags/2.6.26-9/1421_usb-ehci-fix-handling-of-dead-controllers.patch 2009-01-20 21:29:55 UTC (rev 1479)
1697 @@ -0,0 +1,93 @@
1698 +Added-By: Gordon Malm <gengor@g.o>
1699 +
1700 +---
1701 +
1702 +From 67b2e029743a52670d77864723b4d0d40f7733b5 Mon Sep 17 00:00:00 2001
1703 +From: Alan Stern <stern@×××××××××××××××.edu>
1704 +Date: Wed, 12 Nov 2008 17:04:53 -0500
1705 +Subject: USB: EHCI: fix handling of dead controllers
1706 +
1707 +From: Alan Stern <stern@×××××××××××××××.edu>
1708 +
1709 +commit 67b2e029743a52670d77864723b4d0d40f7733b5 upstream.
1710 +
1711 +This patch (as1165) makes a few small changes in the logic used by
1712 +ehci-hcd when it encounters a controller error:
1713 +
1714 + Instead of printing out the masked status, it prints the
1715 + original status as read directly from the hardware.
1716 +
1717 + It doesn't check for the STS_HALT status bit before taking
1718 + action. The mere fact that the STS_FATAL bit is set means
1719 + that something bad has happened and the controller needs to
1720 + be reset. With the old code this test could never succeed
1721 + because the STS_HALT bit was masked out from the status.
1722 +
1723 +I anticipate that this will prevent the occasional "irq X: nobody cared"
1724 +problem people encounter when their EHCI controllers die.
1725 +
1726 +Signed-off-by: Alan Stern <stern@×××××××××××××××.edu>
1727 +Cc: David Brownell <david-b@×××××××.net>
1728 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
1729 +
1730 +---
1731 + drivers/usb/host/ehci-hcd.c | 25 ++++++++++++-------------
1732 + 1 file changed, 12 insertions(+), 13 deletions(-)
1733 +
1734 +--- a/drivers/usb/host/ehci-hcd.c
1735 ++++ b/drivers/usb/host/ehci-hcd.c
1736 +@@ -643,7 +643,7 @@ static int ehci_run (struct usb_hcd *hcd
1737 + static irqreturn_t ehci_irq (struct usb_hcd *hcd)
1738 + {
1739 + struct ehci_hcd *ehci = hcd_to_ehci (hcd);
1740 +- u32 status, pcd_status = 0, cmd;
1741 ++ u32 status, masked_status, pcd_status = 0, cmd;
1742 + int bh;
1743 +
1744 + spin_lock (&ehci->lock);
1745 +@@ -656,14 +656,14 @@ static irqreturn_t ehci_irq (struct usb_
1746 + goto dead;
1747 + }
1748 +
1749 +- status &= INTR_MASK;
1750 +- if (!status) { /* irq sharing? */
1751 ++ masked_status = status & INTR_MASK;
1752 ++ if (!masked_status) { /* irq sharing? */
1753 + spin_unlock(&ehci->lock);
1754 + return IRQ_NONE;
1755 + }
1756 +
1757 + /* clear (just) interrupts */
1758 +- ehci_writel(ehci, status, &ehci->regs->status);
1759 ++ ehci_writel(ehci, masked_status, &ehci->regs->status);
1760 + cmd = ehci_readl(ehci, &ehci->regs->command);
1761 + bh = 0;
1762 +
1763 +@@ -731,19 +731,18 @@ static irqreturn_t ehci_irq (struct usb_
1764 +
1765 + /* PCI errors [4.15.2.4] */
1766 + if (unlikely ((status & STS_FATAL) != 0)) {
1767 ++ ehci_err(ehci, "fatal error\n");
1768 + dbg_cmd (ehci, "fatal", ehci_readl(ehci,
1769 + &ehci->regs->command));
1770 + dbg_status (ehci, "fatal", status);
1771 +- if (status & STS_HALT) {
1772 +- ehci_err (ehci, "fatal error\n");
1773 ++ ehci_halt(ehci);
1774 + dead:
1775 +- ehci_reset (ehci);
1776 +- ehci_writel(ehci, 0, &ehci->regs->configured_flag);
1777 +- /* generic layer kills/unlinks all urbs, then
1778 +- * uses ehci_stop to clean up the rest
1779 +- */
1780 +- bh = 1;
1781 +- }
1782 ++ ehci_reset(ehci);
1783 ++ ehci_writel(ehci, 0, &ehci->regs->configured_flag);
1784 ++ /* generic layer kills/unlinks all urbs, then
1785 ++ * uses ehci_stop to clean up the rest
1786 ++ */
1787 ++ bh = 1;
1788 + }
1789 +
1790 + if (bh)
1791
1792 Added: hardened/2.6/tags/2.6.26-9/1422_usb-fix-ps3-usb-shutdown-problems.patch
1793 ===================================================================
1794 --- hardened/2.6/tags/2.6.26-9/1422_usb-fix-ps3-usb-shutdown-problems.patch (rev 0)
1795 +++ hardened/2.6/tags/2.6.26-9/1422_usb-fix-ps3-usb-shutdown-problems.patch 2009-01-20 21:29:55 UTC (rev 1479)
1796 @@ -0,0 +1,64 @@
1797 +Added-By: Gordon Malm <gengor@g.o>
1798 +
1799 +---
1800 +
1801 +From ddcb01ff9bf49c4dbbb058423559f7bc90b89374 Mon Sep 17 00:00:00 2001
1802 +From: Geoff Levand <geoffrey.levand@×××××××.com>
1803 +Date: Fri, 31 Oct 2008 13:52:54 -0700
1804 +Subject: USB: Fix PS3 USB shutdown problems
1805 +
1806 +From: Geoff Levand <geoffrey.levand@×××××××.com>
1807 +
1808 +commit ddcb01ff9bf49c4dbbb058423559f7bc90b89374 upstream.
1809 +
1810 +Add ehci_shutdown() or ohci_shutdown() calls to the USB
1811 +PS3 bus glue. ehci_shutdown() and ohci_shutdown() do some
1812 +controller specific cleanups not done by usb_remove_hcd().
1813 +
1814 +Fixes errors on shutdown or reboot similar to these:
1815 +
1816 + ps3-ehci-driver sb_07: HC died; cleaning up
1817 + irq 51: nobody cared (try booting with the "irqpoll" option)
1818 +
1819 +Related bugzilla reports:
1820 +
1821 + http://bugzilla.kernel.org/show_bug.cgi?id=11819
1822 + http://bugzilla.terrasoftsolutions.com/show_bug.cgi?id=317
1823 +
1824 +Signed-off-by: Geoff Levand <geoffrey.levand@×××××××.com>
1825 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
1826 +
1827 +---
1828 + drivers/usb/host/ehci-ps3.c | 1 +
1829 + drivers/usb/host/ohci-ps3.c | 3 ++-
1830 + 2 files changed, 3 insertions(+), 1 deletion(-)
1831 +
1832 +--- a/drivers/usb/host/ehci-ps3.c
1833 ++++ b/drivers/usb/host/ehci-ps3.c
1834 +@@ -205,6 +205,7 @@ static int ps3_ehci_remove(struct ps3_sy
1835 +
1836 + tmp = hcd->irq;
1837 +
1838 ++ ehci_shutdown(hcd);
1839 + usb_remove_hcd(hcd);
1840 +
1841 + ps3_system_bus_set_driver_data(dev, NULL);
1842 +--- a/drivers/usb/host/ohci-ps3.c
1843 ++++ b/drivers/usb/host/ohci-ps3.c
1844 +@@ -192,7 +192,7 @@ fail_start:
1845 + return result;
1846 + }
1847 +
1848 +-static int ps3_ohci_remove (struct ps3_system_bus_device *dev)
1849 ++static int ps3_ohci_remove(struct ps3_system_bus_device *dev)
1850 + {
1851 + unsigned int tmp;
1852 + struct usb_hcd *hcd =
1853 +@@ -205,6 +205,7 @@ static int ps3_ohci_remove (struct ps3_s
1854 +
1855 + tmp = hcd->irq;
1856 +
1857 ++ ohci_shutdown(hcd);
1858 + usb_remove_hcd(hcd);
1859 +
1860 + ps3_system_bus_set_driver_data(dev, NULL);
1861
1862 Added: hardened/2.6/tags/2.6.26-9/1423_v4l-dvb-cve-2008-5033-fix-oops-on-tvaudio-when-controlling-bass-treble.patch
1863 ===================================================================
1864 --- hardened/2.6/tags/2.6.26-9/1423_v4l-dvb-cve-2008-5033-fix-oops-on-tvaudio-when-controlling-bass-treble.patch (rev 0)
1865 +++ hardened/2.6/tags/2.6.26-9/1423_v4l-dvb-cve-2008-5033-fix-oops-on-tvaudio-when-controlling-bass-treble.patch 2009-01-20 21:29:55 UTC (rev 1479)
1866 @@ -0,0 +1,135 @@
1867 +Added-By: Gordon Malm <gengor@g.o>
1868 +
1869 +---
1870 +
1871 +From 01a1a3cc1e3fbe718bd06a2a5d4d1a2d0fb4d7d9 Mon Sep 17 00:00:00 2001
1872 +From: Mauro Carvalho Chehab <mchehab@××××××.com>
1873 +Date: Fri, 14 Nov 2008 10:46:59 -0300
1874 +Subject: V4L/DVB (9624): CVE-2008-5033: fix OOPS on tvaudio when controlling bass/treble
1875 +
1876 +From: Mauro Carvalho Chehab <mchehab@××××××.com>
1877 +
1878 +commit 01a1a3cc1e3fbe718bd06a2a5d4d1a2d0fb4d7d9 upstream.
1879 +
1880 +This bug were supposed to be fixed by 5ba2f67afb02c5302b2898949ed6fc3b3d37dcf1,
1881 +where a call to NULL happens.
1882 +
1883 +Not all tvaudio chips allow controlling bass/treble. So, the driver
1884 +has a table with a flag to indicate if the chip does support it.
1885 +
1886 +Unfortunately, the handling of this logic were broken for a very long
1887 +time (probably since the first module version). Due to that, an OOPS
1888 +were generated for devices that don't support bass/treble.
1889 +
1890 +This were the resulting OOPS message before the patch, with debug messages
1891 +enabled:
1892 +
1893 +tvaudio' 1-005b: VIDIOC_S_CTRL
1894 +BUG: unable to handle kernel NULL pointer dereference at 00000000
1895 +IP: [<00000000>]
1896 +*pde = 22fda067 *pte = 00000000
1897 +Oops: 0000 [#1] SMP
1898 +Modules linked in: snd_hda_intel snd_seq_dummy snd_seq_oss snd_seq_midi_event snd_seq snd_seq_device
1899 +snd_pcm_oss snd_mixer_oss snd_pcm snd_timer snd_hwdep snd soundcore tuner_simple tuner_types tea5767 tuner
1900 +tvaudio bttv bridgebnep rfcomm l2cap bluetooth it87 hwmon_vid hwmon fuse sunrpc ipt_REJECT
1901 +nf_conntrack_ipv4 iptable_filter ip_tables ip6t_REJECT xt_tcpudp nf_conntrack_ipv6 xt_state nf_conntrack
1902 +ip6table_filter ip6_tables x_tables ipv6 dm_mirrordm_multipath dm_mod configfs videodev v4l1_compat
1903 +ir_common 8139cp compat_ioctl32 v4l2_common 8139too videobuf_dma_sg videobuf_core mii btcx_risc tveeprom
1904 +i915 button snd_page_alloc serio_raw drm pcspkr i2c_algo_bit i2c_i801 i2c_core iTCO_wdt
1905 +iTCO_vendor_support sr_mod cdrom sg ata_generic pata_acpi ata_piix libata sd_mod scsi_mod ext3 jbdmbcache
1906 +uhci_hcd ohci_hcd ehci_hcd [last unloaded: soundcore]
1907 +
1908 +Pid: 15413, comm: qv4l2 Not tainted (2.6.25.14-108.fc9.i686 #1)
1909 +EIP: 0060:[<00000000>] EFLAGS: 00210246 CPU: 0
1910 +EIP is at 0x0
1911 +EAX: 00008000 EBX: ebd21600 ECX: e2fd9ec4 EDX: 00200046
1912 +ESI: f8c0f0c4 EDI: f8c0f0c4 EBP: e2fd9d50 ESP: e2fd9d2c
1913 + DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
1914 +Process qv4l2 (pid: 15413, ti=e2fd9000 task=ebe44000 task.ti=e2fd9000)
1915 +Stack: f8c0c6ae e2ff2a00 00000d00 e2fd9ec4 ebc4e000 e2fd9d5c f8c0c448 00000000
1916 + f899c12a e2fd9d5c f899c154 e2fd9d68 e2fd9d80 c0560185 e2fd9d88 f8f3e1d8
1917 + f8f3e1dc ebc4e034 f8f3e18c e2fd9ec4 00000000 e2fd9d90 f899c286 c008561c
1918 +Call Trace:
1919 + [<f8c0c6ae>] ? chip_command+0x266/0x4b6 [tvaudio]
1920 + [<f8c0c448>] ? chip_command+0x0/0x4b6 [tvaudio]
1921 + [<f899c12a>] ? i2c_cmd+0x0/0x2f [i2c_core]
1922 + [<f899c154>] ? i2c_cmd+0x2a/0x2f [i2c_core]
1923 + [<c0560185>] ? device_for_each_child+0x21/0x49
1924 + [<f899c286>] ? i2c_clients_command+0x1c/0x1e [i2c_core]
1925 + [<f8f283d8>] ? bttv_call_i2c_clients+0x14/0x16 [bttv]
1926 + [<f8f23601>] ? bttv_s_ctrl+0x1bc/0x313 [bttv]
1927 + [<f8f23445>] ? bttv_s_ctrl+0x0/0x313 [bttv]
1928 + [<f8b6096d>] ? __video_do_ioctl+0x1f84/0x3726 [videodev]
1929 + [<c05abb4e>] ? sock_aio_write+0x100/0x10d
1930 + [<c041b23e>] ? kmap_atomic_prot+0x1dd/0x1df
1931 + [<c043a0c9>] ? enqueue_hrtimer+0xc2/0xcd
1932 + [<c04f4fa4>] ? copy_from_user+0x39/0x121
1933 + [<f8b622b9>] ? __video_ioctl2+0x1aa/0x24a [videodev]
1934 + [<c04054fd>] ? do_notify_resume+0x768/0x795
1935 + [<c043c0f7>] ? getnstimeofday+0x34/0xd1
1936 + [<c0437b77>] ? autoremove_wake_function+0x0/0x33
1937 + [<f8b62368>] ? video_ioctl2+0xf/0x13 [videodev]
1938 + [<c048c6f0>] ? vfs_ioctl+0x50/0x69
1939 + [<c048c942>] ? do_vfs_ioctl+0x239/0x24c
1940 + [<c048c995>] ? sys_ioctl+0x40/0x5b
1941 + [<c0405bf2>] ? syscall_call+0x7/0xb
1942 + [<c0620000>] ? cpuid4_cache_sysfs_exit+0x3d/0x69
1943 + =======================
1944 +Code: Bad EIP value.
1945 +EIP: [<00000000>] 0x0 SS:ESP 0068:e2fd9d2c
1946 +
1947 +Signed-off-by: Mauro Carvalho Chehab <mchehab@××××××.com>
1948 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
1949 +
1950 +---
1951 + drivers/media/video/tvaudio.c | 15 +++++++--------
1952 + 1 file changed, 7 insertions(+), 8 deletions(-)
1953 +
1954 +--- a/drivers/media/video/tvaudio.c
1955 ++++ b/drivers/media/video/tvaudio.c
1956 +@@ -1576,13 +1576,13 @@ static int tvaudio_get_ctrl(struct CHIPS
1957 + return 0;
1958 + }
1959 + case V4L2_CID_AUDIO_BASS:
1960 +- if (desc->flags & CHIP_HAS_BASSTREBLE)
1961 ++ if (!(desc->flags & CHIP_HAS_BASSTREBLE))
1962 + break;
1963 + ctrl->value = chip->bass;
1964 + return 0;
1965 + case V4L2_CID_AUDIO_TREBLE:
1966 +- if (desc->flags & CHIP_HAS_BASSTREBLE)
1967 +- return -EINVAL;
1968 ++ if (!(desc->flags & CHIP_HAS_BASSTREBLE))
1969 ++ break;
1970 + ctrl->value = chip->treble;
1971 + return 0;
1972 + }
1973 +@@ -1642,16 +1642,15 @@ static int tvaudio_set_ctrl(struct CHIPS
1974 + return 0;
1975 + }
1976 + case V4L2_CID_AUDIO_BASS:
1977 +- if (desc->flags & CHIP_HAS_BASSTREBLE)
1978 ++ if (!(desc->flags & CHIP_HAS_BASSTREBLE))
1979 + break;
1980 + chip->bass = ctrl->value;
1981 + chip_write(chip,desc->bassreg,desc->bassfunc(chip->bass));
1982 +
1983 + return 0;
1984 + case V4L2_CID_AUDIO_TREBLE:
1985 +- if (desc->flags & CHIP_HAS_BASSTREBLE)
1986 +- return -EINVAL;
1987 +-
1988 ++ if (!(desc->flags & CHIP_HAS_BASSTREBLE))
1989 ++ break;
1990 + chip->treble = ctrl->value;
1991 + chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble));
1992 +
1993 +@@ -1695,7 +1694,7 @@ static int chip_command(struct i2c_clien
1994 + break;
1995 + case V4L2_CID_AUDIO_BASS:
1996 + case V4L2_CID_AUDIO_TREBLE:
1997 +- if (desc->flags & CHIP_HAS_BASSTREBLE)
1998 ++ if (!(desc->flags & CHIP_HAS_BASSTREBLE))
1999 + return -EINVAL;
2000 + break;
2001 + default:
2002
2003 Added: hardened/2.6/tags/2.6.26-9/1424_atm-cve-2008-5079-duplicate-listen-on-socket-corrupts-the-vcc-table.patch
2004 ===================================================================
2005 --- hardened/2.6/tags/2.6.26-9/1424_atm-cve-2008-5079-duplicate-listen-on-socket-corrupts-the-vcc-table.patch (rev 0)
2006 +++ hardened/2.6/tags/2.6.26-9/1424_atm-cve-2008-5079-duplicate-listen-on-socket-corrupts-the-vcc-table.patch 2009-01-20 21:29:55 UTC (rev 1479)
2007 @@ -0,0 +1,45 @@
2008 +Added-By: Gordon Malm <gengor@g.o>
2009 +
2010 +---
2011 +
2012 +From 17b24b3c97498935a2ef9777370b1151dfed3f6f Mon Sep 17 00:00:00 2001
2013 +From: Chas Williams <chas@××××××××××××.mil>
2014 +Date: Thu, 4 Dec 2008 14:58:13 -0800
2015 +Subject: ATM: CVE-2008-5079: duplicate listen() on socket corrupts the vcc table
2016 +
2017 +From: Chas Williams <chas@××××××××××××.mil>
2018 +
2019 +commit 17b24b3c97498935a2ef9777370b1151dfed3f6f upstream.
2020 +
2021 +As reported by Hugo Dias that it is possible to cause a local denial
2022 +of service attack by calling the svc_listen function twice on the same
2023 +socket and reading /proc/net/atm/*vc
2024 +
2025 +Signed-off-by: Chas Williams <chas@××××××××××××.mil>
2026 +Signed-off-by: David S. Miller <davem@×××××××××.net>
2027 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
2028 +
2029 +---
2030 +
2031 +--- a/net/atm/svc.c
2032 ++++ b/net/atm/svc.c
2033 +@@ -293,7 +293,10 @@ static int svc_listen(struct socket *soc
2034 + error = -EINVAL;
2035 + goto out;
2036 + }
2037 +- vcc_insert_socket(sk);
2038 ++ if (test_bit(ATM_VF_LISTEN, &vcc->flags)) {
2039 ++ error = -EADDRINUSE;
2040 ++ goto out;
2041 ++ }
2042 + set_bit(ATM_VF_WAITING, &vcc->flags);
2043 + prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
2044 + sigd_enq(vcc,as_listen,NULL,NULL,&vcc->local);
2045 +@@ -307,6 +310,7 @@ static int svc_listen(struct socket *soc
2046 + goto out;
2047 + }
2048 + set_bit(ATM_VF_LISTEN,&vcc->flags);
2049 ++ vcc_insert_socket(sk);
2050 + sk->sk_max_ack_backlog = backlog > 0 ? backlog : ATM_BACKLOG_DEFAULT;
2051 + error = -sk->sk_err;
2052 + out:
2053
2054 Added: hardened/2.6/tags/2.6.26-9/1425_enforce-a-minimum-sg_io-timeout.patch
2055 ===================================================================
2056 --- hardened/2.6/tags/2.6.26-9/1425_enforce-a-minimum-sg_io-timeout.patch (rev 0)
2057 +++ hardened/2.6/tags/2.6.26-9/1425_enforce-a-minimum-sg_io-timeout.patch 2009-01-20 21:29:55 UTC (rev 1479)
2058 @@ -0,0 +1,64 @@
2059 +Added-By: Gordon Malm <gengor@g.o>
2060 +
2061 +---
2062 +
2063 +From f2f1fa78a155524b849edf359e42a3001ea652c0 Mon Sep 17 00:00:00 2001
2064 +From: Linus Torvalds <torvalds@××××××××××××××××.org>
2065 +Date: Fri, 5 Dec 2008 14:49:18 -0800
2066 +Subject: Enforce a minimum SG_IO timeout
2067 +
2068 +From: Linus Torvalds <torvalds@××××××××××××××××.org>
2069 +
2070 +commit f2f1fa78a155524b849edf359e42a3001ea652c0 upstream.
2071 +
2072 +There's no point in having too short SG_IO timeouts, since if the
2073 +command does end up timing out, we'll end up through the reset sequence
2074 +that is several seconds long in order to abort the command that timed
2075 +out.
2076 +
2077 +As a result, shorter timeouts than a few seconds simply do not make
2078 +sense, as the recovery would be longer than the timeout itself.
2079 +
2080 +Add a BLK_MIN_SG_TIMEOUT to match the existign BLK_DEFAULT_SG_TIMEOUT.
2081 +
2082 +Suggested-by: Alan Cox <alan@××××××××××××××××.uk>
2083 +Acked-by: Tejun Heo <tj@××××××.org>
2084 +Acked-by: Jens Axboe <jens.axboe@××××××.com>
2085 +Cc: Jeff Garzik <jeff@××××××.org>
2086 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
2087 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
2088 +
2089 +---
2090 +
2091 +--- a/block/bsg.c
2092 ++++ b/block/bsg.c
2093 +@@ -202,6 +202,8 @@ static int blk_fill_sgv4_hdr_rq(struct r
2094 + rq->timeout = q->sg_timeout;
2095 + if (!rq->timeout)
2096 + rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
2097 ++ if (rq->timeout < BLK_MIN_SG_TIMEOUT)
2098 ++ rq->timeout = BLK_MIN_SG_TIMEOUT;
2099 +
2100 + return 0;
2101 + }
2102 +--- a/block/scsi_ioctl.c
2103 ++++ b/block/scsi_ioctl.c
2104 +@@ -208,6 +208,8 @@ static int blk_fill_sghdr_rq(struct requ
2105 + rq->timeout = q->sg_timeout;
2106 + if (!rq->timeout)
2107 + rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
2108 ++ if (rq->timeout < BLK_MIN_SG_TIMEOUT)
2109 ++ rq->timeout = BLK_MIN_SG_TIMEOUT;
2110 +
2111 + return 0;
2112 + }
2113 +--- a/include/linux/blkdev.h
2114 ++++ b/include/linux/blkdev.h
2115 +@@ -623,6 +623,7 @@ extern unsigned long blk_max_low_pfn, bl
2116 + * default timeout for SG_IO if none specified
2117 + */
2118 + #define BLK_DEFAULT_SG_TIMEOUT (60 * HZ)
2119 ++#define BLK_MIN_SG_TIMEOUT (7 * HZ)
2120 +
2121 + #ifdef CONFIG_BOUNCE
2122 + extern int init_emergency_isa_pool(void);
2123
2124 Added: hardened/2.6/tags/2.6.26-9/1506_sctp-avoid_memory_overflow_with_bad_stream_ID.patch
2125 ===================================================================
2126 --- hardened/2.6/tags/2.6.26-9/1506_sctp-avoid_memory_overflow_with_bad_stream_ID.patch (rev 0)
2127 +++ hardened/2.6/tags/2.6.26-9/1506_sctp-avoid_memory_overflow_with_bad_stream_ID.patch 2009-01-20 21:29:55 UTC (rev 1479)
2128 @@ -0,0 +1,80 @@
2129 +Added-By: Gordon Malm <gengor@g.o>
2130 +
2131 +Note: Re-diffed to eliminate failed hunks.
2132 +
2133 +---
2134 +
2135 +From: Wei Yongjun <yjwei@××××××××××.com>
2136 +Date: Fri, 26 Dec 2008 00:58:11 +0000 (-0800)
2137 +Subject: sctp: Avoid memory overflow while FWD-TSN chunk is received with bad stream ID
2138 +X-Git-Tag: v2.6.29-rc1~581^2~75
2139 +X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=9fcb95a105758b81ef0131cd18e2db5149f13e95
2140 +
2141 +sctp: Avoid memory overflow while FWD-TSN chunk is received with bad stream ID
2142 +
2143 +If FWD-TSN chunk is received with bad stream ID, the sctp will not do the
2144 +validity check, this may cause memory overflow when overwrite the TSN of
2145 +the stream ID.
2146 +
2147 +The FORWARD-TSN chunk is like this:
2148 +
2149 +FORWARD-TSN chunk
2150 + Type = 192
2151 + Flags = 0
2152 + Length = 172
2153 + NewTSN = 99
2154 + Stream = 10000
2155 + StreamSequence = 0xFFFF
2156 +
2157 +This patch fix this problem by discard the chunk if stream ID is not
2158 +less than MIS.
2159 +
2160 +Signed-off-by: Wei Yongjun <yjwei@××××××××××.com>
2161 +Signed-off-by: Vlad Yasevich <vladislav.yasevich@××.com>
2162 +Signed-off-by: David S. Miller <davem@×××××××××.net>
2163 +---
2164 +
2165 +--- a/net/sctp/sm_statefuns.c
2166 ++++ b/net/sctp/sm_statefuns.c
2167 +@@ -3641,6 +3641,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(c
2168 + {
2169 + struct sctp_chunk *chunk = arg;
2170 + struct sctp_fwdtsn_hdr *fwdtsn_hdr;
2171 ++ struct sctp_fwdtsn_skip *skip;
2172 + __u16 len;
2173 + __u32 tsn;
2174 +
2175 +@@ -3670,6 +3671,12 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(c
2176 + if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0)
2177 + goto discard_noforce;
2178 +
2179 ++ /* Silently discard the chunk if stream-id is not valid */
2180 ++ sctp_walk_fwdtsn(skip, chunk) {
2181 ++ if (ntohs(skip->stream) >= asoc->c.sinit_max_instreams)
2182 ++ goto discard_noforce;
2183 ++ }
2184 ++
2185 + sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn));
2186 + if (len > sizeof(struct sctp_fwdtsn_hdr))
2187 + sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
2188 +@@ -3701,6 +3708,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_f
2189 + {
2190 + struct sctp_chunk *chunk = arg;
2191 + struct sctp_fwdtsn_hdr *fwdtsn_hdr;
2192 ++ struct sctp_fwdtsn_skip *skip;
2193 + __u16 len;
2194 + __u32 tsn;
2195 +
2196 +@@ -3730,6 +3738,12 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_f
2197 + if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0)
2198 + goto gen_shutdown;
2199 +
2200 ++ /* Silently discard the chunk if stream-id is not valid */
2201 ++ sctp_walk_fwdtsn(skip, chunk) {
2202 ++ if (ntohs(skip->stream) >= asoc->c.sinit_max_instreams)
2203 ++ goto gen_shutdown;
2204 ++ }
2205 ++
2206 + sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn));
2207 + if (len > sizeof(struct sctp_fwdtsn_hdr))
2208 + sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
2209
2210 Added: hardened/2.6/tags/2.6.26-9/4420_grsec-2.1.12-2.6.26.6-200810131006.patch
2211 ===================================================================
2212 --- hardened/2.6/tags/2.6.26-9/4420_grsec-2.1.12-2.6.26.6-200810131006.patch (rev 0)
2213 +++ hardened/2.6/tags/2.6.26-9/4420_grsec-2.1.12-2.6.26.6-200810131006.patch 2009-01-20 21:29:55 UTC (rev 1479)
2214 @@ -0,0 +1,37662 @@
2215 +diff -urNp linux-2.6.26.6/arch/alpha/kernel/module.c linux-2.6.26.6/arch/alpha/kernel/module.c
2216 +--- linux-2.6.26.6/arch/alpha/kernel/module.c 2008-10-08 23:24:05.000000000 -0400
2217 ++++ linux-2.6.26.6/arch/alpha/kernel/module.c 2008-10-11 21:54:18.000000000 -0400
2218 +@@ -182,7 +182,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
2219 +
2220 + /* The small sections were sorted to the end of the segment.
2221 + The following should definitely cover them. */
2222 +- gp = (u64)me->module_core + me->core_size - 0x8000;
2223 ++ gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
2224 + got = sechdrs[me->arch.gotsecindex].sh_addr;
2225 +
2226 + for (i = 0; i < n; i++) {
2227 +diff -urNp linux-2.6.26.6/arch/alpha/kernel/osf_sys.c linux-2.6.26.6/arch/alpha/kernel/osf_sys.c
2228 +--- linux-2.6.26.6/arch/alpha/kernel/osf_sys.c 2008-10-08 23:24:05.000000000 -0400
2229 ++++ linux-2.6.26.6/arch/alpha/kernel/osf_sys.c 2008-10-11 21:54:18.000000000 -0400
2230 +@@ -1227,6 +1227,10 @@ arch_get_unmapped_area(struct file *filp
2231 + merely specific addresses, but regions of memory -- perhaps
2232 + this feature should be incorporated into all ports? */
2233 +
2234 ++#ifdef CONFIG_PAX_RANDMMAP
2235 ++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2236 ++#endif
2237 ++
2238 + if (addr) {
2239 + addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
2240 + if (addr != (unsigned long) -ENOMEM)
2241 +@@ -1234,8 +1238,8 @@ arch_get_unmapped_area(struct file *filp
2242 + }
2243 +
2244 + /* Next, try allocating at TASK_UNMAPPED_BASE. */
2245 +- addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
2246 +- len, limit);
2247 ++ addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
2248 ++
2249 + if (addr != (unsigned long) -ENOMEM)
2250 + return addr;
2251 +
2252 +diff -urNp linux-2.6.26.6/arch/alpha/kernel/ptrace.c linux-2.6.26.6/arch/alpha/kernel/ptrace.c
2253 +--- linux-2.6.26.6/arch/alpha/kernel/ptrace.c 2008-10-08 23:24:05.000000000 -0400
2254 ++++ linux-2.6.26.6/arch/alpha/kernel/ptrace.c 2008-10-11 21:54:18.000000000 -0400
2255 +@@ -15,6 +15,7 @@
2256 + #include <linux/slab.h>
2257 + #include <linux/security.h>
2258 + #include <linux/signal.h>
2259 ++#include <linux/grsecurity.h>
2260 +
2261 + #include <asm/uaccess.h>
2262 + #include <asm/pgtable.h>
2263 +@@ -266,6 +267,9 @@ long arch_ptrace(struct task_struct *chi
2264 + size_t copied;
2265 + long ret;
2266 +
2267 ++ if (gr_handle_ptrace(child, request))
2268 ++ return -EPERM;
2269 ++
2270 + switch (request) {
2271 + /* When I and D space are separate, these will need to be fixed. */
2272 + case PTRACE_PEEKTEXT: /* read word at location addr. */
2273 +diff -urNp linux-2.6.26.6/arch/alpha/mm/fault.c linux-2.6.26.6/arch/alpha/mm/fault.c
2274 +--- linux-2.6.26.6/arch/alpha/mm/fault.c 2008-10-08 23:24:05.000000000 -0400
2275 ++++ linux-2.6.26.6/arch/alpha/mm/fault.c 2008-10-11 21:54:18.000000000 -0400
2276 +@@ -54,6 +54,124 @@ __load_new_mm_context(struct mm_struct *
2277 + __reload_thread(pcb);
2278 + }
2279 +
2280 ++#ifdef CONFIG_PAX_PAGEEXEC
2281 ++/*
2282 ++ * PaX: decide what to do with offenders (regs->pc = fault address)
2283 ++ *
2284 ++ * returns 1 when task should be killed
2285 ++ * 2 when patched PLT trampoline was detected
2286 ++ * 3 when unpatched PLT trampoline was detected
2287 ++ */
2288 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
2289 ++{
2290 ++
2291 ++#ifdef CONFIG_PAX_EMUPLT
2292 ++ int err;
2293 ++
2294 ++ do { /* PaX: patched PLT emulation #1 */
2295 ++ unsigned int ldah, ldq, jmp;
2296 ++
2297 ++ err = get_user(ldah, (unsigned int *)regs->pc);
2298 ++ err |= get_user(ldq, (unsigned int *)(regs->pc+4));
2299 ++ err |= get_user(jmp, (unsigned int *)(regs->pc+8));
2300 ++
2301 ++ if (err)
2302 ++ break;
2303 ++
2304 ++ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
2305 ++ (ldq & 0xFFFF0000U) == 0xA77B0000U &&
2306 ++ jmp == 0x6BFB0000U)
2307 ++ {
2308 ++ unsigned long r27, addr;
2309 ++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
2310 ++ unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
2311 ++
2312 ++ addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
2313 ++ err = get_user(r27, (unsigned long *)addr);
2314 ++ if (err)
2315 ++ break;
2316 ++
2317 ++ regs->r27 = r27;
2318 ++ regs->pc = r27;
2319 ++ return 2;
2320 ++ }
2321 ++ } while (0);
2322 ++
2323 ++ do { /* PaX: patched PLT emulation #2 */
2324 ++ unsigned int ldah, lda, br;
2325 ++
2326 ++ err = get_user(ldah, (unsigned int *)regs->pc);
2327 ++ err |= get_user(lda, (unsigned int *)(regs->pc+4));
2328 ++ err |= get_user(br, (unsigned int *)(regs->pc+8));
2329 ++
2330 ++ if (err)
2331 ++ break;
2332 ++
2333 ++ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
2334 ++ (lda & 0xFFFF0000U) == 0xA77B0000U &&
2335 ++ (br & 0xFFE00000U) == 0xC3E00000U)
2336 ++ {
2337 ++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
2338 ++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
2339 ++ unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
2340 ++
2341 ++ regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
2342 ++ regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
2343 ++ return 2;
2344 ++ }
2345 ++ } while (0);
2346 ++
2347 ++ do { /* PaX: unpatched PLT emulation */
2348 ++ unsigned int br;
2349 ++
2350 ++ err = get_user(br, (unsigned int *)regs->pc);
2351 ++
2352 ++ if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
2353 ++ unsigned int br2, ldq, nop, jmp;
2354 ++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
2355 ++
2356 ++ addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
2357 ++ err = get_user(br2, (unsigned int *)addr);
2358 ++ err |= get_user(ldq, (unsigned int *)(addr+4));
2359 ++ err |= get_user(nop, (unsigned int *)(addr+8));
2360 ++ err |= get_user(jmp, (unsigned int *)(addr+12));
2361 ++ err |= get_user(resolver, (unsigned long *)(addr+16));
2362 ++
2363 ++ if (err)
2364 ++ break;
2365 ++
2366 ++ if (br2 == 0xC3600000U &&
2367 ++ ldq == 0xA77B000CU &&
2368 ++ nop == 0x47FF041FU &&
2369 ++ jmp == 0x6B7B0000U)
2370 ++ {
2371 ++ regs->r28 = regs->pc+4;
2372 ++ regs->r27 = addr+16;
2373 ++ regs->pc = resolver;
2374 ++ return 3;
2375 ++ }
2376 ++ }
2377 ++ } while (0);
2378 ++#endif
2379 ++
2380 ++ return 1;
2381 ++}
2382 ++
2383 ++void pax_report_insns(void *pc, void *sp)
2384 ++{
2385 ++ unsigned long i;
2386 ++
2387 ++ printk(KERN_ERR "PAX: bytes at PC: ");
2388 ++ for (i = 0; i < 5; i++) {
2389 ++ unsigned int c;
2390 ++ if (get_user(c, (unsigned int *)pc+i))
2391 ++ printk(KERN_CONT "???????? ");
2392 ++ else
2393 ++ printk(KERN_CONT "%08x ", c);
2394 ++ }
2395 ++ printk("\n");
2396 ++}
2397 ++#endif
2398 +
2399 + /*
2400 + * This routine handles page faults. It determines the address,
2401 +@@ -131,8 +249,29 @@ do_page_fault(unsigned long address, uns
2402 + good_area:
2403 + si_code = SEGV_ACCERR;
2404 + if (cause < 0) {
2405 +- if (!(vma->vm_flags & VM_EXEC))
2406 ++ if (!(vma->vm_flags & VM_EXEC)) {
2407 ++
2408 ++#ifdef CONFIG_PAX_PAGEEXEC
2409 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
2410 ++ goto bad_area;
2411 ++
2412 ++ up_read(&mm->mmap_sem);
2413 ++ switch (pax_handle_fetch_fault(regs)) {
2414 ++
2415 ++#ifdef CONFIG_PAX_EMUPLT
2416 ++ case 2:
2417 ++ case 3:
2418 ++ return;
2419 ++#endif
2420 ++
2421 ++ }
2422 ++ pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
2423 ++ do_group_exit(SIGKILL);
2424 ++#else
2425 + goto bad_area;
2426 ++#endif
2427 ++
2428 ++ }
2429 + } else if (!cause) {
2430 + /* Allow reads even for write-only mappings */
2431 + if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
2432 +diff -urNp linux-2.6.26.6/arch/arm/mm/mmap.c linux-2.6.26.6/arch/arm/mm/mmap.c
2433 +--- linux-2.6.26.6/arch/arm/mm/mmap.c 2008-10-08 23:24:05.000000000 -0400
2434 ++++ linux-2.6.26.6/arch/arm/mm/mmap.c 2008-10-11 21:54:19.000000000 -0400
2435 +@@ -60,6 +60,10 @@ arch_get_unmapped_area(struct file *filp
2436 + if (len > TASK_SIZE)
2437 + return -ENOMEM;
2438 +
2439 ++#ifdef CONFIG_PAX_RANDMMAP
2440 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2441 ++#endif
2442 ++
2443 + if (addr) {
2444 + if (do_align)
2445 + addr = COLOUR_ALIGN(addr, pgoff);
2446 +@@ -72,10 +76,10 @@ arch_get_unmapped_area(struct file *filp
2447 + return addr;
2448 + }
2449 + if (len > mm->cached_hole_size) {
2450 +- start_addr = addr = mm->free_area_cache;
2451 ++ start_addr = addr = mm->free_area_cache;
2452 + } else {
2453 +- start_addr = addr = TASK_UNMAPPED_BASE;
2454 +- mm->cached_hole_size = 0;
2455 ++ start_addr = addr = mm->mmap_base;
2456 ++ mm->cached_hole_size = 0;
2457 + }
2458 +
2459 + full_search:
2460 +@@ -91,8 +95,8 @@ full_search:
2461 + * Start a new search - just in case we missed
2462 + * some holes.
2463 + */
2464 +- if (start_addr != TASK_UNMAPPED_BASE) {
2465 +- start_addr = addr = TASK_UNMAPPED_BASE;
2466 ++ if (start_addr != mm->mmap_base) {
2467 ++ start_addr = addr = mm->mmap_base;
2468 + mm->cached_hole_size = 0;
2469 + goto full_search;
2470 + }
2471 +diff -urNp linux-2.6.26.6/arch/avr32/mm/fault.c linux-2.6.26.6/arch/avr32/mm/fault.c
2472 +--- linux-2.6.26.6/arch/avr32/mm/fault.c 2008-10-08 23:24:05.000000000 -0400
2473 ++++ linux-2.6.26.6/arch/avr32/mm/fault.c 2008-10-11 21:54:19.000000000 -0400
2474 +@@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
2475 +
2476 + int exception_trace = 1;
2477 +
2478 ++#ifdef CONFIG_PAX_PAGEEXEC
2479 ++void pax_report_insns(void *pc, void *sp)
2480 ++{
2481 ++ unsigned long i;
2482 ++
2483 ++ printk(KERN_ERR "PAX: bytes at PC: ");
2484 ++ for (i = 0; i < 20; i++) {
2485 ++ unsigned char c;
2486 ++ if (get_user(c, (unsigned char *)pc+i))
2487 ++ printk(KERN_CONT "???????? ");
2488 ++ else
2489 ++ printk(KERN_CONT "%02x ", c);
2490 ++ }
2491 ++ printk("\n");
2492 ++}
2493 ++#endif
2494 ++
2495 + /*
2496 + * This routine handles page faults. It determines the address and the
2497 + * problem, and then passes it off to one of the appropriate routines.
2498 +@@ -157,6 +174,16 @@ bad_area:
2499 + up_read(&mm->mmap_sem);
2500 +
2501 + if (user_mode(regs)) {
2502 ++
2503 ++#ifdef CONFIG_PAX_PAGEEXEC
2504 ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
2505 ++ if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
2506 ++ pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
2507 ++ do_group_exit(SIGKILL);
2508 ++ }
2509 ++ }
2510 ++#endif
2511 ++
2512 + if (exception_trace && printk_ratelimit())
2513 + printk("%s%s[%d]: segfault at %08lx pc %08lx "
2514 + "sp %08lx ecr %lu\n",
2515 +diff -urNp linux-2.6.26.6/arch/ia64/ia32/binfmt_elf32.c linux-2.6.26.6/arch/ia64/ia32/binfmt_elf32.c
2516 +--- linux-2.6.26.6/arch/ia64/ia32/binfmt_elf32.c 2008-10-08 23:24:05.000000000 -0400
2517 ++++ linux-2.6.26.6/arch/ia64/ia32/binfmt_elf32.c 2008-10-11 21:54:19.000000000 -0400
2518 +@@ -45,6 +45,13 @@ randomize_stack_top(unsigned long stack_
2519 +
2520 + #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
2521 +
2522 ++#ifdef CONFIG_PAX_ASLR
2523 ++#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
2524 ++
2525 ++#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
2526 ++#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
2527 ++#endif
2528 ++
2529 + /* Ugly but avoids duplication */
2530 + #include "../../../fs/binfmt_elf.c"
2531 +
2532 +diff -urNp linux-2.6.26.6/arch/ia64/ia32/ia32priv.h linux-2.6.26.6/arch/ia64/ia32/ia32priv.h
2533 +--- linux-2.6.26.6/arch/ia64/ia32/ia32priv.h 2008-10-08 23:24:05.000000000 -0400
2534 ++++ linux-2.6.26.6/arch/ia64/ia32/ia32priv.h 2008-10-11 21:54:19.000000000 -0400
2535 +@@ -303,7 +303,14 @@ struct old_linux32_dirent {
2536 + #define ELF_DATA ELFDATA2LSB
2537 + #define ELF_ARCH EM_386
2538 +
2539 +-#define IA32_STACK_TOP IA32_PAGE_OFFSET
2540 ++#ifdef CONFIG_PAX_RANDUSTACK
2541 ++#define __IA32_DELTA_STACK (current->mm->delta_stack)
2542 ++#else
2543 ++#define __IA32_DELTA_STACK 0UL
2544 ++#endif
2545 ++
2546 ++#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
2547 ++
2548 + #define IA32_GATE_OFFSET IA32_PAGE_OFFSET
2549 + #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
2550 +
2551 +diff -urNp linux-2.6.26.6/arch/ia64/kernel/module.c linux-2.6.26.6/arch/ia64/kernel/module.c
2552 +--- linux-2.6.26.6/arch/ia64/kernel/module.c 2008-10-08 23:24:05.000000000 -0400
2553 ++++ linux-2.6.26.6/arch/ia64/kernel/module.c 2008-10-11 21:54:19.000000000 -0400
2554 +@@ -321,7 +321,7 @@ module_alloc (unsigned long size)
2555 + void
2556 + module_free (struct module *mod, void *module_region)
2557 + {
2558 +- if (mod->arch.init_unw_table && module_region == mod->module_init) {
2559 ++ if (mod->arch.init_unw_table && module_region == mod->module_init_rx) {
2560 + unw_remove_unwind_table(mod->arch.init_unw_table);
2561 + mod->arch.init_unw_table = NULL;
2562 + }
2563 +@@ -499,15 +499,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
2564 + }
2565 +
2566 + static inline int
2567 ++in_init_rx (const struct module *mod, uint64_t addr)
2568 ++{
2569 ++ return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
2570 ++}
2571 ++
2572 ++static inline int
2573 ++in_init_rw (const struct module *mod, uint64_t addr)
2574 ++{
2575 ++ return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
2576 ++}
2577 ++
2578 ++static inline int
2579 + in_init (const struct module *mod, uint64_t addr)
2580 + {
2581 +- return addr - (uint64_t) mod->module_init < mod->init_size;
2582 ++ return in_init_rx(mod, addr) || in_init_rw(mod, addr);
2583 ++}
2584 ++
2585 ++static inline int
2586 ++in_core_rx (const struct module *mod, uint64_t addr)
2587 ++{
2588 ++ return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
2589 ++}
2590 ++
2591 ++static inline int
2592 ++in_core_rw (const struct module *mod, uint64_t addr)
2593 ++{
2594 ++ return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
2595 + }
2596 +
2597 + static inline int
2598 + in_core (const struct module *mod, uint64_t addr)
2599 + {
2600 +- return addr - (uint64_t) mod->module_core < mod->core_size;
2601 ++ return in_core_rx(mod, addr) || in_core_rw(mod, addr);
2602 + }
2603 +
2604 + static inline int
2605 +@@ -691,7 +715,14 @@ do_reloc (struct module *mod, uint8_t r_
2606 + break;
2607 +
2608 + case RV_BDREL:
2609 +- val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
2610 ++ if (in_init_rx(mod, val))
2611 ++ val -= (uint64_t) mod->module_init_rx;
2612 ++ else if (in_init_rw(mod, val))
2613 ++ val -= (uint64_t) mod->module_init_rw;
2614 ++ else if (in_core_rx(mod, val))
2615 ++ val -= (uint64_t) mod->module_core_rx;
2616 ++ else if (in_core_rw(mod, val))
2617 ++ val -= (uint64_t) mod->module_core_rw;
2618 + break;
2619 +
2620 + case RV_LTV:
2621 +@@ -825,15 +856,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
2622 + * addresses have been selected...
2623 + */
2624 + uint64_t gp;
2625 +- if (mod->core_size > MAX_LTOFF)
2626 ++ if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
2627 + /*
2628 + * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
2629 + * at the end of the module.
2630 + */
2631 +- gp = mod->core_size - MAX_LTOFF / 2;
2632 ++ gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
2633 + else
2634 +- gp = mod->core_size / 2;
2635 +- gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
2636 ++ gp = (mod->core_size_rx + mod->core_size_rw) / 2;
2637 ++ gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
2638 + mod->arch.gp = gp;
2639 + DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
2640 + }
2641 +diff -urNp linux-2.6.26.6/arch/ia64/kernel/sys_ia64.c linux-2.6.26.6/arch/ia64/kernel/sys_ia64.c
2642 +--- linux-2.6.26.6/arch/ia64/kernel/sys_ia64.c 2008-10-08 23:24:05.000000000 -0400
2643 ++++ linux-2.6.26.6/arch/ia64/kernel/sys_ia64.c 2008-10-11 21:54:19.000000000 -0400
2644 +@@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
2645 + if (REGION_NUMBER(addr) == RGN_HPAGE)
2646 + addr = 0;
2647 + #endif
2648 ++
2649 ++#ifdef CONFIG_PAX_RANDMMAP
2650 ++ if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
2651 ++ addr = mm->free_area_cache;
2652 ++ else
2653 ++#endif
2654 ++
2655 + if (!addr)
2656 + addr = mm->free_area_cache;
2657 +
2658 +@@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil
2659 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
2660 + /* At this point: (!vma || addr < vma->vm_end). */
2661 + if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
2662 +- if (start_addr != TASK_UNMAPPED_BASE) {
2663 ++ if (start_addr != mm->mmap_base) {
2664 + /* Start a new search --- just in case we missed some holes. */
2665 +- addr = TASK_UNMAPPED_BASE;
2666 ++ addr = mm->mmap_base;
2667 + goto full_search;
2668 + }
2669 + return -ENOMEM;
2670 +diff -urNp linux-2.6.26.6/arch/ia64/mm/fault.c linux-2.6.26.6/arch/ia64/mm/fault.c
2671 +--- linux-2.6.26.6/arch/ia64/mm/fault.c 2008-10-08 23:24:05.000000000 -0400
2672 ++++ linux-2.6.26.6/arch/ia64/mm/fault.c 2008-10-11 21:54:19.000000000 -0400
2673 +@@ -72,6 +72,23 @@ mapped_kernel_page_is_present (unsigned
2674 + return pte_present(pte);
2675 + }
2676 +
2677 ++#ifdef CONFIG_PAX_PAGEEXEC
2678 ++void pax_report_insns(void *pc, void *sp)
2679 ++{
2680 ++ unsigned long i;
2681 ++
2682 ++ printk(KERN_ERR "PAX: bytes at PC: ");
2683 ++ for (i = 0; i < 8; i++) {
2684 ++ unsigned int c;
2685 ++ if (get_user(c, (unsigned int *)pc+i))
2686 ++ printk(KERN_CONT "???????? ");
2687 ++ else
2688 ++ printk(KERN_CONT "%08x ", c);
2689 ++ }
2690 ++ printk("\n");
2691 ++}
2692 ++#endif
2693 ++
2694 + void __kprobes
2695 + ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
2696 + {
2697 +@@ -145,9 +162,23 @@ ia64_do_page_fault (unsigned long addres
2698 + mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
2699 + | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
2700 +
2701 +- if ((vma->vm_flags & mask) != mask)
2702 ++ if ((vma->vm_flags & mask) != mask) {
2703 ++
2704 ++#ifdef CONFIG_PAX_PAGEEXEC
2705 ++ if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
2706 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
2707 ++ goto bad_area;
2708 ++
2709 ++ up_read(&mm->mmap_sem);
2710 ++ pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
2711 ++ do_group_exit(SIGKILL);
2712 ++ }
2713 ++#endif
2714 ++
2715 + goto bad_area;
2716 +
2717 ++ }
2718 ++
2719 + survive:
2720 + /*
2721 + * If for any reason at all we couldn't handle the fault, make
2722 +diff -urNp linux-2.6.26.6/arch/ia64/mm/init.c linux-2.6.26.6/arch/ia64/mm/init.c
2723 +--- linux-2.6.26.6/arch/ia64/mm/init.c 2008-10-08 23:24:05.000000000 -0400
2724 ++++ linux-2.6.26.6/arch/ia64/mm/init.c 2008-10-11 21:54:19.000000000 -0400
2725 +@@ -122,6 +122,19 @@ ia64_init_addr_space (void)
2726 + vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
2727 + vma->vm_end = vma->vm_start + PAGE_SIZE;
2728 + vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
2729 ++
2730 ++#ifdef CONFIG_PAX_PAGEEXEC
2731 ++ if (current->mm->pax_flags & MF_PAX_PAGEEXEC) {
2732 ++ vma->vm_flags &= ~VM_EXEC;
2733 ++
2734 ++#ifdef CONFIG_PAX_MPROTECT
2735 ++ if (current->mm->pax_flags & MF_PAX_MPROTECT)
2736 ++ vma->vm_flags &= ~VM_MAYEXEC;
2737 ++#endif
2738 ++
2739 ++ }
2740 ++#endif
2741 ++
2742 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
2743 + down_write(&current->mm->mmap_sem);
2744 + if (insert_vm_struct(current->mm, vma)) {
2745 +diff -urNp linux-2.6.26.6/arch/mips/kernel/binfmt_elfn32.c linux-2.6.26.6/arch/mips/kernel/binfmt_elfn32.c
2746 +--- linux-2.6.26.6/arch/mips/kernel/binfmt_elfn32.c 2008-10-08 23:24:05.000000000 -0400
2747 ++++ linux-2.6.26.6/arch/mips/kernel/binfmt_elfn32.c 2008-10-11 21:54:19.000000000 -0400
2748 +@@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
2749 + #undef ELF_ET_DYN_BASE
2750 + #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
2751 +
2752 ++#ifdef CONFIG_PAX_ASLR
2753 ++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
2754 ++
2755 ++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
2756 ++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
2757 ++#endif
2758 ++
2759 + #include <asm/processor.h>
2760 + #include <linux/module.h>
2761 + #include <linux/elfcore.h>
2762 +diff -urNp linux-2.6.26.6/arch/mips/kernel/binfmt_elfo32.c linux-2.6.26.6/arch/mips/kernel/binfmt_elfo32.c
2763 +--- linux-2.6.26.6/arch/mips/kernel/binfmt_elfo32.c 2008-10-08 23:24:05.000000000 -0400
2764 ++++ linux-2.6.26.6/arch/mips/kernel/binfmt_elfo32.c 2008-10-11 21:54:19.000000000 -0400
2765 +@@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
2766 + #undef ELF_ET_DYN_BASE
2767 + #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
2768 +
2769 ++#ifdef CONFIG_PAX_ASLR
2770 ++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
2771 ++
2772 ++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
2773 ++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
2774 ++#endif
2775 ++
2776 + #include <asm/processor.h>
2777 + #include <linux/module.h>
2778 + #include <linux/elfcore.h>
2779 +diff -urNp linux-2.6.26.6/arch/mips/kernel/syscall.c linux-2.6.26.6/arch/mips/kernel/syscall.c
2780 +--- linux-2.6.26.6/arch/mips/kernel/syscall.c 2008-10-08 23:24:05.000000000 -0400
2781 ++++ linux-2.6.26.6/arch/mips/kernel/syscall.c 2008-10-11 21:54:19.000000000 -0400
2782 +@@ -93,6 +93,11 @@ unsigned long arch_get_unmapped_area(str
2783 + do_color_align = 0;
2784 + if (filp || (flags & MAP_SHARED))
2785 + do_color_align = 1;
2786 ++
2787 ++#ifdef CONFIG_PAX_RANDMMAP
2788 ++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2789 ++#endif
2790 ++
2791 + if (addr) {
2792 + if (do_color_align)
2793 + addr = COLOUR_ALIGN(addr, pgoff);
2794 +@@ -103,7 +108,7 @@ unsigned long arch_get_unmapped_area(str
2795 + (!vmm || addr + len <= vmm->vm_start))
2796 + return addr;
2797 + }
2798 +- addr = TASK_UNMAPPED_BASE;
2799 ++ addr = current->mm->mmap_base;
2800 + if (do_color_align)
2801 + addr = COLOUR_ALIGN(addr, pgoff);
2802 + else
2803 +diff -urNp linux-2.6.26.6/arch/mips/mm/fault.c linux-2.6.26.6/arch/mips/mm/fault.c
2804 +--- linux-2.6.26.6/arch/mips/mm/fault.c 2008-10-08 23:24:05.000000000 -0400
2805 ++++ linux-2.6.26.6/arch/mips/mm/fault.c 2008-10-11 21:54:19.000000000 -0400
2806 +@@ -26,6 +26,23 @@
2807 + #include <asm/ptrace.h>
2808 + #include <asm/highmem.h> /* For VMALLOC_END */
2809 +
2810 ++#ifdef CONFIG_PAX_PAGEEXEC
2811 ++void pax_report_insns(void *pc)
2812 ++{
2813 ++ unsigned long i;
2814 ++
2815 ++ printk(KERN_ERR "PAX: bytes at PC: ");
2816 ++ for (i = 0; i < 5; i++) {
2817 ++ unsigned int c;
2818 ++ if (get_user(c, (unsigned int *)pc+i))
2819 ++ printk(KERN_CONT "???????? ");
2820 ++ else
2821 ++ printk(KERN_CONT "%08x ", c);
2822 ++ }
2823 ++ printk("\n");
2824 ++}
2825 ++#endif
2826 ++
2827 + /*
2828 + * This routine handles page faults. It determines the address,
2829 + * and the problem, and then passes it off to one of the appropriate
2830 +diff -urNp linux-2.6.26.6/arch/parisc/kernel/module.c linux-2.6.26.6/arch/parisc/kernel/module.c
2831 +--- linux-2.6.26.6/arch/parisc/kernel/module.c 2008-10-08 23:24:05.000000000 -0400
2832 ++++ linux-2.6.26.6/arch/parisc/kernel/module.c 2008-10-11 21:54:19.000000000 -0400
2833 +@@ -73,16 +73,38 @@
2834 +
2835 + /* three functions to determine where in the module core
2836 + * or init pieces the location is */
2837 ++static inline int in_init_rx(struct module *me, void *loc)
2838 ++{
2839 ++ return (loc >= me->module_init_rx &&
2840 ++ loc < (me->module_init_rx + me->init_size_rx));
2841 ++}
2842 ++
2843 ++static inline int in_init_rw(struct module *me, void *loc)
2844 ++{
2845 ++ return (loc >= me->module_init_rw &&
2846 ++ loc < (me->module_init_rw + me->init_size_rw));
2847 ++}
2848 ++
2849 + static inline int in_init(struct module *me, void *loc)
2850 + {
2851 +- return (loc >= me->module_init &&
2852 +- loc <= (me->module_init + me->init_size));
2853 ++ return in_init_rx(me, loc) || in_init_rw(me, loc);
2854 ++}
2855 ++
2856 ++static inline int in_core_rx(struct module *me, void *loc)
2857 ++{
2858 ++ return (loc >= me->module_core_rx &&
2859 ++ loc < (me->module_core_rx + me->core_size_rx));
2860 ++}
2861 ++
2862 ++static inline int in_core_rw(struct module *me, void *loc)
2863 ++{
2864 ++ return (loc >= me->module_core_rw &&
2865 ++ loc < (me->module_core_rw + me->core_size_rw));
2866 + }
2867 +
2868 + static inline int in_core(struct module *me, void *loc)
2869 + {
2870 +- return (loc >= me->module_core &&
2871 +- loc <= (me->module_core + me->core_size));
2872 ++ return in_core_rx(me, loc) || in_core_rw(me, loc);
2873 + }
2874 +
2875 + static inline int in_local(struct module *me, void *loc)
2876 +@@ -296,21 +318,21 @@ int module_frob_arch_sections(CONST Elf_
2877 + }
2878 +
2879 + /* align things a bit */
2880 +- me->core_size = ALIGN(me->core_size, 16);
2881 +- me->arch.got_offset = me->core_size;
2882 +- me->core_size += gots * sizeof(struct got_entry);
2883 +-
2884 +- me->core_size = ALIGN(me->core_size, 16);
2885 +- me->arch.fdesc_offset = me->core_size;
2886 +- me->core_size += fdescs * sizeof(Elf_Fdesc);
2887 +-
2888 +- me->core_size = ALIGN(me->core_size, 16);
2889 +- me->arch.stub_offset = me->core_size;
2890 +- me->core_size += stubs * sizeof(struct stub_entry);
2891 +-
2892 +- me->init_size = ALIGN(me->init_size, 16);
2893 +- me->arch.init_stub_offset = me->init_size;
2894 +- me->init_size += init_stubs * sizeof(struct stub_entry);
2895 ++ me->core_size_rw = ALIGN(me->core_size_rw, 16);
2896 ++ me->arch.got_offset = me->core_size_rw;
2897 ++ me->core_size_rw += gots * sizeof(struct got_entry);
2898 ++
2899 ++ me->core_size_rw = ALIGN(me->core_size_rw, 16);
2900 ++ me->arch.fdesc_offset = me->core_size_rw;
2901 ++ me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
2902 ++
2903 ++ me->core_size_rx = ALIGN(me->core_size_rx, 16);
2904 ++ me->arch.stub_offset = me->core_size_rx;
2905 ++ me->core_size_rx += stubs * sizeof(struct stub_entry);
2906 ++
2907 ++ me->init_size_rx = ALIGN(me->init_size_rx, 16);
2908 ++ me->arch.init_stub_offset = me->init_size_rx;
2909 ++ me->init_size_rx += init_stubs * sizeof(struct stub_entry);
2910 +
2911 + me->arch.got_max = gots;
2912 + me->arch.fdesc_max = fdescs;
2913 +@@ -330,7 +352,7 @@ static Elf64_Word get_got(struct module
2914 +
2915 + BUG_ON(value == 0);
2916 +
2917 +- got = me->module_core + me->arch.got_offset;
2918 ++ got = me->module_core_rw + me->arch.got_offset;
2919 + for (i = 0; got[i].addr; i++)
2920 + if (got[i].addr == value)
2921 + goto out;
2922 +@@ -348,7 +370,7 @@ static Elf64_Word get_got(struct module
2923 + #ifdef CONFIG_64BIT
2924 + static Elf_Addr get_fdesc(struct module *me, unsigned long value)
2925 + {
2926 +- Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
2927 ++ Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
2928 +
2929 + if (!value) {
2930 + printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
2931 +@@ -366,7 +388,7 @@ static Elf_Addr get_fdesc(struct module
2932 +
2933 + /* Create new one */
2934 + fdesc->addr = value;
2935 +- fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
2936 ++ fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
2937 + return (Elf_Addr)fdesc;
2938 + }
2939 + #endif /* CONFIG_64BIT */
2940 +@@ -386,12 +408,12 @@ static Elf_Addr get_stub(struct module *
2941 + if(init_section) {
2942 + i = me->arch.init_stub_count++;
2943 + BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
2944 +- stub = me->module_init + me->arch.init_stub_offset +
2945 ++ stub = me->module_init_rx + me->arch.init_stub_offset +
2946 + i * sizeof(struct stub_entry);
2947 + } else {
2948 + i = me->arch.stub_count++;
2949 + BUG_ON(me->arch.stub_count > me->arch.stub_max);
2950 +- stub = me->module_core + me->arch.stub_offset +
2951 ++ stub = me->module_core_rx + me->arch.stub_offset +
2952 + i * sizeof(struct stub_entry);
2953 + }
2954 +
2955 +@@ -759,7 +781,7 @@ register_unwind_table(struct module *me,
2956 +
2957 + table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
2958 + end = table + sechdrs[me->arch.unwind_section].sh_size;
2959 +- gp = (Elf_Addr)me->module_core + me->arch.got_offset;
2960 ++ gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
2961 +
2962 + DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
2963 + me->arch.unwind_section, table, end, gp);
2964 +diff -urNp linux-2.6.26.6/arch/parisc/kernel/sys_parisc.c linux-2.6.26.6/arch/parisc/kernel/sys_parisc.c
2965 +--- linux-2.6.26.6/arch/parisc/kernel/sys_parisc.c 2008-10-08 23:24:05.000000000 -0400
2966 ++++ linux-2.6.26.6/arch/parisc/kernel/sys_parisc.c 2008-10-11 21:54:19.000000000 -0400
2967 +@@ -98,7 +98,7 @@ unsigned long arch_get_unmapped_area(str
2968 + if (flags & MAP_FIXED)
2969 + return addr;
2970 + if (!addr)
2971 +- addr = TASK_UNMAPPED_BASE;
2972 ++ addr = current->mm->mmap_base;
2973 +
2974 + if (filp) {
2975 + addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
2976 +diff -urNp linux-2.6.26.6/arch/parisc/kernel/traps.c linux-2.6.26.6/arch/parisc/kernel/traps.c
2977 +--- linux-2.6.26.6/arch/parisc/kernel/traps.c 2008-10-08 23:24:05.000000000 -0400
2978 ++++ linux-2.6.26.6/arch/parisc/kernel/traps.c 2008-10-11 21:54:19.000000000 -0400
2979 +@@ -732,9 +732,7 @@ void handle_interruption(int code, struc
2980 +
2981 + down_read(&current->mm->mmap_sem);
2982 + vma = find_vma(current->mm,regs->iaoq[0]);
2983 +- if (vma && (regs->iaoq[0] >= vma->vm_start)
2984 +- && (vma->vm_flags & VM_EXEC)) {
2985 +-
2986 ++ if (vma && (regs->iaoq[0] >= vma->vm_start)) {
2987 + fault_address = regs->iaoq[0];
2988 + fault_space = regs->iasq[0];
2989 +
2990 +diff -urNp linux-2.6.26.6/arch/parisc/mm/fault.c linux-2.6.26.6/arch/parisc/mm/fault.c
2991 +--- linux-2.6.26.6/arch/parisc/mm/fault.c 2008-10-08 23:24:05.000000000 -0400
2992 ++++ linux-2.6.26.6/arch/parisc/mm/fault.c 2008-10-11 21:54:19.000000000 -0400
2993 +@@ -16,6 +16,7 @@
2994 + #include <linux/sched.h>
2995 + #include <linux/interrupt.h>
2996 + #include <linux/module.h>
2997 ++#include <linux/unistd.h>
2998 +
2999 + #include <asm/uaccess.h>
3000 + #include <asm/traps.h>
3001 +@@ -53,7 +54,7 @@ DEFINE_PER_CPU(struct exception_data, ex
3002 + static unsigned long
3003 + parisc_acctyp(unsigned long code, unsigned int inst)
3004 + {
3005 +- if (code == 6 || code == 16)
3006 ++ if (code == 6 || code == 7 || code == 16)
3007 + return VM_EXEC;
3008 +
3009 + switch (inst & 0xf0000000) {
3010 +@@ -139,6 +140,116 @@ parisc_acctyp(unsigned long code, unsign
3011 + }
3012 + #endif
3013 +
3014 ++#ifdef CONFIG_PAX_PAGEEXEC
3015 ++/*
3016 ++ * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
3017 ++ *
3018 ++ * returns 1 when task should be killed
3019 ++ * 2 when rt_sigreturn trampoline was detected
3020 ++ * 3 when unpatched PLT trampoline was detected
3021 ++ */
3022 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
3023 ++{
3024 ++
3025 ++#ifdef CONFIG_PAX_EMUPLT
3026 ++ int err;
3027 ++
3028 ++ do { /* PaX: unpatched PLT emulation */
3029 ++ unsigned int bl, depwi;
3030 ++
3031 ++ err = get_user(bl, (unsigned int *)instruction_pointer(regs));
3032 ++ err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
3033 ++
3034 ++ if (err)
3035 ++ break;
3036 ++
3037 ++ if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
3038 ++ unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
3039 ++
3040 ++ err = get_user(ldw, (unsigned int *)addr);
3041 ++ err |= get_user(bv, (unsigned int *)(addr+4));
3042 ++ err |= get_user(ldw2, (unsigned int *)(addr+8));
3043 ++
3044 ++ if (err)
3045 ++ break;
3046 ++
3047 ++ if (ldw == 0x0E801096U &&
3048 ++ bv == 0xEAC0C000U &&
3049 ++ ldw2 == 0x0E881095U)
3050 ++ {
3051 ++ unsigned int resolver, map;
3052 ++
3053 ++ err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
3054 ++ err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
3055 ++ if (err)
3056 ++ break;
3057 ++
3058 ++ regs->gr[20] = instruction_pointer(regs)+8;
3059 ++ regs->gr[21] = map;
3060 ++ regs->gr[22] = resolver;
3061 ++ regs->iaoq[0] = resolver | 3UL;
3062 ++ regs->iaoq[1] = regs->iaoq[0] + 4;
3063 ++ return 3;
3064 ++ }
3065 ++ }
3066 ++ } while (0);
3067 ++#endif
3068 ++
3069 ++#ifdef CONFIG_PAX_EMUTRAMP
3070 ++
3071 ++#ifndef CONFIG_PAX_EMUSIGRT
3072 ++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
3073 ++ return 1;
3074 ++#endif
3075 ++
3076 ++ do { /* PaX: rt_sigreturn emulation */
3077 ++ unsigned int ldi1, ldi2, bel, nop;
3078 ++
3079 ++ err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
3080 ++ err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
3081 ++ err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
3082 ++ err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
3083 ++
3084 ++ if (err)
3085 ++ break;
3086 ++
3087 ++ if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
3088 ++ ldi2 == 0x3414015AU &&
3089 ++ bel == 0xE4008200U &&
3090 ++ nop == 0x08000240U)
3091 ++ {
3092 ++ regs->gr[25] = (ldi1 & 2) >> 1;
3093 ++ regs->gr[20] = __NR_rt_sigreturn;
3094 ++ regs->gr[31] = regs->iaoq[1] + 16;
3095 ++ regs->sr[0] = regs->iasq[1];
3096 ++ regs->iaoq[0] = 0x100UL;
3097 ++ regs->iaoq[1] = regs->iaoq[0] + 4;
3098 ++ regs->iasq[0] = regs->sr[2];
3099 ++ regs->iasq[1] = regs->sr[2];
3100 ++ return 2;
3101 ++ }
3102 ++ } while (0);
3103 ++#endif
3104 ++
3105 ++ return 1;
3106 ++}
3107 ++
3108 ++void pax_report_insns(void *pc, void *sp)
3109 ++{
3110 ++ unsigned long i;
3111 ++
3112 ++ printk(KERN_ERR "PAX: bytes at PC: ");
3113 ++ for (i = 0; i < 5; i++) {
3114 ++ unsigned int c;
3115 ++ if (get_user(c, (unsigned int *)pc+i))
3116 ++ printk(KERN_CONT "???????? ");
3117 ++ else
3118 ++ printk(KERN_CONT "%08x ", c);
3119 ++ }
3120 ++ printk("\n");
3121 ++}
3122 ++#endif
3123 ++
3124 + void do_page_fault(struct pt_regs *regs, unsigned long code,
3125 + unsigned long address)
3126 + {
3127 +@@ -165,8 +276,33 @@ good_area:
3128 +
3129 + acc_type = parisc_acctyp(code,regs->iir);
3130 +
3131 +- if ((vma->vm_flags & acc_type) != acc_type)
3132 ++ if ((vma->vm_flags & acc_type) != acc_type) {
3133 ++
3134 ++#ifdef CONFIG_PAX_PAGEEXEC
3135 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
3136 ++ (address & ~3UL) == instruction_pointer(regs))
3137 ++ {
3138 ++ up_read(&mm->mmap_sem);
3139 ++ switch (pax_handle_fetch_fault(regs)) {
3140 ++
3141 ++#ifdef CONFIG_PAX_EMUPLT
3142 ++ case 3:
3143 ++ return;
3144 ++#endif
3145 ++
3146 ++#ifdef CONFIG_PAX_EMUTRAMP
3147 ++ case 2:
3148 ++ return;
3149 ++#endif
3150 ++
3151 ++ }
3152 ++ pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
3153 ++ do_group_exit(SIGKILL);
3154 ++ }
3155 ++#endif
3156 ++
3157 + goto bad_area;
3158 ++ }
3159 +
3160 + /*
3161 + * If for any reason at all we couldn't handle the fault, make
3162 +diff -urNp linux-2.6.26.6/arch/powerpc/kernel/module_32.c linux-2.6.26.6/arch/powerpc/kernel/module_32.c
3163 +--- linux-2.6.26.6/arch/powerpc/kernel/module_32.c 2008-10-08 23:24:05.000000000 -0400
3164 ++++ linux-2.6.26.6/arch/powerpc/kernel/module_32.c 2008-10-11 21:54:19.000000000 -0400
3165 +@@ -175,7 +175,7 @@ int module_frob_arch_sections(Elf32_Ehdr
3166 + me->arch.core_plt_section = i;
3167 + }
3168 + if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
3169 +- printk("Module doesn't contain .plt or .init.plt sections.\n");
3170 ++ printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
3171 + return -ENOEXEC;
3172 + }
3173 +
3174 +@@ -216,11 +216,16 @@ static uint32_t do_plt_call(void *locati
3175 +
3176 + DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
3177 + /* Init, or core PLT? */
3178 +- if (location >= mod->module_core
3179 +- && location < mod->module_core + mod->core_size)
3180 ++ if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
3181 ++ (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
3182 + entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
3183 +- else
3184 ++ else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
3185 ++ (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
3186 + entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
3187 ++ else {
3188 ++ printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
3189 ++ return ~0UL;
3190 ++ }
3191 +
3192 + /* Find this entry, or if that fails, the next avail. entry */
3193 + while (entry->jump[0]) {
3194 +diff -urNp linux-2.6.26.6/arch/powerpc/kernel/signal_32.c linux-2.6.26.6/arch/powerpc/kernel/signal_32.c
3195 +--- linux-2.6.26.6/arch/powerpc/kernel/signal_32.c 2008-10-08 23:24:05.000000000 -0400
3196 ++++ linux-2.6.26.6/arch/powerpc/kernel/signal_32.c 2008-10-11 21:54:19.000000000 -0400
3197 +@@ -743,7 +743,7 @@ int handle_rt_signal32(unsigned long sig
3198 + /* Save user registers on the stack */
3199 + frame = &rt_sf->uc.uc_mcontext;
3200 + addr = frame;
3201 +- if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
3202 ++ if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
3203 + if (save_user_regs(regs, frame, 0))
3204 + goto badframe;
3205 + regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
3206 +diff -urNp linux-2.6.26.6/arch/powerpc/kernel/signal_64.c linux-2.6.26.6/arch/powerpc/kernel/signal_64.c
3207 +--- linux-2.6.26.6/arch/powerpc/kernel/signal_64.c 2008-10-08 23:24:05.000000000 -0400
3208 ++++ linux-2.6.26.6/arch/powerpc/kernel/signal_64.c 2008-10-11 21:54:19.000000000 -0400
3209 +@@ -371,7 +371,7 @@ int handle_rt_signal64(int signr, struct
3210 + current->thread.fpscr.val = 0;
3211 +
3212 + /* Set up to return from userspace. */
3213 +- if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
3214 ++ if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
3215 + regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
3216 + } else {
3217 + err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
3218 +diff -urNp linux-2.6.26.6/arch/powerpc/kernel/vdso.c linux-2.6.26.6/arch/powerpc/kernel/vdso.c
3219 +--- linux-2.6.26.6/arch/powerpc/kernel/vdso.c 2008-10-08 23:24:05.000000000 -0400
3220 ++++ linux-2.6.26.6/arch/powerpc/kernel/vdso.c 2008-10-11 21:54:19.000000000 -0400
3221 +@@ -212,7 +212,7 @@ int arch_setup_additional_pages(struct l
3222 + vdso_base = VDSO32_MBASE;
3223 + #endif
3224 +
3225 +- current->mm->context.vdso_base = 0;
3226 ++ current->mm->context.vdso_base = ~0UL;
3227 +
3228 + /* vDSO has a problem and was disabled, just don't "enable" it for the
3229 + * process
3230 +@@ -229,7 +229,7 @@ int arch_setup_additional_pages(struct l
3231 + */
3232 + down_write(&mm->mmap_sem);
3233 + vdso_base = get_unmapped_area(NULL, vdso_base,
3234 +- vdso_pages << PAGE_SHIFT, 0, 0);
3235 ++ vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
3236 + if (IS_ERR_VALUE(vdso_base)) {
3237 + rc = vdso_base;
3238 + goto fail_mmapsem;
3239 +diff -urNp linux-2.6.26.6/arch/powerpc/mm/fault.c linux-2.6.26.6/arch/powerpc/mm/fault.c
3240 +--- linux-2.6.26.6/arch/powerpc/mm/fault.c 2008-10-08 23:24:05.000000000 -0400
3241 ++++ linux-2.6.26.6/arch/powerpc/mm/fault.c 2008-10-11 21:54:19.000000000 -0400
3242 +@@ -29,6 +29,10 @@
3243 + #include <linux/module.h>
3244 + #include <linux/kprobes.h>
3245 + #include <linux/kdebug.h>
3246 ++#include <linux/slab.h>
3247 ++#include <linux/pagemap.h>
3248 ++#include <linux/compiler.h>
3249 ++#include <linux/unistd.h>
3250 +
3251 + #include <asm/page.h>
3252 + #include <asm/pgtable.h>
3253 +@@ -62,6 +66,363 @@ static inline int notify_page_fault(stru
3254 + }
3255 + #endif
3256 +
3257 ++#ifdef CONFIG_PAX_EMUSIGRT
3258 ++void pax_syscall_close(struct vm_area_struct *vma)
3259 ++{
3260 ++ vma->vm_mm->call_syscall = 0UL;
3261 ++}
3262 ++
3263 ++static int pax_syscall_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
3264 ++{
3265 ++ unsigned int *kaddr;
3266 ++
3267 ++ vmf->page = alloc_page(GFP_HIGHUSER);
3268 ++ if (!vmf->page)
3269 ++ return VM_FAULT_OOM;
3270 ++
3271 ++ kaddr = kmap(vmf->page);
3272 ++ memset(kaddr, 0, PAGE_SIZE);
3273 ++ kaddr[0] = 0x44000002U; /* sc */
3274 ++ __flush_dcache_icache(kaddr);
3275 ++ kunmap(vmf->page);
3276 ++ return VM_FAULT_MAJOR;
3277 ++}
3278 ++
3279 ++static struct vm_operations_struct pax_vm_ops = {
3280 ++ .close = pax_syscall_close,
3281 ++ .fault = pax_syscall_fault
3282 ++};
3283 ++
3284 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
3285 ++{
3286 ++ int ret;
3287 ++
3288 ++ vma->vm_mm = current->mm;
3289 ++ vma->vm_start = addr;
3290 ++ vma->vm_end = addr + PAGE_SIZE;
3291 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
3292 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
3293 ++ vma->vm_ops = &pax_vm_ops;
3294 ++
3295 ++ ret = insert_vm_struct(current->mm, vma);
3296 ++ if (ret)
3297 ++ return ret;
3298 ++
3299 ++ ++current->mm->total_vm;
3300 ++ return 0;
3301 ++}
3302 ++#endif
3303 ++
3304 ++#ifdef CONFIG_PAX_PAGEEXEC
3305 ++/*
3306 ++ * PaX: decide what to do with offenders (regs->nip = fault address)
3307 ++ *
3308 ++ * returns 1 when task should be killed
3309 ++ * 2 when patched GOT trampoline was detected
3310 ++ * 3 when patched PLT trampoline was detected
3311 ++ * 4 when unpatched PLT trampoline was detected
3312 ++ * 5 when sigreturn trampoline was detected
3313 ++ * 6 when rt_sigreturn trampoline was detected
3314 ++ */
3315 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
3316 ++{
3317 ++
3318 ++#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
3319 ++ int err;
3320 ++#endif
3321 ++
3322 ++#ifdef CONFIG_PAX_EMUPLT
3323 ++ do { /* PaX: patched GOT emulation */
3324 ++ unsigned int blrl;
3325 ++
3326 ++ err = get_user(blrl, (unsigned int *)regs->nip);
3327 ++
3328 ++ if (!err && blrl == 0x4E800021U) {
3329 ++ unsigned long temp = regs->nip;
3330 ++
3331 ++ regs->nip = regs->link & 0xFFFFFFFCUL;
3332 ++ regs->link = temp + 4UL;
3333 ++ return 2;
3334 ++ }
3335 ++ } while (0);
3336 ++
3337 ++ do { /* PaX: patched PLT emulation #1 */
3338 ++ unsigned int b;
3339 ++
3340 ++ err = get_user(b, (unsigned int *)regs->nip);
3341 ++
3342 ++ if (!err && (b & 0xFC000003U) == 0x48000000U) {
3343 ++ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
3344 ++ return 3;
3345 ++ }
3346 ++ } while (0);
3347 ++
3348 ++ do { /* PaX: unpatched PLT emulation #1 */
3349 ++ unsigned int li, b;
3350 ++
3351 ++ err = get_user(li, (unsigned int *)regs->nip);
3352 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
3353 ++
3354 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
3355 ++ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
3356 ++ unsigned long addr = b | 0xFC000000UL;
3357 ++
3358 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
3359 ++ err = get_user(rlwinm, (unsigned int *)addr);
3360 ++ err |= get_user(add, (unsigned int *)(addr+4));
3361 ++ err |= get_user(li2, (unsigned int *)(addr+8));
3362 ++ err |= get_user(addis2, (unsigned int *)(addr+12));
3363 ++ err |= get_user(mtctr, (unsigned int *)(addr+16));
3364 ++ err |= get_user(li3, (unsigned int *)(addr+20));
3365 ++ err |= get_user(addis3, (unsigned int *)(addr+24));
3366 ++ err |= get_user(bctr, (unsigned int *)(addr+28));
3367 ++
3368 ++ if (err)
3369 ++ break;
3370 ++
3371 ++ if (rlwinm == 0x556C083CU &&
3372 ++ add == 0x7D6C5A14U &&
3373 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
3374 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
3375 ++ mtctr == 0x7D8903A6U &&
3376 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
3377 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
3378 ++ bctr == 0x4E800420U)
3379 ++ {
3380 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3381 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3382 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
3383 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3384 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
3385 ++ regs->nip = regs->ctr;
3386 ++ return 4;
3387 ++ }
3388 ++ }
3389 ++ } while (0);
3390 ++
3391 ++#if 0
3392 ++ do { /* PaX: unpatched PLT emulation #2 */
3393 ++ unsigned int lis, lwzu, b, bctr;
3394 ++
3395 ++ err = get_user(lis, (unsigned int *)regs->nip);
3396 ++ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
3397 ++ err |= get_user(b, (unsigned int *)(regs->nip+8));
3398 ++ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
3399 ++
3400 ++ if (err)
3401 ++ break;
3402 ++
3403 ++ if ((lis & 0xFFFF0000U) == 0x39600000U &&
3404 ++ (lwzu & 0xU) == 0xU &&
3405 ++ (b & 0xFC000003U) == 0x48000000U &&
3406 ++ bctr == 0x4E800420U)
3407 ++ {
3408 ++ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
3409 ++ unsigned long addr = b | 0xFC000000UL;
3410 ++
3411 ++ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
3412 ++ err = get_user(addis, (unsigned int *)addr);
3413 ++ err |= get_user(addi, (unsigned int *)(addr+4));
3414 ++ err |= get_user(rlwinm, (unsigned int *)(addr+8));
3415 ++ err |= get_user(add, (unsigned int *)(addr+12));
3416 ++ err |= get_user(li2, (unsigned int *)(addr+16));
3417 ++ err |= get_user(addis2, (unsigned int *)(addr+20));
3418 ++ err |= get_user(mtctr, (unsigned int *)(addr+24));
3419 ++ err |= get_user(li3, (unsigned int *)(addr+28));
3420 ++ err |= get_user(addis3, (unsigned int *)(addr+32));
3421 ++ err |= get_user(bctr, (unsigned int *)(addr+36));
3422 ++
3423 ++ if (err)
3424 ++ break;
3425 ++
3426 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
3427 ++ (addi & 0xFFFF0000U) == 0x396B0000U &&
3428 ++ rlwinm == 0x556C083CU &&
3429 ++ add == 0x7D6C5A14U &&
3430 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
3431 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
3432 ++ mtctr == 0x7D8903A6U &&
3433 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
3434 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
3435 ++ bctr == 0x4E800420U)
3436 ++ {
3437 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3438 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3439 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
3440 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3441 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
3442 ++ regs->nip = regs->ctr;
3443 ++ return 4;
3444 ++ }
3445 ++ }
3446 ++ } while (0);
3447 ++#endif
3448 ++
3449 ++ do { /* PaX: unpatched PLT emulation #3 */
3450 ++ unsigned int li, b;
3451 ++
3452 ++ err = get_user(li, (unsigned int *)regs->nip);
3453 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
3454 ++
3455 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
3456 ++ unsigned int addis, lwz, mtctr, bctr;
3457 ++ unsigned long addr = b | 0xFC000000UL;
3458 ++
3459 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
3460 ++ err = get_user(addis, (unsigned int *)addr);
3461 ++ err |= get_user(lwz, (unsigned int *)(addr+4));
3462 ++ err |= get_user(mtctr, (unsigned int *)(addr+8));
3463 ++ err |= get_user(bctr, (unsigned int *)(addr+12));
3464 ++
3465 ++ if (err)
3466 ++ break;
3467 ++
3468 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
3469 ++ (lwz & 0xFFFF0000U) == 0x816B0000U &&
3470 ++ mtctr == 0x7D6903A6U &&
3471 ++ bctr == 0x4E800420U)
3472 ++ {
3473 ++ unsigned int r11;
3474 ++
3475 ++ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3476 ++ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3477 ++
3478 ++ err = get_user(r11, (unsigned int *)addr);
3479 ++ if (err)
3480 ++ break;
3481 ++
3482 ++ regs->gpr[PT_R11] = r11;
3483 ++ regs->ctr = r11;
3484 ++ regs->nip = r11;
3485 ++ return 4;
3486 ++ }
3487 ++ }
3488 ++ } while (0);
3489 ++#endif
3490 ++
3491 ++#ifdef CONFIG_PAX_EMUSIGRT
3492 ++ do { /* PaX: sigreturn emulation */
3493 ++ unsigned int li, sc;
3494 ++
3495 ++ err = get_user(li, (unsigned int *)regs->nip);
3496 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
3497 ++
3498 ++ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
3499 ++ struct vm_area_struct *vma;
3500 ++ unsigned long call_syscall;
3501 ++
3502 ++ down_read(&current->mm->mmap_sem);
3503 ++ call_syscall = current->mm->call_syscall;
3504 ++ up_read(&current->mm->mmap_sem);
3505 ++ if (likely(call_syscall))
3506 ++ goto emulate;
3507 ++
3508 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
3509 ++
3510 ++ down_write(&current->mm->mmap_sem);
3511 ++ if (current->mm->call_syscall) {
3512 ++ call_syscall = current->mm->call_syscall;
3513 ++ up_write(&current->mm->mmap_sem);
3514 ++ if (vma)
3515 ++ kmem_cache_free(vm_area_cachep, vma);
3516 ++ goto emulate;
3517 ++ }
3518 ++
3519 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
3520 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
3521 ++ up_write(&current->mm->mmap_sem);
3522 ++ if (vma)
3523 ++ kmem_cache_free(vm_area_cachep, vma);
3524 ++ return 1;
3525 ++ }
3526 ++
3527 ++ if (pax_insert_vma(vma, call_syscall)) {
3528 ++ up_write(&current->mm->mmap_sem);
3529 ++ kmem_cache_free(vm_area_cachep, vma);
3530 ++ return 1;
3531 ++ }
3532 ++
3533 ++ current->mm->call_syscall = call_syscall;
3534 ++ up_write(&current->mm->mmap_sem);
3535 ++
3536 ++emulate:
3537 ++ regs->gpr[PT_R0] = __NR_sigreturn;
3538 ++ regs->nip = call_syscall;
3539 ++ return 5;
3540 ++ }
3541 ++ } while (0);
3542 ++
3543 ++ do { /* PaX: rt_sigreturn emulation */
3544 ++ unsigned int li, sc;
3545 ++
3546 ++ err = get_user(li, (unsigned int *)regs->nip);
3547 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
3548 ++
3549 ++ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
3550 ++ struct vm_area_struct *vma;
3551 ++ unsigned int call_syscall;
3552 ++
3553 ++ down_read(&current->mm->mmap_sem);
3554 ++ call_syscall = current->mm->call_syscall;
3555 ++ up_read(&current->mm->mmap_sem);
3556 ++ if (likely(call_syscall))
3557 ++ goto rt_emulate;
3558 ++
3559 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
3560 ++
3561 ++ down_write(&current->mm->mmap_sem);
3562 ++ if (current->mm->call_syscall) {
3563 ++ call_syscall = current->mm->call_syscall;
3564 ++ up_write(&current->mm->mmap_sem);
3565 ++ if (vma)
3566 ++ kmem_cache_free(vm_area_cachep, vma);
3567 ++ goto rt_emulate;
3568 ++ }
3569 ++
3570 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
3571 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
3572 ++ up_write(&current->mm->mmap_sem);
3573 ++ if (vma)
3574 ++ kmem_cache_free(vm_area_cachep, vma);
3575 ++ return 1;
3576 ++ }
3577 ++
3578 ++ if (pax_insert_vma(vma, call_syscall)) {
3579 ++ up_write(&current->mm->mmap_sem);
3580 ++ kmem_cache_free(vm_area_cachep, vma);
3581 ++ return 1;
3582 ++ }
3583 ++
3584 ++ current->mm->call_syscall = call_syscall;
3585 ++ up_write(&current->mm->mmap_sem);
3586 ++
3587 ++rt_emulate:
3588 ++ regs->gpr[PT_R0] = __NR_rt_sigreturn;
3589 ++ regs->nip = call_syscall;
3590 ++ return 6;
3591 ++ }
3592 ++ } while (0);
3593 ++#endif
3594 ++
3595 ++ return 1;
3596 ++}
3597 ++
3598 ++void pax_report_insns(void *pc, void *sp)
3599 ++{
3600 ++ unsigned long i;
3601 ++
3602 ++ printk(KERN_ERR "PAX: bytes at PC: ");
3603 ++ for (i = 0; i < 5; i++) {
3604 ++ unsigned int c;
3605 ++ if (get_user(c, (unsigned int *)pc+i))
3606 ++ printk(KERN_CONT "???????? ");
3607 ++ else
3608 ++ printk(KERN_CONT "%08x ", c);
3609 ++ }
3610 ++ printk("\n");
3611 ++}
3612 ++#endif
3613 ++
3614 + /*
3615 + * Check whether the instruction at regs->nip is a store using
3616 + * an update addressing form which will update r1.
3617 +@@ -157,7 +518,7 @@ int __kprobes do_page_fault(struct pt_re
3618 + * indicate errors in DSISR but can validly be set in SRR1.
3619 + */
3620 + if (trap == 0x400)
3621 +- error_code &= 0x48200000;
3622 ++ error_code &= 0x58200000;
3623 + else
3624 + is_write = error_code & DSISR_ISSTORE;
3625 + #else
3626 +@@ -355,6 +716,37 @@ bad_area:
3627 + bad_area_nosemaphore:
3628 + /* User mode accesses cause a SIGSEGV */
3629 + if (user_mode(regs)) {
3630 ++
3631 ++#ifdef CONFIG_PAX_PAGEEXEC
3632 ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
3633 ++#ifdef CONFIG_PPC64
3634 ++ if (is_exec && (error_code & DSISR_PROTFAULT)) {
3635 ++#else
3636 ++ if (is_exec && regs->nip == address) {
3637 ++#endif
3638 ++ switch (pax_handle_fetch_fault(regs)) {
3639 ++
3640 ++#ifdef CONFIG_PAX_EMUPLT
3641 ++ case 2:
3642 ++ case 3:
3643 ++ case 4:
3644 ++ return 0;
3645 ++#endif
3646 ++
3647 ++#ifdef CONFIG_PAX_EMUSIGRT
3648 ++ case 5:
3649 ++ case 6:
3650 ++ return 0;
3651 ++#endif
3652 ++
3653 ++ }
3654 ++
3655 ++ pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[PT_R1]);
3656 ++ do_group_exit(SIGKILL);
3657 ++ }
3658 ++ }
3659 ++#endif
3660 ++
3661 + _exception(SIGSEGV, regs, code, address);
3662 + return 0;
3663 + }
3664 +diff -urNp linux-2.6.26.6/arch/powerpc/mm/mmap.c linux-2.6.26.6/arch/powerpc/mm/mmap.c
3665 +--- linux-2.6.26.6/arch/powerpc/mm/mmap.c 2008-10-08 23:24:05.000000000 -0400
3666 ++++ linux-2.6.26.6/arch/powerpc/mm/mmap.c 2008-10-11 21:54:19.000000000 -0400
3667 +@@ -75,10 +75,22 @@ void arch_pick_mmap_layout(struct mm_str
3668 + */
3669 + if (mmap_is_legacy()) {
3670 + mm->mmap_base = TASK_UNMAPPED_BASE;
3671 ++
3672 ++#ifdef CONFIG_PAX_RANDMMAP
3673 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
3674 ++ mm->mmap_base += mm->delta_mmap;
3675 ++#endif
3676 ++
3677 + mm->get_unmapped_area = arch_get_unmapped_area;
3678 + mm->unmap_area = arch_unmap_area;
3679 + } else {
3680 + mm->mmap_base = mmap_base();
3681 ++
3682 ++#ifdef CONFIG_PAX_RANDMMAP
3683 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
3684 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
3685 ++#endif
3686 ++
3687 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
3688 + mm->unmap_area = arch_unmap_area_topdown;
3689 + }
3690 +diff -urNp linux-2.6.26.6/arch/ppc/mm/fault.c linux-2.6.26.6/arch/ppc/mm/fault.c
3691 +--- linux-2.6.26.6/arch/ppc/mm/fault.c 2008-10-08 23:24:05.000000000 -0400
3692 ++++ linux-2.6.26.6/arch/ppc/mm/fault.c 2008-10-11 21:54:19.000000000 -0400
3693 +@@ -25,6 +25,10 @@
3694 + #include <linux/interrupt.h>
3695 + #include <linux/highmem.h>
3696 + #include <linux/module.h>
3697 ++#include <linux/slab.h>
3698 ++#include <linux/pagemap.h>
3699 ++#include <linux/compiler.h>
3700 ++#include <linux/unistd.h>
3701 +
3702 + #include <asm/page.h>
3703 + #include <asm/pgtable.h>
3704 +@@ -48,6 +52,363 @@ unsigned long pte_misses; /* updated by
3705 + unsigned long pte_errors; /* updated by do_page_fault() */
3706 + unsigned int probingmem;
3707 +
3708 ++#ifdef CONFIG_PAX_EMUSIGRT
3709 ++void pax_syscall_close(struct vm_area_struct *vma)
3710 ++{
3711 ++ vma->vm_mm->call_syscall = 0UL;
3712 ++}
3713 ++
3714 ++static int pax_syscall_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
3715 ++{
3716 ++ unsigned int *kaddr;
3717 ++
3718 ++ vmf->page = alloc_page(GFP_HIGHUSER);
3719 ++ if (!vmf->page)
3720 ++ return VM_FAULT_OOM;
3721 ++
3722 ++ kaddr = kmap(vmf->page);
3723 ++ memset(kaddr, 0, PAGE_SIZE);
3724 ++ kaddr[0] = 0x44000002U; /* sc */
3725 ++ __flush_dcache_icache(kaddr);
3726 ++ kunmap(vmf->page);
3727 ++ return VM_FAULT_MAJOR;
3728 ++}
3729 ++
3730 ++static struct vm_operations_struct pax_vm_ops = {
3731 ++ .close = pax_syscall_close,
3732 ++ .fault = pax_syscall_fault
3733 ++};
3734 ++
3735 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
3736 ++{
3737 ++ int ret;
3738 ++
3739 ++ vma->vm_mm = current->mm;
3740 ++ vma->vm_start = addr;
3741 ++ vma->vm_end = addr + PAGE_SIZE;
3742 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
3743 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
3744 ++ vma->vm_ops = &pax_vm_ops;
3745 ++
3746 ++ ret = insert_vm_struct(current->mm, vma);
3747 ++ if (ret)
3748 ++ return ret;
3749 ++
3750 ++ ++current->mm->total_vm;
3751 ++ return 0;
3752 ++}
3753 ++#endif
3754 ++
3755 ++#ifdef CONFIG_PAX_PAGEEXEC
3756 ++/*
3757 ++ * PaX: decide what to do with offenders (regs->nip = fault address)
3758 ++ *
3759 ++ * returns 1 when task should be killed
3760 ++ * 2 when patched GOT trampoline was detected
3761 ++ * 3 when patched PLT trampoline was detected
3762 ++ * 4 when unpatched PLT trampoline was detected
3763 ++ * 5 when sigreturn trampoline was detected
3764 ++ * 6 when rt_sigreturn trampoline was detected
3765 ++ */
3766 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
3767 ++{
3768 ++
3769 ++#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
3770 ++ int err;
3771 ++#endif
3772 ++
3773 ++#ifdef CONFIG_PAX_EMUPLT
3774 ++ do { /* PaX: patched GOT emulation */
3775 ++ unsigned int blrl;
3776 ++
3777 ++ err = get_user(blrl, (unsigned int *)regs->nip);
3778 ++
3779 ++ if (!err && blrl == 0x4E800021U) {
3780 ++ unsigned long temp = regs->nip;
3781 ++
3782 ++ regs->nip = regs->link & 0xFFFFFFFCUL;
3783 ++ regs->link = temp + 4UL;
3784 ++ return 2;
3785 ++ }
3786 ++ } while (0);
3787 ++
3788 ++ do { /* PaX: patched PLT emulation #1 */
3789 ++ unsigned int b;
3790 ++
3791 ++ err = get_user(b, (unsigned int *)regs->nip);
3792 ++
3793 ++ if (!err && (b & 0xFC000003U) == 0x48000000U) {
3794 ++ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
3795 ++ return 3;
3796 ++ }
3797 ++ } while (0);
3798 ++
3799 ++ do { /* PaX: unpatched PLT emulation #1 */
3800 ++ unsigned int li, b;
3801 ++
3802 ++ err = get_user(li, (unsigned int *)regs->nip);
3803 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
3804 ++
3805 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
3806 ++ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
3807 ++ unsigned long addr = b | 0xFC000000UL;
3808 ++
3809 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
3810 ++ err = get_user(rlwinm, (unsigned int *)addr);
3811 ++ err |= get_user(add, (unsigned int *)(addr+4));
3812 ++ err |= get_user(li2, (unsigned int *)(addr+8));
3813 ++ err |= get_user(addis2, (unsigned int *)(addr+12));
3814 ++ err |= get_user(mtctr, (unsigned int *)(addr+16));
3815 ++ err |= get_user(li3, (unsigned int *)(addr+20));
3816 ++ err |= get_user(addis3, (unsigned int *)(addr+24));
3817 ++ err |= get_user(bctr, (unsigned int *)(addr+28));
3818 ++
3819 ++ if (err)
3820 ++ break;
3821 ++
3822 ++ if (rlwinm == 0x556C083CU &&
3823 ++ add == 0x7D6C5A14U &&
3824 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
3825 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
3826 ++ mtctr == 0x7D8903A6U &&
3827 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
3828 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
3829 ++ bctr == 0x4E800420U)
3830 ++ {
3831 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3832 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3833 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
3834 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3835 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
3836 ++ regs->nip = regs->ctr;
3837 ++ return 4;
3838 ++ }
3839 ++ }
3840 ++ } while (0);
3841 ++
3842 ++#if 0
3843 ++ do { /* PaX: unpatched PLT emulation #2 */
3844 ++ unsigned int lis, lwzu, b, bctr;
3845 ++
3846 ++ err = get_user(lis, (unsigned int *)regs->nip);
3847 ++ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
3848 ++ err |= get_user(b, (unsigned int *)(regs->nip+8));
3849 ++ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
3850 ++
3851 ++ if (err)
3852 ++ break;
3853 ++
3854 ++ if ((lis & 0xFFFF0000U) == 0x39600000U &&
3855 ++ (lwzu & 0xU) == 0xU &&
3856 ++ (b & 0xFC000003U) == 0x48000000U &&
3857 ++ bctr == 0x4E800420U)
3858 ++ {
3859 ++ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
3860 ++ unsigned long addr = b | 0xFC000000UL;
3861 ++
3862 ++ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
3863 ++ err = get_user(addis, (unsigned int *)addr);
3864 ++ err |= get_user(addi, (unsigned int *)(addr+4));
3865 ++ err |= get_user(rlwinm, (unsigned int *)(addr+8));
3866 ++ err |= get_user(add, (unsigned int *)(addr+12));
3867 ++ err |= get_user(li2, (unsigned int *)(addr+16));
3868 ++ err |= get_user(addis2, (unsigned int *)(addr+20));
3869 ++ err |= get_user(mtctr, (unsigned int *)(addr+24));
3870 ++ err |= get_user(li3, (unsigned int *)(addr+28));
3871 ++ err |= get_user(addis3, (unsigned int *)(addr+32));
3872 ++ err |= get_user(bctr, (unsigned int *)(addr+36));
3873 ++
3874 ++ if (err)
3875 ++ break;
3876 ++
3877 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
3878 ++ (addi & 0xFFFF0000U) == 0x396B0000U &&
3879 ++ rlwinm == 0x556C083CU &&
3880 ++ add == 0x7D6C5A14U &&
3881 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
3882 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
3883 ++ mtctr == 0x7D8903A6U &&
3884 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
3885 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
3886 ++ bctr == 0x4E800420U)
3887 ++ {
3888 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3889 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3890 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
3891 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3892 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
3893 ++ regs->nip = regs->ctr;
3894 ++ return 4;
3895 ++ }
3896 ++ }
3897 ++ } while (0);
3898 ++#endif
3899 ++
3900 ++ do { /* PaX: unpatched PLT emulation #3 */
3901 ++ unsigned int li, b;
3902 ++
3903 ++ err = get_user(li, (unsigned int *)regs->nip);
3904 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
3905 ++
3906 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
3907 ++ unsigned int addis, lwz, mtctr, bctr;
3908 ++ unsigned long addr = b | 0xFC000000UL;
3909 ++
3910 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
3911 ++ err = get_user(addis, (unsigned int *)addr);
3912 ++ err |= get_user(lwz, (unsigned int *)(addr+4));
3913 ++ err |= get_user(mtctr, (unsigned int *)(addr+8));
3914 ++ err |= get_user(bctr, (unsigned int *)(addr+12));
3915 ++
3916 ++ if (err)
3917 ++ break;
3918 ++
3919 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
3920 ++ (lwz & 0xFFFF0000U) == 0x816B0000U &&
3921 ++ mtctr == 0x7D6903A6U &&
3922 ++ bctr == 0x4E800420U)
3923 ++ {
3924 ++ unsigned int r11;
3925 ++
3926 ++ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3927 ++ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3928 ++
3929 ++ err = get_user(r11, (unsigned int *)addr);
3930 ++ if (err)
3931 ++ break;
3932 ++
3933 ++ regs->gpr[PT_R11] = r11;
3934 ++ regs->ctr = r11;
3935 ++ regs->nip = r11;
3936 ++ return 4;
3937 ++ }
3938 ++ }
3939 ++ } while (0);
3940 ++#endif
3941 ++
3942 ++#ifdef CONFIG_PAX_EMUSIGRT
3943 ++ do { /* PaX: sigreturn emulation */
3944 ++ unsigned int li, sc;
3945 ++
3946 ++ err = get_user(li, (unsigned int *)regs->nip);
3947 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
3948 ++
3949 ++ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
3950 ++ struct vm_area_struct *vma;
3951 ++ unsigned long call_syscall;
3952 ++
3953 ++ down_read(&current->mm->mmap_sem);
3954 ++ call_syscall = current->mm->call_syscall;
3955 ++ up_read(&current->mm->mmap_sem);
3956 ++ if (likely(call_syscall))
3957 ++ goto emulate;
3958 ++
3959 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
3960 ++
3961 ++ down_write(&current->mm->mmap_sem);
3962 ++ if (current->mm->call_syscall) {
3963 ++ call_syscall = current->mm->call_syscall;
3964 ++ up_write(&current->mm->mmap_sem);
3965 ++ if (vma)
3966 ++ kmem_cache_free(vm_area_cachep, vma);
3967 ++ goto emulate;
3968 ++ }
3969 ++
3970 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
3971 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
3972 ++ up_write(&current->mm->mmap_sem);
3973 ++ if (vma)
3974 ++ kmem_cache_free(vm_area_cachep, vma);
3975 ++ return 1;
3976 ++ }
3977 ++
3978 ++ if (pax_insert_vma(vma, call_syscall)) {
3979 ++ up_write(&current->mm->mmap_sem);
3980 ++ kmem_cache_free(vm_area_cachep, vma);
3981 ++ return 1;
3982 ++ }
3983 ++
3984 ++ current->mm->call_syscall = call_syscall;
3985 ++ up_write(&current->mm->mmap_sem);
3986 ++
3987 ++emulate:
3988 ++ regs->gpr[PT_R0] = __NR_sigreturn;
3989 ++ regs->nip = call_syscall;
3990 ++ return 5;
3991 ++ }
3992 ++ } while (0);
3993 ++
3994 ++ do { /* PaX: rt_sigreturn emulation */
3995 ++ unsigned int li, sc;
3996 ++
3997 ++ err = get_user(li, (unsigned int *)regs->nip);
3998 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
3999 ++
4000 ++ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
4001 ++ struct vm_area_struct *vma;
4002 ++ unsigned int call_syscall;
4003 ++
4004 ++ down_read(&current->mm->mmap_sem);
4005 ++ call_syscall = current->mm->call_syscall;
4006 ++ up_read(&current->mm->mmap_sem);
4007 ++ if (likely(call_syscall))
4008 ++ goto rt_emulate;
4009 ++
4010 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
4011 ++
4012 ++ down_write(&current->mm->mmap_sem);
4013 ++ if (current->mm->call_syscall) {
4014 ++ call_syscall = current->mm->call_syscall;
4015 ++ up_write(&current->mm->mmap_sem);
4016 ++ if (vma)
4017 ++ kmem_cache_free(vm_area_cachep, vma);
4018 ++ goto rt_emulate;
4019 ++ }
4020 ++
4021 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
4022 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
4023 ++ up_write(&current->mm->mmap_sem);
4024 ++ if (vma)
4025 ++ kmem_cache_free(vm_area_cachep, vma);
4026 ++ return 1;
4027 ++ }
4028 ++
4029 ++ if (pax_insert_vma(vma, call_syscall)) {
4030 ++ up_write(&current->mm->mmap_sem);
4031 ++ kmem_cache_free(vm_area_cachep, vma);
4032 ++ return 1;
4033 ++ }
4034 ++
4035 ++ current->mm->call_syscall = call_syscall;
4036 ++ up_write(&current->mm->mmap_sem);
4037 ++
4038 ++rt_emulate:
4039 ++ regs->gpr[PT_R0] = __NR_rt_sigreturn;
4040 ++ regs->nip = call_syscall;
4041 ++ return 6;
4042 ++ }
4043 ++ } while (0);
4044 ++#endif
4045 ++
4046 ++ return 1;
4047 ++}
4048 ++
4049 ++void pax_report_insns(void *pc, void *sp)
4050 ++{
4051 ++ unsigned long i;
4052 ++
4053 ++ printk(KERN_ERR "PAX: bytes at PC: ");
4054 ++ for (i = 0; i < 5; i++) {
4055 ++ unsigned int c;
4056 ++ if (get_user(c, (unsigned int *)pc+i))
4057 ++ printk(KERN_CONT "???????? ");
4058 ++ else
4059 ++ printk(KERN_CONT "%08x ", c);
4060 ++ }
4061 ++ printk("\n");
4062 ++}
4063 ++#endif
4064 ++
4065 + /*
4066 + * Check whether the instruction at regs->nip is a store using
4067 + * an update addressing form which will update r1.
4068 +@@ -109,7 +470,7 @@ int do_page_fault(struct pt_regs *regs,
4069 + * indicate errors in DSISR but can validly be set in SRR1.
4070 + */
4071 + if (TRAP(regs) == 0x400)
4072 +- error_code &= 0x48200000;
4073 ++ error_code &= 0x58200000;
4074 + else
4075 + is_write = error_code & 0x02000000;
4076 + #endif /* CONFIG_4xx || CONFIG_BOOKE */
4077 +@@ -204,15 +565,14 @@ good_area:
4078 + pte_t *ptep;
4079 + pmd_t *pmdp;
4080 +
4081 +-#if 0
4082 ++#if 1
4083 + /* It would be nice to actually enforce the VM execute
4084 + permission on CPUs which can do so, but far too
4085 + much stuff in userspace doesn't get the permissions
4086 + right, so we let any page be executed for now. */
4087 + if (! (vma->vm_flags & VM_EXEC))
4088 + goto bad_area;
4089 +-#endif
4090 +-
4091 ++#else
4092 + /* Since 4xx/Book-E supports per-page execute permission,
4093 + * we lazily flush dcache to icache. */
4094 + ptep = NULL;
4095 +@@ -235,6 +595,7 @@ good_area:
4096 + pte_unmap_unlock(ptep, ptl);
4097 + }
4098 + #endif
4099 ++#endif
4100 + /* a read */
4101 + } else {
4102 + /* protection fault */
4103 +@@ -278,6 +639,33 @@ bad_area:
4104 +
4105 + /* User mode accesses cause a SIGSEGV */
4106 + if (user_mode(regs)) {
4107 ++
4108 ++#ifdef CONFIG_PAX_PAGEEXEC
4109 ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
4110 ++ if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
4111 ++ switch (pax_handle_fetch_fault(regs)) {
4112 ++
4113 ++#ifdef CONFIG_PAX_EMUPLT
4114 ++ case 2:
4115 ++ case 3:
4116 ++ case 4:
4117 ++ return 0;
4118 ++#endif
4119 ++
4120 ++#ifdef CONFIG_PAX_EMUSIGRT
4121 ++ case 5:
4122 ++ case 6:
4123 ++ return 0;
4124 ++#endif
4125 ++
4126 ++ }
4127 ++
4128 ++ pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[1]);
4129 ++ do_group_exit(SIGKILL);
4130 ++ }
4131 ++ }
4132 ++#endif
4133 ++
4134 + _exception(SIGSEGV, regs, code, address);
4135 + return 0;
4136 + }
4137 +diff -urNp linux-2.6.26.6/arch/s390/kernel/module.c linux-2.6.26.6/arch/s390/kernel/module.c
4138 +--- linux-2.6.26.6/arch/s390/kernel/module.c 2008-10-08 23:24:05.000000000 -0400
4139 ++++ linux-2.6.26.6/arch/s390/kernel/module.c 2008-10-11 21:54:19.000000000 -0400
4140 +@@ -166,11 +166,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
4141 +
4142 + /* Increase core size by size of got & plt and set start
4143 + offsets for got and plt. */
4144 +- me->core_size = ALIGN(me->core_size, 4);
4145 +- me->arch.got_offset = me->core_size;
4146 +- me->core_size += me->arch.got_size;
4147 +- me->arch.plt_offset = me->core_size;
4148 +- me->core_size += me->arch.plt_size;
4149 ++ me->core_size_rw = ALIGN(me->core_size_rw, 4);
4150 ++ me->arch.got_offset = me->core_size_rw;
4151 ++ me->core_size_rw += me->arch.got_size;
4152 ++ me->arch.plt_offset = me->core_size_rx;
4153 ++ me->core_size_rx += me->arch.plt_size;
4154 + return 0;
4155 + }
4156 +
4157 +@@ -256,7 +256,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
4158 + if (info->got_initialized == 0) {
4159 + Elf_Addr *gotent;
4160 +
4161 +- gotent = me->module_core + me->arch.got_offset +
4162 ++ gotent = me->module_core_rw + me->arch.got_offset +
4163 + info->got_offset;
4164 + *gotent = val;
4165 + info->got_initialized = 1;
4166 +@@ -280,7 +280,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
4167 + else if (r_type == R_390_GOTENT ||
4168 + r_type == R_390_GOTPLTENT)
4169 + *(unsigned int *) loc =
4170 +- (val + (Elf_Addr) me->module_core - loc) >> 1;
4171 ++ (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
4172 + else if (r_type == R_390_GOT64 ||
4173 + r_type == R_390_GOTPLT64)
4174 + *(unsigned long *) loc = val;
4175 +@@ -294,7 +294,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
4176 + case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
4177 + if (info->plt_initialized == 0) {
4178 + unsigned int *ip;
4179 +- ip = me->module_core + me->arch.plt_offset +
4180 ++ ip = me->module_core_rx + me->arch.plt_offset +
4181 + info->plt_offset;
4182 + #ifndef CONFIG_64BIT
4183 + ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
4184 +@@ -316,7 +316,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
4185 + val = me->arch.plt_offset - me->arch.got_offset +
4186 + info->plt_offset + rela->r_addend;
4187 + else
4188 +- val = (Elf_Addr) me->module_core +
4189 ++ val = (Elf_Addr) me->module_core_rx +
4190 + me->arch.plt_offset + info->plt_offset +
4191 + rela->r_addend - loc;
4192 + if (r_type == R_390_PLT16DBL)
4193 +@@ -336,7 +336,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
4194 + case R_390_GOTOFF32: /* 32 bit offset to GOT. */
4195 + case R_390_GOTOFF64: /* 64 bit offset to GOT. */
4196 + val = val + rela->r_addend -
4197 +- ((Elf_Addr) me->module_core + me->arch.got_offset);
4198 ++ ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
4199 + if (r_type == R_390_GOTOFF16)
4200 + *(unsigned short *) loc = val;
4201 + else if (r_type == R_390_GOTOFF32)
4202 +@@ -346,7 +346,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
4203 + break;
4204 + case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
4205 + case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
4206 +- val = (Elf_Addr) me->module_core + me->arch.got_offset +
4207 ++ val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
4208 + rela->r_addend - loc;
4209 + if (r_type == R_390_GOTPC)
4210 + *(unsigned int *) loc = val;
4211 +diff -urNp linux-2.6.26.6/arch/sparc/kernel/sys_sparc.c linux-2.6.26.6/arch/sparc/kernel/sys_sparc.c
4212 +--- linux-2.6.26.6/arch/sparc/kernel/sys_sparc.c 2008-10-08 23:24:05.000000000 -0400
4213 ++++ linux-2.6.26.6/arch/sparc/kernel/sys_sparc.c 2008-10-11 21:54:19.000000000 -0400
4214 +@@ -56,7 +56,7 @@ unsigned long arch_get_unmapped_area(str
4215 + if (ARCH_SUN4C_SUN4 && len > 0x20000000)
4216 + return -ENOMEM;
4217 + if (!addr)
4218 +- addr = TASK_UNMAPPED_BASE;
4219 ++ addr = current->mm->mmap_base;
4220 +
4221 + if (flags & MAP_SHARED)
4222 + addr = COLOUR_ALIGN(addr);
4223 +diff -urNp linux-2.6.26.6/arch/sparc/Makefile linux-2.6.26.6/arch/sparc/Makefile
4224 +--- linux-2.6.26.6/arch/sparc/Makefile 2008-10-08 23:24:05.000000000 -0400
4225 ++++ linux-2.6.26.6/arch/sparc/Makefile 2008-10-11 21:54:19.000000000 -0400
4226 +@@ -36,7 +36,7 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc
4227 + # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
4228 + INIT_Y := $(patsubst %/, %/built-in.o, $(init-y))
4229 + CORE_Y := $(core-y)
4230 +-CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
4231 ++CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
4232 + CORE_Y := $(patsubst %/, %/built-in.o, $(CORE_Y))
4233 + DRIVERS_Y := $(patsubst %/, %/built-in.o, $(drivers-y))
4234 + NET_Y := $(patsubst %/, %/built-in.o, $(net-y))
4235 +diff -urNp linux-2.6.26.6/arch/sparc/mm/fault.c linux-2.6.26.6/arch/sparc/mm/fault.c
4236 +--- linux-2.6.26.6/arch/sparc/mm/fault.c 2008-10-08 23:24:05.000000000 -0400
4237 ++++ linux-2.6.26.6/arch/sparc/mm/fault.c 2008-10-11 21:54:19.000000000 -0400
4238 +@@ -21,6 +21,9 @@
4239 + #include <linux/interrupt.h>
4240 + #include <linux/module.h>
4241 + #include <linux/kdebug.h>
4242 ++#include <linux/slab.h>
4243 ++#include <linux/pagemap.h>
4244 ++#include <linux/compiler.h>
4245 +
4246 + #include <asm/system.h>
4247 + #include <asm/page.h>
4248 +@@ -167,6 +170,249 @@ static unsigned long compute_si_addr(str
4249 + return safe_compute_effective_address(regs, insn);
4250 + }
4251 +
4252 ++#ifdef CONFIG_PAX_PAGEEXEC
4253 ++void pax_emuplt_close(struct vm_area_struct *vma)
4254 ++{
4255 ++ vma->vm_mm->call_dl_resolve = 0UL;
4256 ++}
4257 ++
4258 ++static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
4259 ++{
4260 ++ unsigned int *kaddr;
4261 ++
4262 ++ vmf->page = alloc_page(GFP_HIGHUSER);
4263 ++ if (!vmf->page)
4264 ++ return VM_FAULT_OOM;
4265 ++
4266 ++ kaddr = kmap(vmf->page);
4267 ++ memset(kaddr, 0, PAGE_SIZE);
4268 ++ kaddr[0] = 0x9DE3BFA8U; /* save */
4269 ++ flush_dcache_page(vmf->page);
4270 ++ kunmap(vmf->page);
4271 ++ return VM_FAULT_MAJOR;
4272 ++}
4273 ++
4274 ++static struct vm_operations_struct pax_vm_ops = {
4275 ++ .close = pax_emuplt_close,
4276 ++ .fault = pax_emuplt_fault
4277 ++};
4278 ++
4279 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
4280 ++{
4281 ++ int ret;
4282 ++
4283 ++ vma->vm_mm = current->mm;
4284 ++ vma->vm_start = addr;
4285 ++ vma->vm_end = addr + PAGE_SIZE;
4286 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
4287 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
4288 ++ vma->vm_ops = &pax_vm_ops;
4289 ++
4290 ++ ret = insert_vm_struct(current->mm, vma);
4291 ++ if (ret)
4292 ++ return ret;
4293 ++
4294 ++ ++current->mm->total_vm;
4295 ++ return 0;
4296 ++}
4297 ++
4298 ++/*
4299 ++ * PaX: decide what to do with offenders (regs->pc = fault address)
4300 ++ *
4301 ++ * returns 1 when task should be killed
4302 ++ * 2 when patched PLT trampoline was detected
4303 ++ * 3 when unpatched PLT trampoline was detected
4304 ++ */
4305 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
4306 ++{
4307 ++
4308 ++#ifdef CONFIG_PAX_EMUPLT
4309 ++ int err;
4310 ++
4311 ++ do { /* PaX: patched PLT emulation #1 */
4312 ++ unsigned int sethi1, sethi2, jmpl;
4313 ++
4314 ++ err = get_user(sethi1, (unsigned int *)regs->pc);
4315 ++ err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
4316 ++ err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
4317 ++
4318 ++ if (err)
4319 ++ break;
4320 ++
4321 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4322 ++ (sethi2 & 0xFFC00000U) == 0x03000000U &&
4323 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U)
4324 ++ {
4325 ++ unsigned int addr;
4326 ++
4327 ++ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
4328 ++ addr = regs->u_regs[UREG_G1];
4329 ++ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
4330 ++ regs->pc = addr;
4331 ++ regs->npc = addr+4;
4332 ++ return 2;
4333 ++ }
4334 ++ } while (0);
4335 ++
4336 ++ { /* PaX: patched PLT emulation #2 */
4337 ++ unsigned int ba;
4338 ++
4339 ++ err = get_user(ba, (unsigned int *)regs->pc);
4340 ++
4341 ++ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
4342 ++ unsigned int addr;
4343 ++
4344 ++ addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
4345 ++ regs->pc = addr;
4346 ++ regs->npc = addr+4;
4347 ++ return 2;
4348 ++ }
4349 ++ }
4350 ++
4351 ++ do { /* PaX: patched PLT emulation #3 */
4352 ++ unsigned int sethi, jmpl, nop;
4353 ++
4354 ++ err = get_user(sethi, (unsigned int *)regs->pc);
4355 ++ err |= get_user(jmpl, (unsigned int *)(regs->pc+4));
4356 ++ err |= get_user(nop, (unsigned int *)(regs->pc+8));
4357 ++
4358 ++ if (err)
4359 ++ break;
4360 ++
4361 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
4362 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
4363 ++ nop == 0x01000000U)
4364 ++ {
4365 ++ unsigned int addr;
4366 ++
4367 ++ addr = (sethi & 0x003FFFFFU) << 10;
4368 ++ regs->u_regs[UREG_G1] = addr;
4369 ++ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
4370 ++ regs->pc = addr;
4371 ++ regs->npc = addr+4;
4372 ++ return 2;
4373 ++ }
4374 ++ } while (0);
4375 ++
4376 ++ do { /* PaX: unpatched PLT emulation step 1 */
4377 ++ unsigned int sethi, ba, nop;
4378 ++
4379 ++ err = get_user(sethi, (unsigned int *)regs->pc);
4380 ++ err |= get_user(ba, (unsigned int *)(regs->pc+4));
4381 ++ err |= get_user(nop, (unsigned int *)(regs->pc+8));
4382 ++
4383 ++ if (err)
4384 ++ break;
4385 ++
4386 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
4387 ++ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
4388 ++ nop == 0x01000000U)
4389 ++ {
4390 ++ unsigned int addr, save, call;
4391 ++
4392 ++ if ((ba & 0xFFC00000U) == 0x30800000U)
4393 ++ addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
4394 ++ else
4395 ++ addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
4396 ++
4397 ++ err = get_user(save, (unsigned int *)addr);
4398 ++ err |= get_user(call, (unsigned int *)(addr+4));
4399 ++ err |= get_user(nop, (unsigned int *)(addr+8));
4400 ++ if (err)
4401 ++ break;
4402 ++
4403 ++ if (save == 0x9DE3BFA8U &&
4404 ++ (call & 0xC0000000U) == 0x40000000U &&
4405 ++ nop == 0x01000000U)
4406 ++ {
4407 ++ struct vm_area_struct *vma;
4408 ++ unsigned long call_dl_resolve;
4409 ++
4410 ++ down_read(&current->mm->mmap_sem);
4411 ++ call_dl_resolve = current->mm->call_dl_resolve;
4412 ++ up_read(&current->mm->mmap_sem);
4413 ++ if (likely(call_dl_resolve))
4414 ++ goto emulate;
4415 ++
4416 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
4417 ++
4418 ++ down_write(&current->mm->mmap_sem);
4419 ++ if (current->mm->call_dl_resolve) {
4420 ++ call_dl_resolve = current->mm->call_dl_resolve;
4421 ++ up_write(&current->mm->mmap_sem);
4422 ++ if (vma)
4423 ++ kmem_cache_free(vm_area_cachep, vma);
4424 ++ goto emulate;
4425 ++ }
4426 ++
4427 ++ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
4428 ++ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
4429 ++ up_write(&current->mm->mmap_sem);
4430 ++ if (vma)
4431 ++ kmem_cache_free(vm_area_cachep, vma);
4432 ++ return 1;
4433 ++ }
4434 ++
4435 ++ if (pax_insert_vma(vma, call_dl_resolve)) {
4436 ++ up_write(&current->mm->mmap_sem);
4437 ++ kmem_cache_free(vm_area_cachep, vma);
4438 ++ return 1;
4439 ++ }
4440 ++
4441 ++ current->mm->call_dl_resolve = call_dl_resolve;
4442 ++ up_write(&current->mm->mmap_sem);
4443 ++
4444 ++emulate:
4445 ++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
4446 ++ regs->pc = call_dl_resolve;
4447 ++ regs->npc = addr+4;
4448 ++ return 3;
4449 ++ }
4450 ++ }
4451 ++ } while (0);
4452 ++
4453 ++ do { /* PaX: unpatched PLT emulation step 2 */
4454 ++ unsigned int save, call, nop;
4455 ++
4456 ++ err = get_user(save, (unsigned int *)(regs->pc-4));
4457 ++ err |= get_user(call, (unsigned int *)regs->pc);
4458 ++ err |= get_user(nop, (unsigned int *)(regs->pc+4));
4459 ++ if (err)
4460 ++ break;
4461 ++
4462 ++ if (save == 0x9DE3BFA8U &&
4463 ++ (call & 0xC0000000U) == 0x40000000U &&
4464 ++ nop == 0x01000000U)
4465 ++ {
4466 ++ unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
4467 ++
4468 ++ regs->u_regs[UREG_RETPC] = regs->pc;
4469 ++ regs->pc = dl_resolve;
4470 ++ regs->npc = dl_resolve+4;
4471 ++ return 3;
4472 ++ }
4473 ++ } while (0);
4474 ++#endif
4475 ++
4476 ++ return 1;
4477 ++}
4478 ++
4479 ++void pax_report_insns(void *pc, void *sp)
4480 ++{
4481 ++ unsigned long i;
4482 ++
4483 ++ printk(KERN_ERR "PAX: bytes at PC: ");
4484 ++ for (i = 0; i < 5; i++) {
4485 ++ unsigned int c;
4486 ++ if (get_user(c, (unsigned int *)pc+i))
4487 ++ printk(KERN_CONT "???????? ");
4488 ++ else
4489 ++ printk(KERN_CONT "%08x ", c);
4490 ++ }
4491 ++ printk("\n");
4492 ++}
4493 ++#endif
4494 ++
4495 + asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
4496 + unsigned long address)
4497 + {
4498 +@@ -231,6 +477,24 @@ good_area:
4499 + if(!(vma->vm_flags & VM_WRITE))
4500 + goto bad_area;
4501 + } else {
4502 ++
4503 ++#ifdef CONFIG_PAX_PAGEEXEC
4504 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
4505 ++ up_read(&mm->mmap_sem);
4506 ++ switch (pax_handle_fetch_fault(regs)) {
4507 ++
4508 ++#ifdef CONFIG_PAX_EMUPLT
4509 ++ case 2:
4510 ++ case 3:
4511 ++ return;
4512 ++#endif
4513 ++
4514 ++ }
4515 ++ pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]);
4516 ++ do_group_exit(SIGKILL);
4517 ++ }
4518 ++#endif
4519 ++
4520 + /* Allow reads even for write-only mappings */
4521 + if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
4522 + goto bad_area;
4523 +diff -urNp linux-2.6.26.6/arch/sparc/mm/init.c linux-2.6.26.6/arch/sparc/mm/init.c
4524 +--- linux-2.6.26.6/arch/sparc/mm/init.c 2008-10-08 23:24:05.000000000 -0400
4525 ++++ linux-2.6.26.6/arch/sparc/mm/init.c 2008-10-11 21:54:19.000000000 -0400
4526 +@@ -311,6 +311,9 @@ extern void device_scan(void);
4527 + pgprot_t PAGE_SHARED __read_mostly;
4528 + EXPORT_SYMBOL(PAGE_SHARED);
4529 +
4530 ++pgprot_t PAGE_SHARED_NOEXEC __read_mostly;
4531 ++EXPORT_SYMBOL(PAGE_SHARED_NOEXEC);
4532 ++
4533 + void __init paging_init(void)
4534 + {
4535 + switch(sparc_cpu_model) {
4536 +@@ -336,17 +339,17 @@ void __init paging_init(void)
4537 +
4538 + /* Initialize the protection map with non-constant, MMU dependent values. */
4539 + protection_map[0] = PAGE_NONE;
4540 +- protection_map[1] = PAGE_READONLY;
4541 +- protection_map[2] = PAGE_COPY;
4542 +- protection_map[3] = PAGE_COPY;
4543 ++ protection_map[1] = PAGE_READONLY_NOEXEC;
4544 ++ protection_map[2] = PAGE_COPY_NOEXEC;
4545 ++ protection_map[3] = PAGE_COPY_NOEXEC;
4546 + protection_map[4] = PAGE_READONLY;
4547 + protection_map[5] = PAGE_READONLY;
4548 + protection_map[6] = PAGE_COPY;
4549 + protection_map[7] = PAGE_COPY;
4550 + protection_map[8] = PAGE_NONE;
4551 +- protection_map[9] = PAGE_READONLY;
4552 +- protection_map[10] = PAGE_SHARED;
4553 +- protection_map[11] = PAGE_SHARED;
4554 ++ protection_map[9] = PAGE_READONLY_NOEXEC;
4555 ++ protection_map[10] = PAGE_SHARED_NOEXEC;
4556 ++ protection_map[11] = PAGE_SHARED_NOEXEC;
4557 + protection_map[12] = PAGE_READONLY;
4558 + protection_map[13] = PAGE_READONLY;
4559 + protection_map[14] = PAGE_SHARED;
4560 +diff -urNp linux-2.6.26.6/arch/sparc/mm/srmmu.c linux-2.6.26.6/arch/sparc/mm/srmmu.c
4561 +--- linux-2.6.26.6/arch/sparc/mm/srmmu.c 2008-10-08 23:24:05.000000000 -0400
4562 ++++ linux-2.6.26.6/arch/sparc/mm/srmmu.c 2008-10-11 21:54:19.000000000 -0400
4563 +@@ -2160,6 +2160,13 @@ void __init ld_mmu_srmmu(void)
4564 + PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED);
4565 + BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
4566 + BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
4567 ++
4568 ++#ifdef CONFIG_PAX_PAGEEXEC
4569 ++ PAGE_SHARED_NOEXEC = pgprot_val(SRMMU_PAGE_SHARED_NOEXEC);
4570 ++ BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
4571 ++ BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
4572 ++#endif
4573 ++
4574 + BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
4575 + page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
4576 +
4577 +diff -urNp linux-2.6.26.6/arch/sparc64/kernel/Makefile linux-2.6.26.6/arch/sparc64/kernel/Makefile
4578 +--- linux-2.6.26.6/arch/sparc64/kernel/Makefile 2008-10-08 23:24:05.000000000 -0400
4579 ++++ linux-2.6.26.6/arch/sparc64/kernel/Makefile 2008-10-11 21:54:19.000000000 -0400
4580 +@@ -3,7 +3,7 @@
4581 + #
4582 +
4583 + EXTRA_AFLAGS := -ansi
4584 +-EXTRA_CFLAGS := -Werror
4585 ++#EXTRA_CFLAGS := -Werror
4586 +
4587 + extra-y := head.o init_task.o vmlinux.lds
4588 +
4589 +diff -urNp linux-2.6.26.6/arch/sparc64/kernel/sys_sparc.c linux-2.6.26.6/arch/sparc64/kernel/sys_sparc.c
4590 +--- linux-2.6.26.6/arch/sparc64/kernel/sys_sparc.c 2008-10-08 23:24:05.000000000 -0400
4591 ++++ linux-2.6.26.6/arch/sparc64/kernel/sys_sparc.c 2008-10-11 21:54:19.000000000 -0400
4592 +@@ -124,7 +124,7 @@ unsigned long arch_get_unmapped_area(str
4593 + /* We do not accept a shared mapping if it would violate
4594 + * cache aliasing constraints.
4595 + */
4596 +- if ((flags & MAP_SHARED) &&
4597 ++ if ((filp || (flags & MAP_SHARED)) &&
4598 + ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
4599 + return -EINVAL;
4600 + return addr;
4601 +@@ -139,6 +139,10 @@ unsigned long arch_get_unmapped_area(str
4602 + if (filp || (flags & MAP_SHARED))
4603 + do_color_align = 1;
4604 +
4605 ++#ifdef CONFIG_PAX_RANDMMAP
4606 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
4607 ++#endif
4608 ++
4609 + if (addr) {
4610 + if (do_color_align)
4611 + addr = COLOUR_ALIGN(addr, pgoff);
4612 +@@ -152,9 +156,9 @@ unsigned long arch_get_unmapped_area(str
4613 + }
4614 +
4615 + if (len > mm->cached_hole_size) {
4616 +- start_addr = addr = mm->free_area_cache;
4617 ++ start_addr = addr = mm->free_area_cache;
4618 + } else {
4619 +- start_addr = addr = TASK_UNMAPPED_BASE;
4620 ++ start_addr = addr = mm->mmap_base;
4621 + mm->cached_hole_size = 0;
4622 + }
4623 +
4624 +@@ -174,8 +178,8 @@ full_search:
4625 + vma = find_vma(mm, VA_EXCLUDE_END);
4626 + }
4627 + if (unlikely(task_size < addr)) {
4628 +- if (start_addr != TASK_UNMAPPED_BASE) {
4629 +- start_addr = addr = TASK_UNMAPPED_BASE;
4630 ++ if (start_addr != mm->mmap_base) {
4631 ++ start_addr = addr = mm->mmap_base;
4632 + mm->cached_hole_size = 0;
4633 + goto full_search;
4634 + }
4635 +@@ -215,7 +219,7 @@ arch_get_unmapped_area_topdown(struct fi
4636 + /* We do not accept a shared mapping if it would violate
4637 + * cache aliasing constraints.
4638 + */
4639 +- if ((flags & MAP_SHARED) &&
4640 ++ if ((filp || (flags & MAP_SHARED)) &&
4641 + ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
4642 + return -EINVAL;
4643 + return addr;
4644 +@@ -378,6 +382,12 @@ void arch_pick_mmap_layout(struct mm_str
4645 + current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
4646 + sysctl_legacy_va_layout) {
4647 + mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
4648 ++
4649 ++#ifdef CONFIG_PAX_RANDMMAP
4650 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
4651 ++ mm->mmap_base += mm->delta_mmap;
4652 ++#endif
4653 ++
4654 + mm->get_unmapped_area = arch_get_unmapped_area;
4655 + mm->unmap_area = arch_unmap_area;
4656 + } else {
4657 +@@ -392,6 +402,12 @@ void arch_pick_mmap_layout(struct mm_str
4658 + gap = (task_size / 6 * 5);
4659 +
4660 + mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
4661 ++
4662 ++#ifdef CONFIG_PAX_RANDMMAP
4663 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
4664 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
4665 ++#endif
4666 ++
4667 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
4668 + mm->unmap_area = arch_unmap_area_topdown;
4669 + }
4670 +diff -urNp linux-2.6.26.6/arch/sparc64/mm/fault.c linux-2.6.26.6/arch/sparc64/mm/fault.c
4671 +--- linux-2.6.26.6/arch/sparc64/mm/fault.c 2008-10-08 23:24:05.000000000 -0400
4672 ++++ linux-2.6.26.6/arch/sparc64/mm/fault.c 2008-10-11 21:54:19.000000000 -0400
4673 +@@ -20,6 +20,9 @@
4674 + #include <linux/kprobes.h>
4675 + #include <linux/kallsyms.h>
4676 + #include <linux/kdebug.h>
4677 ++#include <linux/slab.h>
4678 ++#include <linux/pagemap.h>
4679 ++#include <linux/compiler.h>
4680 +
4681 + #include <asm/page.h>
4682 + #include <asm/pgtable.h>
4683 +@@ -262,6 +265,367 @@ cannot_handle:
4684 + unhandled_fault (address, current, regs);
4685 + }
4686 +
4687 ++#ifdef CONFIG_PAX_PAGEEXEC
4688 ++#ifdef CONFIG_PAX_EMUPLT
4689 ++static void pax_emuplt_close(struct vm_area_struct *vma)
4690 ++{
4691 ++ vma->vm_mm->call_dl_resolve = 0UL;
4692 ++}
4693 ++
4694 ++static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
4695 ++{
4696 ++ unsigned int *kaddr;
4697 ++
4698 ++ vmf->page = alloc_page(GFP_HIGHUSER);
4699 ++ if (!vmf->page)
4700 ++ return VM_FAULT_OOM;
4701 ++
4702 ++ kaddr = kmap(vmf->page);
4703 ++ memset(kaddr, 0, PAGE_SIZE);
4704 ++ kaddr[0] = 0x9DE3BFA8U; /* save */
4705 ++ flush_dcache_page(vmf->page);
4706 ++ kunmap(vmf->page);
4707 ++ return VM_FAULT_MAJOR;
4708 ++}
4709 ++
4710 ++static struct vm_operations_struct pax_vm_ops = {
4711 ++ .close = pax_emuplt_close,
4712 ++ .fault = pax_emuplt_fault
4713 ++};
4714 ++
4715 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
4716 ++{
4717 ++ int ret;
4718 ++
4719 ++ vma->vm_mm = current->mm;
4720 ++ vma->vm_start = addr;
4721 ++ vma->vm_end = addr + PAGE_SIZE;
4722 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
4723 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
4724 ++ vma->vm_ops = &pax_vm_ops;
4725 ++
4726 ++ ret = insert_vm_struct(current->mm, vma);
4727 ++ if (ret)
4728 ++ return ret;
4729 ++
4730 ++ ++current->mm->total_vm;
4731 ++ return 0;
4732 ++}
4733 ++#endif
4734 ++
4735 ++/*
4736 ++ * PaX: decide what to do with offenders (regs->tpc = fault address)
4737 ++ *
4738 ++ * returns 1 when task should be killed
4739 ++ * 2 when patched PLT trampoline was detected
4740 ++ * 3 when unpatched PLT trampoline was detected
4741 ++ */
4742 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
4743 ++{
4744 ++
4745 ++#ifdef CONFIG_PAX_EMUPLT
4746 ++ int err;
4747 ++
4748 ++ do { /* PaX: patched PLT emulation #1 */
4749 ++ unsigned int sethi1, sethi2, jmpl;
4750 ++
4751 ++ err = get_user(sethi1, (unsigned int *)regs->tpc);
4752 ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
4753 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+8));
4754 ++
4755 ++ if (err)
4756 ++ break;
4757 ++
4758 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4759 ++ (sethi2 & 0xFFC00000U) == 0x03000000U &&
4760 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U)
4761 ++ {
4762 ++ unsigned long addr;
4763 ++
4764 ++ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
4765 ++ addr = regs->u_regs[UREG_G1];
4766 ++ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
4767 ++ regs->tpc = addr;
4768 ++ regs->tnpc = addr+4;
4769 ++ return 2;
4770 ++ }
4771 ++ } while (0);
4772 ++
4773 ++ { /* PaX: patched PLT emulation #2 */
4774 ++ unsigned int ba;
4775 ++
4776 ++ err = get_user(ba, (unsigned int *)regs->tpc);
4777 ++
4778 ++ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
4779 ++ unsigned long addr;
4780 ++
4781 ++ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
4782 ++ regs->tpc = addr;
4783 ++ regs->tnpc = addr+4;
4784 ++ return 2;
4785 ++ }
4786 ++ }
4787 ++
4788 ++ do { /* PaX: patched PLT emulation #3 */
4789 ++ unsigned int sethi, jmpl, nop;
4790 ++
4791 ++ err = get_user(sethi, (unsigned int *)regs->tpc);
4792 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+4));
4793 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
4794 ++
4795 ++ if (err)
4796 ++ break;
4797 ++
4798 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
4799 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
4800 ++ nop == 0x01000000U)
4801 ++ {
4802 ++ unsigned long addr;
4803 ++
4804 ++ addr = (sethi & 0x003FFFFFU) << 10;
4805 ++ regs->u_regs[UREG_G1] = addr;
4806 ++ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
4807 ++ regs->tpc = addr;
4808 ++ regs->tnpc = addr+4;
4809 ++ return 2;
4810 ++ }
4811 ++ } while (0);
4812 ++
4813 ++ do { /* PaX: patched PLT emulation #4 */
4814 ++ unsigned int mov1, call, mov2;
4815 ++
4816 ++ err = get_user(mov1, (unsigned int *)regs->tpc);
4817 ++ err |= get_user(call, (unsigned int *)(regs->tpc+4));
4818 ++ err |= get_user(mov2, (unsigned int *)(regs->tpc+8));
4819 ++
4820 ++ if (err)
4821 ++ break;
4822 ++
4823 ++ if (mov1 == 0x8210000FU &&
4824 ++ (call & 0xC0000000U) == 0x40000000U &&
4825 ++ mov2 == 0x9E100001U)
4826 ++ {
4827 ++ unsigned long addr;
4828 ++
4829 ++ regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
4830 ++ addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
4831 ++ regs->tpc = addr;
4832 ++ regs->tnpc = addr+4;
4833 ++ return 2;
4834 ++ }
4835 ++ } while (0);
4836 ++
4837 ++ do { /* PaX: patched PLT emulation #5 */
4838 ++ unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
4839 ++
4840 ++ err = get_user(sethi1, (unsigned int *)regs->tpc);
4841 ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
4842 ++ err |= get_user(or1, (unsigned int *)(regs->tpc+8));
4843 ++ err |= get_user(or2, (unsigned int *)(regs->tpc+12));
4844 ++ err |= get_user(sllx, (unsigned int *)(regs->tpc+16));
4845 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+20));
4846 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+24));
4847 ++
4848 ++ if (err)
4849 ++ break;
4850 ++
4851 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4852 ++ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
4853 ++ (or1 & 0xFFFFE000U) == 0x82106000U &&
4854 ++ (or2 & 0xFFFFE000U) == 0x8A116000U &&
4855 ++ sllx == 0x83287020 &&
4856 ++ jmpl == 0x81C04005U &&
4857 ++ nop == 0x01000000U)
4858 ++ {
4859 ++ unsigned long addr;
4860 ++
4861 ++ regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
4862 ++ regs->u_regs[UREG_G1] <<= 32;
4863 ++ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
4864 ++ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
4865 ++ regs->tpc = addr;
4866 ++ regs->tnpc = addr+4;
4867 ++ return 2;
4868 ++ }
4869 ++ } while (0);
4870 ++
4871 ++ do { /* PaX: patched PLT emulation #6 */
4872 ++ unsigned int sethi1, sethi2, sllx, or, jmpl, nop;
4873 ++
4874 ++ err = get_user(sethi1, (unsigned int *)regs->tpc);
4875 ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
4876 ++ err |= get_user(sllx, (unsigned int *)(regs->tpc+8));
4877 ++ err |= get_user(or, (unsigned int *)(regs->tpc+12));
4878 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+16));
4879 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+20));
4880 ++
4881 ++ if (err)
4882 ++ break;
4883 ++
4884 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4885 ++ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
4886 ++ sllx == 0x83287020 &&
4887 ++ (or & 0xFFFFE000U) == 0x8A116000U &&
4888 ++ jmpl == 0x81C04005U &&
4889 ++ nop == 0x01000000U)
4890 ++ {
4891 ++ unsigned long addr;
4892 ++
4893 ++ regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
4894 ++ regs->u_regs[UREG_G1] <<= 32;
4895 ++ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
4896 ++ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
4897 ++ regs->tpc = addr;
4898 ++ regs->tnpc = addr+4;
4899 ++ return 2;
4900 ++ }
4901 ++ } while (0);
4902 ++
4903 ++ do { /* PaX: patched PLT emulation #7 */
4904 ++ unsigned int sethi, ba, nop;
4905 ++
4906 ++ err = get_user(sethi, (unsigned int *)regs->tpc);
4907 ++ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
4908 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
4909 ++
4910 ++ if (err)
4911 ++ break;
4912 ++
4913 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
4914 ++ (ba & 0xFFF00000U) == 0x30600000U &&
4915 ++ nop == 0x01000000U)
4916 ++ {
4917 ++ unsigned long addr;
4918 ++
4919 ++ addr = (sethi & 0x003FFFFFU) << 10;
4920 ++ regs->u_regs[UREG_G1] = addr;
4921 ++ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
4922 ++ regs->tpc = addr;
4923 ++ regs->tnpc = addr+4;
4924 ++ return 2;
4925 ++ }
4926 ++ } while (0);
4927 ++
4928 ++ do { /* PaX: unpatched PLT emulation step 1 */
4929 ++ unsigned int sethi, ba, nop;
4930 ++
4931 ++ err = get_user(sethi, (unsigned int *)regs->tpc);
4932 ++ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
4933 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
4934 ++
4935 ++ if (err)
4936 ++ break;
4937 ++
4938 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
4939 ++ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
4940 ++ nop == 0x01000000U)
4941 ++ {
4942 ++ unsigned long addr;
4943 ++ unsigned int save, call;
4944 ++
4945 ++ if ((ba & 0xFFC00000U) == 0x30800000U)
4946 ++ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
4947 ++ else
4948 ++ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
4949 ++
4950 ++ err = get_user(save, (unsigned int *)addr);
4951 ++ err |= get_user(call, (unsigned int *)(addr+4));
4952 ++ err |= get_user(nop, (unsigned int *)(addr+8));
4953 ++ if (err)
4954 ++ break;
4955 ++
4956 ++ if (save == 0x9DE3BFA8U &&
4957 ++ (call & 0xC0000000U) == 0x40000000U &&
4958 ++ nop == 0x01000000U)
4959 ++ {
4960 ++ struct vm_area_struct *vma;
4961 ++ unsigned long call_dl_resolve;
4962 ++
4963 ++ down_read(&current->mm->mmap_sem);
4964 ++ call_dl_resolve = current->mm->call_dl_resolve;
4965 ++ up_read(&current->mm->mmap_sem);
4966 ++ if (likely(call_dl_resolve))
4967 ++ goto emulate;
4968 ++
4969 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
4970 ++
4971 ++ down_write(&current->mm->mmap_sem);
4972 ++ if (current->mm->call_dl_resolve) {
4973 ++ call_dl_resolve = current->mm->call_dl_resolve;
4974 ++ up_write(&current->mm->mmap_sem);
4975 ++ if (vma)
4976 ++ kmem_cache_free(vm_area_cachep, vma);
4977 ++ goto emulate;
4978 ++ }
4979 ++
4980 ++ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
4981 ++ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
4982 ++ up_write(&current->mm->mmap_sem);
4983 ++ if (vma)
4984 ++ kmem_cache_free(vm_area_cachep, vma);
4985 ++ return 1;
4986 ++ }
4987 ++
4988 ++ if (pax_insert_vma(vma, call_dl_resolve)) {
4989 ++ up_write(&current->mm->mmap_sem);
4990 ++ kmem_cache_free(vm_area_cachep, vma);
4991 ++ return 1;
4992 ++ }
4993 ++
4994 ++ current->mm->call_dl_resolve = call_dl_resolve;
4995 ++ up_write(&current->mm->mmap_sem);
4996 ++
4997 ++emulate:
4998 ++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
4999 ++ regs->tpc = call_dl_resolve;
5000 ++ regs->tnpc = addr+4;
5001 ++ return 3;
5002 ++ }
5003 ++ }
5004 ++ } while (0);
5005 ++
5006 ++ do { /* PaX: unpatched PLT emulation step 2 */
5007 ++ unsigned int save, call, nop;
5008 ++
5009 ++ err = get_user(save, (unsigned int *)(regs->tpc-4));
5010 ++ err |= get_user(call, (unsigned int *)regs->tpc);
5011 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+4));
5012 ++ if (err)
5013 ++ break;
5014 ++
5015 ++ if (save == 0x9DE3BFA8U &&
5016 ++ (call & 0xC0000000U) == 0x40000000U &&
5017 ++ nop == 0x01000000U)
5018 ++ {
5019 ++ unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
5020 ++
5021 ++ regs->u_regs[UREG_RETPC] = regs->tpc;
5022 ++ regs->tpc = dl_resolve;
5023 ++ regs->tnpc = dl_resolve+4;
5024 ++ return 3;
5025 ++ }
5026 ++ } while (0);
5027 ++#endif
5028 ++
5029 ++ return 1;
5030 ++}
5031 ++
5032 ++void pax_report_insns(void *pc, void *sp)
5033 ++{
5034 ++ unsigned long i;
5035 ++
5036 ++ printk(KERN_ERR "PAX: bytes at PC: ");
5037 ++ for (i = 0; i < 5; i++) {
5038 ++ unsigned int c;
5039 ++ if (get_user(c, (unsigned int *)pc+i))
5040 ++ printk(KERN_CONT "???????? ");
5041 ++ else
5042 ++ printk(KERN_CONT "%08x ", c);
5043 ++ }
5044 ++ printk("\n");
5045 ++}
5046 ++#endif
5047 ++
5048 + asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
5049 + {
5050 + struct mm_struct *mm = current->mm;
5051 +@@ -303,8 +667,10 @@ asmlinkage void __kprobes do_sparc64_fau
5052 + goto intr_or_no_mm;
5053 +
5054 + if (test_thread_flag(TIF_32BIT)) {
5055 +- if (!(regs->tstate & TSTATE_PRIV))
5056 ++ if (!(regs->tstate & TSTATE_PRIV)) {
5057 + regs->tpc &= 0xffffffff;
5058 ++ regs->tnpc &= 0xffffffff;
5059 ++ }
5060 + address &= 0xffffffff;
5061 + }
5062 +
5063 +@@ -321,6 +687,29 @@ asmlinkage void __kprobes do_sparc64_fau
5064 + if (!vma)
5065 + goto bad_area;
5066 +
5067 ++#ifdef CONFIG_PAX_PAGEEXEC
5068 ++ /* PaX: detect ITLB misses on non-exec pages */
5069 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
5070 ++ !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
5071 ++ {
5072 ++ if (address != regs->tpc)
5073 ++ goto good_area;
5074 ++
5075 ++ up_read(&mm->mmap_sem);
5076 ++ switch (pax_handle_fetch_fault(regs)) {
5077 ++
5078 ++#ifdef CONFIG_PAX_EMUPLT
5079 ++ case 2:
5080 ++ case 3:
5081 ++ return;
5082 ++#endif
5083 ++
5084 ++ }
5085 ++ pax_report_fault(regs, (void *)regs->tpc, (void *)(regs->u_regs[UREG_FP] + STACK_BIAS));
5086 ++ do_group_exit(SIGKILL);
5087 ++ }
5088 ++#endif
5089 ++
5090 + /* Pure DTLB misses do not tell us whether the fault causing
5091 + * load/store/atomic was a write or not, it only says that there
5092 + * was no match. So in such a case we (carefully) read the
5093 +diff -urNp linux-2.6.26.6/arch/sparc64/mm/Makefile linux-2.6.26.6/arch/sparc64/mm/Makefile
5094 +--- linux-2.6.26.6/arch/sparc64/mm/Makefile 2008-10-08 23:24:05.000000000 -0400
5095 ++++ linux-2.6.26.6/arch/sparc64/mm/Makefile 2008-10-11 21:54:19.000000000 -0400
5096 +@@ -2,7 +2,7 @@
5097 + #
5098 +
5099 + EXTRA_AFLAGS := -ansi
5100 +-EXTRA_CFLAGS := -Werror
5101 ++#EXTRA_CFLAGS := -Werror
5102 +
5103 + obj-y := ultra.o tlb.o tsb.o fault.o init.o generic.o
5104 +
5105 +diff -urNp linux-2.6.26.6/arch/um/sys-i386/syscalls.c linux-2.6.26.6/arch/um/sys-i386/syscalls.c
5106 +--- linux-2.6.26.6/arch/um/sys-i386/syscalls.c 2008-10-08 23:24:05.000000000 -0400
5107 ++++ linux-2.6.26.6/arch/um/sys-i386/syscalls.c 2008-10-11 21:55:07.000000000 -0400
5108 +@@ -10,6 +10,21 @@
5109 + #include "asm/uaccess.h"
5110 + #include "asm/unistd.h"
5111 +
5112 ++int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
5113 ++{
5114 ++ unsigned long pax_task_size = TASK_SIZE;
5115 ++
5116 ++#ifdef CONFIG_PAX_SEGMEXEC
5117 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
5118 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
5119 ++#endif
5120 ++
5121 ++ if (len > pax_task_size || addr > pax_task_size - len)
5122 ++ return -EINVAL;
5123 ++
5124 ++ return 0;
5125 ++}
5126 ++
5127 + /*
5128 + * Perform the select(nd, in, out, ex, tv) and mmap() system
5129 + * calls. Linux/i386 didn't use to be able to handle more than
5130 +diff -urNp linux-2.6.26.6/arch/v850/kernel/module.c linux-2.6.26.6/arch/v850/kernel/module.c
5131 +--- linux-2.6.26.6/arch/v850/kernel/module.c 2008-10-08 23:24:05.000000000 -0400
5132 ++++ linux-2.6.26.6/arch/v850/kernel/module.c 2008-10-11 21:54:19.000000000 -0400
5133 +@@ -150,8 +150,8 @@ static uint32_t do_plt_call (void *locat
5134 + tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
5135 +
5136 + /* Init, or core PLT? */
5137 +- if (location >= mod->module_core
5138 +- && location < mod->module_core + mod->core_size)
5139 ++ if (location >= mod->module_core_rx
5140 ++ && location < mod->module_core_rx + mod->core_size_rx)
5141 + entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
5142 + else
5143 + entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
5144 +diff -urNp linux-2.6.26.6/arch/x86/boot/bitops.h linux-2.6.26.6/arch/x86/boot/bitops.h
5145 +--- linux-2.6.26.6/arch/x86/boot/bitops.h 2008-10-08 23:24:05.000000000 -0400
5146 ++++ linux-2.6.26.6/arch/x86/boot/bitops.h 2008-10-11 21:54:19.000000000 -0400
5147 +@@ -26,7 +26,7 @@ static inline int variable_test_bit(int
5148 + u8 v;
5149 + const u32 *p = (const u32 *)addr;
5150 +
5151 +- asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
5152 ++ asm volatile("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
5153 + return v;
5154 + }
5155 +
5156 +@@ -37,7 +37,7 @@ static inline int variable_test_bit(int
5157 +
5158 + static inline void set_bit(int nr, void *addr)
5159 + {
5160 +- asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
5161 ++ asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
5162 + }
5163 +
5164 + #endif /* BOOT_BITOPS_H */
5165 +diff -urNp linux-2.6.26.6/arch/x86/boot/boot.h linux-2.6.26.6/arch/x86/boot/boot.h
5166 +--- linux-2.6.26.6/arch/x86/boot/boot.h 2008-10-08 23:24:05.000000000 -0400
5167 ++++ linux-2.6.26.6/arch/x86/boot/boot.h 2008-10-11 21:54:19.000000000 -0400
5168 +@@ -78,7 +78,7 @@ static inline void io_delay(void)
5169 + static inline u16 ds(void)
5170 + {
5171 + u16 seg;
5172 +- asm("movw %%ds,%0" : "=rm" (seg));
5173 ++ asm volatile("movw %%ds,%0" : "=rm" (seg));
5174 + return seg;
5175 + }
5176 +
5177 +@@ -174,7 +174,7 @@ static inline void wrgs32(u32 v, addr_t
5178 + static inline int memcmp(const void *s1, const void *s2, size_t len)
5179 + {
5180 + u8 diff;
5181 +- asm("repe; cmpsb; setnz %0"
5182 ++ asm volatile("repe; cmpsb; setnz %0"
5183 + : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
5184 + return diff;
5185 + }
5186 +diff -urNp linux-2.6.26.6/arch/x86/boot/compressed/head_32.S linux-2.6.26.6/arch/x86/boot/compressed/head_32.S
5187 +--- linux-2.6.26.6/arch/x86/boot/compressed/head_32.S 2008-10-08 23:24:05.000000000 -0400
5188 ++++ linux-2.6.26.6/arch/x86/boot/compressed/head_32.S 2008-10-11 21:54:19.000000000 -0400
5189 +@@ -70,7 +70,7 @@ startup_32:
5190 + addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebx
5191 + andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebx
5192 + #else
5193 +- movl $LOAD_PHYSICAL_ADDR, %ebx
5194 ++ movl $____LOAD_PHYSICAL_ADDR, %ebx
5195 + #endif
5196 +
5197 + /* Replace the compressed data size with the uncompressed size */
5198 +@@ -105,7 +105,7 @@ startup_32:
5199 + addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebp
5200 + andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebp
5201 + #else
5202 +- movl $LOAD_PHYSICAL_ADDR, %ebp
5203 ++ movl $____LOAD_PHYSICAL_ADDR, %ebp
5204 + #endif
5205 +
5206 + /*
5207 +@@ -159,16 +159,15 @@ relocated:
5208 + * and where it was actually loaded.
5209 + */
5210 + movl %ebp, %ebx
5211 +- subl $LOAD_PHYSICAL_ADDR, %ebx
5212 ++ subl $____LOAD_PHYSICAL_ADDR, %ebx
5213 + jz 2f /* Nothing to be done if loaded at compiled addr. */
5214 + /*
5215 + * Process relocations.
5216 + */
5217 +
5218 + 1: subl $4, %edi
5219 +- movl 0(%edi), %ecx
5220 +- testl %ecx, %ecx
5221 +- jz 2f
5222 ++ movl (%edi), %ecx
5223 ++ jecxz 2f
5224 + addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
5225 + jmp 1b
5226 + 2:
5227 +diff -urNp linux-2.6.26.6/arch/x86/boot/compressed/misc.c linux-2.6.26.6/arch/x86/boot/compressed/misc.c
5228 +--- linux-2.6.26.6/arch/x86/boot/compressed/misc.c 2008-10-08 23:24:05.000000000 -0400
5229 ++++ linux-2.6.26.6/arch/x86/boot/compressed/misc.c 2008-10-11 21:54:19.000000000 -0400
5230 +@@ -410,7 +410,7 @@ static void parse_elf(void *output)
5231 + case PT_LOAD:
5232 + #ifdef CONFIG_RELOCATABLE
5233 + dest = output;
5234 +- dest += (phdr->p_paddr - LOAD_PHYSICAL_ADDR);
5235 ++ dest += (phdr->p_paddr - ____LOAD_PHYSICAL_ADDR);
5236 + #else
5237 + dest = (void *)(phdr->p_paddr);
5238 + #endif
5239 +@@ -459,7 +459,7 @@ asmlinkage void decompress_kernel(void *
5240 + if (heap > ((-__PAGE_OFFSET-(512<<20)-1) & 0x7fffffff))
5241 + error("Destination address too large");
5242 + #ifndef CONFIG_RELOCATABLE
5243 +- if ((u32)output != LOAD_PHYSICAL_ADDR)
5244 ++ if ((u32)output != ____LOAD_PHYSICAL_ADDR)
5245 + error("Wrong destination address");
5246 + #endif
5247 + #endif
5248 +diff -urNp linux-2.6.26.6/arch/x86/boot/compressed/relocs.c linux-2.6.26.6/arch/x86/boot/compressed/relocs.c
5249 +--- linux-2.6.26.6/arch/x86/boot/compressed/relocs.c 2008-10-08 23:24:05.000000000 -0400
5250 ++++ linux-2.6.26.6/arch/x86/boot/compressed/relocs.c 2008-10-11 21:54:19.000000000 -0400
5251 +@@ -10,9 +10,13 @@
5252 + #define USE_BSD
5253 + #include <endian.h>
5254 +
5255 ++#include "../../../../include/linux/autoconf.h"
5256 ++
5257 ++#define MAX_PHDRS 100
5258 + #define MAX_SHDRS 100
5259 + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
5260 + static Elf32_Ehdr ehdr;
5261 ++static Elf32_Phdr phdr[MAX_PHDRS];
5262 + static Elf32_Shdr shdr[MAX_SHDRS];
5263 + static Elf32_Sym *symtab[MAX_SHDRS];
5264 + static Elf32_Rel *reltab[MAX_SHDRS];
5265 +@@ -241,6 +245,34 @@ static void read_ehdr(FILE *fp)
5266 + }
5267 + }
5268 +
5269 ++static void read_phdrs(FILE *fp)
5270 ++{
5271 ++ int i;
5272 ++ if (ehdr.e_phnum > MAX_PHDRS) {
5273 ++ die("%d program headers supported: %d\n",
5274 ++ ehdr.e_phnum, MAX_PHDRS);
5275 ++ }
5276 ++ if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) {
5277 ++ die("Seek to %d failed: %s\n",
5278 ++ ehdr.e_phoff, strerror(errno));
5279 ++ }
5280 ++ if (fread(&phdr, sizeof(phdr[0]), ehdr.e_phnum, fp) != ehdr.e_phnum) {
5281 ++ die("Cannot read ELF program headers: %s\n",
5282 ++ strerror(errno));
5283 ++ }
5284 ++ for(i = 0; i < ehdr.e_phnum; i++) {
5285 ++ phdr[i].p_type = elf32_to_cpu(phdr[i].p_type);
5286 ++ phdr[i].p_offset = elf32_to_cpu(phdr[i].p_offset);
5287 ++ phdr[i].p_vaddr = elf32_to_cpu(phdr[i].p_vaddr);
5288 ++ phdr[i].p_paddr = elf32_to_cpu(phdr[i].p_paddr);
5289 ++ phdr[i].p_filesz = elf32_to_cpu(phdr[i].p_filesz);
5290 ++ phdr[i].p_memsz = elf32_to_cpu(phdr[i].p_memsz);
5291 ++ phdr[i].p_flags = elf32_to_cpu(phdr[i].p_flags);
5292 ++ phdr[i].p_align = elf32_to_cpu(phdr[i].p_align);
5293 ++ }
5294 ++
5295 ++}
5296 ++
5297 + static void read_shdrs(FILE *fp)
5298 + {
5299 + int i;
5300 +@@ -327,6 +359,8 @@ static void read_symtabs(FILE *fp)
5301 + static void read_relocs(FILE *fp)
5302 + {
5303 + int i,j;
5304 ++ uint32_t base;
5305 ++
5306 + for(i = 0; i < ehdr.e_shnum; i++) {
5307 + if (shdr[i].sh_type != SHT_REL) {
5308 + continue;
5309 +@@ -344,8 +378,17 @@ static void read_relocs(FILE *fp)
5310 + die("Cannot read symbol table: %s\n",
5311 + strerror(errno));
5312 + }
5313 ++ base = 0;
5314 ++ for (j = 0; j < ehdr.e_phnum; j++) {
5315 ++ if (phdr[j].p_type != PT_LOAD )
5316 ++ continue;
5317 ++ 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)
5318 ++ continue;
5319 ++ base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr;
5320 ++ break;
5321 ++ }
5322 + for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) {
5323 +- reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset);
5324 ++ reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset) + base;
5325 + reltab[i][j].r_info = elf32_to_cpu(reltab[i][j].r_info);
5326 + }
5327 + }
5328 +@@ -482,6 +525,23 @@ static void walk_relocs(void (*visit)(El
5329 + if (sym->st_shndx == SHN_ABS) {
5330 + continue;
5331 + }
5332 ++ /* Don't relocate actual per-cpu variables, they are absolute indices, not addresses */
5333 ++ if (!strcmp(sec_name(sym->st_shndx), ".data.percpu") && strncmp(sym_name(sym_strtab, sym), "__per_cpu_", 10))
5334 ++ continue;
5335 ++#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32)
5336 ++ /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */
5337 ++ if (!strcmp(sec_name(sym->st_shndx), ".init.text"))
5338 ++ continue;
5339 ++ if (!strcmp(sec_name(sym->st_shndx), ".exit.text"))
5340 ++ continue;
5341 ++ if (!strcmp(sec_name(sym->st_shndx), ".text.head")) {
5342 ++ if (strcmp(sym_name(sym_strtab, sym), "__init_end") &&
5343 ++ strcmp(sym_name(sym_strtab, sym), "KERNEL_TEXT_OFFSET"))
5344 ++ continue;
5345 ++ }
5346 ++ if (!strcmp(sec_name(sym->st_shndx), ".text"))
5347 ++ continue;
5348 ++#endif
5349 + if (r_type == R_386_PC32) {
5350 + /* PC relative relocations don't need to be adjusted */
5351 + }
5352 +@@ -609,6 +669,7 @@ int main(int argc, char **argv)
5353 + fname, strerror(errno));
5354 + }
5355 + read_ehdr(fp);
5356 ++ read_phdrs(fp);
5357 + read_shdrs(fp);
5358 + read_strtabs(fp);
5359 + read_symtabs(fp);
5360 +diff -urNp linux-2.6.26.6/arch/x86/boot/cpucheck.c linux-2.6.26.6/arch/x86/boot/cpucheck.c
5361 +--- linux-2.6.26.6/arch/x86/boot/cpucheck.c 2008-10-08 23:24:05.000000000 -0400
5362 ++++ linux-2.6.26.6/arch/x86/boot/cpucheck.c 2008-10-11 21:54:19.000000000 -0400
5363 +@@ -76,7 +76,7 @@ static int has_fpu(void)
5364 + u16 fcw = -1, fsw = -1;
5365 + u32 cr0;
5366 +
5367 +- asm("movl %%cr0,%0" : "=r" (cr0));
5368 ++ asm volatile("movl %%cr0,%0" : "=r" (cr0));
5369 + if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
5370 + cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
5371 + asm volatile("movl %0,%%cr0" : : "r" (cr0));
5372 +@@ -92,7 +92,7 @@ static int has_eflag(u32 mask)
5373 + {
5374 + u32 f0, f1;
5375 +
5376 +- asm("pushfl ; "
5377 ++ asm volatile("pushfl ; "
5378 + "pushfl ; "
5379 + "popl %0 ; "
5380 + "movl %0,%1 ; "
5381 +@@ -117,7 +117,7 @@ static void get_flags(void)
5382 + set_bit(X86_FEATURE_FPU, cpu.flags);
5383 +
5384 + if (has_eflag(X86_EFLAGS_ID)) {
5385 +- asm("cpuid"
5386 ++ asm volatile("cpuid"
5387 + : "=a" (max_intel_level),
5388 + "=b" (cpu_vendor[0]),
5389 + "=d" (cpu_vendor[1]),
5390 +@@ -126,7 +126,7 @@ static void get_flags(void)
5391 +
5392 + if (max_intel_level >= 0x00000001 &&
5393 + max_intel_level <= 0x0000ffff) {
5394 +- asm("cpuid"
5395 ++ asm volatile("cpuid"
5396 + : "=a" (tfms),
5397 + "=c" (cpu.flags[4]),
5398 + "=d" (cpu.flags[0])
5399 +@@ -138,7 +138,7 @@ static void get_flags(void)
5400 + cpu.model += ((tfms >> 16) & 0xf) << 4;
5401 + }
5402 +
5403 +- asm("cpuid"
5404 ++ asm volatile("cpuid"
5405 + : "=a" (max_amd_level)
5406 + : "a" (0x80000000)
5407 + : "ebx", "ecx", "edx");
5408 +@@ -146,7 +146,7 @@ static void get_flags(void)
5409 + if (max_amd_level >= 0x80000001 &&
5410 + max_amd_level <= 0x8000ffff) {
5411 + u32 eax = 0x80000001;
5412 +- asm("cpuid"
5413 ++ asm volatile("cpuid"
5414 + : "+a" (eax),
5415 + "=c" (cpu.flags[6]),
5416 + "=d" (cpu.flags[1])
5417 +@@ -205,9 +205,9 @@ int check_cpu(int *cpu_level_ptr, int *r
5418 + u32 ecx = MSR_K7_HWCR;
5419 + u32 eax, edx;
5420 +
5421 +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
5422 ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
5423 + eax &= ~(1 << 15);
5424 +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
5425 ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
5426 +
5427 + get_flags(); /* Make sure it really did something */
5428 + err = check_flags();
5429 +@@ -220,9 +220,9 @@ int check_cpu(int *cpu_level_ptr, int *r
5430 + u32 ecx = MSR_VIA_FCR;
5431 + u32 eax, edx;
5432 +
5433 +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
5434 ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
5435 + eax |= (1<<1)|(1<<7);
5436 +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
5437 ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
5438 +
5439 + set_bit(X86_FEATURE_CX8, cpu.flags);
5440 + err = check_flags();
5441 +@@ -233,12 +233,12 @@ int check_cpu(int *cpu_level_ptr, int *r
5442 + u32 eax, edx;
5443 + u32 level = 1;
5444 +
5445 +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
5446 +- asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
5447 +- asm("cpuid"
5448 ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
5449 ++ asm volatile("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
5450 ++ asm volatile("cpuid"
5451 + : "+a" (level), "=d" (cpu.flags[0])
5452 + : : "ecx", "ebx");
5453 +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
5454 ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
5455 +
5456 + err = check_flags();
5457 + }
5458 +diff -urNp linux-2.6.26.6/arch/x86/boot/edd.c linux-2.6.26.6/arch/x86/boot/edd.c
5459 +--- linux-2.6.26.6/arch/x86/boot/edd.c 2008-10-08 23:24:05.000000000 -0400
5460 ++++ linux-2.6.26.6/arch/x86/boot/edd.c 2008-10-11 21:54:19.000000000 -0400
5461 +@@ -76,7 +76,7 @@ static int get_edd_info(u8 devno, struct
5462 + ax = 0x4100;
5463 + bx = EDDMAGIC1;
5464 + dx = devno;
5465 +- asm("pushfl; stc; int $0x13; setc %%al; popfl"
5466 ++ asm volatile("pushfl; stc; int $0x13; setc %%al; popfl"
5467 + : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
5468 + : : "esi", "edi");
5469 +
5470 +@@ -95,7 +95,7 @@ static int get_edd_info(u8 devno, struct
5471 + ei->params.length = sizeof(ei->params);
5472 + ax = 0x4800;
5473 + dx = devno;
5474 +- asm("pushfl; int $0x13; popfl"
5475 ++ asm volatile("pushfl; int $0x13; popfl"
5476 + : "+a" (ax), "+d" (dx), "=m" (ei->params)
5477 + : "S" (&ei->params)
5478 + : "ebx", "ecx", "edi");
5479 +@@ -106,7 +106,7 @@ static int get_edd_info(u8 devno, struct
5480 + ax = 0x0800;
5481 + dx = devno;
5482 + di = 0;
5483 +- asm("pushw %%es; "
5484 ++ asm volatile("pushw %%es; "
5485 + "movw %%di,%%es; "
5486 + "pushfl; stc; int $0x13; setc %%al; popfl; "
5487 + "popw %%es"
5488 +diff -urNp linux-2.6.26.6/arch/x86/boot/main.c linux-2.6.26.6/arch/x86/boot/main.c
5489 +--- linux-2.6.26.6/arch/x86/boot/main.c 2008-10-08 23:24:05.000000000 -0400
5490 ++++ linux-2.6.26.6/arch/x86/boot/main.c 2008-10-11 21:54:19.000000000 -0400
5491 +@@ -77,7 +77,7 @@ static void query_ist(void)
5492 + if (cpu.level < 6)
5493 + return;
5494 +
5495 +- asm("int $0x15"
5496 ++ asm volatile("int $0x15"
5497 + : "=a" (boot_params.ist_info.signature),
5498 + "=b" (boot_params.ist_info.command),
5499 + "=c" (boot_params.ist_info.event),
5500 +diff -urNp linux-2.6.26.6/arch/x86/boot/mca.c linux-2.6.26.6/arch/x86/boot/mca.c
5501 +--- linux-2.6.26.6/arch/x86/boot/mca.c 2008-10-08 23:24:05.000000000 -0400
5502 ++++ linux-2.6.26.6/arch/x86/boot/mca.c 2008-10-11 21:54:19.000000000 -0400
5503 +@@ -19,7 +19,7 @@ int query_mca(void)
5504 + u8 err;
5505 + u16 es, bx, len;
5506 +
5507 +- asm("pushw %%es ; "
5508 ++ asm volatile("pushw %%es ; "
5509 + "int $0x15 ; "
5510 + "setc %0 ; "
5511 + "movw %%es, %1 ; "
5512 +diff -urNp linux-2.6.26.6/arch/x86/boot/memory.c linux-2.6.26.6/arch/x86/boot/memory.c
5513 +--- linux-2.6.26.6/arch/x86/boot/memory.c 2008-10-08 23:24:05.000000000 -0400
5514 ++++ linux-2.6.26.6/arch/x86/boot/memory.c 2008-10-11 21:54:19.000000000 -0400
5515 +@@ -30,7 +30,7 @@ static int detect_memory_e820(void)
5516 + /* Important: %edx is clobbered by some BIOSes,
5517 + so it must be either used for the error output
5518 + or explicitly marked clobbered. */
5519 +- asm("int $0x15; setc %0"
5520 ++ asm volatile("int $0x15; setc %0"
5521 + : "=d" (err), "+b" (next), "=a" (id), "+c" (size),
5522 + "=m" (*desc)
5523 + : "D" (desc), "d" (SMAP), "a" (0xe820));
5524 +@@ -65,7 +65,7 @@ static int detect_memory_e801(void)
5525 +
5526 + bx = cx = dx = 0;
5527 + ax = 0xe801;
5528 +- asm("stc; int $0x15; setc %0"
5529 ++ asm volatile("stc; int $0x15; setc %0"
5530 + : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
5531 +
5532 + if (err)
5533 +@@ -95,7 +95,7 @@ static int detect_memory_88(void)
5534 + u8 err;
5535 +
5536 + ax = 0x8800;
5537 +- asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
5538 ++ asm volatile("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
5539 +
5540 + boot_params.screen_info.ext_mem_k = ax;
5541 +
5542 +diff -urNp linux-2.6.26.6/arch/x86/boot/video.c linux-2.6.26.6/arch/x86/boot/video.c
5543 +--- linux-2.6.26.6/arch/x86/boot/video.c 2008-10-08 23:24:05.000000000 -0400
5544 ++++ linux-2.6.26.6/arch/x86/boot/video.c 2008-10-11 21:54:19.000000000 -0400
5545 +@@ -23,7 +23,7 @@ static void store_cursor_position(void)
5546 +
5547 + ax = 0x0300;
5548 + bx = 0;
5549 +- asm(INT10
5550 ++ asm volatile(INT10
5551 + : "=d" (curpos), "+a" (ax), "+b" (bx)
5552 + : : "ecx", "esi", "edi");
5553 +
5554 +@@ -38,7 +38,7 @@ static void store_video_mode(void)
5555 + /* N.B.: the saving of the video page here is a bit silly,
5556 + since we pretty much assume page 0 everywhere. */
5557 + ax = 0x0f00;
5558 +- asm(INT10
5559 ++ asm volatile(INT10
5560 + : "+a" (ax), "=b" (page)
5561 + : : "ecx", "edx", "esi", "edi");
5562 +
5563 +diff -urNp linux-2.6.26.6/arch/x86/boot/video-vesa.c linux-2.6.26.6/arch/x86/boot/video-vesa.c
5564 +--- linux-2.6.26.6/arch/x86/boot/video-vesa.c 2008-10-08 23:24:05.000000000 -0400
5565 ++++ linux-2.6.26.6/arch/x86/boot/video-vesa.c 2008-10-11 21:54:19.000000000 -0400
5566 +@@ -41,7 +41,7 @@ static int vesa_probe(void)
5567 +
5568 + ax = 0x4f00;
5569 + di = (size_t)&vginfo;
5570 +- asm(INT10
5571 ++ asm volatile(INT10
5572 + : "+a" (ax), "+D" (di), "=m" (vginfo)
5573 + : : "ebx", "ecx", "edx", "esi");
5574 +
5575 +@@ -68,7 +68,7 @@ static int vesa_probe(void)
5576 + ax = 0x4f01;
5577 + cx = mode;
5578 + di = (size_t)&vminfo;
5579 +- asm(INT10
5580 ++ asm volatile(INT10
5581 + : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
5582 + : : "ebx", "edx", "esi");
5583 +
5584 +@@ -123,7 +123,7 @@ static int vesa_set_mode(struct mode_inf
5585 + ax = 0x4f01;
5586 + cx = vesa_mode;
5587 + di = (size_t)&vminfo;
5588 +- asm(INT10
5589 ++ asm volatile(INT10
5590 + : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
5591 + : : "ebx", "edx", "esi");
5592 +
5593 +@@ -203,19 +203,20 @@ static void vesa_dac_set_8bits(void)
5594 + /* Save the VESA protected mode info */
5595 + static void vesa_store_pm_info(void)
5596 + {
5597 +- u16 ax, bx, di, es;
5598 ++ u16 ax, bx, cx, di, es;
5599 +
5600 + ax = 0x4f0a;
5601 +- bx = di = 0;
5602 +- asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
5603 +- : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
5604 +- : : "ecx", "esi");
5605 ++ bx = cx = di = 0;
5606 ++ asm volatile("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
5607 ++ : "=d" (es), "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di)
5608 ++ : : "esi");
5609 +
5610 + if (ax != 0x004f)
5611 + return;
5612 +
5613 + boot_params.screen_info.vesapm_seg = es;
5614 + boot_params.screen_info.vesapm_off = di;
5615 ++ boot_params.screen_info.vesapm_size = cx;
5616 + }
5617 +
5618 + /*
5619 +@@ -269,7 +270,7 @@ void vesa_store_edid(void)
5620 + /* Note: The VBE DDC spec is different from the main VESA spec;
5621 + we genuinely have to assume all registers are destroyed here. */
5622 +
5623 +- asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
5624 ++ asm volatile("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
5625 + : "+a" (ax), "+b" (bx)
5626 + : "c" (cx), "D" (di)
5627 + : "esi");
5628 +@@ -285,7 +286,7 @@ void vesa_store_edid(void)
5629 + cx = 0; /* Controller 0 */
5630 + dx = 0; /* EDID block number */
5631 + di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
5632 +- asm(INT10
5633 ++ asm volatile(INT10
5634 + : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info)
5635 + : "c" (cx), "D" (di)
5636 + : "esi");
5637 +diff -urNp linux-2.6.26.6/arch/x86/boot/video-vga.c linux-2.6.26.6/arch/x86/boot/video-vga.c
5638 +--- linux-2.6.26.6/arch/x86/boot/video-vga.c 2008-10-08 23:24:05.000000000 -0400
5639 ++++ linux-2.6.26.6/arch/x86/boot/video-vga.c 2008-10-11 21:54:19.000000000 -0400
5640 +@@ -225,7 +225,7 @@ static int vga_probe(void)
5641 + };
5642 + u8 vga_flag;
5643 +
5644 +- asm(INT10
5645 ++ asm volatile(INT10
5646 + : "=b" (ega_bx)
5647 + : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
5648 + : "ecx", "edx", "esi", "edi");
5649 +@@ -237,7 +237,7 @@ static int vga_probe(void)
5650 + /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
5651 + if ((u8)ega_bx != 0x10) {
5652 + /* EGA/VGA */
5653 +- asm(INT10
5654 ++ asm volatile(INT10
5655 + : "=a" (vga_flag)
5656 + : "a" (0x1a00)
5657 + : "ebx", "ecx", "edx", "esi", "edi");
5658 +diff -urNp linux-2.6.26.6/arch/x86/boot/voyager.c linux-2.6.26.6/arch/x86/boot/voyager.c
5659 +--- linux-2.6.26.6/arch/x86/boot/voyager.c 2008-10-08 23:24:05.000000000 -0400
5660 ++++ linux-2.6.26.6/arch/x86/boot/voyager.c 2008-10-11 21:54:19.000000000 -0400
5661 +@@ -23,7 +23,7 @@ int query_voyager(void)
5662 +
5663 + data_ptr[0] = 0xff; /* Flag on config not found(?) */
5664 +
5665 +- asm("pushw %%es ; "
5666 ++ asm volatile("pushw %%es ; "
5667 + "int $0x15 ; "
5668 + "setc %0 ; "
5669 + "movw %%es, %1 ; "
5670 +diff -urNp linux-2.6.26.6/arch/x86/ia32/ia32_signal.c linux-2.6.26.6/arch/x86/ia32/ia32_signal.c
5671 +--- linux-2.6.26.6/arch/x86/ia32/ia32_signal.c 2008-10-08 23:24:05.000000000 -0400
5672 ++++ linux-2.6.26.6/arch/x86/ia32/ia32_signal.c 2008-10-11 21:54:19.000000000 -0400
5673 +@@ -531,6 +531,7 @@ int ia32_setup_rt_frame(int sig, struct
5674 + __NR_ia32_rt_sigreturn,
5675 + 0x80cd,
5676 + 0,
5677 ++ 0
5678 + };
5679 +
5680 + frame = get_sigframe(ka, regs, sizeof(*frame));
5681 +diff -urNp linux-2.6.26.6/arch/x86/Kconfig linux-2.6.26.6/arch/x86/Kconfig
5682 +--- linux-2.6.26.6/arch/x86/Kconfig 2008-10-08 23:24:05.000000000 -0400
5683 ++++ linux-2.6.26.6/arch/x86/Kconfig 2008-10-11 21:54:19.000000000 -0400
5684 +@@ -887,7 +887,7 @@ config PAGE_OFFSET
5685 + hex
5686 + default 0xB0000000 if VMSPLIT_3G_OPT
5687 + default 0x80000000 if VMSPLIT_2G
5688 +- default 0x78000000 if VMSPLIT_2G_OPT
5689 ++ default 0x70000000 if VMSPLIT_2G_OPT
5690 + default 0x40000000 if VMSPLIT_1G
5691 + default 0xC0000000
5692 + depends on X86_32
5693 +@@ -1206,8 +1206,7 @@ config CRASH_DUMP
5694 + config PHYSICAL_START
5695 + hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
5696 + default "0x1000000" if X86_NUMAQ
5697 +- default "0x200000" if X86_64
5698 +- default "0x100000"
5699 ++ default "0x200000"
5700 + help
5701 + This gives the physical address where the kernel is loaded.
5702 +
5703 +@@ -1299,9 +1298,9 @@ config HOTPLUG_CPU
5704 + suspend.
5705 +
5706 + config COMPAT_VDSO
5707 +- def_bool y
5708 ++ def_bool n
5709 + prompt "Compat VDSO support"
5710 +- depends on X86_32 || IA32_EMULATION
5711 ++ depends on (X86_32 || IA32_EMULATION) && !PAX_NOEXEC
5712 + help
5713 + Map the 32-bit VDSO to the predictable old-style address too.
5714 + ---help---
5715 +@@ -1488,7 +1487,7 @@ config PCI
5716 + choice
5717 + prompt "PCI access mode"
5718 + depends on X86_32 && PCI && !X86_VISWS
5719 +- default PCI_GOANY
5720 ++ default PCI_GODIRECT
5721 + ---help---
5722 + On PCI systems, the BIOS can be used to detect the PCI devices and
5723 + determine their configuration. However, some old PCI motherboards
5724 +diff -urNp linux-2.6.26.6/arch/x86/Kconfig.cpu linux-2.6.26.6/arch/x86/Kconfig.cpu
5725 +--- linux-2.6.26.6/arch/x86/Kconfig.cpu 2008-10-08 23:24:05.000000000 -0400
5726 ++++ linux-2.6.26.6/arch/x86/Kconfig.cpu 2008-10-11 21:54:19.000000000 -0400
5727 +@@ -340,7 +340,7 @@ config X86_PPRO_FENCE
5728 +
5729 + config X86_F00F_BUG
5730 + def_bool y
5731 +- depends on M586MMX || M586TSC || M586 || M486 || M386
5732 ++ depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
5733 +
5734 + config X86_WP_WORKS_OK
5735 + def_bool y
5736 +@@ -360,7 +360,7 @@ config X86_POPAD_OK
5737 +
5738 + config X86_ALIGNMENT_16
5739 + def_bool y
5740 +- depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
5741 ++ depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MCORE2 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
5742 +
5743 + config X86_GOOD_APIC
5744 + def_bool y
5745 +@@ -403,7 +403,7 @@ config X86_TSC
5746 + # generates cmov.
5747 + config X86_CMOV
5748 + def_bool y
5749 +- depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || X86_64)
5750 ++ depends on (MK8 || MK7 || MCORE2 || MPSC || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || X86_64)
5751 +
5752 + config X86_MINIMUM_CPU_FAMILY
5753 + int
5754 +diff -urNp linux-2.6.26.6/arch/x86/Kconfig.debug linux-2.6.26.6/arch/x86/Kconfig.debug
5755 +--- linux-2.6.26.6/arch/x86/Kconfig.debug 2008-10-08 23:24:05.000000000 -0400
5756 ++++ linux-2.6.26.6/arch/x86/Kconfig.debug 2008-10-11 21:54:19.000000000 -0400
5757 +@@ -84,7 +84,7 @@ config X86_PTDUMP
5758 + config DEBUG_RODATA
5759 + bool "Write protect kernel read-only data structures"
5760 + default y
5761 +- depends on DEBUG_KERNEL
5762 ++ depends on DEBUG_KERNEL && BROKEN
5763 + help
5764 + Mark the kernel read-only data as write-protected in the pagetables,
5765 + in order to catch accidental (and incorrect) writes to such const
5766 +diff -urNp linux-2.6.26.6/arch/x86/kernel/acpi/boot.c linux-2.6.26.6/arch/x86/kernel/acpi/boot.c
5767 +--- linux-2.6.26.6/arch/x86/kernel/acpi/boot.c 2008-10-08 23:24:05.000000000 -0400
5768 ++++ linux-2.6.26.6/arch/x86/kernel/acpi/boot.c 2008-10-11 21:54:19.000000000 -0400
5769 +@@ -1227,7 +1227,7 @@ static struct dmi_system_id __initdata a
5770 + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
5771 + },
5772 + },
5773 +- {}
5774 ++ { NULL, NULL, {{0, NULL}}, NULL}
5775 + };
5776 +
5777 + #endif /* __i386__ */
5778 +diff -urNp linux-2.6.26.6/arch/x86/kernel/acpi/realmode/wakeup.S linux-2.6.26.6/arch/x86/kernel/acpi/realmode/wakeup.S
5779 +--- linux-2.6.26.6/arch/x86/kernel/acpi/realmode/wakeup.S 2008-10-08 23:24:05.000000000 -0400
5780 ++++ linux-2.6.26.6/arch/x86/kernel/acpi/realmode/wakeup.S 2008-10-11 21:54:19.000000000 -0400
5781 +@@ -104,7 +104,7 @@ _start:
5782 + movl %eax, %ecx
5783 + orl %edx, %ecx
5784 + jz 1f
5785 +- movl $0xc0000080, %ecx
5786 ++ mov $MSR_EFER, %ecx
5787 + wrmsr
5788 + 1:
5789 +
5790 +diff -urNp linux-2.6.26.6/arch/x86/kernel/acpi/wakeup_32.S linux-2.6.26.6/arch/x86/kernel/acpi/wakeup_32.S
5791 +--- linux-2.6.26.6/arch/x86/kernel/acpi/wakeup_32.S 2008-10-08 23:24:05.000000000 -0400
5792 ++++ linux-2.6.26.6/arch/x86/kernel/acpi/wakeup_32.S 2008-10-11 21:54:19.000000000 -0400
5793 +@@ -30,13 +30,11 @@ wakeup_pmode_return:
5794 + # and restore the stack ... but you need gdt for this to work
5795 + movl saved_context_esp, %esp
5796 +
5797 +- movl %cs:saved_magic, %eax
5798 +- cmpl $0x12345678, %eax
5799 ++ cmpl $0x12345678, saved_magic
5800 + jne bogus_magic
5801 +
5802 + # jump to place where we left off
5803 +- movl saved_eip, %eax
5804 +- jmp *%eax
5805 ++ jmp *(saved_eip)
5806 +
5807 + bogus_magic:
5808 + jmp bogus_magic
5809 +diff -urNp linux-2.6.26.6/arch/x86/kernel/alternative.c linux-2.6.26.6/arch/x86/kernel/alternative.c
5810 +--- linux-2.6.26.6/arch/x86/kernel/alternative.c 2008-10-08 23:24:05.000000000 -0400
5811 ++++ linux-2.6.26.6/arch/x86/kernel/alternative.c 2008-10-11 22:15:25.000000000 -0400
5812 +@@ -403,7 +403,7 @@ void apply_paravirt(struct paravirt_patc
5813 +
5814 + BUG_ON(p->len > MAX_PATCH_LEN);
5815 + /* prep the buffer with the original instructions */
5816 +- memcpy(insnbuf, p->instr, p->len);
5817 ++ memcpy(insnbuf, ktla_ktva(p->instr), p->len);
5818 + used = pv_init_ops.patch(p->instrtype, p->clobbers, insnbuf,
5819 + (unsigned long)p->instr, p->len);
5820 +
5821 +@@ -483,11 +483,26 @@ void __init alternative_instructions(voi
5822 + * instructions. And on the local CPU you need to be protected again NMI or MCE
5823 + * handlers seeing an inconsistent instruction while you patch.
5824 + */
5825 +-void *text_poke_early(void *addr, const void *opcode, size_t len)
5826 ++void *__kprobes text_poke_early(void *addr, const void *opcode, size_t len)
5827 + {
5828 + unsigned long flags;
5829 ++
5830 ++#ifdef CONFIG_PAX_KERNEXEC
5831 ++ unsigned long cr0;
5832 ++#endif
5833 ++
5834 + local_irq_save(flags);
5835 +- memcpy(addr, opcode, len);
5836 ++
5837 ++#ifdef CONFIG_PAX_KERNEXEC
5838 ++ pax_open_kernel(cr0);
5839 ++#endif
5840 ++
5841 ++ memcpy(ktla_ktva(addr), opcode, len);
5842 ++
5843 ++#ifdef CONFIG_PAX_KERNEXEC
5844 ++ pax_close_kernel(cr0);
5845 ++#endif
5846 ++
5847 + local_irq_restore(flags);
5848 + sync_core();
5849 + /* Could also do a CLFLUSH here to speed up CPU recovery; but
5850 +@@ -508,33 +523,27 @@ void *text_poke_early(void *addr, const
5851 + */
5852 + void *__kprobes text_poke(void *addr, const void *opcode, size_t len)
5853 + {
5854 +- unsigned long flags;
5855 +- char *vaddr;
5856 +- int nr_pages = 2;
5857 ++ unsigned char *vaddr = ktla_ktva(addr);
5858 + struct page *pages[2];
5859 +- int i;
5860 ++ size_t i;
5861 ++
5862 ++ if (!core_kernel_text((unsigned long)addr)
5863 +
5864 +- if (!core_kernel_text((unsigned long)addr)) {
5865 +- pages[0] = vmalloc_to_page(addr);
5866 +- pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
5867 ++#if defined(CONFIG_X86_32) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
5868 ++ && (vaddr < MODULES_VADDR || MODULES_END < vaddr)
5869 ++#endif
5870 ++
5871 ++ ) {
5872 ++ pages[0] = vmalloc_to_page(vaddr);
5873 ++ pages[1] = vmalloc_to_page(vaddr + PAGE_SIZE);
5874 + } else {
5875 +- pages[0] = virt_to_page(addr);
5876 ++ pages[0] = virt_to_page(vaddr);
5877 + WARN_ON(!PageReserved(pages[0]));
5878 +- pages[1] = virt_to_page(addr + PAGE_SIZE);
5879 ++ pages[1] = virt_to_page(vaddr + PAGE_SIZE);
5880 + }
5881 + BUG_ON(!pages[0]);
5882 +- if (!pages[1])
5883 +- nr_pages = 1;
5884 +- vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL);
5885 +- BUG_ON(!vaddr);
5886 +- local_irq_save(flags);
5887 +- memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len);
5888 +- local_irq_restore(flags);
5889 +- vunmap(vaddr);
5890 +- sync_core();
5891 +- /* Could also do a CLFLUSH here to speed up CPU recovery; but
5892 +- that causes hangs on some VIA CPUs. */
5893 ++ text_poke_early(addr, opcode, len);
5894 + for (i = 0; i < len; i++)
5895 +- BUG_ON(((char *)addr)[i] != ((char *)opcode)[i]);
5896 ++ BUG_ON((vaddr)[i] != ((unsigned char *)opcode)[i]);
5897 + return addr;
5898 + }
5899 +diff -urNp linux-2.6.26.6/arch/x86/kernel/apm_32.c linux-2.6.26.6/arch/x86/kernel/apm_32.c
5900 +--- linux-2.6.26.6/arch/x86/kernel/apm_32.c 2008-10-08 23:24:05.000000000 -0400
5901 ++++ linux-2.6.26.6/arch/x86/kernel/apm_32.c 2008-10-11 21:54:19.000000000 -0400
5902 +@@ -406,7 +406,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitq
5903 + static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
5904 + static struct apm_user *user_list;
5905 + static DEFINE_SPINLOCK(user_list_lock);
5906 +-static const struct desc_struct bad_bios_desc = { { { 0, 0x00409200 } } };
5907 ++static const struct desc_struct bad_bios_desc = { { { 0, 0x00409300 } } };
5908 +
5909 + static const char driver_version[] = "1.16ac"; /* no spaces */
5910 +
5911 +@@ -601,19 +601,42 @@ static u8 apm_bios_call(u32 func, u32 eb
5912 + struct desc_struct save_desc_40;
5913 + struct desc_struct *gdt;
5914 +
5915 ++#ifdef CONFIG_PAX_KERNEXEC
5916 ++ unsigned long cr0;
5917 ++#endif
5918 ++
5919 + cpus = apm_save_cpus();
5920 +
5921 + cpu = get_cpu();
5922 + gdt = get_cpu_gdt_table(cpu);
5923 + save_desc_40 = gdt[0x40 / 8];
5924 ++
5925 ++#ifdef CONFIG_PAX_KERNEXEC
5926 ++ pax_open_kernel(cr0);
5927 ++#endif
5928 ++
5929 + gdt[0x40 / 8] = bad_bios_desc;
5930 +
5931 ++#ifdef CONFIG_PAX_KERNEXEC
5932 ++ pax_close_kernel(cr0);
5933 ++#endif
5934 ++
5935 + apm_irq_save(flags);
5936 + APM_DO_SAVE_SEGS;
5937 + apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
5938 + APM_DO_RESTORE_SEGS;
5939 + apm_irq_restore(flags);
5940 ++
5941 ++#ifdef CONFIG_PAX_KERNEXEC
5942 ++ pax_open_kernel(cr0);
5943 ++#endif
5944 ++
5945 + gdt[0x40 / 8] = save_desc_40;
5946 ++
5947 ++#ifdef CONFIG_PAX_KERNEXEC
5948 ++ pax_close_kernel(cr0);
5949 ++#endif
5950 ++
5951 + put_cpu();
5952 + apm_restore_cpus(cpus);
5953 +
5954 +@@ -644,19 +667,42 @@ static u8 apm_bios_call_simple(u32 func,
5955 + struct desc_struct save_desc_40;
5956 + struct desc_struct *gdt;
5957 +
5958 ++#ifdef CONFIG_PAX_KERNEXEC
5959 ++ unsigned long cr0;
5960 ++#endif
5961 ++
5962 + cpus = apm_save_cpus();
5963 +
5964 + cpu = get_cpu();
5965 + gdt = get_cpu_gdt_table(cpu);
5966 + save_desc_40 = gdt[0x40 / 8];
5967 ++
5968 ++#ifdef CONFIG_PAX_KERNEXEC
5969 ++ pax_open_kernel(cr0);
5970 ++#endif
5971 ++
5972 + gdt[0x40 / 8] = bad_bios_desc;
5973 +
5974 ++#ifdef CONFIG_PAX_KERNEXEC
5975 ++ pax_close_kernel(cr0);
5976 ++#endif
5977 ++
5978 + apm_irq_save(flags);
5979 + APM_DO_SAVE_SEGS;
5980 + error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
5981 + APM_DO_RESTORE_SEGS;
5982 + apm_irq_restore(flags);
5983 ++
5984 ++#ifdef CONFIG_PAX_KERNEXEC
5985 ++ pax_open_kernel(cr0);
5986 ++#endif
5987 ++
5988 + gdt[0x40 / 8] = save_desc_40;
5989 ++
5990 ++#ifdef CONFIG_PAX_KERNEXEC
5991 ++ pax_close_kernel(cr0);
5992 ++#endif
5993 ++
5994 + put_cpu();
5995 + apm_restore_cpus(cpus);
5996 + return error;
5997 +@@ -928,7 +974,7 @@ recalc:
5998 +
5999 + static void apm_power_off(void)
6000 + {
6001 +- unsigned char po_bios_call[] = {
6002 ++ const unsigned char po_bios_call[] = {
6003 + 0xb8, 0x00, 0x10, /* movw $0x1000,ax */
6004 + 0x8e, 0xd0, /* movw ax,ss */
6005 + 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */
6006 +@@ -1868,7 +1914,10 @@ static const struct file_operations apm_
6007 + static struct miscdevice apm_device = {
6008 + APM_MINOR_DEV,
6009 + "apm_bios",
6010 +- &apm_bios_fops
6011 ++ &apm_bios_fops,
6012 ++ {NULL, NULL},
6013 ++ NULL,
6014 ++ NULL
6015 + };
6016 +
6017 +
6018 +@@ -2189,7 +2238,7 @@ static struct dmi_system_id __initdata a
6019 + { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
6020 + },
6021 +
6022 +- { }
6023 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
6024 + };
6025 +
6026 + /*
6027 +@@ -2207,6 +2256,10 @@ static int __init apm_init(void)
6028 + struct desc_struct *gdt;
6029 + int err;
6030 +
6031 ++#ifdef CONFIG_PAX_KERNEXEC
6032 ++ unsigned long cr0;
6033 ++#endif
6034 ++
6035 + dmi_check_system(apm_dmi_table);
6036 +
6037 + if (apm_info.bios.version == 0 || paravirt_enabled()) {
6038 +@@ -2280,9 +2333,18 @@ static int __init apm_init(void)
6039 + * This is for buggy BIOS's that refer to (real mode) segment 0x40
6040 + * even though they are called in protected mode.
6041 + */
6042 ++
6043 ++#ifdef CONFIG_PAX_KERNEXEC
6044 ++ pax_open_kernel(cr0);
6045 ++#endif
6046 ++
6047 + set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
6048 + _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
6049 +
6050 ++#ifdef CONFIG_PAX_KERNEXEC
6051 ++ pax_close_kernel(cr0);
6052 ++#endif
6053 ++
6054 + /*
6055 + * Set up the long jump entry point to the APM BIOS, which is called
6056 + * from inline assembly.
6057 +@@ -2301,6 +2363,11 @@ static int __init apm_init(void)
6058 + * code to that CPU.
6059 + */
6060 + gdt = get_cpu_gdt_table(0);
6061 ++
6062 ++#ifdef CONFIG_PAX_KERNEXEC
6063 ++ pax_open_kernel(cr0);
6064 ++#endif
6065 ++
6066 + set_base(gdt[APM_CS >> 3],
6067 + __va((unsigned long)apm_info.bios.cseg << 4));
6068 + set_base(gdt[APM_CS_16 >> 3],
6069 +@@ -2308,6 +2375,10 @@ static int __init apm_init(void)
6070 + set_base(gdt[APM_DS >> 3],
6071 + __va((unsigned long)apm_info.bios.dseg << 4));
6072 +
6073 ++#ifdef CONFIG_PAX_KERNEXEC
6074 ++ pax_close_kernel(cr0);
6075 ++#endif
6076 ++
6077 + proc_create("apm", 0, NULL, &apm_file_ops);
6078 +
6079 + kapmd_task = kthread_create(apm, NULL, "kapmd");
6080 +diff -urNp linux-2.6.26.6/arch/x86/kernel/asm-offsets_32.c linux-2.6.26.6/arch/x86/kernel/asm-offsets_32.c
6081 +--- linux-2.6.26.6/arch/x86/kernel/asm-offsets_32.c 2008-10-08 23:24:05.000000000 -0400
6082 ++++ linux-2.6.26.6/arch/x86/kernel/asm-offsets_32.c 2008-10-11 21:54:19.000000000 -0400
6083 +@@ -100,6 +100,7 @@ void foo(void)
6084 + DEFINE(PTRS_PER_PTE, PTRS_PER_PTE);
6085 + DEFINE(PTRS_PER_PMD, PTRS_PER_PMD);
6086 + DEFINE(PTRS_PER_PGD, PTRS_PER_PGD);
6087 ++ DEFINE(PERCPU_MODULE_RESERVE, PERCPU_MODULE_RESERVE);
6088 +
6089 + OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
6090 +
6091 +@@ -113,6 +114,7 @@ void foo(void)
6092 + OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
6093 + OFFSET(PV_CPU_irq_enable_syscall_ret, pv_cpu_ops, irq_enable_syscall_ret);
6094 + OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
6095 ++ OFFSET(PV_CPU_write_cr0, pv_cpu_ops, write_cr0);
6096 + #endif
6097 +
6098 + #ifdef CONFIG_XEN
6099 +diff -urNp linux-2.6.26.6/arch/x86/kernel/asm-offsets_64.c linux-2.6.26.6/arch/x86/kernel/asm-offsets_64.c
6100 +--- linux-2.6.26.6/arch/x86/kernel/asm-offsets_64.c 2008-10-08 23:24:05.000000000 -0400
6101 ++++ linux-2.6.26.6/arch/x86/kernel/asm-offsets_64.c 2008-10-11 21:54:19.000000000 -0400
6102 +@@ -117,6 +117,7 @@ int main(void)
6103 + ENTRY(cr8);
6104 + BLANK();
6105 + #undef ENTRY
6106 ++ DEFINE(TSS_size, sizeof(struct tss_struct));
6107 + DEFINE(TSS_ist, offsetof(struct tss_struct, x86_tss.ist));
6108 + BLANK();
6109 + DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
6110 +diff -urNp linux-2.6.26.6/arch/x86/kernel/cpu/common.c linux-2.6.26.6/arch/x86/kernel/cpu/common.c
6111 +--- linux-2.6.26.6/arch/x86/kernel/cpu/common.c 2008-10-08 23:24:05.000000000 -0400
6112 ++++ linux-2.6.26.6/arch/x86/kernel/cpu/common.c 2008-10-11 21:54:19.000000000 -0400
6113 +@@ -4,7 +4,6 @@
6114 + #include <linux/smp.h>
6115 + #include <linux/module.h>
6116 + #include <linux/percpu.h>
6117 +-#include <linux/bootmem.h>
6118 + #include <asm/processor.h>
6119 + #include <asm/i387.h>
6120 + #include <asm/msr.h>
6121 +@@ -21,42 +20,6 @@
6122 +
6123 + #include "cpu.h"
6124 +
6125 +-DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
6126 +- [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } },
6127 +- [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } },
6128 +- [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } },
6129 +- [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } },
6130 +- /*
6131 +- * Segments used for calling PnP BIOS have byte granularity.
6132 +- * They code segments and data segments have fixed 64k limits,
6133 +- * the transfer segment sizes are set at run time.
6134 +- */
6135 +- /* 32-bit code */
6136 +- [GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } },
6137 +- /* 16-bit code */
6138 +- [GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } },
6139 +- /* 16-bit data */
6140 +- [GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } },
6141 +- /* 16-bit data */
6142 +- [GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } },
6143 +- /* 16-bit data */
6144 +- [GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } },
6145 +- /*
6146 +- * The APM segments have byte granularity and their bases
6147 +- * are set at run time. All have 64k limits.
6148 +- */
6149 +- /* 32-bit code */
6150 +- [GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } },
6151 +- /* 16-bit code */
6152 +- [GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } },
6153 +- /* data */
6154 +- [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } },
6155 +-
6156 +- [GDT_ENTRY_ESPFIX_SS] = { { { 0x00000000, 0x00c09200 } } },
6157 +- [GDT_ENTRY_PERCPU] = { { { 0x00000000, 0x00000000 } } },
6158 +-} };
6159 +-EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
6160 +-
6161 + __u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
6162 +
6163 + static int cachesize_override __cpuinitdata = -1;
6164 +@@ -479,6 +442,10 @@ void __cpuinit identify_cpu(struct cpuin
6165 + * we do "generic changes."
6166 + */
6167 +
6168 ++#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
6169 ++ setup_clear_cpu_cap(X86_FEATURE_SEP);
6170 ++#endif
6171 ++
6172 + /* If the model name is still unset, do table lookup. */
6173 + if (!c->x86_model_id[0]) {
6174 + char *p;
6175 +@@ -615,7 +582,7 @@ static __init int setup_disablecpuid(cha
6176 + }
6177 + __setup("clearcpuid=", setup_disablecpuid);
6178 +
6179 +-cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
6180 ++cpumask_t cpu_initialized = CPU_MASK_NONE;
6181 +
6182 + void __init early_cpu_init(void)
6183 + {
6184 +@@ -644,7 +611,7 @@ void switch_to_new_gdt(void)
6185 + {
6186 + struct desc_ptr gdt_descr;
6187 +
6188 +- gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
6189 ++ gdt_descr.address = (unsigned long)get_cpu_gdt_table(smp_processor_id());
6190 + gdt_descr.size = GDT_SIZE - 1;
6191 + load_gdt(&gdt_descr);
6192 + asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory");
6193 +@@ -660,7 +627,7 @@ void __cpuinit cpu_init(void)
6194 + {
6195 + int cpu = smp_processor_id();
6196 + struct task_struct *curr = current;
6197 +- struct tss_struct *t = &per_cpu(init_tss, cpu);
6198 ++ struct tss_struct *t = init_tss + cpu;
6199 + struct thread_struct *thread = &curr->thread;
6200 +
6201 + if (cpu_test_and_set(cpu, cpu_initialized)) {
6202 +@@ -715,7 +682,7 @@ void __cpuinit cpu_init(void)
6203 + }
6204 +
6205 + #ifdef CONFIG_HOTPLUG_CPU
6206 +-void __cpuinit cpu_uninit(void)
6207 ++void cpu_uninit(void)
6208 + {
6209 + int cpu = raw_smp_processor_id();
6210 + cpu_clear(cpu, cpu_initialized);
6211 +diff -urNp linux-2.6.26.6/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c linux-2.6.26.6/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
6212 +--- linux-2.6.26.6/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-10-08 23:24:05.000000000 -0400
6213 ++++ linux-2.6.26.6/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-10-11 21:54:19.000000000 -0400
6214 +@@ -560,7 +560,7 @@ static const struct dmi_system_id sw_any
6215 + DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
6216 + },
6217 + },
6218 +- { }
6219 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
6220 + };
6221 + #endif
6222 +
6223 +diff -urNp linux-2.6.26.6/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c linux-2.6.26.6/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
6224 +--- linux-2.6.26.6/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2008-10-08 23:24:05.000000000 -0400
6225 ++++ linux-2.6.26.6/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2008-10-11 21:54:19.000000000 -0400
6226 +@@ -223,7 +223,7 @@ static struct cpu_model models[] =
6227 + { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
6228 + { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
6229 +
6230 +- { NULL, }
6231 ++ { NULL, NULL, 0, NULL}
6232 + };
6233 + #undef _BANIAS
6234 + #undef BANIAS
6235 +diff -urNp linux-2.6.26.6/arch/x86/kernel/cpu/intel.c linux-2.6.26.6/arch/x86/kernel/cpu/intel.c
6236 +--- linux-2.6.26.6/arch/x86/kernel/cpu/intel.c 2008-10-08 23:24:05.000000000 -0400
6237 ++++ linux-2.6.26.6/arch/x86/kernel/cpu/intel.c 2008-10-11 21:54:19.000000000 -0400
6238 +@@ -107,7 +107,7 @@ static void __cpuinit trap_init_f00f_bug
6239 + * Update the IDT descriptor and reload the IDT so that
6240 + * it uses the read-only mapped virtual address.
6241 + */
6242 +- idt_descr.address = fix_to_virt(FIX_F00F_IDT);
6243 ++ idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
6244 + load_idt(&idt_descr);
6245 + }
6246 + #endif
6247 +diff -urNp linux-2.6.26.6/arch/x86/kernel/cpu/mcheck/mce_64.c linux-2.6.26.6/arch/x86/kernel/cpu/mcheck/mce_64.c
6248 +--- linux-2.6.26.6/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-10-08 23:24:05.000000000 -0400
6249 ++++ linux-2.6.26.6/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-10-11 21:54:19.000000000 -0400
6250 +@@ -672,6 +672,7 @@ static struct miscdevice mce_log_device
6251 + MISC_MCELOG_MINOR,
6252 + "mcelog",
6253 + &mce_chrdev_ops,
6254 ++ {NULL, NULL}, NULL, NULL
6255 + };
6256 +
6257 + static unsigned long old_cr4 __initdata;
6258 +diff -urNp linux-2.6.26.6/arch/x86/kernel/cpu/mtrr/generic.c linux-2.6.26.6/arch/x86/kernel/cpu/mtrr/generic.c
6259 +--- linux-2.6.26.6/arch/x86/kernel/cpu/mtrr/generic.c 2008-10-08 23:24:05.000000000 -0400
6260 ++++ linux-2.6.26.6/arch/x86/kernel/cpu/mtrr/generic.c 2008-10-11 21:55:52.000000000 -0400
6261 +@@ -31,11 +31,11 @@ static struct fixed_range_block fixed_ra
6262 + { MTRRfix64K_00000_MSR, 1 }, /* one 64k MTRR */
6263 + { MTRRfix16K_80000_MSR, 2 }, /* two 16k MTRRs */
6264 + { MTRRfix4K_C0000_MSR, 8 }, /* eight 4k MTRRs */
6265 +- {}
6266 ++ { 0, 0 }
6267 + };
6268 +
6269 + static unsigned long smp_changes_mask;
6270 +-static struct mtrr_state mtrr_state = {};
6271 ++static struct mtrr_state mtrr_state;
6272 + static int mtrr_state_set;
6273 + static u64 tom2;
6274 +
6275 +@@ -213,7 +213,7 @@ void __init get_mtrr_state(void)
6276 + mtrr_state.enabled = (lo & 0xc00) >> 10;
6277 +
6278 + if (amd_special_default_mtrr()) {
6279 +- unsigned lo, hi;
6280 ++ unsigned hi;
6281 + /* TOP_MEM2 */
6282 + rdmsr(MSR_K8_TOP_MEM2, lo, hi);
6283 + tom2 = hi;
6284 +diff -urNp linux-2.6.26.6/arch/x86/kernel/crash.c linux-2.6.26.6/arch/x86/kernel/crash.c
6285 +--- linux-2.6.26.6/arch/x86/kernel/crash.c 2008-10-08 23:24:05.000000000 -0400
6286 ++++ linux-2.6.26.6/arch/x86/kernel/crash.c 2008-10-11 21:54:19.000000000 -0400
6287 +@@ -59,7 +59,7 @@ static int crash_nmi_callback(struct not
6288 + local_irq_disable();
6289 +
6290 + #ifdef CONFIG_X86_32
6291 +- if (!user_mode_vm(regs)) {
6292 ++ if (!user_mode(regs)) {
6293 + crash_fixup_ss_esp(&fixed_regs, regs);
6294 + regs = &fixed_regs;
6295 + }
6296 +diff -urNp linux-2.6.26.6/arch/x86/kernel/doublefault_32.c linux-2.6.26.6/arch/x86/kernel/doublefault_32.c
6297 +--- linux-2.6.26.6/arch/x86/kernel/doublefault_32.c 2008-10-08 23:24:05.000000000 -0400
6298 ++++ linux-2.6.26.6/arch/x86/kernel/doublefault_32.c 2008-10-11 21:54:19.000000000 -0400
6299 +@@ -11,7 +11,7 @@
6300 +
6301 + #define DOUBLEFAULT_STACKSIZE (1024)
6302 + static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
6303 +-#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
6304 ++#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
6305 +
6306 + #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
6307 +
6308 +@@ -21,7 +21,7 @@ static void doublefault_fn(void)
6309 + unsigned long gdt, tss;
6310 +
6311 + store_gdt(&gdt_desc);
6312 +- gdt = gdt_desc.address;
6313 ++ gdt = (unsigned long)gdt_desc.address;
6314 +
6315 + printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
6316 +
6317 +@@ -60,10 +60,10 @@ struct tss_struct doublefault_tss __cach
6318 + /* 0x2 bit is always set */
6319 + .flags = X86_EFLAGS_SF | 0x2,
6320 + .sp = STACK_START,
6321 +- .es = __USER_DS,
6322 ++ .es = __KERNEL_DS,
6323 + .cs = __KERNEL_CS,
6324 + .ss = __KERNEL_DS,
6325 +- .ds = __USER_DS,
6326 ++ .ds = __KERNEL_DS,
6327 + .fs = __KERNEL_PERCPU,
6328 +
6329 + .__cr3 = __pa(swapper_pg_dir)
6330 +diff -urNp linux-2.6.26.6/arch/x86/kernel/efi_32.c linux-2.6.26.6/arch/x86/kernel/efi_32.c
6331 +--- linux-2.6.26.6/arch/x86/kernel/efi_32.c 2008-10-08 23:24:05.000000000 -0400
6332 ++++ linux-2.6.26.6/arch/x86/kernel/efi_32.c 2008-10-11 21:54:19.000000000 -0400
6333 +@@ -38,70 +38,37 @@
6334 + */
6335 +
6336 + static unsigned long efi_rt_eflags;
6337 +-static pgd_t efi_bak_pg_dir_pointer[2];
6338 ++static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS] __attribute__ ((aligned (4096)));
6339 +
6340 +-void efi_call_phys_prelog(void)
6341 ++void __init efi_call_phys_prelog(void)
6342 + {
6343 +- unsigned long cr4;
6344 +- unsigned long temp;
6345 + struct desc_ptr gdt_descr;
6346 +
6347 + local_irq_save(efi_rt_eflags);
6348 +
6349 +- /*
6350 +- * If I don't have PAE, I should just duplicate two entries in page
6351 +- * directory. If I have PAE, I just need to duplicate one entry in
6352 +- * page directory.
6353 +- */
6354 +- cr4 = read_cr4();
6355 +-
6356 +- if (cr4 & X86_CR4_PAE) {
6357 +- efi_bak_pg_dir_pointer[0].pgd =
6358 +- swapper_pg_dir[pgd_index(0)].pgd;
6359 +- swapper_pg_dir[0].pgd =
6360 +- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
6361 +- } else {
6362 +- efi_bak_pg_dir_pointer[0].pgd =
6363 +- swapper_pg_dir[pgd_index(0)].pgd;
6364 +- efi_bak_pg_dir_pointer[1].pgd =
6365 +- swapper_pg_dir[pgd_index(0x400000)].pgd;
6366 +- swapper_pg_dir[pgd_index(0)].pgd =
6367 +- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
6368 +- temp = PAGE_OFFSET + 0x400000;
6369 +- swapper_pg_dir[pgd_index(0x400000)].pgd =
6370 +- swapper_pg_dir[pgd_index(temp)].pgd;
6371 +- }
6372 ++ clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
6373 ++ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
6374 ++ min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
6375 +
6376 + /*
6377 + * After the lock is released, the original page table is restored.
6378 + */
6379 + __flush_tlb_all();
6380 +
6381 +- gdt_descr.address = __pa(get_cpu_gdt_table(0));
6382 ++ gdt_descr.address = (struct desc_struct *)__pa(get_cpu_gdt_table(0));
6383 + gdt_descr.size = GDT_SIZE - 1;
6384 + load_gdt(&gdt_descr);
6385 + }
6386 +
6387 +-void efi_call_phys_epilog(void)
6388 ++void __init efi_call_phys_epilog(void)
6389 + {
6390 +- unsigned long cr4;
6391 + struct desc_ptr gdt_descr;
6392 +
6393 +- gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
6394 ++ gdt_descr.address = get_cpu_gdt_table(0);
6395 + gdt_descr.size = GDT_SIZE - 1;
6396 + load_gdt(&gdt_descr);
6397 +
6398 +- cr4 = read_cr4();
6399 +-
6400 +- if (cr4 & X86_CR4_PAE) {
6401 +- swapper_pg_dir[pgd_index(0)].pgd =
6402 +- efi_bak_pg_dir_pointer[0].pgd;
6403 +- } else {
6404 +- swapper_pg_dir[pgd_index(0)].pgd =
6405 +- efi_bak_pg_dir_pointer[0].pgd;
6406 +- swapper_pg_dir[pgd_index(0x400000)].pgd =
6407 +- efi_bak_pg_dir_pointer[1].pgd;
6408 +- }
6409 ++ clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
6410 +
6411 + /*
6412 + * After the lock is released, the original page table is restored.
6413 +diff -urNp linux-2.6.26.6/arch/x86/kernel/efi_stub_32.S linux-2.6.26.6/arch/x86/kernel/efi_stub_32.S
6414 +--- linux-2.6.26.6/arch/x86/kernel/efi_stub_32.S 2008-10-08 23:24:05.000000000 -0400
6415 ++++ linux-2.6.26.6/arch/x86/kernel/efi_stub_32.S 2008-10-11 21:54:19.000000000 -0400
6416 +@@ -6,6 +6,7 @@
6417 + */
6418 +
6419 + #include <linux/linkage.h>
6420 ++#include <linux/init.h>
6421 + #include <asm/page.h>
6422 +
6423 + /*
6424 +@@ -20,7 +21,7 @@
6425 + * service functions will comply with gcc calling convention, too.
6426 + */
6427 +
6428 +-.text
6429 ++__INIT
6430 + ENTRY(efi_call_phys)
6431 + /*
6432 + * 0. The function can only be called in Linux kernel. So CS has been
6433 +@@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
6434 + * The mapping of lower virtual memory has been created in prelog and
6435 + * epilog.
6436 + */
6437 +- movl $1f, %edx
6438 +- subl $__PAGE_OFFSET, %edx
6439 +- jmp *%edx
6440 ++ jmp 1f-__PAGE_OFFSET
6441 + 1:
6442 +
6443 + /*
6444 +@@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
6445 + * parameter 2, ..., param n. To make things easy, we save the return
6446 + * address of efi_call_phys in a global variable.
6447 + */
6448 +- popl %edx
6449 +- movl %edx, saved_return_addr
6450 +- /* get the function pointer into ECX*/
6451 +- popl %ecx
6452 +- movl %ecx, efi_rt_function_ptr
6453 +- movl $2f, %edx
6454 +- subl $__PAGE_OFFSET, %edx
6455 +- pushl %edx
6456 ++ popl (saved_return_addr)
6457 ++ popl (efi_rt_function_ptr)
6458 +
6459 + /*
6460 + * 3. Clear PG bit in %CR0.
6461 +@@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
6462 + /*
6463 + * 5. Call the physical function.
6464 + */
6465 +- jmp *%ecx
6466 ++ call *(efi_rt_function_ptr-__PAGE_OFFSET)
6467 +
6468 +-2:
6469 + /*
6470 + * 6. After EFI runtime service returns, control will return to
6471 + * following instruction. We'd better readjust stack pointer first.
6472 +@@ -88,34 +80,27 @@ ENTRY(efi_call_phys)
6473 + movl %cr0, %edx
6474 + orl $0x80000000, %edx
6475 + movl %edx, %cr0
6476 +- jmp 1f
6477 +-1:
6478 ++
6479 + /*
6480 + * 8. Now restore the virtual mode from flat mode by
6481 + * adding EIP with PAGE_OFFSET.
6482 + */
6483 +- movl $1f, %edx
6484 +- jmp *%edx
6485 ++ jmp 1f+__PAGE_OFFSET
6486 + 1:
6487 +
6488 + /*
6489 + * 9. Balance the stack. And because EAX contain the return value,
6490 + * we'd better not clobber it.
6491 + */
6492 +- leal efi_rt_function_ptr, %edx
6493 +- movl (%edx), %ecx
6494 +- pushl %ecx
6495 ++ pushl (efi_rt_function_ptr)
6496 +
6497 + /*
6498 +- * 10. Push the saved return address onto the stack and return.
6499 ++ * 10. Return to the saved return address.
6500 + */
6501 +- leal saved_return_addr, %edx
6502 +- movl (%edx), %ecx
6503 +- pushl %ecx
6504 +- ret
6505 ++ jmpl *(saved_return_addr)
6506 + .previous
6507 +
6508 +-.data
6509 ++__INITDATA
6510 + saved_return_addr:
6511 + .long 0
6512 + efi_rt_function_ptr:
6513 +diff -urNp linux-2.6.26.6/arch/x86/kernel/entry_32.S linux-2.6.26.6/arch/x86/kernel/entry_32.S
6514 +--- linux-2.6.26.6/arch/x86/kernel/entry_32.S 2008-10-08 23:24:05.000000000 -0400
6515 ++++ linux-2.6.26.6/arch/x86/kernel/entry_32.S 2008-10-11 21:54:19.000000000 -0400
6516 +@@ -90,7 +90,7 @@
6517 + #define resume_userspace_sig resume_userspace
6518 + #endif
6519 +
6520 +-#define SAVE_ALL \
6521 ++#define __SAVE_ALL(_DS) \
6522 + cld; \
6523 + pushl %fs; \
6524 + CFI_ADJUST_CFA_OFFSET 4;\
6525 +@@ -122,12 +122,26 @@
6526 + pushl %ebx; \
6527 + CFI_ADJUST_CFA_OFFSET 4;\
6528 + CFI_REL_OFFSET ebx, 0;\
6529 +- movl $(__USER_DS), %edx; \
6530 ++ movl $(_DS), %edx; \
6531 + movl %edx, %ds; \
6532 + movl %edx, %es; \
6533 + movl $(__KERNEL_PERCPU), %edx; \
6534 + movl %edx, %fs
6535 +
6536 ++#ifdef CONFIG_PAX_KERNEXEC
6537 ++#define SAVE_ALL \
6538 ++ __SAVE_ALL(__KERNEL_DS); \
6539 ++ GET_CR0_INTO_EDX; \
6540 ++ movl %edx, %esi; \
6541 ++ orl $X86_CR0_WP, %edx; \
6542 ++ xorl %edx, %esi; \
6543 ++ SET_CR0_FROM_EDX
6544 ++#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
6545 ++#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
6546 ++#else
6547 ++#define SAVE_ALL __SAVE_ALL(__USER_DS)
6548 ++#endif
6549 ++
6550 + #define RESTORE_INT_REGS \
6551 + popl %ebx; \
6552 + CFI_ADJUST_CFA_OFFSET -4;\
6553 +@@ -218,6 +232,11 @@ ENTRY(ret_from_fork)
6554 + CFI_ADJUST_CFA_OFFSET 4
6555 + popfl
6556 + CFI_ADJUST_CFA_OFFSET -4
6557 ++
6558 ++#ifdef CONFIG_PAX_KERNEXEC
6559 ++ xorl %esi, %esi
6560 ++#endif
6561 ++
6562 + jmp syscall_exit
6563 + CFI_ENDPROC
6564 + END(ret_from_fork)
6565 +@@ -241,7 +260,17 @@ check_userspace:
6566 + movb PT_CS(%esp), %al
6567 + andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax
6568 + cmpl $USER_RPL, %eax
6569 ++
6570 ++#ifdef CONFIG_PAX_KERNEXEC
6571 ++ jae resume_userspace
6572 ++
6573 ++ GET_CR0_INTO_EDX
6574 ++ xorl %esi, %edx
6575 ++ SET_CR0_FROM_EDX
6576 ++ jmp resume_kernel
6577 ++#else
6578 + jb resume_kernel # not returning to v8086 or userspace
6579 ++#endif
6580 +
6581 + ENTRY(resume_userspace)
6582 + LOCKDEP_SYS_EXIT
6583 +@@ -303,10 +332,9 @@ sysenter_past_esp:
6584 + /*CFI_REL_OFFSET cs, 0*/
6585 + /*
6586 + * Push current_thread_info()->sysenter_return to the stack.
6587 +- * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
6588 +- * pushed above; +8 corresponds to copy_thread's esp0 setting.
6589 + */
6590 +- pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
6591 ++ GET_THREAD_INFO(%ebp)
6592 ++ pushl TI_sysenter_return(%ebp)
6593 + CFI_ADJUST_CFA_OFFSET 4
6594 + CFI_REL_OFFSET eip, 0
6595 +
6596 +@@ -319,9 +347,17 @@ sysenter_past_esp:
6597 + * Load the potential sixth argument from user stack.
6598 + * Careful about security.
6599 + */
6600 ++ movl PT_OLDESP(%esp),%ebp
6601 ++
6602 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
6603 ++ mov PT_OLDSS(%esp),%ds
6604 ++1: movl %ds:(%ebp),%ebp
6605 ++#else
6606 + cmpl $__PAGE_OFFSET-3,%ebp
6607 + jae syscall_fault
6608 + 1: movl (%ebp),%ebp
6609 ++#endif
6610 ++
6611 + movl %ebp,PT_EBP(%esp)
6612 + .section __ex_table,"a"
6613 + .align 4
6614 +@@ -343,20 +379,37 @@ sysenter_past_esp:
6615 + movl TI_flags(%ebp), %ecx
6616 + testw $_TIF_ALLWORK_MASK, %cx
6617 + jne syscall_exit_work
6618 ++
6619 ++#ifdef CONFIG_PAX_RANDKSTACK
6620 ++ pushl %eax
6621 ++ CFI_ADJUST_CFA_OFFSET 4
6622 ++ call pax_randomize_kstack
6623 ++ popl %eax
6624 ++ CFI_ADJUST_CFA_OFFSET -4
6625 ++#endif
6626 ++
6627 + /* if something modifies registers it must also disable sysexit */
6628 + movl PT_EIP(%esp), %edx
6629 + movl PT_OLDESP(%esp), %ecx
6630 + xorl %ebp,%ebp
6631 + TRACE_IRQS_ON
6632 + 1: mov PT_FS(%esp), %fs
6633 ++2: mov PT_DS(%esp), %ds
6634 ++3: mov PT_ES(%esp), %es
6635 + ENABLE_INTERRUPTS_SYSCALL_RET
6636 + CFI_ENDPROC
6637 + .pushsection .fixup,"ax"
6638 +-2: movl $0,PT_FS(%esp)
6639 ++4: movl $0,PT_FS(%esp)
6640 ++ jmp 1b
6641 ++5: movl $0,PT_DS(%esp)
6642 ++ jmp 1b
6643 ++6: movl $0,PT_ES(%esp)
6644 + jmp 1b
6645 + .section __ex_table,"a"
6646 + .align 4
6647 +- .long 1b,2b
6648 ++ .long 1b,4b
6649 ++ .long 2b,5b
6650 ++ .long 3b,6b
6651 + .popsection
6652 + ENDPROC(ia32_sysenter_target)
6653 +
6654 +@@ -390,6 +443,10 @@ no_singlestep:
6655 + testw $_TIF_ALLWORK_MASK, %cx # current->work
6656 + jne syscall_exit_work
6657 +
6658 ++#ifdef CONFIG_PAX_RANDKSTACK
6659 ++ call pax_randomize_kstack
6660 ++#endif
6661 ++
6662 + restore_all:
6663 + movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
6664 + # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
6665 +@@ -483,25 +540,19 @@ work_resched:
6666 +
6667 + work_notifysig: # deal with pending signals and
6668 + # notify-resume requests
6669 ++ movl %esp, %eax
6670 + #ifdef CONFIG_VM86
6671 + testl $X86_EFLAGS_VM, PT_EFLAGS(%esp)
6672 +- movl %esp, %eax
6673 +- jne work_notifysig_v86 # returning to kernel-space or
6674 ++ jz 1f # returning to kernel-space or
6675 + # vm86-space
6676 +- xorl %edx, %edx
6677 +- call do_notify_resume
6678 +- jmp resume_userspace_sig
6679 +
6680 +- ALIGN
6681 +-work_notifysig_v86:
6682 + pushl %ecx # save ti_flags for do_notify_resume
6683 + CFI_ADJUST_CFA_OFFSET 4
6684 + call save_v86_state # %eax contains pt_regs pointer
6685 + popl %ecx
6686 + CFI_ADJUST_CFA_OFFSET -4
6687 + movl %eax, %esp
6688 +-#else
6689 +- movl %esp, %eax
6690 ++1:
6691 + #endif
6692 + xorl %edx, %edx
6693 + call do_notify_resume
6694 +@@ -552,17 +603,24 @@ syscall_badsys:
6695 + END(syscall_badsys)
6696 + CFI_ENDPROC
6697 +
6698 +-#define FIXUP_ESPFIX_STACK \
6699 +- /* since we are on a wrong stack, we cant make it a C code :( */ \
6700 +- PER_CPU(gdt_page, %ebx); \
6701 +- GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \
6702 +- addl %esp, %eax; \
6703 +- pushl $__KERNEL_DS; \
6704 +- CFI_ADJUST_CFA_OFFSET 4; \
6705 +- pushl %eax; \
6706 +- CFI_ADJUST_CFA_OFFSET 4; \
6707 +- lss (%esp), %esp; \
6708 ++.macro FIXUP_ESPFIX_STACK
6709 ++ /* since we are on a wrong stack, we cant make it a C code :( */
6710 ++#ifdef CONFIG_SMP
6711 ++ movl PER_CPU_VAR(cpu_number), %ebx;
6712 ++ shll $PAGE_SHIFT_asm, %ebx;
6713 ++ addl $cpu_gdt_table, %ebx;
6714 ++#else
6715 ++ movl $cpu_gdt_table, %ebx;
6716 ++#endif
6717 ++ GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah);
6718 ++ addl %esp, %eax;
6719 ++ pushl $__KERNEL_DS;
6720 ++ CFI_ADJUST_CFA_OFFSET 4;
6721 ++ pushl %eax;
6722 ++ CFI_ADJUST_CFA_OFFSET 4;
6723 ++ lss (%esp), %esp;
6724 + CFI_ADJUST_CFA_OFFSET -8;
6725 ++.endm
6726 + #define UNWIND_ESPFIX_STACK \
6727 + movl %ss, %eax; \
6728 + /* see if on espfix stack */ \
6729 +@@ -579,7 +637,7 @@ END(syscall_badsys)
6730 + * Build the entry stubs and pointer table with
6731 + * some assembler magic.
6732 + */
6733 +-.section .rodata,"a"
6734 ++.section .rodata,"a",@progbits
6735 + ENTRY(interrupt)
6736 + .text
6737 +
6738 +@@ -679,12 +737,21 @@ error_code:
6739 + popl %ecx
6740 + CFI_ADJUST_CFA_OFFSET -4
6741 + /*CFI_REGISTER es, ecx*/
6742 ++
6743 ++#ifdef CONFIG_PAX_KERNEXEC
6744 ++ GET_CR0_INTO_EDX
6745 ++ movl %edx, %esi
6746 ++ orl $X86_CR0_WP, %edx
6747 ++ xorl %edx, %esi
6748 ++ SET_CR0_FROM_EDX
6749 ++#endif
6750 ++
6751 + movl PT_FS(%esp), %edi # get the function address
6752 + movl PT_ORIG_EAX(%esp), %edx # get the error code
6753 + movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
6754 + mov %ecx, PT_FS(%esp)
6755 + /*CFI_REL_OFFSET fs, ES*/
6756 +- movl $(__USER_DS), %ecx
6757 ++ movl $(__KERNEL_DS), %ecx
6758 + movl %ecx, %ds
6759 + movl %ecx, %es
6760 + movl %esp,%eax # pt_regs pointer
6761 +@@ -818,6 +885,13 @@ nmi_stack_correct:
6762 + xorl %edx,%edx # zero error code
6763 + movl %esp,%eax # pt_regs pointer
6764 + call do_nmi
6765 ++
6766 ++#ifdef CONFIG_PAX_KERNEXEC
6767 ++ GET_CR0_INTO_EDX
6768 ++ xorl %esi, %edx
6769 ++ SET_CR0_FROM_EDX
6770 ++#endif
6771 ++
6772 + jmp restore_nocheck_notrace
6773 + CFI_ENDPROC
6774 +
6775 +@@ -858,6 +932,13 @@ nmi_espfix_stack:
6776 + FIXUP_ESPFIX_STACK # %eax == %esp
6777 + xorl %edx,%edx # zero error code
6778 + call do_nmi
6779 ++
6780 ++#ifdef CONFIG_PAX_KERNEXEC
6781 ++ GET_CR0_INTO_EDX
6782 ++ xorl %esi, %edx
6783 ++ SET_CR0_FROM_EDX
6784 ++#endif
6785 ++
6786 + RESTORE_REGS
6787 + lss 12+4(%esp), %esp # back to espfix stack
6788 + CFI_ADJUST_CFA_OFFSET -24
6789 +@@ -1110,7 +1191,6 @@ ENDPROC(xen_failsafe_callback)
6790 +
6791 + #endif /* CONFIG_XEN */
6792 +
6793 +-.section .rodata,"a"
6794 + #include "syscall_table_32.S"
6795 +
6796 + syscall_table_size=(.-sys_call_table)
6797 +diff -urNp linux-2.6.26.6/arch/x86/kernel/entry_64.S linux-2.6.26.6/arch/x86/kernel/entry_64.S
6798 +--- linux-2.6.26.6/arch/x86/kernel/entry_64.S 2008-10-08 23:24:05.000000000 -0400
6799 ++++ linux-2.6.26.6/arch/x86/kernel/entry_64.S 2008-10-11 21:54:19.000000000 -0400
6800 +@@ -767,17 +767,18 @@ END(spurious_interrupt)
6801 + xorl %ebx,%ebx
6802 + 1:
6803 + .if \ist
6804 +- movq %gs:pda_data_offset, %rbp
6805 ++ imul $TSS_size, %gs:pda_cpunumber, %ebp
6806 ++ lea init_tss(%rbp), %rbp
6807 + .endif
6808 + movq %rsp,%rdi
6809 + movq ORIG_RAX(%rsp),%rsi
6810 + movq $-1,ORIG_RAX(%rsp)
6811 + .if \ist
6812 +- subq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
6813 ++ subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
6814 + .endif
6815 + call \sym
6816 + .if \ist
6817 +- addq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
6818 ++ addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
6819 + .endif
6820 + DISABLE_INTERRUPTS(CLBR_NONE)
6821 + .if \irqtrace
6822 +diff -urNp linux-2.6.26.6/arch/x86/kernel/head_32.S linux-2.6.26.6/arch/x86/kernel/head_32.S
6823 +--- linux-2.6.26.6/arch/x86/kernel/head_32.S 2008-10-08 23:24:05.000000000 -0400
6824 ++++ linux-2.6.26.6/arch/x86/kernel/head_32.S 2008-10-11 21:55:07.000000000 -0400
6825 +@@ -19,6 +19,7 @@
6826 + #include <asm/asm-offsets.h>
6827 + #include <asm/setup.h>
6828 + #include <asm/processor-flags.h>
6829 ++#include <asm/msr-index.h>
6830 +
6831 + /* Physical address */
6832 + #define pa(X) ((X) - __PAGE_OFFSET)
6833 +@@ -64,17 +65,22 @@ LOW_PAGES = 1<<(32-PAGE_SHIFT_asm)
6834 + LOW_PAGES = LOW_PAGES + 0x1000000
6835 + #endif
6836 +
6837 +-#if PTRS_PER_PMD > 1
6838 +-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD
6839 +-#else
6840 +-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD)
6841 +-#endif
6842 ++PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PTE)
6843 + BOOTBITMAP_SIZE = LOW_PAGES / 8
6844 + ALLOCATOR_SLOP = 4
6845 +
6846 + INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
6847 +
6848 + /*
6849 ++ * Real beginning of normal "text" segment
6850 ++ */
6851 ++ENTRY(stext)
6852 ++ENTRY(_stext)
6853 ++
6854 ++.section .text.startup,"ax",@progbits
6855 ++ ljmp $(__BOOT_CS),$phys_startup_32
6856 ++
6857 ++/*
6858 + * 32-bit kernel entrypoint; only used by the boot CPU. On entry,
6859 + * %esi points to the real-mode code as a 32-bit pointer.
6860 + * CS and DS must be 4 GB flat segments, but we don't depend on
6861 +@@ -82,6 +88,12 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE +
6862 + * can.
6863 + */
6864 + .section .text.head,"ax",@progbits
6865 ++
6866 ++#ifdef CONFIG_PAX_KERNEXEC
6867 ++/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
6868 ++.fill 4096,1,0xcc
6869 ++#endif
6870 ++
6871 + ENTRY(startup_32)
6872 + /* test KEEP_SEGMENTS flag to see if the bootloader is asking
6873 + us to not reload segments */
6874 +@@ -99,6 +111,56 @@ ENTRY(startup_32)
6875 + movl %eax,%gs
6876 + 2:
6877 +
6878 ++ movl $pa(cpu_gdt_table),%edi
6879 ++ movl $__per_cpu_start,%eax
6880 ++ movw %ax,__KERNEL_PERCPU + 2(%edi)
6881 ++ rorl $16,%eax
6882 ++ movb %al,__KERNEL_PERCPU + 4(%edi)
6883 ++ movb %ah,__KERNEL_PERCPU + 7(%edi)
6884 ++ movl $__per_cpu_end + PERCPU_MODULE_RESERVE - 1,%eax
6885 ++ subl $__per_cpu_start,%eax
6886 ++ movw %ax,__KERNEL_PERCPU + 0(%edi)
6887 ++
6888 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
6889 ++ /* check for VMware */
6890 ++ movl $0x564d5868,%eax
6891 ++ xorl %ebx,%ebx
6892 ++ movl $0xa,%ecx
6893 ++ movl $0x5658,%edx
6894 ++ in (%dx),%eax
6895 ++ cmpl $0x564d5868,%ebx
6896 ++ jz 2f
6897 ++
6898 ++ movl $NR_CPUS,%ecx
6899 ++ movl $pa(cpu_gdt_table),%edi
6900 ++1:
6901 ++ movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),GDT_ENTRY_KERNEL_DS * 8 + 4(%edi)
6902 ++ addl $PAGE_SIZE_asm,%edi
6903 ++ loop 1b
6904 ++2:
6905 ++#endif
6906 ++
6907 ++#ifdef CONFIG_PAX_KERNEXEC
6908 ++ movl $pa(boot_gdt),%edi
6909 ++ movl $KERNEL_TEXT_OFFSET,%eax
6910 ++ movw %ax,__BOOT_CS + 2(%edi)
6911 ++ rorl $16,%eax
6912 ++ movb %al,__BOOT_CS + 4(%edi)
6913 ++ movb %ah,__BOOT_CS + 7(%edi)
6914 ++ rorl $16,%eax
6915 ++
6916 ++ movl $NR_CPUS,%ecx
6917 ++ movl $pa(cpu_gdt_table),%edi
6918 ++1:
6919 ++ movw %ax,__KERNEL_CS + 2(%edi)
6920 ++ rorl $16,%eax
6921 ++ movb %al,__KERNEL_CS + 4(%edi)
6922 ++ movb %ah,__KERNEL_CS + 7(%edi)
6923 ++ rorl $16,%eax
6924 ++ addl $PAGE_SIZE_asm,%edi
6925 ++ loop 1b
6926 ++#endif
6927 ++
6928 + /*
6929 + * Clear BSS first so that there are no surprises...
6930 + */
6931 +@@ -142,9 +204,7 @@ ENTRY(startup_32)
6932 + cmpl $num_subarch_entries, %eax
6933 + jae bad_subarch
6934 +
6935 +- movl pa(subarch_entries)(,%eax,4), %eax
6936 +- subl $__PAGE_OFFSET, %eax
6937 +- jmp *%eax
6938 ++ jmp *pa(subarch_entries)(,%eax,4)
6939 +
6940 + bad_subarch:
6941 + WEAK(lguest_entry)
6942 +@@ -156,9 +216,9 @@ WEAK(xen_entry)
6943 + __INITDATA
6944 +
6945 + subarch_entries:
6946 +- .long default_entry /* normal x86/PC */
6947 +- .long lguest_entry /* lguest hypervisor */
6948 +- .long xen_entry /* Xen hypervisor */
6949 ++ .long pa(default_entry) /* normal x86/PC */
6950 ++ .long pa(lguest_entry) /* lguest hypervisor */
6951 ++ .long pa(xen_entry) /* Xen hypervisor */
6952 + num_subarch_entries = (. - subarch_entries) / 4
6953 + .previous
6954 + #endif /* CONFIG_PARAVIRT */
6955 +@@ -172,7 +232,7 @@ num_subarch_entries = (. - subarch_entri
6956 + *
6957 + * Note that the stack is not yet set up!
6958 + */
6959 +-#define PTE_ATTR 0x007 /* PRESENT+RW+USER */
6960 ++#define PTE_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
6961 + #define PDE_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
6962 + #define PGD_ATTR 0x001 /* PRESENT (no other attributes) */
6963 +
6964 +@@ -221,8 +281,7 @@ default_entry:
6965 + movl %edi,pa(init_pg_tables_end)
6966 +
6967 + /* Do early initialization of the fixmap area */
6968 +- movl $pa(swapper_pg_fixmap)+PDE_ATTR,%eax
6969 +- movl %eax,pa(swapper_pg_pmd+0x1000*KPMDS-8)
6970 ++ movl $pa(swapper_pg_fixmap)+PDE_ATTR,pa(swapper_pg_pmd+0x1000*KPMDS-8)
6971 + #else /* Not PAE */
6972 +
6973 + page_pde_offset = (__PAGE_OFFSET >> 20);
6974 +@@ -251,8 +310,7 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
6975 + movl %edi,pa(init_pg_tables_end)
6976 +
6977 + /* Do early initialization of the fixmap area */
6978 +- movl $pa(swapper_pg_fixmap)+PDE_ATTR,%eax
6979 +- movl %eax,pa(swapper_pg_dir+0xffc)
6980 ++ movl $pa(swapper_pg_fixmap)+PDE_ATTR,pa(swapper_pg_dir+0xffc)
6981 + #endif
6982 + jmp 3f
6983 + /*
6984 +@@ -316,13 +374,16 @@ ENTRY(startup_32_smp)
6985 + jnc 6f
6986 +
6987 + /* Setup EFER (Extended Feature Enable Register) */
6988 +- movl $0xc0000080, %ecx
6989 ++ movl $MSR_EFER, %ecx
6990 + rdmsr
6991 +
6992 + btsl $11, %eax
6993 + /* Make changes effective */
6994 + wrmsr
6995 +
6996 ++ btsl $63-32,pa(__supported_pte_mask+4)
6997 ++ movl $1,pa(nx_enabled)
6998 ++
6999 + 6:
7000 +
7001 + /*
7002 +@@ -348,9 +409,7 @@ ENTRY(startup_32_smp)
7003 +
7004 + #ifdef CONFIG_SMP
7005 + cmpb $0, ready
7006 +- jz 1f /* Initial CPU cleans BSS */
7007 +- jmp checkCPUtype
7008 +-1:
7009 ++ jnz checkCPUtype /* Initial CPU cleans BSS */
7010 + #endif /* CONFIG_SMP */
7011 +
7012 + /*
7013 +@@ -427,12 +486,12 @@ is386: movl $2,%ecx # set MP
7014 + ljmp $(__KERNEL_CS),$1f
7015 + 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
7016 + movl %eax,%ss # after changing gdt.
7017 +- movl %eax,%fs # gets reset once there's real percpu
7018 +-
7019 +- movl $(__USER_DS),%eax # DS/ES contains default USER segment
7020 + movl %eax,%ds
7021 + movl %eax,%es
7022 +
7023 ++ movl $(__KERNEL_PERCPU), %eax
7024 ++ movl %eax,%fs # set this cpu's percpu
7025 ++
7026 + xorl %eax,%eax # Clear GS and LDT
7027 + movl %eax,%gs
7028 + lldt %ax
7029 +@@ -443,11 +502,7 @@ is386: movl $2,%ecx # set MP
7030 + movb ready, %cl
7031 + movb $1, ready
7032 + cmpb $0,%cl # the first CPU calls start_kernel
7033 +- je 1f
7034 +- movl $(__KERNEL_PERCPU), %eax
7035 +- movl %eax,%fs # set this cpu's percpu
7036 +- jmp initialize_secondary # all other CPUs call initialize_secondary
7037 +-1:
7038 ++ jne initialize_secondary # all other CPUs call initialize_secondary
7039 + #endif /* CONFIG_SMP */
7040 + jmp i386_start_kernel
7041 +
7042 +@@ -533,15 +588,15 @@ early_page_fault:
7043 + jmp early_fault
7044 +
7045 + early_fault:
7046 +- cld
7047 + #ifdef CONFIG_PRINTK
7048 ++ cmpl $2,%ss:early_recursion_flag
7049 ++ je hlt_loop
7050 ++ incl %ss:early_recursion_flag
7051 ++ cld
7052 + pusha
7053 + movl $(__KERNEL_DS),%eax
7054 + movl %eax,%ds
7055 + movl %eax,%es
7056 +- cmpl $2,early_recursion_flag
7057 +- je hlt_loop
7058 +- incl early_recursion_flag
7059 + movl %cr2,%eax
7060 + pushl %eax
7061 + pushl %edx /* trapno */
7062 +@@ -551,8 +606,8 @@ early_fault:
7063 + #else
7064 + call printk
7065 + #endif
7066 +-#endif
7067 + call dump_stack
7068 ++#endif
7069 + hlt_loop:
7070 + hlt
7071 + jmp hlt_loop
7072 +@@ -560,8 +615,11 @@ hlt_loop:
7073 + /* This is the default interrupt "handler" :-) */
7074 + ALIGN
7075 + ignore_int:
7076 +- cld
7077 + #ifdef CONFIG_PRINTK
7078 ++ cmpl $2,%ss:early_recursion_flag
7079 ++ je hlt_loop
7080 ++ incl %ss:early_recursion_flag
7081 ++ cld
7082 + pushl %eax
7083 + pushl %ecx
7084 + pushl %edx
7085 +@@ -570,9 +628,6 @@ ignore_int:
7086 + movl $(__KERNEL_DS),%eax
7087 + movl %eax,%ds
7088 + movl %eax,%es
7089 +- cmpl $2,early_recursion_flag
7090 +- je hlt_loop
7091 +- incl early_recursion_flag
7092 + pushl 16(%esp)
7093 + pushl 24(%esp)
7094 + pushl 32(%esp)
7095 +@@ -592,36 +647,41 @@ ignore_int:
7096 + #endif
7097 + iret
7098 +
7099 +-.section .text
7100 +-/*
7101 +- * Real beginning of normal "text" segment
7102 +- */
7103 +-ENTRY(stext)
7104 +-ENTRY(_stext)
7105 +-
7106 + /*
7107 + * BSS section
7108 + */
7109 +-.section ".bss.page_aligned","wa"
7110 +- .align PAGE_SIZE_asm
7111 + #ifdef CONFIG_X86_PAE
7112 ++.section .swapper_pg_pmd,"a",@progbits
7113 + swapper_pg_pmd:
7114 + .fill 1024*KPMDS,4,0
7115 + #else
7116 ++.section .swapper_pg_dir,"a",@progbits
7117 + ENTRY(swapper_pg_dir)
7118 + .fill 1024,4,0
7119 + #endif
7120 + swapper_pg_fixmap:
7121 + .fill 1024,4,0
7122 ++
7123 ++.section .empty_zero_page,"a",@progbits
7124 + ENTRY(empty_zero_page)
7125 + .fill 4096,1,0
7126 ++
7127 ++/*
7128 ++ * The IDT has to be page-aligned to simplify the Pentium
7129 ++ * F0 0F bug workaround.. We have a special link segment
7130 ++ * for this.
7131 ++ */
7132 ++.section .idt,"a",@progbits
7133 ++ENTRY(idt_table)
7134 ++ .fill 256,8,0
7135 ++
7136 + /*
7137 + * This starts the data section.
7138 + */
7139 ++.data
7140 ++
7141 + #ifdef CONFIG_X86_PAE
7142 +-.section ".data.page_aligned","wa"
7143 +- /* Page-aligned for the benefit of paravirt? */
7144 +- .align PAGE_SIZE_asm
7145 ++.section .swapper_pg_dir,"a",@progbits
7146 + ENTRY(swapper_pg_dir)
7147 + .long pa(swapper_pg_pmd+PGD_ATTR),0 /* low identity map */
7148 + # if KPMDS == 3
7149 +@@ -644,11 +704,12 @@ ENTRY(swapper_pg_dir)
7150 +
7151 + .data
7152 + ENTRY(stack_start)
7153 +- .long init_thread_union+THREAD_SIZE
7154 ++ .long init_thread_union+THREAD_SIZE-8
7155 + .long __BOOT_DS
7156 +
7157 + ready: .byte 0
7158 +
7159 ++.section .rodata,"a",@progbits
7160 + early_recursion_flag:
7161 + .long 0
7162 +
7163 +@@ -684,7 +745,7 @@ fault_msg:
7164 + .word 0 # 32 bit align gdt_desc.address
7165 + boot_gdt_descr:
7166 + .word __BOOT_DS+7
7167 +- .long boot_gdt - __PAGE_OFFSET
7168 ++ .long pa(boot_gdt)
7169 +
7170 + .word 0 # 32-bit align idt_desc.address
7171 + idt_descr:
7172 +@@ -695,7 +756,7 @@ idt_descr:
7173 + .word 0 # 32 bit align gdt_desc.address
7174 + ENTRY(early_gdt_descr)
7175 + .word GDT_ENTRIES*8-1
7176 +- .long per_cpu__gdt_page /* Overwritten for secondary CPUs */
7177 ++ .long cpu_gdt_table /* Overwritten for secondary CPUs */
7178 +
7179 + /*
7180 + * The boot_gdt must mirror the equivalent in setup.S and is
7181 +@@ -704,5 +765,59 @@ ENTRY(early_gdt_descr)
7182 + .align L1_CACHE_BYTES
7183 + ENTRY(boot_gdt)
7184 + .fill GDT_ENTRY_BOOT_CS,8,0
7185 +- .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
7186 +- .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
7187 ++ .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */
7188 ++ .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */
7189 ++
7190 ++ .align PAGE_SIZE_asm
7191 ++ENTRY(cpu_gdt_table)
7192 ++ .rept NR_CPUS
7193 ++ .quad 0x0000000000000000 /* NULL descriptor */
7194 ++ .quad 0x0000000000000000 /* 0x0b reserved */
7195 ++ .quad 0x0000000000000000 /* 0x13 reserved */
7196 ++ .quad 0x0000000000000000 /* 0x1b reserved */
7197 ++ .quad 0x0000000000000000 /* 0x20 unused */
7198 ++ .quad 0x0000000000000000 /* 0x28 unused */
7199 ++ .quad 0x0000000000000000 /* 0x33 TLS entry 1 */
7200 ++ .quad 0x0000000000000000 /* 0x3b TLS entry 2 */
7201 ++ .quad 0x0000000000000000 /* 0x43 TLS entry 3 */
7202 ++ .quad 0x0000000000000000 /* 0x4b reserved */
7203 ++ .quad 0x0000000000000000 /* 0x53 reserved */
7204 ++ .quad 0x0000000000000000 /* 0x5b reserved */
7205 ++
7206 ++ .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
7207 ++ .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
7208 ++ .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */
7209 ++ .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */
7210 ++
7211 ++ .quad 0x0000000000000000 /* 0x80 TSS descriptor */
7212 ++ .quad 0x0000000000000000 /* 0x88 LDT descriptor */
7213 ++
7214 ++ /*
7215 ++ * Segments used for calling PnP BIOS have byte granularity.
7216 ++ * The code segments and data segments have fixed 64k limits,
7217 ++ * the transfer segment sizes are set at run time.
7218 ++ */
7219 ++ .quad 0x00409b000000ffff /* 0x90 32-bit code */
7220 ++ .quad 0x00009b000000ffff /* 0x98 16-bit code */
7221 ++ .quad 0x000093000000ffff /* 0xa0 16-bit data */
7222 ++ .quad 0x0000930000000000 /* 0xa8 16-bit data */
7223 ++ .quad 0x0000930000000000 /* 0xb0 16-bit data */
7224 ++
7225 ++ /*
7226 ++ * The APM segments have byte granularity and their bases
7227 ++ * are set at run time. All have 64k limits.
7228 ++ */
7229 ++ .quad 0x00409b000000ffff /* 0xb8 APM CS code */
7230 ++ .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */
7231 ++ .quad 0x004093000000ffff /* 0xc8 APM DS data */
7232 ++
7233 ++ .quad 0x00c0930000000000 /* 0xd0 - ESPFIX SS */
7234 ++ .quad 0x0040930000000000 /* 0xd8 - PERCPU */
7235 ++ .quad 0x0000000000000000 /* 0xe0 - PCIBIOS_CS */
7236 ++ .quad 0x0000000000000000 /* 0xe8 - PCIBIOS_DS */
7237 ++ .quad 0x0000000000000000 /* 0xf0 - unused */
7238 ++ .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
7239 ++
7240 ++ /* Be sure this is zeroed to avoid false validations in Xen */
7241 ++ .fill PAGE_SIZE_asm - GDT_SIZE,1,0
7242 ++ .endr
7243 +diff -urNp linux-2.6.26.6/arch/x86/kernel/head64.c linux-2.6.26.6/arch/x86/kernel/head64.c
7244 +--- linux-2.6.26.6/arch/x86/kernel/head64.c 2008-10-08 23:24:05.000000000 -0400
7245 ++++ linux-2.6.26.6/arch/x86/kernel/head64.c 2008-10-11 21:54:19.000000000 -0400
7246 +@@ -143,6 +143,11 @@ void __init x86_64_start_kernel(char * r
7247 + /* Make NULL pointers segfault */
7248 + zap_identity_mappings();
7249 +
7250 ++ for (i = 0; i < NR_CPUS; i++)
7251 ++ cpu_pda(i) = &boot_cpu_pda[i];
7252 ++
7253 ++ pda_init(0);
7254 ++
7255 + /* Cleanup the over mapped high alias */
7256 + cleanup_highmap();
7257 +
7258 +@@ -157,10 +162,6 @@ void __init x86_64_start_kernel(char * r
7259 +
7260 + early_printk("Kernel alive\n");
7261 +
7262 +- for (i = 0; i < NR_CPUS; i++)
7263 +- cpu_pda(i) = &boot_cpu_pda[i];
7264 +-
7265 +- pda_init(0);
7266 + copy_bootdata(__va(real_mode_data));
7267 +
7268 + reserve_early(__pa_symbol(&_text), __pa_symbol(&_end), "TEXT DATA BSS");
7269 +diff -urNp linux-2.6.26.6/arch/x86/kernel/head_64.S linux-2.6.26.6/arch/x86/kernel/head_64.S
7270 +--- linux-2.6.26.6/arch/x86/kernel/head_64.S 2008-10-08 23:24:05.000000000 -0400
7271 ++++ linux-2.6.26.6/arch/x86/kernel/head_64.S 2008-10-11 22:15:25.000000000 -0400
7272 +@@ -77,6 +77,8 @@ startup_64:
7273 + */
7274 + addq %rbp, init_level4_pgt + 0(%rip)
7275 + addq %rbp, init_level4_pgt + (258*8)(%rip)
7276 ++ addq %rbp, init_level4_pgt + (388*8)(%rip)
7277 ++ addq %rbp, init_level4_pgt + (452*8)(%rip)
7278 + addq %rbp, init_level4_pgt + (511*8)(%rip)
7279 +
7280 + addq %rbp, level3_ident_pgt + 0(%rip)
7281 +@@ -181,6 +183,10 @@ ENTRY(secondary_startup_64)
7282 + btl $20,%edi /* No Execute supported? */
7283 + jnc 1f
7284 + btsl $_EFER_NX, %eax
7285 ++ leaq init_level4_pgt(%rip), %rdi
7286 ++ btsq $_PAGE_BIT_NX, 8*258(%rdi)
7287 ++ btsq $_PAGE_BIT_NX, 8*388(%rdi)
7288 ++ btsq $_PAGE_BIT_NX, 8*452(%rdi)
7289 + 1: wrmsr /* Make changes effective */
7290 +
7291 + /* Setup cr0 */
7292 +@@ -255,15 +261,15 @@ ENTRY(secondary_startup_64)
7293 + .align 8
7294 + ENTRY(initial_code)
7295 + .quad x86_64_start_kernel
7296 +- __FINITDATA
7297 +
7298 + ENTRY(init_rsp)
7299 + .quad init_thread_union+THREAD_SIZE-8
7300 ++ __FINITDATA
7301 +
7302 + bad_address:
7303 + jmp bad_address
7304 +
7305 +- .section ".init.text","ax"
7306 ++ __INIT
7307 + #ifdef CONFIG_EARLY_PRINTK
7308 + .globl early_idt_handlers
7309 + early_idt_handlers:
7310 +@@ -308,18 +314,23 @@ ENTRY(early_idt_handler)
7311 + #endif /* EARLY_PRINTK */
7312 + 1: hlt
7313 + jmp 1b
7314 ++ .previous
7315 +
7316 + #ifdef CONFIG_EARLY_PRINTK
7317 ++ __INITDATA
7318 + early_recursion_flag:
7319 + .long 0
7320 ++ .previous
7321 +
7322 ++ .section .rodata,"a",@progbits
7323 + early_idt_msg:
7324 + .asciz "PANIC: early exception %02lx rip %lx:%lx error %lx cr2 %lx\n"
7325 + early_idt_ripmsg:
7326 + .asciz "RIP %s\n"
7327 +-#endif /* CONFIG_EARLY_PRINTK */
7328 + .previous
7329 ++#endif /* CONFIG_EARLY_PRINTK */
7330 +
7331 ++ .section .rodata,"a",@progbits
7332 + .balign PAGE_SIZE
7333 +
7334 + #define NEXT_PAGE(name) \
7335 +@@ -344,7 +355,11 @@ NEXT_PAGE(init_level4_pgt)
7336 + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
7337 + .fill 257,8,0
7338 + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
7339 +- .fill 252,8,0
7340 ++ .fill 129,8,0
7341 ++ .quad level3_vmalloc_pgt - __START_KERNEL_map + _KERNPG_TABLE
7342 ++ .fill 63,8,0
7343 ++ .quad level3_vmemmap_pgt - __START_KERNEL_map + _KERNPG_TABLE
7344 ++ .fill 58,8,0
7345 + /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
7346 + .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE
7347 +
7348 +@@ -352,6 +367,12 @@ NEXT_PAGE(level3_ident_pgt)
7349 + .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
7350 + .fill 511,8,0
7351 +
7352 ++NEXT_PAGE(level3_vmalloc_pgt)
7353 ++ .fill 512,8,0
7354 ++
7355 ++NEXT_PAGE(level3_vmemmap_pgt)
7356 ++ .fill 512,8,0
7357 ++
7358 + NEXT_PAGE(level3_kernel_pgt)
7359 + .fill 510,8,0
7360 + /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */
7361 +@@ -393,36 +414,18 @@ NEXT_PAGE(level2_spare_pgt)
7362 + #undef PMDS
7363 + #undef NEXT_PAGE
7364 +
7365 +- .data
7366 +- .align 16
7367 +- .globl cpu_gdt_descr
7368 +-cpu_gdt_descr:
7369 +- .word gdt_end-cpu_gdt_table-1
7370 +-gdt:
7371 +- .quad cpu_gdt_table
7372 +-#ifdef CONFIG_SMP
7373 +- .rept NR_CPUS-1
7374 +- .word 0
7375 +- .quad 0
7376 +- .endr
7377 +-#endif
7378 +-
7379 +-ENTRY(phys_base)
7380 +- /* This must match the first entry in level2_kernel_pgt */
7381 +- .quad 0x0000000000000000
7382 +-
7383 + /* We need valid kernel segments for data and code in long mode too
7384 + * IRET will check the segment types kkeil 2000/10/28
7385 + * Also sysret mandates a special GDT layout
7386 + */
7387 +-
7388 +- .section .data.page_aligned, "aw"
7389 ++
7390 + .align PAGE_SIZE
7391 +
7392 + /* The TLS descriptors are currently at a different place compared to i386.
7393 + Hopefully nobody expects them at a fixed place (Wine?) */
7394 +
7395 + ENTRY(cpu_gdt_table)
7396 ++ .rept NR_CPUS
7397 + .quad 0x0000000000000000 /* NULL descriptor */
7398 + .quad 0x00cf9b000000ffff /* __KERNEL32_CS */
7399 + .quad 0x00af9b000000ffff /* __KERNEL_CS */
7400 +@@ -435,15 +438,24 @@ ENTRY(cpu_gdt_table)
7401 + .quad 0,0 /* LDT */
7402 + .quad 0,0,0 /* three TLS descriptors */
7403 + .quad 0x0000f40000000000 /* node/CPU stored in limit */
7404 +-gdt_end:
7405 + /* asm/segment.h:GDT_ENTRIES must match this */
7406 + /* This should be a multiple of the cache line size */
7407 +- /* GDTs of other CPUs are now dynamically allocated */
7408 +
7409 + /* zero the remaining page */
7410 + .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
7411 ++ .endr
7412 ++
7413 ++ .align 16
7414 ++ .globl cpu_gdt_descr
7415 ++cpu_gdt_descr:
7416 ++ .word GDT_SIZE-1
7417 ++gdt:
7418 ++ .quad cpu_gdt_table
7419 ++
7420 ++ENTRY(phys_base)
7421 ++ /* This must match the first entry in level2_kernel_pgt */
7422 ++ .quad 0x0000000000000000
7423 +
7424 +- .section .bss, "aw", @nobits
7425 + .align L1_CACHE_BYTES
7426 + ENTRY(idt_table)
7427 + .skip 256 * 16
7428 +diff -urNp linux-2.6.26.6/arch/x86/kernel/i386_ksyms_32.c linux-2.6.26.6/arch/x86/kernel/i386_ksyms_32.c
7429 +--- linux-2.6.26.6/arch/x86/kernel/i386_ksyms_32.c 2008-10-08 23:24:05.000000000 -0400
7430 ++++ linux-2.6.26.6/arch/x86/kernel/i386_ksyms_32.c 2008-10-11 21:54:19.000000000 -0400
7431 +@@ -3,8 +3,12 @@
7432 + #include <asm/desc.h>
7433 + #include <asm/pgtable.h>
7434 +
7435 ++EXPORT_SYMBOL_GPL(cpu_gdt_table);
7436 ++
7437 + /* Networking helper routines. */
7438 + EXPORT_SYMBOL(csum_partial_copy_generic);
7439 ++EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
7440 ++EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
7441 +
7442 + EXPORT_SYMBOL(__get_user_1);
7443 + EXPORT_SYMBOL(__get_user_2);
7444 +@@ -19,3 +23,7 @@ EXPORT_SYMBOL(strstr);
7445 +
7446 + EXPORT_SYMBOL(csum_partial);
7447 + EXPORT_SYMBOL(empty_zero_page);
7448 ++
7449 ++#ifdef CONFIG_PAX_KERNEXEC
7450 ++EXPORT_SYMBOL(KERNEL_TEXT_OFFSET);
7451 ++#endif
7452 +diff -urNp linux-2.6.26.6/arch/x86/kernel/init_task.c linux-2.6.26.6/arch/x86/kernel/init_task.c
7453 +--- linux-2.6.26.6/arch/x86/kernel/init_task.c 2008-10-08 23:24:05.000000000 -0400
7454 ++++ linux-2.6.26.6/arch/x86/kernel/init_task.c 2008-10-11 21:54:19.000000000 -0400
7455 +@@ -42,5 +42,5 @@ EXPORT_SYMBOL(init_task);
7456 + * section. Since TSS's are completely CPU-local, we want them
7457 + * on exact cacheline boundaries, to eliminate cacheline ping-pong.
7458 + */
7459 +-DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
7460 +-
7461 ++struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
7462 ++EXPORT_SYMBOL(init_tss);
7463 +diff -urNp linux-2.6.26.6/arch/x86/kernel/ioport.c linux-2.6.26.6/arch/x86/kernel/ioport.c
7464 +--- linux-2.6.26.6/arch/x86/kernel/ioport.c 2008-10-08 23:24:05.000000000 -0400
7465 ++++ linux-2.6.26.6/arch/x86/kernel/ioport.c 2008-10-11 21:54:19.000000000 -0400
7466 +@@ -14,6 +14,7 @@
7467 + #include <linux/slab.h>
7468 + #include <linux/thread_info.h>
7469 + #include <linux/syscalls.h>
7470 ++#include <linux/grsecurity.h>
7471 +
7472 + /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
7473 + static void set_bitmap(unsigned long *bitmap, unsigned int base,
7474 +@@ -40,6 +41,12 @@ asmlinkage long sys_ioperm(unsigned long
7475 +
7476 + if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
7477 + return -EINVAL;
7478 ++#ifdef CONFIG_GRKERNSEC_IO
7479 ++ if (turn_on) {
7480 ++ gr_handle_ioperm();
7481 ++ return -EPERM;
7482 ++ }
7483 ++#endif
7484 + if (turn_on && !capable(CAP_SYS_RAWIO))
7485 + return -EPERM;
7486 +
7487 +@@ -66,7 +73,7 @@ asmlinkage long sys_ioperm(unsigned long
7488 + * because the ->io_bitmap_max value must match the bitmap
7489 + * contents:
7490 + */
7491 +- tss = &per_cpu(init_tss, get_cpu());
7492 ++ tss = init_tss + get_cpu();
7493 +
7494 + set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
7495 +
7496 +@@ -121,8 +128,13 @@ static int do_iopl(unsigned int level, s
7497 + return -EINVAL;
7498 + /* Trying to gain more privileges? */
7499 + if (level > old) {
7500 ++#ifdef CONFIG_GRKERNSEC_IO
7501 ++ gr_handle_iopl();
7502 ++ return -EPERM;
7503 ++#else
7504 + if (!capable(CAP_SYS_RAWIO))
7505 + return -EPERM;
7506 ++#endif
7507 + }
7508 + regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
7509 +
7510 +diff -urNp linux-2.6.26.6/arch/x86/kernel/irq_32.c linux-2.6.26.6/arch/x86/kernel/irq_32.c
7511 +--- linux-2.6.26.6/arch/x86/kernel/irq_32.c 2008-10-08 23:24:05.000000000 -0400
7512 ++++ linux-2.6.26.6/arch/x86/kernel/irq_32.c 2008-10-11 21:54:19.000000000 -0400
7513 +@@ -115,7 +115,7 @@ unsigned int do_IRQ(struct pt_regs *regs
7514 + int arg1, arg2, bx;
7515 +
7516 + /* build the stack frame on the IRQ stack */
7517 +- isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
7518 ++ isp = (u32*) ((char*)irqctx + sizeof(*irqctx) - 8);
7519 + irqctx->tinfo.task = curctx->tinfo.task;
7520 + irqctx->tinfo.previous_esp = current_stack_pointer;
7521 +
7522 +@@ -209,7 +209,7 @@ asmlinkage void do_softirq(void)
7523 + irqctx->tinfo.previous_esp = current_stack_pointer;
7524 +
7525 + /* build the stack frame on the softirq stack */
7526 +- isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
7527 ++ isp = (u32*) ((char*)irqctx + sizeof(*irqctx) - 8);
7528 +
7529 + asm volatile(
7530 + " xchgl %%ebx,%%esp \n"
7531 +diff -urNp linux-2.6.26.6/arch/x86/kernel/kprobes.c linux-2.6.26.6/arch/x86/kernel/kprobes.c
7532 +--- linux-2.6.26.6/arch/x86/kernel/kprobes.c 2008-10-08 23:24:05.000000000 -0400
7533 ++++ linux-2.6.26.6/arch/x86/kernel/kprobes.c 2008-10-11 21:54:19.000000000 -0400
7534 +@@ -166,9 +166,24 @@ static void __kprobes set_jmp_op(void *f
7535 + char op;
7536 + s32 raddr;
7537 + } __attribute__((packed)) * jop;
7538 +- jop = (struct __arch_jmp_op *)from;
7539 ++
7540 ++#ifdef CONFIG_PAX_KERNEXEC
7541 ++ unsigned long cr0;
7542 ++#endif
7543 ++
7544 ++ jop = (struct __arch_jmp_op *)(ktla_ktva(from));
7545 ++
7546 ++#ifdef CONFIG_PAX_KERNEXEC
7547 ++ pax_open_kernel(cr0);
7548 ++#endif
7549 ++
7550 + jop->raddr = (s32)((long)(to) - ((long)(from) + 5));
7551 + jop->op = RELATIVEJUMP_INSTRUCTION;
7552 ++
7553 ++#ifdef CONFIG_PAX_KERNEXEC
7554 ++ pax_close_kernel(cr0);
7555 ++#endif
7556 ++
7557 + }
7558 +
7559 + /*
7560 +@@ -342,16 +357,29 @@ static void __kprobes fix_riprel(struct
7561 +
7562 + static void __kprobes arch_copy_kprobe(struct kprobe *p)
7563 + {
7564 +- memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
7565 ++
7566 ++#ifdef CONFIG_PAX_KERNEXEC
7567 ++ unsigned long cr0;
7568 ++#endif
7569 ++
7570 ++#ifdef CONFIG_PAX_KERNEXEC
7571 ++ pax_open_kernel(cr0);
7572 ++#endif
7573 ++
7574 ++ memcpy(p->ainsn.insn, ktla_ktva(p->addr), MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
7575 ++
7576 ++#ifdef CONFIG_PAX_KERNEXEC
7577 ++ pax_close_kernel(cr0);
7578 ++#endif
7579 +
7580 + fix_riprel(p);
7581 +
7582 +- if (can_boost(p->addr))
7583 ++ if (can_boost(ktla_ktva(p->addr)))
7584 + p->ainsn.boostable = 0;
7585 + else
7586 + p->ainsn.boostable = -1;
7587 +
7588 +- p->opcode = *p->addr;
7589 ++ p->opcode = *(ktla_ktva(p->addr));
7590 + }
7591 +
7592 + int __kprobes arch_prepare_kprobe(struct kprobe *p)
7593 +@@ -428,7 +456,7 @@ static void __kprobes prepare_singlestep
7594 + if (p->opcode == BREAKPOINT_INSTRUCTION)
7595 + regs->ip = (unsigned long)p->addr;
7596 + else
7597 +- regs->ip = (unsigned long)p->ainsn.insn;
7598 ++ regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
7599 + }
7600 +
7601 + /* Called with kretprobe_lock held */
7602 +@@ -450,7 +478,7 @@ static void __kprobes setup_singlestep(s
7603 + if (p->ainsn.boostable == 1 && !p->post_handler) {
7604 + /* Boost up -- we can execute copied instructions directly */
7605 + reset_current_kprobe();
7606 +- regs->ip = (unsigned long)p->ainsn.insn;
7607 ++ regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
7608 + preempt_enable_no_resched();
7609 + return;
7610 + }
7611 +@@ -772,7 +800,7 @@ static void __kprobes resume_execution(s
7612 + struct pt_regs *regs, struct kprobe_ctlblk *kcb)
7613 + {
7614 + unsigned long *tos = stack_addr(regs);
7615 +- unsigned long copy_ip = (unsigned long)p->ainsn.insn;
7616 ++ unsigned long copy_ip = ktva_ktla((unsigned long)p->ainsn.insn);
7617 + unsigned long orig_ip = (unsigned long)p->addr;
7618 + kprobe_opcode_t *insn = p->ainsn.insn;
7619 +
7620 +@@ -955,7 +983,7 @@ int __kprobes kprobe_exceptions_notify(s
7621 + struct die_args *args = data;
7622 + int ret = NOTIFY_DONE;
7623 +
7624 +- if (args->regs && user_mode_vm(args->regs))
7625 ++ if (args->regs && user_mode(args->regs))
7626 + return ret;
7627 +
7628 + switch (val) {
7629 +diff -urNp linux-2.6.26.6/arch/x86/kernel/ldt.c linux-2.6.26.6/arch/x86/kernel/ldt.c
7630 +--- linux-2.6.26.6/arch/x86/kernel/ldt.c 2008-10-08 23:24:05.000000000 -0400
7631 ++++ linux-2.6.26.6/arch/x86/kernel/ldt.c 2008-10-11 21:54:19.000000000 -0400
7632 +@@ -65,7 +65,7 @@ static int alloc_ldt(mm_context_t *pc, i
7633 + cpumask_t mask;
7634 +
7635 + preempt_disable();
7636 +- load_LDT(pc);
7637 ++ load_LDT_nolock(pc);
7638 + mask = cpumask_of_cpu(smp_processor_id());
7639 + if (!cpus_equal(current->mm->cpu_vm_mask, mask))
7640 + smp_call_function(flush_ldt, NULL, 1, 1);
7641 +@@ -110,6 +110,24 @@ int init_new_context(struct task_struct
7642 + retval = copy_ldt(&mm->context, &old_mm->context);
7643 + mutex_unlock(&old_mm->context.lock);
7644 + }
7645 ++
7646 ++ if (tsk == current) {
7647 ++ mm->context.vdso = ~0UL;
7648 ++
7649 ++#ifdef CONFIG_X86_32
7650 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
7651 ++ mm->context.user_cs_base = 0UL;
7652 ++ mm->context.user_cs_limit = ~0UL;
7653 ++
7654 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
7655 ++ cpus_clear(mm->context.cpu_user_cs_mask);
7656 ++#endif
7657 ++
7658 ++#endif
7659 ++#endif
7660 ++
7661 ++ }
7662 ++
7663 + return retval;
7664 + }
7665 +
7666 +@@ -223,6 +241,13 @@ static int write_ldt(void __user *ptr, u
7667 + }
7668 + }
7669 +
7670 ++#ifdef CONFIG_PAX_SEGMEXEC
7671 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
7672 ++ error = -EINVAL;
7673 ++ goto out_unlock;
7674 ++ }
7675 ++#endif
7676 ++
7677 + fill_ldt(&ldt, &ldt_info);
7678 + if (oldmode)
7679 + ldt.avl = 0;
7680 +diff -urNp linux-2.6.26.6/arch/x86/kernel/machine_kexec_32.c linux-2.6.26.6/arch/x86/kernel/machine_kexec_32.c
7681 +--- linux-2.6.26.6/arch/x86/kernel/machine_kexec_32.c 2008-10-08 23:24:05.000000000 -0400
7682 ++++ linux-2.6.26.6/arch/x86/kernel/machine_kexec_32.c 2008-10-11 21:55:52.000000000 -0400
7683 +@@ -30,7 +30,7 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED
7684 + static u32 kexec_pte0[1024] PAGE_ALIGNED;
7685 + static u32 kexec_pte1[1024] PAGE_ALIGNED;
7686 +
7687 +-static void set_idt(void *newidt, __u16 limit)
7688 ++static void set_idt(struct desc_struct *newidt, __u16 limit)
7689 + {
7690 + struct desc_ptr curidt;
7691 +
7692 +@@ -42,7 +42,7 @@ static void set_idt(void *newidt, __u16
7693 + };
7694 +
7695 +
7696 +-static void set_gdt(void *newgdt, __u16 limit)
7697 ++static void set_gdt(struct desc_struct *newgdt, __u16 limit)
7698 + {
7699 + struct desc_ptr curgdt;
7700 +
7701 +@@ -111,10 +111,10 @@ NORET_TYPE void machine_kexec(struct kim
7702 + local_irq_disable();
7703 +
7704 + control_page = page_address(image->control_code_page);
7705 +- memcpy(control_page, relocate_kernel, PAGE_SIZE);
7706 ++ memcpy(control_page, (void *)ktla_ktva((unsigned long)relocate_kernel), PAGE_SIZE);
7707 +
7708 + page_list[PA_CONTROL_PAGE] = __pa(control_page);
7709 +- page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
7710 ++ page_list[VA_CONTROL_PAGE] = ktla_ktva((unsigned long)relocate_kernel);
7711 + page_list[PA_PGD] = __pa(kexec_pgd);
7712 + page_list[VA_PGD] = (unsigned long)kexec_pgd;
7713 + #ifdef CONFIG_X86_PAE
7714 +diff -urNp linux-2.6.26.6/arch/x86/kernel/module_32.c linux-2.6.26.6/arch/x86/kernel/module_32.c
7715 +--- linux-2.6.26.6/arch/x86/kernel/module_32.c 2008-10-08 23:24:05.000000000 -0400
7716 ++++ linux-2.6.26.6/arch/x86/kernel/module_32.c 2008-10-11 21:54:19.000000000 -0400
7717 +@@ -23,6 +23,9 @@
7718 + #include <linux/kernel.h>
7719 + #include <linux/bug.h>
7720 +
7721 ++#include <asm/desc.h>
7722 ++#include <asm/pgtable.h>
7723 ++
7724 + #if 0
7725 + #define DEBUGP printk
7726 + #else
7727 +@@ -33,9 +36,31 @@ void *module_alloc(unsigned long size)
7728 + {
7729 + if (size == 0)
7730 + return NULL;
7731 ++
7732 ++#ifdef CONFIG_PAX_KERNEXEC
7733 ++ return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
7734 ++#else
7735 + return vmalloc_exec(size);
7736 ++#endif
7737 ++
7738 + }
7739 +
7740 ++#ifdef CONFIG_PAX_KERNEXEC
7741 ++void *module_alloc_exec(unsigned long size)
7742 ++{
7743 ++ struct vm_struct *area;
7744 ++
7745 ++ if (size == 0)
7746 ++ return NULL;
7747 ++
7748 ++ area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
7749 ++ if (area)
7750 ++ return area->addr;
7751 ++
7752 ++ return NULL;
7753 ++}
7754 ++EXPORT_SYMBOL(module_alloc_exec);
7755 ++#endif
7756 +
7757 + /* Free memory returned from module_alloc */
7758 + void module_free(struct module *mod, void *module_region)
7759 +@@ -45,6 +70,45 @@ void module_free(struct module *mod, voi
7760 + table entries. */
7761 + }
7762 +
7763 ++#ifdef CONFIG_PAX_KERNEXEC
7764 ++void module_free_exec(struct module *mod, void *module_region)
7765 ++{
7766 ++ struct vm_struct **p, *tmp;
7767 ++
7768 ++ if (!module_region)
7769 ++ return;
7770 ++
7771 ++ if ((PAGE_SIZE-1) & (unsigned long)module_region) {
7772 ++ printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
7773 ++ WARN_ON(1);
7774 ++ return;
7775 ++ }
7776 ++
7777 ++ write_lock(&vmlist_lock);
7778 ++ for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next)
7779 ++ if (tmp->addr == module_region)
7780 ++ break;
7781 ++
7782 ++ if (tmp) {
7783 ++ unsigned long cr0;
7784 ++
7785 ++ pax_open_kernel(cr0);
7786 ++ memset(tmp->addr, 0xCC, tmp->size);
7787 ++ pax_close_kernel(cr0);
7788 ++
7789 ++ *p = tmp->next;
7790 ++ kfree(tmp);
7791 ++ }
7792 ++ write_unlock(&vmlist_lock);
7793 ++
7794 ++ if (!tmp) {
7795 ++ printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
7796 ++ module_region);
7797 ++ WARN_ON(1);
7798 ++ }
7799 ++}
7800 ++#endif
7801 ++
7802 + /* We don't need anything special. */
7803 + int module_frob_arch_sections(Elf_Ehdr *hdr,
7804 + Elf_Shdr *sechdrs,
7805 +@@ -63,14 +127,20 @@ int apply_relocate(Elf32_Shdr *sechdrs,
7806 + unsigned int i;
7807 + Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
7808 + Elf32_Sym *sym;
7809 +- uint32_t *location;
7810 ++ uint32_t *plocation, location;
7811 ++
7812 ++#ifdef CONFIG_PAX_KERNEXEC
7813 ++ unsigned long cr0;
7814 ++#endif
7815 +
7816 + DEBUGP("Applying relocate section %u to %u\n", relsec,
7817 + sechdrs[relsec].sh_info);
7818 + for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
7819 + /* This is where to make the change */
7820 +- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
7821 +- + rel[i].r_offset;
7822 ++ plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
7823 ++ location = (uint32_t)plocation;
7824 ++ if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
7825 ++ plocation = ktla_ktva((void *)plocation);
7826 + /* This is the symbol it is referring to. Note that all
7827 + undefined symbols have been resolved. */
7828 + sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
7829 +@@ -78,12 +148,32 @@ int apply_relocate(Elf32_Shdr *sechdrs,
7830 +
7831 + switch (ELF32_R_TYPE(rel[i].r_info)) {
7832 + case R_386_32:
7833 ++
7834 ++#ifdef CONFIG_PAX_KERNEXEC
7835 ++ pax_open_kernel(cr0);
7836 ++#endif
7837 ++
7838 + /* We add the value into the location given */
7839 +- *location += sym->st_value;
7840 ++ *plocation += sym->st_value;
7841 ++
7842 ++#ifdef CONFIG_PAX_KERNEXEC
7843 ++ pax_close_kernel(cr0);
7844 ++#endif
7845 ++
7846 + break;
7847 + case R_386_PC32:
7848 ++
7849 ++#ifdef CONFIG_PAX_KERNEXEC
7850 ++ pax_open_kernel(cr0);
7851 ++#endif
7852 ++
7853 + /* Add the value, subtract its postition */
7854 +- *location += sym->st_value - (uint32_t)location;
7855 ++ *plocation += sym->st_value - location;
7856 ++
7857 ++#ifdef CONFIG_PAX_KERNEXEC
7858 ++ pax_close_kernel(cr0);
7859 ++#endif
7860 ++
7861 + break;
7862 + default:
7863 + printk(KERN_ERR "module %s: Unknown relocation: %u\n",
7864 +diff -urNp linux-2.6.26.6/arch/x86/kernel/module_64.c linux-2.6.26.6/arch/x86/kernel/module_64.c
7865 +--- linux-2.6.26.6/arch/x86/kernel/module_64.c 2008-10-08 23:24:05.000000000 -0400
7866 ++++ linux-2.6.26.6/arch/x86/kernel/module_64.c 2008-10-11 21:54:19.000000000 -0400
7867 +@@ -39,7 +39,7 @@ void module_free(struct module *mod, voi
7868 + table entries. */
7869 + }
7870 +
7871 +-void *module_alloc(unsigned long size)
7872 ++static void *__module_alloc(unsigned long size, pgprot_t prot)
7873 + {
7874 + struct vm_struct *area;
7875 +
7876 +@@ -53,8 +53,31 @@ void *module_alloc(unsigned long size)
7877 + if (!area)
7878 + return NULL;
7879 +
7880 +- return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
7881 ++ return __vmalloc_area(area, GFP_KERNEL | __GFP_ZERO, prot);
7882 ++}
7883 ++
7884 ++#ifdef CONFIG_PAX_KERNEXEC
7885 ++void *module_alloc(unsigned long size)
7886 ++{
7887 ++ return __module_alloc(size, PAGE_KERNEL);
7888 ++}
7889 ++
7890 ++void module_free_exec(struct module *mod, void *module_region)
7891 ++{
7892 ++ module_free(mod, module_region);
7893 ++}
7894 ++
7895 ++void *module_alloc_exec(unsigned long size)
7896 ++{
7897 ++ return __module_alloc(size, PAGE_KERNEL_RX);
7898 + }
7899 ++#else
7900 ++void *module_alloc(unsigned long size)
7901 ++{
7902 ++ return __module_alloc(size, PAGE_KERNEL_EXEC);
7903 ++}
7904 ++#endif
7905 ++
7906 + #endif
7907 +
7908 + /* We don't need anything special. */
7909 +@@ -76,7 +99,11 @@ int apply_relocate_add(Elf64_Shdr *sechd
7910 + Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
7911 + Elf64_Sym *sym;
7912 + void *loc;
7913 +- u64 val;
7914 ++ u64 val;
7915 ++
7916 ++#ifdef CONFIG_PAX_KERNEXEC
7917 ++ unsigned long cr0;
7918 ++#endif
7919 +
7920 + DEBUGP("Applying relocate section %u to %u\n", relsec,
7921 + sechdrs[relsec].sh_info);
7922 +@@ -100,21 +127,61 @@ int apply_relocate_add(Elf64_Shdr *sechd
7923 + case R_X86_64_NONE:
7924 + break;
7925 + case R_X86_64_64:
7926 ++
7927 ++#ifdef CONFIG_PAX_KERNEXEC
7928 ++ pax_open_kernel(cr0);
7929 ++#endif
7930 ++
7931 + *(u64 *)loc = val;
7932 ++
7933 ++#ifdef CONFIG_PAX_KERNEXEC
7934 ++ pax_close_kernel(cr0);
7935 ++#endif
7936 ++
7937 + break;
7938 + case R_X86_64_32:
7939 ++
7940 ++#ifdef CONFIG_PAX_KERNEXEC
7941 ++ pax_open_kernel(cr0);
7942 ++#endif
7943 ++
7944 + *(u32 *)loc = val;
7945 ++
7946 ++#ifdef CONFIG_PAX_KERNEXEC
7947 ++ pax_close_kernel(cr0);
7948 ++#endif
7949 ++
7950 + if (val != *(u32 *)loc)
7951 + goto overflow;
7952 + break;
7953 + case R_X86_64_32S:
7954 ++
7955 ++#ifdef CONFIG_PAX_KERNEXEC
7956 ++ pax_open_kernel(cr0);
7957 ++#endif
7958 ++
7959 + *(s32 *)loc = val;
7960 ++
7961 ++#ifdef CONFIG_PAX_KERNEXEC
7962 ++ pax_close_kernel(cr0);
7963 ++#endif
7964 ++
7965 + if ((s64)val != *(s32 *)loc)
7966 + goto overflow;
7967 + break;
7968 + case R_X86_64_PC32:
7969 + val -= (u64)loc;
7970 ++
7971 ++#ifdef CONFIG_PAX_KERNEXEC
7972 ++ pax_open_kernel(cr0);
7973 ++#endif
7974 ++
7975 + *(u32 *)loc = val;
7976 ++
7977 ++#ifdef CONFIG_PAX_KERNEXEC
7978 ++ pax_close_kernel(cr0);
7979 ++#endif
7980 ++
7981 + #if 0
7982 + if ((s64)val != *(s32 *)loc)
7983 + goto overflow;
7984 +diff -urNp linux-2.6.26.6/arch/x86/kernel/mpparse.c linux-2.6.26.6/arch/x86/kernel/mpparse.c
7985 +--- linux-2.6.26.6/arch/x86/kernel/mpparse.c 2008-10-08 23:24:05.000000000 -0400
7986 ++++ linux-2.6.26.6/arch/x86/kernel/mpparse.c 2008-10-11 21:54:19.000000000 -0400
7987 +@@ -313,14 +313,14 @@ static int __init smp_read_mpc(struct mp
7988 +
7989 + memcpy(str, mpc->mpc_productid, 12);
7990 + str[12] = 0;
7991 +- printk("Product ID: %s ", str);
7992 ++ printk(KERN_CONT "Product ID: %s ", str);
7993 +
7994 + #ifdef CONFIG_X86_32
7995 + mps_oem_check(mpc, oem, str);
7996 + #endif
7997 +- printk(KERN_INFO "MPTABLE: Product ID: %s ", str);
7998 ++ printk(KERN_CONT "MPTABLE: Product ID: %s ", str);
7999 +
8000 +- printk(KERN_INFO "MPTABLE: APIC at: 0x%X\n", mpc->mpc_lapic);
8001 ++ printk(KERN_CONT "MPTABLE: APIC at: 0x%X\n", mpc->mpc_lapic);
8002 +
8003 + /* save the local APIC address, it might be non-default */
8004 + if (!acpi_lapic)
8005 +diff -urNp linux-2.6.26.6/arch/x86/kernel/paravirt.c linux-2.6.26.6/arch/x86/kernel/paravirt.c
8006 +--- linux-2.6.26.6/arch/x86/kernel/paravirt.c 2008-10-08 23:24:05.000000000 -0400
8007 ++++ linux-2.6.26.6/arch/x86/kernel/paravirt.c 2008-10-11 21:54:19.000000000 -0400
8008 +@@ -42,7 +42,7 @@ void _paravirt_nop(void)
8009 + {
8010 + }
8011 +
8012 +-static void __init default_banner(void)
8013 ++static void default_banner(void)
8014 + {
8015 + printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
8016 + pv_info.name);
8017 +@@ -159,7 +159,7 @@ unsigned paravirt_patch_insns(void *insn
8018 + if (insn_len > len || start == NULL)
8019 + insn_len = len;
8020 + else
8021 +- memcpy(insnbuf, start, insn_len);
8022 ++ memcpy(insnbuf, ktla_ktva(start), insn_len);
8023 +
8024 + return insn_len;
8025 + }
8026 +@@ -261,21 +261,21 @@ enum paravirt_lazy_mode paravirt_get_laz
8027 + return __get_cpu_var(paravirt_lazy_mode);
8028 + }
8029 +
8030 +-struct pv_info pv_info = {
8031 ++struct pv_info pv_info __read_only = {
8032 + .name = "bare hardware",
8033 + .paravirt_enabled = 0,
8034 + .kernel_rpl = 0,
8035 + .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */
8036 + };
8037 +
8038 +-struct pv_init_ops pv_init_ops = {
8039 ++struct pv_init_ops pv_init_ops __read_only = {
8040 + .patch = native_patch,
8041 + .banner = default_banner,
8042 + .arch_setup = paravirt_nop,
8043 + .memory_setup = machine_specific_memory_setup,
8044 + };
8045 +
8046 +-struct pv_time_ops pv_time_ops = {
8047 ++struct pv_time_ops pv_time_ops __read_only = {
8048 + .time_init = hpet_time_init,
8049 + .get_wallclock = native_get_wallclock,
8050 + .set_wallclock = native_set_wallclock,
8051 +@@ -283,7 +283,7 @@ struct pv_time_ops pv_time_ops = {
8052 + .get_cpu_khz = native_calculate_cpu_khz,
8053 + };
8054 +
8055 +-struct pv_irq_ops pv_irq_ops = {
8056 ++struct pv_irq_ops pv_irq_ops __read_only = {
8057 + .init_IRQ = native_init_IRQ,
8058 + .save_fl = native_save_fl,
8059 + .restore_fl = native_restore_fl,
8060 +@@ -293,7 +293,7 @@ struct pv_irq_ops pv_irq_ops = {
8061 + .halt = native_halt,
8062 + };
8063 +
8064 +-struct pv_cpu_ops pv_cpu_ops = {
8065 ++struct pv_cpu_ops pv_cpu_ops __read_only = {
8066 + .cpuid = native_cpuid,
8067 + .get_debugreg = native_get_debugreg,
8068 + .set_debugreg = native_set_debugreg,
8069 +@@ -339,7 +339,7 @@ struct pv_cpu_ops pv_cpu_ops = {
8070 + },
8071 + };
8072 +
8073 +-struct pv_apic_ops pv_apic_ops = {
8074 ++struct pv_apic_ops pv_apic_ops __read_only = {
8075 + #ifdef CONFIG_X86_LOCAL_APIC
8076 + .apic_write = native_apic_write,
8077 + .apic_write_atomic = native_apic_write_atomic,
8078 +@@ -350,7 +350,7 @@ struct pv_apic_ops pv_apic_ops = {
8079 + #endif
8080 + };
8081 +
8082 +-struct pv_mmu_ops pv_mmu_ops = {
8083 ++struct pv_mmu_ops pv_mmu_ops __read_only = {
8084 + #ifndef CONFIG_X86_64
8085 + .pagetable_setup_start = native_pagetable_setup_start,
8086 + .pagetable_setup_done = native_pagetable_setup_done,
8087 +diff -urNp linux-2.6.26.6/arch/x86/kernel/process_32.c linux-2.6.26.6/arch/x86/kernel/process_32.c
8088 +--- linux-2.6.26.6/arch/x86/kernel/process_32.c 2008-10-08 23:24:05.000000000 -0400
8089 ++++ linux-2.6.26.6/arch/x86/kernel/process_32.c 2008-10-11 21:55:07.000000000 -0400
8090 +@@ -66,8 +66,10 @@ EXPORT_SYMBOL(boot_option_idle_override)
8091 + DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
8092 + EXPORT_PER_CPU_SYMBOL(current_task);
8093 +
8094 ++#ifdef CONFIG_SMP
8095 + DEFINE_PER_CPU(int, cpu_number);
8096 + EXPORT_PER_CPU_SYMBOL(cpu_number);
8097 ++#endif
8098 +
8099 + /*
8100 + * Return saved PC of a blocked thread.
8101 +@@ -75,6 +77,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_number);
8102 + unsigned long thread_saved_pc(struct task_struct *tsk)
8103 + {
8104 + return ((unsigned long *)tsk->thread.sp)[3];
8105 ++//XXX return tsk->thread.eip;
8106 + }
8107 +
8108 + /*
8109 +@@ -201,7 +204,7 @@ void __show_registers(struct pt_regs *re
8110 + unsigned long sp;
8111 + unsigned short ss, gs;
8112 +
8113 +- if (user_mode_vm(regs)) {
8114 ++ if (user_mode(regs)) {
8115 + sp = regs->sp;
8116 + ss = regs->ss & 0xffff;
8117 + savesegment(gs, gs);
8118 +@@ -278,8 +281,8 @@ int kernel_thread(int (*fn)(void *), voi
8119 + regs.bx = (unsigned long) fn;
8120 + regs.dx = (unsigned long) arg;
8121 +
8122 +- regs.ds = __USER_DS;
8123 +- regs.es = __USER_DS;
8124 ++ regs.ds = __KERNEL_DS;
8125 ++ regs.es = __KERNEL_DS;
8126 + regs.fs = __KERNEL_PERCPU;
8127 + regs.orig_ax = -1;
8128 + regs.ip = (unsigned long) kernel_thread_helper;
8129 +@@ -301,7 +304,7 @@ void exit_thread(void)
8130 + struct task_struct *tsk = current;
8131 + struct thread_struct *t = &tsk->thread;
8132 + int cpu = get_cpu();
8133 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
8134 ++ struct tss_struct *tss = init_tss + cpu;
8135 +
8136 + kfree(t->io_bitmap_ptr);
8137 + t->io_bitmap_ptr = NULL;
8138 +@@ -322,6 +325,7 @@ void flush_thread(void)
8139 + {
8140 + struct task_struct *tsk = current;
8141 +
8142 ++ loadsegment(gs, 0);
8143 + tsk->thread.debugreg0 = 0;
8144 + tsk->thread.debugreg1 = 0;
8145 + tsk->thread.debugreg2 = 0;
8146 +@@ -361,7 +365,7 @@ int copy_thread(int nr, unsigned long cl
8147 + struct task_struct *tsk;
8148 + int err;
8149 +
8150 +- childregs = task_pt_regs(p);
8151 ++ childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
8152 + *childregs = *regs;
8153 + childregs->ax = 0;
8154 + childregs->sp = sp;
8155 +@@ -390,6 +394,7 @@ int copy_thread(int nr, unsigned long cl
8156 + * Set a new TLS for the child thread?
8157 + */
8158 + if (clone_flags & CLONE_SETTLS)
8159 ++//XXX needs set_fs()?
8160 + err = do_set_thread_area(p, -1,
8161 + (struct user_desc __user *)childregs->si, 0);
8162 +
8163 +@@ -589,7 +594,7 @@ struct task_struct * __switch_to(struct
8164 + struct thread_struct *prev = &prev_p->thread,
8165 + *next = &next_p->thread;
8166 + int cpu = smp_processor_id();
8167 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
8168 ++ struct tss_struct *tss = init_tss + cpu;
8169 +
8170 + /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
8171 +
8172 +@@ -617,6 +622,11 @@ struct task_struct * __switch_to(struct
8173 + */
8174 + savesegment(gs, prev->gs);
8175 +
8176 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
8177 ++ if (!segment_eq(task_thread_info(prev_p)->addr_limit, task_thread_info(next_p)->addr_limit))
8178 ++ __set_fs(task_thread_info(next_p)->addr_limit, cpu);
8179 ++#endif
8180 ++
8181 + /*
8182 + * Load the per-thread Thread-Local Storage descriptor.
8183 + */
8184 +@@ -755,15 +765,27 @@ unsigned long get_wchan(struct task_stru
8185 + return 0;
8186 + }
8187 +
8188 +-unsigned long arch_align_stack(unsigned long sp)
8189 ++#ifdef CONFIG_PAX_RANDKSTACK
8190 ++asmlinkage void pax_randomize_kstack(void)
8191 + {
8192 +- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
8193 +- sp -= get_random_int() % 8192;
8194 +- return sp & ~0xf;
8195 +-}
8196 ++ struct thread_struct *thread = &current->thread;
8197 ++ unsigned long time;
8198 +
8199 +-unsigned long arch_randomize_brk(struct mm_struct *mm)
8200 +-{
8201 +- unsigned long range_end = mm->brk + 0x02000000;
8202 +- return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
8203 ++ if (!randomize_va_space)
8204 ++ return;
8205 ++
8206 ++ rdtscl(time);
8207 ++
8208 ++ /* P4 seems to return a 0 LSB, ignore it */
8209 ++#ifdef CONFIG_MPENTIUM4
8210 ++ time &= 0x1EUL;
8211 ++ time <<= 2;
8212 ++#else
8213 ++ time &= 0xFUL;
8214 ++ time <<= 3;
8215 ++#endif
8216 ++
8217 ++ thread->sp0 ^= time;
8218 ++ load_sp0(init_tss + smp_processor_id(), thread);
8219 + }
8220 ++#endif
8221 +diff -urNp linux-2.6.26.6/arch/x86/kernel/process_64.c linux-2.6.26.6/arch/x86/kernel/process_64.c
8222 +--- linux-2.6.26.6/arch/x86/kernel/process_64.c 2008-10-08 23:24:05.000000000 -0400
8223 ++++ linux-2.6.26.6/arch/x86/kernel/process_64.c 2008-10-11 21:54:19.000000000 -0400
8224 +@@ -146,6 +146,8 @@ static inline void play_dead(void)
8225 + void cpu_idle(void)
8226 + {
8227 + current_thread_info()->status |= TS_POLLING;
8228 ++ current->stack_canary = pax_get_random_long();
8229 ++ write_pda(stack_canary, current->stack_canary);
8230 + /* endless idle loop with no priority at all */
8231 + while (1) {
8232 + tick_nohz_stop_sched_tick();
8233 +@@ -255,7 +257,7 @@ void exit_thread(void)
8234 + struct thread_struct *t = &me->thread;
8235 +
8236 + if (me->thread.io_bitmap_ptr) {
8237 +- struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
8238 ++ struct tss_struct *tss = init_tss + get_cpu();
8239 +
8240 + kfree(t->io_bitmap_ptr);
8241 + t->io_bitmap_ptr = NULL;
8242 +@@ -566,7 +568,7 @@ __switch_to(struct task_struct *prev_p,
8243 + struct thread_struct *prev = &prev_p->thread,
8244 + *next = &next_p->thread;
8245 + int cpu = smp_processor_id();
8246 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
8247 ++ struct tss_struct *tss = init_tss + cpu;
8248 +
8249 + /* we're going to use this soon, after a few expensive things */
8250 + if (next_p->fpu_counter>5)
8251 +@@ -641,7 +643,6 @@ __switch_to(struct task_struct *prev_p,
8252 + write_pda(kernelstack,
8253 + (unsigned long)task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
8254 + #ifdef CONFIG_CC_STACKPROTECTOR
8255 +- write_pda(stack_canary, next_p->stack_canary);
8256 + /*
8257 + * Build time only check to make sure the stack_canary is at
8258 + * offset 40 in the pda; this is a gcc ABI requirement
8259 +@@ -855,16 +856,3 @@ long sys_arch_prctl(int code, unsigned l
8260 + {
8261 + return do_arch_prctl(current, code, addr);
8262 + }
8263 +-
8264 +-unsigned long arch_align_stack(unsigned long sp)
8265 +-{
8266 +- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
8267 +- sp -= get_random_int() % 8192;
8268 +- return sp & ~0xf;
8269 +-}
8270 +-
8271 +-unsigned long arch_randomize_brk(struct mm_struct *mm)
8272 +-{
8273 +- unsigned long range_end = mm->brk + 0x02000000;
8274 +- return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
8275 +-}
8276 +diff -urNp linux-2.6.26.6/arch/x86/kernel/ptrace.c linux-2.6.26.6/arch/x86/kernel/ptrace.c
8277 +--- linux-2.6.26.6/arch/x86/kernel/ptrace.c 2008-10-08 23:24:05.000000000 -0400
8278 ++++ linux-2.6.26.6/arch/x86/kernel/ptrace.c 2008-10-11 21:54:19.000000000 -0400
8279 +@@ -1371,7 +1371,7 @@ void send_sigtrap(struct task_struct *ts
8280 + info.si_code = TRAP_BRKPT;
8281 +
8282 + /* User-mode ip? */
8283 +- info.si_addr = user_mode_vm(regs) ? (void __user *) regs->ip : NULL;
8284 ++ info.si_addr = user_mode(regs) ? (void __user *) regs->ip : NULL;
8285 +
8286 + /* Send us the fake SIGTRAP */
8287 + force_sig_info(SIGTRAP, &info, tsk);
8288 +diff -urNp linux-2.6.26.6/arch/x86/kernel/reboot.c linux-2.6.26.6/arch/x86/kernel/reboot.c
8289 +--- linux-2.6.26.6/arch/x86/kernel/reboot.c 2008-10-08 23:24:05.000000000 -0400
8290 ++++ linux-2.6.26.6/arch/x86/kernel/reboot.c 2008-10-11 21:54:19.000000000 -0400
8291 +@@ -28,7 +28,7 @@ void (*pm_power_off)(void);
8292 + EXPORT_SYMBOL(pm_power_off);
8293 +
8294 + static long no_idt[3];
8295 +-static int reboot_mode;
8296 ++static unsigned short reboot_mode;
8297 + enum reboot_type reboot_type = BOOT_KBD;
8298 + int reboot_force;
8299 +
8300 +@@ -193,7 +193,7 @@ static struct dmi_system_id __initdata r
8301 + DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
8302 + },
8303 + },
8304 +- { }
8305 ++ { NULL, NULL, {{0, NULL}}, NULL}
8306 + };
8307 +
8308 + static int __init reboot_init(void)
8309 +@@ -209,15 +209,15 @@ core_initcall(reboot_init);
8310 + controller to pulse the CPU reset line, which is more thorough, but
8311 + doesn't work with at least one type of 486 motherboard. It is easy
8312 + to stop this code working; hence the copious comments. */
8313 +-static unsigned long long
8314 +-real_mode_gdt_entries [3] =
8315 ++static struct desc_struct
8316 ++real_mode_gdt_entries [3] __read_only =
8317 + {
8318 +- 0x0000000000000000ULL, /* Null descriptor */
8319 +- 0x00009a000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
8320 +- 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
8321 ++ {{{0x00000000, 0x00000000}}}, /* Null descriptor */
8322 ++ {{{0x0000ffff, 0x00009b00}}}, /* 16-bit real-mode 64k code at 0x00000000 */
8323 ++ {{{0x0100ffff, 0x00009300}}} /* 16-bit real-mode 64k data at 0x00000100 */
8324 + };
8325 +
8326 +-static struct desc_ptr
8327 ++static const struct desc_ptr
8328 + real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries },
8329 + real_mode_idt = { 0x3ff, 0 };
8330 +
8331 +@@ -239,7 +239,7 @@ real_mode_idt = { 0x3ff, 0 };
8332 +
8333 + More could be done here to set up the registers as if a CPU reset had
8334 + occurred; hopefully real BIOSs don't assume much. */
8335 +-static unsigned char real_mode_switch [] =
8336 ++static const unsigned char real_mode_switch [] =
8337 + {
8338 + 0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */
8339 + 0x66, 0x83, 0xe0, 0x11, /* andl $0x00000011,%eax */
8340 +@@ -253,7 +253,7 @@ static unsigned char real_mode_switch []
8341 + 0x24, 0x10, /* f: andb $0x10,al */
8342 + 0x66, 0x0f, 0x22, 0xc0 /* movl %eax,%cr0 */
8343 + };
8344 +-static unsigned char jump_to_bios [] =
8345 ++static const unsigned char jump_to_bios [] =
8346 + {
8347 + 0xea, 0x00, 0x00, 0xff, 0xff /* ljmp $0xffff,$0x0000 */
8348 + };
8349 +@@ -263,7 +263,7 @@ static unsigned char jump_to_bios [] =
8350 + * specified by the code and length parameters.
8351 + * We assume that length will aways be less that 100!
8352 + */
8353 +-void machine_real_restart(unsigned char *code, int length)
8354 ++void machine_real_restart(const unsigned char *code, unsigned int length)
8355 + {
8356 + local_irq_disable();
8357 +
8358 +@@ -283,8 +283,8 @@ void machine_real_restart(unsigned char
8359 + /* Remap the kernel at virtual address zero, as well as offset zero
8360 + from the kernel segment. This assumes the kernel segment starts at
8361 + virtual address PAGE_OFFSET. */
8362 +- memcpy(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
8363 +- sizeof(swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
8364 ++ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
8365 ++ min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
8366 +
8367 + /*
8368 + * Use `swapper_pg_dir' as our page directory.
8369 +@@ -296,16 +296,15 @@ void machine_real_restart(unsigned char
8370 + boot)". This seems like a fairly standard thing that gets set by
8371 + REBOOT.COM programs, and the previous reset routine did this
8372 + too. */
8373 +- *((unsigned short *)0x472) = reboot_mode;
8374 ++ *(unsigned short *)(__va(0x472)) = reboot_mode;
8375 +
8376 + /* For the switch to real mode, copy some code to low memory. It has
8377 + to be in the first 64k because it is running in 16-bit mode, and it
8378 + has to have the same physical and virtual address, because it turns
8379 + off paging. Copy it near the end of the first page, out of the way
8380 + of BIOS variables. */
8381 +- memcpy((void *)(0x1000 - sizeof(real_mode_switch) - 100),
8382 +- real_mode_switch, sizeof (real_mode_switch));
8383 +- memcpy((void *)(0x1000 - 100), code, length);
8384 ++ memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch));
8385 ++ memcpy(__va(0x1000 - 100), code, length);
8386 +
8387 + /* Set up the IDT for real mode. */
8388 + load_idt(&real_mode_idt);
8389 +diff -urNp linux-2.6.26.6/arch/x86/kernel/setup_32.c linux-2.6.26.6/arch/x86/kernel/setup_32.c
8390 +--- linux-2.6.26.6/arch/x86/kernel/setup_32.c 2008-10-08 23:24:05.000000000 -0400
8391 ++++ linux-2.6.26.6/arch/x86/kernel/setup_32.c 2008-10-11 21:55:52.000000000 -0400
8392 +@@ -67,6 +67,7 @@
8393 + #include <asm/bios_ebda.h>
8394 + #include <asm/cacheflush.h>
8395 + #include <asm/processor.h>
8396 ++#include <asm/boot.h>
8397 +
8398 + /* This value is set up by the early boot code to point to the value
8399 + immediately after the boot time page tables. It contains a *physical*
8400 +@@ -341,10 +342,10 @@ early_param("reservetop", parse_reservet
8401 + */
8402 + unsigned long __init find_max_low_pfn(void)
8403 + {
8404 +- unsigned long max_low_pfn;
8405 ++ unsigned long __max_low_pfn;
8406 +
8407 +- max_low_pfn = max_pfn;
8408 +- if (max_low_pfn > MAXMEM_PFN) {
8409 ++ __max_low_pfn = max_pfn;
8410 ++ if (__max_low_pfn > MAXMEM_PFN) {
8411 + if (highmem_pages == -1)
8412 + highmem_pages = max_pfn - MAXMEM_PFN;
8413 + if (highmem_pages + MAXMEM_PFN < max_pfn)
8414 +@@ -353,7 +354,7 @@ unsigned long __init find_max_low_pfn(vo
8415 + printk("only %luMB highmem pages available, ignoring highmem size of %uMB.\n", pages_to_mb(max_pfn - MAXMEM_PFN), pages_to_mb(highmem_pages));
8416 + highmem_pages = 0;
8417 + }
8418 +- max_low_pfn = MAXMEM_PFN;
8419 ++ __max_low_pfn = MAXMEM_PFN;
8420 + #ifndef CONFIG_HIGHMEM
8421 + /* Maximum memory usable is what is directly addressable */
8422 + printk(KERN_WARNING "Warning only %ldMB will be used.\n",
8423 +@@ -381,18 +382,18 @@ unsigned long __init find_max_low_pfn(vo
8424 + highmem_pages = 0;
8425 + }
8426 + if (highmem_pages) {
8427 +- if (max_low_pfn-highmem_pages < 64*1024*1024/PAGE_SIZE){
8428 ++ if (__max_low_pfn-highmem_pages < 64*1024*1024/PAGE_SIZE){
8429 + printk(KERN_ERR "highmem size %uMB results in smaller than 64MB lowmem, ignoring it.\n", pages_to_mb(highmem_pages));
8430 + highmem_pages = 0;
8431 + }
8432 +- max_low_pfn -= highmem_pages;
8433 ++ __max_low_pfn -= highmem_pages;
8434 + }
8435 + #else
8436 + if (highmem_pages)
8437 + printk(KERN_ERR "ignoring highmem size on non-highmem kernel!\n");
8438 + #endif
8439 + }
8440 +- return max_low_pfn;
8441 ++ return __max_low_pfn;
8442 + }
8443 +
8444 + #define BIOS_LOWMEM_KILOBYTES 0x413
8445 +@@ -447,7 +448,7 @@ static void __init reserve_ebda_region(v
8446 +
8447 + #ifndef CONFIG_NEED_MULTIPLE_NODES
8448 + static void __init setup_bootmem_allocator(void);
8449 +-static unsigned long __init setup_memory(void)
8450 ++static void __init setup_memory(void)
8451 + {
8452 + /*
8453 + * partially used pages are not usable - thus
8454 +@@ -477,8 +478,6 @@ static unsigned long __init setup_memory
8455 + pages_to_mb(max_low_pfn));
8456 +
8457 + setup_bootmem_allocator();
8458 +-
8459 +- return max_low_pfn;
8460 + }
8461 +
8462 + static void __init zone_sizes_init(void)
8463 +@@ -498,7 +497,7 @@ static void __init zone_sizes_init(void)
8464 + free_area_init_nodes(max_zone_pfns);
8465 + }
8466 + #else
8467 +-extern unsigned long __init setup_memory(void);
8468 ++extern void __init setup_memory(void);
8469 + extern void zone_sizes_init(void);
8470 + #endif /* !CONFIG_NEED_MULTIPLE_NODES */
8471 +
8472 +@@ -662,8 +661,8 @@ void __init setup_bootmem_allocator(void
8473 + * the (very unlikely) case of us accidentally initializing the
8474 + * bootmem allocator with an invalid RAM area.
8475 + */
8476 +- reserve_bootmem(__pa_symbol(_text), (PFN_PHYS(min_low_pfn) +
8477 +- bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text),
8478 ++ reserve_bootmem(LOAD_PHYSICAL_ADDR, (PFN_PHYS(min_low_pfn) +
8479 ++ bootmap_size + PAGE_SIZE-1) - LOAD_PHYSICAL_ADDR,
8480 + BOOTMEM_DEFAULT);
8481 +
8482 + /*
8483 +@@ -758,8 +757,6 @@ DEFINE_PER_CPU(int, x86_cpu_to_node_map)
8484 + */
8485 + void __init setup_arch(char **cmdline_p)
8486 + {
8487 +- unsigned long max_low_pfn;
8488 +-
8489 + memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
8490 + pre_setup_arch_hook();
8491 + early_cpu_init();
8492 +@@ -799,14 +796,14 @@ void __init setup_arch(char **cmdline_p)
8493 +
8494 + if (!boot_params.hdr.root_flags)
8495 + root_mountflags &= ~MS_RDONLY;
8496 +- init_mm.start_code = (unsigned long) _text;
8497 +- init_mm.end_code = (unsigned long) _etext;
8498 ++ init_mm.start_code = ktla_ktva((unsigned long) _text);
8499 ++ init_mm.end_code = ktla_ktva((unsigned long) _etext);
8500 + init_mm.end_data = (unsigned long) _edata;
8501 + init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
8502 +
8503 +- code_resource.start = virt_to_phys(_text);
8504 +- code_resource.end = virt_to_phys(_etext)-1;
8505 +- data_resource.start = virt_to_phys(_etext);
8506 ++ code_resource.start = virt_to_phys(ktla_ktva(_text));
8507 ++ code_resource.end = virt_to_phys(ktla_ktva(_etext))-1;
8508 ++ data_resource.start = virt_to_phys(_data);
8509 + data_resource.end = virt_to_phys(_edata)-1;
8510 + bss_resource.start = virt_to_phys(&__bss_start);
8511 + bss_resource.end = virt_to_phys(&__bss_stop)-1;
8512 +@@ -830,7 +827,7 @@ void __init setup_arch(char **cmdline_p)
8513 + if (mtrr_trim_uncached_memory(max_pfn))
8514 + propagate_e820_map();
8515 +
8516 +- max_low_pfn = setup_memory();
8517 ++ setup_memory();
8518 +
8519 + #ifdef CONFIG_KVM_CLOCK
8520 + kvmclock_init();
8521 +diff -urNp linux-2.6.26.6/arch/x86/kernel/setup64.c linux-2.6.26.6/arch/x86/kernel/setup64.c
8522 +--- linux-2.6.26.6/arch/x86/kernel/setup64.c 2008-10-08 23:24:05.000000000 -0400
8523 ++++ linux-2.6.26.6/arch/x86/kernel/setup64.c 2008-10-11 21:55:07.000000000 -0400
8524 +@@ -38,15 +38,13 @@ struct x8664_pda *_cpu_pda[NR_CPUS] __re
8525 + EXPORT_SYMBOL(_cpu_pda);
8526 + struct x8664_pda boot_cpu_pda[NR_CPUS] __cacheline_aligned;
8527 +
8528 +-struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
8529 ++struct desc_ptr idt_descr __read_only = { 256 * 16 - 1, (unsigned long) idt_table };
8530 +
8531 + char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
8532 +
8533 + unsigned long __supported_pte_mask __read_mostly = ~0UL;
8534 + EXPORT_SYMBOL_GPL(__supported_pte_mask);
8535 +
8536 +-static int do_not_nx __cpuinitdata = 0;
8537 +-
8538 + /* noexec=on|off
8539 + Control non executable mappings for 64bit processes.
8540 +
8541 +@@ -59,16 +57,14 @@ static int __init nonx_setup(char *str)
8542 + return -EINVAL;
8543 + if (!strncmp(str, "on", 2)) {
8544 + __supported_pte_mask |= _PAGE_NX;
8545 +- do_not_nx = 0;
8546 + } else if (!strncmp(str, "off", 3)) {
8547 +- do_not_nx = 1;
8548 + __supported_pte_mask &= ~_PAGE_NX;
8549 + }
8550 + return 0;
8551 + }
8552 + early_param("noexec", nonx_setup);
8553 +
8554 +-int force_personality32 = 0;
8555 ++int force_personality32;
8556 +
8557 + /* noexec32=on|off
8558 + Control non executable heap for 32bit processes.
8559 +@@ -151,7 +147,7 @@ void __cpuinit check_efer(void)
8560 + unsigned long efer;
8561 +
8562 + rdmsrl(MSR_EFER, efer);
8563 +- if (!(efer & EFER_NX) || do_not_nx) {
8564 ++ if (!(efer & EFER_NX)) {
8565 + __supported_pte_mask &= ~_PAGE_NX;
8566 + }
8567 + }
8568 +@@ -174,12 +170,13 @@ DEFINE_PER_CPU(struct orig_ist, orig_ist
8569 + void __cpuinit cpu_init (void)
8570 + {
8571 + int cpu = stack_smp_processor_id();
8572 +- struct tss_struct *t = &per_cpu(init_tss, cpu);
8573 ++ struct tss_struct *t = init_tss + cpu;
8574 + struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu);
8575 + unsigned long v;
8576 + char *estacks = NULL;
8577 + struct task_struct *me;
8578 + int i;
8579 ++ struct desc_ptr cpu_gdt_descr = { .size = GDT_SIZE - 1, .address = (unsigned long)get_cpu_gdt_table(cpu)};
8580 +
8581 + /* CPU 0 is initialised in head64.c */
8582 + if (cpu != 0) {
8583 +@@ -197,14 +194,9 @@ void __cpuinit cpu_init (void)
8584 + clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
8585 +
8586 + /*
8587 +- * Initialize the per-CPU GDT with the boot GDT,
8588 +- * and set up the GDT descriptor:
8589 ++ * Initialize the per-CPU GDT with the boot GDT:
8590 + */
8591 +- if (cpu)
8592 +- memcpy(get_cpu_gdt_table(cpu), cpu_gdt_table, GDT_SIZE);
8593 +-
8594 +- cpu_gdt_descr[cpu].size = GDT_SIZE;
8595 +- load_gdt((const struct desc_ptr *)&cpu_gdt_descr[cpu]);
8596 ++ load_gdt(&cpu_gdt_descr);
8597 + load_idt((const struct desc_ptr *)&idt_descr);
8598 +
8599 + memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
8600 +diff -urNp linux-2.6.26.6/arch/x86/kernel/signal_32.c linux-2.6.26.6/arch/x86/kernel/signal_32.c
8601 +--- linux-2.6.26.6/arch/x86/kernel/signal_32.c 2008-10-08 23:24:05.000000000 -0400
8602 ++++ linux-2.6.26.6/arch/x86/kernel/signal_32.c 2008-10-11 21:54:19.000000000 -0400
8603 +@@ -378,9 +378,9 @@ setup_frame(int sig, struct k_sigaction
8604 + }
8605 +
8606 + if (current->mm->context.vdso)
8607 +- restorer = VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
8608 ++ restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
8609 + else
8610 +- restorer = &frame->retcode;
8611 ++ restorer = (void __user *)&frame->retcode;
8612 + if (ka->sa.sa_flags & SA_RESTORER)
8613 + restorer = ka->sa.sa_restorer;
8614 +
8615 +@@ -460,7 +460,7 @@ static int setup_rt_frame(int sig, struc
8616 + goto give_sigsegv;
8617 +
8618 + /* Set up to return from userspace. */
8619 +- restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
8620 ++ restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
8621 + if (ka->sa.sa_flags & SA_RESTORER)
8622 + restorer = ka->sa.sa_restorer;
8623 + err |= __put_user(restorer, &frame->pretcode);
8624 +@@ -590,7 +590,7 @@ static void do_signal(struct pt_regs *re
8625 + * X86_32: vm86 regs switched out by assembly code before reaching
8626 + * here, so testing against kernel CS suffices.
8627 + */
8628 +- if (!user_mode(regs))
8629 ++ if (!user_mode_novm(regs))
8630 + return;
8631 +
8632 + if (current_thread_info()->status & TS_RESTORE_SIGMASK)
8633 +diff -urNp linux-2.6.26.6/arch/x86/kernel/signal_64.c linux-2.6.26.6/arch/x86/kernel/signal_64.c
8634 +--- linux-2.6.26.6/arch/x86/kernel/signal_64.c 2008-10-08 23:24:05.000000000 -0400
8635 ++++ linux-2.6.26.6/arch/x86/kernel/signal_64.c 2008-10-11 21:54:19.000000000 -0400
8636 +@@ -312,8 +312,8 @@ static int setup_rt_frame(int sig, struc
8637 + err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
8638 + err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
8639 + if (sizeof(*set) == 16) {
8640 +- __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
8641 +- __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
8642 ++ err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
8643 ++ err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
8644 + } else
8645 + err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
8646 +
8647 +diff -urNp linux-2.6.26.6/arch/x86/kernel/smpboot.c linux-2.6.26.6/arch/x86/kernel/smpboot.c
8648 +--- linux-2.6.26.6/arch/x86/kernel/smpboot.c 2008-10-08 23:24:05.000000000 -0400
8649 ++++ linux-2.6.26.6/arch/x86/kernel/smpboot.c 2008-10-11 21:55:07.000000000 -0400
8650 +@@ -847,15 +847,13 @@ static int __cpuinit do_boot_cpu(int api
8651 + .cpu = cpu,
8652 + .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
8653 + };
8654 ++
8655 ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
8656 ++ unsigned long cr0;
8657 ++#endif
8658 ++
8659 + INIT_WORK(&c_idle.work, do_fork_idle);
8660 + #ifdef CONFIG_X86_64
8661 +- /* allocate memory for gdts of secondary cpus. Hotplug is considered */
8662 +- if (!cpu_gdt_descr[cpu].address &&
8663 +- !(cpu_gdt_descr[cpu].address = get_zeroed_page(GFP_KERNEL))) {
8664 +- printk(KERN_ERR "Failed to allocate GDT for CPU %d\n", cpu);
8665 +- return -1;
8666 +- }
8667 +-
8668 + /* Allocate node local memory for AP pdas */
8669 + if (cpu_pda(cpu) == &boot_cpu_pda[cpu]) {
8670 + struct x8664_pda *newpda, *pda;
8671 +@@ -905,7 +903,17 @@ do_rest:
8672 + #ifdef CONFIG_X86_32
8673 + per_cpu(current_task, cpu) = c_idle.idle;
8674 + init_gdt(cpu);
8675 ++
8676 ++#ifdef CONFIG_PAX_KERNEXEC
8677 ++ pax_open_kernel(cr0);
8678 ++#endif
8679 ++
8680 + early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
8681 ++
8682 ++#ifdef CONFIG_PAX_KERNEXEC
8683 ++ pax_close_kernel(cr0);
8684 ++#endif
8685 ++
8686 + c_idle.idle->thread.ip = (unsigned long) start_secondary;
8687 + /* Stack for startup_32 can be just as for start_secondary onwards */
8688 + stack_start.sp = (void *) c_idle.idle->thread.sp;
8689 +@@ -913,7 +921,7 @@ do_rest:
8690 + #else
8691 + cpu_pda(cpu)->pcurrent = c_idle.idle;
8692 + init_rsp = c_idle.idle->thread.sp;
8693 +- load_sp0(&per_cpu(init_tss, cpu), &c_idle.idle->thread);
8694 ++ load_sp0(init_tss + cpu, &c_idle.idle->thread);
8695 + initial_code = (unsigned long)start_secondary;
8696 + clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
8697 + #endif
8698 +diff -urNp linux-2.6.26.6/arch/x86/kernel/smpcommon.c linux-2.6.26.6/arch/x86/kernel/smpcommon.c
8699 +--- linux-2.6.26.6/arch/x86/kernel/smpcommon.c 2008-10-08 23:24:05.000000000 -0400
8700 ++++ linux-2.6.26.6/arch/x86/kernel/smpcommon.c 2008-10-11 21:55:07.000000000 -0400
8701 +@@ -3,9 +3,10 @@
8702 + */
8703 + #include <linux/module.h>
8704 + #include <asm/smp.h>
8705 ++#include <asm/sections.h>
8706 +
8707 + #ifdef CONFIG_X86_32
8708 +-DEFINE_PER_CPU(unsigned long, this_cpu_off);
8709 ++DEFINE_PER_CPU(unsigned long, this_cpu_off) = (unsigned long)__per_cpu_start;
8710 + EXPORT_PER_CPU_SYMBOL(this_cpu_off);
8711 +
8712 + /* Initialize the CPU's GDT. This is either the boot CPU doing itself
8713 +@@ -13,15 +14,19 @@ EXPORT_PER_CPU_SYMBOL(this_cpu_off);
8714 + secondary which will soon come up. */
8715 + __cpuinit void init_gdt(int cpu)
8716 + {
8717 +- struct desc_struct *gdt = get_cpu_gdt_table(cpu);
8718 ++ struct desc_struct d, *gdt = get_cpu_gdt_table(cpu);
8719 ++ unsigned long base, limit;
8720 ++
8721 ++ base = per_cpu_offset(cpu);
8722 ++ limit = PERCPU_ENOUGH_ROOM - 1;
8723 ++ if (limit < 64*1024)
8724 ++ pack_descriptor(&d, base, limit, 0x80 | DESCTYPE_S | 0x3, 0x4);
8725 ++ else
8726 ++ pack_descriptor(&d, base, limit >> PAGE_SHIFT, 0x80 | DESCTYPE_S | 0x3, 0xC);
8727 +
8728 +- pack_descriptor(&gdt[GDT_ENTRY_PERCPU],
8729 +- __per_cpu_offset[cpu], 0xFFFFF,
8730 +- 0x2 | DESCTYPE_S, 0x8);
8731 ++ write_gdt_entry(gdt, GDT_ENTRY_PERCPU, &d, DESCTYPE_S);
8732 +
8733 +- gdt[GDT_ENTRY_PERCPU].s = 1;
8734 +-
8735 +- per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu];
8736 ++ per_cpu(this_cpu_off, cpu) = base;
8737 + per_cpu(cpu_number, cpu) = cpu;
8738 + }
8739 + #endif
8740 +diff -urNp linux-2.6.26.6/arch/x86/kernel/step.c linux-2.6.26.6/arch/x86/kernel/step.c
8741 +--- linux-2.6.26.6/arch/x86/kernel/step.c 2008-10-08 23:24:05.000000000 -0400
8742 ++++ linux-2.6.26.6/arch/x86/kernel/step.c 2008-10-11 21:55:07.000000000 -0400
8743 +@@ -23,22 +23,20 @@ unsigned long convert_ip_to_linear(struc
8744 + * and APM bios ones we just ignore here.
8745 + */
8746 + if ((seg & SEGMENT_TI_MASK) == SEGMENT_LDT) {
8747 +- u32 *desc;
8748 ++ struct desc_struct *desc;
8749 + unsigned long base;
8750 +
8751 +- seg &= ~7UL;
8752 ++ seg >>= 3;
8753 +
8754 + mutex_lock(&child->mm->context.lock);
8755 +- if (unlikely((seg >> 3) >= child->mm->context.size))
8756 +- addr = -1L; /* bogus selector, access would fault */
8757 ++ if (unlikely(seg >= child->mm->context.size))
8758 ++ addr = -EINVAL;
8759 + else {
8760 +- desc = child->mm->context.ldt + seg;
8761 +- base = ((desc[0] >> 16) |
8762 +- ((desc[1] & 0xff) << 16) |
8763 +- (desc[1] & 0xff000000));
8764 ++ desc = &child->mm->context.ldt[seg];
8765 ++ base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000);
8766 +
8767 + /* 16-bit code segment? */
8768 +- if (!((desc[1] >> 22) & 1))
8769 ++ if (!((desc->b >> 22) & 1))
8770 + addr &= 0xffff;
8771 + addr += base;
8772 + }
8773 +@@ -54,6 +52,9 @@ static int is_setting_trap_flag(struct t
8774 + unsigned char opcode[15];
8775 + unsigned long addr = convert_ip_to_linear(child, regs);
8776 +
8777 ++ if (addr == -EINVAL)
8778 ++ return 0;
8779 ++
8780 + copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
8781 + for (i = 0; i < copied; i++) {
8782 + switch (opcode[i]) {
8783 +@@ -75,7 +76,7 @@ static int is_setting_trap_flag(struct t
8784 +
8785 + #ifdef CONFIG_X86_64
8786 + case 0x40 ... 0x4f:
8787 +- if (regs->cs != __USER_CS)
8788 ++ if ((regs->cs & 0xffff) != __USER_CS)
8789 + /* 32-bit mode: register increment */
8790 + return 0;
8791 + /* 64-bit mode: REX prefix */
8792 +diff -urNp linux-2.6.26.6/arch/x86/kernel/syscall_table_32.S linux-2.6.26.6/arch/x86/kernel/syscall_table_32.S
8793 +--- linux-2.6.26.6/arch/x86/kernel/syscall_table_32.S 2008-10-08 23:24:05.000000000 -0400
8794 ++++ linux-2.6.26.6/arch/x86/kernel/syscall_table_32.S 2008-10-11 21:54:19.000000000 -0400
8795 +@@ -1,3 +1,4 @@
8796 ++.section .rodata,"a",@progbits
8797 + ENTRY(sys_call_table)
8798 + .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
8799 + .long sys_exit
8800 +diff -urNp linux-2.6.26.6/arch/x86/kernel/sys_i386_32.c linux-2.6.26.6/arch/x86/kernel/sys_i386_32.c
8801 +--- linux-2.6.26.6/arch/x86/kernel/sys_i386_32.c 2008-10-08 23:24:05.000000000 -0400
8802 ++++ linux-2.6.26.6/arch/x86/kernel/sys_i386_32.c 2008-10-11 21:54:19.000000000 -0400
8803 +@@ -22,6 +22,21 @@
8804 + #include <asm/uaccess.h>
8805 + #include <asm/unistd.h>
8806 +
8807 ++int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
8808 ++{
8809 ++ unsigned long pax_task_size = TASK_SIZE;
8810 ++
8811 ++#ifdef CONFIG_PAX_SEGMEXEC
8812 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
8813 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
8814 ++#endif
8815 ++
8816 ++ if (len > pax_task_size || addr > pax_task_size - len)
8817 ++ return -EINVAL;
8818 ++
8819 ++ return 0;
8820 ++}
8821 ++
8822 + asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
8823 + unsigned long prot, unsigned long flags,
8824 + unsigned long fd, unsigned long pgoff)
8825 +@@ -81,6 +96,205 @@ out:
8826 + return err;
8827 + }
8828 +
8829 ++unsigned long
8830 ++arch_get_unmapped_area(struct file *filp, unsigned long addr,
8831 ++ unsigned long len, unsigned long pgoff, unsigned long flags)
8832 ++{
8833 ++ struct mm_struct *mm = current->mm;
8834 ++ struct vm_area_struct *vma;
8835 ++ unsigned long start_addr, pax_task_size = TASK_SIZE;
8836 ++
8837 ++#ifdef CONFIG_PAX_SEGMEXEC
8838 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
8839 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
8840 ++#endif
8841 ++
8842 ++ if (len > pax_task_size)
8843 ++ return -ENOMEM;
8844 ++
8845 ++ if (flags & MAP_FIXED)
8846 ++ return addr;
8847 ++
8848 ++#ifdef CONFIG_PAX_RANDMMAP
8849 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
8850 ++#endif
8851 ++
8852 ++ if (addr) {
8853 ++ addr = PAGE_ALIGN(addr);
8854 ++ vma = find_vma(mm, addr);
8855 ++ if (pax_task_size - len >= addr &&
8856 ++ (!vma || addr + len <= vma->vm_start))
8857 ++ return addr;
8858 ++ }
8859 ++ if (len > mm->cached_hole_size) {
8860 ++ start_addr = addr = mm->free_area_cache;
8861 ++ } else {
8862 ++ start_addr = addr = mm->mmap_base;
8863 ++ mm->cached_hole_size = 0;
8864 ++ }
8865 ++
8866 ++#ifdef CONFIG_PAX_PAGEEXEC
8867 ++ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
8868 ++ start_addr = 0x00110000UL;
8869 ++
8870 ++#ifdef CONFIG_PAX_RANDMMAP
8871 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
8872 ++ start_addr += mm->delta_mmap & 0x03FFF000UL;
8873 ++#endif
8874 ++
8875 ++ if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
8876 ++ start_addr = addr = mm->mmap_base;
8877 ++ else
8878 ++ addr = start_addr;
8879 ++ }
8880 ++#endif
8881 ++
8882 ++full_search:
8883 ++ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
8884 ++ /* At this point: (!vma || addr < vma->vm_end). */
8885 ++ if (pax_task_size - len < addr) {
8886 ++ /*
8887 ++ * Start a new search - just in case we missed
8888 ++ * some holes.
8889 ++ */
8890 ++ if (start_addr != mm->mmap_base) {
8891 ++ start_addr = addr = mm->mmap_base;
8892 ++ mm->cached_hole_size = 0;
8893 ++ goto full_search;
8894 ++ }
8895 ++ return -ENOMEM;
8896 ++ }
8897 ++ if (!vma || addr + len <= vma->vm_start) {
8898 ++ /*
8899 ++ * Remember the place where we stopped the search:
8900 ++ */
8901 ++ mm->free_area_cache = addr + len;
8902 ++ return addr;
8903 ++ }
8904 ++ if (addr + mm->cached_hole_size < vma->vm_start)
8905 ++ mm->cached_hole_size = vma->vm_start - addr;
8906 ++ addr = vma->vm_end;
8907 ++ if (mm->start_brk <= addr && addr < mm->mmap_base) {
8908 ++ start_addr = addr = mm->mmap_base;
8909 ++ mm->cached_hole_size = 0;
8910 ++ goto full_search;
8911 ++ }
8912 ++ }
8913 ++}
8914 ++
8915 ++unsigned long
8916 ++arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
8917 ++ const unsigned long len, const unsigned long pgoff,
8918 ++ const unsigned long flags)
8919 ++{
8920 ++ struct vm_area_struct *vma;
8921 ++ struct mm_struct *mm = current->mm;
8922 ++ unsigned long base = mm->mmap_base, addr = addr0, pax_task_size = TASK_SIZE;
8923 ++
8924 ++#ifdef CONFIG_PAX_SEGMEXEC
8925 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
8926 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
8927 ++#endif
8928 ++
8929 ++ /* requested length too big for entire address space */
8930 ++ if (len > pax_task_size)
8931 ++ return -ENOMEM;
8932 ++
8933 ++ if (flags & MAP_FIXED)
8934 ++ return addr;
8935 ++
8936 ++#ifdef CONFIG_PAX_PAGEEXEC
8937 ++ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
8938 ++ goto bottomup;
8939 ++#endif
8940 ++
8941 ++#ifdef CONFIG_PAX_RANDMMAP
8942 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
8943 ++#endif
8944 ++
8945 ++ /* requesting a specific address */
8946 ++ if (addr) {
8947 ++ addr = PAGE_ALIGN(addr);
8948 ++ vma = find_vma(mm, addr);
8949 ++ if (pax_task_size - len >= addr &&
8950 ++ (!vma || addr + len <= vma->vm_start))
8951 ++ return addr;
8952 ++ }
8953 ++
8954 ++ /* check if free_area_cache is useful for us */
8955 ++ if (len <= mm->cached_hole_size) {
8956 ++ mm->cached_hole_size = 0;
8957 ++ mm->free_area_cache = mm->mmap_base;
8958 ++ }
8959 ++
8960 ++ /* either no address requested or can't fit in requested address hole */
8961 ++ addr = mm->free_area_cache;
8962 ++
8963 ++ /* make sure it can fit in the remaining address space */
8964 ++ if (addr > len) {
8965 ++ vma = find_vma(mm, addr-len);
8966 ++ if (!vma || addr <= vma->vm_start)
8967 ++ /* remember the address as a hint for next time */
8968 ++ return (mm->free_area_cache = addr-len);
8969 ++ }
8970 ++
8971 ++ if (mm->mmap_base < len)
8972 ++ goto bottomup;
8973 ++
8974 ++ addr = mm->mmap_base-len;
8975 ++
8976 ++ do {
8977 ++ /*
8978 ++ * Lookup failure means no vma is above this address,
8979 ++ * else if new region fits below vma->vm_start,
8980 ++ * return with success:
8981 ++ */
8982 ++ vma = find_vma(mm, addr);
8983 ++ if (!vma || addr+len <= vma->vm_start)
8984 ++ /* remember the address as a hint for next time */
8985 ++ return (mm->free_area_cache = addr);
8986 ++
8987 ++ /* remember the largest hole we saw so far */
8988 ++ if (addr + mm->cached_hole_size < vma->vm_start)
8989 ++ mm->cached_hole_size = vma->vm_start - addr;
8990 ++
8991 ++ /* try just below the current vma->vm_start */
8992 ++ addr = vma->vm_start-len;
8993 ++ } while (len < vma->vm_start);
8994 ++
8995 ++bottomup:
8996 ++ /*
8997 ++ * A failed mmap() very likely causes application failure,
8998 ++ * so fall back to the bottom-up function here. This scenario
8999 ++ * can happen with large stack limits and large mmap()
9000 ++ * allocations.
9001 ++ */
9002 ++
9003 ++#ifdef CONFIG_PAX_SEGMEXEC
9004 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
9005 ++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
9006 ++ else
9007 ++#endif
9008 ++
9009 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
9010 ++
9011 ++#ifdef CONFIG_PAX_RANDMMAP
9012 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
9013 ++ mm->mmap_base += mm->delta_mmap;
9014 ++#endif
9015 ++
9016 ++ mm->free_area_cache = mm->mmap_base;
9017 ++ mm->cached_hole_size = ~0UL;
9018 ++ addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
9019 ++ /*
9020 ++ * Restore the topdown base:
9021 ++ */
9022 ++ mm->mmap_base = base;
9023 ++ mm->free_area_cache = base;
9024 ++ mm->cached_hole_size = ~0UL;
9025 ++
9026 ++ return addr;
9027 ++}
9028 +
9029 + struct sel_arg_struct {
9030 + unsigned long n;
9031 +diff -urNp linux-2.6.26.6/arch/x86/kernel/sys_x86_64.c linux-2.6.26.6/arch/x86/kernel/sys_x86_64.c
9032 +--- linux-2.6.26.6/arch/x86/kernel/sys_x86_64.c 2008-10-08 23:24:05.000000000 -0400
9033 ++++ linux-2.6.26.6/arch/x86/kernel/sys_x86_64.c 2008-10-11 21:54:19.000000000 -0400
9034 +@@ -45,8 +45,8 @@ out:
9035 + return error;
9036 + }
9037 +
9038 +-static void find_start_end(unsigned long flags, unsigned long *begin,
9039 +- unsigned long *end)
9040 ++static void find_start_end(struct mm_struct *mm, unsigned long flags,
9041 ++ unsigned long *begin, unsigned long *end)
9042 + {
9043 + if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
9044 + unsigned long new_begin;
9045 +@@ -65,7 +65,7 @@ static void find_start_end(unsigned long
9046 + *begin = new_begin;
9047 + }
9048 + } else {
9049 +- *begin = TASK_UNMAPPED_BASE;
9050 ++ *begin = mm->mmap_base;
9051 + *end = TASK_SIZE;
9052 + }
9053 + }
9054 +@@ -82,11 +82,15 @@ arch_get_unmapped_area(struct file *filp
9055 + if (flags & MAP_FIXED)
9056 + return addr;
9057 +
9058 +- find_start_end(flags, &begin, &end);
9059 ++ find_start_end(mm, flags, &begin, &end);
9060 +
9061 + if (len > end)
9062 + return -ENOMEM;
9063 +
9064 ++#ifdef CONFIG_PAX_RANDMMAP
9065 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
9066 ++#endif
9067 ++
9068 + if (addr) {
9069 + addr = PAGE_ALIGN(addr);
9070 + vma = find_vma(mm, addr);
9071 +@@ -141,7 +145,7 @@ arch_get_unmapped_area_topdown(struct fi
9072 + {
9073 + struct vm_area_struct *vma;
9074 + struct mm_struct *mm = current->mm;
9075 +- unsigned long addr = addr0;
9076 ++ unsigned long base = mm->mmap_base, addr = addr0;
9077 +
9078 + /* requested length too big for entire address space */
9079 + if (len > TASK_SIZE)
9080 +@@ -154,6 +158,10 @@ arch_get_unmapped_area_topdown(struct fi
9081 + if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT))
9082 + goto bottomup;
9083 +
9084 ++#ifdef CONFIG_PAX_RANDMMAP
9085 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
9086 ++#endif
9087 ++
9088 + /* requesting a specific address */
9089 + if (addr) {
9090 + addr = PAGE_ALIGN(addr);
9091 +@@ -211,13 +219,21 @@ bottomup:
9092 + * can happen with large stack limits and large mmap()
9093 + * allocations.
9094 + */
9095 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
9096 ++
9097 ++#ifdef CONFIG_PAX_RANDMMAP
9098 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
9099 ++ mm->mmap_base += mm->delta_mmap;
9100 ++#endif
9101 ++
9102 ++ mm->free_area_cache = mm->mmap_base;
9103 + mm->cached_hole_size = ~0UL;
9104 +- mm->free_area_cache = TASK_UNMAPPED_BASE;
9105 + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
9106 + /*
9107 + * Restore the topdown base:
9108 + */
9109 +- mm->free_area_cache = mm->mmap_base;
9110 ++ mm->mmap_base = base;
9111 ++ mm->free_area_cache = base;
9112 + mm->cached_hole_size = ~0UL;
9113 +
9114 + return addr;
9115 +diff -urNp linux-2.6.26.6/arch/x86/kernel/time_32.c linux-2.6.26.6/arch/x86/kernel/time_32.c
9116 +--- linux-2.6.26.6/arch/x86/kernel/time_32.c 2008-10-08 23:24:05.000000000 -0400
9117 ++++ linux-2.6.26.6/arch/x86/kernel/time_32.c 2008-10-11 21:54:19.000000000 -0400
9118 +@@ -52,20 +52,30 @@ unsigned long profile_pc(struct pt_regs
9119 + if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs) &&
9120 + in_lock_functions(pc)) {
9121 + #ifdef CONFIG_FRAME_POINTER
9122 +- return *(unsigned long *)(regs->bp + 4);
9123 ++ return ktla_ktva(*(unsigned long *)(regs->bp + 4));
9124 + #else
9125 + unsigned long *sp = (unsigned long *)&regs->sp;
9126 +
9127 + /* Return address is either directly at stack pointer
9128 + or above a saved flags. Eflags has bits 22-31 zero,
9129 + kernel addresses don't. */
9130 ++
9131 ++#ifdef CONFIG_PAX_KERNEXEC
9132 ++ return ktla_ktva(sp[0]);
9133 ++#else
9134 + if (sp[0] >> 22)
9135 + return sp[0];
9136 + if (sp[1] >> 22)
9137 + return sp[1];
9138 + #endif
9139 ++
9140 ++#endif
9141 + }
9142 + #endif
9143 ++
9144 ++ if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs))
9145 ++ pc = ktla_ktva(pc);
9146 ++
9147 + return pc;
9148 + }
9149 + EXPORT_SYMBOL(profile_pc);
9150 +diff -urNp linux-2.6.26.6/arch/x86/kernel/tlb_32.c linux-2.6.26.6/arch/x86/kernel/tlb_32.c
9151 +--- linux-2.6.26.6/arch/x86/kernel/tlb_32.c 2008-10-08 23:24:05.000000000 -0400
9152 ++++ linux-2.6.26.6/arch/x86/kernel/tlb_32.c 2008-10-11 21:54:19.000000000 -0400
9153 +@@ -5,7 +5,7 @@
9154 + #include <asm/tlbflush.h>
9155 +
9156 + DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate)
9157 +- ____cacheline_aligned = { &init_mm, 0, };
9158 ++ ____cacheline_aligned = { &init_mm, 0, {0} };
9159 +
9160 + /* must come after the send_IPI functions above for inlining */
9161 + #include <mach_ipi.h>
9162 +diff -urNp linux-2.6.26.6/arch/x86/kernel/tls.c linux-2.6.26.6/arch/x86/kernel/tls.c
9163 +--- linux-2.6.26.6/arch/x86/kernel/tls.c 2008-10-08 23:24:05.000000000 -0400
9164 ++++ linux-2.6.26.6/arch/x86/kernel/tls.c 2008-10-11 21:54:19.000000000 -0400
9165 +@@ -84,6 +84,11 @@ int do_set_thread_area(struct task_struc
9166 + if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
9167 + return -EINVAL;
9168 +
9169 ++#ifdef CONFIG_PAX_SEGMEXEC
9170 ++ if ((p->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
9171 ++ return -EINVAL;
9172 ++#endif
9173 ++
9174 + set_tls_desc(p, idx, &info, 1);
9175 +
9176 + return 0;
9177 +diff -urNp linux-2.6.26.6/arch/x86/kernel/traps_32.c linux-2.6.26.6/arch/x86/kernel/traps_32.c
9178 +--- linux-2.6.26.6/arch/x86/kernel/traps_32.c 2008-10-08 23:24:05.000000000 -0400
9179 ++++ linux-2.6.26.6/arch/x86/kernel/traps_32.c 2008-10-11 21:55:07.000000000 -0400
9180 +@@ -70,14 +70,6 @@ asmlinkage int system_call(void);
9181 + /* Do we ignore FPU interrupts ? */
9182 + char ignore_fpu_irq;
9183 +
9184 +-/*
9185 +- * The IDT has to be page-aligned to simplify the Pentium
9186 +- * F0 0F bug workaround.. We have a special link segment
9187 +- * for this.
9188 +- */
9189 +-gate_desc idt_table[256]
9190 +- __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, };
9191 +-
9192 + asmlinkage void divide_error(void);
9193 + asmlinkage void debug(void);
9194 + asmlinkage void nmi(void);
9195 +@@ -339,22 +331,23 @@ void show_registers(struct pt_regs *regs
9196 + * When in-kernel, we also print out the stack and code at the
9197 + * time of the fault..
9198 + */
9199 +- if (!user_mode_vm(regs)) {
9200 ++ if (!user_mode(regs)) {
9201 + unsigned int code_prologue = code_bytes * 43 / 64;
9202 + unsigned int code_len = code_bytes;
9203 + unsigned char c;
9204 + u8 *ip;
9205 ++ unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->cs) >> 3]);
9206 +
9207 + printk("\n" KERN_EMERG "Stack: ");
9208 + show_stack_log_lvl(NULL, regs, &regs->sp, 0, KERN_EMERG);
9209 +
9210 + printk(KERN_EMERG "Code: ");
9211 +
9212 +- ip = (u8 *)regs->ip - code_prologue;
9213 ++ ip = (u8 *)regs->ip - code_prologue + cs_base;
9214 + if (ip < (u8 *)PAGE_OFFSET ||
9215 + probe_kernel_address(ip, c)) {
9216 + /* try starting at EIP */
9217 +- ip = (u8 *)regs->ip;
9218 ++ ip = (u8 *)regs->ip + cs_base;
9219 + code_len = code_len - code_prologue + 1;
9220 + }
9221 + for (i = 0; i < code_len; i++, ip++) {
9222 +@@ -363,7 +356,7 @@ void show_registers(struct pt_regs *regs
9223 + printk(" Bad EIP value.");
9224 + break;
9225 + }
9226 +- if (ip == (u8 *)regs->ip)
9227 ++ if (ip == (u8 *)regs->ip + cs_base)
9228 + printk("<%02x> ", c);
9229 + else
9230 + printk("%02x ", c);
9231 +@@ -376,6 +369,7 @@ int is_valid_bugaddr(unsigned long ip)
9232 + {
9233 + unsigned short ud2;
9234 +
9235 ++ ip = ktla_ktva(ip);
9236 + if (ip < PAGE_OFFSET)
9237 + return 0;
9238 + if (probe_kernel_address((unsigned short *)ip, ud2))
9239 +@@ -488,7 +482,7 @@ void die(const char *str, struct pt_regs
9240 + static inline void
9241 + die_if_kernel(const char *str, struct pt_regs *regs, long err)
9242 + {
9243 +- if (!user_mode_vm(regs))
9244 ++ if (!user_mode(regs))
9245 + die(str, regs, err);
9246 + }
9247 +
9248 +@@ -498,7 +492,7 @@ do_trap(int trapnr, int signr, char *str
9249 + {
9250 + struct task_struct *tsk = current;
9251 +
9252 +- if (regs->flags & X86_VM_MASK) {
9253 ++ if (v8086_mode(regs)) {
9254 + if (vm86)
9255 + goto vm86_trap;
9256 + goto trap_signal;
9257 +@@ -532,6 +526,12 @@ kernel_trap:
9258 + tsk->thread.trap_no = trapnr;
9259 + die(str, regs, error_code);
9260 + }
9261 ++
9262 ++#ifdef CONFIG_PAX_REFCOUNT
9263 ++ if (trapnr == 4)
9264 ++ pax_report_refcount_overflow(regs);
9265 ++#endif
9266 ++
9267 + return;
9268 +
9269 + vm86_trap:
9270 +@@ -612,7 +612,7 @@ void __kprobes do_general_protection(str
9271 + int cpu;
9272 +
9273 + cpu = get_cpu();
9274 +- tss = &per_cpu(init_tss, cpu);
9275 ++ tss = init_tss + cpu;
9276 + thread = &current->thread;
9277 +
9278 + /*
9279 +@@ -644,12 +644,28 @@ void __kprobes do_general_protection(str
9280 + }
9281 + put_cpu();
9282 +
9283 +- if (regs->flags & X86_VM_MASK)
9284 ++ if (v8086_mode(regs))
9285 + goto gp_in_vm86;
9286 +
9287 +- if (!user_mode(regs))
9288 ++ if (!user_mode_novm(regs))
9289 + goto gp_in_kernel;
9290 +
9291 ++#ifdef CONFIG_PAX_PAGEEXEC
9292 ++ if (!nx_enabled && current->mm && (current->mm->pax_flags & MF_PAX_PAGEEXEC)) {
9293 ++ struct mm_struct *mm = current->mm;
9294 ++ unsigned long limit;
9295 ++
9296 ++ down_write(&mm->mmap_sem);
9297 ++ limit = mm->context.user_cs_limit;
9298 ++ if (limit < TASK_SIZE) {
9299 ++ track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC);
9300 ++ up_write(&mm->mmap_sem);
9301 ++ return;
9302 ++ }
9303 ++ up_write(&mm->mmap_sem);
9304 ++ }
9305 ++#endif
9306 ++
9307 + current->thread.error_code = error_code;
9308 + current->thread.trap_no = 13;
9309 +
9310 +@@ -678,6 +694,13 @@ gp_in_kernel:
9311 + if (notify_die(DIE_GPF, "general protection fault", regs,
9312 + error_code, 13, SIGSEGV) == NOTIFY_STOP)
9313 + return;
9314 ++
9315 ++#ifdef CONFIG_PAX_KERNEXEC
9316 ++ if ((regs->cs & 0xFFFF) == __KERNEL_CS)
9317 ++ die("PAX: suspicious general protection fault", regs, error_code);
9318 ++ else
9319 ++#endif
9320 ++
9321 + die("general protection fault", regs, error_code);
9322 + }
9323 + }
9324 +@@ -779,7 +802,7 @@ void notrace __kprobes die_nmi(struct pt
9325 + * If we are in kernel we are probably nested up pretty bad
9326 + * and might aswell get out now while we still can:
9327 + */
9328 +- if (!user_mode_vm(regs)) {
9329 ++ if (!user_mode(regs)) {
9330 + current->thread.trap_no = 2;
9331 + crash_kexec(regs);
9332 + }
9333 +@@ -925,7 +948,7 @@ void __kprobes do_debug(struct pt_regs *
9334 + goto clear_dr7;
9335 + }
9336 +
9337 +- if (regs->flags & X86_VM_MASK)
9338 ++ if (v8086_mode(regs))
9339 + goto debug_vm86;
9340 +
9341 + /* Save debug status register where ptrace can see it */
9342 +@@ -941,7 +964,7 @@ void __kprobes do_debug(struct pt_regs *
9343 + * check for kernel mode by just checking the CPL
9344 + * of CS.
9345 + */
9346 +- if (!user_mode(regs))
9347 ++ if (!user_mode_novm(regs))
9348 + goto clear_TF_reenable;
9349 + }
9350 +
9351 +@@ -1097,7 +1120,7 @@ void do_simd_coprocessor_error(struct pt
9352 + * Handle strange cache flush from user space exception
9353 + * in all other cases. This is undocumented behaviour.
9354 + */
9355 +- if (regs->flags & X86_VM_MASK) {
9356 ++ if (v8086_mode(regs)) {
9357 + handle_vm86_fault((struct kernel_vm86_regs *)regs, error_code);
9358 + return;
9359 + }
9360 +@@ -1117,19 +1140,14 @@ void do_spurious_interrupt_bug(struct pt
9361 +
9362 + unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp)
9363 + {
9364 +- struct desc_struct *gdt = __get_cpu_var(gdt_page).gdt;
9365 + unsigned long base = (kesp - uesp) & -THREAD_SIZE;
9366 + unsigned long new_kesp = kesp - base;
9367 + unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
9368 +- __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
9369 ++ struct desc_struct ss;
9370 +
9371 + /* Set up base for espfix segment */
9372 +- desc &= 0x00f0ff0000000000ULL;
9373 +- desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
9374 +- ((((__u64)base) << 32) & 0xff00000000000000ULL) |
9375 +- ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
9376 +- (lim_pages & 0xffff);
9377 +- *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
9378 ++ pack_descriptor(&ss, base, lim_pages, 0x93, 0xC);
9379 ++ write_gdt_entry(get_cpu_gdt_table(smp_processor_id()), GDT_ENTRY_ESPFIX_SS, &ss, DESCTYPE_S);
9380 +
9381 + return new_kesp;
9382 + }
9383 +diff -urNp linux-2.6.26.6/arch/x86/kernel/traps_64.c linux-2.6.26.6/arch/x86/kernel/traps_64.c
9384 +--- linux-2.6.26.6/arch/x86/kernel/traps_64.c 2008-10-08 23:24:05.000000000 -0400
9385 ++++ linux-2.6.26.6/arch/x86/kernel/traps_64.c 2008-10-11 21:54:19.000000000 -0400
9386 +@@ -669,6 +669,12 @@ static void __kprobes do_trap(int trapnr
9387 + tsk->thread.trap_no = trapnr;
9388 + die(str, regs, error_code);
9389 + }
9390 ++
9391 ++#ifdef CONFIG_PAX_REFCOUNT
9392 ++ if (trapnr == 4)
9393 ++ pax_report_refcount_overflow(regs);
9394 ++#endif
9395 ++
9396 + return;
9397 + }
9398 +
9399 +diff -urNp linux-2.6.26.6/arch/x86/kernel/tsc_32.c linux-2.6.26.6/arch/x86/kernel/tsc_32.c
9400 +--- linux-2.6.26.6/arch/x86/kernel/tsc_32.c 2008-10-08 23:24:05.000000000 -0400
9401 ++++ linux-2.6.26.6/arch/x86/kernel/tsc_32.c 2008-10-11 21:54:19.000000000 -0400
9402 +@@ -353,7 +353,7 @@ static struct dmi_system_id __initdata b
9403 + DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
9404 + },
9405 + },
9406 +- {}
9407 ++ { NULL, NULL, {{0, NULL}}, NULL}
9408 + };
9409 +
9410 + /*
9411 +diff -urNp linux-2.6.26.6/arch/x86/kernel/vm86_32.c linux-2.6.26.6/arch/x86/kernel/vm86_32.c
9412 +--- linux-2.6.26.6/arch/x86/kernel/vm86_32.c 2008-10-08 23:24:05.000000000 -0400
9413 ++++ linux-2.6.26.6/arch/x86/kernel/vm86_32.c 2008-10-11 21:54:19.000000000 -0400
9414 +@@ -147,7 +147,7 @@ struct pt_regs *save_v86_state(struct ke
9415 + do_exit(SIGSEGV);
9416 + }
9417 +
9418 +- tss = &per_cpu(init_tss, get_cpu());
9419 ++ tss = init_tss + get_cpu();
9420 + current->thread.sp0 = current->thread.saved_sp0;
9421 + current->thread.sysenter_cs = __KERNEL_CS;
9422 + load_sp0(tss, &current->thread);
9423 +@@ -324,7 +324,7 @@ static void do_sys_vm86(struct kernel_vm
9424 + tsk->thread.saved_fs = info->regs32->fs;
9425 + savesegment(gs, tsk->thread.saved_gs);
9426 +
9427 +- tss = &per_cpu(init_tss, get_cpu());
9428 ++ tss = init_tss + get_cpu();
9429 + tsk->thread.sp0 = (unsigned long) &info->VM86_TSS_ESP0;
9430 + if (cpu_has_sep)
9431 + tsk->thread.sysenter_cs = 0;
9432 +diff -urNp linux-2.6.26.6/arch/x86/kernel/vmi_32.c linux-2.6.26.6/arch/x86/kernel/vmi_32.c
9433 +--- linux-2.6.26.6/arch/x86/kernel/vmi_32.c 2008-10-08 23:24:05.000000000 -0400
9434 ++++ linux-2.6.26.6/arch/x86/kernel/vmi_32.c 2008-10-11 21:54:19.000000000 -0400
9435 +@@ -101,18 +101,43 @@ static unsigned patch_internal(int call,
9436 + {
9437 + u64 reloc;
9438 + struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
9439 ++
9440 ++#ifdef CONFIG_PAX_KERNEXEC
9441 ++ unsigned long cr0;
9442 ++#endif
9443 ++
9444 + reloc = call_vrom_long_func(vmi_rom, get_reloc, call);
9445 + switch(rel->type) {
9446 + case VMI_RELOCATION_CALL_REL:
9447 + BUG_ON(len < 5);
9448 ++
9449 ++#ifdef CONFIG_PAX_KERNEXEC
9450 ++ pax_open_kernel(cr0);
9451 ++#endif
9452 ++
9453 + *(char *)insnbuf = MNEM_CALL;
9454 + patch_offset(insnbuf, ip, (unsigned long)rel->eip);
9455 ++
9456 ++#ifdef CONFIG_PAX_KERNEXEC
9457 ++ pax_close_kernel(cr0);
9458 ++#endif
9459 ++
9460 + return 5;
9461 +
9462 + case VMI_RELOCATION_JUMP_REL:
9463 + BUG_ON(len < 5);
9464 ++
9465 ++#ifdef CONFIG_PAX_KERNEXEC
9466 ++ pax_open_kernel(cr0);
9467 ++#endif
9468 ++
9469 + *(char *)insnbuf = MNEM_JMP;
9470 + patch_offset(insnbuf, ip, (unsigned long)rel->eip);
9471 ++
9472 ++#ifdef CONFIG_PAX_KERNEXEC
9473 ++ pax_close_kernel(cr0);
9474 ++#endif
9475 ++
9476 + return 5;
9477 +
9478 + case VMI_RELOCATION_NOP:
9479 +@@ -515,14 +540,14 @@ static void vmi_set_pud(pud_t *pudp, pud
9480 +
9481 + static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
9482 + {
9483 +- const pte_t pte = { .pte = 0 };
9484 ++ const pte_t pte = __pte(0ULL);
9485 + vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE);
9486 + vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
9487 + }
9488 +
9489 + static void vmi_pmd_clear(pmd_t *pmd)
9490 + {
9491 +- const pte_t pte = { .pte = 0 };
9492 ++ const pte_t pte = __pte(0ULL);
9493 + vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD);
9494 + vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD);
9495 + }
9496 +@@ -551,8 +576,8 @@ vmi_startup_ipi_hook(int phys_apicid, un
9497 + ap.ss = __KERNEL_DS;
9498 + ap.esp = (unsigned long) start_esp;
9499 +
9500 +- ap.ds = __USER_DS;
9501 +- ap.es = __USER_DS;
9502 ++ ap.ds = __KERNEL_DS;
9503 ++ ap.es = __KERNEL_DS;
9504 + ap.fs = __KERNEL_PERCPU;
9505 + ap.gs = 0;
9506 +
9507 +@@ -747,12 +772,20 @@ static inline int __init activate_vmi(vo
9508 + u64 reloc;
9509 + const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc;
9510 +
9511 ++#ifdef CONFIG_PAX_KERNEXEC
9512 ++ unsigned long cr0;
9513 ++#endif
9514 ++
9515 + if (call_vrom_func(vmi_rom, vmi_init) != 0) {
9516 + printk(KERN_ERR "VMI ROM failed to initialize!");
9517 + return 0;
9518 + }
9519 + savesegment(cs, kernel_cs);
9520 +
9521 ++#ifdef CONFIG_PAX_KERNEXEC
9522 ++ pax_open_kernel(cr0);
9523 ++#endif
9524 ++
9525 + pv_info.paravirt_enabled = 1;
9526 + pv_info.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
9527 + pv_info.name = "vmi";
9528 +@@ -943,6 +976,10 @@ static inline int __init activate_vmi(vo
9529 +
9530 + para_fill(pv_irq_ops.safe_halt, Halt);
9531 +
9532 ++#ifdef CONFIG_PAX_KERNEXEC
9533 ++ pax_close_kernel(cr0);
9534 ++#endif
9535 ++
9536 + /*
9537 + * Alternative instruction rewriting doesn't happen soon enough
9538 + * to convert VMI_IRET to a call instead of a jump; so we have
9539 +diff -urNp linux-2.6.26.6/arch/x86/kernel/vmlinux_32.lds.S linux-2.6.26.6/arch/x86/kernel/vmlinux_32.lds.S
9540 +--- linux-2.6.26.6/arch/x86/kernel/vmlinux_32.lds.S 2008-10-08 23:24:05.000000000 -0400
9541 ++++ linux-2.6.26.6/arch/x86/kernel/vmlinux_32.lds.S 2008-10-11 21:54:19.000000000 -0400
9542 +@@ -15,6 +15,20 @@
9543 + #include <asm/page.h>
9544 + #include <asm/cache.h>
9545 + #include <asm/boot.h>
9546 ++#include <asm/segment.h>
9547 ++
9548 ++#ifdef CONFIG_X86_PAE
9549 ++#define PMD_SHIFT 21
9550 ++#else
9551 ++#define PMD_SHIFT 22
9552 ++#endif
9553 ++#define PMD_SIZE (1 << PMD_SHIFT)
9554 ++
9555 ++#ifdef CONFIG_PAX_KERNEXEC
9556 ++#define __KERNEL_TEXT_OFFSET (__PAGE_OFFSET + (((____LOAD_PHYSICAL_ADDR + 2*(PMD_SIZE - 1)) - 1) & ~(PMD_SIZE - 1)))
9557 ++#else
9558 ++#define __KERNEL_TEXT_OFFSET 0
9559 ++#endif
9560 +
9561 + OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
9562 + OUTPUT_ARCH(i386)
9563 +@@ -22,90 +36,23 @@ ENTRY(phys_startup_32)
9564 + jiffies = jiffies_64;
9565 +
9566 + PHDRS {
9567 +- text PT_LOAD FLAGS(5); /* R_E */
9568 +- data PT_LOAD FLAGS(7); /* RWE */
9569 +- note PT_NOTE FLAGS(0); /* ___ */
9570 ++ initdata PT_LOAD FLAGS(6); /* RW_ */
9571 ++ percpu PT_LOAD FLAGS(6); /* RW_ */
9572 ++ inittext PT_LOAD FLAGS(5); /* R_E */
9573 ++ text PT_LOAD FLAGS(5); /* R_E */
9574 ++ rodata PT_LOAD FLAGS(4); /* R__ */
9575 ++ data PT_LOAD FLAGS(6); /* RW_ */
9576 ++ note PT_NOTE FLAGS(0); /* ___ */
9577 + }
9578 + SECTIONS
9579 + {
9580 +- . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
9581 +- phys_startup_32 = startup_32 - LOAD_OFFSET;
9582 +-
9583 +- .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
9584 +- _text = .; /* Text and read-only data */
9585 +- *(.text.head)
9586 +- } :text = 0x9090
9587 +-
9588 +- /* read-only */
9589 +- .text : AT(ADDR(.text) - LOAD_OFFSET) {
9590 +- . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
9591 +- *(.text.page_aligned)
9592 +- TEXT_TEXT
9593 +- SCHED_TEXT
9594 +- LOCK_TEXT
9595 +- KPROBES_TEXT
9596 +- *(.fixup)
9597 +- *(.gnu.warning)
9598 +- _etext = .; /* End of text section */
9599 +- } :text = 0x9090
9600 +-
9601 +- . = ALIGN(16); /* Exception table */
9602 +- __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
9603 +- __start___ex_table = .;
9604 +- *(__ex_table)
9605 +- __stop___ex_table = .;
9606 +- }
9607 +-
9608 +- NOTES :text :note
9609 +-
9610 +- BUG_TABLE :text
9611 +-
9612 +- . = ALIGN(4);
9613 +- .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
9614 +- __tracedata_start = .;
9615 +- *(.tracedata)
9616 +- __tracedata_end = .;
9617 +- }
9618 ++ . = LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR;
9619 +
9620 +- RODATA
9621 +-
9622 +- /* writeable */
9623 +- . = ALIGN(PAGE_SIZE);
9624 +- .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
9625 +- DATA_DATA
9626 +- CONSTRUCTORS
9627 +- } :data
9628 +-
9629 +- . = ALIGN(PAGE_SIZE);
9630 +- .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
9631 +- __nosave_begin = .;
9632 +- *(.data.nosave)
9633 +- . = ALIGN(PAGE_SIZE);
9634 +- __nosave_end = .;
9635 +- }
9636 +-
9637 +- . = ALIGN(PAGE_SIZE);
9638 +- .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
9639 +- *(.data.page_aligned)
9640 +- *(.data.idt)
9641 +- }
9642 +-
9643 +- . = ALIGN(32);
9644 +- .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
9645 +- *(.data.cacheline_aligned)
9646 +- }
9647 +-
9648 +- /* rarely changed data like cpu maps */
9649 +- . = ALIGN(32);
9650 +- .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
9651 +- *(.data.read_mostly)
9652 +- _edata = .; /* End of data section */
9653 +- }
9654 +-
9655 +- . = ALIGN(THREAD_SIZE); /* init_task */
9656 +- .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
9657 +- *(.data.init_task)
9658 +- }
9659 ++ .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
9660 ++ __LOAD_PHYSICAL_ADDR = . - LOAD_OFFSET;
9661 ++ phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
9662 ++ *(.text.startup)
9663 ++ } :initdata
9664 +
9665 + /* might get freed after init */
9666 + . = ALIGN(PAGE_SIZE);
9667 +@@ -123,14 +70,8 @@ SECTIONS
9668 + . = ALIGN(PAGE_SIZE);
9669 +
9670 + /* will be freed after init */
9671 +- . = ALIGN(PAGE_SIZE); /* Init code and data */
9672 +- .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
9673 +- __init_begin = .;
9674 +- _sinittext = .;
9675 +- INIT_TEXT
9676 +- _einittext = .;
9677 +- }
9678 + .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
9679 ++ __init_begin = .;
9680 + INIT_DATA
9681 + }
9682 + . = ALIGN(16);
9683 +@@ -170,11 +111,6 @@ SECTIONS
9684 + *(.parainstructions)
9685 + __parainstructions_end = .;
9686 + }
9687 +- /* .exit.text is discard at runtime, not link time, to deal with references
9688 +- from .altinstructions and .eh_frame */
9689 +- .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
9690 +- EXIT_TEXT
9691 +- }
9692 + .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
9693 + EXIT_DATA
9694 + }
9695 +@@ -187,17 +123,144 @@ SECTIONS
9696 + }
9697 + #endif
9698 + . = ALIGN(PAGE_SIZE);
9699 +- .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
9700 +- __per_cpu_start = .;
9701 ++ per_cpu_start = .;
9702 ++ .data.percpu (0) : AT(ADDR(.data.percpu) - LOAD_OFFSET + per_cpu_start) {
9703 ++ __per_cpu_start = . + per_cpu_start;
9704 ++ LONG(0)
9705 + *(.data.percpu)
9706 + *(.data.percpu.shared_aligned)
9707 +- __per_cpu_end = .;
9708 +- }
9709 ++ __per_cpu_end = . + per_cpu_start;
9710 ++ } :percpu
9711 ++ . += per_cpu_start;
9712 + . = ALIGN(PAGE_SIZE);
9713 + /* freed after init ends here */
9714 +
9715 ++ . = ALIGN(PAGE_SIZE); /* Init code and data */
9716 ++ .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
9717 ++ _sinittext = .;
9718 ++ INIT_TEXT
9719 ++ _einittext = .;
9720 ++ } :inittext
9721 ++
9722 ++ /* .exit.text is discard at runtime, not link time, to deal with references
9723 ++ from .altinstructions and .eh_frame */
9724 ++ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
9725 ++ EXIT_TEXT
9726 ++ }
9727 ++
9728 ++ .filler : AT(ADDR(.filler) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
9729 ++ BYTE(0)
9730 ++ . = ALIGN(2*PMD_SIZE) - 1;
9731 ++ }
9732 ++
9733 ++ /* freed after init ends here */
9734 ++
9735 ++ .text.head : AT(ADDR(.text.head) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
9736 ++ __init_end = . + __KERNEL_TEXT_OFFSET;
9737 ++ KERNEL_TEXT_OFFSET = . + __KERNEL_TEXT_OFFSET;
9738 ++ _text = .; /* Text and read-only data */
9739 ++ *(.text.head)
9740 ++ } :text = 0x9090
9741 ++
9742 ++ /* read-only */
9743 ++ .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
9744 ++ . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
9745 ++ *(.text.page_aligned)
9746 ++ TEXT_TEXT
9747 ++ SCHED_TEXT
9748 ++ LOCK_TEXT
9749 ++ KPROBES_TEXT
9750 ++ *(.fixup)
9751 ++ *(.gnu.warning)
9752 ++ _etext = .; /* End of text section */
9753 ++ } :text = 0x9090
9754 ++
9755 ++ . += __KERNEL_TEXT_OFFSET;
9756 ++ . = ALIGN(4096); /* Exception table */
9757 ++ __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
9758 ++ __start___ex_table = .;
9759 ++ *(__ex_table)
9760 ++ __stop___ex_table = .;
9761 ++ } :rodata
9762 ++
9763 ++ NOTES :rodata :note
9764 ++
9765 ++ BUG_TABLE :rodata
9766 ++
9767 ++ . = ALIGN(4);
9768 ++ .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
9769 ++ __tracedata_start = .;
9770 ++ *(.tracedata)
9771 ++ __tracedata_end = .;
9772 ++ }
9773 ++
9774 ++ RO_DATA(PAGE_SIZE)
9775 ++
9776 ++ . = ALIGN(PAGE_SIZE);
9777 ++ .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
9778 ++ *(.idt)
9779 ++ . = ALIGN(PAGE_SIZE);
9780 ++ *(.empty_zero_page)
9781 ++ *(.swapper_pg_pmd)
9782 ++ *(.swapper_pg_dir)
9783 ++ }
9784 ++
9785 ++#ifdef CONFIG_PAX_KERNEXEC
9786 ++
9787 ++#ifdef CONFIG_MODULES
9788 ++ . = ALIGN(PAGE_SIZE);
9789 ++ .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
9790 ++ MODULES_VADDR = .;
9791 ++ BYTE(0)
9792 ++ . += (6 * 1024 * 1024);
9793 ++ . = ALIGN( PMD_SIZE) - 1;
9794 ++ MODULES_END = .;
9795 ++ }
9796 ++#else
9797 ++ . = ALIGN(PMD_SIZE) - 1;
9798 ++#endif
9799 ++
9800 ++#endif
9801 ++
9802 ++ /* writeable */
9803 ++ . = ALIGN(PAGE_SIZE);
9804 ++ .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
9805 ++ _data = .;
9806 ++ DATA_DATA
9807 ++ CONSTRUCTORS
9808 ++ } :data
9809 ++
9810 ++ . = ALIGN(PAGE_SIZE);
9811 ++ .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
9812 ++ __nosave_begin = .;
9813 ++ *(.data.nosave)
9814 ++ . = ALIGN(PAGE_SIZE);
9815 ++ __nosave_end = .;
9816 ++ }
9817 ++
9818 ++ . = ALIGN(PAGE_SIZE);
9819 ++ .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
9820 ++ *(.data.page_aligned)
9821 ++ }
9822 ++
9823 ++ . = ALIGN(32);
9824 ++ .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
9825 ++ *(.data.cacheline_aligned)
9826 ++ }
9827 ++
9828 ++ /* rarely changed data like cpu maps */
9829 ++ . = ALIGN(32);
9830 ++ .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
9831 ++ *(.data.read_mostly)
9832 ++ _edata = .; /* End of data section */
9833 ++ }
9834 ++
9835 ++ . = ALIGN(THREAD_SIZE); /* init_task */
9836 ++ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
9837 ++ *(.data.init_task)
9838 ++ }
9839 ++
9840 + .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
9841 +- __init_end = .;
9842 + __bss_start = .; /* BSS */
9843 + *(.bss.page_aligned)
9844 + *(.bss)
9845 +diff -urNp linux-2.6.26.6/arch/x86/kernel/vmlinux_64.lds.S linux-2.6.26.6/arch/x86/kernel/vmlinux_64.lds.S
9846 +--- linux-2.6.26.6/arch/x86/kernel/vmlinux_64.lds.S 2008-10-08 23:24:05.000000000 -0400
9847 ++++ linux-2.6.26.6/arch/x86/kernel/vmlinux_64.lds.S 2008-10-11 21:54:19.000000000 -0400
9848 +@@ -16,8 +16,8 @@ jiffies_64 = jiffies;
9849 + _proxy_pda = 1;
9850 + PHDRS {
9851 + text PT_LOAD FLAGS(5); /* R_E */
9852 +- data PT_LOAD FLAGS(7); /* RWE */
9853 +- user PT_LOAD FLAGS(7); /* RWE */
9854 ++ data PT_LOAD FLAGS(6); /* RW_ */
9855 ++ user PT_LOAD FLAGS(7); /* RWX */
9856 + data.init PT_LOAD FLAGS(7); /* RWE */
9857 + note PT_NOTE FLAGS(4); /* R__ */
9858 + }
9859 +@@ -51,7 +51,7 @@ SECTIONS
9860 +
9861 + BUG_TABLE :text
9862 +
9863 +- RODATA
9864 ++ RO_DATA(PAGE_SIZE)
9865 +
9866 + . = ALIGN(4);
9867 + .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
9868 +@@ -60,15 +60,18 @@ SECTIONS
9869 + __tracedata_end = .;
9870 + }
9871 +
9872 ++#ifdef CONFIG_PAX_KERNEXEC
9873 ++ . = ALIGN(2*1024*1024); /* Align data segment to PMD size boundary */
9874 ++#else
9875 + . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */
9876 ++#endif
9877 + /* Data */
9878 ++ _data = .;
9879 + .data : AT(ADDR(.data) - LOAD_OFFSET) {
9880 + DATA_DATA
9881 + CONSTRUCTORS
9882 + } :data
9883 +
9884 +- _edata = .; /* End of data section */
9885 +-
9886 + . = ALIGN(PAGE_SIZE);
9887 + . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
9888 + .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
9889 +@@ -79,9 +82,27 @@ SECTIONS
9890 + *(.data.read_mostly)
9891 + }
9892 +
9893 ++ . = ALIGN(THREAD_SIZE); /* init_task */
9894 ++ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
9895 ++ *(.data.init_task)
9896 ++ }
9897 ++
9898 ++ . = ALIGN(PAGE_SIZE);
9899 ++ .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
9900 ++ *(.data.page_aligned)
9901 ++ }
9902 ++
9903 ++ . = ALIGN(PAGE_SIZE);
9904 ++ __nosave_begin = .;
9905 ++ .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
9906 ++ . = ALIGN(PAGE_SIZE);
9907 ++ __nosave_end = .;
9908 ++
9909 ++ _edata = .; /* End of data section */
9910 ++
9911 + #define VSYSCALL_ADDR (-10*1024*1024)
9912 +-#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
9913 +-#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
9914 ++#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
9915 ++#define VSYSCALL_VIRT_ADDR ((ADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
9916 +
9917 + #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
9918 + #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
9919 +@@ -129,23 +150,13 @@ SECTIONS
9920 + #undef VVIRT_OFFSET
9921 + #undef VVIRT
9922 +
9923 +- . = ALIGN(THREAD_SIZE); /* init_task */
9924 +- .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
9925 +- *(.data.init_task)
9926 +- }:data.init
9927 +-
9928 +- . = ALIGN(PAGE_SIZE);
9929 +- .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
9930 +- *(.data.page_aligned)
9931 +- }
9932 +-
9933 + /* might get freed after init */
9934 + . = ALIGN(PAGE_SIZE);
9935 + __smp_alt_begin = .;
9936 + __smp_locks = .;
9937 + .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
9938 + *(.smp_locks)
9939 +- }
9940 ++ } :data.init
9941 + __smp_locks_end = .;
9942 + . = ALIGN(PAGE_SIZE);
9943 + __smp_alt_end = .;
9944 +@@ -221,12 +232,6 @@ SECTIONS
9945 + . = ALIGN(PAGE_SIZE);
9946 + __init_end = .;
9947 +
9948 +- . = ALIGN(PAGE_SIZE);
9949 +- __nosave_begin = .;
9950 +- .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
9951 +- . = ALIGN(PAGE_SIZE);
9952 +- __nosave_end = .;
9953 +-
9954 + __bss_start = .; /* BSS */
9955 + .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
9956 + *(.bss.page_aligned)
9957 +@@ -234,6 +239,7 @@ SECTIONS
9958 + }
9959 + __bss_stop = .;
9960 +
9961 ++ . = ALIGN(2*1024*1024);
9962 + _end = . ;
9963 +
9964 + /* Sections to be discarded */
9965 +diff -urNp linux-2.6.26.6/arch/x86/kernel/vsyscall_64.c linux-2.6.26.6/arch/x86/kernel/vsyscall_64.c
9966 +--- linux-2.6.26.6/arch/x86/kernel/vsyscall_64.c 2008-10-08 23:24:05.000000000 -0400
9967 ++++ linux-2.6.26.6/arch/x86/kernel/vsyscall_64.c 2008-10-11 21:54:19.000000000 -0400
9968 +@@ -235,13 +235,13 @@ static ctl_table kernel_table2[] = {
9969 + .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int),
9970 + .mode = 0644,
9971 + .proc_handler = vsyscall_sysctl_change },
9972 +- {}
9973 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
9974 + };
9975 +
9976 + static ctl_table kernel_root_table2[] = {
9977 + { .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555,
9978 + .child = kernel_table2 },
9979 +- {}
9980 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
9981 + };
9982 + #endif
9983 +
9984 +@@ -251,6 +251,11 @@ static void __cpuinit vsyscall_set_cpu(i
9985 + {
9986 + unsigned long *d;
9987 + unsigned long node = 0;
9988 ++
9989 ++#ifdef CONFIG_PAX_KERNEXEC
9990 ++ unsigned long cr0;
9991 ++#endif
9992 ++
9993 + #ifdef CONFIG_NUMA
9994 + node = cpu_to_node(cpu);
9995 + #endif
9996 +@@ -261,10 +266,20 @@ static void __cpuinit vsyscall_set_cpu(i
9997 + in user space in vgetcpu.
9998 + 12 bits for the CPU and 8 bits for the node. */
9999 + d = (unsigned long *)(get_cpu_gdt_table(cpu) + GDT_ENTRY_PER_CPU);
10000 ++
10001 ++#ifdef CONFIG_PAX_KERNEXEC
10002 ++ pax_open_kernel(cr0);
10003 ++#endif
10004 ++
10005 + *d = 0x0f40000000000ULL;
10006 + *d |= cpu;
10007 + *d |= (node & 0xf) << 12;
10008 + *d |= (node >> 4) << 48;
10009 ++
10010 ++#ifdef CONFIG_PAX_KERNEXEC
10011 ++ pax_close_kernel(cr0);
10012 ++#endif
10013 ++
10014 + }
10015 +
10016 + static void __cpuinit cpu_vsyscall_init(void *arg)
10017 +diff -urNp linux-2.6.26.6/arch/x86/kernel/x8664_ksyms_64.c linux-2.6.26.6/arch/x86/kernel/x8664_ksyms_64.c
10018 +--- linux-2.6.26.6/arch/x86/kernel/x8664_ksyms_64.c 2008-10-08 23:24:05.000000000 -0400
10019 ++++ linux-2.6.26.6/arch/x86/kernel/x8664_ksyms_64.c 2008-10-11 21:54:19.000000000 -0400
10020 +@@ -53,8 +53,3 @@ EXPORT_SYMBOL(init_level4_pgt);
10021 + EXPORT_SYMBOL(load_gs_index);
10022 +
10023 + EXPORT_SYMBOL(_proxy_pda);
10024 +-
10025 +-#ifdef CONFIG_PARAVIRT
10026 +-/* Virtualized guests may want to use it */
10027 +-EXPORT_SYMBOL_GPL(cpu_gdt_descr);
10028 +-#endif
10029 +diff -urNp linux-2.6.26.6/arch/x86/kvm/i8254.c linux-2.6.26.6/arch/x86/kvm/i8254.c
10030 +--- linux-2.6.26.6/arch/x86/kvm/i8254.c 2008-10-08 23:24:05.000000000 -0400
10031 ++++ linux-2.6.26.6/arch/x86/kvm/i8254.c 2008-10-11 21:55:52.000000000 -0400
10032 +@@ -91,7 +91,7 @@ static void pit_set_gate(struct kvm *kvm
10033 + c->gate = val;
10034 + }
10035 +
10036 +-int pit_get_gate(struct kvm *kvm, int channel)
10037 ++static int pit_get_gate(struct kvm *kvm, int channel)
10038 + {
10039 + WARN_ON(!mutex_is_locked(&kvm->arch.vpit->pit_state.lock));
10040 +
10041 +@@ -193,7 +193,7 @@ static void pit_latch_status(struct kvm
10042 + }
10043 + }
10044 +
10045 +-int __pit_timer_fn(struct kvm_kpit_state *ps)
10046 ++static int __pit_timer_fn(struct kvm_kpit_state *ps)
10047 + {
10048 + struct kvm_vcpu *vcpu0 = ps->pit->kvm->vcpus[0];
10049 + struct kvm_kpit_timer *pt = &ps->pit_timer;
10050 +@@ -575,7 +575,7 @@ void kvm_free_pit(struct kvm *kvm)
10051 + }
10052 + }
10053 +
10054 +-void __inject_pit_timer_intr(struct kvm *kvm)
10055 ++static void __inject_pit_timer_intr(struct kvm *kvm)
10056 + {
10057 + mutex_lock(&kvm->lock);
10058 + kvm_ioapic_set_irq(kvm->arch.vioapic, 0, 1);
10059 +diff -urNp linux-2.6.26.6/arch/x86/kvm/mmu.c linux-2.6.26.6/arch/x86/kvm/mmu.c
10060 +--- linux-2.6.26.6/arch/x86/kvm/mmu.c 2008-10-08 23:24:05.000000000 -0400
10061 ++++ linux-2.6.26.6/arch/x86/kvm/mmu.c 2008-10-11 21:55:52.000000000 -0400
10062 +@@ -1950,7 +1950,7 @@ void kvm_mmu_zap_all(struct kvm *kvm)
10063 + kvm_flush_remote_tlbs(kvm);
10064 + }
10065 +
10066 +-void kvm_mmu_remove_one_alloc_mmu_page(struct kvm *kvm)
10067 ++static void kvm_mmu_remove_one_alloc_mmu_page(struct kvm *kvm)
10068 + {
10069 + struct kvm_mmu_page *page;
10070 +
10071 +diff -urNp linux-2.6.26.6/arch/x86/kvm/svm.c linux-2.6.26.6/arch/x86/kvm/svm.c
10072 +--- linux-2.6.26.6/arch/x86/kvm/svm.c 2008-10-08 23:24:05.000000000 -0400
10073 ++++ linux-2.6.26.6/arch/x86/kvm/svm.c 2008-10-11 21:54:19.000000000 -0400
10074 +@@ -1478,7 +1478,19 @@ static void reload_tss(struct kvm_vcpu *
10075 + int cpu = raw_smp_processor_id();
10076 +
10077 + struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu);
10078 ++
10079 ++#ifdef CONFIG_PAX_KERNEXEC
10080 ++ unsigned long cr0;
10081 ++
10082 ++ pax_open_kernel(cr0);
10083 ++#endif
10084 ++
10085 + svm_data->tss_desc->type = 9; /* available 32/64-bit TSS */
10086 ++
10087 ++#ifdef CONFIG_PAX_KERNEXEC
10088 ++ pax_close_kernel(cr0);
10089 ++#endif
10090 ++
10091 + load_TR_desc();
10092 + }
10093 +
10094 +diff -urNp linux-2.6.26.6/arch/x86/kvm/vmx.c linux-2.6.26.6/arch/x86/kvm/vmx.c
10095 +--- linux-2.6.26.6/arch/x86/kvm/vmx.c 2008-10-08 23:24:05.000000000 -0400
10096 ++++ linux-2.6.26.6/arch/x86/kvm/vmx.c 2008-10-11 21:55:52.000000000 -0400
10097 +@@ -111,7 +111,7 @@ static struct vmcs_config {
10098 + u32 vmentry_ctrl;
10099 + } vmcs_config;
10100 +
10101 +-struct vmx_capability {
10102 ++static struct vmx_capability {
10103 + u32 ept;
10104 + u32 vpid;
10105 + } vmx_capability;
10106 +@@ -475,9 +475,23 @@ static void reload_tss(void)
10107 + struct descriptor_table gdt;
10108 + struct desc_struct *descs;
10109 +
10110 ++#ifdef CONFIG_PAX_KERNEXEC
10111 ++ unsigned long cr0;
10112 ++#endif
10113 ++
10114 + get_gdt(&gdt);
10115 + descs = (void *)gdt.base;
10116 ++
10117 ++#ifdef CONFIG_PAX_KERNEXEC
10118 ++ pax_open_kernel(cr0);
10119 ++#endif
10120 ++
10121 + descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
10122 ++
10123 ++#ifdef CONFIG_PAX_KERNEXEC
10124 ++ pax_close_kernel(cr0);
10125 ++#endif
10126 ++
10127 + load_TR_desc();
10128 + }
10129 +
10130 +@@ -1824,7 +1838,7 @@ static void allocate_vpid(struct vcpu_vm
10131 + spin_unlock(&vmx_vpid_lock);
10132 + }
10133 +
10134 +-void vmx_disable_intercept_for_msr(struct page *msr_bitmap, u32 msr)
10135 ++static void vmx_disable_intercept_for_msr(struct page *msr_bitmap, u32 msr)
10136 + {
10137 + void *va;
10138 +
10139 +@@ -2956,7 +2970,7 @@ static void vmx_vcpu_run(struct kvm_vcpu
10140 + vcpu->arch.interrupt_window_open =
10141 + (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
10142 +
10143 +- asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
10144 ++ asm("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS));
10145 + vmx->launched = 1;
10146 +
10147 + intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
10148 +diff -urNp linux-2.6.26.6/arch/x86/kvm/x86.c linux-2.6.26.6/arch/x86/kvm/x86.c
10149 +--- linux-2.6.26.6/arch/x86/kvm/x86.c 2008-10-08 23:24:05.000000000 -0400
10150 ++++ linux-2.6.26.6/arch/x86/kvm/x86.c 2008-10-11 21:55:52.000000000 -0400
10151 +@@ -63,34 +63,34 @@ static int kvm_dev_ioctl_get_supported_c
10152 + struct kvm_x86_ops *kvm_x86_ops;
10153 +
10154 + struct kvm_stats_debugfs_item debugfs_entries[] = {
10155 +- { "pf_fixed", VCPU_STAT(pf_fixed) },
10156 +- { "pf_guest", VCPU_STAT(pf_guest) },
10157 +- { "tlb_flush", VCPU_STAT(tlb_flush) },
10158 +- { "invlpg", VCPU_STAT(invlpg) },
10159 +- { "exits", VCPU_STAT(exits) },
10160 +- { "io_exits", VCPU_STAT(io_exits) },
10161 +- { "mmio_exits", VCPU_STAT(mmio_exits) },
10162 +- { "signal_exits", VCPU_STAT(signal_exits) },
10163 +- { "irq_window", VCPU_STAT(irq_window_exits) },
10164 +- { "halt_exits", VCPU_STAT(halt_exits) },
10165 +- { "halt_wakeup", VCPU_STAT(halt_wakeup) },
10166 +- { "hypercalls", VCPU_STAT(hypercalls) },
10167 +- { "request_irq", VCPU_STAT(request_irq_exits) },
10168 +- { "irq_exits", VCPU_STAT(irq_exits) },
10169 +- { "host_state_reload", VCPU_STAT(host_state_reload) },
10170 +- { "efer_reload", VCPU_STAT(efer_reload) },
10171 +- { "fpu_reload", VCPU_STAT(fpu_reload) },
10172 +- { "insn_emulation", VCPU_STAT(insn_emulation) },
10173 +- { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail) },
10174 +- { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped) },
10175 +- { "mmu_pte_write", VM_STAT(mmu_pte_write) },
10176 +- { "mmu_pte_updated", VM_STAT(mmu_pte_updated) },
10177 +- { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped) },
10178 +- { "mmu_flooded", VM_STAT(mmu_flooded) },
10179 +- { "mmu_recycled", VM_STAT(mmu_recycled) },
10180 +- { "mmu_cache_miss", VM_STAT(mmu_cache_miss) },
10181 +- { "remote_tlb_flush", VM_STAT(remote_tlb_flush) },
10182 +- { "largepages", VM_STAT(lpages) },
10183 ++ { "pf_fixed", VCPU_STAT(pf_fixed), NULL },
10184 ++ { "pf_guest", VCPU_STAT(pf_guest), NULL },
10185 ++ { "tlb_flush", VCPU_STAT(tlb_flush), NULL },
10186 ++ { "invlpg", VCPU_STAT(invlpg), NULL },
10187 ++ { "exits", VCPU_STAT(exits), NULL },
10188 ++ { "io_exits", VCPU_STAT(io_exits), NULL },
10189 ++ { "mmio_exits", VCPU_STAT(mmio_exits), NULL },
10190 ++ { "signal_exits", VCPU_STAT(signal_exits), NULL },
10191 ++ { "irq_window", VCPU_STAT(irq_window_exits), NULL },
10192 ++ { "halt_exits", VCPU_STAT(halt_exits), NULL },
10193 ++ { "halt_wakeup", VCPU_STAT(halt_wakeup), NULL },
10194 ++ { "hypercalls", VCPU_STAT(hypercalls), NULL },
10195 ++ { "request_irq", VCPU_STAT(request_irq_exits), NULL },
10196 ++ { "irq_exits", VCPU_STAT(irq_exits), NULL },
10197 ++ { "host_state_reload", VCPU_STAT(host_state_reload), NULL },
10198 ++ { "efer_reload", VCPU_STAT(efer_reload), NULL },
10199 ++ { "fpu_reload", VCPU_STAT(fpu_reload), NULL },
10200 ++ { "insn_emulation", VCPU_STAT(insn_emulation), NULL },
10201 ++ { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail), NULL },
10202 ++ { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped), NULL },
10203 ++ { "mmu_pte_write", VM_STAT(mmu_pte_write), NULL },
10204 ++ { "mmu_pte_updated", VM_STAT(mmu_pte_updated), NULL },
10205 ++ { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped), NULL },
10206 ++ { "mmu_flooded", VM_STAT(mmu_flooded), NULL },
10207 ++ { "mmu_recycled", VM_STAT(mmu_recycled), NULL },
10208 ++ { "mmu_cache_miss", VM_STAT(mmu_cache_miss), NULL },
10209 ++ { "remote_tlb_flush", VM_STAT(remote_tlb_flush), NULL },
10210 ++ { "largepages", VM_STAT(lpages), NULL },
10211 + { NULL }
10212 + };
10213 +
10214 +@@ -1254,7 +1254,7 @@ static int kvm_vcpu_ioctl_set_lapic(stru
10215 + static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
10216 + struct kvm_interrupt *irq)
10217 + {
10218 +- if (irq->irq < 0 || irq->irq >= 256)
10219 ++ if (irq->irq >= 256)
10220 + return -EINVAL;
10221 + if (irqchip_in_kernel(vcpu->kvm))
10222 + return -ENXIO;
10223 +@@ -3411,7 +3411,7 @@ static int load_state_from_tss16(struct
10224 + return 0;
10225 + }
10226 +
10227 +-int kvm_task_switch_16(struct kvm_vcpu *vcpu, u16 tss_selector,
10228 ++static int kvm_task_switch_16(struct kvm_vcpu *vcpu, u16 tss_selector,
10229 + u32 old_tss_base,
10230 + struct desc_struct *nseg_desc)
10231 + {
10232 +@@ -3440,7 +3440,7 @@ out:
10233 + return ret;
10234 + }
10235 +
10236 +-int kvm_task_switch_32(struct kvm_vcpu *vcpu, u16 tss_selector,
10237 ++static int kvm_task_switch_32(struct kvm_vcpu *vcpu, u16 tss_selector,
10238 + u32 old_tss_base,
10239 + struct desc_struct *nseg_desc)
10240 + {
10241 +diff -urNp linux-2.6.26.6/arch/x86/lib/checksum_32.S linux-2.6.26.6/arch/x86/lib/checksum_32.S
10242 +--- linux-2.6.26.6/arch/x86/lib/checksum_32.S 2008-10-08 23:24:05.000000000 -0400
10243 ++++ linux-2.6.26.6/arch/x86/lib/checksum_32.S 2008-10-11 21:54:19.000000000 -0400
10244 +@@ -28,7 +28,8 @@
10245 + #include <linux/linkage.h>
10246 + #include <asm/dwarf2.h>
10247 + #include <asm/errno.h>
10248 +-
10249 ++#include <asm/segment.h>
10250 ++
10251 + /*
10252 + * computes a partial checksum, e.g. for TCP/UDP fragments
10253 + */
10254 +@@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic (
10255 +
10256 + #define ARGBASE 16
10257 + #define FP 12
10258 +-
10259 +-ENTRY(csum_partial_copy_generic)
10260 ++
10261 ++ENTRY(csum_partial_copy_generic_to_user)
10262 + CFI_STARTPROC
10263 ++ pushl $(__USER_DS)
10264 ++ CFI_ADJUST_CFA_OFFSET 4
10265 ++ popl %es
10266 ++ CFI_ADJUST_CFA_OFFSET -4
10267 ++ jmp csum_partial_copy_generic
10268 ++
10269 ++ENTRY(csum_partial_copy_generic_from_user)
10270 ++ pushl $(__USER_DS)
10271 ++ CFI_ADJUST_CFA_OFFSET 4
10272 ++ popl %ds
10273 ++ CFI_ADJUST_CFA_OFFSET -4
10274 ++
10275 ++ENTRY(csum_partial_copy_generic)
10276 + subl $4,%esp
10277 + CFI_ADJUST_CFA_OFFSET 4
10278 + pushl %edi
10279 +@@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic)
10280 + jmp 4f
10281 + SRC(1: movw (%esi), %bx )
10282 + addl $2, %esi
10283 +-DST( movw %bx, (%edi) )
10284 ++DST( movw %bx, %es:(%edi) )
10285 + addl $2, %edi
10286 + addw %bx, %ax
10287 + adcl $0, %eax
10288 +@@ -343,30 +357,30 @@ DST( movw %bx, (%edi) )
10289 + SRC(1: movl (%esi), %ebx )
10290 + SRC( movl 4(%esi), %edx )
10291 + adcl %ebx, %eax
10292 +-DST( movl %ebx, (%edi) )
10293 ++DST( movl %ebx, %es:(%edi) )
10294 + adcl %edx, %eax
10295 +-DST( movl %edx, 4(%edi) )
10296 ++DST( movl %edx, %es:4(%edi) )
10297 +
10298 + SRC( movl 8(%esi), %ebx )
10299 + SRC( movl 12(%esi), %edx )
10300 + adcl %ebx, %eax
10301 +-DST( movl %ebx, 8(%edi) )
10302 ++DST( movl %ebx, %es:8(%edi) )
10303 + adcl %edx, %eax
10304 +-DST( movl %edx, 12(%edi) )
10305 ++DST( movl %edx, %es:12(%edi) )
10306 +
10307 + SRC( movl 16(%esi), %ebx )
10308 + SRC( movl 20(%esi), %edx )
10309 + adcl %ebx, %eax
10310 +-DST( movl %ebx, 16(%edi) )
10311 ++DST( movl %ebx, %es:16(%edi) )
10312 + adcl %edx, %eax
10313 +-DST( movl %edx, 20(%edi) )
10314 ++DST( movl %edx, %es:20(%edi) )
10315 +
10316 + SRC( movl 24(%esi), %ebx )
10317 + SRC( movl 28(%esi), %edx )
10318 + adcl %ebx, %eax
10319 +-DST( movl %ebx, 24(%edi) )
10320 ++DST( movl %ebx, %es:24(%edi) )
10321 + adcl %edx, %eax
10322 +-DST( movl %edx, 28(%edi) )
10323 ++DST( movl %edx, %es:28(%edi) )
10324 +
10325 + lea 32(%esi), %esi
10326 + lea 32(%edi), %edi
10327 +@@ -380,7 +394,7 @@ DST( movl %edx, 28(%edi) )
10328 + shrl $2, %edx # This clears CF
10329 + SRC(3: movl (%esi), %ebx )
10330 + adcl %ebx, %eax
10331 +-DST( movl %ebx, (%edi) )
10332 ++DST( movl %ebx, %es:(%edi) )
10333 + lea 4(%esi), %esi
10334 + lea 4(%edi), %edi
10335 + dec %edx
10336 +@@ -392,12 +406,12 @@ DST( movl %ebx, (%edi) )
10337 + jb 5f
10338 + SRC( movw (%esi), %cx )
10339 + leal 2(%esi), %esi
10340 +-DST( movw %cx, (%edi) )
10341 ++DST( movw %cx, %es:(%edi) )
10342 + leal 2(%edi), %edi
10343 + je 6f
10344 + shll $16,%ecx
10345 + SRC(5: movb (%esi), %cl )
10346 +-DST( movb %cl, (%edi) )
10347 ++DST( movb %cl, %es:(%edi) )
10348 + 6: addl %ecx, %eax
10349 + adcl $0, %eax
10350 + 7:
10351 +@@ -408,7 +422,7 @@ DST( movb %cl, (%edi) )
10352 +
10353 + 6001:
10354 + movl ARGBASE+20(%esp), %ebx # src_err_ptr
10355 +- movl $-EFAULT, (%ebx)
10356 ++ movl $-EFAULT, %ss:(%ebx)
10357 +
10358 + # zero the complete destination - computing the rest
10359 + # is too much work
10360 +@@ -421,11 +435,19 @@ DST( movb %cl, (%edi) )
10361 +
10362 + 6002:
10363 + movl ARGBASE+24(%esp), %ebx # dst_err_ptr
10364 +- movl $-EFAULT,(%ebx)
10365 ++ movl $-EFAULT,%ss:(%ebx)
10366 + jmp 5000b
10367 +
10368 + .previous
10369 +
10370 ++ pushl %ss
10371 ++ CFI_ADJUST_CFA_OFFSET 4
10372 ++ popl %ds
10373 ++ CFI_ADJUST_CFA_OFFSET -4
10374 ++ pushl %ss
10375 ++ CFI_ADJUST_CFA_OFFSET 4
10376 ++ popl %es
10377 ++ CFI_ADJUST_CFA_OFFSET -4
10378 + popl %ebx
10379 + CFI_ADJUST_CFA_OFFSET -4
10380 + CFI_RESTORE ebx
10381 +@@ -439,26 +461,41 @@ DST( movb %cl, (%edi) )
10382 + CFI_ADJUST_CFA_OFFSET -4
10383 + ret
10384 + CFI_ENDPROC
10385 +-ENDPROC(csum_partial_copy_generic)
10386 ++ENDPROC(csum_partial_copy_generic_to_user)
10387 +
10388 + #else
10389 +
10390 + /* Version for PentiumII/PPro */
10391 +
10392 + #define ROUND1(x) \
10393 ++ nop; nop; nop; \
10394 + SRC(movl x(%esi), %ebx ) ; \
10395 + addl %ebx, %eax ; \
10396 +- DST(movl %ebx, x(%edi) ) ;
10397 ++ DST(movl %ebx, %es:x(%edi)) ;
10398 +
10399 + #define ROUND(x) \
10400 ++ nop; nop; nop; \
10401 + SRC(movl x(%esi), %ebx ) ; \
10402 + adcl %ebx, %eax ; \
10403 +- DST(movl %ebx, x(%edi) ) ;
10404 ++ DST(movl %ebx, %es:x(%edi)) ;
10405 +
10406 + #define ARGBASE 12
10407 +-
10408 +-ENTRY(csum_partial_copy_generic)
10409 ++
10410 ++ENTRY(csum_partial_copy_generic_to_user)
10411 + CFI_STARTPROC
10412 ++ pushl $(__USER_DS)
10413 ++ CFI_ADJUST_CFA_OFFSET 4
10414 ++ popl %es
10415 ++ CFI_ADJUST_CFA_OFFSET -4
10416 ++ jmp csum_partial_copy_generic
10417 ++
10418 ++ENTRY(csum_partial_copy_generic_from_user)
10419 ++ pushl $(__USER_DS)
10420 ++ CFI_ADJUST_CFA_OFFSET 4
10421 ++ popl %ds
10422 ++ CFI_ADJUST_CFA_OFFSET -4
10423 ++
10424 ++ENTRY(csum_partial_copy_generic)
10425 + pushl %ebx
10426 + CFI_ADJUST_CFA_OFFSET 4
10427 + CFI_REL_OFFSET ebx, 0
10428 +@@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic)
10429 + subl %ebx, %edi
10430 + lea -1(%esi),%edx
10431 + andl $-32,%edx
10432 +- lea 3f(%ebx,%ebx), %ebx
10433 ++ lea 3f(%ebx,%ebx,2), %ebx
10434 + testl %esi, %esi
10435 + jmp *%ebx
10436 + 1: addl $64,%esi
10437 +@@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic)
10438 + jb 5f
10439 + SRC( movw (%esi), %dx )
10440 + leal 2(%esi), %esi
10441 +-DST( movw %dx, (%edi) )
10442 ++DST( movw %dx, %es:(%edi) )
10443 + leal 2(%edi), %edi
10444 + je 6f
10445 + shll $16,%edx
10446 + 5:
10447 + SRC( movb (%esi), %dl )
10448 +-DST( movb %dl, (%edi) )
10449 ++DST( movb %dl, %es:(%edi) )
10450 + 6: addl %edx, %eax
10451 + adcl $0, %eax
10452 + 7:
10453 + .section .fixup, "ax"
10454 + 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
10455 +- movl $-EFAULT, (%ebx)
10456 ++ movl $-EFAULT, %ss:(%ebx)
10457 + # zero the complete destination (computing the rest is too much work)
10458 + movl ARGBASE+8(%esp),%edi # dst
10459 + movl ARGBASE+12(%esp),%ecx # len
10460 +@@ -523,10 +560,18 @@ DST( movb %dl, (%edi) )
10461 + rep; stosb
10462 + jmp 7b
10463 + 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
10464 +- movl $-EFAULT, (%ebx)
10465 ++ movl $-EFAULT, %ss:(%ebx)
10466 + jmp 7b
10467 + .previous
10468 +
10469 ++ pushl %ss
10470 ++ CFI_ADJUST_CFA_OFFSET 4
10471 ++ popl %ds
10472 ++ CFI_ADJUST_CFA_OFFSET -4
10473 ++ pushl %ss
10474 ++ CFI_ADJUST_CFA_OFFSET 4
10475 ++ popl %es
10476 ++ CFI_ADJUST_CFA_OFFSET -4
10477 + popl %esi
10478 + CFI_ADJUST_CFA_OFFSET -4
10479 + CFI_RESTORE esi
10480 +@@ -538,7 +583,7 @@ DST( movb %dl, (%edi) )
10481 + CFI_RESTORE ebx
10482 + ret
10483 + CFI_ENDPROC
10484 +-ENDPROC(csum_partial_copy_generic)
10485 ++ENDPROC(csum_partial_copy_generic_to_user)
10486 +
10487 + #undef ROUND
10488 + #undef ROUND1
10489 +diff -urNp linux-2.6.26.6/arch/x86/lib/clear_page_64.S linux-2.6.26.6/arch/x86/lib/clear_page_64.S
10490 +--- linux-2.6.26.6/arch/x86/lib/clear_page_64.S 2008-10-08 23:24:05.000000000 -0400
10491 ++++ linux-2.6.26.6/arch/x86/lib/clear_page_64.S 2008-10-11 21:54:19.000000000 -0400
10492 +@@ -44,7 +44,7 @@ ENDPROC(clear_page)
10493 +
10494 + #include <asm/cpufeature.h>
10495 +
10496 +- .section .altinstr_replacement,"ax"
10497 ++ .section .altinstr_replacement,"a"
10498 + 1: .byte 0xeb /* jmp <disp8> */
10499 + .byte (clear_page_c - clear_page) - (2f - 1b) /* offset */
10500 + 2:
10501 +diff -urNp linux-2.6.26.6/arch/x86/lib/copy_page_64.S linux-2.6.26.6/arch/x86/lib/copy_page_64.S
10502 +--- linux-2.6.26.6/arch/x86/lib/copy_page_64.S 2008-10-08 23:24:05.000000000 -0400
10503 ++++ linux-2.6.26.6/arch/x86/lib/copy_page_64.S 2008-10-11 21:54:19.000000000 -0400
10504 +@@ -104,7 +104,7 @@ ENDPROC(copy_page)
10505 +
10506 + #include <asm/cpufeature.h>
10507 +
10508 +- .section .altinstr_replacement,"ax"
10509 ++ .section .altinstr_replacement,"a"
10510 + 1: .byte 0xeb /* jmp <disp8> */
10511 + .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */
10512 + 2:
10513 +diff -urNp linux-2.6.26.6/arch/x86/lib/copy_user_64.S linux-2.6.26.6/arch/x86/lib/copy_user_64.S
10514 +--- linux-2.6.26.6/arch/x86/lib/copy_user_64.S 2008-10-08 23:24:05.000000000 -0400
10515 ++++ linux-2.6.26.6/arch/x86/lib/copy_user_64.S 2008-10-11 21:54:19.000000000 -0400
10516 +@@ -19,7 +19,7 @@
10517 + .byte 0xe9 /* 32bit jump */
10518 + .long \orig-1f /* by default jump to orig */
10519 + 1:
10520 +- .section .altinstr_replacement,"ax"
10521 ++ .section .altinstr_replacement,"a"
10522 + 2: .byte 0xe9 /* near jump with 32bit immediate */
10523 + .long \alt-1b /* offset */ /* or alternatively to alt */
10524 + .previous
10525 +@@ -76,6 +76,8 @@ ENDPROC(copy_from_user)
10526 + /* must zero dest */
10527 + bad_from_user:
10528 + CFI_STARTPROC
10529 ++ testl %edx,%edx
10530 ++ js bad_to_user
10531 + movl %edx,%ecx
10532 + xorl %eax,%eax
10533 + rep
10534 +diff -urNp linux-2.6.26.6/arch/x86/lib/getuser_32.S linux-2.6.26.6/arch/x86/lib/getuser_32.S
10535 +--- linux-2.6.26.6/arch/x86/lib/getuser_32.S 2008-10-08 23:24:05.000000000 -0400
10536 ++++ linux-2.6.26.6/arch/x86/lib/getuser_32.S 2008-10-11 21:54:19.000000000 -0400
10537 +@@ -11,7 +11,7 @@
10538 + #include <linux/linkage.h>
10539 + #include <asm/dwarf2.h>
10540 + #include <asm/thread_info.h>
10541 +-
10542 ++#include <asm/segment.h>
10543 +
10544 + /*
10545 + * __get_user_X
10546 +@@ -31,7 +31,11 @@ ENTRY(__get_user_1)
10547 + GET_THREAD_INFO(%edx)
10548 + cmpl TI_addr_limit(%edx),%eax
10549 + jae bad_get_user
10550 ++ pushl $(__USER_DS)
10551 ++ popl %ds
10552 + 1: movzbl (%eax),%edx
10553 ++ pushl %ss
10554 ++ pop %ds
10555 + xorl %eax,%eax
10556 + ret
10557 + CFI_ENDPROC
10558 +@@ -44,7 +48,11 @@ ENTRY(__get_user_2)
10559 + GET_THREAD_INFO(%edx)
10560 + cmpl TI_addr_limit(%edx),%eax
10561 + jae bad_get_user
10562 ++ pushl $(__USER_DS)
10563 ++ popl %ds
10564 + 2: movzwl -1(%eax),%edx
10565 ++ pushl %ss
10566 ++ pop %ds
10567 + xorl %eax,%eax
10568 + ret
10569 + CFI_ENDPROC
10570 +@@ -57,7 +65,11 @@ ENTRY(__get_user_4)
10571 + GET_THREAD_INFO(%edx)
10572 + cmpl TI_addr_limit(%edx),%eax
10573 + jae bad_get_user
10574 ++ pushl $(__USER_DS)
10575 ++ popl %ds
10576 + 3: movl -3(%eax),%edx
10577 ++ pushl %ss
10578 ++ pop %ds
10579 + xorl %eax,%eax
10580 + ret
10581 + CFI_ENDPROC
10582 +@@ -65,6 +77,8 @@ ENDPROC(__get_user_4)
10583 +
10584 + bad_get_user:
10585 + CFI_STARTPROC
10586 ++ pushl %ss
10587 ++ pop %ds
10588 + xorl %edx,%edx
10589 + movl $-14,%eax
10590 + ret
10591 +diff -urNp linux-2.6.26.6/arch/x86/lib/memcpy_64.S linux-2.6.26.6/arch/x86/lib/memcpy_64.S
10592 +--- linux-2.6.26.6/arch/x86/lib/memcpy_64.S 2008-10-08 23:24:05.000000000 -0400
10593 ++++ linux-2.6.26.6/arch/x86/lib/memcpy_64.S 2008-10-11 21:54:19.000000000 -0400
10594 +@@ -114,7 +114,7 @@ ENDPROC(__memcpy)
10595 + /* Some CPUs run faster using the string copy instructions.
10596 + It is also a lot simpler. Use this when possible */
10597 +
10598 +- .section .altinstr_replacement,"ax"
10599 ++ .section .altinstr_replacement,"a"
10600 + 1: .byte 0xeb /* jmp <disp8> */
10601 + .byte (memcpy_c - memcpy) - (2f - 1b) /* offset */
10602 + 2:
10603 +diff -urNp linux-2.6.26.6/arch/x86/lib/memset_64.S linux-2.6.26.6/arch/x86/lib/memset_64.S
10604 +--- linux-2.6.26.6/arch/x86/lib/memset_64.S 2008-10-08 23:24:05.000000000 -0400
10605 ++++ linux-2.6.26.6/arch/x86/lib/memset_64.S 2008-10-11 21:54:19.000000000 -0400
10606 +@@ -118,7 +118,7 @@ ENDPROC(__memset)
10607 +
10608 + #include <asm/cpufeature.h>
10609 +
10610 +- .section .altinstr_replacement,"ax"
10611 ++ .section .altinstr_replacement,"a"
10612 + 1: .byte 0xeb /* jmp <disp8> */
10613 + .byte (memset_c - memset) - (2f - 1b) /* offset */
10614 + 2:
10615 +diff -urNp linux-2.6.26.6/arch/x86/lib/mmx_32.c linux-2.6.26.6/arch/x86/lib/mmx_32.c
10616 +--- linux-2.6.26.6/arch/x86/lib/mmx_32.c 2008-10-08 23:24:05.000000000 -0400
10617 ++++ linux-2.6.26.6/arch/x86/lib/mmx_32.c 2008-10-11 21:54:19.000000000 -0400
10618 +@@ -29,6 +29,7 @@ void *_mmx_memcpy(void *to, const void *
10619 + {
10620 + void *p;
10621 + int i;
10622 ++ unsigned long cr0;
10623 +
10624 + if (unlikely(in_interrupt()))
10625 + return __memcpy(to, from, len);
10626 +@@ -39,44 +40,72 @@ void *_mmx_memcpy(void *to, const void *
10627 + kernel_fpu_begin();
10628 +
10629 + __asm__ __volatile__ (
10630 +- "1: prefetch (%0)\n" /* This set is 28 bytes */
10631 +- " prefetch 64(%0)\n"
10632 +- " prefetch 128(%0)\n"
10633 +- " prefetch 192(%0)\n"
10634 +- " prefetch 256(%0)\n"
10635 ++ "1: prefetch (%1)\n" /* This set is 28 bytes */
10636 ++ " prefetch 64(%1)\n"
10637 ++ " prefetch 128(%1)\n"
10638 ++ " prefetch 192(%1)\n"
10639 ++ " prefetch 256(%1)\n"
10640 + "2: \n"
10641 + ".section .fixup, \"ax\"\n"
10642 +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
10643 ++ "3: \n"
10644 ++
10645 ++#ifdef CONFIG_PAX_KERNEXEC
10646 ++ " movl %%cr0, %0\n"
10647 ++ " movl %0, %%eax\n"
10648 ++ " andl $0xFFFEFFFF, %%eax\n"
10649 ++ " movl %%eax, %%cr0\n"
10650 ++#endif
10651 ++
10652 ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
10653 ++
10654 ++#ifdef CONFIG_PAX_KERNEXEC
10655 ++ " movl %0, %%cr0\n"
10656 ++#endif
10657 ++
10658 + " jmp 2b\n"
10659 + ".previous\n"
10660 + _ASM_EXTABLE(1b, 3b)
10661 +- : : "r" (from));
10662 ++ : "=&r" (cr0) : "r" (from) : "ax");
10663 +
10664 + for ( ; i > 5; i--) {
10665 + __asm__ __volatile__ (
10666 +- "1: prefetch 320(%0)\n"
10667 +- "2: movq (%0), %%mm0\n"
10668 +- " movq 8(%0), %%mm1\n"
10669 +- " movq 16(%0), %%mm2\n"
10670 +- " movq 24(%0), %%mm3\n"
10671 +- " movq %%mm0, (%1)\n"
10672 +- " movq %%mm1, 8(%1)\n"
10673 +- " movq %%mm2, 16(%1)\n"
10674 +- " movq %%mm3, 24(%1)\n"
10675 +- " movq 32(%0), %%mm0\n"
10676 +- " movq 40(%0), %%mm1\n"
10677 +- " movq 48(%0), %%mm2\n"
10678 +- " movq 56(%0), %%mm3\n"
10679 +- " movq %%mm0, 32(%1)\n"
10680 +- " movq %%mm1, 40(%1)\n"
10681 +- " movq %%mm2, 48(%1)\n"
10682 +- " movq %%mm3, 56(%1)\n"
10683 ++ "1: prefetch 320(%1)\n"
10684 ++ "2: movq (%1), %%mm0\n"
10685 ++ " movq 8(%1), %%mm1\n"
10686 ++ " movq 16(%1), %%mm2\n"
10687 ++ " movq 24(%1), %%mm3\n"
10688 ++ " movq %%mm0, (%2)\n"
10689 ++ " movq %%mm1, 8(%2)\n"
10690 ++ " movq %%mm2, 16(%2)\n"
10691 ++ " movq %%mm3, 24(%2)\n"
10692 ++ " movq 32(%1), %%mm0\n"
10693 ++ " movq 40(%1), %%mm1\n"
10694 ++ " movq 48(%1), %%mm2\n"
10695 ++ " movq 56(%1), %%mm3\n"
10696 ++ " movq %%mm0, 32(%2)\n"
10697 ++ " movq %%mm1, 40(%2)\n"
10698 ++ " movq %%mm2, 48(%2)\n"
10699 ++ " movq %%mm3, 56(%2)\n"
10700 + ".section .fixup, \"ax\"\n"
10701 +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
10702 ++ "3:\n"
10703 ++
10704 ++#ifdef CONFIG_PAX_KERNEXEC
10705 ++ " movl %%cr0, %0\n"
10706 ++ " movl %0, %%eax\n"
10707 ++ " andl $0xFFFEFFFF, %%eax\n"
10708 ++ " movl %%eax, %%cr0\n"
10709 ++#endif
10710 ++
10711 ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
10712 ++
10713 ++#ifdef CONFIG_PAX_KERNEXEC
10714 ++ " movl %0, %%cr0\n"
10715 ++#endif
10716 ++
10717 + " jmp 2b\n"
10718 + ".previous\n"
10719 + _ASM_EXTABLE(1b, 3b)
10720 +- : : "r" (from), "r" (to) : "memory");
10721 ++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
10722 +
10723 + from += 64;
10724 + to += 64;
10725 +@@ -158,6 +187,7 @@ static void fast_clear_page(void *page)
10726 + static void fast_copy_page(void *to, void *from)
10727 + {
10728 + int i;
10729 ++ unsigned long cr0;
10730 +
10731 + kernel_fpu_begin();
10732 +
10733 +@@ -166,42 +196,70 @@ static void fast_copy_page(void *to, voi
10734 + * but that is for later. -AV
10735 + */
10736 + __asm__ __volatile__(
10737 +- "1: prefetch (%0)\n"
10738 +- " prefetch 64(%0)\n"
10739 +- " prefetch 128(%0)\n"
10740 +- " prefetch 192(%0)\n"
10741 +- " prefetch 256(%0)\n"
10742 ++ "1: prefetch (%1)\n"
10743 ++ " prefetch 64(%1)\n"
10744 ++ " prefetch 128(%1)\n"
10745 ++ " prefetch 192(%1)\n"
10746 ++ " prefetch 256(%1)\n"
10747 + "2: \n"
10748 + ".section .fixup, \"ax\"\n"
10749 +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
10750 ++ "3: \n"
10751 ++
10752 ++#ifdef CONFIG_PAX_KERNEXEC
10753 ++ " movl %%cr0, %0\n"
10754 ++ " movl %0, %%eax\n"
10755 ++ " andl $0xFFFEFFFF, %%eax\n"
10756 ++ " movl %%eax, %%cr0\n"
10757 ++#endif
10758 ++
10759 ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
10760 ++
10761 ++#ifdef CONFIG_PAX_KERNEXEC
10762 ++ " movl %0, %%cr0\n"
10763 ++#endif
10764 ++
10765 + " jmp 2b\n"
10766 + ".previous\n"
10767 +- _ASM_EXTABLE(1b, 3b) : : "r" (from));
10768 ++ _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
10769 +
10770 + for (i = 0; i < (4096-320)/64; i++) {
10771 + __asm__ __volatile__ (
10772 +- "1: prefetch 320(%0)\n"
10773 +- "2: movq (%0), %%mm0\n"
10774 +- " movntq %%mm0, (%1)\n"
10775 +- " movq 8(%0), %%mm1\n"
10776 +- " movntq %%mm1, 8(%1)\n"
10777 +- " movq 16(%0), %%mm2\n"
10778 +- " movntq %%mm2, 16(%1)\n"
10779 +- " movq 24(%0), %%mm3\n"
10780 +- " movntq %%mm3, 24(%1)\n"
10781 +- " movq 32(%0), %%mm4\n"
10782 +- " movntq %%mm4, 32(%1)\n"
10783 +- " movq 40(%0), %%mm5\n"
10784 +- " movntq %%mm5, 40(%1)\n"
10785 +- " movq 48(%0), %%mm6\n"
10786 +- " movntq %%mm6, 48(%1)\n"
10787 +- " movq 56(%0), %%mm7\n"
10788 +- " movntq %%mm7, 56(%1)\n"
10789 ++ "1: prefetch 320(%1)\n"
10790 ++ "2: movq (%1), %%mm0\n"
10791 ++ " movntq %%mm0, (%2)\n"
10792 ++ " movq 8(%1), %%mm1\n"
10793 ++ " movntq %%mm1, 8(%2)\n"
10794 ++ " movq 16(%1), %%mm2\n"
10795 ++ " movntq %%mm2, 16(%2)\n"
10796 ++ " movq 24(%1), %%mm3\n"
10797 ++ " movntq %%mm3, 24(%2)\n"
10798 ++ " movq 32(%1), %%mm4\n"
10799 ++ " movntq %%mm4, 32(%2)\n"
10800 ++ " movq 40(%1), %%mm5\n"
10801 ++ " movntq %%mm5, 40(%2)\n"
10802 ++ " movq 48(%1), %%mm6\n"
10803 ++ " movntq %%mm6, 48(%2)\n"
10804 ++ " movq 56(%1), %%mm7\n"
10805 ++ " movntq %%mm7, 56(%2)\n"
10806 + ".section .fixup, \"ax\"\n"
10807 +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
10808 ++ "3:\n"
10809 ++
10810 ++#ifdef CONFIG_PAX_KERNEXEC
10811 ++ " movl %%cr0, %0\n"
10812 ++ " movl %0, %%eax\n"
10813 ++ " andl $0xFFFEFFFF, %%eax\n"
10814 ++ " movl %%eax, %%cr0\n"
10815 ++#endif
10816 ++
10817 ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
10818 ++
10819 ++#ifdef CONFIG_PAX_KERNEXEC
10820 ++ " movl %0, %%cr0\n"
10821 ++#endif
10822 ++
10823 + " jmp 2b\n"
10824 + ".previous\n"
10825 +- _ASM_EXTABLE(1b, 3b) : : "r" (from), "r" (to) : "memory");
10826 ++ _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
10827 +
10828 + from += 64;
10829 + to += 64;
10830 +@@ -280,47 +338,76 @@ static void fast_clear_page(void *page)
10831 + static void fast_copy_page(void *to, void *from)
10832 + {
10833 + int i;
10834 ++ unsigned long cr0;
10835 +
10836 + kernel_fpu_begin();
10837 +
10838 + __asm__ __volatile__ (
10839 +- "1: prefetch (%0)\n"
10840 +- " prefetch 64(%0)\n"
10841 +- " prefetch 128(%0)\n"
10842 +- " prefetch 192(%0)\n"
10843 +- " prefetch 256(%0)\n"
10844 ++ "1: prefetch (%1)\n"
10845 ++ " prefetch 64(%1)\n"
10846 ++ " prefetch 128(%1)\n"
10847 ++ " prefetch 192(%1)\n"
10848 ++ " prefetch 256(%1)\n"
10849 + "2: \n"
10850 + ".section .fixup, \"ax\"\n"
10851 +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
10852 ++ "3: \n"
10853 ++
10854 ++#ifdef CONFIG_PAX_KERNEXEC
10855 ++ " movl %%cr0, %0\n"
10856 ++ " movl %0, %%eax\n"
10857 ++ " andl $0xFFFEFFFF, %%eax\n"
10858 ++ " movl %%eax, %%cr0\n"
10859 ++#endif
10860 ++
10861 ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
10862 ++
10863 ++#ifdef CONFIG_PAX_KERNEXEC
10864 ++ " movl %0, %%cr0\n"
10865 ++#endif
10866 ++
10867 + " jmp 2b\n"
10868 + ".previous\n"
10869 +- _ASM_EXTABLE(1b, 3b) : : "r" (from));
10870 ++ _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
10871 +
10872 + for (i = 0; i < 4096/64; i++) {
10873 + __asm__ __volatile__ (
10874 +- "1: prefetch 320(%0)\n"
10875 +- "2: movq (%0), %%mm0\n"
10876 +- " movq 8(%0), %%mm1\n"
10877 +- " movq 16(%0), %%mm2\n"
10878 +- " movq 24(%0), %%mm3\n"
10879 +- " movq %%mm0, (%1)\n"
10880 +- " movq %%mm1, 8(%1)\n"
10881 +- " movq %%mm2, 16(%1)\n"
10882 +- " movq %%mm3, 24(%1)\n"
10883 +- " movq 32(%0), %%mm0\n"
10884 +- " movq 40(%0), %%mm1\n"
10885 +- " movq 48(%0), %%mm2\n"
10886 +- " movq 56(%0), %%mm3\n"
10887 +- " movq %%mm0, 32(%1)\n"
10888 +- " movq %%mm1, 40(%1)\n"
10889 +- " movq %%mm2, 48(%1)\n"
10890 +- " movq %%mm3, 56(%1)\n"
10891 ++ "1: prefetch 320(%1)\n"
10892 ++ "2: movq (%1), %%mm0\n"
10893 ++ " movq 8(%1), %%mm1\n"
10894 ++ " movq 16(%1), %%mm2\n"
10895 ++ " movq 24(%1), %%mm3\n"
10896 ++ " movq %%mm0, (%2)\n"
10897 ++ " movq %%mm1, 8(%2)\n"
10898 ++ " movq %%mm2, 16(%2)\n"
10899 ++ " movq %%mm3, 24(%2)\n"
10900 ++ " movq 32(%1), %%mm0\n"
10901 ++ " movq 40(%1), %%mm1\n"
10902 ++ " movq 48(%1), %%mm2\n"
10903 ++ " movq 56(%1), %%mm3\n"
10904 ++ " movq %%mm0, 32(%2)\n"
10905 ++ " movq %%mm1, 40(%2)\n"
10906 ++ " movq %%mm2, 48(%2)\n"
10907 ++ " movq %%mm3, 56(%2)\n"
10908 + ".section .fixup, \"ax\"\n"
10909 +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
10910 ++ "3:\n"
10911 ++
10912 ++#ifdef CONFIG_PAX_KERNEXEC
10913 ++ " movl %%cr0, %0\n"
10914 ++ " movl %0, %%eax\n"
10915 ++ " andl $0xFFFEFFFF, %%eax\n"
10916 ++ " movl %%eax, %%cr0\n"
10917 ++#endif
10918 ++
10919 ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
10920 ++
10921 ++#ifdef CONFIG_PAX_KERNEXEC
10922 ++ " movl %0, %%cr0\n"
10923 ++#endif
10924 ++
10925 + " jmp 2b\n"
10926 + ".previous\n"
10927 + _ASM_EXTABLE(1b, 3b)
10928 +- : : "r" (from), "r" (to) : "memory");
10929 ++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
10930 +
10931 + from += 64;
10932 + to += 64;
10933 +diff -urNp linux-2.6.26.6/arch/x86/lib/putuser_32.S linux-2.6.26.6/arch/x86/lib/putuser_32.S
10934 +--- linux-2.6.26.6/arch/x86/lib/putuser_32.S 2008-10-08 23:24:05.000000000 -0400
10935 ++++ linux-2.6.26.6/arch/x86/lib/putuser_32.S 2008-10-11 21:54:19.000000000 -0400
10936 +@@ -11,7 +11,7 @@
10937 + #include <linux/linkage.h>
10938 + #include <asm/dwarf2.h>
10939 + #include <asm/thread_info.h>
10940 +-
10941 ++#include <asm/segment.h>
10942 +
10943 + /*
10944 + * __put_user_X
10945 +@@ -41,7 +41,11 @@ ENTRY(__put_user_1)
10946 + ENTER
10947 + cmpl TI_addr_limit(%ebx),%ecx
10948 + jae bad_put_user
10949 ++ pushl $(__USER_DS)
10950 ++ popl %ds
10951 + 1: movb %al,(%ecx)
10952 ++ pushl %ss
10953 ++ popl %ds
10954 + xorl %eax,%eax
10955 + EXIT
10956 + ENDPROC(__put_user_1)
10957 +@@ -52,7 +56,11 @@ ENTRY(__put_user_2)
10958 + subl $1,%ebx
10959 + cmpl %ebx,%ecx
10960 + jae bad_put_user
10961 ++ pushl $(__USER_DS)
10962 ++ popl %ds
10963 + 2: movw %ax,(%ecx)
10964 ++ pushl %ss
10965 ++ popl %ds
10966 + xorl %eax,%eax
10967 + EXIT
10968 + ENDPROC(__put_user_2)
10969 +@@ -63,7 +71,11 @@ ENTRY(__put_user_4)
10970 + subl $3,%ebx
10971 + cmpl %ebx,%ecx
10972 + jae bad_put_user
10973 ++ pushl $(__USER_DS)
10974 ++ popl %ds
10975 + 3: movl %eax,(%ecx)
10976 ++ pushl %ss
10977 ++ popl %ds
10978 + xorl %eax,%eax
10979 + EXIT
10980 + ENDPROC(__put_user_4)
10981 +@@ -74,8 +86,12 @@ ENTRY(__put_user_8)
10982 + subl $7,%ebx
10983 + cmpl %ebx,%ecx
10984 + jae bad_put_user
10985 ++ pushl $(__USER_DS)
10986 ++ popl %ds
10987 + 4: movl %eax,(%ecx)
10988 + 5: movl %edx,4(%ecx)
10989 ++ pushl %ss
10990 ++ popl %ds
10991 + xorl %eax,%eax
10992 + EXIT
10993 + ENDPROC(__put_user_8)
10994 +@@ -85,6 +101,10 @@ bad_put_user:
10995 + CFI_DEF_CFA esp, 2*4
10996 + CFI_OFFSET eip, -1*4
10997 + CFI_OFFSET ebx, -2*4
10998 ++ pushl %ss
10999 ++ CFI_ADJUST_CFA_OFFSET 4
11000 ++ popl %ds
11001 ++ CFI_ADJUST_CFA_OFFSET -4
11002 + movl $-14,%eax
11003 + EXIT
11004 + END(bad_put_user)
11005 +diff -urNp linux-2.6.26.6/arch/x86/lib/usercopy_32.c linux-2.6.26.6/arch/x86/lib/usercopy_32.c
11006 +--- linux-2.6.26.6/arch/x86/lib/usercopy_32.c 2008-10-08 23:24:05.000000000 -0400
11007 ++++ linux-2.6.26.6/arch/x86/lib/usercopy_32.c 2008-10-11 21:55:52.000000000 -0400
11008 +@@ -29,31 +29,38 @@ static inline int __movsl_is_ok(unsigned
11009 + * Copy a null terminated string from userspace.
11010 + */
11011 +
11012 +-#define __do_strncpy_from_user(dst, src, count, res) \
11013 +-do { \
11014 +- int __d0, __d1, __d2; \
11015 +- might_sleep(); \
11016 +- __asm__ __volatile__( \
11017 +- " testl %1,%1\n" \
11018 +- " jz 2f\n" \
11019 +- "0: lodsb\n" \
11020 +- " stosb\n" \
11021 +- " testb %%al,%%al\n" \
11022 +- " jz 1f\n" \
11023 +- " decl %1\n" \
11024 +- " jnz 0b\n" \
11025 +- "1: subl %1,%0\n" \
11026 +- "2:\n" \
11027 +- ".section .fixup,\"ax\"\n" \
11028 +- "3: movl %5,%0\n" \
11029 +- " jmp 2b\n" \
11030 +- ".previous\n" \
11031 +- _ASM_EXTABLE(0b,3b) \
11032 +- : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \
11033 +- "=&D" (__d2) \
11034 +- : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
11035 +- : "memory"); \
11036 +-} while (0)
11037 ++static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
11038 ++{
11039 ++ int __d0, __d1, __d2;
11040 ++ long res = -EFAULT;
11041 ++
11042 ++ might_sleep();
11043 ++ __asm__ __volatile__(
11044 ++ " movw %w10,%%ds\n"
11045 ++ " testl %1,%1\n"
11046 ++ " jz 2f\n"
11047 ++ "0: lodsb\n"
11048 ++ " stosb\n"
11049 ++ " testb %%al,%%al\n"
11050 ++ " jz 1f\n"
11051 ++ " decl %1\n"
11052 ++ " jnz 0b\n"
11053 ++ "1: subl %1,%0\n"
11054 ++ "2:\n"
11055 ++ " pushl %%ss\n"
11056 ++ " popl %%ds\n"
11057 ++ ".section .fixup,\"ax\"\n"
11058 ++ "3: movl %5,%0\n"
11059 ++ " jmp 2b\n"
11060 ++ ".previous\n"
11061 ++ _ASM_EXTABLE(0b,3b)
11062 ++ : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),
11063 ++ "=&D" (__d2)
11064 ++ : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
11065 ++ "r"(__USER_DS)
11066 ++ : "memory");
11067 ++ return res;
11068 ++}
11069 +
11070 + /**
11071 + * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
11072 +@@ -78,9 +85,7 @@ do { \
11073 + long
11074 + __strncpy_from_user(char *dst, const char __user *src, long count)
11075 + {
11076 +- long res;
11077 +- __do_strncpy_from_user(dst, src, count, res);
11078 +- return res;
11079 ++ return __do_strncpy_from_user(dst, src, count);
11080 + }
11081 + EXPORT_SYMBOL(__strncpy_from_user);
11082 +
11083 +@@ -107,7 +112,7 @@ strncpy_from_user(char *dst, const char
11084 + {
11085 + long res = -EFAULT;
11086 + if (access_ok(VERIFY_READ, src, 1))
11087 +- __do_strncpy_from_user(dst, src, count, res);
11088 ++ res = __do_strncpy_from_user(dst, src, count);
11089 + return res;
11090 + }
11091 + EXPORT_SYMBOL(strncpy_from_user);
11092 +@@ -116,24 +121,30 @@ EXPORT_SYMBOL(strncpy_from_user);
11093 + * Zero Userspace
11094 + */
11095 +
11096 +-#define __do_clear_user(addr,size) \
11097 +-do { \
11098 +- int __d0; \
11099 +- might_sleep(); \
11100 +- __asm__ __volatile__( \
11101 +- "0: rep; stosl\n" \
11102 +- " movl %2,%0\n" \
11103 +- "1: rep; stosb\n" \
11104 +- "2:\n" \
11105 +- ".section .fixup,\"ax\"\n" \
11106 +- "3: lea 0(%2,%0,4),%0\n" \
11107 +- " jmp 2b\n" \
11108 +- ".previous\n" \
11109 +- _ASM_EXTABLE(0b,3b) \
11110 +- _ASM_EXTABLE(1b,2b) \
11111 +- : "=&c"(size), "=&D" (__d0) \
11112 +- : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
11113 +-} while (0)
11114 ++static unsigned long __do_clear_user(void __user *addr, unsigned long size)
11115 ++{
11116 ++ int __d0;
11117 ++
11118 ++ might_sleep();
11119 ++ __asm__ __volatile__(
11120 ++ " movw %w6,%%es\n"
11121 ++ "0: rep; stosl\n"
11122 ++ " movl %2,%0\n"
11123 ++ "1: rep; stosb\n"
11124 ++ "2:\n"
11125 ++ " pushl %%ss\n"
11126 ++ " popl %%es\n"
11127 ++ ".section .fixup,\"ax\"\n"
11128 ++ "3: lea 0(%2,%0,4),%0\n"
11129 ++ " jmp 2b\n"
11130 ++ ".previous\n"
11131 ++ _ASM_EXTABLE(0b,3b)
11132 ++ _ASM_EXTABLE(1b,2b)
11133 ++ : "=&c"(size), "=&D" (__d0)
11134 ++ : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
11135 ++ "r"(__USER_DS));
11136 ++ return size;
11137 ++}
11138 +
11139 + /**
11140 + * clear_user: - Zero a block of memory in user space.
11141 +@@ -150,7 +161,7 @@ clear_user(void __user *to, unsigned lon
11142 + {
11143 + might_sleep();
11144 + if (access_ok(VERIFY_WRITE, to, n))
11145 +- __do_clear_user(to, n);
11146 ++ n = __do_clear_user(to, n);
11147 + return n;
11148 + }
11149 + EXPORT_SYMBOL(clear_user);
11150 +@@ -169,8 +180,7 @@ EXPORT_SYMBOL(clear_user);
11151 + unsigned long
11152 + __clear_user(void __user *to, unsigned long n)
11153 + {
11154 +- __do_clear_user(to, n);
11155 +- return n;
11156 ++ return __do_clear_user(to, n);
11157 + }
11158 + EXPORT_SYMBOL(__clear_user);
11159 +
11160 +@@ -193,14 +203,17 @@ long strnlen_user(const char __user *s,
11161 + might_sleep();
11162 +
11163 + __asm__ __volatile__(
11164 ++ " movw %w8,%%es\n"
11165 + " testl %0, %0\n"
11166 + " jz 3f\n"
11167 +- " andl %0,%%ecx\n"
11168 ++ " movl %0,%%ecx\n"
11169 + "0: repne; scasb\n"
11170 + " setne %%al\n"
11171 + " subl %%ecx,%0\n"
11172 + " addl %0,%%eax\n"
11173 + "1:\n"
11174 ++ " pushl %%ss\n"
11175 ++ " popl %%es\n"
11176 + ".section .fixup,\"ax\"\n"
11177 + "2: xorl %%eax,%%eax\n"
11178 + " jmp 1b\n"
11179 +@@ -212,7 +225,7 @@ long strnlen_user(const char __user *s,
11180 + " .long 0b,2b\n"
11181 + ".previous"
11182 + :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
11183 +- :"0" (n), "1" (s), "2" (0), "3" (mask)
11184 ++ :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
11185 + :"cc");
11186 + return res & mask;
11187 + }
11188 +@@ -220,10 +233,11 @@ EXPORT_SYMBOL(strnlen_user);
11189 +
11190 + #ifdef CONFIG_X86_INTEL_USERCOPY
11191 + static unsigned long
11192 +-__copy_user_intel(void __user *to, const void *from, unsigned long size)
11193 ++__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
11194 + {
11195 + int d0, d1;
11196 + __asm__ __volatile__(
11197 ++ " movw %w6, %%es\n"
11198 + " .align 2,0x90\n"
11199 + "1: movl 32(%4), %%eax\n"
11200 + " cmpl $67, %0\n"
11201 +@@ -232,36 +246,36 @@ __copy_user_intel(void __user *to, const
11202 + " .align 2,0x90\n"
11203 + "3: movl 0(%4), %%eax\n"
11204 + "4: movl 4(%4), %%edx\n"
11205 +- "5: movl %%eax, 0(%3)\n"
11206 +- "6: movl %%edx, 4(%3)\n"
11207 ++ "5: movl %%eax, %%es:0(%3)\n"
11208 ++ "6: movl %%edx, %%es:4(%3)\n"
11209 + "7: movl 8(%4), %%eax\n"
11210 + "8: movl 12(%4),%%edx\n"
11211 +- "9: movl %%eax, 8(%3)\n"
11212 +- "10: movl %%edx, 12(%3)\n"
11213 ++ "9: movl %%eax, %%es:8(%3)\n"
11214 ++ "10: movl %%edx, %%es:12(%3)\n"
11215 + "11: movl 16(%4), %%eax\n"
11216 + "12: movl 20(%4), %%edx\n"
11217 +- "13: movl %%eax, 16(%3)\n"
11218 +- "14: movl %%edx, 20(%3)\n"
11219 ++ "13: movl %%eax, %%es:16(%3)\n"
11220 ++ "14: movl %%edx, %%es:20(%3)\n"
11221 + "15: movl 24(%4), %%eax\n"
11222 + "16: movl 28(%4), %%edx\n"
11223 +- "17: movl %%eax, 24(%3)\n"
11224 +- "18: movl %%edx, 28(%3)\n"
11225 ++ "17: movl %%eax, %%es:24(%3)\n"
11226 ++ "18: movl %%edx, %%es:28(%3)\n"
11227 + "19: movl 32(%4), %%eax\n"
11228 + "20: movl 36(%4), %%edx\n"
11229 +- "21: movl %%eax, 32(%3)\n"
11230 +- "22: movl %%edx, 36(%3)\n"
11231 ++ "21: movl %%eax, %%es:32(%3)\n"
11232 ++ "22: movl %%edx, %%es:36(%3)\n"
11233 + "23: movl 40(%4), %%eax\n"
11234 + "24: movl 44(%4), %%edx\n"
11235 +- "25: movl %%eax, 40(%3)\n"
11236 +- "26: movl %%edx, 44(%3)\n"
11237 ++ "25: movl %%eax, %%es:40(%3)\n"
11238 ++ "26: movl %%edx, %%es:44(%3)\n"
11239 + "27: movl 48(%4), %%eax\n"
11240 + "28: movl 52(%4), %%edx\n"
11241 +- "29: movl %%eax, 48(%3)\n"
11242 +- "30: movl %%edx, 52(%3)\n"
11243 ++ "29: movl %%eax, %%es:48(%3)\n"
11244 ++ "30: movl %%edx, %%es:52(%3)\n"
11245 + "31: movl 56(%4), %%eax\n"
11246 + "32: movl 60(%4), %%edx\n"
11247 +- "33: movl %%eax, 56(%3)\n"
11248 +- "34: movl %%edx, 60(%3)\n"
11249 ++ "33: movl %%eax, %%es:56(%3)\n"
11250 ++ "34: movl %%edx, %%es:60(%3)\n"
11251 + " addl $-64, %0\n"
11252 + " addl $64, %4\n"
11253 + " addl $64, %3\n"
11254 +@@ -275,6 +289,8 @@ __copy_user_intel(void __user *to, const
11255 + "36: movl %%eax, %0\n"
11256 + "37: rep; movsb\n"
11257 + "100:\n"
11258 ++ " pushl %%ss\n"
11259 ++ " popl %%es\n"
11260 + ".section .fixup,\"ax\"\n"
11261 + "101: lea 0(%%eax,%0,4),%0\n"
11262 + " jmp 100b\n"
11263 +@@ -321,7 +337,117 @@ __copy_user_intel(void __user *to, const
11264 + " .long 99b,101b\n"
11265 + ".previous"
11266 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
11267 +- : "1"(to), "2"(from), "0"(size)
11268 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
11269 ++ : "eax", "edx", "memory");
11270 ++ return size;
11271 ++}
11272 ++
11273 ++static unsigned long
11274 ++__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
11275 ++{
11276 ++ int d0, d1;
11277 ++ __asm__ __volatile__(
11278 ++ " movw %w6, %%ds\n"
11279 ++ " .align 2,0x90\n"
11280 ++ "1: movl 32(%4), %%eax\n"
11281 ++ " cmpl $67, %0\n"
11282 ++ " jbe 3f\n"
11283 ++ "2: movl 64(%4), %%eax\n"
11284 ++ " .align 2,0x90\n"
11285 ++ "3: movl 0(%4), %%eax\n"
11286 ++ "4: movl 4(%4), %%edx\n"
11287 ++ "5: movl %%eax, %%es:0(%3)\n"
11288 ++ "6: movl %%edx, %%es:4(%3)\n"
11289 ++ "7: movl 8(%4), %%eax\n"
11290 ++ "8: movl 12(%4),%%edx\n"
11291 ++ "9: movl %%eax, %%es:8(%3)\n"
11292 ++ "10: movl %%edx, %%es:12(%3)\n"
11293 ++ "11: movl 16(%4), %%eax\n"
11294 ++ "12: movl 20(%4), %%edx\n"
11295 ++ "13: movl %%eax, %%es:16(%3)\n"
11296 ++ "14: movl %%edx, %%es:20(%3)\n"
11297 ++ "15: movl 24(%4), %%eax\n"
11298 ++ "16: movl 28(%4), %%edx\n"
11299 ++ "17: movl %%eax, %%es:24(%3)\n"
11300 ++ "18: movl %%edx, %%es:28(%3)\n"
11301 ++ "19: movl 32(%4), %%eax\n"
11302 ++ "20: movl 36(%4), %%edx\n"
11303 ++ "21: movl %%eax, %%es:32(%3)\n"
11304 ++ "22: movl %%edx, %%es:36(%3)\n"
11305 ++ "23: movl 40(%4), %%eax\n"
11306 ++ "24: movl 44(%4), %%edx\n"
11307 ++ "25: movl %%eax, %%es:40(%3)\n"
11308 ++ "26: movl %%edx, %%es:44(%3)\n"
11309 ++ "27: movl 48(%4), %%eax\n"
11310 ++ "28: movl 52(%4), %%edx\n"
11311 ++ "29: movl %%eax, %%es:48(%3)\n"
11312 ++ "30: movl %%edx, %%es:52(%3)\n"
11313 ++ "31: movl 56(%4), %%eax\n"
11314 ++ "32: movl 60(%4), %%edx\n"
11315 ++ "33: movl %%eax, %%es:56(%3)\n"
11316 ++ "34: movl %%edx, %%es:60(%3)\n"
11317 ++ " addl $-64, %0\n"
11318 ++ " addl $64, %4\n"
11319 ++ " addl $64, %3\n"
11320 ++ " cmpl $63, %0\n"
11321 ++ " ja 1b\n"
11322 ++ "35: movl %0, %%eax\n"
11323 ++ " shrl $2, %0\n"
11324 ++ " andl $3, %%eax\n"
11325 ++ " cld\n"
11326 ++ "99: rep; movsl\n"
11327 ++ "36: movl %%eax, %0\n"
11328 ++ "37: rep; movsb\n"
11329 ++ "100:\n"
11330 ++ " pushl %%ss\n"
11331 ++ " popl %%ds\n"
11332 ++ ".section .fixup,\"ax\"\n"
11333 ++ "101: lea 0(%%eax,%0,4),%0\n"
11334 ++ " jmp 100b\n"
11335 ++ ".previous\n"
11336 ++ ".section __ex_table,\"a\"\n"
11337 ++ " .align 4\n"
11338 ++ " .long 1b,100b\n"
11339 ++ " .long 2b,100b\n"
11340 ++ " .long 3b,100b\n"
11341 ++ " .long 4b,100b\n"
11342 ++ " .long 5b,100b\n"
11343 ++ " .long 6b,100b\n"
11344 ++ " .long 7b,100b\n"
11345 ++ " .long 8b,100b\n"
11346 ++ " .long 9b,100b\n"
11347 ++ " .long 10b,100b\n"
11348 ++ " .long 11b,100b\n"
11349 ++ " .long 12b,100b\n"
11350 ++ " .long 13b,100b\n"
11351 ++ " .long 14b,100b\n"
11352 ++ " .long 15b,100b\n"
11353 ++ " .long 16b,100b\n"
11354 ++ " .long 17b,100b\n"
11355 ++ " .long 18b,100b\n"
11356 ++ " .long 19b,100b\n"
11357 ++ " .long 20b,100b\n"
11358 ++ " .long 21b,100b\n"
11359 ++ " .long 22b,100b\n"
11360 ++ " .long 23b,100b\n"
11361 ++ " .long 24b,100b\n"
11362 ++ " .long 25b,100b\n"
11363 ++ " .long 26b,100b\n"
11364 ++ " .long 27b,100b\n"
11365 ++ " .long 28b,100b\n"
11366 ++ " .long 29b,100b\n"
11367 ++ " .long 30b,100b\n"
11368 ++ " .long 31b,100b\n"
11369 ++ " .long 32b,100b\n"
11370 ++ " .long 33b,100b\n"
11371 ++ " .long 34b,100b\n"
11372 ++ " .long 35b,100b\n"
11373 ++ " .long 36b,100b\n"
11374 ++ " .long 37b,100b\n"
11375 ++ " .long 99b,101b\n"
11376 ++ ".previous"
11377 ++ : "=&c"(size), "=&D" (d0), "=&S" (d1)
11378 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
11379 + : "eax", "edx", "memory");
11380 + return size;
11381 + }
11382 +@@ -331,6 +457,7 @@ __copy_user_zeroing_intel(void *to, cons
11383 + {
11384 + int d0, d1;
11385 + __asm__ __volatile__(
11386 ++ " movw %w6, %%ds\n"
11387 + " .align 2,0x90\n"
11388 + "0: movl 32(%4), %%eax\n"
11389 + " cmpl $67, %0\n"
11390 +@@ -339,36 +466,36 @@ __copy_user_zeroing_intel(void *to, cons
11391 + " .align 2,0x90\n"
11392 + "2: movl 0(%4), %%eax\n"
11393 + "21: movl 4(%4), %%edx\n"
11394 +- " movl %%eax, 0(%3)\n"
11395 +- " movl %%edx, 4(%3)\n"
11396 ++ " movl %%eax, %%es:0(%3)\n"
11397 ++ " movl %%edx, %%es:4(%3)\n"
11398 + "3: movl 8(%4), %%eax\n"
11399 + "31: movl 12(%4),%%edx\n"
11400 +- " movl %%eax, 8(%3)\n"
11401 +- " movl %%edx, 12(%3)\n"
11402 ++ " movl %%eax, %%es:8(%3)\n"
11403 ++ " movl %%edx, %%es:12(%3)\n"
11404 + "4: movl 16(%4), %%eax\n"
11405 + "41: movl 20(%4), %%edx\n"
11406 +- " movl %%eax, 16(%3)\n"
11407 +- " movl %%edx, 20(%3)\n"
11408 ++ " movl %%eax, %%es:16(%3)\n"
11409 ++ " movl %%edx, %%es:20(%3)\n"
11410 + "10: movl 24(%4), %%eax\n"
11411 + "51: movl 28(%4), %%edx\n"
11412 +- " movl %%eax, 24(%3)\n"
11413 +- " movl %%edx, 28(%3)\n"
11414 ++ " movl %%eax, %%es:24(%3)\n"
11415 ++ " movl %%edx, %%es:28(%3)\n"
11416 + "11: movl 32(%4), %%eax\n"
11417 + "61: movl 36(%4), %%edx\n"
11418 +- " movl %%eax, 32(%3)\n"
11419 +- " movl %%edx, 36(%3)\n"
11420 ++ " movl %%eax, %%es:32(%3)\n"
11421 ++ " movl %%edx, %%es:36(%3)\n"
11422 + "12: movl 40(%4), %%eax\n"
11423 + "71: movl 44(%4), %%edx\n"
11424 +- " movl %%eax, 40(%3)\n"
11425 +- " movl %%edx, 44(%3)\n"
11426 ++ " movl %%eax, %%es:40(%3)\n"
11427 ++ " movl %%edx, %%es:44(%3)\n"
11428 + "13: movl 48(%4), %%eax\n"
11429 + "81: movl 52(%4), %%edx\n"
11430 +- " movl %%eax, 48(%3)\n"
11431 +- " movl %%edx, 52(%3)\n"
11432 ++ " movl %%eax, %%es:48(%3)\n"
11433 ++ " movl %%edx, %%es:52(%3)\n"
11434 + "14: movl 56(%4), %%eax\n"
11435 + "91: movl 60(%4), %%edx\n"
11436 +- " movl %%eax, 56(%3)\n"
11437 +- " movl %%edx, 60(%3)\n"
11438 ++ " movl %%eax, %%es:56(%3)\n"
11439 ++ " movl %%edx, %%es:60(%3)\n"
11440 + " addl $-64, %0\n"
11441 + " addl $64, %4\n"
11442 + " addl $64, %3\n"
11443 +@@ -382,6 +509,8 @@ __copy_user_zeroing_intel(void *to, cons
11444 + " movl %%eax,%0\n"
11445 + "7: rep; movsb\n"
11446 + "8:\n"
11447 ++ " pushl %%ss\n"
11448 ++ " popl %%ds\n"
11449 + ".section .fixup,\"ax\"\n"
11450 + "9: lea 0(%%eax,%0,4),%0\n"
11451 + "16: pushl %0\n"
11452 +@@ -416,7 +545,7 @@ __copy_user_zeroing_intel(void *to, cons
11453 + " .long 7b,16b\n"
11454 + ".previous"
11455 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
11456 +- : "1"(to), "2"(from), "0"(size)
11457 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
11458 + : "eax", "edx", "memory");
11459 + return size;
11460 + }
11461 +@@ -432,6 +561,7 @@ static unsigned long __copy_user_zeroing
11462 + int d0, d1;
11463 +
11464 + __asm__ __volatile__(
11465 ++ " movw %w6, %%ds\n"
11466 + " .align 2,0x90\n"
11467 + "0: movl 32(%4), %%eax\n"
11468 + " cmpl $67, %0\n"
11469 +@@ -440,36 +570,36 @@ static unsigned long __copy_user_zeroing
11470 + " .align 2,0x90\n"
11471 + "2: movl 0(%4), %%eax\n"
11472 + "21: movl 4(%4), %%edx\n"
11473 +- " movnti %%eax, 0(%3)\n"
11474 +- " movnti %%edx, 4(%3)\n"
11475 ++ " movnti %%eax, %%es:0(%3)\n"
11476 ++ " movnti %%edx, %%es:4(%3)\n"
11477 + "3: movl 8(%4), %%eax\n"
11478 + "31: movl 12(%4),%%edx\n"
11479 +- " movnti %%eax, 8(%3)\n"
11480 +- " movnti %%edx, 12(%3)\n"
11481 ++ " movnti %%eax, %%es:8(%3)\n"
11482 ++ " movnti %%edx, %%es:12(%3)\n"
11483 + "4: movl 16(%4), %%eax\n"
11484 + "41: movl 20(%4), %%edx\n"
11485 +- " movnti %%eax, 16(%3)\n"
11486 +- " movnti %%edx, 20(%3)\n"
11487 ++ " movnti %%eax, %%es:16(%3)\n"
11488 ++ " movnti %%edx, %%es:20(%3)\n"
11489 + "10: movl 24(%4), %%eax\n"
11490 + "51: movl 28(%4), %%edx\n"
11491 +- " movnti %%eax, 24(%3)\n"
11492 +- " movnti %%edx, 28(%3)\n"
11493 ++ " movnti %%eax, %%es:24(%3)\n"
11494 ++ " movnti %%edx, %%es:28(%3)\n"
11495 + "11: movl 32(%4), %%eax\n"
11496 + "61: movl 36(%4), %%edx\n"
11497 +- " movnti %%eax, 32(%3)\n"
11498 +- " movnti %%edx, 36(%3)\n"
11499 ++ " movnti %%eax, %%es:32(%3)\n"
11500 ++ " movnti %%edx, %%es:36(%3)\n"
11501 + "12: movl 40(%4), %%eax\n"
11502 + "71: movl 44(%4), %%edx\n"
11503 +- " movnti %%eax, 40(%3)\n"
11504 +- " movnti %%edx, 44(%3)\n"
11505 ++ " movnti %%eax, %%es:40(%3)\n"
11506 ++ " movnti %%edx, %%es:44(%3)\n"
11507 + "13: movl 48(%4), %%eax\n"
11508 + "81: movl 52(%4), %%edx\n"
11509 +- " movnti %%eax, 48(%3)\n"
11510 +- " movnti %%edx, 52(%3)\n"
11511 ++ " movnti %%eax, %%es:48(%3)\n"
11512 ++ " movnti %%edx, %%es:52(%3)\n"
11513 + "14: movl 56(%4), %%eax\n"
11514 + "91: movl 60(%4), %%edx\n"
11515 +- " movnti %%eax, 56(%3)\n"
11516 +- " movnti %%edx, 60(%3)\n"
11517 ++ " movnti %%eax, %%es:56(%3)\n"
11518 ++ " movnti %%edx, %%es:60(%3)\n"
11519 + " addl $-64, %0\n"
11520 + " addl $64, %4\n"
11521 + " addl $64, %3\n"
11522 +@@ -484,6 +614,8 @@ static unsigned long __copy_user_zeroing
11523 + " movl %%eax,%0\n"
11524 + "7: rep; movsb\n"
11525 + "8:\n"
11526 ++ " pushl %%ss\n"
11527 ++ " popl %%ds\n"
11528 + ".section .fixup,\"ax\"\n"
11529 + "9: lea 0(%%eax,%0,4),%0\n"
11530 + "16: pushl %0\n"
11531 +@@ -518,7 +650,7 @@ static unsigned long __copy_user_zeroing
11532 + " .long 7b,16b\n"
11533 + ".previous"
11534 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
11535 +- : "1"(to), "2"(from), "0"(size)
11536 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
11537 + : "eax", "edx", "memory");
11538 + return size;
11539 + }
11540 +@@ -529,6 +661,7 @@ static unsigned long __copy_user_intel_n
11541 + int d0, d1;
11542 +
11543 + __asm__ __volatile__(
11544 ++ " movw %w6, %%ds\n"
11545 + " .align 2,0x90\n"
11546 + "0: movl 32(%4), %%eax\n"
11547 + " cmpl $67, %0\n"
11548 +@@ -537,36 +670,36 @@ static unsigned long __copy_user_intel_n
11549 + " .align 2,0x90\n"
11550 + "2: movl 0(%4), %%eax\n"
11551 + "21: movl 4(%4), %%edx\n"
11552 +- " movnti %%eax, 0(%3)\n"
11553 +- " movnti %%edx, 4(%3)\n"
11554 ++ " movnti %%eax, %%es:0(%3)\n"
11555 ++ " movnti %%edx, %%es:4(%3)\n"
11556 + "3: movl 8(%4), %%eax\n"
11557 + "31: movl 12(%4),%%edx\n"
11558 +- " movnti %%eax, 8(%3)\n"
11559 +- " movnti %%edx, 12(%3)\n"
11560 ++ " movnti %%eax, %%es:8(%3)\n"
11561 ++ " movnti %%edx, %%es:12(%3)\n"
11562 + "4: movl 16(%4), %%eax\n"
11563 + "41: movl 20(%4), %%edx\n"
11564 +- " movnti %%eax, 16(%3)\n"
11565 +- " movnti %%edx, 20(%3)\n"
11566 ++ " movnti %%eax, %%es:16(%3)\n"
11567 ++ " movnti %%edx, %%es:20(%3)\n"
11568 + "10: movl 24(%4), %%eax\n"
11569 + "51: movl 28(%4), %%edx\n"
11570 +- " movnti %%eax, 24(%3)\n"
11571 +- " movnti %%edx, 28(%3)\n"
11572 ++ " movnti %%eax, %%es:24(%3)\n"
11573 ++ " movnti %%edx, %%es:28(%3)\n"
11574 + "11: movl 32(%4), %%eax\n"
11575 + "61: movl 36(%4), %%edx\n"
11576 +- " movnti %%eax, 32(%3)\n"
11577 +- " movnti %%edx, 36(%3)\n"
11578 ++ " movnti %%eax, %%es:32(%3)\n"
11579 ++ " movnti %%edx, %%es:36(%3)\n"
11580 + "12: movl 40(%4), %%eax\n"
11581 + "71: movl 44(%4), %%edx\n"
11582 +- " movnti %%eax, 40(%3)\n"
11583 +- " movnti %%edx, 44(%3)\n"
11584 ++ " movnti %%eax, %%es:40(%3)\n"
11585 ++ " movnti %%edx, %%es:44(%3)\n"
11586 + "13: movl 48(%4), %%eax\n"
11587 + "81: movl 52(%4), %%edx\n"
11588 +- " movnti %%eax, 48(%3)\n"
11589 +- " movnti %%edx, 52(%3)\n"
11590 ++ " movnti %%eax, %%es:48(%3)\n"
11591 ++ " movnti %%edx, %%es:52(%3)\n"
11592 + "14: movl 56(%4), %%eax\n"
11593 + "91: movl 60(%4), %%edx\n"
11594 +- " movnti %%eax, 56(%3)\n"
11595 +- " movnti %%edx, 60(%3)\n"
11596 ++ " movnti %%eax, %%es:56(%3)\n"
11597 ++ " movnti %%edx, %%es:60(%3)\n"
11598 + " addl $-64, %0\n"
11599 + " addl $64, %4\n"
11600 + " addl $64, %3\n"
11601 +@@ -581,6 +714,8 @@ static unsigned long __copy_user_intel_n
11602 + " movl %%eax,%0\n"
11603 + "7: rep; movsb\n"
11604 + "8:\n"
11605 ++ " pushl %%ss\n"
11606 ++ " popl %%ds\n"
11607 + ".section .fixup,\"ax\"\n"
11608 + "9: lea 0(%%eax,%0,4),%0\n"
11609 + "16: jmp 8b\n"
11610 +@@ -609,7 +744,7 @@ static unsigned long __copy_user_intel_n
11611 + " .long 7b,16b\n"
11612 + ".previous"
11613 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
11614 +- : "1"(to), "2"(from), "0"(size)
11615 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
11616 + : "eax", "edx", "memory");
11617 + return size;
11618 + }
11619 +@@ -622,90 +757,146 @@ static unsigned long __copy_user_intel_n
11620 + */
11621 + unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
11622 + unsigned long size);
11623 +-unsigned long __copy_user_intel(void __user *to, const void *from,
11624 ++unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
11625 ++ unsigned long size);
11626 ++unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
11627 + unsigned long size);
11628 + unsigned long __copy_user_zeroing_intel_nocache(void *to,
11629 + const void __user *from, unsigned long size);
11630 + #endif /* CONFIG_X86_INTEL_USERCOPY */
11631 +
11632 + /* Generic arbitrary sized copy. */
11633 +-#define __copy_user(to, from, size) \
11634 +-do { \
11635 +- int __d0, __d1, __d2; \
11636 +- __asm__ __volatile__( \
11637 +- " cmp $7,%0\n" \
11638 +- " jbe 1f\n" \
11639 +- " movl %1,%0\n" \
11640 +- " negl %0\n" \
11641 +- " andl $7,%0\n" \
11642 +- " subl %0,%3\n" \
11643 +- "4: rep; movsb\n" \
11644 +- " movl %3,%0\n" \
11645 +- " shrl $2,%0\n" \
11646 +- " andl $3,%3\n" \
11647 +- " .align 2,0x90\n" \
11648 +- "0: rep; movsl\n" \
11649 +- " movl %3,%0\n" \
11650 +- "1: rep; movsb\n" \
11651 +- "2:\n" \
11652 +- ".section .fixup,\"ax\"\n" \
11653 +- "5: addl %3,%0\n" \
11654 +- " jmp 2b\n" \
11655 +- "3: lea 0(%3,%0,4),%0\n" \
11656 +- " jmp 2b\n" \
11657 +- ".previous\n" \
11658 +- ".section __ex_table,\"a\"\n" \
11659 +- " .align 4\n" \
11660 +- " .long 4b,5b\n" \
11661 +- " .long 0b,3b\n" \
11662 +- " .long 1b,2b\n" \
11663 +- ".previous" \
11664 +- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
11665 +- : "3"(size), "0"(size), "1"(to), "2"(from) \
11666 +- : "memory"); \
11667 +-} while (0)
11668 +-
11669 +-#define __copy_user_zeroing(to, from, size) \
11670 +-do { \
11671 +- int __d0, __d1, __d2; \
11672 +- __asm__ __volatile__( \
11673 +- " cmp $7,%0\n" \
11674 +- " jbe 1f\n" \
11675 +- " movl %1,%0\n" \
11676 +- " negl %0\n" \
11677 +- " andl $7,%0\n" \
11678 +- " subl %0,%3\n" \
11679 +- "4: rep; movsb\n" \
11680 +- " movl %3,%0\n" \
11681 +- " shrl $2,%0\n" \
11682 +- " andl $3,%3\n" \
11683 +- " .align 2,0x90\n" \
11684 +- "0: rep; movsl\n" \
11685 +- " movl %3,%0\n" \
11686 +- "1: rep; movsb\n" \
11687 +- "2:\n" \
11688 +- ".section .fixup,\"ax\"\n" \
11689 +- "5: addl %3,%0\n" \
11690 +- " jmp 6f\n" \
11691 +- "3: lea 0(%3,%0,4),%0\n" \
11692 +- "6: pushl %0\n" \
11693 +- " pushl %%eax\n" \
11694 +- " xorl %%eax,%%eax\n" \
11695 +- " rep; stosb\n" \
11696 +- " popl %%eax\n" \
11697 +- " popl %0\n" \
11698 +- " jmp 2b\n" \
11699 +- ".previous\n" \
11700 +- ".section __ex_table,\"a\"\n" \
11701 +- " .align 4\n" \
11702 +- " .long 4b,5b\n" \
11703 +- " .long 0b,3b\n" \
11704 +- " .long 1b,6b\n" \
11705 +- ".previous" \
11706 +- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
11707 +- : "3"(size), "0"(size), "1"(to), "2"(from) \
11708 +- : "memory"); \
11709 +-} while (0)
11710 ++static unsigned long
11711 ++__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
11712 ++{
11713 ++ int __d0, __d1, __d2;
11714 ++
11715 ++ __asm__ __volatile__(
11716 ++ " movw %w8,%%es\n"
11717 ++ " cmp $7,%0\n"
11718 ++ " jbe 1f\n"
11719 ++ " movl %1,%0\n"
11720 ++ " negl %0\n"
11721 ++ " andl $7,%0\n"
11722 ++ " subl %0,%3\n"
11723 ++ "4: rep; movsb\n"
11724 ++ " movl %3,%0\n"
11725 ++ " shrl $2,%0\n"
11726 ++ " andl $3,%3\n"
11727 ++ " .align 2,0x90\n"
11728 ++ "0: rep; movsl\n"
11729 ++ " movl %3,%0\n"
11730 ++ "1: rep; movsb\n"
11731 ++ "2:\n"
11732 ++ " pushl %%ss\n"
11733 ++ " popl %%es\n"
11734 ++ ".section .fixup,\"ax\"\n"
11735 ++ "5: addl %3,%0\n"
11736 ++ " jmp 2b\n"
11737 ++ "3: lea 0(%3,%0,4),%0\n"
11738 ++ " jmp 2b\n"
11739 ++ ".previous\n"
11740 ++ ".section __ex_table,\"a\"\n"
11741 ++ " .align 4\n"
11742 ++ " .long 4b,5b\n"
11743 ++ " .long 0b,3b\n"
11744 ++ " .long 1b,2b\n"
11745 ++ ".previous"
11746 ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
11747 ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
11748 ++ : "memory");
11749 ++ return size;
11750 ++}
11751 ++
11752 ++static unsigned long
11753 ++__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
11754 ++{
11755 ++ int __d0, __d1, __d2;
11756 ++
11757 ++ __asm__ __volatile__(
11758 ++ " movw %w8,%%ds\n"
11759 ++ " cmp $7,%0\n"
11760 ++ " jbe 1f\n"
11761 ++ " movl %1,%0\n"
11762 ++ " negl %0\n"
11763 ++ " andl $7,%0\n"
11764 ++ " subl %0,%3\n"
11765 ++ "4: rep; movsb\n"
11766 ++ " movl %3,%0\n"
11767 ++ " shrl $2,%0\n"
11768 ++ " andl $3,%3\n"
11769 ++ " .align 2,0x90\n"
11770 ++ "0: rep; movsl\n"
11771 ++ " movl %3,%0\n"
11772 ++ "1: rep; movsb\n"
11773 ++ "2:\n"
11774 ++ " pushl %%ss\n"
11775 ++ " popl %%ds\n"
11776 ++ ".section .fixup,\"ax\"\n"
11777 ++ "5: addl %3,%0\n"
11778 ++ " jmp 2b\n"
11779 ++ "3: lea 0(%3,%0,4),%0\n"
11780 ++ " jmp 2b\n"
11781 ++ ".previous\n"
11782 ++ ".section __ex_table,\"a\"\n"
11783 ++ " .align 4\n"
11784 ++ " .long 4b,5b\n"
11785 ++ " .long 0b,3b\n"
11786 ++ " .long 1b,2b\n"
11787 ++ ".previous"
11788 ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
11789 ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
11790 ++ : "memory");
11791 ++ return size;
11792 ++}
11793 ++
11794 ++static unsigned long
11795 ++__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
11796 ++{
11797 ++ int __d0, __d1, __d2;
11798 ++
11799 ++ __asm__ __volatile__(
11800 ++ " movw %w8,%%ds\n"
11801 ++ " cmp $7,%0\n"
11802 ++ " jbe 1f\n"
11803 ++ " movl %1,%0\n"
11804 ++ " negl %0\n"
11805 ++ " andl $7,%0\n"
11806 ++ " subl %0,%3\n"
11807 ++ "4: rep; movsb\n"
11808 ++ " movl %3,%0\n"
11809 ++ " shrl $2,%0\n"
11810 ++ " andl $3,%3\n"
11811 ++ " .align 2,0x90\n"
11812 ++ "0: rep; movsl\n"
11813 ++ " movl %3,%0\n"
11814 ++ "1: rep; movsb\n"
11815 ++ "2:\n"
11816 ++ " pushl %%ss\n"
11817 ++ " popl %%ds\n"
11818 ++ ".section .fixup,\"ax\"\n"
11819 ++ "5: addl %3,%0\n"
11820 ++ " jmp 6f\n"
11821 ++ "3: lea 0(%3,%0,4),%0\n"
11822 ++ "6: pushl %0\n"
11823 ++ " pushl %%eax\n"
11824 ++ " xorl %%eax,%%eax\n"
11825 ++ " rep; stosb\n"
11826 ++ " popl %%eax\n"
11827 ++ " popl %0\n"
11828 ++ " jmp 2b\n"
11829 ++ ".previous\n"
11830 ++ ".section __ex_table,\"a\"\n"
11831 ++ " .align 4\n"
11832 ++ " .long 4b,5b\n"
11833 ++ " .long 0b,3b\n"
11834 ++ " .long 1b,6b\n"
11835 ++ ".previous"
11836 ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
11837 ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
11838 ++ : "memory");
11839 ++ return size;
11840 ++}
11841 +
11842 + unsigned long __copy_to_user_ll(void __user *to, const void *from,
11843 + unsigned long n)
11844 +@@ -768,9 +959,9 @@ survive:
11845 + }
11846 + #endif
11847 + if (movsl_is_ok(to, from, n))
11848 +- __copy_user(to, from, n);
11849 ++ n = __generic_copy_to_user(to, from, n);
11850 + else
11851 +- n = __copy_user_intel(to, from, n);
11852 ++ n = __generic_copy_to_user_intel(to, from, n);
11853 + return n;
11854 + }
11855 + EXPORT_SYMBOL(__copy_to_user_ll);
11856 +@@ -779,7 +970,7 @@ unsigned long __copy_from_user_ll(void *
11857 + unsigned long n)
11858 + {
11859 + if (movsl_is_ok(to, from, n))
11860 +- __copy_user_zeroing(to, from, n);
11861 ++ n = __copy_user_zeroing(to, from, n);
11862 + else
11863 + n = __copy_user_zeroing_intel(to, from, n);
11864 + return n;
11865 +@@ -790,10 +981,9 @@ unsigned long __copy_from_user_ll_nozero
11866 + unsigned long n)
11867 + {
11868 + if (movsl_is_ok(to, from, n))
11869 +- __copy_user(to, from, n);
11870 ++ n = __generic_copy_from_user(to, from, n);
11871 + else
11872 +- n = __copy_user_intel((void __user *)to,
11873 +- (const void *)from, n);
11874 ++ n = __generic_copy_from_user_intel(to, from, n);
11875 + return n;
11876 + }
11877 + EXPORT_SYMBOL(__copy_from_user_ll_nozero);
11878 +@@ -802,12 +992,12 @@ unsigned long __copy_from_user_ll_nocach
11879 + unsigned long n)
11880 + {
11881 + #ifdef CONFIG_X86_INTEL_USERCOPY
11882 +- if (n > 64 && cpu_has_xmm2)
11883 ++ if ( n > 64 && cpu_has_xmm2)
11884 + n = __copy_user_zeroing_intel_nocache(to, from, n);
11885 + else
11886 +- __copy_user_zeroing(to, from, n);
11887 ++ n = __copy_user_zeroing(to, from, n);
11888 + #else
11889 +- __copy_user_zeroing(to, from, n);
11890 ++ n = __copy_user_zeroing(to, from, n);
11891 + #endif
11892 + return n;
11893 + }
11894 +@@ -817,12 +1007,12 @@ unsigned long __copy_from_user_ll_nocach
11895 + unsigned long n)
11896 + {
11897 + #ifdef CONFIG_X86_INTEL_USERCOPY
11898 +- if (n > 64 && cpu_has_xmm2)
11899 ++ if ( n > 64 && cpu_has_xmm2)
11900 + n = __copy_user_intel_nocache(to, from, n);
11901 + else
11902 +- __copy_user(to, from, n);
11903 ++ n = __generic_copy_from_user(to, from, n);
11904 + #else
11905 +- __copy_user(to, from, n);
11906 ++ n = __generic_copy_from_user(to, from, n);
11907 + #endif
11908 + return n;
11909 + }
11910 +@@ -871,8 +1061,35 @@ copy_from_user(void *to, const void __us
11911 + {
11912 + if (access_ok(VERIFY_READ, from, n))
11913 + n = __copy_from_user(to, from, n);
11914 +- else
11915 ++ else if ((long)n > 0)
11916 + memset(to, 0, n);
11917 + return n;
11918 + }
11919 + EXPORT_SYMBOL(copy_from_user);
11920 ++
11921 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
11922 ++void __set_fs(mm_segment_t x, int cpu)
11923 ++{
11924 ++ unsigned long limit = x.seg;
11925 ++ struct desc_struct d;
11926 ++
11927 ++ current_thread_info()->addr_limit = x;
11928 ++ if (likely(limit))
11929 ++ limit = (limit - 1UL) >> PAGE_SHIFT;
11930 ++ pack_descriptor(&d, 0UL, limit, 0xF3, 0xC);
11931 ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, &d, DESCTYPE_S);
11932 ++}
11933 ++
11934 ++void set_fs(mm_segment_t x)
11935 ++{
11936 ++ __set_fs(x, get_cpu());
11937 ++ put_cpu_no_resched();
11938 ++}
11939 ++#else
11940 ++void set_fs(mm_segment_t x)
11941 ++{
11942 ++ current_thread_info()->addr_limit = x;
11943 ++}
11944 ++#endif
11945 ++
11946 ++EXPORT_SYMBOL(set_fs);
11947 +diff -urNp linux-2.6.26.6/arch/x86/mach-voyager/voyager_basic.c linux-2.6.26.6/arch/x86/mach-voyager/voyager_basic.c
11948 +--- linux-2.6.26.6/arch/x86/mach-voyager/voyager_basic.c 2008-10-08 23:24:05.000000000 -0400
11949 ++++ linux-2.6.26.6/arch/x86/mach-voyager/voyager_basic.c 2008-10-11 21:54:19.000000000 -0400
11950 +@@ -123,7 +123,7 @@ int __init voyager_memory_detect(int reg
11951 + __u8 cmos[4];
11952 + ClickMap_t *map;
11953 + unsigned long map_addr;
11954 +- unsigned long old;
11955 ++ pte_t old;
11956 +
11957 + if (region >= CLICK_ENTRIES) {
11958 + printk("Voyager: Illegal ClickMap region %d\n", region);
11959 +@@ -138,7 +138,7 @@ int __init voyager_memory_detect(int reg
11960 +
11961 + /* steal page 0 for this */
11962 + old = pg0[0];
11963 +- pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
11964 ++ pg0[0] = __pte((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
11965 + local_flush_tlb();
11966 + /* now clear everything out but page 0 */
11967 + map = (ClickMap_t *) (map_addr & (~PAGE_MASK));
11968 +diff -urNp linux-2.6.26.6/arch/x86/mach-voyager/voyager_smp.c linux-2.6.26.6/arch/x86/mach-voyager/voyager_smp.c
11969 +--- linux-2.6.26.6/arch/x86/mach-voyager/voyager_smp.c 2008-10-08 23:24:05.000000000 -0400
11970 ++++ linux-2.6.26.6/arch/x86/mach-voyager/voyager_smp.c 2008-10-11 21:54:19.000000000 -0400
11971 +@@ -515,6 +515,10 @@ static void __init do_boot_cpu(__u8 cpu)
11972 + __u32 *hijack_vector;
11973 + __u32 start_phys_address = setup_trampoline();
11974 +
11975 ++#ifdef CONFIG_PAX_KERNEXEC
11976 ++ unsigned long cr0;
11977 ++#endif
11978 ++
11979 + /* There's a clever trick to this: The linux trampoline is
11980 + * compiled to begin at absolute location zero, so make the
11981 + * address zero but have the data segment selector compensate
11982 +@@ -534,7 +538,17 @@ static void __init do_boot_cpu(__u8 cpu)
11983 +
11984 + init_gdt(cpu);
11985 + per_cpu(current_task, cpu) = idle;
11986 +- early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
11987 ++
11988 ++#ifdef CONFIG_PAX_KERNEXEC
11989 ++ pax_open_kernel(cr0);
11990 ++#endif
11991 ++
11992 ++ early_gdt_descr.address = get_cpu_gdt_table(cpu);
11993 ++
11994 ++#ifdef CONFIG_PAX_KERNEXEC
11995 ++ pax_close_kernel(cr0);
11996 ++#endif
11997 ++
11998 + irq_ctx_init(cpu);
11999 +
12000 + /* Note: Don't modify initial ss override */
12001 +@@ -1217,7 +1231,7 @@ void smp_local_timer_interrupt(void)
12002 + per_cpu(prof_counter, cpu);
12003 + }
12004 +
12005 +- update_process_times(user_mode_vm(get_irq_regs()));
12006 ++ update_process_times(user_mode(get_irq_regs()));
12007 + }
12008 +
12009 + if (((1 << cpu) & voyager_extended_vic_processors) == 0)
12010 +diff -urNp linux-2.6.26.6/arch/x86/Makefile linux-2.6.26.6/arch/x86/Makefile
12011 +--- linux-2.6.26.6/arch/x86/Makefile 2008-10-08 23:24:05.000000000 -0400
12012 ++++ linux-2.6.26.6/arch/x86/Makefile 2008-10-11 21:54:19.000000000 -0400
12013 +@@ -258,3 +258,12 @@ endef
12014 + CLEAN_FILES += arch/x86/boot/fdimage \
12015 + arch/x86/boot/image.iso \
12016 + arch/x86/boot/mtools.conf
12017 ++
12018 ++define OLD_LD
12019 ++
12020 ++*** ${VERSION}.${PATCHLEVEL} PaX kernels no longer build correctly with old versions of binutils.
12021 ++*** Please upgrade your binutils to 2.18 or newer
12022 ++endef
12023 ++
12024 ++archprepare:
12025 ++ $(if $(LDFLAGS_BUILD_ID),,$(error $(OLD_LD)))
12026 +diff -urNp linux-2.6.26.6/arch/x86/mm/discontig_32.c linux-2.6.26.6/arch/x86/mm/discontig_32.c
12027 +--- linux-2.6.26.6/arch/x86/mm/discontig_32.c 2008-10-08 23:24:05.000000000 -0400
12028 ++++ linux-2.6.26.6/arch/x86/mm/discontig_32.c 2008-10-11 21:55:52.000000000 -0400
12029 +@@ -311,7 +311,7 @@ void __init remap_numa_kva(void)
12030 + #endif /* CONFIG_DISCONTIGMEM */
12031 +
12032 + extern void setup_bootmem_allocator(void);
12033 +-unsigned long __init setup_memory(void)
12034 ++unsigned void __init setup_memory(void)
12035 + {
12036 + int nid;
12037 + unsigned long system_start_pfn, system_max_low_pfn;
12038 +@@ -384,7 +384,6 @@ unsigned long __init setup_memory(void)
12039 + memset(NODE_DATA(0), 0, sizeof(struct pglist_data));
12040 + NODE_DATA(0)->bdata = &node0_bdata;
12041 + setup_bootmem_allocator();
12042 +- return max_low_pfn;
12043 + }
12044 +
12045 + void __init numa_kva_reserve(void)
12046 +diff -urNp linux-2.6.26.6/arch/x86/mm/extable.c linux-2.6.26.6/arch/x86/mm/extable.c
12047 +--- linux-2.6.26.6/arch/x86/mm/extable.c 2008-10-08 23:24:05.000000000 -0400
12048 ++++ linux-2.6.26.6/arch/x86/mm/extable.c 2008-10-11 21:55:07.000000000 -0400
12049 +@@ -1,14 +1,62 @@
12050 + #include <linux/module.h>
12051 + #include <linux/spinlock.h>
12052 ++#include <linux/sort.h>
12053 + #include <asm/uaccess.h>
12054 +
12055 ++/*
12056 ++ * The exception table needs to be sorted so that the binary
12057 ++ * search that we use to find entries in it works properly.
12058 ++ * This is used both for the kernel exception table and for
12059 ++ * the exception tables of modules that get loaded.
12060 ++ */
12061 ++static int cmp_ex(const void *a, const void *b)
12062 ++{
12063 ++ const struct exception_table_entry *x = a, *y = b;
12064 ++
12065 ++ /* avoid overflow */
12066 ++ if (x->insn > y->insn)
12067 ++ return 1;
12068 ++ if (x->insn < y->insn)
12069 ++ return -1;
12070 ++ return 0;
12071 ++}
12072 ++
12073 ++static void swap_ex(void *a, void *b, int size)
12074 ++{
12075 ++ struct exception_table_entry t, *x = a, *y = b;
12076 ++
12077 ++#ifdef CONFIG_PAX_KERNEXEC
12078 ++ unsigned long cr0;
12079 ++#endif
12080 ++
12081 ++ t = *x;
12082 ++
12083 ++#ifdef CONFIG_PAX_KERNEXEC
12084 ++ pax_open_kernel(cr0);
12085 ++#endif
12086 ++
12087 ++ *x = *y;
12088 ++ *y = t;
12089 ++
12090 ++#ifdef CONFIG_PAX_KERNEXEC
12091 ++ pax_close_kernel(cr0);
12092 ++#endif
12093 ++
12094 ++}
12095 ++
12096 ++void sort_extable(struct exception_table_entry *start,
12097 ++ struct exception_table_entry *finish)
12098 ++{
12099 ++ sort(start, finish - start, sizeof(struct exception_table_entry),
12100 ++ cmp_ex, swap_ex);
12101 ++}
12102 +
12103 + int fixup_exception(struct pt_regs *regs)
12104 + {
12105 + const struct exception_table_entry *fixup;
12106 +
12107 + #ifdef CONFIG_PNPBIOS
12108 +- if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) {
12109 ++ if (unlikely(!v8086_mode(regs) && SEGMENT_IS_PNP_CODE(regs->cs))) {
12110 + extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
12111 + extern u32 pnp_bios_is_utter_crap;
12112 + pnp_bios_is_utter_crap = 1;
12113 +diff -urNp linux-2.6.26.6/arch/x86/mm/fault.c linux-2.6.26.6/arch/x86/mm/fault.c
12114 +--- linux-2.6.26.6/arch/x86/mm/fault.c 2008-10-08 23:24:05.000000000 -0400
12115 ++++ linux-2.6.26.6/arch/x86/mm/fault.c 2008-10-11 21:55:07.000000000 -0400
12116 +@@ -25,6 +25,8 @@
12117 + #include <linux/kprobes.h>
12118 + #include <linux/uaccess.h>
12119 + #include <linux/kdebug.h>
12120 ++#include <linux/unistd.h>
12121 ++#include <linux/compiler.h>
12122 +
12123 + #include <asm/system.h>
12124 + #include <asm/desc.h>
12125 +@@ -34,6 +36,7 @@
12126 + #include <asm/tlbflush.h>
12127 + #include <asm/proto.h>
12128 + #include <asm-generic/sections.h>
12129 ++#include <asm/tlbflush.h>
12130 +
12131 + /*
12132 + * Page fault error code bits
12133 +@@ -55,11 +58,7 @@ static inline int notify_page_fault(stru
12134 + int ret = 0;
12135 +
12136 + /* kprobe_running() needs smp_processor_id() */
12137 +-#ifdef CONFIG_X86_32
12138 +- if (!user_mode_vm(regs)) {
12139 +-#else
12140 + if (!user_mode(regs)) {
12141 +-#endif
12142 + preempt_disable();
12143 + if (kprobe_running() && kprobe_fault_handler(regs, 14))
12144 + ret = 1;
12145 +@@ -257,6 +256,30 @@ bad:
12146 + #endif
12147 + }
12148 +
12149 ++#ifdef CONFIG_PAX_EMUTRAMP
12150 ++static int pax_handle_fetch_fault(struct pt_regs *regs);
12151 ++#endif
12152 ++
12153 ++#ifdef CONFIG_PAX_PAGEEXEC
12154 ++static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
12155 ++{
12156 ++ pgd_t *pgd;
12157 ++ pud_t *pud;
12158 ++ pmd_t *pmd;
12159 ++
12160 ++ pgd = pgd_offset(mm, address);
12161 ++ if (!pgd_present(*pgd))
12162 ++ return NULL;
12163 ++ pud = pud_offset(pgd, address);
12164 ++ if (!pud_present(*pud))
12165 ++ return NULL;
12166 ++ pmd = pmd_offset(pud, address);
12167 ++ if (!pmd_present(*pmd))
12168 ++ return NULL;
12169 ++ return pmd;
12170 ++}
12171 ++#endif
12172 ++
12173 + #ifdef CONFIG_X86_32
12174 + static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
12175 + {
12176 +@@ -343,7 +366,7 @@ static int is_errata93(struct pt_regs *r
12177 + static int is_errata100(struct pt_regs *regs, unsigned long address)
12178 + {
12179 + #ifdef CONFIG_X86_64
12180 +- if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) &&
12181 ++ if ((regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT)) &&
12182 + (address >> 32))
12183 + return 1;
12184 + #endif
12185 +@@ -380,17 +403,32 @@ static void show_fault_oops(struct pt_re
12186 + #endif
12187 +
12188 + #ifdef CONFIG_X86_PAE
12189 +- if (error_code & PF_INSTR) {
12190 ++ if (nx_enabled && (error_code & PF_INSTR)) {
12191 + unsigned int level;
12192 + pte_t *pte = lookup_address(address, &level);
12193 +
12194 + if (pte && pte_present(*pte) && !pte_exec(*pte))
12195 + printk(KERN_CRIT "kernel tried to execute "
12196 + "NX-protected page - exploit attempt? "
12197 +- "(uid: %d)\n", current->uid);
12198 ++ "(uid: %d, task: %s, pid: %d)\n",
12199 ++ current->uid, current->comm, task_pid_nr(current));
12200 + }
12201 + #endif
12202 +
12203 ++#ifdef CONFIG_PAX_KERNEXEC
12204 ++#ifdef CONFIG_MODULES
12205 ++ if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
12206 ++#else
12207 ++ if (init_mm.start_code <= address && address < init_mm.end_code)
12208 ++#endif
12209 ++ if (current->signal->curr_ip)
12210 ++ printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
12211 ++ NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current->uid, current->euid);
12212 ++ else
12213 ++ printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
12214 ++ current->comm, task_pid_nr(current), current->uid, current->euid);
12215 ++#endif
12216 ++
12217 + printk(KERN_ALERT "BUG: unable to handle kernel ");
12218 + if (address < PAGE_SIZE)
12219 + printk(KERN_CONT "NULL pointer dereference");
12220 +@@ -583,13 +621,22 @@ void __kprobes do_page_fault(struct pt_r
12221 + struct task_struct *tsk;
12222 + struct mm_struct *mm;
12223 + struct vm_area_struct *vma;
12224 +- unsigned long address;
12225 + int write, si_code;
12226 + int fault;
12227 + #ifdef CONFIG_X86_64
12228 + unsigned long flags;
12229 + #endif
12230 +
12231 ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
12232 ++ pte_t *pte;
12233 ++ pmd_t *pmd;
12234 ++ spinlock_t *ptl;
12235 ++ unsigned char pte_mask;
12236 ++#endif
12237 ++
12238 ++ /* get the address */
12239 ++ const unsigned long address = read_cr2();
12240 ++
12241 + /*
12242 + * We can fault from pretty much anywhere, with unknown IRQ state.
12243 + */
12244 +@@ -599,9 +646,6 @@ void __kprobes do_page_fault(struct pt_r
12245 + mm = tsk->mm;
12246 + prefetchw(&mm->mmap_sem);
12247 +
12248 +- /* get the address */
12249 +- address = read_cr2();
12250 +-
12251 + si_code = SEGV_MAPERR;
12252 +
12253 + if (notify_page_fault(regs))
12254 +@@ -652,7 +696,7 @@ void __kprobes do_page_fault(struct pt_r
12255 + * atomic region then we must not take the fault.
12256 + */
12257 + if (in_atomic() || !mm)
12258 +- goto bad_area_nosemaphore;
12259 ++ goto bad_area_nopax;
12260 + #else /* CONFIG_X86_64 */
12261 + if (likely(regs->flags & X86_EFLAGS_IF))
12262 + local_irq_enable();
12263 +@@ -665,13 +709,13 @@ void __kprobes do_page_fault(struct pt_r
12264 + * atomic region then we must not take the fault.
12265 + */
12266 + if (unlikely(in_atomic() || !mm))
12267 +- goto bad_area_nosemaphore;
12268 ++ goto bad_area_nopax;
12269 +
12270 + /*
12271 + * User-mode registers count as a user access even for any
12272 + * potential system fault or CPU buglet.
12273 + */
12274 +- if (user_mode_vm(regs))
12275 ++ if (user_mode(regs))
12276 + error_code |= PF_USER;
12277 + again:
12278 + #endif
12279 +@@ -693,10 +737,104 @@ again:
12280 + if (!down_read_trylock(&mm->mmap_sem)) {
12281 + if ((error_code & PF_USER) == 0 &&
12282 + !search_exception_tables(regs->ip))
12283 +- goto bad_area_nosemaphore;
12284 ++ goto bad_area_nopax;
12285 + down_read(&mm->mmap_sem);
12286 + }
12287 +
12288 ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
12289 ++ if (nx_enabled || (error_code & (PF_PROT|PF_USER)) != (PF_PROT|PF_USER) || v8086_mode(regs) ||
12290 ++ !(mm->pax_flags & MF_PAX_PAGEEXEC))
12291 ++ goto not_pax_fault;
12292 ++
12293 ++ /* PaX: it's our fault, let's handle it if we can */
12294 ++
12295 ++ /* PaX: take a look at read faults before acquiring any locks */
12296 ++ if (unlikely(!(error_code & PF_WRITE) && (regs->ip == address))) {
12297 ++ /* instruction fetch attempt from a protected page in user mode */
12298 ++ up_read(&mm->mmap_sem);
12299 ++
12300 ++#ifdef CONFIG_PAX_EMUTRAMP
12301 ++ switch (pax_handle_fetch_fault(regs)) {
12302 ++ case 2:
12303 ++ return;
12304 ++ }
12305 ++#endif
12306 ++
12307 ++ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
12308 ++ do_group_exit(SIGKILL);
12309 ++ }
12310 ++
12311 ++ pmd = pax_get_pmd(mm, address);
12312 ++ if (unlikely(!pmd))
12313 ++ goto not_pax_fault;
12314 ++
12315 ++ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
12316 ++ if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
12317 ++ pte_unmap_unlock(pte, ptl);
12318 ++ goto not_pax_fault;
12319 ++ }
12320 ++
12321 ++ if (unlikely((error_code & PF_WRITE) && !pte_write(*pte))) {
12322 ++ /* write attempt to a protected page in user mode */
12323 ++ pte_unmap_unlock(pte, ptl);
12324 ++ goto not_pax_fault;
12325 ++ }
12326 ++
12327 ++#ifdef CONFIG_SMP
12328 ++ if (likely(address > get_limit(regs->cs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
12329 ++#else
12330 ++ if (likely(address > get_limit(regs->cs)))
12331 ++#endif
12332 ++ {
12333 ++ set_pte(pte, pte_mkread(*pte));
12334 ++ __flush_tlb_one(address);
12335 ++ pte_unmap_unlock(pte, ptl);
12336 ++ up_read(&mm->mmap_sem);
12337 ++ return;
12338 ++ }
12339 ++
12340 ++ pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & PF_WRITE) << (_PAGE_BIT_DIRTY-1));
12341 ++
12342 ++ /*
12343 ++ * PaX: fill DTLB with user rights and retry
12344 ++ */
12345 ++ __asm__ __volatile__ (
12346 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
12347 ++ "movw %w4,%%es\n"
12348 ++#endif
12349 ++ "orb %2,(%1)\n"
12350 ++#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
12351 ++/*
12352 ++ * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
12353 ++ * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
12354 ++ * page fault when examined during a TLB load attempt. this is true not only
12355 ++ * for PTEs holding a non-present entry but also present entries that will
12356 ++ * raise a page fault (such as those set up by PaX, or the copy-on-write
12357 ++ * mechanism). in effect it means that we do *not* need to flush the TLBs
12358 ++ * for our target pages since their PTEs are simply not in the TLBs at all.
12359 ++
12360 ++ * the best thing in omitting it is that we gain around 15-20% speed in the
12361 ++ * fast path of the page fault handler and can get rid of tracing since we
12362 ++ * can no longer flush unintended entries.
12363 ++ */
12364 ++ "invlpg (%0)\n"
12365 ++#endif
12366 ++ "testb $0,%%es:(%0)\n"
12367 ++ "xorb %3,(%1)\n"
12368 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
12369 ++ "pushl %%ss\n"
12370 ++ "popl %%es\n"
12371 ++#endif
12372 ++ :
12373 ++ : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
12374 ++ : "memory", "cc");
12375 ++ pte_unmap_unlock(pte, ptl);
12376 ++ up_read(&mm->mmap_sem);
12377 ++ return;
12378 ++
12379 ++not_pax_fault:
12380 ++#endif
12381 ++
12382 + vma = find_vma(mm, address);
12383 + if (!vma)
12384 + goto bad_area;
12385 +@@ -714,6 +852,12 @@ again:
12386 + if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp)
12387 + goto bad_area;
12388 + }
12389 ++
12390 ++#ifdef CONFIG_PAX_SEGMEXEC
12391 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)
12392 ++ goto bad_area;
12393 ++#endif
12394 ++
12395 + if (expand_stack(vma, address))
12396 + goto bad_area;
12397 + /*
12398 +@@ -723,6 +867,8 @@ again:
12399 + good_area:
12400 + si_code = SEGV_ACCERR;
12401 + write = 0;
12402 ++ if (nx_enabled && (error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
12403 ++ goto bad_area;
12404 + switch (error_code & (PF_PROT|PF_WRITE)) {
12405 + default: /* 3: write, present */
12406 + /* fall through */
12407 +@@ -780,6 +926,54 @@ bad_area:
12408 + up_read(&mm->mmap_sem);
12409 +
12410 + bad_area_nosemaphore:
12411 ++
12412 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
12413 ++ if (mm && (error_code & PF_USER)) {
12414 ++ unsigned long ip = regs->ip;
12415 ++
12416 ++ if (v8086_mode(regs))
12417 ++ ip = ((regs->cs & 0xffff) << 4) + (regs->ip & 0xffff);
12418 ++
12419 ++ /*
12420 ++ * It's possible to have interrupts off here.
12421 ++ */
12422 ++ local_irq_enable();
12423 ++
12424 ++#ifdef CONFIG_PAX_PAGEEXEC
12425 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) &&
12426 ++ (nx_enabled && ((error_code & PF_INSTR) || !(error_code & (PF_PROT | PF_WRITE))) && (regs->ip == address))) {
12427 ++
12428 ++#ifdef CONFIG_PAX_EMUTRAMP
12429 ++ switch (pax_handle_fetch_fault(regs)) {
12430 ++ case 2:
12431 ++ return;
12432 ++ }
12433 ++#endif
12434 ++
12435 ++ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
12436 ++ do_group_exit(SIGKILL);
12437 ++ }
12438 ++#endif
12439 ++
12440 ++#ifdef CONFIG_PAX_SEGMEXEC
12441 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & (PF_PROT | PF_WRITE)) && (regs->ip + SEGMEXEC_TASK_SIZE == address)) {
12442 ++
12443 ++#ifdef CONFIG_PAX_EMUTRAMP
12444 ++ switch (pax_handle_fetch_fault(regs)) {
12445 ++ case 2:
12446 ++ return;
12447 ++ }
12448 ++#endif
12449 ++
12450 ++ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
12451 ++ do_group_exit(SIGKILL);
12452 ++ }
12453 ++#endif
12454 ++
12455 ++ }
12456 ++#endif
12457 ++
12458 ++bad_area_nopax:
12459 + /* User mode accesses just cause a SIGSEGV */
12460 + if (error_code & PF_USER) {
12461 + /*
12462 +@@ -862,7 +1056,7 @@ no_context:
12463 + #ifdef CONFIG_X86_32
12464 + die("Oops", regs, error_code);
12465 + bust_spinlocks(0);
12466 +- do_exit(SIGKILL);
12467 ++ do_group_exit(SIGKILL);
12468 + #else
12469 + if (__die("Oops", regs, error_code))
12470 + regs = NULL;
12471 +@@ -876,17 +1070,17 @@ no_context:
12472 + * us unable to handle the page fault gracefully.
12473 + */
12474 + out_of_memory:
12475 +- up_read(&mm->mmap_sem);
12476 + if (is_global_init(tsk)) {
12477 + yield();
12478 + #ifdef CONFIG_X86_32
12479 +- down_read(&mm->mmap_sem);
12480 + goto survive;
12481 + #else
12482 ++ up_read(&mm->mmap_sem);
12483 + goto again;
12484 + #endif
12485 + }
12486 +
12487 ++ up_read(&mm->mmap_sem);
12488 + printk("VM: killing process %s\n", tsk->comm);
12489 + if (error_code & PF_USER)
12490 + do_group_exit(SIGKILL);
12491 +@@ -983,3 +1177,174 @@ void vmalloc_sync_all(void)
12492 + }
12493 + #endif
12494 + }
12495 ++
12496 ++#ifdef CONFIG_PAX_EMUTRAMP
12497 ++static int pax_handle_fetch_fault_32(struct pt_regs *regs)
12498 ++{
12499 ++ int err;
12500 ++
12501 ++ do { /* PaX: gcc trampoline emulation #1 */
12502 ++ unsigned char mov1, mov2;
12503 ++ unsigned short jmp;
12504 ++ unsigned int addr1, addr2;
12505 ++
12506 ++#ifdef CONFIG_X86_64
12507 ++ if ((regs->ip + 11) >> 32)
12508 ++ break;
12509 ++#endif
12510 ++
12511 ++ err = get_user(mov1, (unsigned char __user *)regs->ip);
12512 ++ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
12513 ++ err |= get_user(mov2, (unsigned char __user *)(regs->ip + 5));
12514 ++ err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
12515 ++ err |= get_user(jmp, (unsigned short __user *)(regs->ip + 10));
12516 ++
12517 ++ if (err)
12518 ++ break;
12519 ++
12520 ++ if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
12521 ++ regs->cx = addr1;
12522 ++ regs->ax = addr2;
12523 ++ regs->ip = addr2;
12524 ++ return 2;
12525 ++ }
12526 ++ } while (0);
12527 ++
12528 ++ do { /* PaX: gcc trampoline emulation #2 */
12529 ++ unsigned char mov, jmp;
12530 ++ unsigned int addr1, addr2;
12531 ++
12532 ++#ifdef CONFIG_X86_64
12533 ++ if ((regs->ip + 9) >> 32)
12534 ++ break;
12535 ++#endif
12536 ++
12537 ++ err = get_user(mov, (unsigned char __user *)regs->ip);
12538 ++ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
12539 ++ err |= get_user(jmp, (unsigned char __user *)(regs->ip + 5));
12540 ++ err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
12541 ++
12542 ++ if (err)
12543 ++ break;
12544 ++
12545 ++ if (mov == 0xB9 && jmp == 0xE9) {
12546 ++ regs->cx = addr1;
12547 ++ regs->ip = (unsigned int)(regs->ip + addr2 + 10);
12548 ++ return 2;
12549 ++ }
12550 ++ } while (0);
12551 ++
12552 ++ return 1; /* PaX in action */
12553 ++}
12554 ++
12555 ++#ifdef CONFIG_X86_64
12556 ++static int pax_handle_fetch_fault_64(struct pt_regs *regs)
12557 ++{
12558 ++ int err;
12559 ++
12560 ++ do { /* PaX: gcc trampoline emulation #1 */
12561 ++ unsigned short mov1, mov2, jmp1;
12562 ++ unsigned char jmp2;
12563 ++ unsigned int addr1;
12564 ++ unsigned long addr2;
12565 ++
12566 ++ err = get_user(mov1, (unsigned short __user *)regs->ip);
12567 ++ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 2));
12568 ++ err |= get_user(mov2, (unsigned short __user *)(regs->ip + 6));
12569 ++ err |= get_user(addr2, (unsigned long __user *)(regs->ip + 8));
12570 ++ err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 16));
12571 ++ err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 18));
12572 ++
12573 ++ if (err)
12574 ++ break;
12575 ++
12576 ++ if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
12577 ++ regs->r11 = addr1;
12578 ++ regs->r10 = addr2;
12579 ++ regs->ip = addr1;
12580 ++ return 2;
12581 ++ }
12582 ++ } while (0);
12583 ++
12584 ++ do { /* PaX: gcc trampoline emulation #2 */
12585 ++ unsigned short mov1, mov2, jmp1;
12586 ++ unsigned char jmp2;
12587 ++ unsigned long addr1, addr2;
12588 ++
12589 ++ err = get_user(mov1, (unsigned short __user *)regs->ip);
12590 ++ err |= get_user(addr1, (unsigned long __user *)(regs->ip + 2));
12591 ++ err |= get_user(mov2, (unsigned short __user *)(regs->ip + 10));
12592 ++ err |= get_user(addr2, (unsigned long __user *)(regs->ip + 12));
12593 ++ err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 20));
12594 ++ err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 22));
12595 ++
12596 ++ if (err)
12597 ++ break;
12598 ++
12599 ++ if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
12600 ++ regs->r11 = addr1;
12601 ++ regs->r10 = addr2;
12602 ++ regs->ip = addr1;
12603 ++ return 2;
12604 ++ }
12605 ++ } while (0);
12606 ++
12607 ++ return 1; /* PaX in action */
12608 ++}
12609 ++#endif
12610 ++
12611 ++/*
12612 ++ * PaX: decide what to do with offenders (regs->ip = fault address)
12613 ++ *
12614 ++ * returns 1 when task should be killed
12615 ++ * 2 when gcc trampoline was detected
12616 ++ */
12617 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
12618 ++{
12619 ++ if (v8086_mode(regs))
12620 ++ return 1;
12621 ++
12622 ++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
12623 ++ return 1;
12624 ++
12625 ++#ifdef CONFIG_X86_32
12626 ++ return pax_handle_fetch_fault_32(regs);
12627 ++#else
12628 ++ if (regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT))
12629 ++ return pax_handle_fetch_fault_32(regs);
12630 ++ else
12631 ++ return pax_handle_fetch_fault_64(regs);
12632 ++#endif
12633 ++}
12634 ++#endif
12635 ++
12636 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
12637 ++void pax_report_insns(void *pc, void *sp)
12638 ++{
12639 ++ long i;
12640 ++
12641 ++ printk(KERN_ERR "PAX: bytes at PC: ");
12642 ++ for (i = 0; i < 20; i++) {
12643 ++ unsigned char c;
12644 ++ if (get_user(c, (unsigned char __user *)pc+i))
12645 ++ printk(KERN_CONT "?? ");
12646 ++ else
12647 ++ printk(KERN_CONT "%02x ", c);
12648 ++ }
12649 ++ printk("\n");
12650 ++
12651 ++ printk(KERN_ERR "PAX: bytes at SP-%lu: ", (unsigned long)sizeof(long));
12652 ++ for (i = -1; i < 80 / sizeof(long); i++) {
12653 ++ unsigned long c;
12654 ++ if (get_user(c, (unsigned long __user *)sp+i))
12655 ++#ifdef CONFIG_X86_32
12656 ++ printk(KERN_CONT "???????? ");
12657 ++#else
12658 ++ printk(KERN_CONT "???????????????? ");
12659 ++#endif
12660 ++ else
12661 ++ printk(KERN_CONT "%0*lx ", 2 * (int)sizeof(long), c);
12662 ++ }
12663 ++ printk("\n");
12664 ++}
12665 ++#endif
12666 +diff -urNp linux-2.6.26.6/arch/x86/mm/highmem_32.c linux-2.6.26.6/arch/x86/mm/highmem_32.c
12667 +--- linux-2.6.26.6/arch/x86/mm/highmem_32.c 2008-10-08 23:24:05.000000000 -0400
12668 ++++ linux-2.6.26.6/arch/x86/mm/highmem_32.c 2008-10-11 21:54:19.000000000 -0400
12669 +@@ -74,6 +74,10 @@ void *kmap_atomic_prot(struct page *page
12670 + enum fixed_addresses idx;
12671 + unsigned long vaddr;
12672 +
12673 ++#ifdef CONFIG_PAX_KERNEXEC
12674 ++ unsigned long cr0;
12675 ++#endif
12676 ++
12677 + /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
12678 + pagefault_disable();
12679 +
12680 +@@ -85,7 +89,17 @@ void *kmap_atomic_prot(struct page *page
12681 + idx = type + KM_TYPE_NR*smp_processor_id();
12682 + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
12683 + BUG_ON(!pte_none(*(kmap_pte-idx)));
12684 ++
12685 ++#ifdef CONFIG_PAX_KERNEXEC
12686 ++ pax_open_kernel(cr0);
12687 ++#endif
12688 ++
12689 + set_pte(kmap_pte-idx, mk_pte(page, prot));
12690 ++
12691 ++#ifdef CONFIG_PAX_KERNEXEC
12692 ++ pax_close_kernel(cr0);
12693 ++#endif
12694 ++
12695 + arch_flush_lazy_mmu_mode();
12696 +
12697 + return (void *)vaddr;
12698 +@@ -101,15 +115,29 @@ void kunmap_atomic(void *kvaddr, enum km
12699 + unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
12700 + enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
12701 +
12702 ++#ifdef CONFIG_PAX_KERNEXEC
12703 ++ unsigned long cr0;
12704 ++#endif
12705 ++
12706 + /*
12707 + * Force other mappings to Oops if they'll try to access this pte
12708 + * without first remap it. Keeping stale mappings around is a bad idea
12709 + * also, in case the page changes cacheability attributes or becomes
12710 + * a protected page in a hypervisor.
12711 + */
12712 +- if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx))
12713 ++ if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) {
12714 ++
12715 ++#ifdef CONFIG_PAX_KERNEXEC
12716 ++ pax_open_kernel(cr0);
12717 ++#endif
12718 ++
12719 + kpte_clear_flush(kmap_pte-idx, vaddr);
12720 +- else {
12721 ++
12722 ++#ifdef CONFIG_PAX_KERNEXEC
12723 ++ pax_close_kernel(cr0);
12724 ++#endif
12725 ++
12726 ++ } else {
12727 + #ifdef CONFIG_DEBUG_HIGHMEM
12728 + BUG_ON(vaddr < PAGE_OFFSET);
12729 + BUG_ON(vaddr >= (unsigned long)high_memory);
12730 +@@ -128,11 +156,25 @@ void *kmap_atomic_pfn(unsigned long pfn,
12731 + enum fixed_addresses idx;
12732 + unsigned long vaddr;
12733 +
12734 ++#ifdef CONFIG_PAX_KERNEXEC
12735 ++ unsigned long cr0;
12736 ++#endif
12737 ++
12738 + pagefault_disable();
12739 +
12740 + idx = type + KM_TYPE_NR*smp_processor_id();
12741 + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
12742 ++
12743 ++#ifdef CONFIG_PAX_KERNEXEC
12744 ++ pax_open_kernel(cr0);
12745 ++#endif
12746 ++
12747 + set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
12748 ++
12749 ++#ifdef CONFIG_PAX_KERNEXEC
12750 ++ pax_close_kernel(cr0);
12751 ++#endif
12752 ++
12753 + arch_flush_lazy_mmu_mode();
12754 +
12755 + return (void*) vaddr;
12756 +diff -urNp linux-2.6.26.6/arch/x86/mm/hugetlbpage.c linux-2.6.26.6/arch/x86/mm/hugetlbpage.c
12757 +--- linux-2.6.26.6/arch/x86/mm/hugetlbpage.c 2008-10-08 23:24:05.000000000 -0400
12758 ++++ linux-2.6.26.6/arch/x86/mm/hugetlbpage.c 2008-10-11 21:54:19.000000000 -0400
12759 +@@ -230,13 +230,18 @@ static unsigned long hugetlb_get_unmappe
12760 + {
12761 + struct mm_struct *mm = current->mm;
12762 + struct vm_area_struct *vma;
12763 +- unsigned long start_addr;
12764 ++ unsigned long start_addr, pax_task_size = TASK_SIZE;
12765 ++
12766 ++#ifdef CONFIG_PAX_SEGMEXEC
12767 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
12768 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
12769 ++#endif
12770 +
12771 + if (len > mm->cached_hole_size) {
12772 +- start_addr = mm->free_area_cache;
12773 ++ start_addr = mm->free_area_cache;
12774 + } else {
12775 +- start_addr = TASK_UNMAPPED_BASE;
12776 +- mm->cached_hole_size = 0;
12777 ++ start_addr = mm->mmap_base;
12778 ++ mm->cached_hole_size = 0;
12779 + }
12780 +
12781 + full_search:
12782 +@@ -244,13 +249,13 @@ full_search:
12783 +
12784 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
12785 + /* At this point: (!vma || addr < vma->vm_end). */
12786 +- if (TASK_SIZE - len < addr) {
12787 ++ if (pax_task_size - len < addr) {
12788 + /*
12789 + * Start a new search - just in case we missed
12790 + * some holes.
12791 + */
12792 +- if (start_addr != TASK_UNMAPPED_BASE) {
12793 +- start_addr = TASK_UNMAPPED_BASE;
12794 ++ if (start_addr != mm->mmap_base) {
12795 ++ start_addr = mm->mmap_base;
12796 + mm->cached_hole_size = 0;
12797 + goto full_search;
12798 + }
12799 +@@ -272,9 +277,8 @@ static unsigned long hugetlb_get_unmappe
12800 + {
12801 + struct mm_struct *mm = current->mm;
12802 + struct vm_area_struct *vma, *prev_vma;
12803 +- unsigned long base = mm->mmap_base, addr = addr0;
12804 ++ unsigned long base = mm->mmap_base, addr;
12805 + unsigned long largest_hole = mm->cached_hole_size;
12806 +- int first_time = 1;
12807 +
12808 + /* don't allow allocations above current base */
12809 + if (mm->free_area_cache > base)
12810 +@@ -284,7 +288,7 @@ static unsigned long hugetlb_get_unmappe
12811 + largest_hole = 0;
12812 + mm->free_area_cache = base;
12813 + }
12814 +-try_again:
12815 ++
12816 + /* make sure it can fit in the remaining address space */
12817 + if (mm->free_area_cache < len)
12818 + goto fail;
12819 +@@ -326,22 +330,26 @@ try_again:
12820 +
12821 + fail:
12822 + /*
12823 +- * if hint left us with no space for the requested
12824 +- * mapping then try again:
12825 +- */
12826 +- if (first_time) {
12827 +- mm->free_area_cache = base;
12828 +- largest_hole = 0;
12829 +- first_time = 0;
12830 +- goto try_again;
12831 +- }
12832 +- /*
12833 + * A failed mmap() very likely causes application failure,
12834 + * so fall back to the bottom-up function here. This scenario
12835 + * can happen with large stack limits and large mmap()
12836 + * allocations.
12837 + */
12838 +- mm->free_area_cache = TASK_UNMAPPED_BASE;
12839 ++
12840 ++#ifdef CONFIG_PAX_SEGMEXEC
12841 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
12842 ++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
12843 ++ else
12844 ++#endif
12845 ++
12846 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
12847 ++
12848 ++#ifdef CONFIG_PAX_RANDMMAP
12849 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
12850 ++ mm->mmap_base += mm->delta_mmap;
12851 ++#endif
12852 ++
12853 ++ mm->free_area_cache = mm->mmap_base;
12854 + mm->cached_hole_size = ~0UL;
12855 + addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
12856 + len, pgoff, flags);
12857 +@@ -349,6 +357,7 @@ fail:
12858 + /*
12859 + * Restore the topdown base:
12860 + */
12861 ++ mm->mmap_base = base;
12862 + mm->free_area_cache = base;
12863 + mm->cached_hole_size = ~0UL;
12864 +
12865 +@@ -361,10 +370,17 @@ hugetlb_get_unmapped_area(struct file *f
12866 + {
12867 + struct mm_struct *mm = current->mm;
12868 + struct vm_area_struct *vma;
12869 ++ unsigned long pax_task_size = TASK_SIZE;
12870 +
12871 + if (len & ~HPAGE_MASK)
12872 + return -EINVAL;
12873 +- if (len > TASK_SIZE)
12874 ++
12875 ++#ifdef CONFIG_PAX_SEGMEXEC
12876 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
12877 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
12878 ++#endif
12879 ++
12880 ++ if (len > pax_task_size)
12881 + return -ENOMEM;
12882 +
12883 + if (flags & MAP_FIXED) {
12884 +@@ -376,7 +392,7 @@ hugetlb_get_unmapped_area(struct file *f
12885 + if (addr) {
12886 + addr = ALIGN(addr, HPAGE_SIZE);
12887 + vma = find_vma(mm, addr);
12888 +- if (TASK_SIZE - len >= addr &&
12889 ++ if (pax_task_size - len >= addr &&
12890 + (!vma || addr + len <= vma->vm_start))
12891 + return addr;
12892 + }
12893 +diff -urNp linux-2.6.26.6/arch/x86/mm/init_32.c linux-2.6.26.6/arch/x86/mm/init_32.c
12894 +--- linux-2.6.26.6/arch/x86/mm/init_32.c 2008-10-08 23:24:05.000000000 -0400
12895 ++++ linux-2.6.26.6/arch/x86/mm/init_32.c 2008-10-11 21:54:19.000000000 -0400
12896 +@@ -47,6 +47,7 @@
12897 + #include <asm/paravirt.h>
12898 + #include <asm/setup.h>
12899 + #include <asm/cacheflush.h>
12900 ++#include <asm/desc.h>
12901 +
12902 + unsigned int __VMALLOC_RESERVE = 128 << 20;
12903 +
12904 +@@ -58,32 +59,6 @@ unsigned long highstart_pfn, highend_pfn
12905 + static noinline int do_test_wp_bit(void);
12906 +
12907 + /*
12908 +- * Creates a middle page table and puts a pointer to it in the
12909 +- * given global directory entry. This only returns the gd entry
12910 +- * in non-PAE compilation mode, since the middle layer is folded.
12911 +- */
12912 +-static pmd_t * __init one_md_table_init(pgd_t *pgd)
12913 +-{
12914 +- pud_t *pud;
12915 +- pmd_t *pmd_table;
12916 +-
12917 +-#ifdef CONFIG_X86_PAE
12918 +- if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
12919 +- pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
12920 +-
12921 +- paravirt_alloc_pmd(&init_mm, __pa(pmd_table) >> PAGE_SHIFT);
12922 +- set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
12923 +- pud = pud_offset(pgd, 0);
12924 +- BUG_ON(pmd_table != pmd_offset(pud, 0));
12925 +- }
12926 +-#endif
12927 +- pud = pud_offset(pgd, 0);
12928 +- pmd_table = pmd_offset(pud, 0);
12929 +-
12930 +- return pmd_table;
12931 +-}
12932 +-
12933 +-/*
12934 + * Create a page table and place a pointer to it in a middle page
12935 + * directory entry:
12936 + */
12937 +@@ -101,7 +76,11 @@ static pte_t * __init one_page_table_ini
12938 + }
12939 +
12940 + paravirt_alloc_pte(&init_mm, __pa(page_table) >> PAGE_SHIFT);
12941 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
12942 ++ set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
12943 ++#else
12944 + set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
12945 ++#endif
12946 + BUG_ON(page_table != pte_offset_kernel(pmd, 0));
12947 + }
12948 +
12949 +@@ -123,6 +102,7 @@ page_table_range_init(unsigned long star
12950 + int pgd_idx, pmd_idx;
12951 + unsigned long vaddr;
12952 + pgd_t *pgd;
12953 ++ pud_t *pud;
12954 + pmd_t *pmd;
12955 +
12956 + vaddr = start;
12957 +@@ -131,8 +111,13 @@ page_table_range_init(unsigned long star
12958 + pgd = pgd_base + pgd_idx;
12959 +
12960 + for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
12961 +- pmd = one_md_table_init(pgd);
12962 +- pmd = pmd + pmd_index(vaddr);
12963 ++ pud = pud_offset(pgd, vaddr);
12964 ++ pmd = pmd_offset(pud, vaddr);
12965 ++
12966 ++#ifdef CONFIG_X86_PAE
12967 ++ paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
12968 ++#endif
12969 ++
12970 + for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end);
12971 + pmd++, pmd_idx++) {
12972 + one_page_table_init(pmd);
12973 +@@ -143,11 +128,23 @@ page_table_range_init(unsigned long star
12974 + }
12975 + }
12976 +
12977 +-static inline int is_kernel_text(unsigned long addr)
12978 ++static inline int is_kernel_text(unsigned long start, unsigned long end)
12979 + {
12980 +- if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
12981 +- return 1;
12982 +- return 0;
12983 ++ unsigned long etext;
12984 ++
12985 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
12986 ++ etext = ktva_ktla((unsigned long)&MODULES_END);
12987 ++#else
12988 ++ etext = (unsigned long)&_etext;
12989 ++#endif
12990 ++
12991 ++ if ((start > ktla_ktva(etext) ||
12992 ++ end <= ktla_ktva((unsigned long)_stext)) &&
12993 ++ (start > ktla_ktva((unsigned long)_einittext) ||
12994 ++ end <= ktla_ktva((unsigned long)_sinittext)) &&
12995 ++ (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000)))
12996 ++ return 0;
12997 ++ return 1;
12998 + }
12999 +
13000 + /*
13001 +@@ -157,9 +154,10 @@ static inline int is_kernel_text(unsigne
13002 + */
13003 + static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
13004 + {
13005 +- int pgd_idx, pmd_idx, pte_ofs;
13006 ++ unsigned int pgd_idx, pmd_idx, pte_ofs;
13007 + unsigned long pfn;
13008 + pgd_t *pgd;
13009 ++ pud_t *pud;
13010 + pmd_t *pmd;
13011 + pte_t *pte;
13012 +
13013 +@@ -167,15 +165,18 @@ static void __init kernel_physical_mappi
13014 + pgd = pgd_base + pgd_idx;
13015 + pfn = 0;
13016 +
13017 +- for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
13018 +- pmd = one_md_table_init(pgd);
13019 +- if (pfn >= max_low_pfn)
13020 +- continue;
13021 ++ for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
13022 ++ pud = pud_offset(pgd, 0);
13023 ++ pmd = pmd_offset(pud, 0);
13024 ++
13025 ++#ifdef CONFIG_X86_PAE
13026 ++ paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
13027 ++#endif
13028 +
13029 + for (pmd_idx = 0;
13030 + pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn;
13031 + pmd++, pmd_idx++) {
13032 +- unsigned int addr = pfn * PAGE_SIZE + PAGE_OFFSET;
13033 ++ unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
13034 +
13035 + /*
13036 + * Map with big pages if possible, otherwise
13037 +@@ -187,14 +188,9 @@ static void __init kernel_physical_mappi
13038 + * slowdowns.
13039 + */
13040 + if (cpu_has_pse && !(pgd_idx == 0 && pmd_idx == 0)) {
13041 +- unsigned int addr2;
13042 + pgprot_t prot = PAGE_KERNEL_LARGE;
13043 +
13044 +- addr2 = (pfn + PTRS_PER_PTE-1) * PAGE_SIZE +
13045 +- PAGE_OFFSET + PAGE_SIZE-1;
13046 +-
13047 +- if (is_kernel_text(addr) ||
13048 +- is_kernel_text(addr2))
13049 ++ if (is_kernel_text(address, address + PMD_SIZE))
13050 + prot = PAGE_KERNEL_LARGE_EXEC;
13051 +
13052 + set_pmd(pmd, pfn_pmd(pfn, prot));
13053 +@@ -207,10 +203,10 @@ static void __init kernel_physical_mappi
13054 +
13055 + for (pte_ofs = 0;
13056 + pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn;
13057 +- pte++, pfn++, pte_ofs++, addr += PAGE_SIZE) {
13058 ++ pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
13059 + pgprot_t prot = PAGE_KERNEL;
13060 +
13061 +- if (is_kernel_text(addr))
13062 ++ if (is_kernel_text(address, address + PAGE_SIZE))
13063 + prot = PAGE_KERNEL_EXEC;
13064 +
13065 + set_pte(pte, pfn_pte(pfn, prot));
13066 +@@ -239,7 +235,9 @@ static inline int page_kills_ppro(unsign
13067 + */
13068 + int devmem_is_allowed(unsigned long pagenr)
13069 + {
13070 +- if (pagenr <= 256)
13071 ++ if (!pagenr)
13072 ++ return 1;
13073 ++ if ((ISA_START_ADDRESS >> PAGE_SHIFT) <= pagenr && pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
13074 + return 1;
13075 + if (!page_is_ram(pagenr))
13076 + return 1;
13077 +@@ -320,10 +318,10 @@ static void __init set_highmem_pages_ini
13078 + # define set_highmem_pages_init(bad_ppro) do { } while (0)
13079 + #endif /* CONFIG_HIGHMEM */
13080 +
13081 +-pteval_t __PAGE_KERNEL = _PAGE_KERNEL;
13082 ++pteval_t __PAGE_KERNEL __read_only = _PAGE_KERNEL;
13083 + EXPORT_SYMBOL(__PAGE_KERNEL);
13084 +
13085 +-pteval_t __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC;
13086 ++pteval_t __PAGE_KERNEL_EXEC __read_only = _PAGE_KERNEL_EXEC;
13087 +
13088 + void __init native_pagetable_setup_start(pgd_t *base)
13089 + {
13090 +@@ -345,7 +343,7 @@ void __init native_pagetable_setup_start
13091 +
13092 + pud = pud_offset(pgd, va);
13093 + pmd = pmd_offset(pud, va);
13094 +- if (!pmd_present(*pmd))
13095 ++ if (!pmd_present(*pmd) || pmd_huge(*pmd))
13096 + break;
13097 +
13098 + pte = pte_offset_kernel(pmd, va);
13099 +@@ -421,12 +419,12 @@ static void __init pagetable_init(void)
13100 + * ACPI suspend needs this for resume, because things like the intel-agp
13101 + * driver might have split up a kernel 4MB mapping.
13102 + */
13103 +-char swsusp_pg_dir[PAGE_SIZE]
13104 ++pgd_t swsusp_pg_dir[PTRS_PER_PGD]
13105 + __attribute__ ((aligned(PAGE_SIZE)));
13106 +
13107 + static inline void save_pg_dir(void)
13108 + {
13109 +- memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
13110 ++ clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD);
13111 + }
13112 + #else /* !CONFIG_ACPI_SLEEP */
13113 + static inline void save_pg_dir(void)
13114 +@@ -456,13 +454,11 @@ void zap_low_mappings(void)
13115 +
13116 + int nx_enabled;
13117 +
13118 +-pteval_t __supported_pte_mask __read_mostly = ~_PAGE_NX;
13119 ++pteval_t __supported_pte_mask __read_only = ~_PAGE_NX;
13120 + EXPORT_SYMBOL_GPL(__supported_pte_mask);
13121 +
13122 + #ifdef CONFIG_X86_PAE
13123 +
13124 +-static int disable_nx __initdata;
13125 +-
13126 + /*
13127 + * noexec = on|off
13128 + *
13129 +@@ -471,40 +467,33 @@ static int disable_nx __initdata;
13130 + * on Enable
13131 + * off Disable
13132 + */
13133 ++#if !defined(CONFIG_PAX_PAGEEXEC)
13134 + static int __init noexec_setup(char *str)
13135 + {
13136 + if (!str || !strcmp(str, "on")) {
13137 +- if (cpu_has_nx) {
13138 +- __supported_pte_mask |= _PAGE_NX;
13139 +- disable_nx = 0;
13140 +- }
13141 ++ if (cpu_has_nx)
13142 ++ nx_enabled = 1;
13143 + } else {
13144 +- if (!strcmp(str, "off")) {
13145 +- disable_nx = 1;
13146 +- __supported_pte_mask &= ~_PAGE_NX;
13147 +- } else {
13148 ++ if (!strcmp(str, "off"))
13149 ++ nx_enabled = 0;
13150 ++ else
13151 + return -EINVAL;
13152 +- }
13153 + }
13154 +
13155 + return 0;
13156 + }
13157 + early_param("noexec", noexec_setup);
13158 ++#endif
13159 +
13160 + static void __init set_nx(void)
13161 + {
13162 +- unsigned int v[4], l, h;
13163 +-
13164 +- if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
13165 +- cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
13166 ++ if (!nx_enabled && cpu_has_nx) {
13167 ++ unsigned l, h;
13168 +
13169 +- if ((v[3] & (1 << 20)) && !disable_nx) {
13170 +- rdmsr(MSR_EFER, l, h);
13171 +- l |= EFER_NX;
13172 +- wrmsr(MSR_EFER, l, h);
13173 +- nx_enabled = 1;
13174 +- __supported_pte_mask |= _PAGE_NX;
13175 +- }
13176 ++ __supported_pte_mask &= ~_PAGE_NX;
13177 ++ rdmsr(MSR_EFER, l, h);
13178 ++ l &= ~EFER_NX;
13179 ++ wrmsr(MSR_EFER, l, h);
13180 + }
13181 + }
13182 + #endif
13183 +@@ -596,7 +585,7 @@ void __init mem_init(void)
13184 + set_highmem_pages_init(bad_ppro);
13185 +
13186 + codesize = (unsigned long) &_etext - (unsigned long) &_text;
13187 +- datasize = (unsigned long) &_edata - (unsigned long) &_etext;
13188 ++ datasize = (unsigned long) &_edata - (unsigned long) &_data;
13189 + initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
13190 +
13191 + kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
13192 +@@ -643,10 +632,10 @@ void __init mem_init(void)
13193 + ((unsigned long)&__init_end -
13194 + (unsigned long)&__init_begin) >> 10,
13195 +
13196 +- (unsigned long)&_etext, (unsigned long)&_edata,
13197 +- ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
13198 ++ (unsigned long)&_data, (unsigned long)&_edata,
13199 ++ ((unsigned long)&_edata - (unsigned long)&_data) >> 10,
13200 +
13201 +- (unsigned long)&_text, (unsigned long)&_etext,
13202 ++ ktla_ktva((unsigned long)&_text), ktla_ktva((unsigned long)&_etext),
13203 + ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
13204 +
13205 + #ifdef CONFIG_HIGHMEM
13206 +@@ -773,6 +762,46 @@ void free_init_pages(char *what, unsigne
13207 +
13208 + void free_initmem(void)
13209 + {
13210 ++
13211 ++#ifdef CONFIG_PAX_KERNEXEC
13212 ++ /* PaX: limit KERNEL_CS to actual size */
13213 ++ unsigned long addr, limit;
13214 ++ struct desc_struct d;
13215 ++ int cpu;
13216 ++ pgd_t *pgd;
13217 ++ pud_t *pud;
13218 ++ pmd_t *pmd;
13219 ++
13220 ++#ifdef CONFIG_MODULES
13221 ++ limit = ktva_ktla((unsigned long)&MODULES_END);
13222 ++#else
13223 ++ limit = (unsigned long)&_etext;
13224 ++#endif
13225 ++ limit = (limit - 1UL) >> PAGE_SHIFT;
13226 ++
13227 ++ for (cpu = 0; cpu < NR_CPUS; cpu++) {
13228 ++ pack_descriptor(&d, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC);
13229 ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, &d, DESCTYPE_S);
13230 ++ }
13231 ++
13232 ++ /* PaX: make KERNEL_CS read-only */
13233 ++ for (addr = ktla_ktva((unsigned long)&_text); addr < (unsigned long)&_data; addr += PMD_SIZE) {
13234 ++ pgd = pgd_offset_k(addr);
13235 ++ pud = pud_offset(pgd, addr);
13236 ++ pmd = pmd_offset(pud, addr);
13237 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
13238 ++ }
13239 ++#ifdef CONFIG_X86_PAE
13240 ++ for (addr = (unsigned long)&__init_begin; addr < (unsigned long)&__init_end; addr += PMD_SIZE) {
13241 ++ pgd = pgd_offset_k(addr);
13242 ++ pud = pud_offset(pgd, addr);
13243 ++ pmd = pmd_offset(pud, addr);
13244 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
13245 ++ }
13246 ++#endif
13247 ++ flush_tlb_all();
13248 ++#endif
13249 ++
13250 + free_init_pages("unused kernel memory",
13251 + (unsigned long)(&__init_begin),
13252 + (unsigned long)(&__init_end));
13253 +diff -urNp linux-2.6.26.6/arch/x86/mm/init_64.c linux-2.6.26.6/arch/x86/mm/init_64.c
13254 +--- linux-2.6.26.6/arch/x86/mm/init_64.c 2008-10-08 23:24:05.000000000 -0400
13255 ++++ linux-2.6.26.6/arch/x86/mm/init_64.c 2008-10-11 21:54:19.000000000 -0400
13256 +@@ -143,6 +143,10 @@ set_pte_phys(unsigned long vaddr, unsign
13257 + pmd_t *pmd;
13258 + pte_t *pte, new_pte;
13259 +
13260 ++#ifdef CONFIG_PAX_KERNEXEC
13261 ++ unsigned long cr0;
13262 ++#endif
13263 ++
13264 + pr_debug("set_pte_phys %lx to %lx\n", vaddr, phys);
13265 +
13266 + pgd = pgd_offset_k(vaddr);
13267 +@@ -154,7 +158,7 @@ set_pte_phys(unsigned long vaddr, unsign
13268 + pud = pud_offset(pgd, vaddr);
13269 + if (pud_none(*pud)) {
13270 + pmd = (pmd_t *) spp_getpage();
13271 +- set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
13272 ++ set_pud(pud, __pud(__pa(pmd) | _PAGE_TABLE));
13273 + if (pmd != pmd_offset(pud, 0)) {
13274 + printk(KERN_ERR "PAGETABLE BUG #01! %p <-> %p\n",
13275 + pmd, pmd_offset(pud, 0));
13276 +@@ -164,7 +168,7 @@ set_pte_phys(unsigned long vaddr, unsign
13277 + pmd = pmd_offset(pud, vaddr);
13278 + if (pmd_none(*pmd)) {
13279 + pte = (pte_t *) spp_getpage();
13280 +- set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
13281 ++ set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
13282 + if (pte != pte_offset_kernel(pmd, 0)) {
13283 + printk(KERN_ERR "PAGETABLE BUG #02!\n");
13284 + return;
13285 +@@ -176,8 +180,17 @@ set_pte_phys(unsigned long vaddr, unsign
13286 + if (!pte_none(*pte) && pte_val(new_pte) &&
13287 + pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask))
13288 + pte_ERROR(*pte);
13289 ++
13290 ++#ifdef CONFIG_PAX_KERNEXEC
13291 ++ pax_open_kernel(cr0);
13292 ++#endif
13293 ++
13294 + set_pte(pte, new_pte);
13295 +
13296 ++#ifdef CONFIG_PAX_KERNEXEC
13297 ++ pax_close_kernel(cr0);
13298 ++#endif
13299 ++
13300 + /*
13301 + * It's enough to flush this one mapping.
13302 + * (PGE mappings get flushed as well)
13303 +@@ -667,7 +680,9 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to
13304 + */
13305 + int devmem_is_allowed(unsigned long pagenr)
13306 + {
13307 +- if (pagenr <= 256)
13308 ++ if (!pagenr)
13309 ++ return 1;
13310 ++ if ((ISA_START_ADDRESS >> PAGE_SHIFT) <= pagenr && pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
13311 + return 1;
13312 + if (!page_is_ram(pagenr))
13313 + return 1;
13314 +@@ -755,6 +770,39 @@ void free_init_pages(char *what, unsigne
13315 +
13316 + void free_initmem(void)
13317 + {
13318 ++
13319 ++#ifdef CONFIG_PAX_KERNEXEC
13320 ++ unsigned long addr, end;
13321 ++ pgd_t *pgd;
13322 ++ pud_t *pud;
13323 ++ pmd_t *pmd;
13324 ++
13325 ++ /* PaX: make kernel code/rodata read-only, rest non-executable */
13326 ++ for (addr = __START_KERNEL_map; addr < __START_KERNEL_map + KERNEL_IMAGE_SIZE; addr += PMD_SIZE) {
13327 ++ pgd = pgd_offset_k(addr);
13328 ++ pud = pud_offset(pgd, addr);
13329 ++ pmd = pmd_offset(pud, addr);
13330 ++ if ((unsigned long)_text <= addr && addr < (unsigned long)_data)
13331 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
13332 ++ else
13333 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
13334 ++ }
13335 ++
13336 ++ addr = (unsigned long)__va(__pa(__START_KERNEL_map));
13337 ++ end = addr + KERNEL_IMAGE_SIZE;
13338 ++ for (; addr < end; addr += PMD_SIZE) {
13339 ++ pgd = pgd_offset_k(addr);
13340 ++ pud = pud_offset(pgd, addr);
13341 ++ pmd = pmd_offset(pud, addr);
13342 ++ if ((unsigned long)__va(__pa(_text)) <= addr && addr < (unsigned long)__va(__pa(_data)))
13343 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
13344 ++ else
13345 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
13346 ++ }
13347 ++
13348 ++ flush_tlb_all();
13349 ++#endif
13350 ++
13351 + free_init_pages("unused kernel memory",
13352 + (unsigned long)(&__init_begin),
13353 + (unsigned long)(&__init_end));
13354 +@@ -913,7 +961,7 @@ int in_gate_area_no_task(unsigned long a
13355 +
13356 + const char *arch_vma_name(struct vm_area_struct *vma)
13357 + {
13358 +- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
13359 ++ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
13360 + return "[vdso]";
13361 + if (vma == &gate_vma)
13362 + return "[vsyscall]";
13363 +diff -urNp linux-2.6.26.6/arch/x86/mm/ioremap.c linux-2.6.26.6/arch/x86/mm/ioremap.c
13364 +--- linux-2.6.26.6/arch/x86/mm/ioremap.c 2008-10-08 23:24:05.000000000 -0400
13365 ++++ linux-2.6.26.6/arch/x86/mm/ioremap.c 2008-10-11 21:54:19.000000000 -0400
13366 +@@ -62,8 +62,8 @@ int page_is_ram(unsigned long pagenr)
13367 + * Second special case: Some BIOSen report the PC BIOS
13368 + * area (640->1Mb) as ram even though it is not.
13369 + */
13370 +- if (pagenr >= (BIOS_BEGIN >> PAGE_SHIFT) &&
13371 +- pagenr < (BIOS_END >> PAGE_SHIFT))
13372 ++ if (pagenr >= (ISA_START_ADDRESS >> PAGE_SHIFT) &&
13373 ++ pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
13374 + return 0;
13375 +
13376 + for (i = 0; i < e820.nr_map; i++) {
13377 +@@ -213,6 +213,8 @@ static void __iomem *__ioremap_caller(re
13378 + break;
13379 + }
13380 +
13381 ++ prot = canon_pgprot(prot);
13382 ++
13383 + /*
13384 + * Ok, go for it..
13385 + */
13386 +diff -urNp linux-2.6.26.6/arch/x86/mm/mmap.c linux-2.6.26.6/arch/x86/mm/mmap.c
13387 +--- linux-2.6.26.6/arch/x86/mm/mmap.c 2008-10-08 23:24:05.000000000 -0400
13388 ++++ linux-2.6.26.6/arch/x86/mm/mmap.c 2008-10-11 21:54:19.000000000 -0400
13389 +@@ -36,7 +36,7 @@
13390 + * Leave an at least ~128 MB hole.
13391 + */
13392 + #define MIN_GAP (128*1024*1024)
13393 +-#define MAX_GAP (TASK_SIZE/6*5)
13394 ++#define MAX_GAP (pax_task_size/6*5)
13395 +
13396 + /*
13397 + * True on X86_32 or when emulating IA32 on X86_64
13398 +@@ -81,27 +81,40 @@ static unsigned long mmap_rnd(void)
13399 + return rnd << PAGE_SHIFT;
13400 + }
13401 +
13402 +-static unsigned long mmap_base(void)
13403 ++static unsigned long mmap_base(struct mm_struct *mm)
13404 + {
13405 + unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
13406 ++ unsigned long pax_task_size = TASK_SIZE;
13407 ++
13408 ++#ifdef CONFIG_PAX_SEGMEXEC
13409 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
13410 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
13411 ++#endif
13412 +
13413 + if (gap < MIN_GAP)
13414 + gap = MIN_GAP;
13415 + else if (gap > MAX_GAP)
13416 + gap = MAX_GAP;
13417 +
13418 +- return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
13419 ++ return PAGE_ALIGN(pax_task_size - gap - mmap_rnd());
13420 + }
13421 +
13422 + /*
13423 + * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64
13424 + * does, but not when emulating X86_32
13425 + */
13426 +-static unsigned long mmap_legacy_base(void)
13427 ++static unsigned long mmap_legacy_base(struct mm_struct *mm)
13428 + {
13429 +- if (mmap_is_ia32())
13430 ++ if (mmap_is_ia32()) {
13431 ++
13432 ++#ifdef CONFIG_PAX_SEGMEXEC
13433 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
13434 ++ return SEGMEXEC_TASK_UNMAPPED_BASE;
13435 ++ else
13436 ++#endif
13437 ++
13438 + return TASK_UNMAPPED_BASE;
13439 +- else
13440 ++ } else
13441 + return TASK_UNMAPPED_BASE + mmap_rnd();
13442 + }
13443 +
13444 +@@ -112,11 +125,23 @@ static unsigned long mmap_legacy_base(vo
13445 + void arch_pick_mmap_layout(struct mm_struct *mm)
13446 + {
13447 + if (mmap_is_legacy()) {
13448 +- mm->mmap_base = mmap_legacy_base();
13449 ++ mm->mmap_base = mmap_legacy_base(mm);
13450 ++
13451 ++#ifdef CONFIG_PAX_RANDMMAP
13452 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
13453 ++ mm->mmap_base += mm->delta_mmap;
13454 ++#endif
13455 ++
13456 + mm->get_unmapped_area = arch_get_unmapped_area;
13457 + mm->unmap_area = arch_unmap_area;
13458 + } else {
13459 +- mm->mmap_base = mmap_base();
13460 ++ mm->mmap_base = mmap_base(mm);
13461 ++
13462 ++#ifdef CONFIG_PAX_RANDMMAP
13463 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
13464 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
13465 ++#endif
13466 ++
13467 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
13468 + mm->unmap_area = arch_unmap_area_topdown;
13469 + }
13470 +diff -urNp linux-2.6.26.6/arch/x86/mm/numa_64.c linux-2.6.26.6/arch/x86/mm/numa_64.c
13471 +--- linux-2.6.26.6/arch/x86/mm/numa_64.c 2008-10-08 23:24:05.000000000 -0400
13472 ++++ linux-2.6.26.6/arch/x86/mm/numa_64.c 2008-10-11 21:54:19.000000000 -0400
13473 +@@ -21,7 +21,7 @@
13474 + #include <asm/k8.h>
13475 +
13476 + #ifndef Dprintk
13477 +-#define Dprintk(x...)
13478 ++#define Dprintk(x...) do {} while (0)
13479 + #endif
13480 +
13481 + struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
13482 +diff -urNp linux-2.6.26.6/arch/x86/mm/pageattr.c linux-2.6.26.6/arch/x86/mm/pageattr.c
13483 +--- linux-2.6.26.6/arch/x86/mm/pageattr.c 2008-10-08 23:24:05.000000000 -0400
13484 ++++ linux-2.6.26.6/arch/x86/mm/pageattr.c 2008-10-11 21:54:19.000000000 -0400
13485 +@@ -20,6 +20,7 @@
13486 + #include <asm/pgalloc.h>
13487 + #include <asm/proto.h>
13488 + #include <asm/pat.h>
13489 ++#include <asm/desc.h>
13490 +
13491 + /*
13492 + * The current flushing context - we pass it instead of 5 arguments:
13493 +@@ -172,7 +173,7 @@ static inline pgprot_t static_protection
13494 + * Does not cover __inittext since that is gone later on. On
13495 + * 64bit we do not enforce !NX on the low mapping
13496 + */
13497 +- if (within(address, (unsigned long)_text, (unsigned long)_etext))
13498 ++ if (within(address, ktla_ktva((unsigned long)_text), ktla_ktva((unsigned long)_etext)))
13499 + pgprot_val(forbidden) |= _PAGE_NX;
13500 +
13501 + /*
13502 +@@ -233,8 +234,20 @@ pte_t *lookup_address(unsigned long addr
13503 + */
13504 + static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
13505 + {
13506 ++
13507 ++#ifdef CONFIG_PAX_KERNEXEC
13508 ++ unsigned long cr0;
13509 ++
13510 ++ pax_open_kernel(cr0);
13511 ++#endif
13512 ++
13513 + /* change init_mm */
13514 + set_pte_atomic(kpte, pte);
13515 ++
13516 ++#ifdef CONFIG_PAX_KERNEXEC
13517 ++ pax_close_kernel(cr0);
13518 ++#endif
13519 ++
13520 + #ifdef CONFIG_X86_32
13521 + if (!SHARED_KERNEL_PMD) {
13522 + struct page *page;
13523 +diff -urNp linux-2.6.26.6/arch/x86/mm/pat.c linux-2.6.26.6/arch/x86/mm/pat.c
13524 +--- linux-2.6.26.6/arch/x86/mm/pat.c 2008-10-08 23:24:05.000000000 -0400
13525 ++++ linux-2.6.26.6/arch/x86/mm/pat.c 2008-10-11 21:54:19.000000000 -0400
13526 +@@ -471,7 +471,7 @@ pgprot_t phys_mem_access_prot(struct fil
13527 + return vma_prot;
13528 + }
13529 +
13530 +-#ifdef CONFIG_NONPROMISC_DEVMEM
13531 ++#ifndef CONFIG_NONPROMISC_DEVMEM
13532 + /* This check is done in drivers/char/mem.c in case of NONPROMISC_DEVMEM*/
13533 + static inline int range_is_allowed(unsigned long pfn, unsigned long size)
13534 + {
13535 +diff -urNp linux-2.6.26.6/arch/x86/mm/pgtable_32.c linux-2.6.26.6/arch/x86/mm/pgtable_32.c
13536 +--- linux-2.6.26.6/arch/x86/mm/pgtable_32.c 2008-10-08 23:24:05.000000000 -0400
13537 ++++ linux-2.6.26.6/arch/x86/mm/pgtable_32.c 2008-10-11 21:54:19.000000000 -0400
13538 +@@ -78,6 +78,10 @@ static void set_pte_pfn(unsigned long va
13539 + pmd_t *pmd;
13540 + pte_t *pte;
13541 +
13542 ++#ifdef CONFIG_PAX_KERNEXEC
13543 ++ unsigned long cr0;
13544 ++#endif
13545 ++
13546 + pgd = swapper_pg_dir + pgd_index(vaddr);
13547 + if (pgd_none(*pgd)) {
13548 + BUG();
13549 +@@ -94,11 +98,20 @@ static void set_pte_pfn(unsigned long va
13550 + return;
13551 + }
13552 + pte = pte_offset_kernel(pmd, vaddr);
13553 ++
13554 ++#ifdef CONFIG_PAX_KERNEXEC
13555 ++ pax_open_kernel(cr0);
13556 ++#endif
13557 ++
13558 + if (pgprot_val(flags))
13559 + set_pte_present(&init_mm, vaddr, pte, pfn_pte(pfn, flags));
13560 + else
13561 + pte_clear(&init_mm, vaddr, pte);
13562 +
13563 ++#ifdef CONFIG_PAX_KERNEXEC
13564 ++ pax_close_kernel(cr0);
13565 ++#endif
13566 ++
13567 + /*
13568 + * It's enough to flush this one mapping.
13569 + * (PGE mappings get flushed as well)
13570 +diff -urNp linux-2.6.26.6/arch/x86/oprofile/backtrace.c linux-2.6.26.6/arch/x86/oprofile/backtrace.c
13571 +--- linux-2.6.26.6/arch/x86/oprofile/backtrace.c 2008-10-08 23:24:05.000000000 -0400
13572 ++++ linux-2.6.26.6/arch/x86/oprofile/backtrace.c 2008-10-11 21:54:19.000000000 -0400
13573 +@@ -37,7 +37,7 @@ static void backtrace_address(void *data
13574 + unsigned int *depth = data;
13575 +
13576 + if ((*depth)--)
13577 +- oprofile_add_trace(addr);
13578 ++ oprofile_add_trace(ktla_ktva(addr));
13579 + }
13580 +
13581 + static struct stacktrace_ops backtrace_ops = {
13582 +@@ -79,7 +79,7 @@ x86_backtrace(struct pt_regs * const reg
13583 + struct frame_head *head = (struct frame_head *)frame_pointer(regs);
13584 + unsigned long stack = kernel_trap_sp(regs);
13585 +
13586 +- if (!user_mode_vm(regs)) {
13587 ++ if (!user_mode(regs)) {
13588 + if (depth)
13589 + dump_trace(NULL, regs, (unsigned long *)stack, 0,
13590 + &backtrace_ops, &depth);
13591 +diff -urNp linux-2.6.26.6/arch/x86/oprofile/op_model_p4.c linux-2.6.26.6/arch/x86/oprofile/op_model_p4.c
13592 +--- linux-2.6.26.6/arch/x86/oprofile/op_model_p4.c 2008-10-08 23:24:05.000000000 -0400
13593 ++++ linux-2.6.26.6/arch/x86/oprofile/op_model_p4.c 2008-10-11 21:54:19.000000000 -0400
13594 +@@ -47,7 +47,7 @@ static inline void setup_num_counters(vo
13595 + #endif
13596 + }
13597 +
13598 +-static int inline addr_increment(void)
13599 ++static inline int addr_increment(void)
13600 + {
13601 + #ifdef CONFIG_SMP
13602 + return smp_num_siblings == 2 ? 2 : 1;
13603 +diff -urNp linux-2.6.26.6/arch/x86/pci/common.c linux-2.6.26.6/arch/x86/pci/common.c
13604 +--- linux-2.6.26.6/arch/x86/pci/common.c 2008-10-08 23:24:05.000000000 -0400
13605 ++++ linux-2.6.26.6/arch/x86/pci/common.c 2008-10-11 21:54:19.000000000 -0400
13606 +@@ -342,7 +342,7 @@ static struct dmi_system_id __devinitdat
13607 + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"),
13608 + },
13609 + },
13610 +- {}
13611 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
13612 + };
13613 +
13614 + void __init dmi_check_pciprobe(void)
13615 +diff -urNp linux-2.6.26.6/arch/x86/pci/early.c linux-2.6.26.6/arch/x86/pci/early.c
13616 +--- linux-2.6.26.6/arch/x86/pci/early.c 2008-10-08 23:24:05.000000000 -0400
13617 ++++ linux-2.6.26.6/arch/x86/pci/early.c 2008-10-11 21:54:19.000000000 -0400
13618 +@@ -7,7 +7,7 @@
13619 + /* Direct PCI access. This is used for PCI accesses in early boot before
13620 + the PCI subsystem works. */
13621 +
13622 +-#define PDprintk(x...)
13623 ++#define PDprintk(x...) do {} while (0)
13624 +
13625 + u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
13626 + {
13627 +diff -urNp linux-2.6.26.6/arch/x86/pci/fixup.c linux-2.6.26.6/arch/x86/pci/fixup.c
13628 +--- linux-2.6.26.6/arch/x86/pci/fixup.c 2008-10-08 23:24:05.000000000 -0400
13629 ++++ linux-2.6.26.6/arch/x86/pci/fixup.c 2008-10-11 21:54:19.000000000 -0400
13630 +@@ -364,7 +364,7 @@ static struct dmi_system_id __devinitdat
13631 + DMI_MATCH(DMI_PRODUCT_NAME, "MS-6702E"),
13632 + },
13633 + },
13634 +- {}
13635 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
13636 + };
13637 +
13638 + /*
13639 +@@ -435,7 +435,7 @@ static struct dmi_system_id __devinitdat
13640 + DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
13641 + },
13642 + },
13643 +- { }
13644 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
13645 + };
13646 +
13647 + static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
13648 +diff -urNp linux-2.6.26.6/arch/x86/pci/irq.c linux-2.6.26.6/arch/x86/pci/irq.c
13649 +--- linux-2.6.26.6/arch/x86/pci/irq.c 2008-10-08 23:24:05.000000000 -0400
13650 ++++ linux-2.6.26.6/arch/x86/pci/irq.c 2008-10-11 21:54:19.000000000 -0400
13651 +@@ -542,7 +542,7 @@ static __init int intel_router_probe(str
13652 + static struct pci_device_id __initdata pirq_440gx[] = {
13653 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
13654 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
13655 +- { },
13656 ++ { PCI_DEVICE(0, 0) }
13657 + };
13658 +
13659 + /* 440GX has a proprietary PIRQ router -- don't use it */
13660 +@@ -1115,7 +1115,7 @@ static struct dmi_system_id __initdata p
13661 + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
13662 + },
13663 + },
13664 +- { }
13665 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
13666 + };
13667 +
13668 + static int __init pcibios_irq_init(void)
13669 +diff -urNp linux-2.6.26.6/arch/x86/pci/pcbios.c linux-2.6.26.6/arch/x86/pci/pcbios.c
13670 +--- linux-2.6.26.6/arch/x86/pci/pcbios.c 2008-10-08 23:24:05.000000000 -0400
13671 ++++ linux-2.6.26.6/arch/x86/pci/pcbios.c 2008-10-11 21:54:19.000000000 -0400
13672 +@@ -57,50 +57,120 @@ union bios32 {
13673 + static struct {
13674 + unsigned long address;
13675 + unsigned short segment;
13676 +-} bios32_indirect = { 0, __KERNEL_CS };
13677 ++} bios32_indirect __read_only = { 0, __PCIBIOS_CS };
13678 +
13679 + /*
13680 + * Returns the entry point for the given service, NULL on error
13681 + */
13682 +
13683 +-static unsigned long bios32_service(unsigned long service)
13684 ++static unsigned long __devinit bios32_service(unsigned long service)
13685 + {
13686 + unsigned char return_code; /* %al */
13687 + unsigned long address; /* %ebx */
13688 + unsigned long length; /* %ecx */
13689 + unsigned long entry; /* %edx */
13690 + unsigned long flags;
13691 ++ struct desc_struct d, *gdt;
13692 ++
13693 ++#ifdef CONFIG_PAX_KERNEXEC
13694 ++ unsigned long cr0;
13695 ++#endif
13696 +
13697 + local_irq_save(flags);
13698 +- __asm__("lcall *(%%edi); cld"
13699 ++
13700 ++ gdt = get_cpu_gdt_table(smp_processor_id());
13701 ++
13702 ++#ifdef CONFIG_PAX_KERNEXEC
13703 ++ pax_open_kernel(cr0);
13704 ++#endif
13705 ++
13706 ++ pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x9B, 0xC);
13707 ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
13708 ++ pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x93, 0xC);
13709 ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
13710 ++
13711 ++#ifdef CONFIG_PAX_KERNEXEC
13712 ++ pax_close_kernel(cr0);
13713 ++#endif
13714 ++
13715 ++ __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld"
13716 + : "=a" (return_code),
13717 + "=b" (address),
13718 + "=c" (length),
13719 + "=d" (entry)
13720 + : "0" (service),
13721 + "1" (0),
13722 +- "D" (&bios32_indirect));
13723 ++ "D" (&bios32_indirect),
13724 ++ "r"(__PCIBIOS_DS)
13725 ++ : "memory");
13726 ++
13727 ++#ifdef CONFIG_PAX_KERNEXEC
13728 ++ pax_open_kernel(cr0);
13729 ++#endif
13730 ++
13731 ++ gdt[GDT_ENTRY_PCIBIOS_CS].a = 0;
13732 ++ gdt[GDT_ENTRY_PCIBIOS_CS].b = 0;
13733 ++ gdt[GDT_ENTRY_PCIBIOS_DS].a = 0;
13734 ++ gdt[GDT_ENTRY_PCIBIOS_DS].b = 0;
13735 ++
13736 ++#ifdef CONFIG_PAX_KERNEXEC
13737 ++ pax_close_kernel(cr0);
13738 ++#endif
13739 ++
13740 + local_irq_restore(flags);
13741 +
13742 + switch (return_code) {
13743 +- case 0:
13744 +- return address + entry;
13745 +- case 0x80: /* Not present */
13746 +- printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
13747 +- return 0;
13748 +- default: /* Shouldn't happen */
13749 +- printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
13750 +- service, return_code);
13751 ++ case 0: {
13752 ++ int cpu;
13753 ++ unsigned char flags;
13754 ++
13755 ++ printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry);
13756 ++ if (address >= 0xFFFF0 || length > 0x100000 - address || length <= entry) {
13757 ++ printk(KERN_WARNING "bios32_service: not valid\n");
13758 + return 0;
13759 ++ }
13760 ++ address = address + PAGE_OFFSET;
13761 ++ length += 16UL; /* some BIOSs underreport this... */
13762 ++ flags = 4;
13763 ++ if (length >= 64*1024*1024) {
13764 ++ length >>= PAGE_SHIFT;
13765 ++ flags |= 8;
13766 ++ }
13767 ++
13768 ++#ifdef CONFIG_PAX_KERNEXEC
13769 ++ pax_open_kernel(cr0);
13770 ++#endif
13771 ++
13772 ++ for (cpu = 0; cpu < NR_CPUS; cpu++) {
13773 ++ gdt = get_cpu_gdt_table(cpu);
13774 ++ pack_descriptor(&d, address, length, 0x9b, flags);
13775 ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
13776 ++ pack_descriptor(&d, address, length, 0x93, flags);
13777 ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
13778 ++ }
13779 ++
13780 ++#ifdef CONFIG_PAX_KERNEXEC
13781 ++ pax_close_kernel(cr0);
13782 ++#endif
13783 ++
13784 ++ return entry;
13785 ++ }
13786 ++ case 0x80: /* Not present */
13787 ++ printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
13788 ++ return 0;
13789 ++ default: /* Shouldn't happen */
13790 ++ printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
13791 ++ service, return_code);
13792 ++ return 0;
13793 + }
13794 + }
13795 +
13796 + static struct {
13797 + unsigned long address;
13798 + unsigned short segment;
13799 +-} pci_indirect = { 0, __KERNEL_CS };
13800 ++} pci_indirect __read_only = { 0, __PCIBIOS_CS };
13801 +
13802 +-static int pci_bios_present;
13803 ++static int pci_bios_present __read_only;
13804 +
13805 + static int __devinit check_pcibios(void)
13806 + {
13807 +@@ -109,11 +179,13 @@ static int __devinit check_pcibios(void)
13808 + unsigned long flags, pcibios_entry;
13809 +
13810 + if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
13811 +- pci_indirect.address = pcibios_entry + PAGE_OFFSET;
13812 ++ pci_indirect.address = pcibios_entry;
13813 +
13814 + local_irq_save(flags);
13815 +- __asm__(
13816 +- "lcall *(%%edi); cld\n\t"
13817 ++ __asm__("movw %w6, %%ds\n\t"
13818 ++ "lcall *%%ss:(%%edi); cld\n\t"
13819 ++ "push %%ss\n\t"
13820 ++ "pop %%ds\n\t"
13821 + "jc 1f\n\t"
13822 + "xor %%ah, %%ah\n"
13823 + "1:"
13824 +@@ -122,7 +194,8 @@ static int __devinit check_pcibios(void)
13825 + "=b" (ebx),
13826 + "=c" (ecx)
13827 + : "1" (PCIBIOS_PCI_BIOS_PRESENT),
13828 +- "D" (&pci_indirect)
13829 ++ "D" (&pci_indirect),
13830 ++ "r" (__PCIBIOS_DS)
13831 + : "memory");
13832 + local_irq_restore(flags);
13833 +
13834 +@@ -166,7 +239,10 @@ static int pci_bios_read(unsigned int se
13835 +
13836 + switch (len) {
13837 + case 1:
13838 +- __asm__("lcall *(%%esi); cld\n\t"
13839 ++ __asm__("movw %w6, %%ds\n\t"
13840 ++ "lcall *%%ss:(%%esi); cld\n\t"
13841 ++ "push %%ss\n\t"
13842 ++ "pop %%ds\n\t"
13843 + "jc 1f\n\t"
13844 + "xor %%ah, %%ah\n"
13845 + "1:"
13846 +@@ -175,7 +251,8 @@ static int pci_bios_read(unsigned int se
13847 + : "1" (PCIBIOS_READ_CONFIG_BYTE),
13848 + "b" (bx),
13849 + "D" ((long)reg),
13850 +- "S" (&pci_indirect));
13851 ++ "S" (&pci_indirect),
13852 ++ "r" (__PCIBIOS_DS));
13853 + /*
13854 + * Zero-extend the result beyond 8 bits, do not trust the
13855 + * BIOS having done it:
13856 +@@ -183,7 +260,10 @@ static int pci_bios_read(unsigned int se
13857 + *value &= 0xff;
13858 + break;
13859 + case 2:
13860 +- __asm__("lcall *(%%esi); cld\n\t"
13861 ++ __asm__("movw %w6, %%ds\n\t"
13862 ++ "lcall *%%ss:(%%esi); cld\n\t"
13863 ++ "push %%ss\n\t"
13864 ++ "pop %%ds\n\t"
13865 + "jc 1f\n\t"
13866 + "xor %%ah, %%ah\n"
13867 + "1:"
13868 +@@ -192,7 +272,8 @@ static int pci_bios_read(unsigned int se
13869 + : "1" (PCIBIOS_READ_CONFIG_WORD),
13870 + "b" (bx),
13871 + "D" ((long)reg),
13872 +- "S" (&pci_indirect));
13873 ++ "S" (&pci_indirect),
13874 ++ "r" (__PCIBIOS_DS));
13875 + /*
13876 + * Zero-extend the result beyond 16 bits, do not trust the
13877 + * BIOS having done it:
13878 +@@ -200,7 +281,10 @@ static int pci_bios_read(unsigned int se
13879 + *value &= 0xffff;
13880 + break;
13881 + case 4:
13882 +- __asm__("lcall *(%%esi); cld\n\t"
13883 ++ __asm__("movw %w6, %%ds\n\t"
13884 ++ "lcall *%%ss:(%%esi); cld\n\t"
13885 ++ "push %%ss\n\t"
13886 ++ "pop %%ds\n\t"
13887 + "jc 1f\n\t"
13888 + "xor %%ah, %%ah\n"
13889 + "1:"
13890 +@@ -209,7 +293,8 @@ static int pci_bios_read(unsigned int se
13891 + : "1" (PCIBIOS_READ_CONFIG_DWORD),
13892 + "b" (bx),
13893 + "D" ((long)reg),
13894 +- "S" (&pci_indirect));
13895 ++ "S" (&pci_indirect),
13896 ++ "r" (__PCIBIOS_DS));
13897 + break;
13898 + }
13899 +
13900 +@@ -232,7 +317,10 @@ static int pci_bios_write(unsigned int s
13901 +
13902 + switch (len) {
13903 + case 1:
13904 +- __asm__("lcall *(%%esi); cld\n\t"
13905 ++ __asm__("movw %w6, %%ds\n\t"
13906 ++ "lcall *%%ss:(%%esi); cld\n\t"
13907 ++ "push %%ss\n\t"
13908 ++ "pop %%ds\n\t"
13909 + "jc 1f\n\t"
13910 + "xor %%ah, %%ah\n"
13911 + "1:"
13912 +@@ -241,10 +329,14 @@ static int pci_bios_write(unsigned int s
13913 + "c" (value),
13914 + "b" (bx),
13915 + "D" ((long)reg),
13916 +- "S" (&pci_indirect));
13917 ++ "S" (&pci_indirect),
13918 ++ "r" (__PCIBIOS_DS));
13919 + break;
13920 + case 2:
13921 +- __asm__("lcall *(%%esi); cld\n\t"
13922 ++ __asm__("movw %w6, %%ds\n\t"
13923 ++ "lcall *%%ss:(%%esi); cld\n\t"
13924 ++ "push %%ss\n\t"
13925 ++ "pop %%ds\n\t"
13926 + "jc 1f\n\t"
13927 + "xor %%ah, %%ah\n"
13928 + "1:"
13929 +@@ -253,10 +345,14 @@ static int pci_bios_write(unsigned int s
13930 + "c" (value),
13931 + "b" (bx),
13932 + "D" ((long)reg),
13933 +- "S" (&pci_indirect));
13934 ++ "S" (&pci_indirect),
13935 ++ "r" (__PCIBIOS_DS));
13936 + break;
13937 + case 4:
13938 +- __asm__("lcall *(%%esi); cld\n\t"
13939 ++ __asm__("movw %w6, %%ds\n\t"
13940 ++ "lcall *%%ss:(%%esi); cld\n\t"
13941 ++ "push %%ss\n\t"
13942 ++ "pop %%ds\n\t"
13943 + "jc 1f\n\t"
13944 + "xor %%ah, %%ah\n"
13945 + "1:"
13946 +@@ -265,7 +361,8 @@ static int pci_bios_write(unsigned int s
13947 + "c" (value),
13948 + "b" (bx),
13949 + "D" ((long)reg),
13950 +- "S" (&pci_indirect));
13951 ++ "S" (&pci_indirect),
13952 ++ "r" (__PCIBIOS_DS));
13953 + break;
13954 + }
13955 +
13956 +@@ -369,10 +466,13 @@ struct irq_routing_table * pcibios_get_i
13957 +
13958 + DBG("PCI: Fetching IRQ routing table... ");
13959 + __asm__("push %%es\n\t"
13960 ++ "movw %w8, %%ds\n\t"
13961 + "push %%ds\n\t"
13962 + "pop %%es\n\t"
13963 +- "lcall *(%%esi); cld\n\t"
13964 ++ "lcall *%%ss:(%%esi); cld\n\t"
13965 + "pop %%es\n\t"
13966 ++ "push %%ss\n\t"
13967 ++ "pop %%ds\n"
13968 + "jc 1f\n\t"
13969 + "xor %%ah, %%ah\n"
13970 + "1:"
13971 +@@ -383,7 +483,8 @@ struct irq_routing_table * pcibios_get_i
13972 + "1" (0),
13973 + "D" ((long) &opt),
13974 + "S" (&pci_indirect),
13975 +- "m" (opt)
13976 ++ "m" (opt),
13977 ++ "r" (__PCIBIOS_DS)
13978 + : "memory");
13979 + DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map);
13980 + if (ret & 0xff00)
13981 +@@ -407,7 +508,10 @@ int pcibios_set_irq_routing(struct pci_d
13982 + {
13983 + int ret;
13984 +
13985 +- __asm__("lcall *(%%esi); cld\n\t"
13986 ++ __asm__("movw %w5, %%ds\n\t"
13987 ++ "lcall *%%ss:(%%esi); cld\n\t"
13988 ++ "push %%ss\n\t"
13989 ++ "pop %%ds\n"
13990 + "jc 1f\n\t"
13991 + "xor %%ah, %%ah\n"
13992 + "1:"
13993 +@@ -415,7 +519,8 @@ int pcibios_set_irq_routing(struct pci_d
13994 + : "0" (PCIBIOS_SET_PCI_HW_INT),
13995 + "b" ((dev->bus->number << 8) | dev->devfn),
13996 + "c" ((irq << 8) | (pin + 10)),
13997 +- "S" (&pci_indirect));
13998 ++ "S" (&pci_indirect),
13999 ++ "r" (__PCIBIOS_DS));
14000 + return !(ret & 0xff00);
14001 + }
14002 + EXPORT_SYMBOL(pcibios_set_irq_routing);
14003 +diff -urNp linux-2.6.26.6/arch/x86/power/cpu_32.c linux-2.6.26.6/arch/x86/power/cpu_32.c
14004 +--- linux-2.6.26.6/arch/x86/power/cpu_32.c 2008-10-08 23:24:05.000000000 -0400
14005 ++++ linux-2.6.26.6/arch/x86/power/cpu_32.c 2008-10-11 21:54:19.000000000 -0400
14006 +@@ -66,7 +66,7 @@ static void do_fpu_end(void)
14007 + static void fix_processor_context(void)
14008 + {
14009 + int cpu = smp_processor_id();
14010 +- struct tss_struct *t = &per_cpu(init_tss, cpu);
14011 ++ struct tss_struct *t = init_tss + cpu;
14012 +
14013 + set_tss_desc(cpu, t); /*
14014 + * This just modifies memory; should not be
14015 +diff -urNp linux-2.6.26.6/arch/x86/power/cpu_64.c linux-2.6.26.6/arch/x86/power/cpu_64.c
14016 +--- linux-2.6.26.6/arch/x86/power/cpu_64.c 2008-10-08 23:24:05.000000000 -0400
14017 ++++ linux-2.6.26.6/arch/x86/power/cpu_64.c 2008-10-11 21:54:19.000000000 -0400
14018 +@@ -136,7 +136,11 @@ void restore_processor_state(void)
14019 + static void fix_processor_context(void)
14020 + {
14021 + int cpu = smp_processor_id();
14022 +- struct tss_struct *t = &per_cpu(init_tss, cpu);
14023 ++ struct tss_struct *t = init_tss + cpu;
14024 ++
14025 ++#ifdef CONFIG_PAX_KERNEXEC
14026 ++ unsigned long cr0;
14027 ++#endif
14028 +
14029 + /*
14030 + * This just modifies memory; should not be necessary. But... This
14031 +@@ -145,8 +149,16 @@ static void fix_processor_context(void)
14032 + */
14033 + set_tss_desc(cpu, t);
14034 +
14035 ++#ifdef CONFIG_PAX_KERNEXEC
14036 ++ pax_open_kernel(cr0);
14037 ++#endif
14038 ++
14039 + get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9;
14040 +
14041 ++#ifdef CONFIG_PAX_KERNEXEC
14042 ++ pax_close_kernel(cr0);
14043 ++#endif
14044 ++
14045 + syscall_init(); /* This sets MSR_*STAR and related */
14046 + load_TR_desc(); /* This does ltr */
14047 + load_LDT(&current->active_mm->context); /* This does lldt */
14048 +diff -urNp linux-2.6.26.6/arch/x86/vdso/vdso32-setup.c linux-2.6.26.6/arch/x86/vdso/vdso32-setup.c
14049 +--- linux-2.6.26.6/arch/x86/vdso/vdso32-setup.c 2008-10-08 23:24:05.000000000 -0400
14050 ++++ linux-2.6.26.6/arch/x86/vdso/vdso32-setup.c 2008-10-11 21:54:19.000000000 -0400
14051 +@@ -239,7 +239,7 @@ static inline void map_compat_vdso(int m
14052 + void enable_sep_cpu(void)
14053 + {
14054 + int cpu = get_cpu();
14055 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
14056 ++ struct tss_struct *tss = init_tss + cpu;
14057 +
14058 + if (!boot_cpu_has(X86_FEATURE_SEP)) {
14059 + put_cpu();
14060 +@@ -262,7 +262,7 @@ static int __init gate_vma_init(void)
14061 + gate_vma.vm_start = FIXADDR_USER_START;
14062 + gate_vma.vm_end = FIXADDR_USER_END;
14063 + gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
14064 +- gate_vma.vm_page_prot = __P101;
14065 ++ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
14066 + /*
14067 + * Make sure the vDSO gets into every core dump.
14068 + * Dumping its contents makes post-mortem fully interpretable later
14069 +@@ -341,7 +341,7 @@ int arch_setup_additional_pages(struct l
14070 + if (compat)
14071 + addr = VDSO_HIGH_BASE;
14072 + else {
14073 +- addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
14074 ++ addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
14075 + if (IS_ERR_VALUE(addr)) {
14076 + ret = addr;
14077 + goto up_fail;
14078 +@@ -368,7 +368,7 @@ int arch_setup_additional_pages(struct l
14079 + goto up_fail;
14080 + }
14081 +
14082 +- current->mm->context.vdso = (void *)addr;
14083 ++ current->mm->context.vdso = addr;
14084 + current_thread_info()->sysenter_return =
14085 + VDSO32_SYMBOL(addr, SYSENTER_RETURN);
14086 +
14087 +@@ -394,7 +394,7 @@ static ctl_table abi_table2[] = {
14088 + .mode = 0644,
14089 + .proc_handler = proc_dointvec
14090 + },
14091 +- {}
14092 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
14093 + };
14094 +
14095 + static ctl_table abi_root_table2[] = {
14096 +@@ -404,7 +404,7 @@ static ctl_table abi_root_table2[] = {
14097 + .mode = 0555,
14098 + .child = abi_table2
14099 + },
14100 +- {}
14101 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
14102 + };
14103 +
14104 + static __init int ia32_binfmt_init(void)
14105 +@@ -419,8 +419,14 @@ __initcall(ia32_binfmt_init);
14106 +
14107 + const char *arch_vma_name(struct vm_area_struct *vma)
14108 + {
14109 +- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
14110 ++ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
14111 + return "[vdso]";
14112 ++
14113 ++#ifdef CONFIG_PAX_SEGMEXEC
14114 ++ if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso)
14115 ++ return "[vdso]";
14116 ++#endif
14117 ++
14118 + return NULL;
14119 + }
14120 +
14121 +@@ -429,7 +435,7 @@ struct vm_area_struct *get_gate_vma(stru
14122 + struct mm_struct *mm = tsk->mm;
14123 +
14124 + /* Check to see if this task was created in compat vdso mode */
14125 +- if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
14126 ++ if (mm && mm->context.vdso == VDSO_HIGH_BASE)
14127 + return &gate_vma;
14128 + return NULL;
14129 + }
14130 +diff -urNp linux-2.6.26.6/arch/x86/vdso/vma.c linux-2.6.26.6/arch/x86/vdso/vma.c
14131 +--- linux-2.6.26.6/arch/x86/vdso/vma.c 2008-10-08 23:24:05.000000000 -0400
14132 ++++ linux-2.6.26.6/arch/x86/vdso/vma.c 2008-10-11 21:54:19.000000000 -0400
14133 +@@ -122,7 +122,7 @@ int arch_setup_additional_pages(struct l
14134 + if (ret)
14135 + goto up_fail;
14136 +
14137 +- current->mm->context.vdso = (void *)addr;
14138 ++ current->mm->context.vdso = addr;
14139 + up_fail:
14140 + up_write(&mm->mmap_sem);
14141 + return ret;
14142 +diff -urNp linux-2.6.26.6/arch/x86/xen/enlighten.c linux-2.6.26.6/arch/x86/xen/enlighten.c
14143 +--- linux-2.6.26.6/arch/x86/xen/enlighten.c 2008-10-08 23:24:05.000000000 -0400
14144 ++++ linux-2.6.26.6/arch/x86/xen/enlighten.c 2008-10-11 21:54:19.000000000 -0400
14145 +@@ -295,7 +295,7 @@ static void xen_set_ldt(const void *addr
14146 + static void xen_load_gdt(const struct desc_ptr *dtr)
14147 + {
14148 + unsigned long *frames;
14149 +- unsigned long va = dtr->address;
14150 ++ unsigned long va = (unsigned long)dtr->address;
14151 + unsigned int size = dtr->size + 1;
14152 + unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
14153 + int f;
14154 +@@ -310,7 +310,7 @@ static void xen_load_gdt(const struct de
14155 + mcs = xen_mc_entry(sizeof(*frames) * pages);
14156 + frames = mcs.args;
14157 +
14158 +- for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
14159 ++ for (f = 0; va < (unsigned long)dtr->address + size; va += PAGE_SIZE, f++) {
14160 + frames[f] = virt_to_mfn(va);
14161 + make_lowmem_page_readonly((void *)va);
14162 + }
14163 +@@ -403,7 +403,7 @@ static void xen_write_idt_entry(gate_des
14164 +
14165 + preempt_disable();
14166 +
14167 +- start = __get_cpu_var(idt_desc).address;
14168 ++ start = (unsigned long)__get_cpu_var(idt_desc).address;
14169 + end = start + __get_cpu_var(idt_desc).size + 1;
14170 +
14171 + xen_mc_flush();
14172 +diff -urNp linux-2.6.26.6/arch/x86/xen/smp.c linux-2.6.26.6/arch/x86/xen/smp.c
14173 +--- linux-2.6.26.6/arch/x86/xen/smp.c 2008-10-08 23:24:05.000000000 -0400
14174 ++++ linux-2.6.26.6/arch/x86/xen/smp.c 2008-10-11 21:54:19.000000000 -0400
14175 +@@ -154,7 +154,7 @@ void __init xen_smp_prepare_boot_cpu(voi
14176 +
14177 + /* We've switched to the "real" per-cpu gdt, so make sure the
14178 + old memory can be recycled */
14179 +- make_lowmem_page_readwrite(&per_cpu__gdt_page);
14180 ++ make_lowmem_page_readwrite(get_cpu_gdt_table(smp_processor_id()));
14181 +
14182 + for_each_possible_cpu(cpu) {
14183 + cpus_clear(per_cpu(cpu_sibling_map, cpu));
14184 +@@ -218,7 +218,7 @@ static __cpuinit int
14185 + cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
14186 + {
14187 + struct vcpu_guest_context *ctxt;
14188 +- struct gdt_page *gdt = &per_cpu(gdt_page, cpu);
14189 ++ struct desc_struct *gdt = get_cpu_gdt_table(cpu);
14190 +
14191 + if (cpu_test_and_set(cpu, xen_cpu_initialized_map))
14192 + return 0;
14193 +@@ -228,8 +228,8 @@ cpu_initialize_context(unsigned int cpu,
14194 + return -ENOMEM;
14195 +
14196 + ctxt->flags = VGCF_IN_KERNEL;
14197 +- ctxt->user_regs.ds = __USER_DS;
14198 +- ctxt->user_regs.es = __USER_DS;
14199 ++ ctxt->user_regs.ds = __KERNEL_DS;
14200 ++ ctxt->user_regs.es = __KERNEL_DS;
14201 + ctxt->user_regs.fs = __KERNEL_PERCPU;
14202 + ctxt->user_regs.gs = 0;
14203 + ctxt->user_regs.ss = __KERNEL_DS;
14204 +@@ -242,11 +242,11 @@ cpu_initialize_context(unsigned int cpu,
14205 +
14206 + ctxt->ldt_ents = 0;
14207 +
14208 +- BUG_ON((unsigned long)gdt->gdt & ~PAGE_MASK);
14209 +- make_lowmem_page_readonly(gdt->gdt);
14210 ++ BUG_ON((unsigned long)gdt & ~PAGE_MASK);
14211 ++ make_lowmem_page_readonly(gdt);
14212 +
14213 +- ctxt->gdt_frames[0] = virt_to_mfn(gdt->gdt);
14214 +- ctxt->gdt_ents = ARRAY_SIZE(gdt->gdt);
14215 ++ ctxt->gdt_frames[0] = virt_to_mfn(gdt);
14216 ++ ctxt->gdt_ents = GDT_ENTRIES;
14217 +
14218 + ctxt->user_regs.cs = __KERNEL_CS;
14219 + ctxt->user_regs.esp = idle->thread.sp0 - sizeof(struct pt_regs);
14220 +diff -urNp linux-2.6.26.6/crypto/async_tx/async_tx.c linux-2.6.26.6/crypto/async_tx/async_tx.c
14221 +--- linux-2.6.26.6/crypto/async_tx/async_tx.c 2008-10-08 23:24:05.000000000 -0400
14222 ++++ linux-2.6.26.6/crypto/async_tx/async_tx.c 2008-10-11 21:54:19.000000000 -0400
14223 +@@ -357,8 +357,8 @@ async_tx_init(void)
14224 + err:
14225 + printk(KERN_ERR "async_tx: initialization failure\n");
14226 +
14227 +- while (--cap >= 0)
14228 +- free_percpu(channel_table[cap]);
14229 ++ while (cap)
14230 ++ free_percpu(channel_table[--cap]);
14231 +
14232 + return 1;
14233 + }
14234 +diff -urNp linux-2.6.26.6/crypto/lrw.c linux-2.6.26.6/crypto/lrw.c
14235 +--- linux-2.6.26.6/crypto/lrw.c 2008-10-08 23:24:05.000000000 -0400
14236 ++++ linux-2.6.26.6/crypto/lrw.c 2008-10-11 21:54:19.000000000 -0400
14237 +@@ -54,7 +54,7 @@ static int setkey(struct crypto_tfm *par
14238 + struct priv *ctx = crypto_tfm_ctx(parent);
14239 + struct crypto_cipher *child = ctx->child;
14240 + int err, i;
14241 +- be128 tmp = { 0 };
14242 ++ be128 tmp = { 0, 0 };
14243 + int bsize = crypto_cipher_blocksize(child);
14244 +
14245 + crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
14246 +diff -urNp linux-2.6.26.6/Documentation/dontdiff linux-2.6.26.6/Documentation/dontdiff
14247 +--- linux-2.6.26.6/Documentation/dontdiff 2008-10-08 23:24:05.000000000 -0400
14248 ++++ linux-2.6.26.6/Documentation/dontdiff 2008-10-11 21:54:19.000000000 -0400
14249 +@@ -3,6 +3,7 @@
14250 + *.bin
14251 + *.cpio
14252 + *.css
14253 ++*.dbg
14254 + *.dvi
14255 + *.eps
14256 + *.gif
14257 +@@ -51,9 +52,14 @@ COPYING
14258 + CREDITS
14259 + CVS
14260 + ChangeSet
14261 ++GPATH
14262 ++GRTAGS
14263 ++GSYMS
14264 ++GTAGS
14265 + Image
14266 + Kerntypes
14267 + MODS.txt
14268 ++Module.markers
14269 + Module.symvers
14270 + PENDING
14271 + SCCS
14272 +@@ -72,6 +78,7 @@ bbootsect
14273 + bin2c
14274 + binkernel.spec
14275 + bootsect
14276 ++bounds.h
14277 + bsetup
14278 + btfixupprep
14279 + build
14280 +@@ -88,6 +95,7 @@ config_data.gz*
14281 + conmakehash
14282 + consolemap_deftbl.c*
14283 + crc32table.h*
14284 ++cpustr.h
14285 + cscope.*
14286 + defkeymap.c*
14287 + devlist.h*
14288 +@@ -136,6 +144,7 @@ miboot*
14289 + mk_elfconfig
14290 + mkboot
14291 + mkbugboot
14292 ++mkcpustr
14293 + mkdep
14294 + mkprep
14295 + mktables
14296 +@@ -177,16 +186,20 @@ times.h*
14297 + tkparse
14298 + trix_boot.h
14299 + utsrelease.h*
14300 +-vdso.lds
14301 ++vdso*.lds
14302 + version.h*
14303 + vmlinux
14304 + vmlinux-*
14305 + vmlinux.aout
14306 +-vmlinux*.lds*
14307 ++vmlinux.bin.all
14308 ++vmlinux*.lds
14309 ++vmlinux.relocs
14310 + vmlinux*.scr
14311 +-vsyscall.lds
14312 ++vsyscall*.lds
14313 ++wakeup.lds
14314 + wanxlfw.inc
14315 + uImage
14316 + unifdef
14317 ++utsrelease.h
14318 + zImage*
14319 + zconf.hash.c
14320 +diff -urNp linux-2.6.26.6/drivers/acpi/blacklist.c linux-2.6.26.6/drivers/acpi/blacklist.c
14321 +--- linux-2.6.26.6/drivers/acpi/blacklist.c 2008-10-08 23:24:05.000000000 -0400
14322 ++++ linux-2.6.26.6/drivers/acpi/blacklist.c 2008-10-11 21:54:19.000000000 -0400
14323 +@@ -71,7 +71,7 @@ static struct acpi_blacklist_item acpi_b
14324 + {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
14325 + "Incorrect _ADR", 1},
14326 +
14327 +- {""}
14328 ++ {"", "", 0, 0, 0, all_versions, 0}
14329 + };
14330 +
14331 + #if CONFIG_ACPI_BLACKLIST_YEAR
14332 +diff -urNp linux-2.6.26.6/drivers/acpi/osl.c linux-2.6.26.6/drivers/acpi/osl.c
14333 +--- linux-2.6.26.6/drivers/acpi/osl.c 2008-10-08 23:24:05.000000000 -0400
14334 ++++ linux-2.6.26.6/drivers/acpi/osl.c 2008-10-11 21:54:19.000000000 -0400
14335 +@@ -494,6 +494,8 @@ acpi_os_read_memory(acpi_physical_addres
14336 + void __iomem *virt_addr;
14337 +
14338 + virt_addr = ioremap(phys_addr, width);
14339 ++ if (!virt_addr)
14340 ++ return AE_NO_MEMORY;
14341 + if (!value)
14342 + value = &dummy;
14343 +
14344 +@@ -522,6 +524,8 @@ acpi_os_write_memory(acpi_physical_addre
14345 + void __iomem *virt_addr;
14346 +
14347 + virt_addr = ioremap(phys_addr, width);
14348 ++ if (!virt_addr)
14349 ++ return AE_NO_MEMORY;
14350 +
14351 + switch (width) {
14352 + case 8:
14353 +diff -urNp linux-2.6.26.6/drivers/acpi/processor_core.c linux-2.6.26.6/drivers/acpi/processor_core.c
14354 +--- linux-2.6.26.6/drivers/acpi/processor_core.c 2008-10-08 23:24:05.000000000 -0400
14355 ++++ linux-2.6.26.6/drivers/acpi/processor_core.c 2008-10-11 21:54:19.000000000 -0400
14356 +@@ -631,7 +631,7 @@ static int __cpuinit acpi_processor_star
14357 + return 0;
14358 + }
14359 +
14360 +- BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
14361 ++ BUG_ON(pr->id >= nr_cpu_ids);
14362 +
14363 + /*
14364 + * Buggy BIOS check
14365 +diff -urNp linux-2.6.26.6/drivers/acpi/processor_idle.c linux-2.6.26.6/drivers/acpi/processor_idle.c
14366 +--- linux-2.6.26.6/drivers/acpi/processor_idle.c 2008-10-08 23:24:05.000000000 -0400
14367 ++++ linux-2.6.26.6/drivers/acpi/processor_idle.c 2008-10-11 21:54:19.000000000 -0400
14368 +@@ -181,7 +181,7 @@ static struct dmi_system_id __cpuinitdat
14369 + DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
14370 + DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
14371 + (void *)2},
14372 +- {},
14373 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
14374 + };
14375 +
14376 + static inline u32 ticks_elapsed(u32 t1, u32 t2)
14377 +diff -urNp linux-2.6.26.6/drivers/acpi/sleep/main.c linux-2.6.26.6/drivers/acpi/sleep/main.c
14378 +--- linux-2.6.26.6/drivers/acpi/sleep/main.c 2008-10-08 23:24:05.000000000 -0400
14379 ++++ linux-2.6.26.6/drivers/acpi/sleep/main.c 2008-10-11 21:54:19.000000000 -0400
14380 +@@ -249,7 +249,7 @@ static struct dmi_system_id __initdata a
14381 + .ident = "Toshiba Satellite 4030cdt",
14382 + .matches = {DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),},
14383 + },
14384 +- {},
14385 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
14386 + };
14387 + #endif /* CONFIG_SUSPEND */
14388 +
14389 +diff -urNp linux-2.6.26.6/drivers/acpi/tables/tbfadt.c linux-2.6.26.6/drivers/acpi/tables/tbfadt.c
14390 +--- linux-2.6.26.6/drivers/acpi/tables/tbfadt.c 2008-10-08 23:24:05.000000000 -0400
14391 ++++ linux-2.6.26.6/drivers/acpi/tables/tbfadt.c 2008-10-11 21:54:19.000000000 -0400
14392 +@@ -48,7 +48,7 @@
14393 + ACPI_MODULE_NAME("tbfadt")
14394 +
14395 + /* Local prototypes */
14396 +-static void inline
14397 ++static inline void
14398 + acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
14399 + u8 bit_width, u64 address);
14400 +
14401 +@@ -122,7 +122,7 @@ static struct acpi_fadt_info fadt_info_t
14402 + *
14403 + ******************************************************************************/
14404 +
14405 +-static void inline
14406 ++static inline void
14407 + acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
14408 + u8 bit_width, u64 address)
14409 + {
14410 +diff -urNp linux-2.6.26.6/drivers/ata/ahci.c linux-2.6.26.6/drivers/ata/ahci.c
14411 +--- linux-2.6.26.6/drivers/ata/ahci.c 2008-10-08 23:24:05.000000000 -0400
14412 ++++ linux-2.6.26.6/drivers/ata/ahci.c 2008-10-11 21:54:19.000000000 -0400
14413 +@@ -546,7 +546,7 @@ static const struct pci_device_id ahci_p
14414 + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
14415 + PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
14416 +
14417 +- { } /* terminate list */
14418 ++ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
14419 + };
14420 +
14421 +
14422 +diff -urNp linux-2.6.26.6/drivers/ata/ata_piix.c linux-2.6.26.6/drivers/ata/ata_piix.c
14423 +--- linux-2.6.26.6/drivers/ata/ata_piix.c 2008-10-08 23:24:05.000000000 -0400
14424 ++++ linux-2.6.26.6/drivers/ata/ata_piix.c 2008-10-11 21:54:19.000000000 -0400
14425 +@@ -275,7 +275,7 @@ static const struct pci_device_id piix_p
14426 + /* SATA Controller IDE (ICH10) */
14427 + { 0x8086, 0x3a26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
14428 +
14429 +- { } /* terminate list */
14430 ++ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
14431 + };
14432 +
14433 + static struct pci_driver piix_pci_driver = {
14434 +@@ -578,7 +578,7 @@ static const struct ich_laptop ich_lapto
14435 + { 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */
14436 + { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */
14437 + /* end marker */
14438 +- { 0, }
14439 ++ { 0, 0, 0 }
14440 + };
14441 +
14442 + /**
14443 +@@ -1134,7 +1134,7 @@ static int piix_broken_suspend(void)
14444 + },
14445 + },
14446 +
14447 +- { } /* terminate list */
14448 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } /* terminate list */
14449 + };
14450 + static const char *oemstrs[] = {
14451 + "Tecra M3,",
14452 +diff -urNp linux-2.6.26.6/drivers/ata/libata-core.c linux-2.6.26.6/drivers/ata/libata-core.c
14453 +--- linux-2.6.26.6/drivers/ata/libata-core.c 2008-10-08 23:24:05.000000000 -0400
14454 ++++ linux-2.6.26.6/drivers/ata/libata-core.c 2008-10-11 21:54:19.000000000 -0400
14455 +@@ -736,7 +736,7 @@ static const struct ata_xfer_ent {
14456 + { ATA_SHIFT_PIO, ATA_NR_PIO_MODES, XFER_PIO_0 },
14457 + { ATA_SHIFT_MWDMA, ATA_NR_MWDMA_MODES, XFER_MW_DMA_0 },
14458 + { ATA_SHIFT_UDMA, ATA_NR_UDMA_MODES, XFER_UDMA_0 },
14459 +- { -1, },
14460 ++ { -1, 0, 0 }
14461 + };
14462 +
14463 + /**
14464 +@@ -2860,7 +2860,7 @@ static const struct ata_timing ata_timin
14465 + { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 20 },
14466 + { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 15 },
14467 +
14468 +- { 0xFF }
14469 ++ { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
14470 + };
14471 +
14472 + #define ENOUGH(v, unit) (((v)-1)/(unit)+1)
14473 +@@ -3947,7 +3947,7 @@ static const struct ata_blacklist_entry
14474 + { "TSSTcorp CDDVDW SH-S202N", "SB01", ATA_HORKAGE_IVB, },
14475 +
14476 + /* End Marker */
14477 +- { }
14478 ++ { NULL, NULL, 0 }
14479 + };
14480 +
14481 + static int strn_pattern_cmp(const char *patt, const char *name, int wildchar)
14482 +diff -urNp linux-2.6.26.6/drivers/char/agp/frontend.c linux-2.6.26.6/drivers/char/agp/frontend.c
14483 +--- linux-2.6.26.6/drivers/char/agp/frontend.c 2008-10-08 23:24:05.000000000 -0400
14484 ++++ linux-2.6.26.6/drivers/char/agp/frontend.c 2008-10-11 21:54:19.000000000 -0400
14485 +@@ -820,7 +820,7 @@ static int agpioc_reserve_wrap(struct ag
14486 + if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
14487 + return -EFAULT;
14488 +
14489 +- if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
14490 ++ if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
14491 + return -EFAULT;
14492 +
14493 + client = agp_find_client_by_pid(reserve.pid);
14494 +diff -urNp linux-2.6.26.6/drivers/char/agp/intel-agp.c linux-2.6.26.6/drivers/char/agp/intel-agp.c
14495 +--- linux-2.6.26.6/drivers/char/agp/intel-agp.c 2008-10-08 23:24:05.000000000 -0400
14496 ++++ linux-2.6.26.6/drivers/char/agp/intel-agp.c 2008-10-11 21:54:20.000000000 -0400
14497 +@@ -2319,7 +2319,7 @@ static struct pci_device_id agp_intel_pc
14498 + ID(PCI_DEVICE_ID_INTEL_IGD_E_HB),
14499 + ID(PCI_DEVICE_ID_INTEL_Q45_HB),
14500 + ID(PCI_DEVICE_ID_INTEL_G45_HB),
14501 +- { }
14502 ++ { 0, 0, 0, 0, 0, 0, 0 }
14503 + };
14504 +
14505 + MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
14506 +diff -urNp linux-2.6.26.6/drivers/char/drm/drm_pciids.h linux-2.6.26.6/drivers/char/drm/drm_pciids.h
14507 +--- linux-2.6.26.6/drivers/char/drm/drm_pciids.h 2008-10-08 23:24:05.000000000 -0400
14508 ++++ linux-2.6.26.6/drivers/char/drm/drm_pciids.h 2008-10-11 21:54:20.000000000 -0400
14509 +@@ -346,7 +346,7 @@
14510 + {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
14511 + {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
14512 + {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
14513 +- {0, 0, 0}
14514 ++ {0, 0, 0, 0, 0, 0, 0 }
14515 +
14516 + #define i830_PCI_IDS \
14517 + {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
14518 +diff -urNp linux-2.6.26.6/drivers/char/hpet.c linux-2.6.26.6/drivers/char/hpet.c
14519 +--- linux-2.6.26.6/drivers/char/hpet.c 2008-10-08 23:24:05.000000000 -0400
14520 ++++ linux-2.6.26.6/drivers/char/hpet.c 2008-10-11 21:54:20.000000000 -0400
14521 +@@ -953,7 +953,7 @@ static struct acpi_driver hpet_acpi_driv
14522 + },
14523 + };
14524 +
14525 +-static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
14526 ++static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL };
14527 +
14528 + static int __init hpet_init(void)
14529 + {
14530 +diff -urNp linux-2.6.26.6/drivers/char/keyboard.c linux-2.6.26.6/drivers/char/keyboard.c
14531 +--- linux-2.6.26.6/drivers/char/keyboard.c 2008-10-08 23:24:05.000000000 -0400
14532 ++++ linux-2.6.26.6/drivers/char/keyboard.c 2008-10-11 21:54:20.000000000 -0400
14533 +@@ -633,6 +633,16 @@ static void k_spec(struct vc_data *vc, u
14534 + kbd->kbdmode == VC_MEDIUMRAW) &&
14535 + value != KVAL(K_SAK))
14536 + return; /* SAK is allowed even in raw mode */
14537 ++
14538 ++#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
14539 ++ {
14540 ++ void *func = fn_handler[value];
14541 ++ if (func == fn_show_state || func == fn_show_ptregs ||
14542 ++ func == fn_show_mem)
14543 ++ return;
14544 ++ }
14545 ++#endif
14546 ++
14547 + fn_handler[value](vc);
14548 + }
14549 +
14550 +@@ -1386,7 +1396,7 @@ static const struct input_device_id kbd_
14551 + .evbit = { BIT_MASK(EV_SND) },
14552 + },
14553 +
14554 +- { }, /* Terminating entry */
14555 ++ { 0 }, /* Terminating entry */
14556 + };
14557 +
14558 + MODULE_DEVICE_TABLE(input, kbd_ids);
14559 +diff -urNp linux-2.6.26.6/drivers/char/mem.c linux-2.6.26.6/drivers/char/mem.c
14560 +--- linux-2.6.26.6/drivers/char/mem.c 2008-10-08 23:24:05.000000000 -0400
14561 ++++ linux-2.6.26.6/drivers/char/mem.c 2008-10-11 21:54:20.000000000 -0400
14562 +@@ -26,6 +26,7 @@
14563 + #include <linux/bootmem.h>
14564 + #include <linux/splice.h>
14565 + #include <linux/pfn.h>
14566 ++#include <linux/grsecurity.h>
14567 +
14568 + #include <asm/uaccess.h>
14569 + #include <asm/io.h>
14570 +@@ -34,6 +35,10 @@
14571 + # include <linux/efi.h>
14572 + #endif
14573 +
14574 ++#ifdef CONFIG_GRKERNSEC
14575 ++extern struct file_operations grsec_fops;
14576 ++#endif
14577 ++
14578 + /*
14579 + * Architectures vary in how they handle caching for addresses
14580 + * outside of main memory.
14581 +@@ -191,6 +196,11 @@ static ssize_t write_mem(struct file * f
14582 + if (!valid_phys_addr_range(p, count))
14583 + return -EFAULT;
14584 +
14585 ++#ifdef CONFIG_GRKERNSEC_KMEM
14586 ++ gr_handle_mem_write();
14587 ++ return -EPERM;
14588 ++#endif
14589 ++
14590 + written = 0;
14591 +
14592 + #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
14593 +@@ -346,6 +356,11 @@ static int mmap_mem(struct file * file,
14594 + &vma->vm_page_prot))
14595 + return -EINVAL;
14596 +
14597 ++#ifdef CONFIG_GRKERNSEC_KMEM
14598 ++ if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
14599 ++ return -EPERM;
14600 ++#endif
14601 ++
14602 + vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
14603 + size,
14604 + vma->vm_page_prot);
14605 +@@ -584,6 +599,11 @@ static ssize_t write_kmem(struct file *
14606 + ssize_t written;
14607 + char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
14608 +
14609 ++#ifdef CONFIG_GRKERNSEC_KMEM
14610 ++ gr_handle_kmem_write();
14611 ++ return -EPERM;
14612 ++#endif
14613 ++
14614 + if (p < (unsigned long) high_memory) {
14615 +
14616 + wrote = count;
14617 +@@ -787,6 +807,16 @@ static loff_t memory_lseek(struct file *
14618 +
14619 + static int open_port(struct inode * inode, struct file * filp)
14620 + {
14621 ++#ifdef CONFIG_GRKERNSEC_KMEM
14622 ++ gr_handle_open_port();
14623 ++ return -EPERM;
14624 ++#endif
14625 ++
14626 ++ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
14627 ++}
14628 ++
14629 ++static int open_mem(struct inode * inode, struct file * filp)
14630 ++{
14631 + return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
14632 + }
14633 +
14634 +@@ -794,7 +824,6 @@ static int open_port(struct inode * inod
14635 + #define full_lseek null_lseek
14636 + #define write_zero write_null
14637 + #define read_full read_zero
14638 +-#define open_mem open_port
14639 + #define open_kmem open_mem
14640 + #define open_oldmem open_mem
14641 +
14642 +@@ -931,6 +960,11 @@ static int memory_open(struct inode * in
14643 + filp->f_op = &oldmem_fops;
14644 + break;
14645 + #endif
14646 ++#ifdef CONFIG_GRKERNSEC
14647 ++ case 13:
14648 ++ filp->f_op = &grsec_fops;
14649 ++ break;
14650 ++#endif
14651 + default:
14652 + return -ENXIO;
14653 + }
14654 +@@ -965,6 +999,9 @@ static const struct {
14655 + #ifdef CONFIG_CRASH_DUMP
14656 + {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
14657 + #endif
14658 ++#ifdef CONFIG_GRKERNSEC
14659 ++ {13,"grsec", S_IRUSR | S_IWUGO, &grsec_fops},
14660 ++#endif
14661 + };
14662 +
14663 + static struct class *mem_class;
14664 +diff -urNp linux-2.6.26.6/drivers/char/nvram.c linux-2.6.26.6/drivers/char/nvram.c
14665 +--- linux-2.6.26.6/drivers/char/nvram.c 2008-10-08 23:24:05.000000000 -0400
14666 ++++ linux-2.6.26.6/drivers/char/nvram.c 2008-10-11 21:54:20.000000000 -0400
14667 +@@ -430,7 +430,10 @@ static const struct file_operations nvra
14668 + static struct miscdevice nvram_dev = {
14669 + NVRAM_MINOR,
14670 + "nvram",
14671 +- &nvram_fops
14672 ++ &nvram_fops,
14673 ++ {NULL, NULL},
14674 ++ NULL,
14675 ++ NULL
14676 + };
14677 +
14678 + static int __init
14679 +diff -urNp linux-2.6.26.6/drivers/char/random.c linux-2.6.26.6/drivers/char/random.c
14680 +--- linux-2.6.26.6/drivers/char/random.c 2008-10-08 23:24:05.000000000 -0400
14681 ++++ linux-2.6.26.6/drivers/char/random.c 2008-10-11 21:54:20.000000000 -0400
14682 +@@ -248,8 +248,13 @@
14683 + /*
14684 + * Configuration information
14685 + */
14686 ++#ifdef CONFIG_GRKERNSEC_RANDNET
14687 ++#define INPUT_POOL_WORDS 512
14688 ++#define OUTPUT_POOL_WORDS 128
14689 ++#else
14690 + #define INPUT_POOL_WORDS 128
14691 + #define OUTPUT_POOL_WORDS 32
14692 ++#endif
14693 + #define SEC_XFER_SIZE 512
14694 +
14695 + /*
14696 +@@ -286,10 +291,17 @@ static struct poolinfo {
14697 + int poolwords;
14698 + int tap1, tap2, tap3, tap4, tap5;
14699 + } poolinfo_table[] = {
14700 ++#ifdef CONFIG_GRKERNSEC_RANDNET
14701 ++ /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
14702 ++ { 512, 411, 308, 208, 104, 1 },
14703 ++ /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
14704 ++ { 128, 103, 76, 51, 25, 1 },
14705 ++#else
14706 + /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
14707 + { 128, 103, 76, 51, 25, 1 },
14708 + /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
14709 + { 32, 26, 20, 14, 7, 1 },
14710 ++#endif
14711 + #if 0
14712 + /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
14713 + { 2048, 1638, 1231, 819, 411, 1 },
14714 +@@ -1165,7 +1177,7 @@ EXPORT_SYMBOL(generate_random_uuid);
14715 + #include <linux/sysctl.h>
14716 +
14717 + static int min_read_thresh = 8, min_write_thresh;
14718 +-static int max_read_thresh = INPUT_POOL_WORDS * 32;
14719 ++static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
14720 + static int max_write_thresh = INPUT_POOL_WORDS * 32;
14721 + static char sysctl_bootid[16];
14722 +
14723 +diff -urNp linux-2.6.26.6/drivers/char/tpm/tpm.c linux-2.6.26.6/drivers/char/tpm/tpm.c
14724 +--- linux-2.6.26.6/drivers/char/tpm/tpm.c 2008-10-08 23:24:05.000000000 -0400
14725 ++++ linux-2.6.26.6/drivers/char/tpm/tpm.c 2008-10-11 21:54:20.000000000 -0400
14726 +@@ -970,7 +970,7 @@ ssize_t tpm_write(struct file *file, con
14727 +
14728 + mutex_lock(&chip->buffer_mutex);
14729 +
14730 +- if (in_size > TPM_BUFSIZE)
14731 ++ if (in_size > (unsigned int)TPM_BUFSIZE)
14732 + in_size = TPM_BUFSIZE;
14733 +
14734 + if (copy_from_user
14735 +diff -urNp linux-2.6.26.6/drivers/char/vt_ioctl.c linux-2.6.26.6/drivers/char/vt_ioctl.c
14736 +--- linux-2.6.26.6/drivers/char/vt_ioctl.c 2008-10-08 23:24:05.000000000 -0400
14737 ++++ linux-2.6.26.6/drivers/char/vt_ioctl.c 2008-10-11 21:54:20.000000000 -0400
14738 +@@ -96,6 +96,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
14739 + case KDSKBENT:
14740 + if (!perm)
14741 + return -EPERM;
14742 ++
14743 ++#ifdef CONFIG_GRKERNSEC
14744 ++ if (!capable(CAP_SYS_TTY_CONFIG))
14745 ++ return -EPERM;
14746 ++#endif
14747 ++
14748 + if (!i && v == K_NOSUCHMAP) {
14749 + /* deallocate map */
14750 + key_map = key_maps[s];
14751 +@@ -236,6 +242,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry
14752 + goto reterr;
14753 + }
14754 +
14755 ++#ifdef CONFIG_GRKERNSEC
14756 ++ if (!capable(CAP_SYS_TTY_CONFIG)) {
14757 ++ ret = -EPERM;
14758 ++ goto reterr;
14759 ++ }
14760 ++#endif
14761 ++
14762 + q = func_table[i];
14763 + first_free = funcbufptr + (funcbufsize - funcbufleft);
14764 + for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
14765 +diff -urNp linux-2.6.26.6/drivers/edac/edac_core.h linux-2.6.26.6/drivers/edac/edac_core.h
14766 +--- linux-2.6.26.6/drivers/edac/edac_core.h 2008-10-08 23:24:05.000000000 -0400
14767 ++++ linux-2.6.26.6/drivers/edac/edac_core.h 2008-10-11 21:54:20.000000000 -0400
14768 +@@ -86,11 +86,11 @@ extern int edac_debug_level;
14769 +
14770 + #else /* !CONFIG_EDAC_DEBUG */
14771 +
14772 +-#define debugf0( ... )
14773 +-#define debugf1( ... )
14774 +-#define debugf2( ... )
14775 +-#define debugf3( ... )
14776 +-#define debugf4( ... )
14777 ++#define debugf0( ... ) do {} while (0)
14778 ++#define debugf1( ... ) do {} while (0)
14779 ++#define debugf2( ... ) do {} while (0)
14780 ++#define debugf3( ... ) do {} while (0)
14781 ++#define debugf4( ... ) do {} while (0)
14782 +
14783 + #endif /* !CONFIG_EDAC_DEBUG */
14784 +
14785 +diff -urNp linux-2.6.26.6/drivers/firmware/dmi_scan.c linux-2.6.26.6/drivers/firmware/dmi_scan.c
14786 +--- linux-2.6.26.6/drivers/firmware/dmi_scan.c 2008-10-08 23:24:05.000000000 -0400
14787 ++++ linux-2.6.26.6/drivers/firmware/dmi_scan.c 2008-10-11 21:54:20.000000000 -0400
14788 +@@ -379,11 +379,6 @@ void __init dmi_scan_machine(void)
14789 + }
14790 + }
14791 + else {
14792 +- /*
14793 +- * no iounmap() for that ioremap(); it would be a no-op, but
14794 +- * it's so early in setup that sucker gets confused into doing
14795 +- * what it shouldn't if we actually call it.
14796 +- */
14797 + p = dmi_ioremap(0xF0000, 0x10000);
14798 + if (p == NULL)
14799 + goto out;
14800 +diff -urNp linux-2.6.26.6/drivers/hwmon/fscpos.c linux-2.6.26.6/drivers/hwmon/fscpos.c
14801 +--- linux-2.6.26.6/drivers/hwmon/fscpos.c 2008-10-08 23:24:05.000000000 -0400
14802 ++++ linux-2.6.26.6/drivers/hwmon/fscpos.c 2008-10-11 21:54:20.000000000 -0400
14803 +@@ -230,7 +230,6 @@ static ssize_t set_pwm(struct i2c_client
14804 + unsigned long v = simple_strtoul(buf, NULL, 10);
14805 +
14806 + /* Range: 0..255 */
14807 +- if (v < 0) v = 0;
14808 + if (v > 255) v = 255;
14809 +
14810 + mutex_lock(&data->update_lock);
14811 +diff -urNp linux-2.6.26.6/drivers/hwmon/k8temp.c linux-2.6.26.6/drivers/hwmon/k8temp.c
14812 +--- linux-2.6.26.6/drivers/hwmon/k8temp.c 2008-10-08 23:24:05.000000000 -0400
14813 ++++ linux-2.6.26.6/drivers/hwmon/k8temp.c 2008-10-11 21:54:20.000000000 -0400
14814 +@@ -130,7 +130,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
14815 +
14816 + static struct pci_device_id k8temp_ids[] = {
14817 + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
14818 +- { 0 },
14819 ++ { 0, 0, 0, 0, 0, 0, 0 },
14820 + };
14821 +
14822 + MODULE_DEVICE_TABLE(pci, k8temp_ids);
14823 +diff -urNp linux-2.6.26.6/drivers/hwmon/sis5595.c linux-2.6.26.6/drivers/hwmon/sis5595.c
14824 +--- linux-2.6.26.6/drivers/hwmon/sis5595.c 2008-10-08 23:24:05.000000000 -0400
14825 ++++ linux-2.6.26.6/drivers/hwmon/sis5595.c 2008-10-11 21:54:20.000000000 -0400
14826 +@@ -698,7 +698,7 @@ static struct sis5595_data *sis5595_upda
14827 +
14828 + static struct pci_device_id sis5595_pci_ids[] = {
14829 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
14830 +- { 0, }
14831 ++ { 0, 0, 0, 0, 0, 0, 0 }
14832 + };
14833 +
14834 + MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
14835 +diff -urNp linux-2.6.26.6/drivers/hwmon/via686a.c linux-2.6.26.6/drivers/hwmon/via686a.c
14836 +--- linux-2.6.26.6/drivers/hwmon/via686a.c 2008-10-08 23:24:05.000000000 -0400
14837 ++++ linux-2.6.26.6/drivers/hwmon/via686a.c 2008-10-11 21:54:20.000000000 -0400
14838 +@@ -768,7 +768,7 @@ static struct via686a_data *via686a_upda
14839 +
14840 + static struct pci_device_id via686a_pci_ids[] = {
14841 + { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
14842 +- { 0, }
14843 ++ { 0, 0, 0, 0, 0, 0, 0 }
14844 + };
14845 +
14846 + MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
14847 +diff -urNp linux-2.6.26.6/drivers/hwmon/vt8231.c linux-2.6.26.6/drivers/hwmon/vt8231.c
14848 +--- linux-2.6.26.6/drivers/hwmon/vt8231.c 2008-10-08 23:24:05.000000000 -0400
14849 ++++ linux-2.6.26.6/drivers/hwmon/vt8231.c 2008-10-11 21:54:20.000000000 -0400
14850 +@@ -698,7 +698,7 @@ static struct platform_driver vt8231_dri
14851 +
14852 + static struct pci_device_id vt8231_pci_ids[] = {
14853 + { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
14854 +- { 0, }
14855 ++ { 0, 0, 0, 0, 0, 0, 0 }
14856 + };
14857 +
14858 + MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
14859 +diff -urNp linux-2.6.26.6/drivers/hwmon/w83791d.c linux-2.6.26.6/drivers/hwmon/w83791d.c
14860 +--- linux-2.6.26.6/drivers/hwmon/w83791d.c 2008-10-08 23:24:05.000000000 -0400
14861 ++++ linux-2.6.26.6/drivers/hwmon/w83791d.c 2008-10-11 21:54:20.000000000 -0400
14862 +@@ -290,8 +290,8 @@ static int w83791d_attach_adapter(struct
14863 + static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind);
14864 + static int w83791d_detach_client(struct i2c_client *client);
14865 +
14866 +-static int w83791d_read(struct i2c_client *client, u8 register);
14867 +-static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
14868 ++static int w83791d_read(struct i2c_client *client, u8 reg);
14869 ++static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
14870 + static struct w83791d_data *w83791d_update_device(struct device *dev);
14871 +
14872 + #ifdef DEBUG
14873 +diff -urNp linux-2.6.26.6/drivers/i2c/busses/i2c-i801.c linux-2.6.26.6/drivers/i2c/busses/i2c-i801.c
14874 +--- linux-2.6.26.6/drivers/i2c/busses/i2c-i801.c 2008-10-08 23:24:05.000000000 -0400
14875 ++++ linux-2.6.26.6/drivers/i2c/busses/i2c-i801.c 2008-10-11 21:54:20.000000000 -0400
14876 +@@ -592,7 +592,7 @@ static struct pci_device_id i801_ids[] =
14877 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TOLAPAI_1) },
14878 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) },
14879 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) },
14880 +- { 0, }
14881 ++ { 0, 0, 0, 0, 0, 0, 0 }
14882 + };
14883 +
14884 + MODULE_DEVICE_TABLE (pci, i801_ids);
14885 +diff -urNp linux-2.6.26.6/drivers/i2c/busses/i2c-i810.c linux-2.6.26.6/drivers/i2c/busses/i2c-i810.c
14886 +--- linux-2.6.26.6/drivers/i2c/busses/i2c-i810.c 2008-10-08 23:24:05.000000000 -0400
14887 ++++ linux-2.6.26.6/drivers/i2c/busses/i2c-i810.c 2008-10-11 21:54:20.000000000 -0400
14888 +@@ -198,7 +198,7 @@ static struct pci_device_id i810_ids[] _
14889 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG) },
14890 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC) },
14891 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG) },
14892 +- { 0, },
14893 ++ { 0, 0, 0, 0, 0, 0, 0 },
14894 + };
14895 +
14896 + MODULE_DEVICE_TABLE (pci, i810_ids);
14897 +diff -urNp linux-2.6.26.6/drivers/i2c/busses/i2c-piix4.c linux-2.6.26.6/drivers/i2c/busses/i2c-piix4.c
14898 +--- linux-2.6.26.6/drivers/i2c/busses/i2c-piix4.c 2008-10-08 23:24:05.000000000 -0400
14899 ++++ linux-2.6.26.6/drivers/i2c/busses/i2c-piix4.c 2008-10-11 21:54:20.000000000 -0400
14900 +@@ -133,7 +133,7 @@ static struct dmi_system_id __devinitdat
14901 + .ident = "IBM",
14902 + .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
14903 + },
14904 +- { },
14905 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL },
14906 + };
14907 +
14908 + static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
14909 +@@ -431,7 +431,7 @@ static struct pci_device_id piix4_ids[]
14910 + PCI_DEVICE_ID_SERVERWORKS_CSB6) },
14911 + { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
14912 + PCI_DEVICE_ID_SERVERWORKS_HT1000SB) },
14913 +- { 0, }
14914 ++ { 0, 0, 0, 0, 0, 0, 0 }
14915 + };
14916 +
14917 + MODULE_DEVICE_TABLE (pci, piix4_ids);
14918 +diff -urNp linux-2.6.26.6/drivers/i2c/busses/i2c-sis630.c linux-2.6.26.6/drivers/i2c/busses/i2c-sis630.c
14919 +--- linux-2.6.26.6/drivers/i2c/busses/i2c-sis630.c 2008-10-08 23:24:05.000000000 -0400
14920 ++++ linux-2.6.26.6/drivers/i2c/busses/i2c-sis630.c 2008-10-11 21:54:20.000000000 -0400
14921 +@@ -465,7 +465,7 @@ static struct i2c_adapter sis630_adapter
14922 + static struct pci_device_id sis630_ids[] __devinitdata = {
14923 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
14924 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
14925 +- { 0, }
14926 ++ { 0, 0, 0, 0, 0, 0, 0 }
14927 + };
14928 +
14929 + MODULE_DEVICE_TABLE (pci, sis630_ids);
14930 +diff -urNp linux-2.6.26.6/drivers/i2c/busses/i2c-sis96x.c linux-2.6.26.6/drivers/i2c/busses/i2c-sis96x.c
14931 +--- linux-2.6.26.6/drivers/i2c/busses/i2c-sis96x.c 2008-10-08 23:24:05.000000000 -0400
14932 ++++ linux-2.6.26.6/drivers/i2c/busses/i2c-sis96x.c 2008-10-11 21:54:20.000000000 -0400
14933 +@@ -255,7 +255,7 @@ static struct i2c_adapter sis96x_adapter
14934 +
14935 + static struct pci_device_id sis96x_ids[] = {
14936 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
14937 +- { 0, }
14938 ++ { 0, 0, 0, 0, 0, 0, 0 }
14939 + };
14940 +
14941 + MODULE_DEVICE_TABLE (pci, sis96x_ids);
14942 +diff -urNp linux-2.6.26.6/drivers/ieee1394/dv1394.c linux-2.6.26.6/drivers/ieee1394/dv1394.c
14943 +--- linux-2.6.26.6/drivers/ieee1394/dv1394.c 2008-10-08 23:24:05.000000000 -0400
14944 ++++ linux-2.6.26.6/drivers/ieee1394/dv1394.c 2008-10-11 21:54:20.000000000 -0400
14945 +@@ -739,7 +739,7 @@ static void frame_prepare(struct video_c
14946 + based upon DIF section and sequence
14947 + */
14948 +
14949 +-static void inline
14950 ++static inline void
14951 + frame_put_packet (struct frame *f, struct packet *p)
14952 + {
14953 + int section_type = p->data[0] >> 5; /* section type is in bits 5 - 7 */
14954 +@@ -918,7 +918,7 @@ static int do_dv1394_init(struct video_c
14955 + /* default SYT offset is 3 cycles */
14956 + init->syt_offset = 3;
14957 +
14958 +- if ( (init->channel > 63) || (init->channel < 0) )
14959 ++ if (init->channel > 63)
14960 + init->channel = 63;
14961 +
14962 + chan_mask = (u64)1 << init->channel;
14963 +@@ -2174,7 +2174,7 @@ static struct ieee1394_device_id dv1394_
14964 + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
14965 + .version = AVC_SW_VERSION_ENTRY & 0xffffff
14966 + },
14967 +- { }
14968 ++ { 0, 0, 0, 0, 0, 0 }
14969 + };
14970 +
14971 + MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
14972 +diff -urNp linux-2.6.26.6/drivers/ieee1394/eth1394.c linux-2.6.26.6/drivers/ieee1394/eth1394.c
14973 +--- linux-2.6.26.6/drivers/ieee1394/eth1394.c 2008-10-08 23:24:05.000000000 -0400
14974 ++++ linux-2.6.26.6/drivers/ieee1394/eth1394.c 2008-10-11 21:54:20.000000000 -0400
14975 +@@ -451,7 +451,7 @@ static struct ieee1394_device_id eth1394
14976 + .specifier_id = ETHER1394_GASP_SPECIFIER_ID,
14977 + .version = ETHER1394_GASP_VERSION,
14978 + },
14979 +- {}
14980 ++ { 0, 0, 0, 0, 0, 0 }
14981 + };
14982 +
14983 + MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
14984 +diff -urNp linux-2.6.26.6/drivers/ieee1394/hosts.c linux-2.6.26.6/drivers/ieee1394/hosts.c
14985 +--- linux-2.6.26.6/drivers/ieee1394/hosts.c 2008-10-08 23:24:05.000000000 -0400
14986 ++++ linux-2.6.26.6/drivers/ieee1394/hosts.c 2008-10-11 21:54:20.000000000 -0400
14987 +@@ -78,6 +78,7 @@ static int dummy_isoctl(struct hpsb_iso
14988 + }
14989 +
14990 + static struct hpsb_host_driver dummy_driver = {
14991 ++ .name = "dummy",
14992 + .transmit_packet = dummy_transmit_packet,
14993 + .devctl = dummy_devctl,
14994 + .isoctl = dummy_isoctl
14995 +diff -urNp linux-2.6.26.6/drivers/ieee1394/ohci1394.c linux-2.6.26.6/drivers/ieee1394/ohci1394.c
14996 +--- linux-2.6.26.6/drivers/ieee1394/ohci1394.c 2008-10-08 23:24:05.000000000 -0400
14997 ++++ linux-2.6.26.6/drivers/ieee1394/ohci1394.c 2008-10-11 21:54:20.000000000 -0400
14998 +@@ -147,9 +147,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
14999 + printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
15000 +
15001 + /* Module Parameters */
15002 +-static int phys_dma = 1;
15003 ++static int phys_dma;
15004 + module_param(phys_dma, int, 0444);
15005 +-MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 1).");
15006 ++MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 0).");
15007 +
15008 + static void dma_trm_tasklet(unsigned long data);
15009 + static void dma_trm_reset(struct dma_trm_ctx *d);
15010 +@@ -3437,7 +3437,7 @@ static struct pci_device_id ohci1394_pci
15011 + .subvendor = PCI_ANY_ID,
15012 + .subdevice = PCI_ANY_ID,
15013 + },
15014 +- { 0, },
15015 ++ { 0, 0, 0, 0, 0, 0, 0 },
15016 + };
15017 +
15018 + MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
15019 +diff -urNp linux-2.6.26.6/drivers/ieee1394/raw1394.c linux-2.6.26.6/drivers/ieee1394/raw1394.c
15020 +--- linux-2.6.26.6/drivers/ieee1394/raw1394.c 2008-10-08 23:24:05.000000000 -0400
15021 ++++ linux-2.6.26.6/drivers/ieee1394/raw1394.c 2008-10-11 21:54:20.000000000 -0400
15022 +@@ -2958,7 +2958,7 @@ static struct ieee1394_device_id raw1394
15023 + .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
15024 + .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
15025 + .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff},
15026 +- {}
15027 ++ { 0, 0, 0, 0, 0, 0 }
15028 + };
15029 +
15030 + MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
15031 +diff -urNp linux-2.6.26.6/drivers/ieee1394/sbp2.c linux-2.6.26.6/drivers/ieee1394/sbp2.c
15032 +--- linux-2.6.26.6/drivers/ieee1394/sbp2.c 2008-10-08 23:24:05.000000000 -0400
15033 ++++ linux-2.6.26.6/drivers/ieee1394/sbp2.c 2008-10-11 21:54:20.000000000 -0400
15034 +@@ -283,7 +283,7 @@ static struct ieee1394_device_id sbp2_id
15035 + .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
15036 + .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
15037 + .version = SBP2_SW_VERSION_ENTRY & 0xffffff},
15038 +- {}
15039 ++ { 0, 0, 0, 0, 0, 0 }
15040 + };
15041 + MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
15042 +
15043 +@@ -2101,7 +2101,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot
15044 + MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
15045 + MODULE_LICENSE("GPL");
15046 +
15047 +-static int sbp2_module_init(void)
15048 ++static int __init sbp2_module_init(void)
15049 + {
15050 + int ret;
15051 +
15052 +diff -urNp linux-2.6.26.6/drivers/ieee1394/video1394.c linux-2.6.26.6/drivers/ieee1394/video1394.c
15053 +--- linux-2.6.26.6/drivers/ieee1394/video1394.c 2008-10-08 23:24:05.000000000 -0400
15054 ++++ linux-2.6.26.6/drivers/ieee1394/video1394.c 2008-10-11 21:54:20.000000000 -0400
15055 +@@ -893,7 +893,7 @@ static long video1394_ioctl(struct file
15056 + if (unlikely(d == NULL))
15057 + return -EFAULT;
15058 +
15059 +- if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) {
15060 ++ if (unlikely(v.buffer>=d->num_desc - 1)) {
15061 + PRINT(KERN_ERR, ohci->host->id,
15062 + "Buffer %d out of range",v.buffer);
15063 + return -EINVAL;
15064 +@@ -959,7 +959,7 @@ static long video1394_ioctl(struct file
15065 + if (unlikely(d == NULL))
15066 + return -EFAULT;
15067 +
15068 +- if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) {
15069 ++ if (unlikely(v.buffer>d->num_desc - 1)) {
15070 + PRINT(KERN_ERR, ohci->host->id,
15071 + "Buffer %d out of range",v.buffer);
15072 + return -EINVAL;
15073 +@@ -1030,7 +1030,7 @@ static long video1394_ioctl(struct file
15074 + d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
15075 + if (d == NULL) return -EFAULT;
15076 +
15077 +- if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
15078 ++ if (v.buffer>=d->num_desc - 1) {
15079 + PRINT(KERN_ERR, ohci->host->id,
15080 + "Buffer %d out of range",v.buffer);
15081 + return -EINVAL;
15082 +@@ -1137,7 +1137,7 @@ static long video1394_ioctl(struct file
15083 + d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
15084 + if (d == NULL) return -EFAULT;
15085 +
15086 +- if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
15087 ++ if (v.buffer>=d->num_desc-1) {
15088 + PRINT(KERN_ERR, ohci->host->id,
15089 + "Buffer %d out of range",v.buffer);
15090 + return -EINVAL;
15091 +@@ -1310,7 +1310,7 @@ static struct ieee1394_device_id video13
15092 + .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
15093 + .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff
15094 + },
15095 +- { }
15096 ++ { 0, 0, 0, 0, 0, 0 }
15097 + };
15098 +
15099 + MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
15100 +diff -urNp linux-2.6.26.6/drivers/input/keyboard/atkbd.c linux-2.6.26.6/drivers/input/keyboard/atkbd.c
15101 +--- linux-2.6.26.6/drivers/input/keyboard/atkbd.c 2008-10-08 23:24:05.000000000 -0400
15102 ++++ linux-2.6.26.6/drivers/input/keyboard/atkbd.c 2008-10-11 21:54:20.000000000 -0400
15103 +@@ -1115,7 +1115,7 @@ static struct serio_device_id atkbd_seri
15104 + .id = SERIO_ANY,
15105 + .extra = SERIO_ANY,
15106 + },
15107 +- { 0 }
15108 ++ { 0, 0, 0, 0 }
15109 + };
15110 +
15111 + MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
15112 +diff -urNp linux-2.6.26.6/drivers/input/mouse/lifebook.c linux-2.6.26.6/drivers/input/mouse/lifebook.c
15113 +--- linux-2.6.26.6/drivers/input/mouse/lifebook.c 2008-10-08 23:24:05.000000000 -0400
15114 ++++ linux-2.6.26.6/drivers/input/mouse/lifebook.c 2008-10-11 21:54:20.000000000 -0400
15115 +@@ -110,7 +110,7 @@ static const struct dmi_system_id lifebo
15116 + DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
15117 + },
15118 + },
15119 +- { }
15120 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
15121 + };
15122 +
15123 + static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
15124 +diff -urNp linux-2.6.26.6/drivers/input/mouse/psmouse-base.c linux-2.6.26.6/drivers/input/mouse/psmouse-base.c
15125 +--- linux-2.6.26.6/drivers/input/mouse/psmouse-base.c 2008-10-08 23:24:05.000000000 -0400
15126 ++++ linux-2.6.26.6/drivers/input/mouse/psmouse-base.c 2008-10-11 21:54:20.000000000 -0400
15127 +@@ -1328,7 +1328,7 @@ static struct serio_device_id psmouse_se
15128 + .id = SERIO_ANY,
15129 + .extra = SERIO_ANY,
15130 + },
15131 +- { 0 }
15132 ++ { 0, 0, 0, 0 }
15133 + };
15134 +
15135 + MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
15136 +diff -urNp linux-2.6.26.6/drivers/input/mouse/synaptics.c linux-2.6.26.6/drivers/input/mouse/synaptics.c
15137 +--- linux-2.6.26.6/drivers/input/mouse/synaptics.c 2008-10-08 23:24:05.000000000 -0400
15138 ++++ linux-2.6.26.6/drivers/input/mouse/synaptics.c 2008-10-11 21:54:20.000000000 -0400
15139 +@@ -417,7 +417,7 @@ static void synaptics_process_packet(str
15140 + break;
15141 + case 2:
15142 + if (SYN_MODEL_PEN(priv->model_id))
15143 +- ; /* Nothing, treat a pen as a single finger */
15144 ++ break; /* Nothing, treat a pen as a single finger */
15145 + break;
15146 + case 4 ... 15:
15147 + if (SYN_CAP_PALMDETECT(priv->capabilities))
15148 +@@ -624,7 +624,7 @@ static const struct dmi_system_id toshib
15149 + DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
15150 + },
15151 + },
15152 +- { }
15153 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
15154 + };
15155 + #endif
15156 +
15157 +diff -urNp linux-2.6.26.6/drivers/input/mousedev.c linux-2.6.26.6/drivers/input/mousedev.c
15158 +--- linux-2.6.26.6/drivers/input/mousedev.c 2008-10-08 23:24:05.000000000 -0400
15159 ++++ linux-2.6.26.6/drivers/input/mousedev.c 2008-10-11 21:54:20.000000000 -0400
15160 +@@ -1056,7 +1056,7 @@ static struct input_handler mousedev_han
15161 +
15162 + #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
15163 + static struct miscdevice psaux_mouse = {
15164 +- PSMOUSE_MINOR, "psaux", &mousedev_fops
15165 ++ PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL
15166 + };
15167 + static int psaux_registered;
15168 + #endif
15169 +diff -urNp linux-2.6.26.6/drivers/input/serio/i8042-x86ia64io.h linux-2.6.26.6/drivers/input/serio/i8042-x86ia64io.h
15170 +--- linux-2.6.26.6/drivers/input/serio/i8042-x86ia64io.h 2008-10-08 23:24:05.000000000 -0400
15171 ++++ linux-2.6.26.6/drivers/input/serio/i8042-x86ia64io.h 2008-10-11 21:54:20.000000000 -0400
15172 +@@ -118,7 +118,7 @@ static struct dmi_system_id __initdata i
15173 + DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"),
15174 + },
15175 + },
15176 +- { }
15177 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
15178 + };
15179 +
15180 + /*
15181 +@@ -298,7 +298,7 @@ static struct dmi_system_id __initdata i
15182 + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"),
15183 + },
15184 + },
15185 +- { }
15186 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
15187 + };
15188 +
15189 + #ifdef CONFIG_PNP
15190 +@@ -317,7 +317,7 @@ static struct dmi_system_id __initdata i
15191 + DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"),
15192 + },
15193 + },
15194 +- { }
15195 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
15196 + };
15197 + #endif
15198 +
15199 +diff -urNp linux-2.6.26.6/drivers/input/serio/serio_raw.c linux-2.6.26.6/drivers/input/serio/serio_raw.c
15200 +--- linux-2.6.26.6/drivers/input/serio/serio_raw.c 2008-10-08 23:24:05.000000000 -0400
15201 ++++ linux-2.6.26.6/drivers/input/serio/serio_raw.c 2008-10-11 21:54:20.000000000 -0400
15202 +@@ -369,7 +369,7 @@ static struct serio_device_id serio_raw_
15203 + .id = SERIO_ANY,
15204 + .extra = SERIO_ANY,
15205 + },
15206 +- { 0 }
15207 ++ { 0, 0, 0, 0 }
15208 + };
15209 +
15210 + MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
15211 +diff -urNp linux-2.6.26.6/drivers/md/bitmap.c linux-2.6.26.6/drivers/md/bitmap.c
15212 +--- linux-2.6.26.6/drivers/md/bitmap.c 2008-10-08 23:24:05.000000000 -0400
15213 ++++ linux-2.6.26.6/drivers/md/bitmap.c 2008-10-11 21:54:20.000000000 -0400
15214 +@@ -57,7 +57,7 @@
15215 + # if DEBUG > 0
15216 + # define PRINTK(x...) printk(KERN_DEBUG x)
15217 + # else
15218 +-# define PRINTK(x...)
15219 ++# define PRINTK(x...) do {} while (0)
15220 + # endif
15221 + #endif
15222 +
15223 +diff -urNp linux-2.6.26.6/drivers/mtd/devices/doc2000.c linux-2.6.26.6/drivers/mtd/devices/doc2000.c
15224 +--- linux-2.6.26.6/drivers/mtd/devices/doc2000.c 2008-10-08 23:24:05.000000000 -0400
15225 ++++ linux-2.6.26.6/drivers/mtd/devices/doc2000.c 2008-10-11 21:54:20.000000000 -0400
15226 +@@ -779,7 +779,7 @@ static int doc_write(struct mtd_info *mt
15227 +
15228 + /* The ECC will not be calculated correctly if less than 512 is written */
15229 + /* DBB-
15230 +- if (len != 0x200 && eccbuf)
15231 ++ if (len != 0x200)
15232 + printk(KERN_WARNING
15233 + "ECC needs a full sector write (adr: %lx size %lx)\n",
15234 + (long) to, (long) len);
15235 +diff -urNp linux-2.6.26.6/drivers/mtd/devices/doc2001.c linux-2.6.26.6/drivers/mtd/devices/doc2001.c
15236 +--- linux-2.6.26.6/drivers/mtd/devices/doc2001.c 2008-10-08 23:24:05.000000000 -0400
15237 ++++ linux-2.6.26.6/drivers/mtd/devices/doc2001.c 2008-10-11 21:54:20.000000000 -0400
15238 +@@ -398,6 +398,8 @@ static int doc_read (struct mtd_info *mt
15239 + /* Don't allow read past end of device */
15240 + if (from >= this->totlen)
15241 + return -EINVAL;
15242 ++ if (!len)
15243 ++ return -EINVAL;
15244 +
15245 + /* Don't allow a single read to cross a 512-byte block boundary */
15246 + if (from + len > ((from | 0x1ff) + 1))
15247 +diff -urNp linux-2.6.26.6/drivers/mtd/devices/slram.c linux-2.6.26.6/drivers/mtd/devices/slram.c
15248 +--- linux-2.6.26.6/drivers/mtd/devices/slram.c 2008-10-08 23:24:05.000000000 -0400
15249 ++++ linux-2.6.26.6/drivers/mtd/devices/slram.c 2008-10-11 21:54:20.000000000 -0400
15250 +@@ -275,7 +275,7 @@ static int parse_cmdline(char *devname,
15251 + }
15252 + T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n",
15253 + devname, devstart, devlength);
15254 +- if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) {
15255 ++ if (devlength % SLRAM_BLK_SZ != 0) {
15256 + E("slram: Illegal start / length parameter.\n");
15257 + return(-EINVAL);
15258 + }
15259 +diff -urNp linux-2.6.26.6/drivers/mtd/ubi/build.c linux-2.6.26.6/drivers/mtd/ubi/build.c
15260 +--- linux-2.6.26.6/drivers/mtd/ubi/build.c 2008-10-08 23:24:05.000000000 -0400
15261 ++++ linux-2.6.26.6/drivers/mtd/ubi/build.c 2008-10-11 21:54:20.000000000 -0400
15262 +@@ -1057,7 +1057,7 @@ static int __init bytes_str_to_int(const
15263 + unsigned long result;
15264 +
15265 + result = simple_strtoul(str, &endp, 0);
15266 +- if (str == endp || result < 0) {
15267 ++ if (str == endp) {
15268 + printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n",
15269 + str);
15270 + return -EINVAL;
15271 +diff -urNp linux-2.6.26.6/drivers/net/eepro100.c linux-2.6.26.6/drivers/net/eepro100.c
15272 +--- linux-2.6.26.6/drivers/net/eepro100.c 2008-10-08 23:24:05.000000000 -0400
15273 ++++ linux-2.6.26.6/drivers/net/eepro100.c 2008-10-11 21:54:20.000000000 -0400
15274 +@@ -47,7 +47,7 @@ static int rxdmacount /* = 0 */;
15275 + # define rx_align(skb) skb_reserve((skb), 2)
15276 + # define RxFD_ALIGNMENT __attribute__ ((aligned (2), packed))
15277 + #else
15278 +-# define rx_align(skb)
15279 ++# define rx_align(skb) do {} while (0)
15280 + # define RxFD_ALIGNMENT
15281 + #endif
15282 +
15283 +@@ -2334,33 +2334,33 @@ static void __devexit eepro100_remove_on
15284 + }
15285 +
15286 + static struct pci_device_id eepro100_pci_tbl[] = {
15287 +- { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, },
15288 +- { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, },
15289 +- { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, },
15290 +- { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, },
15291 +- { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, },
15292 +- { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, },
15293 +- { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, },
15294 +- { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, },
15295 +- { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, },
15296 +- { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, },
15297 +- { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, },
15298 +- { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, },
15299 +- { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, },
15300 +- { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, },
15301 +- { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, },
15302 +- { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, },
15303 +- { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, },
15304 +- { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, },
15305 +- { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, },
15306 +- { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, },
15307 +- { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
15308 +- { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, },
15309 +- { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, },
15310 +- { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, },
15311 +- { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, },
15312 +- { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, },
15313 +- { 0,}
15314 ++ { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15315 ++ { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15316 ++ { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15317 ++ { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15318 ++ { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15319 ++ { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15320 ++ { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15321 ++ { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15322 ++ { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15323 ++ { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15324 ++ { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15325 ++ { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15326 ++ { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15327 ++ { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15328 ++ { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15329 ++ { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15330 ++ { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15331 ++ { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15332 ++ { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15333 ++ { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15334 ++ { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15335 ++ { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15336 ++ { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15337 ++ { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15338 ++ { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15339 ++ { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15340 ++ { 0, 0, 0, 0, 0, 0, 0 }
15341 + };
15342 + MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
15343 +
15344 +diff -urNp linux-2.6.26.6/drivers/net/irda/vlsi_ir.c linux-2.6.26.6/drivers/net/irda/vlsi_ir.c
15345 +--- linux-2.6.26.6/drivers/net/irda/vlsi_ir.c 2008-10-08 23:24:05.000000000 -0400
15346 ++++ linux-2.6.26.6/drivers/net/irda/vlsi_ir.c 2008-10-11 21:54:20.000000000 -0400
15347 +@@ -906,13 +906,12 @@ static int vlsi_hard_start_xmit(struct s
15348 + /* no race - tx-ring already empty */
15349 + vlsi_set_baud(idev, iobase);
15350 + netif_wake_queue(ndev);
15351 +- }
15352 +- else
15353 +- ;
15354 ++ } else {
15355 + /* keep the speed change pending like it would
15356 + * for any len>0 packet. tx completion interrupt
15357 + * will apply it when the tx ring becomes empty.
15358 + */
15359 ++ }
15360 + spin_unlock_irqrestore(&idev->lock, flags);
15361 + dev_kfree_skb_any(skb);
15362 + return 0;
15363 +diff -urNp linux-2.6.26.6/drivers/net/pcnet32.c linux-2.6.26.6/drivers/net/pcnet32.c
15364 +--- linux-2.6.26.6/drivers/net/pcnet32.c 2008-10-08 23:24:05.000000000 -0400
15365 ++++ linux-2.6.26.6/drivers/net/pcnet32.c 2008-10-11 21:54:20.000000000 -0400
15366 +@@ -78,7 +78,7 @@ static int cards_found;
15367 + /*
15368 + * VLB I/O addresses
15369 + */
15370 +-static unsigned int pcnet32_portlist[] __initdata =
15371 ++static unsigned int pcnet32_portlist[] __devinitdata =
15372 + { 0x300, 0x320, 0x340, 0x360, 0 };
15373 +
15374 + static int pcnet32_debug = 0;
15375 +diff -urNp linux-2.6.26.6/drivers/net/tg3.h linux-2.6.26.6/drivers/net/tg3.h
15376 +--- linux-2.6.26.6/drivers/net/tg3.h 2008-10-08 23:24:05.000000000 -0400
15377 ++++ linux-2.6.26.6/drivers/net/tg3.h 2008-10-11 21:54:20.000000000 -0400
15378 +@@ -102,6 +102,7 @@
15379 + #define CHIPREV_ID_5750_A0 0x4000
15380 + #define CHIPREV_ID_5750_A1 0x4001
15381 + #define CHIPREV_ID_5750_A3 0x4003
15382 ++#define CHIPREV_ID_5750_C1 0x4201
15383 + #define CHIPREV_ID_5750_C2 0x4202
15384 + #define CHIPREV_ID_5752_A0_HW 0x5000
15385 + #define CHIPREV_ID_5752_A0 0x6000
15386 +diff -urNp linux-2.6.26.6/drivers/pci/hotplug/cpqphp_nvram.c linux-2.6.26.6/drivers/pci/hotplug/cpqphp_nvram.c
15387 +--- linux-2.6.26.6/drivers/pci/hotplug/cpqphp_nvram.c 2008-10-08 23:24:05.000000000 -0400
15388 ++++ linux-2.6.26.6/drivers/pci/hotplug/cpqphp_nvram.c 2008-10-11 21:54:20.000000000 -0400
15389 +@@ -425,9 +425,13 @@ static u32 store_HRT (void __iomem *rom_
15390 +
15391 + void compaq_nvram_init (void __iomem *rom_start)
15392 + {
15393 ++
15394 ++#ifndef CONFIG_PAX_KERNEXEC
15395 + if (rom_start) {
15396 + compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
15397 + }
15398 ++#endif
15399 ++
15400 + dbg("int15 entry = %p\n", compaq_int15_entry_point);
15401 +
15402 + /* initialize our int15 lock */
15403 +diff -urNp linux-2.6.26.6/drivers/pci/pcie/aer/aerdrv.c linux-2.6.26.6/drivers/pci/pcie/aer/aerdrv.c
15404 +--- linux-2.6.26.6/drivers/pci/pcie/aer/aerdrv.c 2008-10-08 23:24:05.000000000 -0400
15405 ++++ linux-2.6.26.6/drivers/pci/pcie/aer/aerdrv.c 2008-10-11 21:54:20.000000000 -0400
15406 +@@ -58,7 +58,7 @@ static struct pcie_port_service_id aer_i
15407 + .port_type = PCIE_RC_PORT,
15408 + .service_type = PCIE_PORT_SERVICE_AER,
15409 + },
15410 +- { /* end: all zeroes */ }
15411 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
15412 + };
15413 +
15414 + static struct pci_error_handlers aer_error_handlers = {
15415 +diff -urNp linux-2.6.26.6/drivers/pci/pcie/aer/aerdrv_core.c linux-2.6.26.6/drivers/pci/pcie/aer/aerdrv_core.c
15416 +--- linux-2.6.26.6/drivers/pci/pcie/aer/aerdrv_core.c 2008-10-08 23:24:05.000000000 -0400
15417 ++++ linux-2.6.26.6/drivers/pci/pcie/aer/aerdrv_core.c 2008-10-11 21:54:20.000000000 -0400
15418 +@@ -663,7 +663,7 @@ static void aer_isr_one_error(struct pci
15419 + struct aer_err_source *e_src)
15420 + {
15421 + struct device *s_device;
15422 +- struct aer_err_info e_info = {0, 0, 0,};
15423 ++ struct aer_err_info e_info = {0, 0, 0, {0, 0, 0, 0}};
15424 + int i;
15425 + u16 id;
15426 +
15427 +diff -urNp linux-2.6.26.6/drivers/pci/pcie/portdrv_pci.c linux-2.6.26.6/drivers/pci/pcie/portdrv_pci.c
15428 +--- linux-2.6.26.6/drivers/pci/pcie/portdrv_pci.c 2008-10-08 23:24:05.000000000 -0400
15429 ++++ linux-2.6.26.6/drivers/pci/pcie/portdrv_pci.c 2008-10-11 21:54:20.000000000 -0400
15430 +@@ -265,7 +265,7 @@ static void pcie_portdrv_err_resume(stru
15431 + static const struct pci_device_id port_pci_ids[] = { {
15432 + /* handle any PCI-Express port */
15433 + PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
15434 +- }, { /* end: all zeroes */ }
15435 ++ }, { 0, 0, 0, 0, 0, 0, 0 }
15436 + };
15437 + MODULE_DEVICE_TABLE(pci, port_pci_ids);
15438 +
15439 +diff -urNp linux-2.6.26.6/drivers/pci/proc.c linux-2.6.26.6/drivers/pci/proc.c
15440 +--- linux-2.6.26.6/drivers/pci/proc.c 2008-10-08 23:24:05.000000000 -0400
15441 ++++ linux-2.6.26.6/drivers/pci/proc.c 2008-10-11 21:54:20.000000000 -0400
15442 +@@ -472,7 +472,16 @@ static const struct file_operations proc
15443 + static int __init pci_proc_init(void)
15444 + {
15445 + struct pci_dev *dev = NULL;
15446 ++
15447 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
15448 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
15449 ++ proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR, NULL);
15450 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
15451 ++ proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
15452 ++#endif
15453 ++#else
15454 + proc_bus_pci_dir = proc_mkdir("bus/pci", NULL);
15455 ++#endif
15456 + proc_create("devices", 0, proc_bus_pci_dir,
15457 + &proc_bus_pci_dev_operations);
15458 + proc_initialized = 1;
15459 +diff -urNp linux-2.6.26.6/drivers/pcmcia/ti113x.h linux-2.6.26.6/drivers/pcmcia/ti113x.h
15460 +--- linux-2.6.26.6/drivers/pcmcia/ti113x.h 2008-10-08 23:24:05.000000000 -0400
15461 ++++ linux-2.6.26.6/drivers/pcmcia/ti113x.h 2008-10-11 21:54:20.000000000 -0400
15462 +@@ -897,7 +897,7 @@ static struct pci_device_id ene_tune_tbl
15463 + DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
15464 + ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
15465 +
15466 +- {}
15467 ++ { 0, 0, 0, 0, 0, 0, 0 }
15468 + };
15469 +
15470 + static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
15471 +diff -urNp linux-2.6.26.6/drivers/pcmcia/yenta_socket.c linux-2.6.26.6/drivers/pcmcia/yenta_socket.c
15472 +--- linux-2.6.26.6/drivers/pcmcia/yenta_socket.c 2008-10-08 23:24:05.000000000 -0400
15473 ++++ linux-2.6.26.6/drivers/pcmcia/yenta_socket.c 2008-10-11 21:54:20.000000000 -0400
15474 +@@ -1358,7 +1358,7 @@ static struct pci_device_id yenta_table
15475 +
15476 + /* match any cardbus bridge */
15477 + CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
15478 +- { /* all zeroes */ }
15479 ++ { 0, 0, 0, 0, 0, 0, 0 }
15480 + };
15481 + MODULE_DEVICE_TABLE(pci, yenta_table);
15482 +
15483 +diff -urNp linux-2.6.26.6/drivers/pnp/pnpbios/bioscalls.c linux-2.6.26.6/drivers/pnp/pnpbios/bioscalls.c
15484 +--- linux-2.6.26.6/drivers/pnp/pnpbios/bioscalls.c 2008-10-08 23:24:05.000000000 -0400
15485 ++++ linux-2.6.26.6/drivers/pnp/pnpbios/bioscalls.c 2008-10-11 21:54:20.000000000 -0400
15486 +@@ -60,7 +60,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
15487 + set_limit(gdt[(selname) >> 3], size); \
15488 + } while(0)
15489 +
15490 +-static struct desc_struct bad_bios_desc;
15491 ++static struct desc_struct bad_bios_desc __read_only;
15492 +
15493 + /*
15494 + * At some point we want to use this stack frame pointer to unwind
15495 +@@ -87,6 +87,10 @@ static inline u16 call_pnp_bios(u16 func
15496 + struct desc_struct save_desc_40;
15497 + int cpu;
15498 +
15499 ++#ifdef CONFIG_PAX_KERNEXEC
15500 ++ unsigned long cr0;
15501 ++#endif
15502 ++
15503 + /*
15504 + * PnP BIOSes are generally not terribly re-entrant.
15505 + * Also, don't rely on them to save everything correctly.
15506 +@@ -96,8 +100,17 @@ static inline u16 call_pnp_bios(u16 func
15507 +
15508 + cpu = get_cpu();
15509 + save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
15510 ++
15511 ++#ifdef CONFIG_PAX_KERNEXEC
15512 ++ pax_open_kernel(cr0);
15513 ++#endif
15514 ++
15515 + get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
15516 +
15517 ++#ifdef CONFIG_PAX_KERNEXEC
15518 ++ pax_close_kernel(cr0);
15519 ++#endif
15520 ++
15521 + /* On some boxes IRQ's during PnP BIOS calls are deadly. */
15522 + spin_lock_irqsave(&pnp_bios_lock, flags);
15523 +
15524 +@@ -134,7 +147,16 @@ static inline u16 call_pnp_bios(u16 func
15525 + :"memory");
15526 + spin_unlock_irqrestore(&pnp_bios_lock, flags);
15527 +
15528 ++#ifdef CONFIG_PAX_KERNEXEC
15529 ++ pax_open_kernel(cr0);
15530 ++#endif
15531 ++
15532 + get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
15533 ++
15534 ++#ifdef CONFIG_PAX_KERNEXEC
15535 ++ pax_close_kernel(cr0);
15536 ++#endif
15537 ++
15538 + put_cpu();
15539 +
15540 + /* If we get here and this is set then the PnP BIOS faulted on us. */
15541 +@@ -468,16 +490,24 @@ int pnp_bios_read_escd(char *data, u32 n
15542 + return status;
15543 + }
15544 +
15545 +-void pnpbios_calls_init(union pnp_bios_install_struct *header)
15546 ++void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
15547 + {
15548 + int i;
15549 +
15550 ++#ifdef CONFIG_PAX_KERNEXEC
15551 ++ unsigned long cr0;
15552 ++#endif
15553 ++
15554 + spin_lock_init(&pnp_bios_lock);
15555 + pnp_bios_callpoint.offset = header->fields.pm16offset;
15556 + pnp_bios_callpoint.segment = PNP_CS16;
15557 +
15558 ++#ifdef CONFIG_PAX_KERNEXEC
15559 ++ pax_open_kernel(cr0);
15560 ++#endif
15561 ++
15562 + bad_bios_desc.a = 0;
15563 +- bad_bios_desc.b = 0x00409200;
15564 ++ bad_bios_desc.b = 0x00409300;
15565 +
15566 + set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
15567 + _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
15568 +@@ -491,4 +521,9 @@ void pnpbios_calls_init(union pnp_bios_i
15569 + set_base(gdt[GDT_ENTRY_PNPBIOS_DS],
15570 + __va(header->fields.pm16dseg));
15571 + }
15572 ++
15573 ++#ifdef CONFIG_PAX_KERNEXEC
15574 ++ pax_close_kernel(cr0);
15575 ++#endif
15576 ++
15577 + }
15578 +diff -urNp linux-2.6.26.6/drivers/pnp/quirks.c linux-2.6.26.6/drivers/pnp/quirks.c
15579 +--- linux-2.6.26.6/drivers/pnp/quirks.c 2008-10-08 23:24:05.000000000 -0400
15580 ++++ linux-2.6.26.6/drivers/pnp/quirks.c 2008-10-11 21:54:20.000000000 -0400
15581 +@@ -319,7 +319,7 @@ static struct pnp_fixup pnp_fixups[] = {
15582 + /* PnP resources that might overlap PCI BARs */
15583 + {"PNP0c01", quirk_system_pci_resources},
15584 + {"PNP0c02", quirk_system_pci_resources},
15585 +- {""}
15586 ++ {"", NULL}
15587 + };
15588 +
15589 + void pnp_fixup_device(struct pnp_dev *dev)
15590 +diff -urNp linux-2.6.26.6/drivers/pnp/resource.c linux-2.6.26.6/drivers/pnp/resource.c
15591 +--- linux-2.6.26.6/drivers/pnp/resource.c 2008-10-08 23:24:05.000000000 -0400
15592 ++++ linux-2.6.26.6/drivers/pnp/resource.c 2008-10-11 21:54:20.000000000 -0400
15593 +@@ -378,7 +378,7 @@ int pnp_check_irq(struct pnp_dev *dev, s
15594 + return 1;
15595 +
15596 + /* check if the resource is valid */
15597 +- if (*irq < 0 || *irq > 15)
15598 ++ if (*irq > 15)
15599 + return 0;
15600 +
15601 + /* check if the resource is reserved */
15602 +@@ -451,7 +451,7 @@ int pnp_check_dma(struct pnp_dev *dev, s
15603 + return 1;
15604 +
15605 + /* check if the resource is valid */
15606 +- if (*dma < 0 || *dma == 4 || *dma > 7)
15607 ++ if (*dma == 4 || *dma > 7)
15608 + return 0;
15609 +
15610 + /* check if the resource is reserved */
15611 +diff -urNp linux-2.6.26.6/drivers/scsi/scsi_logging.h linux-2.6.26.6/drivers/scsi/scsi_logging.h
15612 +--- linux-2.6.26.6/drivers/scsi/scsi_logging.h 2008-10-08 23:24:05.000000000 -0400
15613 ++++ linux-2.6.26.6/drivers/scsi/scsi_logging.h 2008-10-11 21:54:20.000000000 -0400
15614 +@@ -51,7 +51,7 @@ do { \
15615 + } while (0); \
15616 + } while (0)
15617 + #else
15618 +-#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
15619 ++#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
15620 + #endif /* CONFIG_SCSI_LOGGING */
15621 +
15622 + /*
15623 +diff -urNp linux-2.6.26.6/drivers/serial/8250_pci.c linux-2.6.26.6/drivers/serial/8250_pci.c
15624 +--- linux-2.6.26.6/drivers/serial/8250_pci.c 2008-10-08 23:24:05.000000000 -0400
15625 ++++ linux-2.6.26.6/drivers/serial/8250_pci.c 2008-10-11 21:54:20.000000000 -0400
15626 +@@ -2844,7 +2844,7 @@ static struct pci_device_id serial_pci_t
15627 + PCI_ANY_ID, PCI_ANY_ID,
15628 + PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
15629 + 0xffff00, pbn_default },
15630 +- { 0, }
15631 ++ { 0, 0, 0, 0, 0, 0, 0 }
15632 + };
15633 +
15634 + static struct pci_driver serial_pci_driver = {
15635 +diff -urNp linux-2.6.26.6/drivers/usb/class/cdc-acm.c linux-2.6.26.6/drivers/usb/class/cdc-acm.c
15636 +--- linux-2.6.26.6/drivers/usb/class/cdc-acm.c 2008-10-08 23:24:05.000000000 -0400
15637 ++++ linux-2.6.26.6/drivers/usb/class/cdc-acm.c 2008-10-11 21:54:20.000000000 -0400
15638 +@@ -1264,7 +1264,7 @@ static struct usb_device_id acm_ids[] =
15639 + USB_CDC_ACM_PROTO_AT_CDMA) },
15640 +
15641 + /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */
15642 +- { }
15643 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
15644 + };
15645 +
15646 + MODULE_DEVICE_TABLE (usb, acm_ids);
15647 +diff -urNp linux-2.6.26.6/drivers/usb/class/usblp.c linux-2.6.26.6/drivers/usb/class/usblp.c
15648 +--- linux-2.6.26.6/drivers/usb/class/usblp.c 2008-10-08 23:24:05.000000000 -0400
15649 ++++ linux-2.6.26.6/drivers/usb/class/usblp.c 2008-10-11 21:54:20.000000000 -0400
15650 +@@ -227,7 +227,7 @@ static const struct quirk_printer_struct
15651 + { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
15652 + { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@×××.de> */
15653 + { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
15654 +- { 0, 0 }
15655 ++ { 0, 0, 0 }
15656 + };
15657 +
15658 + static int usblp_wwait(struct usblp *usblp, int nonblock);
15659 +@@ -1401,7 +1401,7 @@ static struct usb_device_id usblp_ids []
15660 + { USB_INTERFACE_INFO(7, 1, 2) },
15661 + { USB_INTERFACE_INFO(7, 1, 3) },
15662 + { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */
15663 +- { } /* Terminating entry */
15664 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
15665 + };
15666 +
15667 + MODULE_DEVICE_TABLE (usb, usblp_ids);
15668 +diff -urNp linux-2.6.26.6/drivers/usb/core/hub.c linux-2.6.26.6/drivers/usb/core/hub.c
15669 +--- linux-2.6.26.6/drivers/usb/core/hub.c 2008-10-08 23:24:05.000000000 -0400
15670 ++++ linux-2.6.26.6/drivers/usb/core/hub.c 2008-10-11 21:54:20.000000000 -0400
15671 +@@ -3045,7 +3045,7 @@ static struct usb_device_id hub_id_table
15672 + .bDeviceClass = USB_CLASS_HUB},
15673 + { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
15674 + .bInterfaceClass = USB_CLASS_HUB},
15675 +- { } /* Terminating entry */
15676 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
15677 + };
15678 +
15679 + MODULE_DEVICE_TABLE (usb, hub_id_table);
15680 +diff -urNp linux-2.6.26.6/drivers/usb/host/ehci-pci.c linux-2.6.26.6/drivers/usb/host/ehci-pci.c
15681 +--- linux-2.6.26.6/drivers/usb/host/ehci-pci.c 2008-10-08 23:24:05.000000000 -0400
15682 ++++ linux-2.6.26.6/drivers/usb/host/ehci-pci.c 2008-10-11 21:54:20.000000000 -0400
15683 +@@ -390,7 +390,7 @@ static const struct pci_device_id pci_id
15684 + PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
15685 + .driver_data = (unsigned long) &ehci_pci_hc_driver,
15686 + },
15687 +- { /* end: all zeroes */ }
15688 ++ { 0, 0, 0, 0, 0, 0, 0 }
15689 + };
15690 + MODULE_DEVICE_TABLE(pci, pci_ids);
15691 +
15692 +diff -urNp linux-2.6.26.6/drivers/usb/host/uhci-hcd.c linux-2.6.26.6/drivers/usb/host/uhci-hcd.c
15693 +--- linux-2.6.26.6/drivers/usb/host/uhci-hcd.c 2008-10-08 23:24:05.000000000 -0400
15694 ++++ linux-2.6.26.6/drivers/usb/host/uhci-hcd.c 2008-10-11 21:54:20.000000000 -0400
15695 +@@ -928,7 +928,7 @@ static const struct pci_device_id uhci_p
15696 + /* handle any USB UHCI controller */
15697 + PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),
15698 + .driver_data = (unsigned long) &uhci_driver,
15699 +- }, { /* end: all zeroes */ }
15700 ++ }, { 0, 0, 0, 0, 0, 0, 0 }
15701 + };
15702 +
15703 + MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
15704 +diff -urNp linux-2.6.26.6/drivers/usb/storage/debug.h linux-2.6.26.6/drivers/usb/storage/debug.h
15705 +--- linux-2.6.26.6/drivers/usb/storage/debug.h 2008-10-08 23:24:05.000000000 -0400
15706 ++++ linux-2.6.26.6/drivers/usb/storage/debug.h 2008-10-11 21:54:20.000000000 -0400
15707 +@@ -56,9 +56,9 @@ void usb_stor_show_sense( unsigned char
15708 + #define US_DEBUGPX(x...) printk( x )
15709 + #define US_DEBUG(x) x
15710 + #else
15711 +-#define US_DEBUGP(x...)
15712 +-#define US_DEBUGPX(x...)
15713 +-#define US_DEBUG(x)
15714 ++#define US_DEBUGP(x...) do {} while (0)
15715 ++#define US_DEBUGPX(x...) do {} while (0)
15716 ++#define US_DEBUG(x) do {} while (0)
15717 + #endif
15718 +
15719 + #endif
15720 +diff -urNp linux-2.6.26.6/drivers/usb/storage/usb.c linux-2.6.26.6/drivers/usb/storage/usb.c
15721 +--- linux-2.6.26.6/drivers/usb/storage/usb.c 2008-10-08 23:24:05.000000000 -0400
15722 ++++ linux-2.6.26.6/drivers/usb/storage/usb.c 2008-10-11 21:54:20.000000000 -0400
15723 +@@ -137,7 +137,7 @@ static struct usb_device_id storage_usb_
15724 + #undef UNUSUAL_DEV
15725 + #undef USUAL_DEV
15726 + /* Terminating entry */
15727 +- { }
15728 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
15729 + };
15730 +
15731 + MODULE_DEVICE_TABLE (usb, storage_usb_ids);
15732 +@@ -177,7 +177,7 @@ static struct us_unusual_dev us_unusual_
15733 + # undef USUAL_DEV
15734 +
15735 + /* Terminating entry */
15736 +- { NULL }
15737 ++ { NULL, NULL, 0, 0, NULL }
15738 + };
15739 +
15740 +
15741 +diff -urNp linux-2.6.26.6/drivers/video/fbcmap.c linux-2.6.26.6/drivers/video/fbcmap.c
15742 +--- linux-2.6.26.6/drivers/video/fbcmap.c 2008-10-08 23:24:05.000000000 -0400
15743 ++++ linux-2.6.26.6/drivers/video/fbcmap.c 2008-10-11 21:54:20.000000000 -0400
15744 +@@ -250,8 +250,7 @@ int fb_set_user_cmap(struct fb_cmap_user
15745 + int rc, size = cmap->len * sizeof(u16);
15746 + struct fb_cmap umap;
15747 +
15748 +- if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
15749 +- !info->fbops->fb_setcmap))
15750 ++ if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)
15751 + return -EINVAL;
15752 +
15753 + memset(&umap, 0, sizeof(struct fb_cmap));
15754 +diff -urNp linux-2.6.26.6/drivers/video/fbmem.c linux-2.6.26.6/drivers/video/fbmem.c
15755 +--- linux-2.6.26.6/drivers/video/fbmem.c 2008-10-08 23:24:05.000000000 -0400
15756 ++++ linux-2.6.26.6/drivers/video/fbmem.c 2008-10-11 21:54:20.000000000 -0400
15757 +@@ -395,7 +395,7 @@ static void fb_do_show_logo(struct fb_in
15758 + image->dx += image->width + 8;
15759 + }
15760 + } else if (rotate == FB_ROTATE_UD) {
15761 +- for (x = 0; x < num && image->dx >= 0; x++) {
15762 ++ for (x = 0; x < num && (__s32)image->dx >= 0; x++) {
15763 + info->fbops->fb_imageblit(info, image);
15764 + image->dx -= image->width + 8;
15765 + }
15766 +@@ -407,7 +407,7 @@ static void fb_do_show_logo(struct fb_in
15767 + image->dy += image->height + 8;
15768 + }
15769 + } else if (rotate == FB_ROTATE_CCW) {
15770 +- for (x = 0; x < num && image->dy >= 0; x++) {
15771 ++ for (x = 0; x < num && (__s32)image->dy >= 0; x++) {
15772 + info->fbops->fb_imageblit(info, image);
15773 + image->dy -= image->height + 8;
15774 + }
15775 +@@ -1084,7 +1084,7 @@ fb_ioctl(struct inode *inode, struct fil
15776 + return - EFAULT;
15777 + if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
15778 + return -EINVAL;
15779 +- if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
15780 ++ if (con2fb.framebuffer >= FB_MAX)
15781 + return -EINVAL;
15782 + #ifdef CONFIG_KMOD
15783 + if (!registered_fb[con2fb.framebuffer])
15784 +diff -urNp linux-2.6.26.6/drivers/video/fbmon.c linux-2.6.26.6/drivers/video/fbmon.c
15785 +--- linux-2.6.26.6/drivers/video/fbmon.c 2008-10-08 23:24:05.000000000 -0400
15786 ++++ linux-2.6.26.6/drivers/video/fbmon.c 2008-10-11 21:54:20.000000000 -0400
15787 +@@ -45,7 +45,7 @@
15788 + #ifdef DEBUG
15789 + #define DPRINTK(fmt, args...) printk(fmt,## args)
15790 + #else
15791 +-#define DPRINTK(fmt, args...)
15792 ++#define DPRINTK(fmt, args...) do {} while (0)
15793 + #endif
15794 +
15795 + #define FBMON_FIX_HEADER 1
15796 +diff -urNp linux-2.6.26.6/drivers/video/i810/i810_accel.c linux-2.6.26.6/drivers/video/i810/i810_accel.c
15797 +--- linux-2.6.26.6/drivers/video/i810/i810_accel.c 2008-10-08 23:24:05.000000000 -0400
15798 ++++ linux-2.6.26.6/drivers/video/i810/i810_accel.c 2008-10-11 21:54:20.000000000 -0400
15799 +@@ -73,6 +73,7 @@ static inline int wait_for_space(struct
15800 + }
15801 + }
15802 + printk("ringbuffer lockup!!!\n");
15803 ++ printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
15804 + i810_report_error(mmio);
15805 + par->dev_flags |= LOCKUP;
15806 + info->pixmap.scan_align = 1;
15807 +diff -urNp linux-2.6.26.6/drivers/video/i810/i810_main.c linux-2.6.26.6/drivers/video/i810/i810_main.c
15808 +--- linux-2.6.26.6/drivers/video/i810/i810_main.c 2008-10-08 23:24:05.000000000 -0400
15809 ++++ linux-2.6.26.6/drivers/video/i810/i810_main.c 2008-10-11 21:54:20.000000000 -0400
15810 +@@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t
15811 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
15812 + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,
15813 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
15814 +- { 0 },
15815 ++ { 0, 0, 0, 0, 0, 0, 0 },
15816 + };
15817 +
15818 + static struct pci_driver i810fb_driver = {
15819 +@@ -1509,7 +1509,7 @@ static int i810fb_cursor(struct fb_info
15820 + int size = ((cursor->image.width + 7) >> 3) *
15821 + cursor->image.height;
15822 + int i;
15823 +- u8 *data = kmalloc(64 * 8, GFP_ATOMIC);
15824 ++ u8 *data = kmalloc(64 * 8, GFP_KERNEL);
15825 +
15826 + if (data == NULL)
15827 + return -ENOMEM;
15828 +diff -urNp linux-2.6.26.6/drivers/video/modedb.c linux-2.6.26.6/drivers/video/modedb.c
15829 +--- linux-2.6.26.6/drivers/video/modedb.c 2008-10-08 23:24:05.000000000 -0400
15830 ++++ linux-2.6.26.6/drivers/video/modedb.c 2008-10-11 21:54:20.000000000 -0400
15831 +@@ -38,232 +38,232 @@ static const struct fb_videomode modedb[
15832 + {
15833 + /* 640x400 @ 70 Hz, 31.5 kHz hsync */
15834 + NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
15835 +- 0, FB_VMODE_NONINTERLACED
15836 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15837 + }, {
15838 + /* 640x480 @ 60 Hz, 31.5 kHz hsync */
15839 + NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
15840 +- 0, FB_VMODE_NONINTERLACED
15841 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15842 + }, {
15843 + /* 800x600 @ 56 Hz, 35.15 kHz hsync */
15844 + NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
15845 +- 0, FB_VMODE_NONINTERLACED
15846 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15847 + }, {
15848 + /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
15849 + NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
15850 +- 0, FB_VMODE_INTERLACED
15851 ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
15852 + }, {
15853 + /* 640x400 @ 85 Hz, 37.86 kHz hsync */
15854 + NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
15855 +- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
15856 ++ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15857 + }, {
15858 + /* 640x480 @ 72 Hz, 36.5 kHz hsync */
15859 + NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
15860 +- 0, FB_VMODE_NONINTERLACED
15861 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15862 + }, {
15863 + /* 640x480 @ 75 Hz, 37.50 kHz hsync */
15864 + NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
15865 +- 0, FB_VMODE_NONINTERLACED
15866 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15867 + }, {
15868 + /* 800x600 @ 60 Hz, 37.8 kHz hsync */
15869 + NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
15870 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
15871 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15872 + }, {
15873 + /* 640x480 @ 85 Hz, 43.27 kHz hsync */
15874 + NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
15875 +- 0, FB_VMODE_NONINTERLACED
15876 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15877 + }, {
15878 + /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
15879 + NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
15880 +- 0, FB_VMODE_INTERLACED
15881 ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
15882 + }, {
15883 + /* 800x600 @ 72 Hz, 48.0 kHz hsync */
15884 + NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
15885 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
15886 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15887 + }, {
15888 + /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
15889 + NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
15890 +- 0, FB_VMODE_NONINTERLACED
15891 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15892 + }, {
15893 + /* 640x480 @ 100 Hz, 53.01 kHz hsync */
15894 + NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
15895 +- 0, FB_VMODE_NONINTERLACED
15896 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15897 + }, {
15898 + /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
15899 + NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
15900 +- 0, FB_VMODE_NONINTERLACED
15901 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15902 + }, {
15903 + /* 800x600 @ 85 Hz, 55.84 kHz hsync */
15904 + NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
15905 +- 0, FB_VMODE_NONINTERLACED
15906 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15907 + }, {
15908 + /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
15909 + NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
15910 +- 0, FB_VMODE_NONINTERLACED
15911 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15912 + }, {
15913 + /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
15914 + NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
15915 +- 0, FB_VMODE_INTERLACED
15916 ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
15917 + }, {
15918 + /* 800x600 @ 100 Hz, 64.02 kHz hsync */
15919 + NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
15920 +- 0, FB_VMODE_NONINTERLACED
15921 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15922 + }, {
15923 + /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
15924 + NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
15925 +- 0, FB_VMODE_NONINTERLACED
15926 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15927 + }, {
15928 + /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
15929 + NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
15930 +- 0, FB_VMODE_NONINTERLACED
15931 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15932 + }, {
15933 + /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
15934 + NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
15935 +- 0, FB_VMODE_NONINTERLACED
15936 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15937 + }, {
15938 + /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
15939 + NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
15940 +- 0, FB_VMODE_NONINTERLACED
15941 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15942 + }, {
15943 + /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
15944 + NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13,
15945 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
15946 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15947 + }, {
15948 + /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
15949 + NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
15950 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
15951 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15952 + }, {
15953 + /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
15954 + NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
15955 +- 0, FB_VMODE_NONINTERLACED
15956 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15957 + }, {
15958 + /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
15959 + NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
15960 +- 0, FB_VMODE_NONINTERLACED
15961 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15962 + }, {
15963 + /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
15964 + NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
15965 +- 0, FB_VMODE_NONINTERLACED
15966 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15967 + }, {
15968 + /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
15969 + NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
15970 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
15971 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15972 + }, {
15973 + /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
15974 + NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
15975 +- 0, FB_VMODE_NONINTERLACED
15976 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15977 + }, {
15978 + /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
15979 + NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
15980 +- 0, FB_VMODE_NONINTERLACED
15981 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15982 + }, {
15983 + /* 1024x768 @ 100Hz, 80.21 kHz hsync */
15984 + NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
15985 +- 0, FB_VMODE_NONINTERLACED
15986 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15987 + }, {
15988 + /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
15989 + NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
15990 +- 0, FB_VMODE_NONINTERLACED
15991 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15992 + }, {
15993 + /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
15994 + NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
15995 +- 0, FB_VMODE_NONINTERLACED
15996 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15997 + }, {
15998 + /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
15999 + NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
16000 +- 0, FB_VMODE_NONINTERLACED
16001 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16002 + }, {
16003 + /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
16004 + NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
16005 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16006 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16007 + }, {
16008 + /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
16009 + NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
16010 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16011 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16012 + }, {
16013 + /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
16014 + NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
16015 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16016 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16017 + }, {
16018 + /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
16019 + NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
16020 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16021 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16022 + }, {
16023 + /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
16024 + NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
16025 +- 0, FB_VMODE_NONINTERLACED
16026 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16027 + }, {
16028 + /* 1800x1440 @ 64Hz, 96.15 kHz hsync */
16029 + NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
16030 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16031 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16032 + }, {
16033 + /* 1800x1440 @ 70Hz, 104.52 kHz hsync */
16034 + NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
16035 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16036 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16037 + }, {
16038 + /* 512x384 @ 78 Hz, 31.50 kHz hsync */
16039 + NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
16040 +- 0, FB_VMODE_NONINTERLACED
16041 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16042 + }, {
16043 + /* 512x384 @ 85 Hz, 34.38 kHz hsync */
16044 + NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
16045 +- 0, FB_VMODE_NONINTERLACED
16046 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16047 + }, {
16048 + /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
16049 + NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
16050 +- 0, FB_VMODE_DOUBLE
16051 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16052 + }, {
16053 + /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
16054 + NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
16055 +- 0, FB_VMODE_DOUBLE
16056 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16057 + }, {
16058 + /* 320x240 @ 72 Hz, 36.5 kHz hsync */
16059 + NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
16060 +- 0, FB_VMODE_DOUBLE
16061 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16062 + }, {
16063 + /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
16064 + NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
16065 +- 0, FB_VMODE_DOUBLE
16066 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16067 + }, {
16068 + /* 400x300 @ 60 Hz, 37.8 kHz hsync */
16069 + NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
16070 +- 0, FB_VMODE_DOUBLE
16071 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16072 + }, {
16073 + /* 400x300 @ 72 Hz, 48.0 kHz hsync */
16074 + NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
16075 +- 0, FB_VMODE_DOUBLE
16076 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16077 + }, {
16078 + /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
16079 + NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
16080 +- 0, FB_VMODE_DOUBLE
16081 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16082 + }, {
16083 + /* 480x300 @ 60 Hz, 37.8 kHz hsync */
16084 + NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
16085 +- 0, FB_VMODE_DOUBLE
16086 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16087 + }, {
16088 + /* 480x300 @ 63 Hz, 39.6 kHz hsync */
16089 + NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
16090 +- 0, FB_VMODE_DOUBLE
16091 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16092 + }, {
16093 + /* 480x300 @ 72 Hz, 48.0 kHz hsync */
16094 + NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
16095 +- 0, FB_VMODE_DOUBLE
16096 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16097 + }, {
16098 + /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
16099 + NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
16100 + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
16101 +- FB_VMODE_NONINTERLACED
16102 ++ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16103 + }, {
16104 + /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
16105 + NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6,
16106 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16107 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16108 + }, {
16109 + /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
16110 + NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
16111 +- 0, FB_VMODE_NONINTERLACED
16112 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16113 + }, {
16114 + /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */
16115 + NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3,
16116 +- 0, FB_VMODE_NONINTERLACED
16117 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16118 + },
16119 + };
16120 +
16121 +diff -urNp linux-2.6.26.6/drivers/video/uvesafb.c linux-2.6.26.6/drivers/video/uvesafb.c
16122 +--- linux-2.6.26.6/drivers/video/uvesafb.c 2008-10-08 23:24:05.000000000 -0400
16123 ++++ linux-2.6.26.6/drivers/video/uvesafb.c 2008-10-11 21:54:20.000000000 -0400
16124 +@@ -18,6 +18,7 @@
16125 + #include <linux/fb.h>
16126 + #include <linux/io.h>
16127 + #include <linux/mutex.h>
16128 ++#include <linux/moduleloader.h>
16129 + #include <video/edid.h>
16130 + #include <video/uvesafb.h>
16131 + #ifdef CONFIG_X86
16132 +@@ -117,7 +118,7 @@ static int uvesafb_helper_start(void)
16133 + NULL,
16134 + };
16135 +
16136 +- return call_usermodehelper(v86d_path, argv, envp, 1);
16137 ++ return call_usermodehelper(v86d_path, argv, envp, UMH_WAIT_PROC);
16138 + }
16139 +
16140 + /*
16141 +@@ -569,10 +570,34 @@ static int __devinit uvesafb_vbe_getpmi(
16142 + if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000) {
16143 + par->pmi_setpal = par->ypan = 0;
16144 + } else {
16145 ++
16146 ++#ifdef CONFIG_PAX_KERNEXEC
16147 ++#ifdef CONFIG_MODULES
16148 ++ unsigned long cr0;
16149 ++
16150 ++ par->pmi_code = module_alloc_exec((u16)task->t.regs.ecx);
16151 ++#endif
16152 ++ if (!par->pmi_code) {
16153 ++ par->pmi_setpal = par->ypan = 0;
16154 ++ return 0;
16155 ++ }
16156 ++#endif
16157 ++
16158 + par->pmi_base = (u16 *)phys_to_virt(((u32)task->t.regs.es << 4)
16159 + + task->t.regs.edi);
16160 ++
16161 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16162 ++ pax_open_kernel(cr0);
16163 ++ memcpy(par->pmi_code, par->pmi_base, (u16)task->t.regs.ecx);
16164 ++ pax_close_kernel(cr0);
16165 ++
16166 ++ par->pmi_start = ktva_ktla(par->pmi_code + par->pmi_base[1]);
16167 ++ par->pmi_pal = ktva_ktla(par->pmi_code + par->pmi_base[2]);
16168 ++#else
16169 + par->pmi_start = (u8 *)par->pmi_base + par->pmi_base[1];
16170 + par->pmi_pal = (u8 *)par->pmi_base + par->pmi_base[2];
16171 ++#endif
16172 ++
16173 + printk(KERN_INFO "uvesafb: protected mode interface info at "
16174 + "%04x:%04x\n",
16175 + (u16)task->t.regs.es, (u16)task->t.regs.edi);
16176 +@@ -1827,6 +1852,11 @@ out:
16177 + if (par->vbe_modes)
16178 + kfree(par->vbe_modes);
16179 +
16180 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16181 ++ if (par->pmi_code)
16182 ++ module_free_exec(NULL, par->pmi_code);
16183 ++#endif
16184 ++
16185 + framebuffer_release(info);
16186 + return err;
16187 + }
16188 +@@ -1853,6 +1883,12 @@ static int uvesafb_remove(struct platfor
16189 + kfree(par->vbe_state_orig);
16190 + if (par->vbe_state_saved)
16191 + kfree(par->vbe_state_saved);
16192 ++
16193 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16194 ++ if (par->pmi_code)
16195 ++ module_free_exec(NULL, par->pmi_code);
16196 ++#endif
16197 ++
16198 + }
16199 +
16200 + framebuffer_release(info);
16201 +diff -urNp linux-2.6.26.6/drivers/video/vesafb.c linux-2.6.26.6/drivers/video/vesafb.c
16202 +--- linux-2.6.26.6/drivers/video/vesafb.c 2008-10-08 23:24:05.000000000 -0400
16203 ++++ linux-2.6.26.6/drivers/video/vesafb.c 2008-10-11 21:54:20.000000000 -0400
16204 +@@ -9,6 +9,7 @@
16205 + */
16206 +
16207 + #include <linux/module.h>
16208 ++#include <linux/moduleloader.h>
16209 + #include <linux/kernel.h>
16210 + #include <linux/errno.h>
16211 + #include <linux/string.h>
16212 +@@ -53,8 +54,8 @@ static int vram_remap __initdata; /*
16213 + static int vram_total __initdata; /* Set total amount of memory */
16214 + static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */
16215 + static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */
16216 +-static void (*pmi_start)(void) __read_mostly;
16217 +-static void (*pmi_pal) (void) __read_mostly;
16218 ++static void (*pmi_start)(void) __read_only;
16219 ++static void (*pmi_pal) (void) __read_only;
16220 + static int depth __read_mostly;
16221 + static int vga_compat __read_mostly;
16222 + /* --------------------------------------------------------------------- */
16223 +@@ -224,6 +225,7 @@ static int __init vesafb_probe(struct pl
16224 + unsigned int size_vmode;
16225 + unsigned int size_remap;
16226 + unsigned int size_total;
16227 ++ void *pmi_code = NULL;
16228 +
16229 + if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
16230 + return -ENODEV;
16231 +@@ -266,10 +268,6 @@ static int __init vesafb_probe(struct pl
16232 + size_remap = size_total;
16233 + vesafb_fix.smem_len = size_remap;
16234 +
16235 +-#ifndef __i386__
16236 +- screen_info.vesapm_seg = 0;
16237 +-#endif
16238 +-
16239 + if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
16240 + printk(KERN_WARNING
16241 + "vesafb: cannot reserve video memory at 0x%lx\n",
16242 +@@ -302,9 +300,21 @@ static int __init vesafb_probe(struct pl
16243 + printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
16244 + vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
16245 +
16246 ++#ifdef __i386__
16247 ++
16248 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16249 ++ pmi_code = module_alloc_exec(screen_info.vesapm_size);
16250 ++ if (!pmi_code)
16251 ++#elif !defined(CONFIG_PAX_KERNEXEC)
16252 ++ if (0)
16253 ++#endif
16254 ++
16255 ++#endif
16256 ++ screen_info.vesapm_seg = 0;
16257 ++
16258 + if (screen_info.vesapm_seg) {
16259 +- printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
16260 +- screen_info.vesapm_seg,screen_info.vesapm_off);
16261 ++ printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n",
16262 ++ screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size);
16263 + }
16264 +
16265 + if (screen_info.vesapm_seg < 0xc000)
16266 +@@ -312,9 +322,29 @@ static int __init vesafb_probe(struct pl
16267 +
16268 + if (ypan || pmi_setpal) {
16269 + unsigned short *pmi_base;
16270 +- pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
16271 +- pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
16272 +- pmi_pal = (void*)((char*)pmi_base + pmi_base[2]);
16273 ++
16274 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16275 ++ unsigned long cr0;
16276 ++#endif
16277 ++
16278 ++ pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
16279 ++
16280 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16281 ++ pax_open_kernel(cr0);
16282 ++ memcpy(pmi_code, pmi_base, screen_info.vesapm_size);
16283 ++#else
16284 ++ pmi_code = pmi_base;
16285 ++#endif
16286 ++
16287 ++ pmi_start = (void*)((char*)pmi_code + pmi_base[1]);
16288 ++ pmi_pal = (void*)((char*)pmi_code + pmi_base[2]);
16289 ++
16290 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16291 ++ pmi_start = ktva_ktla(pmi_start);
16292 ++ pmi_pal = ktva_ktla(pmi_pal);
16293 ++ pax_close_kernel(cr0);
16294 ++#endif
16295 ++
16296 + printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
16297 + if (pmi_base[3]) {
16298 + printk(KERN_INFO "vesafb: pmi: ports = ");
16299 +@@ -456,6 +486,11 @@ static int __init vesafb_probe(struct pl
16300 + info->node, info->fix.id);
16301 + return 0;
16302 + err:
16303 ++
16304 ++#if defined(__i386__) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16305 ++ module_free_exec(NULL, pmi_code);
16306 ++#endif
16307 ++
16308 + if (info->screen_base)
16309 + iounmap(info->screen_base);
16310 + framebuffer_release(info);
16311 +diff -urNp linux-2.6.26.6/fs/9p/vfs_inode.c linux-2.6.26.6/fs/9p/vfs_inode.c
16312 +--- linux-2.6.26.6/fs/9p/vfs_inode.c 2008-10-08 23:24:05.000000000 -0400
16313 ++++ linux-2.6.26.6/fs/9p/vfs_inode.c 2008-10-11 21:54:20.000000000 -0400
16314 +@@ -1022,7 +1022,7 @@ static void *v9fs_vfs_follow_link(struct
16315 + static void
16316 + v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
16317 + {
16318 +- char *s = nd_get_link(nd);
16319 ++ const char *s = nd_get_link(nd);
16320 +
16321 + P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name, s);
16322 + if (!IS_ERR(s))
16323 +diff -urNp linux-2.6.26.6/fs/aio.c linux-2.6.26.6/fs/aio.c
16324 +--- linux-2.6.26.6/fs/aio.c 2008-10-08 23:24:05.000000000 -0400
16325 ++++ linux-2.6.26.6/fs/aio.c 2008-10-11 21:54:20.000000000 -0400
16326 +@@ -114,7 +114,7 @@ static int aio_setup_ring(struct kioctx
16327 + size += sizeof(struct io_event) * nr_events;
16328 + nr_pages = (size + PAGE_SIZE-1) >> PAGE_SHIFT;
16329 +
16330 +- if (nr_pages < 0)
16331 ++ if (nr_pages <= 0)
16332 + return -EINVAL;
16333 +
16334 + nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) / sizeof(struct io_event);
16335 +diff -urNp linux-2.6.26.6/fs/autofs4/symlink.c linux-2.6.26.6/fs/autofs4/symlink.c
16336 +--- linux-2.6.26.6/fs/autofs4/symlink.c 2008-10-08 23:24:05.000000000 -0400
16337 ++++ linux-2.6.26.6/fs/autofs4/symlink.c 2008-10-11 21:54:20.000000000 -0400
16338 +@@ -15,7 +15,7 @@
16339 + static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
16340 + {
16341 + struct autofs_info *ino = autofs4_dentry_ino(dentry);
16342 +- nd_set_link(nd, (char *)ino->u.symlink);
16343 ++ nd_set_link(nd, ino->u.symlink);
16344 + return NULL;
16345 + }
16346 +
16347 +diff -urNp linux-2.6.26.6/fs/befs/linuxvfs.c linux-2.6.26.6/fs/befs/linuxvfs.c
16348 +--- linux-2.6.26.6/fs/befs/linuxvfs.c 2008-10-08 23:24:05.000000000 -0400
16349 ++++ linux-2.6.26.6/fs/befs/linuxvfs.c 2008-10-11 21:54:20.000000000 -0400
16350 +@@ -489,7 +489,7 @@ static void befs_put_link(struct dentry
16351 + {
16352 + befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
16353 + if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
16354 +- char *link = nd_get_link(nd);
16355 ++ const char *link = nd_get_link(nd);
16356 + if (!IS_ERR(link))
16357 + kfree(link);
16358 + }
16359 +diff -urNp linux-2.6.26.6/fs/binfmt_aout.c linux-2.6.26.6/fs/binfmt_aout.c
16360 +--- linux-2.6.26.6/fs/binfmt_aout.c 2008-10-08 23:24:05.000000000 -0400
16361 ++++ linux-2.6.26.6/fs/binfmt_aout.c 2008-10-11 21:54:20.000000000 -0400
16362 +@@ -24,6 +24,7 @@
16363 + #include <linux/binfmts.h>
16364 + #include <linux/personality.h>
16365 + #include <linux/init.h>
16366 ++#include <linux/grsecurity.h>
16367 +
16368 + #include <asm/system.h>
16369 + #include <asm/uaccess.h>
16370 +@@ -124,18 +125,22 @@ static int aout_core_dump(long signr, st
16371 + /* If the size of the dump file exceeds the rlimit, then see what would happen
16372 + if we wrote the stack, but not the data area. */
16373 + #ifdef __sparc__
16374 ++ gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize + dump.u_ssize, 1);
16375 + if ((dump.u_dsize + dump.u_ssize) > limit)
16376 + dump.u_dsize = 0;
16377 + #else
16378 ++ gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE, 1);
16379 + if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > limit)
16380 + dump.u_dsize = 0;
16381 + #endif
16382 +
16383 + /* Make sure we have enough room to write the stack and data areas. */
16384 + #ifdef __sparc__
16385 ++ gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
16386 + if (dump.u_ssize > limit)
16387 + dump.u_ssize = 0;
16388 + #else
16389 ++ gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize + 1) * PAGE_SIZE, 1);
16390 + if ((dump.u_ssize + 1) * PAGE_SIZE > limit)
16391 + dump.u_ssize = 0;
16392 + #endif
16393 +@@ -291,6 +296,8 @@ static int load_aout_binary(struct linux
16394 + rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
16395 + if (rlim >= RLIM_INFINITY)
16396 + rlim = ~0;
16397 ++
16398 ++ gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
16399 + if (ex.a_data + ex.a_bss > rlim)
16400 + return -ENOMEM;
16401 +
16402 +@@ -322,6 +329,28 @@ static int load_aout_binary(struct linux
16403 +
16404 + compute_creds(bprm);
16405 + current->flags &= ~PF_FORKNOEXEC;
16406 ++
16407 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
16408 ++ current->mm->pax_flags = 0UL;
16409 ++#endif
16410 ++
16411 ++#ifdef CONFIG_PAX_PAGEEXEC
16412 ++ if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
16413 ++ current->mm->pax_flags |= MF_PAX_PAGEEXEC;
16414 ++
16415 ++#ifdef CONFIG_PAX_EMUTRAMP
16416 ++ if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
16417 ++ current->mm->pax_flags |= MF_PAX_EMUTRAMP;
16418 ++#endif
16419 ++
16420 ++#ifdef CONFIG_PAX_MPROTECT
16421 ++ if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
16422 ++ current->mm->pax_flags |= MF_PAX_MPROTECT;
16423 ++#endif
16424 ++
16425 ++ }
16426 ++#endif
16427 ++
16428 + #ifdef __sparc__
16429 + if (N_MAGIC(ex) == NMAGIC) {
16430 + loff_t pos = fd_offset;
16431 +@@ -413,7 +442,7 @@ static int load_aout_binary(struct linux
16432 +
16433 + down_write(&current->mm->mmap_sem);
16434 + error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
16435 +- PROT_READ | PROT_WRITE | PROT_EXEC,
16436 ++ PROT_READ | PROT_WRITE,
16437 + MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
16438 + fd_offset + ex.a_text);
16439 + up_write(&current->mm->mmap_sem);
16440 +diff -urNp linux-2.6.26.6/fs/binfmt_elf.c linux-2.6.26.6/fs/binfmt_elf.c
16441 +--- linux-2.6.26.6/fs/binfmt_elf.c 2008-10-08 23:24:05.000000000 -0400
16442 ++++ linux-2.6.26.6/fs/binfmt_elf.c 2008-10-11 21:54:20.000000000 -0400
16443 +@@ -38,10 +38,16 @@
16444 + #include <linux/random.h>
16445 + #include <linux/elf.h>
16446 + #include <linux/utsname.h>
16447 ++#include <linux/grsecurity.h>
16448 ++
16449 + #include <asm/uaccess.h>
16450 + #include <asm/param.h>
16451 + #include <asm/page.h>
16452 +
16453 ++#ifdef CONFIG_PAX_SEGMEXEC
16454 ++#include <asm/desc.h>
16455 ++#endif
16456 ++
16457 + static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
16458 + static int load_elf_library(struct file *);
16459 + static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *,
16460 +@@ -84,6 +90,8 @@ static struct linux_binfmt elf_format =
16461 +
16462 + static int set_brk(unsigned long start, unsigned long end)
16463 + {
16464 ++ unsigned long e = end;
16465 ++
16466 + start = ELF_PAGEALIGN(start);
16467 + end = ELF_PAGEALIGN(end);
16468 + if (end > start) {
16469 +@@ -94,7 +102,7 @@ static int set_brk(unsigned long start,
16470 + if (BAD_ADDR(addr))
16471 + return addr;
16472 + }
16473 +- current->mm->start_brk = current->mm->brk = end;
16474 ++ current->mm->start_brk = current->mm->brk = e;
16475 + return 0;
16476 + }
16477 +
16478 +@@ -351,10 +359,10 @@ static unsigned long load_elf_interp(str
16479 + {
16480 + struct elf_phdr *elf_phdata;
16481 + struct elf_phdr *eppnt;
16482 +- unsigned long load_addr = 0;
16483 ++ unsigned long load_addr = 0, pax_task_size = TASK_SIZE;
16484 + int load_addr_set = 0;
16485 + unsigned long last_bss = 0, elf_bss = 0;
16486 +- unsigned long error = ~0UL;
16487 ++ unsigned long error = -EINVAL;
16488 + unsigned long total_size;
16489 + int retval, i, size;
16490 +
16491 +@@ -400,6 +408,11 @@ static unsigned long load_elf_interp(str
16492 + goto out_close;
16493 + }
16494 +
16495 ++#ifdef CONFIG_PAX_SEGMEXEC
16496 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
16497 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
16498 ++#endif
16499 ++
16500 + eppnt = elf_phdata;
16501 + for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
16502 + if (eppnt->p_type == PT_LOAD) {
16503 +@@ -443,8 +456,8 @@ static unsigned long load_elf_interp(str
16504 + k = load_addr + eppnt->p_vaddr;
16505 + if (BAD_ADDR(k) ||
16506 + eppnt->p_filesz > eppnt->p_memsz ||
16507 +- eppnt->p_memsz > TASK_SIZE ||
16508 +- TASK_SIZE - eppnt->p_memsz < k) {
16509 ++ eppnt->p_memsz > pax_task_size ||
16510 ++ pax_task_size - eppnt->p_memsz < k) {
16511 + error = -ENOMEM;
16512 + goto out_close;
16513 + }
16514 +@@ -498,6 +511,177 @@ out:
16515 + return error;
16516 + }
16517 +
16518 ++#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
16519 ++static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
16520 ++{
16521 ++ unsigned long pax_flags = 0UL;
16522 ++
16523 ++#ifdef CONFIG_PAX_PAGEEXEC
16524 ++ if (elf_phdata->p_flags & PF_PAGEEXEC)
16525 ++ pax_flags |= MF_PAX_PAGEEXEC;
16526 ++#endif
16527 ++
16528 ++#ifdef CONFIG_PAX_SEGMEXEC
16529 ++ if (elf_phdata->p_flags & PF_SEGMEXEC)
16530 ++ pax_flags |= MF_PAX_SEGMEXEC;
16531 ++#endif
16532 ++
16533 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
16534 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
16535 ++ if (nx_enabled)
16536 ++ pax_flags &= ~MF_PAX_SEGMEXEC;
16537 ++ else
16538 ++ pax_flags &= ~MF_PAX_PAGEEXEC;
16539 ++ }
16540 ++#endif
16541 ++
16542 ++#ifdef CONFIG_PAX_EMUTRAMP
16543 ++ if (elf_phdata->p_flags & PF_EMUTRAMP)
16544 ++ pax_flags |= MF_PAX_EMUTRAMP;
16545 ++#endif
16546 ++
16547 ++#ifdef CONFIG_PAX_MPROTECT
16548 ++ if (elf_phdata->p_flags & PF_MPROTECT)
16549 ++ pax_flags |= MF_PAX_MPROTECT;
16550 ++#endif
16551 ++
16552 ++#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
16553 ++ if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
16554 ++ pax_flags |= MF_PAX_RANDMMAP;
16555 ++#endif
16556 ++
16557 ++ return pax_flags;
16558 ++}
16559 ++#endif
16560 ++
16561 ++#ifdef CONFIG_PAX_PT_PAX_FLAGS
16562 ++static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
16563 ++{
16564 ++ unsigned long pax_flags = 0UL;
16565 ++
16566 ++#ifdef CONFIG_PAX_PAGEEXEC
16567 ++ if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
16568 ++ pax_flags |= MF_PAX_PAGEEXEC;
16569 ++#endif
16570 ++
16571 ++#ifdef CONFIG_PAX_SEGMEXEC
16572 ++ if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
16573 ++ pax_flags |= MF_PAX_SEGMEXEC;
16574 ++#endif
16575 ++
16576 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
16577 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
16578 ++ if (nx_enabled)
16579 ++ pax_flags &= ~MF_PAX_SEGMEXEC;
16580 ++ else
16581 ++ pax_flags &= ~MF_PAX_PAGEEXEC;
16582 ++ }
16583 ++#endif
16584 ++
16585 ++#ifdef CONFIG_PAX_EMUTRAMP
16586 ++ if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
16587 ++ pax_flags |= MF_PAX_EMUTRAMP;
16588 ++#endif
16589 ++
16590 ++#ifdef CONFIG_PAX_MPROTECT
16591 ++ if (!(elf_phdata->p_flags & PF_NOMPROTECT))
16592 ++ pax_flags |= MF_PAX_MPROTECT;
16593 ++#endif
16594 ++
16595 ++#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
16596 ++ if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
16597 ++ pax_flags |= MF_PAX_RANDMMAP;
16598 ++#endif
16599 ++
16600 ++ return pax_flags;
16601 ++}
16602 ++#endif
16603 ++
16604 ++#ifdef CONFIG_PAX_EI_PAX
16605 ++static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
16606 ++{
16607 ++ unsigned long pax_flags = 0UL;
16608 ++
16609 ++#ifdef CONFIG_PAX_PAGEEXEC
16610 ++ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
16611 ++ pax_flags |= MF_PAX_PAGEEXEC;
16612 ++#endif
16613 ++
16614 ++#ifdef CONFIG_PAX_SEGMEXEC
16615 ++ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
16616 ++ pax_flags |= MF_PAX_SEGMEXEC;
16617 ++#endif
16618 ++
16619 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
16620 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
16621 ++ if (nx_enabled)
16622 ++ pax_flags &= ~MF_PAX_SEGMEXEC;
16623 ++ else
16624 ++ pax_flags &= ~MF_PAX_PAGEEXEC;
16625 ++ }
16626 ++#endif
16627 ++
16628 ++#ifdef CONFIG_PAX_EMUTRAMP
16629 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
16630 ++ pax_flags |= MF_PAX_EMUTRAMP;
16631 ++#endif
16632 ++
16633 ++#ifdef CONFIG_PAX_MPROTECT
16634 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
16635 ++ pax_flags |= MF_PAX_MPROTECT;
16636 ++#endif
16637 ++
16638 ++#ifdef CONFIG_PAX_ASLR
16639 ++ if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
16640 ++ pax_flags |= MF_PAX_RANDMMAP;
16641 ++#endif
16642 ++
16643 ++ return pax_flags;
16644 ++}
16645 ++#endif
16646 ++
16647 ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
16648 ++static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
16649 ++{
16650 ++ unsigned long pax_flags = 0UL;
16651 ++
16652 ++#ifdef CONFIG_PAX_PT_PAX_FLAGS
16653 ++ unsigned long i;
16654 ++#endif
16655 ++
16656 ++#ifdef CONFIG_PAX_EI_PAX
16657 ++ pax_flags = pax_parse_ei_pax(elf_ex);
16658 ++#endif
16659 ++
16660 ++#ifdef CONFIG_PAX_PT_PAX_FLAGS
16661 ++ for (i = 0UL; i < elf_ex->e_phnum; i++)
16662 ++ if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
16663 ++ if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
16664 ++ ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
16665 ++ ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
16666 ++ ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
16667 ++ ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
16668 ++ return -EINVAL;
16669 ++
16670 ++#ifdef CONFIG_PAX_SOFTMODE
16671 ++ if (pax_softmode)
16672 ++ pax_flags = pax_parse_softmode(&elf_phdata[i]);
16673 ++ else
16674 ++#endif
16675 ++
16676 ++ pax_flags = pax_parse_hardmode(&elf_phdata[i]);
16677 ++ break;
16678 ++ }
16679 ++#endif
16680 ++
16681 ++ if (0 > pax_check_flags(&pax_flags))
16682 ++ return -EINVAL;
16683 ++
16684 ++ current->mm->pax_flags = pax_flags;
16685 ++ return 0;
16686 ++}
16687 ++#endif
16688 ++
16689 + /*
16690 + * These are the functions used to load ELF style executables and shared
16691 + * libraries. There is no binary dependent code anywhere else.
16692 +@@ -514,6 +698,11 @@ static unsigned long randomize_stack_top
16693 + {
16694 + unsigned int random_variable = 0;
16695 +
16696 ++#ifdef CONFIG_PAX_RANDUSTACK
16697 ++ if (randomize_va_space)
16698 ++ return stack_top - current->mm->delta_stack;
16699 ++#endif
16700 ++
16701 + if ((current->flags & PF_RANDOMIZE) &&
16702 + !(current->personality & ADDR_NO_RANDOMIZE)) {
16703 + random_variable = get_random_int() & STACK_RND_MASK;
16704 +@@ -532,7 +721,7 @@ static int load_elf_binary(struct linux_
16705 + unsigned long load_addr = 0, load_bias = 0;
16706 + int load_addr_set = 0;
16707 + char * elf_interpreter = NULL;
16708 +- unsigned long error;
16709 ++ unsigned long error = 0;
16710 + struct elf_phdr *elf_ppnt, *elf_phdata;
16711 + unsigned long elf_bss, elf_brk;
16712 + int elf_exec_fileno;
16713 +@@ -543,11 +732,11 @@ static int load_elf_binary(struct linux_
16714 + unsigned long start_code, end_code, start_data, end_data;
16715 + unsigned long reloc_func_desc = 0;
16716 + int executable_stack = EXSTACK_DEFAULT;
16717 +- unsigned long def_flags = 0;
16718 + struct {
16719 + struct elfhdr elf_ex;
16720 + struct elfhdr interp_elf_ex;
16721 + } *loc;
16722 ++ unsigned long pax_task_size = TASK_SIZE;
16723 +
16724 + loc = kmalloc(sizeof(*loc), GFP_KERNEL);
16725 + if (!loc) {
16726 +@@ -715,11 +904,80 @@ static int load_elf_binary(struct linux_
16727 +
16728 + /* OK, This is the point of no return */
16729 + current->flags &= ~PF_FORKNOEXEC;
16730 +- current->mm->def_flags = def_flags;
16731 ++
16732 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
16733 ++ current->mm->pax_flags = 0UL;
16734 ++#endif
16735 ++
16736 ++#ifdef CONFIG_PAX_DLRESOLVE
16737 ++ current->mm->call_dl_resolve = 0UL;
16738 ++#endif
16739 ++
16740 ++#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
16741 ++ current->mm->call_syscall = 0UL;
16742 ++#endif
16743 ++
16744 ++#ifdef CONFIG_PAX_ASLR
16745 ++ current->mm->delta_mmap = 0UL;
16746 ++ current->mm->delta_stack = 0UL;
16747 ++#endif
16748 ++
16749 ++ current->mm->def_flags = 0;
16750 ++
16751 ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
16752 ++ if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
16753 ++ send_sig(SIGKILL, current, 0);
16754 ++ goto out_free_dentry;
16755 ++ }
16756 ++#endif
16757 ++
16758 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
16759 ++ pax_set_initial_flags(bprm);
16760 ++#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
16761 ++ if (pax_set_initial_flags_func)
16762 ++ (pax_set_initial_flags_func)(bprm);
16763 ++#endif
16764 ++
16765 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
16766 ++ if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !nx_enabled) {
16767 ++ current->mm->context.user_cs_limit = PAGE_SIZE;
16768 ++ current->mm->def_flags |= VM_PAGEEXEC;
16769 ++ }
16770 ++#endif
16771 ++
16772 ++#ifdef CONFIG_PAX_SEGMEXEC
16773 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
16774 ++ current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
16775 ++ current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE;
16776 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
16777 ++ }
16778 ++#endif
16779 ++
16780 ++#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
16781 ++ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
16782 ++ set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
16783 ++ put_cpu_no_resched();
16784 ++ }
16785 ++#endif
16786 ++
16787 ++#ifdef CONFIG_PAX_ASLR
16788 ++ if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
16789 ++ current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT;
16790 ++ current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT;
16791 ++ }
16792 ++#endif
16793 +
16794 + /* Do this immediately, since STACK_TOP as used in setup_arg_pages
16795 + may depend on the personality. */
16796 + SET_PERSONALITY(loc->elf_ex, 0);
16797 ++
16798 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
16799 ++ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
16800 ++ executable_stack = EXSTACK_DISABLE_X;
16801 ++ current->personality &= ~READ_IMPLIES_EXEC;
16802 ++ } else
16803 ++#endif
16804 ++
16805 + if (elf_read_implies_exec(loc->elf_ex, executable_stack))
16806 + current->personality |= READ_IMPLIES_EXEC;
16807 +
16808 +@@ -800,6 +1058,20 @@ static int load_elf_binary(struct linux_
16809 + #else
16810 + load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
16811 + #endif
16812 ++
16813 ++#ifdef CONFIG_PAX_RANDMMAP
16814 ++ /* PaX: randomize base address at the default exe base if requested */
16815 ++ if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) {
16816 ++#ifdef CONFIG_SPARC64
16817 ++ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1);
16818 ++#else
16819 ++ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT;
16820 ++#endif
16821 ++ load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias);
16822 ++ elf_flags |= MAP_FIXED;
16823 ++ }
16824 ++#endif
16825 ++
16826 + }
16827 +
16828 + error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
16829 +@@ -832,9 +1104,9 @@ static int load_elf_binary(struct linux_
16830 + * allowed task size. Note that p_filesz must always be
16831 + * <= p_memsz so it is only necessary to check p_memsz.
16832 + */
16833 +- if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
16834 +- elf_ppnt->p_memsz > TASK_SIZE ||
16835 +- TASK_SIZE - elf_ppnt->p_memsz < k) {
16836 ++ if (k >= pax_task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
16837 ++ elf_ppnt->p_memsz > pax_task_size ||
16838 ++ pax_task_size - elf_ppnt->p_memsz < k) {
16839 + /* set_brk can never work. Avoid overflows. */
16840 + send_sig(SIGKILL, current, 0);
16841 + retval = -EINVAL;
16842 +@@ -862,6 +1134,11 @@ static int load_elf_binary(struct linux_
16843 + start_data += load_bias;
16844 + end_data += load_bias;
16845 +
16846 ++#ifdef CONFIG_PAX_RANDMMAP
16847 ++ if (current->mm->pax_flags & MF_PAX_RANDMMAP)
16848 ++ elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4);
16849 ++#endif
16850 ++
16851 + /* Calling set_brk effectively mmaps the pages that we need
16852 + * for the bss and break sections. We must do this before
16853 + * mapping in the interpreter, to make sure it doesn't wind
16854 +@@ -873,9 +1150,11 @@ static int load_elf_binary(struct linux_
16855 + goto out_free_dentry;
16856 + }
16857 + if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
16858 +- send_sig(SIGSEGV, current, 0);
16859 +- retval = -EFAULT; /* Nobody gets to see this, but.. */
16860 +- goto out_free_dentry;
16861 ++ /*
16862 ++ * This bss-zeroing can fail if the ELF
16863 ++ * file specifies odd protections. So
16864 ++ * we don't check the return value
16865 ++ */
16866 + }
16867 +
16868 + if (elf_interpreter) {
16869 +@@ -1118,8 +1397,10 @@ static int dump_seek(struct file *file,
16870 + unsigned long n = off;
16871 + if (n > PAGE_SIZE)
16872 + n = PAGE_SIZE;
16873 +- if (!dump_write(file, buf, n))
16874 ++ if (!dump_write(file, buf, n)) {
16875 ++ free_page((unsigned long)buf);
16876 + return 0;
16877 ++ }
16878 + off -= n;
16879 + }
16880 + free_page((unsigned long)buf);
16881 +@@ -1131,7 +1412,7 @@ static int dump_seek(struct file *file,
16882 + * Decide what to dump of a segment, part, all or none.
16883 + */
16884 + static unsigned long vma_dump_size(struct vm_area_struct *vma,
16885 +- unsigned long mm_flags)
16886 ++ unsigned long mm_flags, long signr)
16887 + {
16888 + /* The vma can be set up to tell us the answer directly. */
16889 + if (vma->vm_flags & VM_ALWAYSDUMP)
16890 +@@ -1157,7 +1438,7 @@ static unsigned long vma_dump_size(struc
16891 + if (vma->vm_file == NULL)
16892 + return 0;
16893 +
16894 +- if (FILTER(MAPPED_PRIVATE))
16895 ++ if (signr == SIGKILL || FILTER(MAPPED_PRIVATE))
16896 + goto whole;
16897 +
16898 + /*
16899 +@@ -1243,8 +1524,11 @@ static int writenote(struct memelfnote *
16900 + #undef DUMP_WRITE
16901 +
16902 + #define DUMP_WRITE(addr, nr) \
16903 ++ do { \
16904 ++ gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
16905 + if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
16906 +- goto end_coredump;
16907 ++ goto end_coredump; \
16908 ++ } while (0);
16909 + #define DUMP_SEEK(off) \
16910 + if (!dump_seek(file, (off))) \
16911 + goto end_coredump;
16912 +@@ -1957,7 +2241,7 @@ static int elf_core_dump(long signr, str
16913 + phdr.p_offset = offset;
16914 + phdr.p_vaddr = vma->vm_start;
16915 + phdr.p_paddr = 0;
16916 +- phdr.p_filesz = vma_dump_size(vma, mm_flags);
16917 ++ phdr.p_filesz = vma_dump_size(vma, mm_flags, signr);
16918 + phdr.p_memsz = vma->vm_end - vma->vm_start;
16919 + offset += phdr.p_filesz;
16920 + phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
16921 +@@ -1989,7 +2273,7 @@ static int elf_core_dump(long signr, str
16922 + unsigned long addr;
16923 + unsigned long end;
16924 +
16925 +- end = vma->vm_start + vma_dump_size(vma, mm_flags);
16926 ++ end = vma->vm_start + vma_dump_size(vma, mm_flags, signr);
16927 +
16928 + for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
16929 + struct page *page;
16930 +@@ -2009,6 +2293,7 @@ static int elf_core_dump(long signr, str
16931 + flush_cache_page(tmp_vma, addr,
16932 + page_to_pfn(page));
16933 + kaddr = kmap(page);
16934 ++ gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
16935 + if ((size += PAGE_SIZE) > limit ||
16936 + !dump_write(file, kaddr,
16937 + PAGE_SIZE)) {
16938 +diff -urNp linux-2.6.26.6/fs/binfmt_flat.c linux-2.6.26.6/fs/binfmt_flat.c
16939 +--- linux-2.6.26.6/fs/binfmt_flat.c 2008-10-08 23:24:05.000000000 -0400
16940 ++++ linux-2.6.26.6/fs/binfmt_flat.c 2008-10-11 21:54:20.000000000 -0400
16941 +@@ -561,7 +561,9 @@ static int load_flat_file(struct linux_b
16942 + realdatastart = (unsigned long) -ENOMEM;
16943 + printk("Unable to allocate RAM for process data, errno %d\n",
16944 + (int)-realdatastart);
16945 ++ down_write(&current->mm->mmap_sem);
16946 + do_munmap(current->mm, textpos, text_len);
16947 ++ up_write(&current->mm->mmap_sem);
16948 + ret = realdatastart;
16949 + goto err;
16950 + }
16951 +@@ -583,8 +585,10 @@ static int load_flat_file(struct linux_b
16952 + }
16953 + if (result >= (unsigned long)-4096) {
16954 + printk("Unable to read data+bss, errno %d\n", (int)-result);
16955 ++ down_write(&current->mm->mmap_sem);
16956 + do_munmap(current->mm, textpos, text_len);
16957 + do_munmap(current->mm, realdatastart, data_len + extra);
16958 ++ up_write(&current->mm->mmap_sem);
16959 + ret = result;
16960 + goto err;
16961 + }
16962 +@@ -657,8 +661,10 @@ static int load_flat_file(struct linux_b
16963 + }
16964 + if (result >= (unsigned long)-4096) {
16965 + printk("Unable to read code+data+bss, errno %d\n",(int)-result);
16966 ++ down_write(&current->mm->mmap_sem);
16967 + do_munmap(current->mm, textpos, text_len + data_len + extra +
16968 + MAX_SHARED_LIBS * sizeof(unsigned long));
16969 ++ up_write(&current->mm->mmap_sem);
16970 + ret = result;
16971 + goto err;
16972 + }
16973 +diff -urNp linux-2.6.26.6/fs/binfmt_misc.c linux-2.6.26.6/fs/binfmt_misc.c
16974 +--- linux-2.6.26.6/fs/binfmt_misc.c 2008-10-08 23:24:05.000000000 -0400
16975 ++++ linux-2.6.26.6/fs/binfmt_misc.c 2008-10-11 21:54:20.000000000 -0400
16976 +@@ -710,7 +710,7 @@ static int bm_fill_super(struct super_bl
16977 + static struct tree_descr bm_files[] = {
16978 + [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
16979 + [3] = {"register", &bm_register_operations, S_IWUSR},
16980 +- /* last one */ {""}
16981 ++ /* last one */ {"", NULL, 0}
16982 + };
16983 + int err = simple_fill_super(sb, 0x42494e4d, bm_files);
16984 + if (!err)
16985 +diff -urNp linux-2.6.26.6/fs/bio.c linux-2.6.26.6/fs/bio.c
16986 +--- linux-2.6.26.6/fs/bio.c 2008-10-08 23:24:05.000000000 -0400
16987 ++++ linux-2.6.26.6/fs/bio.c 2008-10-11 21:55:52.000000000 -0400
16988 +@@ -502,7 +502,7 @@ static int __bio_copy_iov(struct bio *bi
16989 +
16990 + while (bv_len && iov_idx < iov_count) {
16991 + unsigned int bytes;
16992 +- char *iov_addr;
16993 ++ char __user *iov_addr;
16994 +
16995 + bytes = min_t(unsigned int,
16996 + iov[iov_idx].iov_len - iov_off, bv_len);
16997 +diff -urNp linux-2.6.26.6/fs/buffer.c linux-2.6.26.6/fs/buffer.c
16998 +--- linux-2.6.26.6/fs/buffer.c 2008-10-08 23:24:05.000000000 -0400
16999 ++++ linux-2.6.26.6/fs/buffer.c 2008-10-11 21:54:20.000000000 -0400
17000 +@@ -41,6 +41,7 @@
17001 + #include <linux/bitops.h>
17002 + #include <linux/mpage.h>
17003 + #include <linux/bit_spinlock.h>
17004 ++#include <linux/grsecurity.h>
17005 +
17006 + static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
17007 +
17008 +@@ -2191,6 +2192,7 @@ int generic_cont_expand_simple(struct in
17009 +
17010 + err = -EFBIG;
17011 + limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
17012 ++ gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
17013 + if (limit != RLIM_INFINITY && size > (loff_t)limit) {
17014 + send_sig(SIGXFSZ, current, 0);
17015 + goto out;
17016 +diff -urNp linux-2.6.26.6/fs/cifs/cifs_uniupr.h linux-2.6.26.6/fs/cifs/cifs_uniupr.h
17017 +--- linux-2.6.26.6/fs/cifs/cifs_uniupr.h 2008-10-08 23:24:05.000000000 -0400
17018 ++++ linux-2.6.26.6/fs/cifs/cifs_uniupr.h 2008-10-11 21:54:20.000000000 -0400
17019 +@@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa
17020 + {0x0490, 0x04cc, UniCaseRangeU0490},
17021 + {0x1e00, 0x1ffc, UniCaseRangeU1e00},
17022 + {0xff40, 0xff5a, UniCaseRangeUff40},
17023 +- {0}
17024 ++ {0, 0, NULL}
17025 + };
17026 + #endif
17027 +
17028 +diff -urNp linux-2.6.26.6/fs/cifs/link.c linux-2.6.26.6/fs/cifs/link.c
17029 +--- linux-2.6.26.6/fs/cifs/link.c 2008-10-08 23:24:05.000000000 -0400
17030 ++++ linux-2.6.26.6/fs/cifs/link.c 2008-10-11 21:54:20.000000000 -0400
17031 +@@ -318,7 +318,7 @@ cifs_readlink(struct dentry *direntry, c
17032 +
17033 + void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
17034 + {
17035 +- char *p = nd_get_link(nd);
17036 ++ const char *p = nd_get_link(nd);
17037 + if (!IS_ERR(p))
17038 + kfree(p);
17039 + }
17040 +diff -urNp linux-2.6.26.6/fs/compat.c linux-2.6.26.6/fs/compat.c
17041 +--- linux-2.6.26.6/fs/compat.c 2008-10-08 23:24:05.000000000 -0400
17042 ++++ linux-2.6.26.6/fs/compat.c 2008-10-11 21:54:20.000000000 -0400
17043 +@@ -51,6 +51,7 @@
17044 + #include <linux/poll.h>
17045 + #include <linux/mm.h>
17046 + #include <linux/eventpoll.h>
17047 ++#include <linux/grsecurity.h>
17048 +
17049 + #include <asm/uaccess.h>
17050 + #include <asm/mmu_context.h>
17051 +@@ -1294,14 +1295,12 @@ static int compat_copy_strings(int argc,
17052 + if (!kmapped_page || kpos != (pos & PAGE_MASK)) {
17053 + struct page *page;
17054 +
17055 +-#ifdef CONFIG_STACK_GROWSUP
17056 + ret = expand_stack_downwards(bprm->vma, pos);
17057 + if (ret < 0) {
17058 + /* We've exceed the stack rlimit. */
17059 + ret = -E2BIG;
17060 + goto out;
17061 + }
17062 +-#endif
17063 + ret = get_user_pages(current, bprm->mm, pos,
17064 + 1, 1, 1, &page, NULL);
17065 + if (ret <= 0) {
17066 +@@ -1347,6 +1346,11 @@ int compat_do_execve(char * filename,
17067 + compat_uptr_t __user *envp,
17068 + struct pt_regs * regs)
17069 + {
17070 ++#ifdef CONFIG_GRKERNSEC
17071 ++ struct file *old_exec_file;
17072 ++ struct acl_subject_label *old_acl;
17073 ++ struct rlimit old_rlim[RLIM_NLIMITS];
17074 ++#endif
17075 + struct linux_binprm *bprm;
17076 + struct file *file;
17077 + int retval;
17078 +@@ -1367,6 +1371,14 @@ int compat_do_execve(char * filename,
17079 + bprm->filename = filename;
17080 + bprm->interp = filename;
17081 +
17082 ++ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
17083 ++ retval = -EAGAIN;
17084 ++ if (gr_handle_nproc())
17085 ++ goto out_file;
17086 ++ retval = -EACCES;
17087 ++ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
17088 ++ goto out_file;
17089 ++
17090 + retval = bprm_mm_init(bprm);
17091 + if (retval)
17092 + goto out_file;
17093 +@@ -1400,8 +1412,36 @@ int compat_do_execve(char * filename,
17094 + if (retval < 0)
17095 + goto out;
17096 +
17097 ++ if (!gr_tpe_allow(file)) {
17098 ++ retval = -EACCES;
17099 ++ goto out;
17100 ++ }
17101 ++
17102 ++ if (gr_check_crash_exec(file)) {
17103 ++ retval = -EACCES;
17104 ++ goto out;
17105 ++ }
17106 ++
17107 ++ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
17108 ++
17109 ++ gr_handle_exec_args(bprm, (char __user * __user *)argv);
17110 ++
17111 ++#ifdef CONFIG_GRKERNSEC
17112 ++ old_acl = current->acl;
17113 ++ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
17114 ++ old_exec_file = current->exec_file;
17115 ++ get_file(file);
17116 ++ current->exec_file = file;
17117 ++#endif
17118 ++
17119 ++ gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
17120 ++
17121 + retval = search_binary_handler(bprm, regs);
17122 + if (retval >= 0) {
17123 ++#ifdef CONFIG_GRKERNSEC
17124 ++ if (old_exec_file)
17125 ++ fput(old_exec_file);
17126 ++#endif
17127 + /* execve success */
17128 + security_bprm_free(bprm);
17129 + acct_update_integrals(current);
17130 +@@ -1409,6 +1449,13 @@ int compat_do_execve(char * filename,
17131 + return retval;
17132 + }
17133 +
17134 ++#ifdef CONFIG_GRKERNSEC
17135 ++ current->acl = old_acl;
17136 ++ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
17137 ++ fput(current->exec_file);
17138 ++ current->exec_file = old_exec_file;
17139 ++#endif
17140 ++
17141 + out:
17142 + if (bprm->security)
17143 + security_bprm_free(bprm);
17144 +diff -urNp linux-2.6.26.6/fs/compat_ioctl.c linux-2.6.26.6/fs/compat_ioctl.c
17145 +--- linux-2.6.26.6/fs/compat_ioctl.c 2008-10-08 23:24:05.000000000 -0400
17146 ++++ linux-2.6.26.6/fs/compat_ioctl.c 2008-10-11 21:54:20.000000000 -0400
17147 +@@ -1889,15 +1889,15 @@ struct ioctl_trans {
17148 + };
17149 +
17150 + #define HANDLE_IOCTL(cmd,handler) \
17151 +- { (cmd), (ioctl_trans_handler_t)(handler) },
17152 ++ { (cmd), (ioctl_trans_handler_t)(handler), NULL },
17153 +
17154 + /* pointer to compatible structure or no argument */
17155 + #define COMPATIBLE_IOCTL(cmd) \
17156 +- { (cmd), do_ioctl32_pointer },
17157 ++ { (cmd), do_ioctl32_pointer, NULL },
17158 +
17159 + /* argument is an unsigned long integer, not a pointer */
17160 + #define ULONG_IOCTL(cmd) \
17161 +- { (cmd), (ioctl_trans_handler_t)sys_ioctl },
17162 ++ { (cmd), (ioctl_trans_handler_t)sys_ioctl, NULL },
17163 +
17164 + /* ioctl should not be warned about even if it's not implemented.
17165 + Valid reasons to use this:
17166 +diff -urNp linux-2.6.26.6/fs/debugfs/inode.c linux-2.6.26.6/fs/debugfs/inode.c
17167 +--- linux-2.6.26.6/fs/debugfs/inode.c 2008-10-08 23:24:05.000000000 -0400
17168 ++++ linux-2.6.26.6/fs/debugfs/inode.c 2008-10-11 21:54:20.000000000 -0400
17169 +@@ -121,7 +121,7 @@ static inline int debugfs_positive(struc
17170 +
17171 + static int debug_fill_super(struct super_block *sb, void *data, int silent)
17172 + {
17173 +- static struct tree_descr debug_files[] = {{""}};
17174 ++ static struct tree_descr debug_files[] = {{"", NULL, 0}};
17175 +
17176 + return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
17177 + }
17178 +diff -urNp linux-2.6.26.6/fs/exec.c linux-2.6.26.6/fs/exec.c
17179 +--- linux-2.6.26.6/fs/exec.c 2008-10-08 23:24:05.000000000 -0400
17180 ++++ linux-2.6.26.6/fs/exec.c 2008-10-11 21:55:07.000000000 -0400
17181 +@@ -51,6 +51,13 @@
17182 + #include <linux/tsacct_kern.h>
17183 + #include <linux/cn_proc.h>
17184 + #include <linux/audit.h>
17185 ++#include <linux/random.h>
17186 ++#include <linux/grsecurity.h>
17187 ++
17188 ++#ifdef CONFIG_PAX_REFCOUNT
17189 ++#include <linux/kallsyms.h>
17190 ++#include <linux/kdebug.h>
17191 ++#endif
17192 +
17193 + #include <asm/uaccess.h>
17194 + #include <asm/mmu_context.h>
17195 +@@ -65,6 +72,11 @@
17196 + #include <linux/a.out.h>
17197 + #endif
17198 +
17199 ++#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
17200 ++void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
17201 ++EXPORT_SYMBOL(pax_set_initial_flags_func);
17202 ++#endif
17203 ++
17204 + int core_uses_pid;
17205 + char core_pattern[CORENAME_MAX_SIZE] = "core";
17206 + int suid_dumpable = 0;
17207 +@@ -163,18 +175,10 @@ static struct page *get_arg_page(struct
17208 + int write)
17209 + {
17210 + struct page *page;
17211 +- int ret;
17212 +
17213 +-#ifdef CONFIG_STACK_GROWSUP
17214 +- if (write) {
17215 +- ret = expand_stack_downwards(bprm->vma, pos);
17216 +- if (ret < 0)
17217 +- return NULL;
17218 +- }
17219 +-#endif
17220 +- ret = get_user_pages(current, bprm->mm, pos,
17221 +- 1, write, 1, &page, NULL);
17222 +- if (ret <= 0)
17223 ++ if (0 > expand_stack_downwards(bprm->vma, pos))
17224 ++ return NULL;
17225 ++ if (0 >= get_user_pages(current, bprm->mm, pos, 1, write, 1, &page, NULL))
17226 + return NULL;
17227 +
17228 + if (write) {
17229 +@@ -247,6 +251,11 @@ static int __bprm_mm_init(struct linux_b
17230 + vma->vm_start = vma->vm_end - PAGE_SIZE;
17231 +
17232 + vma->vm_flags = VM_STACK_FLAGS;
17233 ++
17234 ++#ifdef CONFIG_PAX_SEGMEXEC
17235 ++ vma->vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
17236 ++#endif
17237 ++
17238 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
17239 + err = insert_vm_struct(mm, vma);
17240 + if (err) {
17241 +@@ -259,6 +268,11 @@ static int __bprm_mm_init(struct linux_b
17242 +
17243 + bprm->p = vma->vm_end - sizeof(void *);
17244 +
17245 ++#ifdef CONFIG_PAX_RANDUSTACK
17246 ++ if (randomize_va_space)
17247 ++ bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK;
17248 ++#endif
17249 ++
17250 + return 0;
17251 +
17252 + err:
17253 +@@ -382,7 +396,7 @@ static int count(char __user * __user *
17254 + if (!p)
17255 + break;
17256 + argv++;
17257 +- if(++i > max)
17258 ++ if (++i > max)
17259 + return -E2BIG;
17260 + cond_resched();
17261 + }
17262 +@@ -522,6 +536,10 @@ static int shift_arg_pages(struct vm_are
17263 + if (vma != find_vma(mm, new_start))
17264 + return -EFAULT;
17265 +
17266 ++#ifdef CONFIG_PAX_SEGMEXEC
17267 ++ BUG_ON(pax_find_mirror_vma(vma));
17268 ++#endif
17269 ++
17270 + /*
17271 + * cover the whole range: [new_start, old_end)
17272 + */
17273 +@@ -610,6 +628,14 @@ int setup_arg_pages(struct linux_binprm
17274 + bprm->exec -= stack_shift;
17275 +
17276 + down_write(&mm->mmap_sem);
17277 ++
17278 ++ /* Move stack pages down in memory. */
17279 ++ if (stack_shift) {
17280 ++ ret = shift_arg_pages(vma, stack_shift);
17281 ++ if (ret)
17282 ++ goto out_unlock;
17283 ++ }
17284 ++
17285 + vm_flags = VM_STACK_FLAGS;
17286 +
17287 + /*
17288 +@@ -623,21 +649,24 @@ int setup_arg_pages(struct linux_binprm
17289 + vm_flags &= ~VM_EXEC;
17290 + vm_flags |= mm->def_flags;
17291 +
17292 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
17293 ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
17294 ++ vm_flags &= ~VM_EXEC;
17295 ++
17296 ++#ifdef CONFIG_PAX_MPROTECT
17297 ++ if (mm->pax_flags & MF_PAX_MPROTECT)
17298 ++ vm_flags &= ~VM_MAYEXEC;
17299 ++#endif
17300 ++
17301 ++ }
17302 ++#endif
17303 ++
17304 + ret = mprotect_fixup(vma, &prev, vma->vm_start, vma->vm_end,
17305 + vm_flags);
17306 + if (ret)
17307 + goto out_unlock;
17308 + BUG_ON(prev != vma);
17309 +
17310 +- /* Move stack pages down in memory. */
17311 +- if (stack_shift) {
17312 +- ret = shift_arg_pages(vma, stack_shift);
17313 +- if (ret) {
17314 +- up_write(&mm->mmap_sem);
17315 +- return ret;
17316 +- }
17317 +- }
17318 +-
17319 + #ifdef CONFIG_STACK_GROWSUP
17320 + stack_base = vma->vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
17321 + #else
17322 +@@ -649,7 +678,7 @@ int setup_arg_pages(struct linux_binprm
17323 +
17324 + out_unlock:
17325 + up_write(&mm->mmap_sem);
17326 +- return 0;
17327 ++ return ret;
17328 + }
17329 + EXPORT_SYMBOL(setup_arg_pages);
17330 +
17331 +@@ -668,7 +697,7 @@ struct file *open_exec(const char *name)
17332 + struct inode *inode = nd.path.dentry->d_inode;
17333 + file = ERR_PTR(-EACCES);
17334 + if (S_ISREG(inode->i_mode)) {
17335 +- int err = vfs_permission(&nd, MAY_EXEC);
17336 ++ err = vfs_permission(&nd, MAY_EXEC);
17337 + file = ERR_PTR(err);
17338 + if (!err) {
17339 + file = nameidata_to_filp(&nd,
17340 +@@ -1270,6 +1299,11 @@ int do_execve(char * filename,
17341 + char __user *__user *envp,
17342 + struct pt_regs * regs)
17343 + {
17344 ++#ifdef CONFIG_GRKERNSEC
17345 ++ struct file *old_exec_file;
17346 ++ struct acl_subject_label *old_acl;
17347 ++ struct rlimit old_rlim[RLIM_NLIMITS];
17348 ++#endif
17349 + struct linux_binprm *bprm;
17350 + struct file *file;
17351 + struct files_struct *displaced;
17352 +@@ -1289,6 +1323,20 @@ int do_execve(char * filename,
17353 + if (IS_ERR(file))
17354 + goto out_kfree;
17355 +
17356 ++ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
17357 ++
17358 ++ if (gr_handle_nproc()) {
17359 ++ allow_write_access(file);
17360 ++ fput(file);
17361 ++ return -EAGAIN;
17362 ++ }
17363 ++
17364 ++ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
17365 ++ allow_write_access(file);
17366 ++ fput(file);
17367 ++ return -EACCES;
17368 ++ }
17369 ++
17370 + sched_exec();
17371 +
17372 + bprm->file = file;
17373 +@@ -1328,8 +1376,38 @@ int do_execve(char * filename,
17374 + if (retval < 0)
17375 + goto out;
17376 +
17377 ++ if (!gr_tpe_allow(file)) {
17378 ++ retval = -EACCES;
17379 ++ goto out;
17380 ++ }
17381 ++
17382 ++ if (gr_check_crash_exec(file)) {
17383 ++ retval = -EACCES;
17384 ++ goto out;
17385 ++ }
17386 ++
17387 ++ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
17388 ++
17389 ++ gr_handle_exec_args(bprm, argv);
17390 ++
17391 ++#ifdef CONFIG_GRKERNSEC
17392 ++ old_acl = current->acl;
17393 ++ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
17394 ++ old_exec_file = current->exec_file;
17395 ++ get_file(file);
17396 ++ current->exec_file = file;
17397 ++#endif
17398 ++
17399 ++ retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
17400 ++ if (retval < 0)
17401 ++ goto out_fail;
17402 ++
17403 + retval = search_binary_handler(bprm,regs);
17404 + if (retval >= 0) {
17405 ++#ifdef CONFIG_GRKERNSEC
17406 ++ if (old_exec_file)
17407 ++ fput(old_exec_file);
17408 ++#endif
17409 + /* execve success */
17410 + security_bprm_free(bprm);
17411 + acct_update_integrals(current);
17412 +@@ -1339,6 +1417,14 @@ int do_execve(char * filename,
17413 + return retval;
17414 + }
17415 +
17416 ++out_fail:
17417 ++#ifdef CONFIG_GRKERNSEC
17418 ++ current->acl = old_acl;
17419 ++ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
17420 ++ fput(current->exec_file);
17421 ++ current->exec_file = old_exec_file;
17422 ++#endif
17423 ++
17424 + out:
17425 + if (bprm->security)
17426 + security_bprm_free(bprm);
17427 +@@ -1505,6 +1591,125 @@ out:
17428 + return ispipe;
17429 + }
17430 +
17431 ++int pax_check_flags(unsigned long *flags)
17432 ++{
17433 ++ int retval = 0;
17434 ++
17435 ++#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC)
17436 ++ if (*flags & MF_PAX_SEGMEXEC)
17437 ++ {
17438 ++ *flags &= ~MF_PAX_SEGMEXEC;
17439 ++ retval = -EINVAL;
17440 ++ }
17441 ++#endif
17442 ++
17443 ++ if ((*flags & MF_PAX_PAGEEXEC)
17444 ++
17445 ++#ifdef CONFIG_PAX_PAGEEXEC
17446 ++ && (*flags & MF_PAX_SEGMEXEC)
17447 ++#endif
17448 ++
17449 ++ )
17450 ++ {
17451 ++ *flags &= ~MF_PAX_PAGEEXEC;
17452 ++ retval = -EINVAL;
17453 ++ }
17454 ++
17455 ++ if ((*flags & MF_PAX_MPROTECT)
17456 ++
17457 ++#ifdef CONFIG_PAX_MPROTECT
17458 ++ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
17459 ++#endif
17460 ++
17461 ++ )
17462 ++ {
17463 ++ *flags &= ~MF_PAX_MPROTECT;
17464 ++ retval = -EINVAL;
17465 ++ }
17466 ++
17467 ++ if ((*flags & MF_PAX_EMUTRAMP)
17468 ++
17469 ++#ifdef CONFIG_PAX_EMUTRAMP
17470 ++ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
17471 ++#endif
17472 ++
17473 ++ )
17474 ++ {
17475 ++ *flags &= ~MF_PAX_EMUTRAMP;
17476 ++ retval = -EINVAL;
17477 ++ }
17478 ++
17479 ++ return retval;
17480 ++}
17481 ++
17482 ++EXPORT_SYMBOL(pax_check_flags);
17483 ++
17484 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
17485 ++void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
17486 ++{
17487 ++ struct task_struct *tsk = current;
17488 ++ struct mm_struct *mm = current->mm;
17489 ++ char *buffer_exec = (char *)__get_free_page(GFP_KERNEL);
17490 ++ char *buffer_fault = (char *)__get_free_page(GFP_KERNEL);
17491 ++ char *path_exec = NULL;
17492 ++ char *path_fault = NULL;
17493 ++ unsigned long start = 0UL, end = 0UL, offset = 0UL;
17494 ++
17495 ++ if (buffer_exec && buffer_fault) {
17496 ++ struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL;
17497 ++
17498 ++ down_read(&mm->mmap_sem);
17499 ++ vma = mm->mmap;
17500 ++ while (vma && (!vma_exec || !vma_fault)) {
17501 ++ if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
17502 ++ vma_exec = vma;
17503 ++ if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
17504 ++ vma_fault = vma;
17505 ++ vma = vma->vm_next;
17506 ++ }
17507 ++ if (vma_exec) {
17508 ++ path_exec = d_path(&vma_exec->vm_file->f_path, buffer_exec, PAGE_SIZE);
17509 ++ if (IS_ERR(path_exec))
17510 ++ path_exec = "<path too long>";
17511 ++ }
17512 ++ if (vma_fault) {
17513 ++ start = vma_fault->vm_start;
17514 ++ end = vma_fault->vm_end;
17515 ++ offset = vma_fault->vm_pgoff << PAGE_SHIFT;
17516 ++ if (vma_fault->vm_file) {
17517 ++ path_fault = d_path(&vma_fault->vm_file->f_path, buffer_fault, PAGE_SIZE);
17518 ++ if (IS_ERR(path_fault))
17519 ++ path_fault = "<path too long>";
17520 ++ } else
17521 ++ path_fault = "<anonymous mapping>";
17522 ++ }
17523 ++ up_read(&mm->mmap_sem);
17524 ++ }
17525 ++ if (tsk->signal->curr_ip)
17526 ++ 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);
17527 ++ else
17528 ++ printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
17529 ++ printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
17530 ++ "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
17531 ++ tsk->uid, tsk->euid, pc, sp);
17532 ++ free_page((unsigned long)buffer_exec);
17533 ++ free_page((unsigned long)buffer_fault);
17534 ++ pax_report_insns(pc, sp);
17535 ++ do_coredump(SIGKILL, SIGKILL, regs);
17536 ++}
17537 ++#endif
17538 ++
17539 ++#ifdef CONFIG_PAX_REFCOUNT
17540 ++void pax_report_refcount_overflow(struct pt_regs *regs)
17541 ++{
17542 ++ printk(KERN_ERR "PAX: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n",
17543 ++ current->comm, task_pid_nr(current), current->uid, current->euid);
17544 ++ print_symbol(KERN_ERR "PAX: refcount overflow occured at: %s\n", instruction_pointer(regs));
17545 ++ show_registers(regs);
17546 ++ force_sig_specific(SIGKILL, current);
17547 ++}
17548 ++#endif
17549 ++
17550 + static void zap_process(struct task_struct *start)
17551 + {
17552 + struct task_struct *t;
17553 +@@ -1702,6 +1907,10 @@ int do_coredump(long signr, int exit_cod
17554 + */
17555 + clear_thread_flag(TIF_SIGPENDING);
17556 +
17557 ++ if (signr == SIGKILL || signr == SIGILL)
17558 ++ gr_handle_brute_attach(current);
17559 ++ gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
17560 ++
17561 + /*
17562 + * lock_kernel() because format_corename() is controlled by sysctl, which
17563 + * uses lock_kernel()
17564 +@@ -1722,6 +1931,8 @@ int do_coredump(long signr, int exit_cod
17565 +
17566 + if (ispipe) {
17567 + helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc);
17568 ++ if (!helper_argv)
17569 ++ goto fail_unlock;
17570 + /* Terminate the string before the first option */
17571 + delimit = strchr(corename, ' ');
17572 + if (delimit)
17573 +diff -urNp linux-2.6.26.6/fs/ext2/balloc.c linux-2.6.26.6/fs/ext2/balloc.c
17574 +--- linux-2.6.26.6/fs/ext2/balloc.c 2008-10-08 23:24:05.000000000 -0400
17575 ++++ linux-2.6.26.6/fs/ext2/balloc.c 2008-10-11 21:54:20.000000000 -0400
17576 +@@ -1192,7 +1192,7 @@ static int ext2_has_free_blocks(struct e
17577 +
17578 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
17579 + root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
17580 +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
17581 ++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
17582 + sbi->s_resuid != current->fsuid &&
17583 + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
17584 + return 0;
17585 +diff -urNp linux-2.6.26.6/fs/ext3/balloc.c linux-2.6.26.6/fs/ext3/balloc.c
17586 +--- linux-2.6.26.6/fs/ext3/balloc.c 2008-10-08 23:24:05.000000000 -0400
17587 ++++ linux-2.6.26.6/fs/ext3/balloc.c 2008-10-11 21:54:20.000000000 -0400
17588 +@@ -1421,7 +1421,7 @@ static int ext3_has_free_blocks(struct e
17589 +
17590 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
17591 + root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
17592 +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
17593 ++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
17594 + sbi->s_resuid != current->fsuid &&
17595 + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
17596 + return 0;
17597 +diff -urNp linux-2.6.26.6/fs/ext3/namei.c linux-2.6.26.6/fs/ext3/namei.c
17598 +--- linux-2.6.26.6/fs/ext3/namei.c 2008-10-08 23:24:05.000000000 -0400
17599 ++++ linux-2.6.26.6/fs/ext3/namei.c 2008-10-11 21:54:20.000000000 -0400
17600 +@@ -1171,9 +1171,9 @@ static struct ext3_dir_entry_2 *do_split
17601 + u32 hash2;
17602 + struct dx_map_entry *map;
17603 + char *data1 = (*bh)->b_data, *data2;
17604 +- unsigned split, move, size, i;
17605 ++ unsigned split, move, size;
17606 + struct ext3_dir_entry_2 *de = NULL, *de2;
17607 +- int err = 0;
17608 ++ int i, err = 0;
17609 +
17610 + bh2 = ext3_append (handle, dir, &newblock, &err);
17611 + if (!(bh2)) {
17612 +diff -urNp linux-2.6.26.6/fs/ext3/xattr.c linux-2.6.26.6/fs/ext3/xattr.c
17613 +--- linux-2.6.26.6/fs/ext3/xattr.c 2008-10-08 23:24:05.000000000 -0400
17614 ++++ linux-2.6.26.6/fs/ext3/xattr.c 2008-10-11 21:54:20.000000000 -0400
17615 +@@ -89,8 +89,8 @@
17616 + printk("\n"); \
17617 + } while (0)
17618 + #else
17619 +-# define ea_idebug(f...)
17620 +-# define ea_bdebug(f...)
17621 ++# define ea_idebug(f...) do {} while (0)
17622 ++# define ea_bdebug(f...) do {} while (0)
17623 + #endif
17624 +
17625 + static void ext3_xattr_cache_insert(struct buffer_head *);
17626 +diff -urNp linux-2.6.26.6/fs/ext4/balloc.c linux-2.6.26.6/fs/ext4/balloc.c
17627 +--- linux-2.6.26.6/fs/ext4/balloc.c 2008-10-08 23:24:05.000000000 -0400
17628 ++++ linux-2.6.26.6/fs/ext4/balloc.c 2008-10-11 21:54:20.000000000 -0400
17629 +@@ -1608,7 +1608,7 @@ static int ext4_has_free_blocks(struct e
17630 +
17631 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
17632 + root_blocks = ext4_r_blocks_count(sbi->s_es);
17633 +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
17634 ++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
17635 + sbi->s_resuid != current->fsuid &&
17636 + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
17637 + return 0;
17638 +diff -urNp linux-2.6.26.6/fs/ext4/namei.c linux-2.6.26.6/fs/ext4/namei.c
17639 +--- linux-2.6.26.6/fs/ext4/namei.c 2008-10-08 23:24:05.000000000 -0400
17640 ++++ linux-2.6.26.6/fs/ext4/namei.c 2008-10-11 21:54:20.000000000 -0400
17641 +@@ -1173,9 +1173,9 @@ static struct ext4_dir_entry_2 *do_split
17642 + u32 hash2;
17643 + struct dx_map_entry *map;
17644 + char *data1 = (*bh)->b_data, *data2;
17645 +- unsigned split, move, size, i;
17646 ++ unsigned split, move, size;
17647 + struct ext4_dir_entry_2 *de = NULL, *de2;
17648 +- int err = 0;
17649 ++ int i, err = 0;
17650 +
17651 + bh2 = ext4_append (handle, dir, &newblock, &err);
17652 + if (!(bh2)) {
17653 +diff -urNp linux-2.6.26.6/fs/fcntl.c linux-2.6.26.6/fs/fcntl.c
17654 +--- linux-2.6.26.6/fs/fcntl.c 2008-10-08 23:24:05.000000000 -0400
17655 ++++ linux-2.6.26.6/fs/fcntl.c 2008-10-11 21:54:20.000000000 -0400
17656 +@@ -20,6 +20,7 @@
17657 + #include <linux/signal.h>
17658 + #include <linux/rcupdate.h>
17659 + #include <linux/pid_namespace.h>
17660 ++#include <linux/grsecurity.h>
17661 +
17662 + #include <asm/poll.h>
17663 + #include <asm/siginfo.h>
17664 +@@ -67,6 +68,7 @@ static int locate_fd(unsigned int orig_s
17665 + spin_lock(&files->file_lock);
17666 +
17667 + error = -EINVAL;
17668 ++ gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
17669 + if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
17670 + goto out;
17671 +
17672 +@@ -86,6 +88,7 @@ repeat:
17673 + fdt->max_fds, start);
17674 +
17675 + error = -EMFILE;
17676 ++ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
17677 + if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
17678 + goto out;
17679 +
17680 +@@ -133,6 +136,8 @@ asmlinkage long sys_dup2(unsigned int ol
17681 + struct files_struct * files = current->files;
17682 + struct fdtable *fdt;
17683 +
17684 ++ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
17685 ++
17686 + spin_lock(&files->file_lock);
17687 + if (!(file = fcheck(oldfd)))
17688 + goto out_unlock;
17689 +@@ -452,7 +457,8 @@ static inline int sigio_perm(struct task
17690 + return (((fown->euid == 0) ||
17691 + (fown->euid == p->suid) || (fown->euid == p->uid) ||
17692 + (fown->uid == p->suid) || (fown->uid == p->uid)) &&
17693 +- !security_file_send_sigiotask(p, fown, sig));
17694 ++ !security_file_send_sigiotask(p, fown, sig) &&
17695 ++ !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
17696 + }
17697 +
17698 + static void send_sigio_to_task(struct task_struct *p,
17699 +diff -urNp linux-2.6.26.6/fs/fuse/control.c linux-2.6.26.6/fs/fuse/control.c
17700 +--- linux-2.6.26.6/fs/fuse/control.c 2008-10-08 23:24:05.000000000 -0400
17701 ++++ linux-2.6.26.6/fs/fuse/control.c 2008-10-11 21:54:20.000000000 -0400
17702 +@@ -159,7 +159,7 @@ void fuse_ctl_remove_conn(struct fuse_co
17703 +
17704 + static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
17705 + {
17706 +- struct tree_descr empty_descr = {""};
17707 ++ struct tree_descr empty_descr = {"", NULL, 0};
17708 + struct fuse_conn *fc;
17709 + int err;
17710 +
17711 +diff -urNp linux-2.6.26.6/fs/fuse/dir.c linux-2.6.26.6/fs/fuse/dir.c
17712 +--- linux-2.6.26.6/fs/fuse/dir.c 2008-10-08 23:24:05.000000000 -0400
17713 ++++ linux-2.6.26.6/fs/fuse/dir.c 2008-10-11 21:54:20.000000000 -0400
17714 +@@ -1031,7 +1031,7 @@ static char *read_link(struct dentry *de
17715 + return link;
17716 + }
17717 +
17718 +-static void free_link(char *link)
17719 ++static void free_link(const char *link)
17720 + {
17721 + if (!IS_ERR(link))
17722 + free_page((unsigned long) link);
17723 +diff -urNp linux-2.6.26.6/fs/hfs/inode.c linux-2.6.26.6/fs/hfs/inode.c
17724 +--- linux-2.6.26.6/fs/hfs/inode.c 2008-10-08 23:24:05.000000000 -0400
17725 ++++ linux-2.6.26.6/fs/hfs/inode.c 2008-10-11 21:54:20.000000000 -0400
17726 +@@ -419,7 +419,7 @@ int hfs_write_inode(struct inode *inode,
17727 +
17728 + if (S_ISDIR(main_inode->i_mode)) {
17729 + if (fd.entrylength < sizeof(struct hfs_cat_dir))
17730 +- /* panic? */;
17731 ++ {/* panic? */}
17732 + hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
17733 + sizeof(struct hfs_cat_dir));
17734 + if (rec.type != HFS_CDR_DIR ||
17735 +@@ -440,7 +440,7 @@ int hfs_write_inode(struct inode *inode,
17736 + sizeof(struct hfs_cat_file));
17737 + } else {
17738 + if (fd.entrylength < sizeof(struct hfs_cat_file))
17739 +- /* panic? */;
17740 ++ {/* panic? */}
17741 + hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
17742 + sizeof(struct hfs_cat_file));
17743 + if (rec.type != HFS_CDR_FIL ||
17744 +diff -urNp linux-2.6.26.6/fs/hfsplus/inode.c linux-2.6.26.6/fs/hfsplus/inode.c
17745 +--- linux-2.6.26.6/fs/hfsplus/inode.c 2008-10-08 23:24:05.000000000 -0400
17746 ++++ linux-2.6.26.6/fs/hfsplus/inode.c 2008-10-11 21:54:20.000000000 -0400
17747 +@@ -421,7 +421,7 @@ int hfsplus_cat_read_inode(struct inode
17748 + struct hfsplus_cat_folder *folder = &entry.folder;
17749 +
17750 + if (fd->entrylength < sizeof(struct hfsplus_cat_folder))
17751 +- /* panic? */;
17752 ++ {/* panic? */}
17753 + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
17754 + sizeof(struct hfsplus_cat_folder));
17755 + hfsplus_get_perms(inode, &folder->permissions, 1);
17756 +@@ -438,7 +438,7 @@ int hfsplus_cat_read_inode(struct inode
17757 + struct hfsplus_cat_file *file = &entry.file;
17758 +
17759 + if (fd->entrylength < sizeof(struct hfsplus_cat_file))
17760 +- /* panic? */;
17761 ++ {/* panic? */}
17762 + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
17763 + sizeof(struct hfsplus_cat_file));
17764 +
17765 +@@ -494,7 +494,7 @@ int hfsplus_cat_write_inode(struct inode
17766 + struct hfsplus_cat_folder *folder = &entry.folder;
17767 +
17768 + if (fd.entrylength < sizeof(struct hfsplus_cat_folder))
17769 +- /* panic? */;
17770 ++ {/* panic? */}
17771 + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
17772 + sizeof(struct hfsplus_cat_folder));
17773 + /* simple node checks? */
17774 +@@ -516,7 +516,7 @@ int hfsplus_cat_write_inode(struct inode
17775 + struct hfsplus_cat_file *file = &entry.file;
17776 +
17777 + if (fd.entrylength < sizeof(struct hfsplus_cat_file))
17778 +- /* panic? */;
17779 ++ {/* panic? */}
17780 + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
17781 + sizeof(struct hfsplus_cat_file));
17782 + hfsplus_inode_write_fork(inode, &file->data_fork);
17783 +diff -urNp linux-2.6.26.6/fs/jffs2/debug.h linux-2.6.26.6/fs/jffs2/debug.h
17784 +--- linux-2.6.26.6/fs/jffs2/debug.h 2008-10-08 23:24:05.000000000 -0400
17785 ++++ linux-2.6.26.6/fs/jffs2/debug.h 2008-10-11 21:54:20.000000000 -0400
17786 +@@ -52,13 +52,13 @@
17787 + #if CONFIG_JFFS2_FS_DEBUG > 0
17788 + #define D1(x) x
17789 + #else
17790 +-#define D1(x)
17791 ++#define D1(x) do {} while (0);
17792 + #endif
17793 +
17794 + #if CONFIG_JFFS2_FS_DEBUG > 1
17795 + #define D2(x) x
17796 + #else
17797 +-#define D2(x)
17798 ++#define D2(x) do {} while (0);
17799 + #endif
17800 +
17801 + /* The prefixes of JFFS2 messages */
17802 +@@ -114,73 +114,73 @@
17803 + #ifdef JFFS2_DBG_READINODE_MESSAGES
17804 + #define dbg_readinode(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
17805 + #else
17806 +-#define dbg_readinode(fmt, ...)
17807 ++#define dbg_readinode(fmt, ...) do {} while (0)
17808 + #endif
17809 + #ifdef JFFS2_DBG_READINODE2_MESSAGES
17810 + #define dbg_readinode2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
17811 + #else
17812 +-#define dbg_readinode2(fmt, ...)
17813 ++#define dbg_readinode2(fmt, ...) do {} while (0)
17814 + #endif
17815 +
17816 + /* Fragtree build debugging messages */
17817 + #ifdef JFFS2_DBG_FRAGTREE_MESSAGES
17818 + #define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
17819 + #else
17820 +-#define dbg_fragtree(fmt, ...)
17821 ++#define dbg_fragtree(fmt, ...) do {} while (0)
17822 + #endif
17823 + #ifdef JFFS2_DBG_FRAGTREE2_MESSAGES
17824 + #define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
17825 + #else
17826 +-#define dbg_fragtree2(fmt, ...)
17827 ++#define dbg_fragtree2(fmt, ...) do {} while (0)
17828 + #endif
17829 +
17830 + /* Directory entry list manilulation debugging messages */
17831 + #ifdef JFFS2_DBG_DENTLIST_MESSAGES
17832 + #define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
17833 + #else
17834 +-#define dbg_dentlist(fmt, ...)
17835 ++#define dbg_dentlist(fmt, ...) do {} while (0)
17836 + #endif
17837 +
17838 + /* Print the messages about manipulating node_refs */
17839 + #ifdef JFFS2_DBG_NODEREF_MESSAGES
17840 + #define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
17841 + #else
17842 +-#define dbg_noderef(fmt, ...)
17843 ++#define dbg_noderef(fmt, ...) do {} while (0)
17844 + #endif
17845 +
17846 + /* Manipulations with the list of inodes (JFFS2 inocache) */
17847 + #ifdef JFFS2_DBG_INOCACHE_MESSAGES
17848 + #define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
17849 + #else
17850 +-#define dbg_inocache(fmt, ...)
17851 ++#define dbg_inocache(fmt, ...) do {} while (0)
17852 + #endif
17853 +
17854 + /* Summary debugging messages */
17855 + #ifdef JFFS2_DBG_SUMMARY_MESSAGES
17856 + #define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
17857 + #else
17858 +-#define dbg_summary(fmt, ...)
17859 ++#define dbg_summary(fmt, ...) do {} while (0)
17860 + #endif
17861 +
17862 + /* File system build messages */
17863 + #ifdef JFFS2_DBG_FSBUILD_MESSAGES
17864 + #define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
17865 + #else
17866 +-#define dbg_fsbuild(fmt, ...)
17867 ++#define dbg_fsbuild(fmt, ...) do {} while (0)
17868 + #endif
17869 +
17870 + /* Watch the object allocations */
17871 + #ifdef JFFS2_DBG_MEMALLOC_MESSAGES
17872 + #define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
17873 + #else
17874 +-#define dbg_memalloc(fmt, ...)
17875 ++#define dbg_memalloc(fmt, ...) do {} while (0)
17876 + #endif
17877 +
17878 + /* Watch the XATTR subsystem */
17879 + #ifdef JFFS2_DBG_XATTR_MESSAGES
17880 + #define dbg_xattr(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
17881 + #else
17882 +-#define dbg_xattr(fmt, ...)
17883 ++#define dbg_xattr(fmt, ...) do {} while (0)
17884 + #endif
17885 +
17886 + /* "Sanity" checks */
17887 +diff -urNp linux-2.6.26.6/fs/jffs2/erase.c linux-2.6.26.6/fs/jffs2/erase.c
17888 +--- linux-2.6.26.6/fs/jffs2/erase.c 2008-10-08 23:24:05.000000000 -0400
17889 ++++ linux-2.6.26.6/fs/jffs2/erase.c 2008-10-11 21:54:20.000000000 -0400
17890 +@@ -431,7 +431,8 @@ static void jffs2_mark_erased_block(stru
17891 + struct jffs2_unknown_node marker = {
17892 + .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
17893 + .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
17894 +- .totlen = cpu_to_je32(c->cleanmarker_size)
17895 ++ .totlen = cpu_to_je32(c->cleanmarker_size),
17896 ++ .hdr_crc = cpu_to_je32(0)
17897 + };
17898 +
17899 + jffs2_prealloc_raw_node_refs(c, jeb, 1);
17900 +diff -urNp linux-2.6.26.6/fs/jffs2/summary.h linux-2.6.26.6/fs/jffs2/summary.h
17901 +--- linux-2.6.26.6/fs/jffs2/summary.h 2008-10-08 23:24:05.000000000 -0400
17902 ++++ linux-2.6.26.6/fs/jffs2/summary.h 2008-10-11 21:54:20.000000000 -0400
17903 +@@ -188,18 +188,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_
17904 +
17905 + #define jffs2_sum_active() (0)
17906 + #define jffs2_sum_init(a) (0)
17907 +-#define jffs2_sum_exit(a)
17908 +-#define jffs2_sum_disable_collecting(a)
17909 ++#define jffs2_sum_exit(a) do {} while (0)
17910 ++#define jffs2_sum_disable_collecting(a) do {} while (0)
17911 + #define jffs2_sum_is_disabled(a) (0)
17912 +-#define jffs2_sum_reset_collected(a)
17913 ++#define jffs2_sum_reset_collected(a) do {} while (0)
17914 + #define jffs2_sum_add_kvec(a,b,c,d) (0)
17915 +-#define jffs2_sum_move_collected(a,b)
17916 ++#define jffs2_sum_move_collected(a,b) do {} while (0)
17917 + #define jffs2_sum_write_sumnode(a) (0)
17918 +-#define jffs2_sum_add_padding_mem(a,b)
17919 +-#define jffs2_sum_add_inode_mem(a,b,c)
17920 +-#define jffs2_sum_add_dirent_mem(a,b,c)
17921 +-#define jffs2_sum_add_xattr_mem(a,b,c)
17922 +-#define jffs2_sum_add_xref_mem(a,b,c)
17923 ++#define jffs2_sum_add_padding_mem(a,b) do {} while (0)
17924 ++#define jffs2_sum_add_inode_mem(a,b,c) do {} while (0)
17925 ++#define jffs2_sum_add_dirent_mem(a,b,c) do {} while (0)
17926 ++#define jffs2_sum_add_xattr_mem(a,b,c) do {} while (0)
17927 ++#define jffs2_sum_add_xref_mem(a,b,c) do {} while (0)
17928 + #define jffs2_sum_scan_sumnode(a,b,c,d,e) (0)
17929 +
17930 + #endif /* CONFIG_JFFS2_SUMMARY */
17931 +diff -urNp linux-2.6.26.6/fs/jffs2/wbuf.c linux-2.6.26.6/fs/jffs2/wbuf.c
17932 +--- linux-2.6.26.6/fs/jffs2/wbuf.c 2008-10-08 23:24:05.000000000 -0400
17933 ++++ linux-2.6.26.6/fs/jffs2/wbuf.c 2008-10-11 21:54:20.000000000 -0400
17934 +@@ -1015,7 +1015,8 @@ static const struct jffs2_unknown_node o
17935 + {
17936 + .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK),
17937 + .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
17938 +- .totlen = constant_cpu_to_je32(8)
17939 ++ .totlen = constant_cpu_to_je32(8),
17940 ++ .hdr_crc = constant_cpu_to_je32(0)
17941 + };
17942 +
17943 + /*
17944 +diff -urNp linux-2.6.26.6/fs/Kconfig linux-2.6.26.6/fs/Kconfig
17945 +--- linux-2.6.26.6/fs/Kconfig 2008-10-08 23:24:05.000000000 -0400
17946 ++++ linux-2.6.26.6/fs/Kconfig 2008-10-11 21:54:20.000000000 -0400
17947 +@@ -926,12 +926,12 @@ config PROC_FS
17948 +
17949 + config PROC_KCORE
17950 + bool "/proc/kcore support" if !ARM
17951 +- depends on PROC_FS && MMU
17952 ++ depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
17953 +
17954 + config PROC_VMCORE
17955 + bool "/proc/vmcore support (EXPERIMENTAL)"
17956 +- depends on PROC_FS && EXPERIMENTAL && CRASH_DUMP
17957 +- default y
17958 ++ depends on PROC_FS && EXPERIMENTAL && CRASH_DUMP && !GRKERNSEC
17959 ++ default n
17960 + help
17961 + Exports the dump image of crashed kernel in ELF format.
17962 +
17963 +diff -urNp linux-2.6.26.6/fs/locks.c linux-2.6.26.6/fs/locks.c
17964 +--- linux-2.6.26.6/fs/locks.c 2008-10-08 23:24:05.000000000 -0400
17965 ++++ linux-2.6.26.6/fs/locks.c 2008-10-11 21:55:52.000000000 -0400
17966 +@@ -2019,16 +2019,16 @@ void locks_remove_flock(struct file *fil
17967 + return;
17968 +
17969 + if (filp->f_op && filp->f_op->flock) {
17970 +- struct file_lock fl = {
17971 ++ struct file_lock flock = {
17972 + .fl_pid = current->tgid,
17973 + .fl_file = filp,
17974 + .fl_flags = FL_FLOCK,
17975 + .fl_type = F_UNLCK,
17976 + .fl_end = OFFSET_MAX,
17977 + };
17978 +- filp->f_op->flock(filp, F_SETLKW, &fl);
17979 +- if (fl.fl_ops && fl.fl_ops->fl_release_private)
17980 +- fl.fl_ops->fl_release_private(&fl);
17981 ++ filp->f_op->flock(filp, F_SETLKW, &flock);
17982 ++ if (flock.fl_ops && flock.fl_ops->fl_release_private)
17983 ++ flock.fl_ops->fl_release_private(&flock);
17984 + }
17985 +
17986 + lock_kernel();
17987 +diff -urNp linux-2.6.26.6/fs/namei.c linux-2.6.26.6/fs/namei.c
17988 +--- linux-2.6.26.6/fs/namei.c 2008-10-08 23:24:05.000000000 -0400
17989 ++++ linux-2.6.26.6/fs/namei.c 2008-10-11 21:54:20.000000000 -0400
17990 +@@ -31,6 +31,7 @@
17991 + #include <linux/file.h>
17992 + #include <linux/fcntl.h>
17993 + #include <linux/device_cgroup.h>
17994 ++#include <linux/grsecurity.h>
17995 + #include <asm/namei.h>
17996 + #include <asm/uaccess.h>
17997 +
17998 +@@ -673,7 +674,7 @@ static __always_inline int __do_follow_l
17999 + cookie = dentry->d_inode->i_op->follow_link(dentry, nd);
18000 + error = PTR_ERR(cookie);
18001 + if (!IS_ERR(cookie)) {
18002 +- char *s = nd_get_link(nd);
18003 ++ const char *s = nd_get_link(nd);
18004 + error = 0;
18005 + if (s)
18006 + error = __vfs_follow_link(nd, s);
18007 +@@ -704,6 +705,13 @@ static inline int do_follow_link(struct
18008 + err = security_inode_follow_link(path->dentry, nd);
18009 + if (err)
18010 + goto loop;
18011 ++
18012 ++ if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
18013 ++ path->dentry->d_inode, path->dentry, nd->path.mnt)) {
18014 ++ err = -EACCES;
18015 ++ goto loop;
18016 ++ }
18017 ++
18018 + current->link_count++;
18019 + current->total_link_count++;
18020 + nd->depth++;
18021 +@@ -1052,11 +1060,18 @@ return_reval:
18022 + break;
18023 + }
18024 + return_base:
18025 ++ if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt)) {
18026 ++ path_put(&nd->path);
18027 ++ return -ENOENT;
18028 ++ }
18029 + return 0;
18030 + out_dput:
18031 + path_put_conditional(&next, nd);
18032 + break;
18033 + }
18034 ++ if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt))
18035 ++ err = -ENOENT;
18036 ++
18037 + path_put(&nd->path);
18038 + return_err:
18039 + return err;
18040 +@@ -1706,9 +1721,17 @@ static int __open_namei_create(struct na
18041 + int error;
18042 + struct dentry *dir = nd->path.dentry;
18043 +
18044 ++ if (!gr_acl_handle_creat(path->dentry, nd->path.dentry, nd->path.mnt, flag, mode)) {
18045 ++ error = -EACCES;
18046 ++ goto out_unlock_dput;
18047 ++ }
18048 ++
18049 + if (!IS_POSIXACL(dir->d_inode))
18050 + mode &= ~current->fs->umask;
18051 + error = vfs_create(dir->d_inode, path->dentry, mode, nd);
18052 ++ if (!error)
18053 ++ gr_handle_create(path->dentry, nd->path.mnt);
18054 ++out_unlock_dput:
18055 + mutex_unlock(&dir->d_inode->i_mutex);
18056 + dput(nd->path.dentry);
18057 + nd->path.dentry = path->dentry;
18058 +@@ -1789,6 +1812,17 @@ struct file *do_filp_open(int dfd, const
18059 + &nd, flag);
18060 + if (error)
18061 + return ERR_PTR(error);
18062 ++
18063 ++ if (gr_handle_rawio(nd.path.dentry->d_inode)) {
18064 ++ error = -EPERM;
18065 ++ goto exit;
18066 ++ }
18067 ++
18068 ++ if (!gr_acl_handle_open(nd.path.dentry, nd.path.mnt, flag)) {
18069 ++ error = -EACCES;
18070 ++ goto exit;
18071 ++ }
18072 ++
18073 + goto ok;
18074 + }
18075 +
18076 +@@ -1852,6 +1886,20 @@ do_last:
18077 + /*
18078 + * It already exists.
18079 + */
18080 ++
18081 ++ if (gr_handle_rawio(path.dentry->d_inode)) {
18082 ++ error = -EPERM;
18083 ++ goto exit_mutex_unlock;
18084 ++ }
18085 ++ if (!gr_acl_handle_open(path.dentry, nd.path.mnt, flag)) {
18086 ++ error = -EACCES;
18087 ++ goto exit_mutex_unlock;
18088 ++ }
18089 ++ if (gr_handle_fifo(path.dentry, nd.path.mnt, dir, flag, acc_mode)) {
18090 ++ error = -EACCES;
18091 ++ goto exit_mutex_unlock;
18092 ++ }
18093 ++
18094 + mutex_unlock(&dir->d_inode->i_mutex);
18095 + audit_inode(pathname, path.dentry);
18096 +
18097 +@@ -1936,6 +1984,13 @@ do_link:
18098 + error = security_inode_follow_link(path.dentry, &nd);
18099 + if (error)
18100 + goto exit_dput;
18101 ++
18102 ++ if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
18103 ++ path.dentry, nd.path.mnt)) {
18104 ++ error = -EACCES;
18105 ++ goto exit_dput;
18106 ++ }
18107 ++
18108 + error = __do_follow_link(&path, &nd);
18109 + if (error) {
18110 + /* Does someone understand code flow here? Or it is only
18111 +@@ -2110,9 +2165,21 @@ asmlinkage long sys_mknodat(int dfd, con
18112 + error = may_mknod(mode);
18113 + if (error)
18114 + goto out_dput;
18115 ++
18116 ++ if (gr_handle_chroot_mknod(dentry, nd.path.mnt, mode)) {
18117 ++ error = -EPERM;
18118 ++ goto out_dput;
18119 ++ }
18120 ++
18121 ++ if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
18122 ++ error = -EACCES;
18123 ++ goto out_dput;
18124 ++ }
18125 ++
18126 + error = mnt_want_write(nd.path.mnt);
18127 + if (error)
18128 + goto out_dput;
18129 ++
18130 + switch (mode & S_IFMT) {
18131 + case 0: case S_IFREG:
18132 + error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd);
18133 +@@ -2126,6 +2193,9 @@ asmlinkage long sys_mknodat(int dfd, con
18134 + break;
18135 + }
18136 + mnt_drop_write(nd.path.mnt);
18137 ++
18138 ++ if (!error)
18139 ++ gr_handle_create(dentry, nd.path.mnt);
18140 + out_dput:
18141 + dput(dentry);
18142 + out_unlock:
18143 +@@ -2184,6 +2254,11 @@ asmlinkage long sys_mkdirat(int dfd, con
18144 + if (IS_ERR(dentry))
18145 + goto out_unlock;
18146 +
18147 ++ if (!gr_acl_handle_mkdir(dentry, nd.path.dentry, nd.path.mnt)) {
18148 ++ error = -EACCES;
18149 ++ goto out_dput;
18150 ++ }
18151 ++
18152 + if (!IS_POSIXACL(nd.path.dentry->d_inode))
18153 + mode &= ~current->fs->umask;
18154 + error = mnt_want_write(nd.path.mnt);
18155 +@@ -2191,6 +2266,10 @@ asmlinkage long sys_mkdirat(int dfd, con
18156 + goto out_dput;
18157 + error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
18158 + mnt_drop_write(nd.path.mnt);
18159 ++
18160 ++ if (!error)
18161 ++ gr_handle_create(dentry, nd.path.mnt);
18162 ++
18163 + out_dput:
18164 + dput(dentry);
18165 + out_unlock:
18166 +@@ -2273,6 +2352,8 @@ static long do_rmdir(int dfd, const char
18167 + char * name;
18168 + struct dentry *dentry;
18169 + struct nameidata nd;
18170 ++ ino_t saved_ino = 0;
18171 ++ dev_t saved_dev = 0;
18172 +
18173 + name = getname(pathname);
18174 + if(IS_ERR(name))
18175 +@@ -2298,11 +2379,26 @@ static long do_rmdir(int dfd, const char
18176 + error = PTR_ERR(dentry);
18177 + if (IS_ERR(dentry))
18178 + goto exit2;
18179 ++
18180 ++ if (dentry->d_inode != NULL) {
18181 ++ if (dentry->d_inode->i_nlink <= 1) {
18182 ++ saved_ino = dentry->d_inode->i_ino;
18183 ++ saved_dev = dentry->d_inode->i_sb->s_dev;
18184 ++ }
18185 ++
18186 ++ if (!gr_acl_handle_rmdir(dentry, nd.path.mnt)) {
18187 ++ error = -EACCES;
18188 ++ goto exit3;
18189 ++ }
18190 ++ }
18191 ++
18192 + error = mnt_want_write(nd.path.mnt);
18193 + if (error)
18194 + goto exit3;
18195 + error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
18196 + mnt_drop_write(nd.path.mnt);
18197 ++ if (!error && (saved_dev || saved_ino))
18198 ++ gr_handle_delete(saved_ino, saved_dev);
18199 + exit3:
18200 + dput(dentry);
18201 + exit2:
18202 +@@ -2363,6 +2459,8 @@ static long do_unlinkat(int dfd, const c
18203 + struct dentry *dentry;
18204 + struct nameidata nd;
18205 + struct inode *inode = NULL;
18206 ++ ino_t saved_ino = 0;
18207 ++ dev_t saved_dev = 0;
18208 +
18209 + name = getname(pathname);
18210 + if(IS_ERR(name))
18211 +@@ -2382,12 +2480,25 @@ static long do_unlinkat(int dfd, const c
18212 + if (nd.last.name[nd.last.len])
18213 + goto slashes;
18214 + inode = dentry->d_inode;
18215 +- if (inode)
18216 ++ if (inode) {
18217 ++ if (inode->i_nlink <= 1) {
18218 ++ saved_ino = inode->i_ino;
18219 ++ saved_dev = inode->i_sb->s_dev;
18220 ++ }
18221 ++
18222 + atomic_inc(&inode->i_count);
18223 ++
18224 ++ if (!gr_acl_handle_unlink(dentry, nd.path.mnt)) {
18225 ++ error = -EACCES;
18226 ++ goto exit2;
18227 ++ }
18228 ++ }
18229 + error = mnt_want_write(nd.path.mnt);
18230 + if (error)
18231 + goto exit2;
18232 + error = vfs_unlink(nd.path.dentry->d_inode, dentry);
18233 ++ if (!error && (saved_ino || saved_dev))
18234 ++ gr_handle_delete(saved_ino, saved_dev);
18235 + mnt_drop_write(nd.path.mnt);
18236 + exit2:
18237 + dput(dentry);
18238 +@@ -2469,10 +2580,18 @@ asmlinkage long sys_symlinkat(const char
18239 + if (IS_ERR(dentry))
18240 + goto out_unlock;
18241 +
18242 ++ if (!gr_acl_handle_symlink(dentry, nd.path.dentry, nd.path.mnt, from)) {
18243 ++ error = -EACCES;
18244 ++ goto out_dput;
18245 ++ }
18246 ++
18247 + error = mnt_want_write(nd.path.mnt);
18248 + if (error)
18249 + goto out_dput;
18250 ++
18251 + error = vfs_symlink(nd.path.dentry->d_inode, dentry, from, S_IALLUGO);
18252 ++ if (!error)
18253 ++ gr_handle_create(dentry, nd.path.mnt);
18254 + mnt_drop_write(nd.path.mnt);
18255 + out_dput:
18256 + dput(dentry);
18257 +@@ -2569,10 +2688,26 @@ asmlinkage long sys_linkat(int olddfd, c
18258 + error = PTR_ERR(new_dentry);
18259 + if (IS_ERR(new_dentry))
18260 + goto out_unlock;
18261 ++
18262 ++ if (gr_handle_hardlink(old_nd.path.dentry, old_nd.path.mnt,
18263 ++ old_nd.path.dentry->d_inode,
18264 ++ old_nd.path.dentry->d_inode->i_mode, to)) {
18265 ++ error = -EACCES;
18266 ++ goto out_dput;
18267 ++ }
18268 ++
18269 ++ if (!gr_acl_handle_link(new_dentry, nd.path.dentry, nd.path.mnt,
18270 ++ old_nd.path.dentry, old_nd.path.mnt, to)) {
18271 ++ error = -EACCES;
18272 ++ goto out_dput;
18273 ++ }
18274 ++
18275 + error = mnt_want_write(nd.path.mnt);
18276 + if (error)
18277 + goto out_dput;
18278 + error = vfs_link(old_nd.path.dentry, nd.path.dentry->d_inode, new_dentry);
18279 ++ if (!error)
18280 ++ gr_handle_create(new_dentry, nd.path.mnt);
18281 + mnt_drop_write(nd.path.mnt);
18282 + out_dput:
18283 + dput(new_dentry);
18284 +@@ -2729,8 +2864,10 @@ int vfs_rename(struct inode *old_dir, st
18285 + error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
18286 + else
18287 + error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
18288 ++
18289 + if (!error) {
18290 + const char *new_name = old_dentry->d_name.name;
18291 ++
18292 + fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir,
18293 + new_dentry->d_inode, old_dentry);
18294 + }
18295 +@@ -2800,11 +2937,21 @@ static int do_rename(int olddfd, const c
18296 + if (new_dentry == trap)
18297 + goto exit5;
18298 +
18299 ++ error = gr_acl_handle_rename(new_dentry, newnd.path.dentry, newnd.path.mnt,
18300 ++ old_dentry, old_dir->d_inode, oldnd.path.mnt,
18301 ++ newname);
18302 ++ if (error)
18303 ++ goto exit5;
18304 ++
18305 + error = mnt_want_write(oldnd.path.mnt);
18306 + if (error)
18307 + goto exit5;
18308 + error = vfs_rename(old_dir->d_inode, old_dentry,
18309 + new_dir->d_inode, new_dentry);
18310 ++ if (!error)
18311 ++ gr_handle_rename(old_dir->d_inode, newnd.path.dentry->d_inode, old_dentry,
18312 ++ new_dentry, oldnd.path.mnt, new_dentry->d_inode ? 1 : 0);
18313 ++
18314 + mnt_drop_write(oldnd.path.mnt);
18315 + exit5:
18316 + dput(new_dentry);
18317 +diff -urNp linux-2.6.26.6/fs/namespace.c linux-2.6.26.6/fs/namespace.c
18318 +--- linux-2.6.26.6/fs/namespace.c 2008-10-08 23:24:05.000000000 -0400
18319 ++++ linux-2.6.26.6/fs/namespace.c 2008-10-11 21:54:20.000000000 -0400
18320 +@@ -27,6 +27,7 @@
18321 + #include <linux/ramfs.h>
18322 + #include <linux/log2.h>
18323 + #include <linux/idr.h>
18324 ++#include <linux/grsecurity.h>
18325 + #include <asm/uaccess.h>
18326 + #include <asm/unistd.h>
18327 + #include "pnode.h"
18328 +@@ -1085,6 +1086,8 @@ static int do_umount(struct vfsmount *mn
18329 + lock_kernel();
18330 + retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
18331 + unlock_kernel();
18332 ++
18333 ++ gr_log_remount(mnt->mnt_devname, retval);
18334 + }
18335 + up_write(&sb->s_umount);
18336 + return retval;
18337 +@@ -1108,6 +1111,9 @@ static int do_umount(struct vfsmount *mn
18338 + security_sb_umount_busy(mnt);
18339 + up_write(&namespace_sem);
18340 + release_mounts(&umount_list);
18341 ++
18342 ++ gr_log_unmount(mnt->mnt_devname, retval);
18343 ++
18344 + return retval;
18345 + }
18346 +
18347 +@@ -1940,6 +1946,11 @@ long do_mount(char *dev_name, char *dir_
18348 + if (retval)
18349 + goto dput_out;
18350 +
18351 ++ if (gr_handle_chroot_mount(nd.path.dentry, nd.path.mnt, dev_name)) {
18352 ++ retval = -EPERM;
18353 ++ goto dput_out;
18354 ++ }
18355 ++
18356 + if (flags & MS_REMOUNT)
18357 + retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
18358 + data_page);
18359 +@@ -1954,6 +1965,9 @@ long do_mount(char *dev_name, char *dir_
18360 + dev_name, data_page);
18361 + dput_out:
18362 + path_put(&nd.path);
18363 ++
18364 ++ gr_log_mount(dev_name, dir_name, retval);
18365 ++
18366 + return retval;
18367 + }
18368 +
18369 +@@ -2072,6 +2086,9 @@ asmlinkage long sys_mount(char __user *
18370 + if (retval < 0)
18371 + goto out3;
18372 +
18373 ++ if (gr_handle_chroot_pivot())
18374 ++ return -EPERM;
18375 ++
18376 + lock_kernel();
18377 + retval = do_mount((char *)dev_page, dir_page, (char *)type_page,
18378 + flags, (void *)data_page);
18379 +diff -urNp linux-2.6.26.6/fs/nfs/nfs4proc.c linux-2.6.26.6/fs/nfs/nfs4proc.c
18380 +--- linux-2.6.26.6/fs/nfs/nfs4proc.c 2008-10-08 23:24:05.000000000 -0400
18381 ++++ linux-2.6.26.6/fs/nfs/nfs4proc.c 2008-10-11 21:54:20.000000000 -0400
18382 +@@ -655,7 +655,7 @@ static int _nfs4_do_open_reclaim(struct
18383 + static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
18384 + {
18385 + struct nfs_server *server = NFS_SERVER(state->inode);
18386 +- struct nfs4_exception exception = { };
18387 ++ struct nfs4_exception exception = {0, 0};
18388 + int err;
18389 + do {
18390 + err = _nfs4_do_open_reclaim(ctx, state);
18391 +@@ -697,7 +697,7 @@ static int _nfs4_open_delegation_recall(
18392 +
18393 + int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
18394 + {
18395 +- struct nfs4_exception exception = { };
18396 ++ struct nfs4_exception exception = {0, 0};
18397 + struct nfs_server *server = NFS_SERVER(state->inode);
18398 + int err;
18399 + do {
18400 +@@ -990,7 +990,7 @@ static int _nfs4_open_expired(struct nfs
18401 + static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
18402 + {
18403 + struct nfs_server *server = NFS_SERVER(state->inode);
18404 +- struct nfs4_exception exception = { };
18405 ++ struct nfs4_exception exception = {0, 0};
18406 + int err;
18407 +
18408 + do {
18409 +@@ -1092,7 +1092,7 @@ out_err:
18410 +
18411 + static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred)
18412 + {
18413 +- struct nfs4_exception exception = { };
18414 ++ struct nfs4_exception exception = {0, 0};
18415 + struct nfs4_state *res;
18416 + int status;
18417 +
18418 +@@ -1181,7 +1181,7 @@ static int nfs4_do_setattr(struct inode
18419 + struct iattr *sattr, struct nfs4_state *state)
18420 + {
18421 + struct nfs_server *server = NFS_SERVER(inode);
18422 +- struct nfs4_exception exception = { };
18423 ++ struct nfs4_exception exception = {0, 0};
18424 + int err;
18425 + do {
18426 + err = nfs4_handle_exception(server,
18427 +@@ -1494,7 +1494,7 @@ static int _nfs4_server_capabilities(str
18428 +
18429 + int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
18430 + {
18431 +- struct nfs4_exception exception = { };
18432 ++ struct nfs4_exception exception = {0, 0};
18433 + int err;
18434 + do {
18435 + err = nfs4_handle_exception(server,
18436 +@@ -1527,7 +1527,7 @@ static int _nfs4_lookup_root(struct nfs_
18437 + static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
18438 + struct nfs_fsinfo *info)
18439 + {
18440 +- struct nfs4_exception exception = { };
18441 ++ struct nfs4_exception exception = {0, 0};
18442 + int err;
18443 + do {
18444 + err = nfs4_handle_exception(server,
18445 +@@ -1616,7 +1616,7 @@ static int _nfs4_proc_getattr(struct nfs
18446 +
18447 + static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
18448 + {
18449 +- struct nfs4_exception exception = { };
18450 ++ struct nfs4_exception exception = {0, 0};
18451 + int err;
18452 + do {
18453 + err = nfs4_handle_exception(server,
18454 +@@ -1706,7 +1706,7 @@ static int nfs4_proc_lookupfh(struct nfs
18455 + struct qstr *name, struct nfs_fh *fhandle,
18456 + struct nfs_fattr *fattr)
18457 + {
18458 +- struct nfs4_exception exception = { };
18459 ++ struct nfs4_exception exception = {0, 0};
18460 + int err;
18461 + do {
18462 + err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr);
18463 +@@ -1735,7 +1735,7 @@ static int _nfs4_proc_lookup(struct inod
18464 +
18465 + static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
18466 + {
18467 +- struct nfs4_exception exception = { };
18468 ++ struct nfs4_exception exception = {0, 0};
18469 + int err;
18470 + do {
18471 + err = nfs4_handle_exception(NFS_SERVER(dir),
18472 +@@ -1799,7 +1799,7 @@ static int _nfs4_proc_access(struct inod
18473 +
18474 + static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
18475 + {
18476 +- struct nfs4_exception exception = { };
18477 ++ struct nfs4_exception exception = {0, 0};
18478 + int err;
18479 + do {
18480 + err = nfs4_handle_exception(NFS_SERVER(inode),
18481 +@@ -1854,7 +1854,7 @@ static int _nfs4_proc_readlink(struct in
18482 + static int nfs4_proc_readlink(struct inode *inode, struct page *page,
18483 + unsigned int pgbase, unsigned int pglen)
18484 + {
18485 +- struct nfs4_exception exception = { };
18486 ++ struct nfs4_exception exception = {0, 0};
18487 + int err;
18488 + do {
18489 + err = nfs4_handle_exception(NFS_SERVER(inode),
18490 +@@ -1950,7 +1950,7 @@ static int _nfs4_proc_remove(struct inod
18491 +
18492 + static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
18493 + {
18494 +- struct nfs4_exception exception = { };
18495 ++ struct nfs4_exception exception = {0, 0};
18496 + int err;
18497 + do {
18498 + err = nfs4_handle_exception(NFS_SERVER(dir),
18499 +@@ -2022,7 +2022,7 @@ static int _nfs4_proc_rename(struct inod
18500 + static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
18501 + struct inode *new_dir, struct qstr *new_name)
18502 + {
18503 +- struct nfs4_exception exception = { };
18504 ++ struct nfs4_exception exception = {0, 0};
18505 + int err;
18506 + do {
18507 + err = nfs4_handle_exception(NFS_SERVER(old_dir),
18508 +@@ -2069,7 +2069,7 @@ static int _nfs4_proc_link(struct inode
18509 +
18510 + static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
18511 + {
18512 +- struct nfs4_exception exception = { };
18513 ++ struct nfs4_exception exception = {0, 0};
18514 + int err;
18515 + do {
18516 + err = nfs4_handle_exception(NFS_SERVER(inode),
18517 +@@ -2126,7 +2126,7 @@ static int _nfs4_proc_symlink(struct ino
18518 + static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
18519 + struct page *page, unsigned int len, struct iattr *sattr)
18520 + {
18521 +- struct nfs4_exception exception = { };
18522 ++ struct nfs4_exception exception = {0, 0};
18523 + int err;
18524 + do {
18525 + err = nfs4_handle_exception(NFS_SERVER(dir),
18526 +@@ -2179,7 +2179,7 @@ static int _nfs4_proc_mkdir(struct inode
18527 + static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
18528 + struct iattr *sattr)
18529 + {
18530 +- struct nfs4_exception exception = { };
18531 ++ struct nfs4_exception exception = {0, 0};
18532 + int err;
18533 + do {
18534 + err = nfs4_handle_exception(NFS_SERVER(dir),
18535 +@@ -2228,7 +2228,7 @@ static int _nfs4_proc_readdir(struct den
18536 + static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
18537 + u64 cookie, struct page *page, unsigned int count, int plus)
18538 + {
18539 +- struct nfs4_exception exception = { };
18540 ++ struct nfs4_exception exception = {0, 0};
18541 + int err;
18542 + do {
18543 + err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode),
18544 +@@ -2298,7 +2298,7 @@ static int _nfs4_proc_mknod(struct inode
18545 + static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
18546 + struct iattr *sattr, dev_t rdev)
18547 + {
18548 +- struct nfs4_exception exception = { };
18549 ++ struct nfs4_exception exception = {0, 0};
18550 + int err;
18551 + do {
18552 + err = nfs4_handle_exception(NFS_SERVER(dir),
18553 +@@ -2327,7 +2327,7 @@ static int _nfs4_proc_statfs(struct nfs_
18554 +
18555 + static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
18556 + {
18557 +- struct nfs4_exception exception = { };
18558 ++ struct nfs4_exception exception = {0, 0};
18559 + int err;
18560 + do {
18561 + err = nfs4_handle_exception(server,
18562 +@@ -2355,7 +2355,7 @@ static int _nfs4_do_fsinfo(struct nfs_se
18563 +
18564 + static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
18565 + {
18566 +- struct nfs4_exception exception = { };
18567 ++ struct nfs4_exception exception = {0, 0};
18568 + int err;
18569 +
18570 + do {
18571 +@@ -2398,7 +2398,7 @@ static int _nfs4_proc_pathconf(struct nf
18572 + static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
18573 + struct nfs_pathconf *pathconf)
18574 + {
18575 +- struct nfs4_exception exception = { };
18576 ++ struct nfs4_exception exception = {0, 0};
18577 + int err;
18578 +
18579 + do {
18580 +@@ -2685,7 +2685,7 @@ out_free:
18581 +
18582 + static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
18583 + {
18584 +- struct nfs4_exception exception = { };
18585 ++ struct nfs4_exception exception = {0, 0};
18586 + ssize_t ret;
18587 + do {
18588 + ret = __nfs4_get_acl_uncached(inode, buf, buflen);
18589 +@@ -2742,7 +2742,7 @@ static int __nfs4_proc_set_acl(struct in
18590 +
18591 + static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
18592 + {
18593 +- struct nfs4_exception exception = { };
18594 ++ struct nfs4_exception exception = {0, 0};
18595 + int err;
18596 + do {
18597 + err = nfs4_handle_exception(NFS_SERVER(inode),
18598 +@@ -3034,7 +3034,7 @@ out:
18599 + int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync)
18600 + {
18601 + struct nfs_server *server = NFS_SERVER(inode);
18602 +- struct nfs4_exception exception = { };
18603 ++ struct nfs4_exception exception = {0, 0};
18604 + int err;
18605 + do {
18606 + err = _nfs4_proc_delegreturn(inode, cred, stateid, issync);
18607 +@@ -3109,7 +3109,7 @@ out:
18608 +
18609 + static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
18610 + {
18611 +- struct nfs4_exception exception = { };
18612 ++ struct nfs4_exception exception = {0, 0};
18613 + int err;
18614 +
18615 + do {
18616 +@@ -3459,7 +3459,7 @@ static int _nfs4_do_setlk(struct nfs4_st
18617 + static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
18618 + {
18619 + struct nfs_server *server = NFS_SERVER(state->inode);
18620 +- struct nfs4_exception exception = { };
18621 ++ struct nfs4_exception exception = {0, 0};
18622 + int err;
18623 +
18624 + do {
18625 +@@ -3477,7 +3477,7 @@ static int nfs4_lock_reclaim(struct nfs4
18626 + static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
18627 + {
18628 + struct nfs_server *server = NFS_SERVER(state->inode);
18629 +- struct nfs4_exception exception = { };
18630 ++ struct nfs4_exception exception = {0, 0};
18631 + int err;
18632 +
18633 + err = nfs4_set_lock_state(state, request);
18634 +@@ -3538,7 +3538,7 @@ out:
18635 +
18636 + static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
18637 + {
18638 +- struct nfs4_exception exception = { };
18639 ++ struct nfs4_exception exception = {0, 0};
18640 + int err;
18641 +
18642 + do {
18643 +@@ -3588,7 +3588,7 @@ nfs4_proc_lock(struct file *filp, int cm
18644 + int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
18645 + {
18646 + struct nfs_server *server = NFS_SERVER(state->inode);
18647 +- struct nfs4_exception exception = { };
18648 ++ struct nfs4_exception exception = {0, 0};
18649 + int err;
18650 +
18651 + err = nfs4_set_lock_state(state, fl);
18652 +diff -urNp linux-2.6.26.6/fs/nfsd/export.c linux-2.6.26.6/fs/nfsd/export.c
18653 +--- linux-2.6.26.6/fs/nfsd/export.c 2008-10-08 23:24:05.000000000 -0400
18654 ++++ linux-2.6.26.6/fs/nfsd/export.c 2008-10-11 21:54:20.000000000 -0400
18655 +@@ -473,7 +473,7 @@ static int secinfo_parse(char **mesg, ch
18656 + * probably discover the problem when someone fails to
18657 + * authenticate.
18658 + */
18659 +- if (f->pseudoflavor < 0)
18660 ++ if ((s32)f->pseudoflavor < 0)
18661 + return -EINVAL;
18662 + err = get_int(mesg, &f->flags);
18663 + if (err)
18664 +diff -urNp linux-2.6.26.6/fs/nls/nls_base.c linux-2.6.26.6/fs/nls/nls_base.c
18665 +--- linux-2.6.26.6/fs/nls/nls_base.c 2008-10-08 23:24:05.000000000 -0400
18666 ++++ linux-2.6.26.6/fs/nls/nls_base.c 2008-10-11 21:54:20.000000000 -0400
18667 +@@ -42,7 +42,7 @@ static const struct utf8_table utf8_tabl
18668 + {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */},
18669 + {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */},
18670 + {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */},
18671 +- {0, /* end of table */}
18672 ++ {0, 0, 0, 0, 0, /* end of table */}
18673 + };
18674 +
18675 + int
18676 +diff -urNp linux-2.6.26.6/fs/ntfs/file.c linux-2.6.26.6/fs/ntfs/file.c
18677 +--- linux-2.6.26.6/fs/ntfs/file.c 2008-10-08 23:24:05.000000000 -0400
18678 ++++ linux-2.6.26.6/fs/ntfs/file.c 2008-10-11 21:54:20.000000000 -0400
18679 +@@ -2291,6 +2291,6 @@ const struct inode_operations ntfs_file_
18680 + #endif /* NTFS_RW */
18681 + };
18682 +
18683 +-const struct file_operations ntfs_empty_file_ops = {};
18684 ++const struct file_operations ntfs_empty_file_ops;
18685 +
18686 +-const struct inode_operations ntfs_empty_inode_ops = {};
18687 ++const struct inode_operations ntfs_empty_inode_ops;
18688 +diff -urNp linux-2.6.26.6/fs/open.c linux-2.6.26.6/fs/open.c
18689 +--- linux-2.6.26.6/fs/open.c 2008-10-08 23:24:05.000000000 -0400
18690 ++++ linux-2.6.26.6/fs/open.c 2008-10-11 21:54:20.000000000 -0400
18691 +@@ -29,6 +29,7 @@
18692 + #include <linux/rcupdate.h>
18693 + #include <linux/audit.h>
18694 + #include <linux/falloc.h>
18695 ++#include <linux/grsecurity.h>
18696 +
18697 + int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
18698 + {
18699 +@@ -206,6 +207,9 @@ int do_truncate(struct dentry *dentry, l
18700 + if (length < 0)
18701 + return -EINVAL;
18702 +
18703 ++ if (filp && !gr_acl_handle_truncate(dentry, filp->f_path.mnt))
18704 ++ return -EACCES;
18705 ++
18706 + newattrs.ia_size = length;
18707 + newattrs.ia_valid = ATTR_SIZE | time_attrs;
18708 + if (filp) {
18709 +@@ -478,6 +482,9 @@ asmlinkage long sys_faccessat(int dfd, c
18710 + if (__mnt_is_readonly(nd.path.mnt))
18711 + res = -EROFS;
18712 +
18713 ++ if (!res && !gr_acl_handle_access(nd.path.dentry, nd.path.mnt, mode))
18714 ++ res = -EACCES;
18715 ++
18716 + out_path_release:
18717 + path_put(&nd.path);
18718 + out:
18719 +@@ -509,6 +516,8 @@ asmlinkage long sys_chdir(const char __u
18720 + if (error)
18721 + goto dput_and_out;
18722 +
18723 ++ gr_log_chdir(nd.path.dentry, nd.path.mnt);
18724 ++
18725 + set_fs_pwd(current->fs, &nd.path);
18726 +
18727 + dput_and_out:
18728 +@@ -535,6 +544,13 @@ asmlinkage long sys_fchdir(unsigned int
18729 + goto out_putf;
18730 +
18731 + error = file_permission(file, MAY_EXEC);
18732 ++
18733 ++ if (!error && !gr_chroot_fchdir(file->f_path.dentry, file->f_path.mnt))
18734 ++ error = -EPERM;
18735 ++
18736 ++ if (!error)
18737 ++ gr_log_chdir(file->f_path.dentry, file->f_path.mnt);
18738 ++
18739 + if (!error)
18740 + set_fs_pwd(current->fs, &file->f_path);
18741 + out_putf:
18742 +@@ -560,8 +576,16 @@ asmlinkage long sys_chroot(const char __
18743 + if (!capable(CAP_SYS_CHROOT))
18744 + goto dput_and_out;
18745 +
18746 ++ if (gr_handle_chroot_chroot(nd.path.dentry, nd.path.mnt))
18747 ++ goto dput_and_out;
18748 ++
18749 + set_fs_root(current->fs, &nd.path);
18750 + set_fs_altroot();
18751 ++
18752 ++ gr_handle_chroot_caps(current);
18753 ++
18754 ++ gr_handle_chroot_chdir(&nd.path);
18755 ++
18756 + error = 0;
18757 + dput_and_out:
18758 + path_put(&nd.path);
18759 +@@ -592,9 +616,22 @@ asmlinkage long sys_fchmod(unsigned int
18760 + err = -EPERM;
18761 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
18762 + goto out_drop_write;
18763 ++
18764 ++ if (!gr_acl_handle_fchmod(dentry, file->f_path.mnt, mode)) {
18765 ++ err = -EACCES;
18766 ++ goto out_drop_write;
18767 ++ }
18768 ++
18769 + mutex_lock(&inode->i_mutex);
18770 + if (mode == (mode_t) -1)
18771 + mode = inode->i_mode;
18772 ++
18773 ++ if (gr_handle_chroot_chmod(dentry, file->f_path.mnt, mode)) {
18774 ++ err = -EPERM;
18775 ++ mutex_unlock(&inode->i_mutex);
18776 ++ goto out_drop_write;
18777 ++ }
18778 ++
18779 + newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
18780 + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
18781 + err = notify_change(dentry, &newattrs);
18782 +@@ -629,9 +666,21 @@ asmlinkage long sys_fchmodat(int dfd, co
18783 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
18784 + goto out_drop_write;
18785 +
18786 ++ if (!gr_acl_handle_chmod(nd.path.dentry, nd.path.mnt, mode)) {
18787 ++ error = -EACCES;
18788 ++ goto out_drop_write;
18789 ++ }
18790 ++
18791 + mutex_lock(&inode->i_mutex);
18792 + if (mode == (mode_t) -1)
18793 + mode = inode->i_mode;
18794 ++
18795 ++ if (gr_handle_chroot_chmod(nd.path.dentry, nd.path.mnt, mode)) {
18796 ++ error = -EACCES;
18797 ++ mutex_unlock(&inode->i_mutex);
18798 ++ goto dput_and_out;
18799 ++ }
18800 ++
18801 + newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
18802 + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
18803 + error = notify_change(nd.path.dentry, &newattrs);
18804 +@@ -650,7 +699,7 @@ asmlinkage long sys_chmod(const char __u
18805 + return sys_fchmodat(AT_FDCWD, filename, mode);
18806 + }
18807 +
18808 +-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
18809 ++static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
18810 + {
18811 + struct inode * inode;
18812 + int error;
18813 +@@ -664,6 +713,12 @@ static int chown_common(struct dentry *
18814 + error = -EPERM;
18815 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
18816 + goto out;
18817 ++
18818 ++ if (!gr_acl_handle_chown(dentry, mnt)) {
18819 ++ error = -EACCES;
18820 ++ goto out;
18821 ++ }
18822 ++
18823 + newattrs.ia_valid = ATTR_CTIME;
18824 + if (user != (uid_t) -1) {
18825 + newattrs.ia_valid |= ATTR_UID;
18826 +@@ -694,7 +749,7 @@ asmlinkage long sys_chown(const char __u
18827 + error = mnt_want_write(nd.path.mnt);
18828 + if (error)
18829 + goto out_release;
18830 +- error = chown_common(nd.path.dentry, user, group);
18831 ++ error = chown_common(nd.path.dentry, user, group, nd.path.mnt);
18832 + mnt_drop_write(nd.path.mnt);
18833 + out_release:
18834 + path_put(&nd.path);
18835 +@@ -719,7 +774,7 @@ asmlinkage long sys_fchownat(int dfd, co
18836 + error = mnt_want_write(nd.path.mnt);
18837 + if (error)
18838 + goto out_release;
18839 +- error = chown_common(nd.path.dentry, user, group);
18840 ++ error = chown_common(nd.path.dentry, user, group, nd.path.mnt);
18841 + mnt_drop_write(nd.path.mnt);
18842 + out_release:
18843 + path_put(&nd.path);
18844 +@@ -738,7 +793,7 @@ asmlinkage long sys_lchown(const char __
18845 + error = mnt_want_write(nd.path.mnt);
18846 + if (error)
18847 + goto out_release;
18848 +- error = chown_common(nd.path.dentry, user, group);
18849 ++ error = chown_common(nd.path.dentry, user, group, nd.path.mnt);
18850 + mnt_drop_write(nd.path.mnt);
18851 + out_release:
18852 + path_put(&nd.path);
18853 +@@ -762,7 +817,7 @@ asmlinkage long sys_fchown(unsigned int
18854 + goto out_fput;
18855 + dentry = file->f_path.dentry;
18856 + audit_inode(NULL, dentry);
18857 +- error = chown_common(dentry, user, group);
18858 ++ error = chown_common(dentry, user, group, file->f_path.mnt);
18859 + mnt_drop_write(file->f_path.mnt);
18860 + out_fput:
18861 + fput(file);
18862 +@@ -993,6 +1048,7 @@ repeat:
18863 + * N.B. For clone tasks sharing a files structure, this test
18864 + * will limit the total number of files that can be opened.
18865 + */
18866 ++ gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
18867 + if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
18868 + goto out;
18869 +
18870 +diff -urNp linux-2.6.26.6/fs/partitions/efi.c linux-2.6.26.6/fs/partitions/efi.c
18871 +--- linux-2.6.26.6/fs/partitions/efi.c 2008-10-08 23:24:05.000000000 -0400
18872 ++++ linux-2.6.26.6/fs/partitions/efi.c 2008-10-11 21:54:20.000000000 -0400
18873 +@@ -99,7 +99,7 @@
18874 + #ifdef EFI_DEBUG
18875 + #define Dprintk(x...) printk(KERN_DEBUG x)
18876 + #else
18877 +-#define Dprintk(x...)
18878 ++#define Dprintk(x...) do {} while (0)
18879 + #endif
18880 +
18881 + /* This allows a kernel command line option 'gpt' to override
18882 +diff -urNp linux-2.6.26.6/fs/pipe.c linux-2.6.26.6/fs/pipe.c
18883 +--- linux-2.6.26.6/fs/pipe.c 2008-10-08 23:24:05.000000000 -0400
18884 ++++ linux-2.6.26.6/fs/pipe.c 2008-10-11 21:54:20.000000000 -0400
18885 +@@ -886,7 +886,7 @@ void free_pipe_info(struct inode *inode)
18886 + inode->i_pipe = NULL;
18887 + }
18888 +
18889 +-static struct vfsmount *pipe_mnt __read_mostly;
18890 ++struct vfsmount *pipe_mnt __read_mostly;
18891 + static int pipefs_delete_dentry(struct dentry *dentry)
18892 + {
18893 + /*
18894 +diff -urNp linux-2.6.26.6/fs/proc/array.c linux-2.6.26.6/fs/proc/array.c
18895 +--- linux-2.6.26.6/fs/proc/array.c 2008-10-08 23:24:05.000000000 -0400
18896 ++++ linux-2.6.26.6/fs/proc/array.c 2008-10-11 21:54:20.000000000 -0400
18897 +@@ -310,6 +310,21 @@ static inline void task_context_switch_c
18898 + p->nivcsw);
18899 + }
18900 +
18901 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
18902 ++static inline void task_pax(struct seq_file *m, struct task_struct *p)
18903 ++{
18904 ++ if (p->mm)
18905 ++ seq_printf(m, "PaX:\t%c%c%c%c%c\n",
18906 ++ p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
18907 ++ p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
18908 ++ p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
18909 ++ p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
18910 ++ p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
18911 ++ else
18912 ++ seq_printf(m, "PaX:\t-----\n");
18913 ++}
18914 ++#endif
18915 ++
18916 + int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
18917 + struct pid *pid, struct task_struct *task)
18918 + {
18919 +@@ -329,9 +344,20 @@ int proc_pid_status(struct seq_file *m,
18920 + task_show_regs(m, task);
18921 + #endif
18922 + task_context_switch_counts(m, task);
18923 ++
18924 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
18925 ++ task_pax(m, task);
18926 ++#endif
18927 ++
18928 + return 0;
18929 + }
18930 +
18931 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
18932 ++#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
18933 ++ (_mm->pax_flags & MF_PAX_RANDMMAP || \
18934 ++ _mm->pax_flags & MF_PAX_SEGMEXEC))
18935 ++#endif
18936 ++
18937 + static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
18938 + struct pid *pid, struct task_struct *task, int whole)
18939 + {
18940 +@@ -424,6 +450,19 @@ static int do_task_stat(struct seq_file
18941 + gtime = task_gtime(task);
18942 + }
18943 +
18944 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
18945 ++ if (PAX_RAND_FLAGS(mm)) {
18946 ++ eip = 0;
18947 ++ esp = 0;
18948 ++ wchan = 0;
18949 ++ }
18950 ++#endif
18951 ++#ifdef CONFIG_GRKERNSEC_HIDESYM
18952 ++ wchan = 0;
18953 ++ eip =0;
18954 ++ esp =0;
18955 ++#endif
18956 ++
18957 + /* scale priority and nice values from timeslices to -20..20 */
18958 + /* to make it look like a "normal" Unix priority/nice value */
18959 + priority = task_prio(task);
18960 +@@ -464,9 +503,15 @@ static int do_task_stat(struct seq_file
18961 + vsize,
18962 + mm ? get_mm_rss(mm) : 0,
18963 + rsslim,
18964 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
18965 ++ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
18966 ++ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
18967 ++ PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0),
18968 ++#else
18969 + mm ? mm->start_code : 0,
18970 + mm ? mm->end_code : 0,
18971 + mm ? mm->start_stack : 0,
18972 ++#endif
18973 + esp,
18974 + eip,
18975 + /* The signal information here is obsolete.
18976 +@@ -519,3 +564,10 @@ int proc_pid_statm(struct seq_file *m, s
18977 +
18978 + return 0;
18979 + }
18980 ++
18981 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
18982 ++int proc_pid_ipaddr(struct task_struct *task, char *buffer)
18983 ++{
18984 ++ return sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
18985 ++}
18986 ++#endif
18987 +diff -urNp linux-2.6.26.6/fs/proc/base.c linux-2.6.26.6/fs/proc/base.c
18988 +--- linux-2.6.26.6/fs/proc/base.c 2008-10-08 23:24:05.000000000 -0400
18989 ++++ linux-2.6.26.6/fs/proc/base.c 2008-10-11 21:54:20.000000000 -0400
18990 +@@ -77,6 +77,8 @@
18991 + #include <linux/oom.h>
18992 + #include <linux/elf.h>
18993 + #include <linux/pid_namespace.h>
18994 ++#include <linux/grsecurity.h>
18995 ++
18996 + #include "internal.h"
18997 +
18998 + /* NOTE:
18999 +@@ -146,7 +148,7 @@ static unsigned int pid_entry_count_dirs
19000 + return count;
19001 + }
19002 +
19003 +-int maps_protect;
19004 ++int maps_protect = 1;
19005 + EXPORT_SYMBOL(maps_protect);
19006 +
19007 + static struct fs_struct *get_fs_struct(struct task_struct *task)
19008 +@@ -227,6 +229,9 @@ static int check_mem_permission(struct t
19009 + if (task == current)
19010 + return 0;
19011 +
19012 ++ if (gr_handle_proc_ptrace(task) || gr_acl_handle_procpidmem(task))
19013 ++ return -EPERM;
19014 ++
19015 + /*
19016 + * If current is actively ptrace'ing, and would also be
19017 + * permitted to freshly attach with ptrace now, permit it.
19018 +@@ -305,9 +310,9 @@ static int proc_pid_auxv(struct task_str
19019 + struct mm_struct *mm = get_task_mm(task);
19020 + if (mm) {
19021 + unsigned int nwords = 0;
19022 +- do
19023 ++ do {
19024 + nwords += 2;
19025 +- while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
19026 ++ } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
19027 + res = nwords * sizeof(mm->saved_auxv[0]);
19028 + if (res > PAGE_SIZE)
19029 + res = PAGE_SIZE;
19030 +@@ -1410,7 +1415,11 @@ static struct inode *proc_pid_make_inode
19031 + inode->i_gid = 0;
19032 + if (task_dumpable(task)) {
19033 + inode->i_uid = task->euid;
19034 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
19035 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
19036 ++#else
19037 + inode->i_gid = task->egid;
19038 ++#endif
19039 + }
19040 + security_task_to_inode(task, inode);
19041 +
19042 +@@ -1426,17 +1435,45 @@ static int pid_getattr(struct vfsmount *
19043 + {
19044 + struct inode *inode = dentry->d_inode;
19045 + struct task_struct *task;
19046 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19047 ++ struct task_struct *tmp = current;
19048 ++#endif
19049 ++
19050 + generic_fillattr(inode, stat);
19051 +
19052 + rcu_read_lock();
19053 + stat->uid = 0;
19054 + stat->gid = 0;
19055 + task = pid_task(proc_pid(inode), PIDTYPE_PID);
19056 +- if (task) {
19057 ++
19058 ++ if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) {
19059 ++ rcu_read_unlock();
19060 ++ return -ENOENT;
19061 ++ }
19062 ++
19063 ++
19064 ++ if (task
19065 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19066 ++ && (!tmp->uid || (tmp->uid == task->uid)
19067 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
19068 ++ || in_group_p(CONFIG_GRKERNSEC_PROC_GID)
19069 ++#endif
19070 ++ )
19071 ++#endif
19072 ++ ) {
19073 + if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
19074 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
19075 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
19076 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19077 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
19078 ++#endif
19079 + task_dumpable(task)) {
19080 + stat->uid = task->euid;
19081 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
19082 ++ stat->gid = CONFIG_GRKERNSEC_PROC_GID;
19083 ++#else
19084 + stat->gid = task->egid;
19085 ++#endif
19086 + }
19087 + }
19088 + rcu_read_unlock();
19089 +@@ -1464,11 +1501,21 @@ static int pid_revalidate(struct dentry
19090 + {
19091 + struct inode *inode = dentry->d_inode;
19092 + struct task_struct *task = get_proc_task(inode);
19093 ++
19094 + if (task) {
19095 + if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
19096 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
19097 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
19098 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19099 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
19100 ++#endif
19101 + task_dumpable(task)) {
19102 + inode->i_uid = task->euid;
19103 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
19104 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
19105 ++#else
19106 + inode->i_gid = task->egid;
19107 ++#endif
19108 + } else {
19109 + inode->i_uid = 0;
19110 + inode->i_gid = 0;
19111 +@@ -1837,12 +1884,22 @@ static int proc_fd_permission(struct ino
19112 + struct nameidata *nd)
19113 + {
19114 + int rv;
19115 ++ struct task_struct *task;
19116 +
19117 + rv = generic_permission(inode, mask, NULL);
19118 +- if (rv == 0)
19119 +- return 0;
19120 ++
19121 + if (task_pid(current) == proc_pid(inode))
19122 + rv = 0;
19123 ++
19124 ++ task = get_proc_task(inode);
19125 ++ if (task == NULL)
19126 ++ return rv;
19127 ++
19128 ++ if (gr_acl_handle_procpidmem(task))
19129 ++ rv = -EACCES;
19130 ++
19131 ++ put_task_struct(task);
19132 ++
19133 + return rv;
19134 + }
19135 +
19136 +@@ -1953,6 +2010,9 @@ static struct dentry *proc_pident_lookup
19137 + if (!task)
19138 + goto out_no_task;
19139 +
19140 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
19141 ++ goto out;
19142 ++
19143 + /*
19144 + * Yes, it does not scale. And it should not. Don't add
19145 + * new entries into /proc/<tgid>/ without very good reasons.
19146 +@@ -1997,6 +2057,9 @@ static int proc_pident_readdir(struct fi
19147 + if (!task)
19148 + goto out_no_task;
19149 +
19150 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
19151 ++ goto out;
19152 ++
19153 + ret = 0;
19154 + i = filp->f_pos;
19155 + switch (i) {
19156 +@@ -2359,6 +2422,9 @@ static struct dentry *proc_base_lookup(s
19157 + if (p > last)
19158 + goto out;
19159 +
19160 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
19161 ++ goto out;
19162 ++
19163 + error = proc_base_instantiate(dir, dentry, task, p);
19164 +
19165 + out:
19166 +@@ -2471,6 +2537,9 @@ static const struct pid_entry tgid_base_
19167 + #ifdef CONFIG_TASK_IO_ACCOUNTING
19168 + INF("io", S_IRUGO, pid_io_accounting),
19169 + #endif
19170 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
19171 ++ INF("ipaddr", S_IRUSR, pid_ipaddr),
19172 ++#endif
19173 + };
19174 +
19175 + static int proc_tgid_base_readdir(struct file * filp,
19176 +@@ -2600,7 +2669,14 @@ static struct dentry *proc_pid_instantia
19177 + if (!inode)
19178 + goto out;
19179 +
19180 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
19181 ++ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
19182 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19183 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
19184 ++ inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP;
19185 ++#else
19186 + inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
19187 ++#endif
19188 + inode->i_op = &proc_tgid_base_inode_operations;
19189 + inode->i_fop = &proc_tgid_base_operations;
19190 + inode->i_flags|=S_IMMUTABLE;
19191 +@@ -2642,7 +2718,11 @@ struct dentry *proc_pid_lookup(struct in
19192 + if (!task)
19193 + goto out;
19194 +
19195 ++ if (gr_check_hidden_task(task))
19196 ++ goto out_put_task;
19197 ++
19198 + result = proc_pid_instantiate(dir, dentry, task, NULL);
19199 ++out_put_task:
19200 + put_task_struct(task);
19201 + out:
19202 + return result;
19203 +@@ -2707,6 +2787,9 @@ int proc_pid_readdir(struct file * filp,
19204 + {
19205 + unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
19206 + struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode);
19207 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19208 ++ struct task_struct *tmp = current;
19209 ++#endif
19210 + struct tgid_iter iter;
19211 + struct pid_namespace *ns;
19212 +
19213 +@@ -2725,6 +2808,17 @@ int proc_pid_readdir(struct file * filp,
19214 + for (iter = next_tgid(ns, iter);
19215 + iter.task;
19216 + iter.tgid += 1, iter = next_tgid(ns, iter)) {
19217 ++ if (gr_pid_is_chrooted(iter.task) || gr_check_hidden_task(iter.task)
19218 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19219 ++ || (tmp->uid && (iter.task->uid != tmp->uid)
19220 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
19221 ++ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
19222 ++#endif
19223 ++ )
19224 ++#endif
19225 ++ )
19226 ++ continue;
19227 ++
19228 + filp->f_pos = iter.tgid + TGID_OFFSET;
19229 + if (proc_pid_fill_cache(filp, dirent, filldir, iter) < 0) {
19230 + put_task_struct(iter.task);
19231 +diff -urNp linux-2.6.26.6/fs/proc/inode.c linux-2.6.26.6/fs/proc/inode.c
19232 +--- linux-2.6.26.6/fs/proc/inode.c 2008-10-08 23:24:05.000000000 -0400
19233 ++++ linux-2.6.26.6/fs/proc/inode.c 2008-10-11 21:54:20.000000000 -0400
19234 +@@ -403,7 +403,11 @@ struct inode *proc_get_inode(struct supe
19235 + if (de->mode) {
19236 + inode->i_mode = de->mode;
19237 + inode->i_uid = de->uid;
19238 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
19239 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
19240 ++#else
19241 + inode->i_gid = de->gid;
19242 ++#endif
19243 + }
19244 + if (de->size)
19245 + inode->i_size = de->size;
19246 +diff -urNp linux-2.6.26.6/fs/proc/internal.h linux-2.6.26.6/fs/proc/internal.h
19247 +--- linux-2.6.26.6/fs/proc/internal.h 2008-10-08 23:24:05.000000000 -0400
19248 ++++ linux-2.6.26.6/fs/proc/internal.h 2008-10-11 21:54:20.000000000 -0400
19249 +@@ -55,6 +55,9 @@ extern int proc_pid_status(struct seq_fi
19250 + struct pid *pid, struct task_struct *task);
19251 + extern int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
19252 + struct pid *pid, struct task_struct *task);
19253 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
19254 ++extern int proc_pid_ipaddr(struct task_struct *task, char *buffer);
19255 ++#endif
19256 + extern loff_t mem_lseek(struct file *file, loff_t offset, int orig);
19257 +
19258 + extern const struct file_operations proc_maps_operations;
19259 +diff -urNp linux-2.6.26.6/fs/proc/proc_misc.c linux-2.6.26.6/fs/proc/proc_misc.c
19260 +--- linux-2.6.26.6/fs/proc/proc_misc.c 2008-10-08 23:24:05.000000000 -0400
19261 ++++ linux-2.6.26.6/fs/proc/proc_misc.c 2008-10-11 21:54:20.000000000 -0400
19262 +@@ -830,6 +830,8 @@ struct proc_dir_entry *proc_root_kcore;
19263 +
19264 + void __init proc_misc_init(void)
19265 + {
19266 ++ int gr_mode = 0;
19267 ++
19268 + static struct {
19269 + char *name;
19270 + int (*read_proc)(char*,char**,off_t,int,int*,void*);
19271 +@@ -845,13 +847,24 @@ void __init proc_misc_init(void)
19272 + {"stram", stram_read_proc},
19273 + #endif
19274 + {"filesystems", filesystems_read_proc},
19275 ++#ifndef CONFIG_GRKERNSEC_PROC_ADD
19276 + {"cmdline", cmdline_read_proc},
19277 ++#endif
19278 + {"execdomains", execdomains_read_proc},
19279 + {NULL,}
19280 + };
19281 + for (p = simple_ones; p->name; p++)
19282 + create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
19283 +
19284 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
19285 ++ gr_mode = S_IRUSR;
19286 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19287 ++ gr_mode = S_IRUSR | S_IRGRP;
19288 ++#endif
19289 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
19290 ++ create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
19291 ++#endif
19292 ++
19293 + proc_symlink("mounts", NULL, "self/mounts");
19294 +
19295 + /* And now for trickier ones */
19296 +@@ -859,14 +872,18 @@ void __init proc_misc_init(void)
19297 + proc_create("kmsg", S_IRUSR, NULL, &proc_kmsg_operations);
19298 + #endif
19299 + proc_create("locks", 0, NULL, &proc_locks_operations);
19300 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
19301 ++ proc_create("devices", gr_mode, NULL, &proc_devinfo_operations);
19302 ++#else
19303 + proc_create("devices", 0, NULL, &proc_devinfo_operations);
19304 ++#endif
19305 + proc_create("cpuinfo", 0, NULL, &proc_cpuinfo_operations);
19306 + #ifdef CONFIG_BLOCK
19307 + proc_create("partitions", 0, NULL, &proc_partitions_operations);
19308 + #endif
19309 + proc_create("stat", 0, NULL, &proc_stat_operations);
19310 + proc_create("interrupts", 0, NULL, &proc_interrupts_operations);
19311 +-#ifdef CONFIG_SLABINFO
19312 ++#if defined(CONFIG_SLABINFO) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
19313 + proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
19314 + #ifdef CONFIG_DEBUG_SLAB_LEAK
19315 + proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations);
19316 +@@ -888,7 +905,7 @@ void __init proc_misc_init(void)
19317 + #ifdef CONFIG_SCHEDSTATS
19318 + proc_create("schedstat", 0, NULL, &proc_schedstat_operations);
19319 + #endif
19320 +-#ifdef CONFIG_PROC_KCORE
19321 ++#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
19322 + proc_root_kcore = proc_create("kcore", S_IRUSR, NULL, &proc_kcore_operations);
19323 + if (proc_root_kcore)
19324 + proc_root_kcore->size =
19325 +diff -urNp linux-2.6.26.6/fs/proc/proc_net.c linux-2.6.26.6/fs/proc/proc_net.c
19326 +--- linux-2.6.26.6/fs/proc/proc_net.c 2008-10-08 23:24:05.000000000 -0400
19327 ++++ linux-2.6.26.6/fs/proc/proc_net.c 2008-10-11 21:54:20.000000000 -0400
19328 +@@ -69,6 +69,14 @@ static struct net *get_proc_task_net(str
19329 + struct nsproxy *ns;
19330 + struct net *net = NULL;
19331 +
19332 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
19333 ++ if (current->fsuid)
19334 ++ return net;
19335 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19336 ++ if (current->fsuid && !in_group_p(CONFIG_GRKERNSEC_PROC_GID))
19337 ++ return net;
19338 ++#endif
19339 ++
19340 + rcu_read_lock();
19341 + task = pid_task(proc_pid(dir), PIDTYPE_PID);
19342 + if (task != NULL) {
19343 +diff -urNp linux-2.6.26.6/fs/proc/proc_sysctl.c linux-2.6.26.6/fs/proc/proc_sysctl.c
19344 +--- linux-2.6.26.6/fs/proc/proc_sysctl.c 2008-10-08 23:24:05.000000000 -0400
19345 ++++ linux-2.6.26.6/fs/proc/proc_sysctl.c 2008-10-11 21:54:20.000000000 -0400
19346 +@@ -7,6 +7,8 @@
19347 + #include <linux/security.h>
19348 + #include "internal.h"
19349 +
19350 ++extern __u32 gr_handle_sysctl(const struct ctl_table *table, const int op);
19351 ++
19352 + static struct dentry_operations proc_sys_dentry_operations;
19353 + static const struct file_operations proc_sys_file_operations;
19354 + static const struct inode_operations proc_sys_inode_operations;
19355 +@@ -151,6 +153,9 @@ static struct dentry *proc_sys_lookup(st
19356 + if (!table)
19357 + goto out;
19358 +
19359 ++ if (gr_handle_sysctl(table, 001))
19360 ++ goto out;
19361 ++
19362 + err = ERR_PTR(-ENOMEM);
19363 + inode = proc_sys_make_inode(dir, table);
19364 + if (!inode)
19365 +@@ -332,6 +337,9 @@ static int proc_sys_readdir(struct file
19366 + if (pos < filp->f_pos)
19367 + continue;
19368 +
19369 ++ if (gr_handle_sysctl(table, 0))
19370 ++ continue;
19371 ++
19372 + if (proc_sys_fill_cache(filp, dirent, filldir, table) < 0)
19373 + goto out;
19374 + filp->f_pos = pos + 1;
19375 +@@ -394,6 +402,30 @@ out:
19376 + return error;
19377 + }
19378 +
19379 ++/* Eric Biederman is to blame */
19380 ++static int proc_sys_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
19381 ++{
19382 ++ int error = 0;
19383 ++ struct ctl_table_header *head;
19384 ++ struct ctl_table *table;
19385 ++
19386 ++ table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head);
19387 ++ /* Has the sysctl entry disappeared on us? */
19388 ++ if (!table)
19389 ++ goto out;
19390 ++
19391 ++ if (gr_handle_sysctl(table, 001)) {
19392 ++ error = -ENOENT;
19393 ++ goto out;
19394 ++ }
19395 ++
19396 ++out:
19397 ++ sysctl_head_finish(head);
19398 ++
19399 ++ generic_fillattr(dentry->d_inode, stat);
19400 ++
19401 ++ return error;
19402 ++}
19403 + static int proc_sys_setattr(struct dentry *dentry, struct iattr *attr)
19404 + {
19405 + struct inode *inode = dentry->d_inode;
19406 +@@ -422,6 +454,7 @@ static const struct inode_operations pro
19407 + .lookup = proc_sys_lookup,
19408 + .permission = proc_sys_permission,
19409 + .setattr = proc_sys_setattr,
19410 ++ .getattr = proc_sys_getattr,
19411 + };
19412 +
19413 + static int proc_sys_revalidate(struct dentry *dentry, struct nameidata *nd)
19414 +diff -urNp linux-2.6.26.6/fs/proc/root.c linux-2.6.26.6/fs/proc/root.c
19415 +--- linux-2.6.26.6/fs/proc/root.c 2008-10-08 23:24:05.000000000 -0400
19416 ++++ linux-2.6.26.6/fs/proc/root.c 2008-10-11 21:54:20.000000000 -0400
19417 +@@ -135,7 +135,15 @@ void __init proc_root_init(void)
19418 + #ifdef CONFIG_PROC_DEVICETREE
19419 + proc_device_tree_init();
19420 + #endif
19421 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
19422 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
19423 ++ proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
19424 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19425 ++ proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
19426 ++#endif
19427 ++#else
19428 + proc_mkdir("bus", NULL);
19429 ++#endif
19430 + proc_sys_init();
19431 + }
19432 +
19433 +diff -urNp linux-2.6.26.6/fs/proc/task_mmu.c linux-2.6.26.6/fs/proc/task_mmu.c
19434 +--- linux-2.6.26.6/fs/proc/task_mmu.c 2008-10-08 23:24:05.000000000 -0400
19435 ++++ linux-2.6.26.6/fs/proc/task_mmu.c 2008-10-11 21:54:20.000000000 -0400
19436 +@@ -46,15 +46,26 @@ void task_mem(struct seq_file *m, struct
19437 + "VmStk:\t%8lu kB\n"
19438 + "VmExe:\t%8lu kB\n"
19439 + "VmLib:\t%8lu kB\n"
19440 +- "VmPTE:\t%8lu kB\n",
19441 +- hiwater_vm << (PAGE_SHIFT-10),
19442 ++ "VmPTE:\t%8lu kB\n"
19443 ++
19444 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
19445 ++ "CsBase:\t%8lx\nCsLim:\t%8lx\n"
19446 ++#endif
19447 ++
19448 ++ ,hiwater_vm << (PAGE_SHIFT-10),
19449 + (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
19450 + mm->locked_vm << (PAGE_SHIFT-10),
19451 + hiwater_rss << (PAGE_SHIFT-10),
19452 + total_rss << (PAGE_SHIFT-10),
19453 + data << (PAGE_SHIFT-10),
19454 + mm->stack_vm << (PAGE_SHIFT-10), text, lib,
19455 +- (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
19456 ++ (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
19457 ++
19458 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
19459 ++ , mm->context.user_cs_base, mm->context.user_cs_limit
19460 ++#endif
19461 ++
19462 ++ );
19463 + }
19464 +
19465 + unsigned long task_vsize(struct mm_struct *mm)
19466 +@@ -198,6 +209,12 @@ static int do_maps_open(struct inode *in
19467 + return ret;
19468 + }
19469 +
19470 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19471 ++#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
19472 ++ (_mm->pax_flags & MF_PAX_RANDMMAP || \
19473 ++ _mm->pax_flags & MF_PAX_SEGMEXEC))
19474 ++#endif
19475 ++
19476 + static int show_map(struct seq_file *m, void *v)
19477 + {
19478 + struct proc_maps_private *priv = m->private;
19479 +@@ -220,13 +237,22 @@ static int show_map(struct seq_file *m,
19480 + }
19481 +
19482 + seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
19483 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19484 ++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
19485 ++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
19486 ++#else
19487 + vma->vm_start,
19488 + vma->vm_end,
19489 ++#endif
19490 + flags & VM_READ ? 'r' : '-',
19491 + flags & VM_WRITE ? 'w' : '-',
19492 + flags & VM_EXEC ? 'x' : '-',
19493 + flags & VM_MAYSHARE ? 's' : 'p',
19494 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19495 ++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_pgoff << PAGE_SHIFT,
19496 ++#else
19497 + vma->vm_pgoff << PAGE_SHIFT,
19498 ++#endif
19499 + MAJOR(dev), MINOR(dev), ino, &len);
19500 +
19501 + /*
19502 +@@ -240,11 +266,11 @@ static int show_map(struct seq_file *m,
19503 + const char *name = arch_vma_name(vma);
19504 + if (!name) {
19505 + if (mm) {
19506 +- if (vma->vm_start <= mm->start_brk &&
19507 +- vma->vm_end >= mm->brk) {
19508 ++ if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
19509 + name = "[heap]";
19510 +- } else if (vma->vm_start <= mm->start_stack &&
19511 +- vma->vm_end >= mm->start_stack) {
19512 ++ } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
19513 ++ (vma->vm_start <= mm->start_stack &&
19514 ++ vma->vm_end >= mm->start_stack)) {
19515 + name = "[stack]";
19516 + }
19517 + } else {
19518 +@@ -377,9 +403,16 @@ static int show_smap(struct seq_file *m,
19519 + };
19520 +
19521 + memset(&mss, 0, sizeof mss);
19522 +- mss.vma = vma;
19523 +- if (vma->vm_mm && !is_vm_hugetlb_page(vma))
19524 +- walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
19525 ++
19526 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19527 ++ if (!PAX_RAND_FLAGS(vma->vm_mm)) {
19528 ++#endif
19529 ++ mss.vma = vma;
19530 ++ if (vma->vm_mm && !is_vm_hugetlb_page(vma))
19531 ++ walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
19532 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19533 ++ }
19534 ++#endif
19535 +
19536 + ret = show_map(m, v);
19537 + if (ret)
19538 +@@ -395,7 +428,11 @@ static int show_smap(struct seq_file *m,
19539 + "Private_Dirty: %8lu kB\n"
19540 + "Referenced: %8lu kB\n"
19541 + "Swap: %8lu kB\n",
19542 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19543 ++ PAX_RAND_FLAGS(vma->vm_mm) ? 0UL : (vma->vm_end - vma->vm_start) >> 10,
19544 ++#else
19545 + (vma->vm_end - vma->vm_start) >> 10,
19546 ++#endif
19547 + mss.resident >> 10,
19548 + (unsigned long)(mss.pss >> (10 + PSS_SHIFT)),
19549 + mss.shared_clean >> 10,
19550 +@@ -747,6 +784,11 @@ static int show_numa_map_checked(struct
19551 + struct proc_maps_private *priv = m->private;
19552 + struct task_struct *task = priv->task;
19553 +
19554 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19555 ++ if (!ptrace_may_attach(task))
19556 ++ return -EACCES;
19557 ++#endif
19558 ++
19559 + if (maps_protect && !ptrace_may_attach(task))
19560 + return -EACCES;
19561 +
19562 +diff -urNp linux-2.6.26.6/fs/readdir.c linux-2.6.26.6/fs/readdir.c
19563 +--- linux-2.6.26.6/fs/readdir.c 2008-10-08 23:24:05.000000000 -0400
19564 ++++ linux-2.6.26.6/fs/readdir.c 2008-10-11 21:54:20.000000000 -0400
19565 +@@ -16,6 +16,8 @@
19566 + #include <linux/security.h>
19567 + #include <linux/syscalls.h>
19568 + #include <linux/unistd.h>
19569 ++#include <linux/namei.h>
19570 ++#include <linux/grsecurity.h>
19571 +
19572 + #include <asm/uaccess.h>
19573 +
19574 +@@ -67,6 +69,7 @@ struct old_linux_dirent {
19575 +
19576 + struct readdir_callback {
19577 + struct old_linux_dirent __user * dirent;
19578 ++ struct file * file;
19579 + int result;
19580 + };
19581 +
19582 +@@ -82,6 +85,10 @@ static int fillonedir(void * __buf, cons
19583 + d_ino = ino;
19584 + if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
19585 + return -EOVERFLOW;
19586 ++
19587 ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
19588 ++ return 0;
19589 ++
19590 + buf->result++;
19591 + dirent = buf->dirent;
19592 + if (!access_ok(VERIFY_WRITE, dirent,
19593 +@@ -113,6 +120,7 @@ asmlinkage long old_readdir(unsigned int
19594 +
19595 + buf.result = 0;
19596 + buf.dirent = dirent;
19597 ++ buf.file = file;
19598 +
19599 + error = vfs_readdir(file, fillonedir, &buf);
19600 + if (error >= 0)
19601 +@@ -139,6 +147,7 @@ struct linux_dirent {
19602 + struct getdents_callback {
19603 + struct linux_dirent __user * current_dir;
19604 + struct linux_dirent __user * previous;
19605 ++ struct file * file;
19606 + int count;
19607 + int error;
19608 + };
19609 +@@ -157,6 +166,10 @@ static int filldir(void * __buf, const c
19610 + d_ino = ino;
19611 + if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
19612 + return -EOVERFLOW;
19613 ++
19614 ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
19615 ++ return 0;
19616 ++
19617 + dirent = buf->previous;
19618 + if (dirent) {
19619 + if (__put_user(offset, &dirent->d_off))
19620 +@@ -203,6 +216,7 @@ asmlinkage long sys_getdents(unsigned in
19621 + buf.previous = NULL;
19622 + buf.count = count;
19623 + buf.error = 0;
19624 ++ buf.file = file;
19625 +
19626 + error = vfs_readdir(file, filldir, &buf);
19627 + if (error < 0)
19628 +@@ -225,6 +239,7 @@ out:
19629 + struct getdents_callback64 {
19630 + struct linux_dirent64 __user * current_dir;
19631 + struct linux_dirent64 __user * previous;
19632 ++ struct file *file;
19633 + int count;
19634 + int error;
19635 + };
19636 +@@ -239,6 +254,10 @@ static int filldir64(void * __buf, const
19637 + buf->error = -EINVAL; /* only used if we fail.. */
19638 + if (reclen > buf->count)
19639 + return -EINVAL;
19640 ++
19641 ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
19642 ++ return 0;
19643 ++
19644 + dirent = buf->previous;
19645 + if (dirent) {
19646 + if (__put_user(offset, &dirent->d_off))
19647 +@@ -285,6 +304,7 @@ asmlinkage long sys_getdents64(unsigned
19648 +
19649 + buf.current_dir = dirent;
19650 + buf.previous = NULL;
19651 ++ buf.file = file;
19652 + buf.count = count;
19653 + buf.error = 0;
19654 +
19655 +diff -urNp linux-2.6.26.6/fs/smbfs/symlink.c linux-2.6.26.6/fs/smbfs/symlink.c
19656 +--- linux-2.6.26.6/fs/smbfs/symlink.c 2008-10-08 23:24:05.000000000 -0400
19657 ++++ linux-2.6.26.6/fs/smbfs/symlink.c 2008-10-11 21:54:20.000000000 -0400
19658 +@@ -55,7 +55,7 @@ static void *smb_follow_link(struct dent
19659 +
19660 + static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
19661 + {
19662 +- char *s = nd_get_link(nd);
19663 ++ const char *s = nd_get_link(nd);
19664 + if (!IS_ERR(s))
19665 + __putname(s);
19666 + }
19667 +diff -urNp linux-2.6.26.6/fs/sysfs/symlink.c linux-2.6.26.6/fs/sysfs/symlink.c
19668 +--- linux-2.6.26.6/fs/sysfs/symlink.c 2008-10-08 23:24:05.000000000 -0400
19669 ++++ linux-2.6.26.6/fs/sysfs/symlink.c 2008-10-11 21:54:20.000000000 -0400
19670 +@@ -175,7 +175,7 @@ static void *sysfs_follow_link(struct de
19671 +
19672 + static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
19673 + {
19674 +- char *page = nd_get_link(nd);
19675 ++ const char *page = nd_get_link(nd);
19676 + if (!IS_ERR(page))
19677 + free_page((unsigned long)page);
19678 + }
19679 +diff -urNp linux-2.6.26.6/fs/udf/balloc.c linux-2.6.26.6/fs/udf/balloc.c
19680 +--- linux-2.6.26.6/fs/udf/balloc.c 2008-10-08 23:24:05.000000000 -0400
19681 ++++ linux-2.6.26.6/fs/udf/balloc.c 2008-10-11 21:54:20.000000000 -0400
19682 +@@ -169,9 +169,7 @@ static void udf_bitmap_free_blocks(struc
19683 + unsigned long overflow;
19684 +
19685 + mutex_lock(&sbi->s_alloc_mutex);
19686 +- if (bloc.logicalBlockNum < 0 ||
19687 +- (bloc.logicalBlockNum + count) >
19688 +- sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
19689 ++ if (bloc.logicalBlockNum + count > sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
19690 + udf_debug("%d < %d || %d + %d > %d\n",
19691 + bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
19692 + sbi->s_partmaps[bloc.partitionReferenceNum].
19693 +@@ -239,7 +237,7 @@ static int udf_bitmap_prealloc_blocks(st
19694 +
19695 + mutex_lock(&sbi->s_alloc_mutex);
19696 + part_len = sbi->s_partmaps[partition].s_partition_len;
19697 +- if (first_block < 0 || first_block >= part_len)
19698 ++ if (first_block >= part_len)
19699 + goto out;
19700 +
19701 + if (first_block + block_count > part_len)
19702 +@@ -300,7 +298,7 @@ static int udf_bitmap_new_block(struct s
19703 + mutex_lock(&sbi->s_alloc_mutex);
19704 +
19705 + repeat:
19706 +- if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
19707 ++ if (goal >= sbi->s_partmaps[partition].s_partition_len)
19708 + goal = 0;
19709 +
19710 + nr_groups = bitmap->s_nr_groups;
19711 +@@ -438,9 +436,7 @@ static void udf_table_free_blocks(struct
19712 + struct udf_inode_info *iinfo;
19713 +
19714 + mutex_lock(&sbi->s_alloc_mutex);
19715 +- if (bloc.logicalBlockNum < 0 ||
19716 +- (bloc.logicalBlockNum + count) >
19717 +- sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
19718 ++ if (bloc.logicalBlockNum + count > sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
19719 + udf_debug("%d < %d || %d + %d > %d\n",
19720 + bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
19721 + sbi->s_partmaps[bloc.partitionReferenceNum].
19722 +@@ -671,8 +667,7 @@ static int udf_table_prealloc_blocks(str
19723 + int8_t etype = -1;
19724 + struct udf_inode_info *iinfo;
19725 +
19726 +- if (first_block < 0 ||
19727 +- first_block >= sbi->s_partmaps[partition].s_partition_len)
19728 ++ if (first_block >= sbi->s_partmaps[partition].s_partition_len)
19729 + return 0;
19730 +
19731 + iinfo = UDF_I(table);
19732 +@@ -750,7 +745,7 @@ static int udf_table_new_block(struct su
19733 + return newblock;
19734 +
19735 + mutex_lock(&sbi->s_alloc_mutex);
19736 +- if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
19737 ++ if (goal >= sbi->s_partmaps[partition].s_partition_len)
19738 + goal = 0;
19739 +
19740 + /* We search for the closest matching block to goal. If we find
19741 +diff -urNp linux-2.6.26.6/fs/ufs/inode.c linux-2.6.26.6/fs/ufs/inode.c
19742 +--- linux-2.6.26.6/fs/ufs/inode.c 2008-10-08 23:24:05.000000000 -0400
19743 ++++ linux-2.6.26.6/fs/ufs/inode.c 2008-10-11 21:54:20.000000000 -0400
19744 +@@ -56,9 +56,7 @@ static int ufs_block_to_path(struct inod
19745 +
19746 +
19747 + UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
19748 +- if (i_block < 0) {
19749 +- ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
19750 +- } else if (i_block < direct_blocks) {
19751 ++ if (i_block < direct_blocks) {
19752 + offsets[n++] = i_block;
19753 + } else if ((i_block -= direct_blocks) < indirect_blocks) {
19754 + offsets[n++] = UFS_IND_BLOCK;
19755 +@@ -440,8 +438,6 @@ int ufs_getfrag_block(struct inode *inod
19756 + lock_kernel();
19757 +
19758 + UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
19759 +- if (fragment < 0)
19760 +- goto abort_negative;
19761 + if (fragment >
19762 + ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
19763 + << uspi->s_fpbshift))
19764 +@@ -504,10 +500,6 @@ abort:
19765 + unlock_kernel();
19766 + return err;
19767 +
19768 +-abort_negative:
19769 +- ufs_warning(sb, "ufs_get_block", "block < 0");
19770 +- goto abort;
19771 +-
19772 + abort_too_big:
19773 + ufs_warning(sb, "ufs_get_block", "block > big");
19774 + goto abort;
19775 +diff -urNp linux-2.6.26.6/fs/utimes.c linux-2.6.26.6/fs/utimes.c
19776 +--- linux-2.6.26.6/fs/utimes.c 2008-10-08 23:24:05.000000000 -0400
19777 ++++ linux-2.6.26.6/fs/utimes.c 2008-10-11 21:54:20.000000000 -0400
19778 +@@ -8,6 +8,7 @@
19779 + #include <linux/stat.h>
19780 + #include <linux/utime.h>
19781 + #include <linux/syscalls.h>
19782 ++#include <linux/grsecurity.h>
19783 + #include <asm/uaccess.h>
19784 + #include <asm/unistd.h>
19785 +
19786 +@@ -57,10 +58,10 @@ long do_utimes(int dfd, char __user *fil
19787 + int error;
19788 + struct nameidata nd;
19789 + struct dentry *dentry;
19790 ++ struct vfsmount *mnt;
19791 + struct inode *inode;
19792 + struct iattr newattrs;
19793 + struct file *f = NULL;
19794 +- struct vfsmount *mnt;
19795 +
19796 + error = -EINVAL;
19797 + if (times && (!nsec_valid(times[0].tv_nsec) ||
19798 +@@ -153,6 +154,12 @@ long do_utimes(int dfd, char __user *fil
19799 + goto mnt_drop_write_and_out;
19800 + }
19801 + }
19802 ++
19803 ++ if (!gr_acl_handle_utime(dentry, mnt)) {
19804 ++ error = -EACCES;
19805 ++ goto mnt_drop_write_and_out;
19806 ++ }
19807 ++
19808 + mutex_lock(&inode->i_mutex);
19809 + error = notify_change(dentry, &newattrs);
19810 + mutex_unlock(&inode->i_mutex);
19811 +diff -urNp linux-2.6.26.6/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.26.6/fs/xfs/linux-2.6/xfs_iops.c
19812 +--- linux-2.6.26.6/fs/xfs/linux-2.6/xfs_iops.c 2008-10-08 23:24:05.000000000 -0400
19813 ++++ linux-2.6.26.6/fs/xfs/linux-2.6/xfs_iops.c 2008-10-11 21:54:20.000000000 -0400
19814 +@@ -560,7 +560,7 @@ xfs_vn_put_link(
19815 + struct nameidata *nd,
19816 + void *p)
19817 + {
19818 +- char *s = nd_get_link(nd);
19819 ++ const char *s = nd_get_link(nd);
19820 +
19821 + if (!IS_ERR(s))
19822 + kfree(s);
19823 +diff -urNp linux-2.6.26.6/fs/xfs/xfs_bmap.c linux-2.6.26.6/fs/xfs/xfs_bmap.c
19824 +--- linux-2.6.26.6/fs/xfs/xfs_bmap.c 2008-10-08 23:24:05.000000000 -0400
19825 ++++ linux-2.6.26.6/fs/xfs/xfs_bmap.c 2008-10-11 21:54:20.000000000 -0400
19826 +@@ -360,7 +360,7 @@ xfs_bmap_validate_ret(
19827 + int nmap,
19828 + int ret_nmap);
19829 + #else
19830 +-#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
19831 ++#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
19832 + #endif /* DEBUG */
19833 +
19834 + #if defined(XFS_RW_TRACE)
19835 +diff -urNp linux-2.6.26.6/grsecurity/gracl_alloc.c linux-2.6.26.6/grsecurity/gracl_alloc.c
19836 +--- linux-2.6.26.6/grsecurity/gracl_alloc.c 1969-12-31 19:00:00.000000000 -0500
19837 ++++ linux-2.6.26.6/grsecurity/gracl_alloc.c 2008-10-11 21:54:20.000000000 -0400
19838 +@@ -0,0 +1,91 @@
19839 ++#include <linux/kernel.h>
19840 ++#include <linux/mm.h>
19841 ++#include <linux/slab.h>
19842 ++#include <linux/vmalloc.h>
19843 ++#include <linux/gracl.h>
19844 ++#include <linux/grsecurity.h>
19845 ++
19846 ++static unsigned long alloc_stack_next = 1;
19847 ++static unsigned long alloc_stack_size = 1;
19848 ++static void **alloc_stack;
19849 ++
19850 ++static __inline__ int
19851 ++alloc_pop(void)
19852 ++{
19853 ++ if (alloc_stack_next == 1)
19854 ++ return 0;
19855 ++
19856 ++ kfree(alloc_stack[alloc_stack_next - 2]);
19857 ++
19858 ++ alloc_stack_next--;
19859 ++
19860 ++ return 1;
19861 ++}
19862 ++
19863 ++static __inline__ void
19864 ++alloc_push(void *buf)
19865 ++{
19866 ++ if (alloc_stack_next >= alloc_stack_size)
19867 ++ BUG();
19868 ++
19869 ++ alloc_stack[alloc_stack_next - 1] = buf;
19870 ++
19871 ++ alloc_stack_next++;
19872 ++
19873 ++ return;
19874 ++}
19875 ++
19876 ++void *
19877 ++acl_alloc(unsigned long len)
19878 ++{
19879 ++ void *ret;
19880 ++
19881 ++ if (len > PAGE_SIZE)
19882 ++ BUG();
19883 ++
19884 ++ ret = kmalloc(len, GFP_KERNEL);
19885 ++
19886 ++ if (ret)
19887 ++ alloc_push(ret);
19888 ++
19889 ++ return ret;
19890 ++}
19891 ++
19892 ++void
19893 ++acl_free_all(void)
19894 ++{
19895 ++ if (gr_acl_is_enabled() || !alloc_stack)
19896 ++ return;
19897 ++
19898 ++ while (alloc_pop()) ;
19899 ++
19900 ++ if (alloc_stack) {
19901 ++ if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
19902 ++ kfree(alloc_stack);
19903 ++ else
19904 ++ vfree(alloc_stack);
19905 ++ }
19906 ++
19907 ++ alloc_stack = NULL;
19908 ++ alloc_stack_size = 1;
19909 ++ alloc_stack_next = 1;
19910 ++
19911 ++ return;
19912 ++}
19913 ++
19914 ++int
19915 ++acl_alloc_stack_init(unsigned long size)
19916 ++{
19917 ++ if ((size * sizeof (void *)) <= PAGE_SIZE)
19918 ++ alloc_stack =
19919 ++ (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
19920 ++ else
19921 ++ alloc_stack = (void **) vmalloc(size * sizeof (void *));
19922 ++
19923 ++ alloc_stack_size = size;
19924 ++
19925 ++ if (!alloc_stack)
19926 ++ return 0;
19927 ++ else
19928 ++ return 1;
19929 ++}
19930 +diff -urNp linux-2.6.26.6/grsecurity/gracl.c linux-2.6.26.6/grsecurity/gracl.c
19931 +--- linux-2.6.26.6/grsecurity/gracl.c 1969-12-31 19:00:00.000000000 -0500
19932 ++++ linux-2.6.26.6/grsecurity/gracl.c 2008-10-11 21:54:20.000000000 -0400
19933 +@@ -0,0 +1,3722 @@
19934 ++#include <linux/kernel.h>
19935 ++#include <linux/module.h>
19936 ++#include <linux/sched.h>
19937 ++#include <linux/mm.h>
19938 ++#include <linux/file.h>
19939 ++#include <linux/fs.h>
19940 ++#include <linux/namei.h>
19941 ++#include <linux/mount.h>
19942 ++#include <linux/tty.h>
19943 ++#include <linux/proc_fs.h>
19944 ++#include <linux/smp_lock.h>
19945 ++#include <linux/slab.h>
19946 ++#include <linux/vmalloc.h>
19947 ++#include <linux/types.h>
19948 ++#include <linux/sysctl.h>
19949 ++#include <linux/netdevice.h>
19950 ++#include <linux/ptrace.h>
19951 ++#include <linux/gracl.h>
19952 ++#include <linux/gralloc.h>
19953 ++#include <linux/grsecurity.h>
19954 ++#include <linux/grinternal.h>
19955 ++#include <linux/pid_namespace.h>
19956 ++#include <linux/fdtable.h>
19957 ++#include <linux/percpu.h>
19958 ++
19959 ++#include <asm/uaccess.h>
19960 ++#include <asm/errno.h>
19961 ++#include <asm/mman.h>
19962 ++
19963 ++static struct acl_role_db acl_role_set;
19964 ++static struct name_db name_set;
19965 ++static struct inodev_db inodev_set;
19966 ++
19967 ++/* for keeping track of userspace pointers used for subjects, so we
19968 ++ can share references in the kernel as well
19969 ++*/
19970 ++
19971 ++static struct dentry *real_root;
19972 ++static struct vfsmount *real_root_mnt;
19973 ++
19974 ++static struct acl_subj_map_db subj_map_set;
19975 ++
19976 ++static struct acl_role_label *default_role;
19977 ++
19978 ++static u16 acl_sp_role_value;
19979 ++
19980 ++extern char *gr_shared_page[4];
19981 ++static DECLARE_MUTEX(gr_dev_sem);
19982 ++DEFINE_RWLOCK(gr_inode_lock);
19983 ++
19984 ++struct gr_arg *gr_usermode;
19985 ++
19986 ++static unsigned int gr_status = GR_STATUS_INIT;
19987 ++
19988 ++extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
19989 ++extern void gr_clear_learn_entries(void);
19990 ++
19991 ++#ifdef CONFIG_GRKERNSEC_RESLOG
19992 ++extern void gr_log_resource(const struct task_struct *task,
19993 ++ const int res, const unsigned long wanted, const int gt);
19994 ++#endif
19995 ++
19996 ++unsigned char *gr_system_salt;
19997 ++unsigned char *gr_system_sum;
19998 ++
19999 ++static struct sprole_pw **acl_special_roles = NULL;
20000 ++static __u16 num_sprole_pws = 0;
20001 ++
20002 ++static struct acl_role_label *kernel_role = NULL;
20003 ++
20004 ++static unsigned int gr_auth_attempts = 0;
20005 ++static unsigned long gr_auth_expires = 0UL;
20006 ++
20007 ++extern struct vfsmount *sock_mnt;
20008 ++extern struct vfsmount *pipe_mnt;
20009 ++extern struct vfsmount *shm_mnt;
20010 ++static struct acl_object_label *fakefs_obj;
20011 ++
20012 ++extern int gr_init_uidset(void);
20013 ++extern void gr_free_uidset(void);
20014 ++extern void gr_remove_uid(uid_t uid);
20015 ++extern int gr_find_uid(uid_t uid);
20016 ++
20017 ++__inline__ int
20018 ++gr_acl_is_enabled(void)
20019 ++{
20020 ++ return (gr_status & GR_READY);
20021 ++}
20022 ++
20023 ++char gr_roletype_to_char(void)
20024 ++{
20025 ++ switch (current->role->roletype &
20026 ++ (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
20027 ++ GR_ROLE_SPECIAL)) {
20028 ++ case GR_ROLE_DEFAULT:
20029 ++ return 'D';
20030 ++ case GR_ROLE_USER:
20031 ++ return 'U';
20032 ++ case GR_ROLE_GROUP:
20033 ++ return 'G';
20034 ++ case GR_ROLE_SPECIAL:
20035 ++ return 'S';
20036 ++ }
20037 ++
20038 ++ return 'X';
20039 ++}
20040 ++
20041 ++__inline__ int
20042 ++gr_acl_tpe_check(void)
20043 ++{
20044 ++ if (unlikely(!(gr_status & GR_READY)))
20045 ++ return 0;
20046 ++ if (current->role->roletype & GR_ROLE_TPE)
20047 ++ return 1;
20048 ++ else
20049 ++ return 0;
20050 ++}
20051 ++
20052 ++int
20053 ++gr_handle_rawio(const struct inode *inode)
20054 ++{
20055 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
20056 ++ if (inode && S_ISBLK(inode->i_mode) &&
20057 ++ grsec_enable_chroot_caps && proc_is_chrooted(current) &&
20058 ++ !capable(CAP_SYS_RAWIO))
20059 ++ return 1;
20060 ++#endif
20061 ++ return 0;
20062 ++}
20063 ++
20064 ++static int
20065 ++gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
20066 ++{
20067 ++ int i;
20068 ++ unsigned long *l1;
20069 ++ unsigned long *l2;
20070 ++ unsigned char *c1;
20071 ++ unsigned char *c2;
20072 ++ int num_longs;
20073 ++
20074 ++ if (likely(lena != lenb))
20075 ++ return 0;
20076 ++
20077 ++ l1 = (unsigned long *)a;
20078 ++ l2 = (unsigned long *)b;
20079 ++
20080 ++ num_longs = lena / sizeof(unsigned long);
20081 ++
20082 ++ for (i = num_longs; i--; l1++, l2++) {
20083 ++ if (unlikely(*l1 != *l2))
20084 ++ return 0;
20085 ++ }
20086 ++
20087 ++ c1 = (unsigned char *) l1;
20088 ++ c2 = (unsigned char *) l2;
20089 ++
20090 ++ i = lena - (num_longs * sizeof(unsigned long));
20091 ++
20092 ++ for (; i--; c1++, c2++) {
20093 ++ if (unlikely(*c1 != *c2))
20094 ++ return 0;
20095 ++ }
20096 ++
20097 ++ return 1;
20098 ++}
20099 ++
20100 ++static char * __our_d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
20101 ++ struct dentry *root, struct vfsmount *rootmnt,
20102 ++ char *buffer, int buflen)
20103 ++{
20104 ++ char * end = buffer+buflen;
20105 ++ char * retval;
20106 ++ int namelen;
20107 ++
20108 ++ *--end = '\0';
20109 ++ buflen--;
20110 ++
20111 ++ if (buflen < 1)
20112 ++ goto Elong;
20113 ++ /* Get '/' right */
20114 ++ retval = end-1;
20115 ++ *retval = '/';
20116 ++
20117 ++ for (;;) {
20118 ++ struct dentry * parent;
20119 ++
20120 ++ if (dentry == root && vfsmnt == rootmnt)
20121 ++ break;
20122 ++ if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
20123 ++ /* Global root? */
20124 ++ spin_lock(&vfsmount_lock);
20125 ++ if (vfsmnt->mnt_parent == vfsmnt) {
20126 ++ spin_unlock(&vfsmount_lock);
20127 ++ goto global_root;
20128 ++ }
20129 ++ dentry = vfsmnt->mnt_mountpoint;
20130 ++ vfsmnt = vfsmnt->mnt_parent;
20131 ++ spin_unlock(&vfsmount_lock);
20132 ++ continue;
20133 ++ }
20134 ++ parent = dentry->d_parent;
20135 ++ prefetch(parent);
20136 ++ namelen = dentry->d_name.len;
20137 ++ buflen -= namelen + 1;
20138 ++ if (buflen < 0)
20139 ++ goto Elong;
20140 ++ end -= namelen;
20141 ++ memcpy(end, dentry->d_name.name, namelen);
20142 ++ *--end = '/';
20143 ++ retval = end;
20144 ++ dentry = parent;
20145 ++ }
20146 ++
20147 ++ return retval;
20148 ++
20149 ++global_root:
20150 ++ namelen = dentry->d_name.len;
20151 ++ buflen -= namelen;
20152 ++ if (buflen < 0)
20153 ++ goto Elong;
20154 ++ retval -= namelen-1; /* hit the slash */
20155 ++ memcpy(retval, dentry->d_name.name, namelen);
20156 ++ return retval;
20157 ++Elong:
20158 ++ return ERR_PTR(-ENAMETOOLONG);
20159 ++}
20160 ++
20161 ++static char *
20162 ++gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
20163 ++ struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
20164 ++{
20165 ++ char *retval;
20166 ++
20167 ++ retval = __our_d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
20168 ++ if (unlikely(IS_ERR(retval)))
20169 ++ retval = strcpy(buf, "<path too long>");
20170 ++ else if (unlikely(retval[1] == '/' && retval[2] == '\0'))
20171 ++ retval[1] = '\0';
20172 ++
20173 ++ return retval;
20174 ++}
20175 ++
20176 ++static char *
20177 ++__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
20178 ++ char *buf, int buflen)
20179 ++{
20180 ++ char *res;
20181 ++
20182 ++ /* we can use real_root, real_root_mnt, because this is only called
20183 ++ by the RBAC system */
20184 ++ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
20185 ++
20186 ++ return res;
20187 ++}
20188 ++
20189 ++static char *
20190 ++d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
20191 ++ char *buf, int buflen)
20192 ++{
20193 ++ char *res;
20194 ++ struct dentry *root;
20195 ++ struct vfsmount *rootmnt;
20196 ++ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
20197 ++
20198 ++ /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
20199 ++ read_lock(&reaper->fs->lock);
20200 ++ root = dget(reaper->fs->root.dentry);
20201 ++ rootmnt = mntget(reaper->fs->root.mnt);
20202 ++ read_unlock(&reaper->fs->lock);
20203 ++
20204 ++ spin_lock(&dcache_lock);
20205 ++ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
20206 ++ spin_unlock(&dcache_lock);
20207 ++
20208 ++ dput(root);
20209 ++ mntput(rootmnt);
20210 ++ return res;
20211 ++}
20212 ++
20213 ++static char *
20214 ++gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
20215 ++{
20216 ++ char *ret;
20217 ++ spin_lock(&dcache_lock);
20218 ++ ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
20219 ++ PAGE_SIZE);
20220 ++ spin_unlock(&dcache_lock);
20221 ++ return ret;
20222 ++}
20223 ++
20224 ++char *
20225 ++gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
20226 ++{
20227 ++ return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
20228 ++ PAGE_SIZE);
20229 ++}
20230 ++
20231 ++char *
20232 ++gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
20233 ++{
20234 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
20235 ++ PAGE_SIZE);
20236 ++}
20237 ++
20238 ++char *
20239 ++gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
20240 ++{
20241 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
20242 ++ PAGE_SIZE);
20243 ++}
20244 ++
20245 ++char *
20246 ++gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
20247 ++{
20248 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
20249 ++ PAGE_SIZE);
20250 ++}
20251 ++
20252 ++char *
20253 ++gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
20254 ++{
20255 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
20256 ++ PAGE_SIZE);
20257 ++}
20258 ++
20259 ++__inline__ __u32
20260 ++to_gr_audit(const __u32 reqmode)
20261 ++{
20262 ++ /* masks off auditable permission flags, then shifts them to create
20263 ++ auditing flags, and adds the special case of append auditing if
20264 ++ we're requesting write */
20265 ++ return (((reqmode & ~GR_AUDITS) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
20266 ++}
20267 ++
20268 ++struct acl_subject_label *
20269 ++lookup_subject_map(const struct acl_subject_label *userp)
20270 ++{
20271 ++ unsigned int index = shash(userp, subj_map_set.s_size);
20272 ++ struct subject_map *match;
20273 ++
20274 ++ match = subj_map_set.s_hash[index];
20275 ++
20276 ++ while (match && match->user != userp)
20277 ++ match = match->next;
20278 ++
20279 ++ if (match != NULL)
20280 ++ return match->kernel;
20281 ++ else
20282 ++ return NULL;
20283 ++}
20284 ++
20285 ++static void
20286 ++insert_subj_map_entry(struct subject_map *subjmap)
20287 ++{
20288 ++ unsigned int index = shash(subjmap->user, subj_map_set.s_size);
20289 ++ struct subject_map **curr;
20290 ++
20291 ++ subjmap->prev = NULL;
20292 ++
20293 ++ curr = &subj_map_set.s_hash[index];
20294 ++ if (*curr != NULL)
20295 ++ (*curr)->prev = subjmap;
20296 ++
20297 ++ subjmap->next = *curr;
20298 ++ *curr = subjmap;
20299 ++
20300 ++ return;
20301 ++}
20302 ++
20303 ++static struct acl_role_label *
20304 ++lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
20305 ++ const gid_t gid)
20306 ++{
20307 ++ unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
20308 ++ struct acl_role_label *match;
20309 ++ struct role_allowed_ip *ipp;
20310 ++ unsigned int x;
20311 ++
20312 ++ match = acl_role_set.r_hash[index];
20313 ++
20314 ++ while (match) {
20315 ++ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
20316 ++ for (x = 0; x < match->domain_child_num; x++) {
20317 ++ if (match->domain_children[x] == uid)
20318 ++ goto found;
20319 ++ }
20320 ++ } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
20321 ++ break;
20322 ++ match = match->next;
20323 ++ }
20324 ++found:
20325 ++ if (match == NULL) {
20326 ++ try_group:
20327 ++ index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
20328 ++ match = acl_role_set.r_hash[index];
20329 ++
20330 ++ while (match) {
20331 ++ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
20332 ++ for (x = 0; x < match->domain_child_num; x++) {
20333 ++ if (match->domain_children[x] == gid)
20334 ++ goto found2;
20335 ++ }
20336 ++ } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
20337 ++ break;
20338 ++ match = match->next;
20339 ++ }
20340 ++found2:
20341 ++ if (match == NULL)
20342 ++ match = default_role;
20343 ++ if (match->allowed_ips == NULL)
20344 ++ return match;
20345 ++ else {
20346 ++ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
20347 ++ if (likely
20348 ++ ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
20349 ++ (ntohl(ipp->addr) & ipp->netmask)))
20350 ++ return match;
20351 ++ }
20352 ++ match = default_role;
20353 ++ }
20354 ++ } else if (match->allowed_ips == NULL) {
20355 ++ return match;
20356 ++ } else {
20357 ++ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
20358 ++ if (likely
20359 ++ ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
20360 ++ (ntohl(ipp->addr) & ipp->netmask)))
20361 ++ return match;
20362 ++ }
20363 ++ goto try_group;
20364 ++ }
20365 ++
20366 ++ return match;
20367 ++}
20368 ++
20369 ++struct acl_subject_label *
20370 ++lookup_acl_subj_label(const ino_t ino, const dev_t dev,
20371 ++ const struct acl_role_label *role)
20372 ++{
20373 ++ unsigned int index = fhash(ino, dev, role->subj_hash_size);
20374 ++ struct acl_subject_label *match;
20375 ++
20376 ++ match = role->subj_hash[index];
20377 ++
20378 ++ while (match && (match->inode != ino || match->device != dev ||
20379 ++ (match->mode & GR_DELETED))) {
20380 ++ match = match->next;
20381 ++ }
20382 ++
20383 ++ if (match && !(match->mode & GR_DELETED))
20384 ++ return match;
20385 ++ else
20386 ++ return NULL;
20387 ++}
20388 ++
20389 ++static struct acl_object_label *
20390 ++lookup_acl_obj_label(const ino_t ino, const dev_t dev,
20391 ++ const struct acl_subject_label *subj)
20392 ++{
20393 ++ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
20394 ++ struct acl_object_label *match;
20395 ++
20396 ++ match = subj->obj_hash[index];
20397 ++
20398 ++ while (match && (match->inode != ino || match->device != dev ||
20399 ++ (match->mode & GR_DELETED))) {
20400 ++ match = match->next;
20401 ++ }
20402 ++
20403 ++ if (match && !(match->mode & GR_DELETED))
20404 ++ return match;
20405 ++ else
20406 ++ return NULL;
20407 ++}
20408 ++
20409 ++static struct acl_object_label *
20410 ++lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
20411 ++ const struct acl_subject_label *subj)
20412 ++{
20413 ++ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
20414 ++ struct acl_object_label *match;
20415 ++
20416 ++ match = subj->obj_hash[index];
20417 ++
20418 ++ while (match && (match->inode != ino || match->device != dev ||
20419 ++ !(match->mode & GR_DELETED))) {
20420 ++ match = match->next;
20421 ++ }
20422 ++
20423 ++ if (match && (match->mode & GR_DELETED))
20424 ++ return match;
20425 ++
20426 ++ match = subj->obj_hash[index];
20427 ++
20428 ++ while (match && (match->inode != ino || match->device != dev ||
20429 ++ (match->mode & GR_DELETED))) {
20430 ++ match = match->next;
20431 ++ }
20432 ++
20433 ++ if (match && !(match->mode & GR_DELETED))
20434 ++ return match;
20435 ++ else
20436 ++ return NULL;
20437 ++}
20438 ++
20439 ++static struct name_entry *
20440 ++lookup_name_entry(const char *name)
20441 ++{
20442 ++ unsigned int len = strlen(name);
20443 ++ unsigned int key = full_name_hash(name, len);
20444 ++ unsigned int index = key % name_set.n_size;
20445 ++ struct name_entry *match;
20446 ++
20447 ++ match = name_set.n_hash[index];
20448 ++
20449 ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
20450 ++ match = match->next;
20451 ++
20452 ++ return match;
20453 ++}
20454 ++
20455 ++static struct name_entry *
20456 ++lookup_name_entry_create(const char *name)
20457 ++{
20458 ++ unsigned int len = strlen(name);
20459 ++ unsigned int key = full_name_hash(name, len);
20460 ++ unsigned int index = key % name_set.n_size;
20461 ++ struct name_entry *match;
20462 ++
20463 ++ match = name_set.n_hash[index];
20464 ++
20465 ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
20466 ++ !match->deleted))
20467 ++ match = match->next;
20468 ++
20469 ++ if (match && match->deleted)
20470 ++ return match;
20471 ++
20472 ++ match = name_set.n_hash[index];
20473 ++
20474 ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
20475 ++ match->deleted))
20476 ++ match = match->next;
20477 ++
20478 ++ if (match && !match->deleted)
20479 ++ return match;
20480 ++ else
20481 ++ return NULL;
20482 ++}
20483 ++
20484 ++static struct inodev_entry *
20485 ++lookup_inodev_entry(const ino_t ino, const dev_t dev)
20486 ++{
20487 ++ unsigned int index = fhash(ino, dev, inodev_set.i_size);
20488 ++ struct inodev_entry *match;
20489 ++
20490 ++ match = inodev_set.i_hash[index];
20491 ++
20492 ++ while (match && (match->nentry->inode != ino || match->nentry->device != dev))
20493 ++ match = match->next;
20494 ++
20495 ++ return match;
20496 ++}
20497 ++
20498 ++static void
20499 ++insert_inodev_entry(struct inodev_entry *entry)
20500 ++{
20501 ++ unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
20502 ++ inodev_set.i_size);
20503 ++ struct inodev_entry **curr;
20504 ++
20505 ++ entry->prev = NULL;
20506 ++
20507 ++ curr = &inodev_set.i_hash[index];
20508 ++ if (*curr != NULL)
20509 ++ (*curr)->prev = entry;
20510 ++
20511 ++ entry->next = *curr;
20512 ++ *curr = entry;
20513 ++
20514 ++ return;
20515 ++}
20516 ++
20517 ++static void
20518 ++__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
20519 ++{
20520 ++ unsigned int index =
20521 ++ rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
20522 ++ struct acl_role_label **curr;
20523 ++
20524 ++ role->prev = NULL;
20525 ++
20526 ++ curr = &acl_role_set.r_hash[index];
20527 ++ if (*curr != NULL)
20528 ++ (*curr)->prev = role;
20529 ++
20530 ++ role->next = *curr;
20531 ++ *curr = role;
20532 ++
20533 ++ return;
20534 ++}
20535 ++
20536 ++static void
20537 ++insert_acl_role_label(struct acl_role_label *role)
20538 ++{
20539 ++ int i;
20540 ++
20541 ++ if (role->roletype & GR_ROLE_DOMAIN) {
20542 ++ for (i = 0; i < role->domain_child_num; i++)
20543 ++ __insert_acl_role_label(role, role->domain_children[i]);
20544 ++ } else
20545 ++ __insert_acl_role_label(role, role->uidgid);
20546 ++}
20547 ++
20548 ++static int
20549 ++insert_name_entry(char *name, const ino_t inode, const dev_t device, __u8 deleted)
20550 ++{
20551 ++ struct name_entry **curr, *nentry;
20552 ++ struct inodev_entry *ientry;
20553 ++ unsigned int len = strlen(name);
20554 ++ unsigned int key = full_name_hash(name, len);
20555 ++ unsigned int index = key % name_set.n_size;
20556 ++
20557 ++ curr = &name_set.n_hash[index];
20558 ++
20559 ++ while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
20560 ++ curr = &((*curr)->next);
20561 ++
20562 ++ if (*curr != NULL)
20563 ++ return 1;
20564 ++
20565 ++ nentry = acl_alloc(sizeof (struct name_entry));
20566 ++ if (nentry == NULL)
20567 ++ return 0;
20568 ++ ientry = acl_alloc(sizeof (struct inodev_entry));
20569 ++ if (ientry == NULL)
20570 ++ return 0;
20571 ++ ientry->nentry = nentry;
20572 ++
20573 ++ nentry->key = key;
20574 ++ nentry->name = name;
20575 ++ nentry->inode = inode;
20576 ++ nentry->device = device;
20577 ++ nentry->len = len;
20578 ++ nentry->deleted = deleted;
20579 ++
20580 ++ nentry->prev = NULL;
20581 ++ curr = &name_set.n_hash[index];
20582 ++ if (*curr != NULL)
20583 ++ (*curr)->prev = nentry;
20584 ++ nentry->next = *curr;
20585 ++ *curr = nentry;
20586 ++
20587 ++ /* insert us into the table searchable by inode/dev */
20588 ++ insert_inodev_entry(ientry);
20589 ++
20590 ++ return 1;
20591 ++}
20592 ++
20593 ++static void
20594 ++insert_acl_obj_label(struct acl_object_label *obj,
20595 ++ struct acl_subject_label *subj)
20596 ++{
20597 ++ unsigned int index =
20598 ++ fhash(obj->inode, obj->device, subj->obj_hash_size);
20599 ++ struct acl_object_label **curr;
20600 ++
20601 ++
20602 ++ obj->prev = NULL;
20603 ++
20604 ++ curr = &subj->obj_hash[index];
20605 ++ if (*curr != NULL)
20606 ++ (*curr)->prev = obj;
20607 ++
20608 ++ obj->next = *curr;
20609 ++ *curr = obj;
20610 ++
20611 ++ return;
20612 ++}
20613 ++
20614 ++static void
20615 ++insert_acl_subj_label(struct acl_subject_label *obj,
20616 ++ struct acl_role_label *role)
20617 ++{
20618 ++ unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
20619 ++ struct acl_subject_label **curr;
20620 ++
20621 ++ obj->prev = NULL;
20622 ++
20623 ++ curr = &role->subj_hash[index];
20624 ++ if (*curr != NULL)
20625 ++ (*curr)->prev = obj;
20626 ++
20627 ++ obj->next = *curr;
20628 ++ *curr = obj;
20629 ++
20630 ++ return;
20631 ++}
20632 ++
20633 ++/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
20634 ++
20635 ++static void *
20636 ++create_table(__u32 * len, int elementsize)
20637 ++{
20638 ++ unsigned int table_sizes[] = {
20639 ++ 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
20640 ++ 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
20641 ++ 4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
20642 ++ 268435399, 536870909, 1073741789, 2147483647
20643 ++ };
20644 ++ void *newtable = NULL;
20645 ++ unsigned int pwr = 0;
20646 ++
20647 ++ while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
20648 ++ table_sizes[pwr] <= *len)
20649 ++ pwr++;
20650 ++
20651 ++ if (table_sizes[pwr] <= *len)
20652 ++ return newtable;
20653 ++
20654 ++ if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
20655 ++ newtable =
20656 ++ kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
20657 ++ else
20658 ++ newtable = vmalloc(table_sizes[pwr] * elementsize);
20659 ++
20660 ++ *len = table_sizes[pwr];
20661 ++
20662 ++ return newtable;
20663 ++}
20664 ++
20665 ++static int
20666 ++init_variables(const struct gr_arg *arg)
20667 ++{
20668 ++ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
20669 ++ unsigned int stacksize;
20670 ++
20671 ++ subj_map_set.s_size = arg->role_db.num_subjects;
20672 ++ acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
20673 ++ name_set.n_size = arg->role_db.num_objects;
20674 ++ inodev_set.i_size = arg->role_db.num_objects;
20675 ++
20676 ++ if (!subj_map_set.s_size || !acl_role_set.r_size ||
20677 ++ !name_set.n_size || !inodev_set.i_size)
20678 ++ return 1;
20679 ++
20680 ++ if (!gr_init_uidset())
20681 ++ return 1;
20682 ++
20683 ++ /* set up the stack that holds allocation info */
20684 ++
20685 ++ stacksize = arg->role_db.num_pointers + 5;
20686 ++
20687 ++ if (!acl_alloc_stack_init(stacksize))
20688 ++ return 1;
20689 ++
20690 ++ /* grab reference for the real root dentry and vfsmount */
20691 ++ read_lock(&reaper->fs->lock);
20692 ++ real_root_mnt = mntget(reaper->fs->root.mnt);
20693 ++ real_root = dget(reaper->fs->root.dentry);
20694 ++ read_unlock(&reaper->fs->lock);
20695 ++
20696 ++ fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
20697 ++ if (fakefs_obj == NULL)
20698 ++ return 1;
20699 ++ fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
20700 ++
20701 ++ subj_map_set.s_hash =
20702 ++ (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
20703 ++ acl_role_set.r_hash =
20704 ++ (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
20705 ++ name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
20706 ++ inodev_set.i_hash =
20707 ++ (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
20708 ++
20709 ++ if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
20710 ++ !name_set.n_hash || !inodev_set.i_hash)
20711 ++ return 1;
20712 ++
20713 ++ memset(subj_map_set.s_hash, 0,
20714 ++ sizeof(struct subject_map *) * subj_map_set.s_size);
20715 ++ memset(acl_role_set.r_hash, 0,
20716 ++ sizeof (struct acl_role_label *) * acl_role_set.r_size);
20717 ++ memset(name_set.n_hash, 0,
20718 ++ sizeof (struct name_entry *) * name_set.n_size);
20719 ++ memset(inodev_set.i_hash, 0,
20720 ++ sizeof (struct inodev_entry *) * inodev_set.i_size);
20721 ++
20722 ++ return 0;
20723 ++}
20724 ++
20725 ++/* free information not needed after startup
20726 ++ currently contains user->kernel pointer mappings for subjects
20727 ++*/
20728 ++
20729 ++static void
20730 ++free_init_variables(void)
20731 ++{
20732 ++ __u32 i;
20733 ++
20734 ++ if (subj_map_set.s_hash) {
20735 ++ for (i = 0; i < subj_map_set.s_size; i++) {
20736 ++ if (subj_map_set.s_hash[i]) {
20737 ++ kfree(subj_map_set.s_hash[i]);
20738 ++ subj_map_set.s_hash[i] = NULL;
20739 ++ }
20740 ++ }
20741 ++
20742 ++ if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
20743 ++ PAGE_SIZE)
20744 ++ kfree(subj_map_set.s_hash);
20745 ++ else
20746 ++ vfree(subj_map_set.s_hash);
20747 ++ }
20748 ++
20749 ++ return;
20750 ++}
20751 ++
20752 ++static void
20753 ++free_variables(void)
20754 ++{
20755 ++ struct acl_subject_label *s;
20756 ++ struct acl_role_label *r;
20757 ++ struct task_struct *task, *task2;
20758 ++ unsigned int i, x;
20759 ++
20760 ++ gr_clear_learn_entries();
20761 ++
20762 ++ read_lock(&tasklist_lock);
20763 ++ do_each_thread(task2, task) {
20764 ++ task->acl_sp_role = 0;
20765 ++ task->acl_role_id = 0;
20766 ++ task->acl = NULL;
20767 ++ task->role = NULL;
20768 ++ } while_each_thread(task2, task);
20769 ++ read_unlock(&tasklist_lock);
20770 ++
20771 ++ /* release the reference to the real root dentry and vfsmount */
20772 ++ if (real_root)
20773 ++ dput(real_root);
20774 ++ real_root = NULL;
20775 ++ if (real_root_mnt)
20776 ++ mntput(real_root_mnt);
20777 ++ real_root_mnt = NULL;
20778 ++
20779 ++ /* free all object hash tables */
20780 ++
20781 ++ FOR_EACH_ROLE_START(r, i)
20782 ++ if (r->subj_hash == NULL)
20783 ++ break;
20784 ++ FOR_EACH_SUBJECT_START(r, s, x)
20785 ++ if (s->obj_hash == NULL)
20786 ++ break;
20787 ++ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
20788 ++ kfree(s->obj_hash);
20789 ++ else
20790 ++ vfree(s->obj_hash);
20791 ++ FOR_EACH_SUBJECT_END(s, x)
20792 ++ FOR_EACH_NESTED_SUBJECT_START(r, s)
20793 ++ if (s->obj_hash == NULL)
20794 ++ break;
20795 ++ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
20796 ++ kfree(s->obj_hash);
20797 ++ else
20798 ++ vfree(s->obj_hash);
20799 ++ FOR_EACH_NESTED_SUBJECT_END(s)
20800 ++ if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
20801 ++ kfree(r->subj_hash);
20802 ++ else
20803 ++ vfree(r->subj_hash);
20804 ++ r->subj_hash = NULL;
20805 ++ FOR_EACH_ROLE_END(r,i)
20806 ++
20807 ++ acl_free_all();
20808 ++
20809 ++ if (acl_role_set.r_hash) {
20810 ++ if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
20811 ++ PAGE_SIZE)
20812 ++ kfree(acl_role_set.r_hash);
20813 ++ else
20814 ++ vfree(acl_role_set.r_hash);
20815 ++ }
20816 ++ if (name_set.n_hash) {
20817 ++ if ((name_set.n_size * sizeof (struct name_entry *)) <=
20818 ++ PAGE_SIZE)
20819 ++ kfree(name_set.n_hash);
20820 ++ else
20821 ++ vfree(name_set.n_hash);
20822 ++ }
20823 ++
20824 ++ if (inodev_set.i_hash) {
20825 ++ if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
20826 ++ PAGE_SIZE)
20827 ++ kfree(inodev_set.i_hash);
20828 ++ else
20829 ++ vfree(inodev_set.i_hash);
20830 ++ }
20831 ++
20832 ++ gr_free_uidset();
20833 ++
20834 ++ memset(&name_set, 0, sizeof (struct name_db));
20835 ++ memset(&inodev_set, 0, sizeof (struct inodev_db));
20836 ++ memset(&acl_role_set, 0, sizeof (struct acl_role_db));
20837 ++ memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
20838 ++
20839 ++ default_role = NULL;
20840 ++
20841 ++ return;
20842 ++}
20843 ++
20844 ++static __u32
20845 ++count_user_objs(struct acl_object_label *userp)
20846 ++{
20847 ++ struct acl_object_label o_tmp;
20848 ++ __u32 num = 0;
20849 ++
20850 ++ while (userp) {
20851 ++ if (copy_from_user(&o_tmp, userp,
20852 ++ sizeof (struct acl_object_label)))
20853 ++ break;
20854 ++
20855 ++ userp = o_tmp.prev;
20856 ++ num++;
20857 ++ }
20858 ++
20859 ++ return num;
20860 ++}
20861 ++
20862 ++static struct acl_subject_label *
20863 ++do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
20864 ++
20865 ++static int
20866 ++copy_user_glob(struct acl_object_label *obj)
20867 ++{
20868 ++ struct acl_object_label *g_tmp, **guser;
20869 ++ unsigned int len;
20870 ++ char *tmp;
20871 ++
20872 ++ if (obj->globbed == NULL)
20873 ++ return 0;
20874 ++
20875 ++ guser = &obj->globbed;
20876 ++ while (*guser) {
20877 ++ g_tmp = (struct acl_object_label *)
20878 ++ acl_alloc(sizeof (struct acl_object_label));
20879 ++ if (g_tmp == NULL)
20880 ++ return -ENOMEM;
20881 ++
20882 ++ if (copy_from_user(g_tmp, *guser,
20883 ++ sizeof (struct acl_object_label)))
20884 ++ return -EFAULT;
20885 ++
20886 ++ len = strnlen_user(g_tmp->filename, PATH_MAX);
20887 ++
20888 ++ if (!len || len >= PATH_MAX)
20889 ++ return -EINVAL;
20890 ++
20891 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
20892 ++ return -ENOMEM;
20893 ++
20894 ++ if (copy_from_user(tmp, g_tmp->filename, len))
20895 ++ return -EFAULT;
20896 ++
20897 ++ g_tmp->filename = tmp;
20898 ++
20899 ++ *guser = g_tmp;
20900 ++ guser = &(g_tmp->next);
20901 ++ }
20902 ++
20903 ++ return 0;
20904 ++}
20905 ++
20906 ++static int
20907 ++copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
20908 ++ struct acl_role_label *role)
20909 ++{
20910 ++ struct acl_object_label *o_tmp;
20911 ++ unsigned int len;
20912 ++ int ret;
20913 ++ char *tmp;
20914 ++
20915 ++ while (userp) {
20916 ++ if ((o_tmp = (struct acl_object_label *)
20917 ++ acl_alloc(sizeof (struct acl_object_label))) == NULL)
20918 ++ return -ENOMEM;
20919 ++
20920 ++ if (copy_from_user(o_tmp, userp,
20921 ++ sizeof (struct acl_object_label)))
20922 ++ return -EFAULT;
20923 ++
20924 ++ userp = o_tmp->prev;
20925 ++
20926 ++ len = strnlen_user(o_tmp->filename, PATH_MAX);
20927 ++
20928 ++ if (!len || len >= PATH_MAX)
20929 ++ return -EINVAL;
20930 ++
20931 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
20932 ++ return -ENOMEM;
20933 ++
20934 ++ if (copy_from_user(tmp, o_tmp->filename, len))
20935 ++ return -EFAULT;
20936 ++
20937 ++ o_tmp->filename = tmp;
20938 ++
20939 ++ insert_acl_obj_label(o_tmp, subj);
20940 ++ if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
20941 ++ o_tmp->device, (o_tmp->mode & GR_DELETED) ? 1 : 0))
20942 ++ return -ENOMEM;
20943 ++
20944 ++ ret = copy_user_glob(o_tmp);
20945 ++ if (ret)
20946 ++ return ret;
20947 ++
20948 ++ if (o_tmp->nested) {
20949 ++ o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
20950 ++ if (IS_ERR(o_tmp->nested))
20951 ++ return PTR_ERR(o_tmp->nested);
20952 ++
20953 ++ /* insert into nested subject list */
20954 ++ o_tmp->nested->next = role->hash->first;
20955 ++ role->hash->first = o_tmp->nested;
20956 ++ }
20957 ++ }
20958 ++
20959 ++ return 0;
20960 ++}
20961 ++
20962 ++static __u32
20963 ++count_user_subjs(struct acl_subject_label *userp)
20964 ++{
20965 ++ struct acl_subject_label s_tmp;
20966 ++ __u32 num = 0;
20967 ++
20968 ++ while (userp) {
20969 ++ if (copy_from_user(&s_tmp, userp,
20970 ++ sizeof (struct acl_subject_label)))
20971 ++ break;
20972 ++
20973 ++ userp = s_tmp.prev;
20974 ++ /* do not count nested subjects against this count, since
20975 ++ they are not included in the hash table, but are
20976 ++ attached to objects. We have already counted
20977 ++ the subjects in userspace for the allocation
20978 ++ stack
20979 ++ */
20980 ++ if (!(s_tmp.mode & GR_NESTED))
20981 ++ num++;
20982 ++ }
20983 ++
20984 ++ return num;
20985 ++}
20986 ++
20987 ++static int
20988 ++copy_user_allowedips(struct acl_role_label *rolep)
20989 ++{
20990 ++ struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
20991 ++
20992 ++ ruserip = rolep->allowed_ips;
20993 ++
20994 ++ while (ruserip) {
20995 ++ rlast = rtmp;
20996 ++
20997 ++ if ((rtmp = (struct role_allowed_ip *)
20998 ++ acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
20999 ++ return -ENOMEM;
21000 ++
21001 ++ if (copy_from_user(rtmp, ruserip,
21002 ++ sizeof (struct role_allowed_ip)))
21003 ++ return -EFAULT;
21004 ++
21005 ++ ruserip = rtmp->prev;
21006 ++
21007 ++ if (!rlast) {
21008 ++ rtmp->prev = NULL;
21009 ++ rolep->allowed_ips = rtmp;
21010 ++ } else {
21011 ++ rlast->next = rtmp;
21012 ++ rtmp->prev = rlast;
21013 ++ }
21014 ++
21015 ++ if (!ruserip)
21016 ++ rtmp->next = NULL;
21017 ++ }
21018 ++
21019 ++ return 0;
21020 ++}
21021 ++
21022 ++static int
21023 ++copy_user_transitions(struct acl_role_label *rolep)
21024 ++{
21025 ++ struct role_transition *rusertp, *rtmp = NULL, *rlast;
21026 ++
21027 ++ unsigned int len;
21028 ++ char *tmp;
21029 ++
21030 ++ rusertp = rolep->transitions;
21031 ++
21032 ++ while (rusertp) {
21033 ++ rlast = rtmp;
21034 ++
21035 ++ if ((rtmp = (struct role_transition *)
21036 ++ acl_alloc(sizeof (struct role_transition))) == NULL)
21037 ++ return -ENOMEM;
21038 ++
21039 ++ if (copy_from_user(rtmp, rusertp,
21040 ++ sizeof (struct role_transition)))
21041 ++ return -EFAULT;
21042 ++
21043 ++ rusertp = rtmp->prev;
21044 ++
21045 ++ len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
21046 ++
21047 ++ if (!len || len >= GR_SPROLE_LEN)
21048 ++ return -EINVAL;
21049 ++
21050 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
21051 ++ return -ENOMEM;
21052 ++
21053 ++ if (copy_from_user(tmp, rtmp->rolename, len))
21054 ++ return -EFAULT;
21055 ++
21056 ++ rtmp->rolename = tmp;
21057 ++
21058 ++ if (!rlast) {
21059 ++ rtmp->prev = NULL;
21060 ++ rolep->transitions = rtmp;
21061 ++ } else {
21062 ++ rlast->next = rtmp;
21063 ++ rtmp->prev = rlast;
21064 ++ }
21065 ++
21066 ++ if (!rusertp)
21067 ++ rtmp->next = NULL;
21068 ++ }
21069 ++
21070 ++ return 0;
21071 ++}
21072 ++
21073 ++static struct acl_subject_label *
21074 ++do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
21075 ++{
21076 ++ struct acl_subject_label *s_tmp = NULL, *s_tmp2;
21077 ++ unsigned int len;
21078 ++ char *tmp;
21079 ++ __u32 num_objs;
21080 ++ struct acl_ip_label **i_tmp, *i_utmp2;
21081 ++ struct gr_hash_struct ghash;
21082 ++ struct subject_map *subjmap;
21083 ++ unsigned int i_num;
21084 ++ int err;
21085 ++
21086 ++ s_tmp = lookup_subject_map(userp);
21087 ++
21088 ++ /* we've already copied this subject into the kernel, just return
21089 ++ the reference to it, and don't copy it over again
21090 ++ */
21091 ++ if (s_tmp)
21092 ++ return(s_tmp);
21093 ++
21094 ++ if ((s_tmp = (struct acl_subject_label *)
21095 ++ acl_alloc(sizeof (struct acl_subject_label))) == NULL)
21096 ++ return ERR_PTR(-ENOMEM);
21097 ++
21098 ++ subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
21099 ++ if (subjmap == NULL)
21100 ++ return ERR_PTR(-ENOMEM);
21101 ++
21102 ++ subjmap->user = userp;
21103 ++ subjmap->kernel = s_tmp;
21104 ++ insert_subj_map_entry(subjmap);
21105 ++
21106 ++ if (copy_from_user(s_tmp, userp,
21107 ++ sizeof (struct acl_subject_label)))
21108 ++ return ERR_PTR(-EFAULT);
21109 ++
21110 ++ len = strnlen_user(s_tmp->filename, PATH_MAX);
21111 ++
21112 ++ if (!len || len >= PATH_MAX)
21113 ++ return ERR_PTR(-EINVAL);
21114 ++
21115 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
21116 ++ return ERR_PTR(-ENOMEM);
21117 ++
21118 ++ if (copy_from_user(tmp, s_tmp->filename, len))
21119 ++ return ERR_PTR(-EFAULT);
21120 ++
21121 ++ s_tmp->filename = tmp;
21122 ++
21123 ++ if (!strcmp(s_tmp->filename, "/"))
21124 ++ role->root_label = s_tmp;
21125 ++
21126 ++ if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
21127 ++ return ERR_PTR(-EFAULT);
21128 ++
21129 ++ /* copy user and group transition tables */
21130 ++
21131 ++ if (s_tmp->user_trans_num) {
21132 ++ uid_t *uidlist;
21133 ++
21134 ++ uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
21135 ++ if (uidlist == NULL)
21136 ++ return ERR_PTR(-ENOMEM);
21137 ++ if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
21138 ++ return ERR_PTR(-EFAULT);
21139 ++
21140 ++ s_tmp->user_transitions = uidlist;
21141 ++ }
21142 ++
21143 ++ if (s_tmp->group_trans_num) {
21144 ++ gid_t *gidlist;
21145 ++
21146 ++ gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
21147 ++ if (gidlist == NULL)
21148 ++ return ERR_PTR(-ENOMEM);
21149 ++ if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
21150 ++ return ERR_PTR(-EFAULT);
21151 ++
21152 ++ s_tmp->group_transitions = gidlist;
21153 ++ }
21154 ++
21155 ++ /* set up object hash table */
21156 ++ num_objs = count_user_objs(ghash.first);
21157 ++
21158 ++ s_tmp->obj_hash_size = num_objs;
21159 ++ s_tmp->obj_hash =
21160 ++ (struct acl_object_label **)
21161 ++ create_table(&(s_tmp->obj_hash_size), sizeof(void *));
21162 ++
21163 ++ if (!s_tmp->obj_hash)
21164 ++ return ERR_PTR(-ENOMEM);
21165 ++
21166 ++ memset(s_tmp->obj_hash, 0,
21167 ++ s_tmp->obj_hash_size *
21168 ++ sizeof (struct acl_object_label *));
21169 ++
21170 ++ /* add in objects */
21171 ++ err = copy_user_objs(ghash.first, s_tmp, role);
21172 ++
21173 ++ if (err)
21174 ++ return ERR_PTR(err);
21175 ++
21176 ++ /* set pointer for parent subject */
21177 ++ if (s_tmp->parent_subject) {
21178 ++ s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
21179 ++
21180 ++ if (IS_ERR(s_tmp2))
21181 ++ return s_tmp2;
21182 ++
21183 ++ s_tmp->parent_subject = s_tmp2;
21184 ++ }
21185 ++
21186 ++ /* add in ip acls */
21187 ++
21188 ++ if (!s_tmp->ip_num) {
21189 ++ s_tmp->ips = NULL;
21190 ++ goto insert;
21191 ++ }
21192 ++
21193 ++ i_tmp =
21194 ++ (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
21195 ++ sizeof (struct
21196 ++ acl_ip_label *));
21197 ++
21198 ++ if (!i_tmp)
21199 ++ return ERR_PTR(-ENOMEM);
21200 ++
21201 ++ for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
21202 ++ *(i_tmp + i_num) =
21203 ++ (struct acl_ip_label *)
21204 ++ acl_alloc(sizeof (struct acl_ip_label));
21205 ++ if (!*(i_tmp + i_num))
21206 ++ return ERR_PTR(-ENOMEM);
21207 ++
21208 ++ if (copy_from_user
21209 ++ (&i_utmp2, s_tmp->ips + i_num,
21210 ++ sizeof (struct acl_ip_label *)))
21211 ++ return ERR_PTR(-EFAULT);
21212 ++
21213 ++ if (copy_from_user
21214 ++ (*(i_tmp + i_num), i_utmp2,
21215 ++ sizeof (struct acl_ip_label)))
21216 ++ return ERR_PTR(-EFAULT);
21217 ++
21218 ++ if ((*(i_tmp + i_num))->iface == NULL)
21219 ++ continue;
21220 ++
21221 ++ len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
21222 ++ if (!len || len >= IFNAMSIZ)
21223 ++ return ERR_PTR(-EINVAL);
21224 ++ tmp = acl_alloc(len);
21225 ++ if (tmp == NULL)
21226 ++ return ERR_PTR(-ENOMEM);
21227 ++ if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
21228 ++ return ERR_PTR(-EFAULT);
21229 ++ (*(i_tmp + i_num))->iface = tmp;
21230 ++ }
21231 ++
21232 ++ s_tmp->ips = i_tmp;
21233 ++
21234 ++insert:
21235 ++ if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
21236 ++ s_tmp->device, (s_tmp->mode & GR_DELETED) ? 1 : 0))
21237 ++ return ERR_PTR(-ENOMEM);
21238 ++
21239 ++ return s_tmp;
21240 ++}
21241 ++
21242 ++static int
21243 ++copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
21244 ++{
21245 ++ struct acl_subject_label s_pre;
21246 ++ struct acl_subject_label * ret;
21247 ++ int err;
21248 ++
21249 ++ while (userp) {
21250 ++ if (copy_from_user(&s_pre, userp,
21251 ++ sizeof (struct acl_subject_label)))
21252 ++ return -EFAULT;
21253 ++
21254 ++ /* do not add nested subjects here, add
21255 ++ while parsing objects
21256 ++ */
21257 ++
21258 ++ if (s_pre.mode & GR_NESTED) {
21259 ++ userp = s_pre.prev;
21260 ++ continue;
21261 ++ }
21262 ++
21263 ++ ret = do_copy_user_subj(userp, role);
21264 ++
21265 ++ err = PTR_ERR(ret);
21266 ++ if (IS_ERR(ret))
21267 ++ return err;
21268 ++
21269 ++ insert_acl_subj_label(ret, role);
21270 ++
21271 ++ userp = s_pre.prev;
21272 ++ }
21273 ++
21274 ++ return 0;
21275 ++}
21276 ++
21277 ++static int
21278 ++copy_user_acl(struct gr_arg *arg)
21279 ++{
21280 ++ struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
21281 ++ struct sprole_pw *sptmp;
21282 ++ struct gr_hash_struct *ghash;
21283 ++ uid_t *domainlist;
21284 ++ unsigned int r_num;
21285 ++ unsigned int len;
21286 ++ char *tmp;
21287 ++ int err = 0;
21288 ++ __u16 i;
21289 ++ __u32 num_subjs;
21290 ++
21291 ++ /* we need a default and kernel role */
21292 ++ if (arg->role_db.num_roles < 2)
21293 ++ return -EINVAL;
21294 ++
21295 ++ /* copy special role authentication info from userspace */
21296 ++
21297 ++ num_sprole_pws = arg->num_sprole_pws;
21298 ++ acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
21299 ++
21300 ++ if (!acl_special_roles) {
21301 ++ err = -ENOMEM;
21302 ++ goto cleanup;
21303 ++ }
21304 ++
21305 ++ for (i = 0; i < num_sprole_pws; i++) {
21306 ++ sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
21307 ++ if (!sptmp) {
21308 ++ err = -ENOMEM;
21309 ++ goto cleanup;
21310 ++ }
21311 ++ if (copy_from_user(sptmp, arg->sprole_pws + i,
21312 ++ sizeof (struct sprole_pw))) {
21313 ++ err = -EFAULT;
21314 ++ goto cleanup;
21315 ++ }
21316 ++
21317 ++ len =
21318 ++ strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
21319 ++
21320 ++ if (!len || len >= GR_SPROLE_LEN) {
21321 ++ err = -EINVAL;
21322 ++ goto cleanup;
21323 ++ }
21324 ++
21325 ++ if ((tmp = (char *) acl_alloc(len)) == NULL) {
21326 ++ err = -ENOMEM;
21327 ++ goto cleanup;
21328 ++ }
21329 ++
21330 ++ if (copy_from_user(tmp, sptmp->rolename, len)) {
21331 ++ err = -EFAULT;
21332 ++ goto cleanup;
21333 ++ }
21334 ++
21335 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
21336 ++ printk(KERN_ALERT "Copying special role %s\n", tmp);
21337 ++#endif
21338 ++ sptmp->rolename = tmp;
21339 ++ acl_special_roles[i] = sptmp;
21340 ++ }
21341 ++
21342 ++ r_utmp = (struct acl_role_label **) arg->role_db.r_table;
21343 ++
21344 ++ for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
21345 ++ r_tmp = acl_alloc(sizeof (struct acl_role_label));
21346 ++
21347 ++ if (!r_tmp) {
21348 ++ err = -ENOMEM;
21349 ++ goto cleanup;
21350 ++ }
21351 ++
21352 ++ if (copy_from_user(&r_utmp2, r_utmp + r_num,
21353 ++ sizeof (struct acl_role_label *))) {
21354 ++ err = -EFAULT;
21355 ++ goto cleanup;
21356 ++ }
21357 ++
21358 ++ if (copy_from_user(r_tmp, r_utmp2,
21359 ++ sizeof (struct acl_role_label))) {
21360 ++ err = -EFAULT;
21361 ++ goto cleanup;
21362 ++ }
21363 ++
21364 ++ len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
21365 ++
21366 ++ if (!len || len >= PATH_MAX) {
21367 ++ err = -EINVAL;
21368 ++ goto cleanup;
21369 ++ }
21370 ++
21371 ++ if ((tmp = (char *) acl_alloc(len)) == NULL) {
21372 ++ err = -ENOMEM;
21373 ++ goto cleanup;
21374 ++ }
21375 ++ if (copy_from_user(tmp, r_tmp->rolename, len)) {
21376 ++ err = -EFAULT;
21377 ++ goto cleanup;
21378 ++ }
21379 ++ r_tmp->rolename = tmp;
21380 ++
21381 ++ if (!strcmp(r_tmp->rolename, "default")
21382 ++ && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
21383 ++ default_role = r_tmp;
21384 ++ } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
21385 ++ kernel_role = r_tmp;
21386 ++ }
21387 ++
21388 ++ if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
21389 ++ err = -ENOMEM;
21390 ++ goto cleanup;
21391 ++ }
21392 ++ if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
21393 ++ err = -EFAULT;
21394 ++ goto cleanup;
21395 ++ }
21396 ++
21397 ++ r_tmp->hash = ghash;
21398 ++
21399 ++ num_subjs = count_user_subjs(r_tmp->hash->first);
21400 ++
21401 ++ r_tmp->subj_hash_size = num_subjs;
21402 ++ r_tmp->subj_hash =
21403 ++ (struct acl_subject_label **)
21404 ++ create_table(&(r_tmp->subj_hash_size), sizeof(void *));
21405 ++
21406 ++ if (!r_tmp->subj_hash) {
21407 ++ err = -ENOMEM;
21408 ++ goto cleanup;
21409 ++ }
21410 ++
21411 ++ err = copy_user_allowedips(r_tmp);
21412 ++ if (err)
21413 ++ goto cleanup;
21414 ++
21415 ++ /* copy domain info */
21416 ++ if (r_tmp->domain_children != NULL) {
21417 ++ domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
21418 ++ if (domainlist == NULL) {
21419 ++ err = -ENOMEM;
21420 ++ goto cleanup;
21421 ++ }
21422 ++ if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
21423 ++ err = -EFAULT;
21424 ++ goto cleanup;
21425 ++ }
21426 ++ r_tmp->domain_children = domainlist;
21427 ++ }
21428 ++
21429 ++ err = copy_user_transitions(r_tmp);
21430 ++ if (err)
21431 ++ goto cleanup;
21432 ++
21433 ++ memset(r_tmp->subj_hash, 0,
21434 ++ r_tmp->subj_hash_size *
21435 ++ sizeof (struct acl_subject_label *));
21436 ++
21437 ++ err = copy_user_subjs(r_tmp->hash->first, r_tmp);
21438 ++
21439 ++ if (err)
21440 ++ goto cleanup;
21441 ++
21442 ++ /* set nested subject list to null */
21443 ++ r_tmp->hash->first = NULL;
21444 ++
21445 ++ insert_acl_role_label(r_tmp);
21446 ++ }
21447 ++
21448 ++ goto return_err;
21449 ++ cleanup:
21450 ++ free_variables();
21451 ++ return_err:
21452 ++ return err;
21453 ++
21454 ++}
21455 ++
21456 ++static int
21457 ++gracl_init(struct gr_arg *args)
21458 ++{
21459 ++ int error = 0;
21460 ++
21461 ++ memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
21462 ++ memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
21463 ++
21464 ++ if (init_variables(args)) {
21465 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
21466 ++ error = -ENOMEM;
21467 ++ free_variables();
21468 ++ goto out;
21469 ++ }
21470 ++
21471 ++ error = copy_user_acl(args);
21472 ++ free_init_variables();
21473 ++ if (error) {
21474 ++ free_variables();
21475 ++ goto out;
21476 ++ }
21477 ++
21478 ++ if ((error = gr_set_acls(0))) {
21479 ++ free_variables();
21480 ++ goto out;
21481 ++ }
21482 ++
21483 ++ gr_status |= GR_READY;
21484 ++ out:
21485 ++ return error;
21486 ++}
21487 ++
21488 ++/* derived from glibc fnmatch() 0: match, 1: no match*/
21489 ++
21490 ++static int
21491 ++glob_match(const char *p, const char *n)
21492 ++{
21493 ++ char c;
21494 ++
21495 ++ while ((c = *p++) != '\0') {
21496 ++ switch (c) {
21497 ++ case '?':
21498 ++ if (*n == '\0')
21499 ++ return 1;
21500 ++ else if (*n == '/')
21501 ++ return 1;
21502 ++ break;
21503 ++ case '\\':
21504 ++ if (*n != c)
21505 ++ return 1;
21506 ++ break;
21507 ++ case '*':
21508 ++ for (c = *p++; c == '?' || c == '*'; c = *p++) {
21509 ++ if (*n == '/')
21510 ++ return 1;
21511 ++ else if (c == '?') {
21512 ++ if (*n == '\0')
21513 ++ return 1;
21514 ++ else
21515 ++ ++n;
21516 ++ }
21517 ++ }
21518 ++ if (c == '\0') {
21519 ++ return 0;
21520 ++ } else {
21521 ++ const char *endp;
21522 ++
21523 ++ if ((endp = strchr(n, '/')) == NULL)
21524 ++ endp = n + strlen(n);
21525 ++
21526 ++ if (c == '[') {
21527 ++ for (--p; n < endp; ++n)
21528 ++ if (!glob_match(p, n))
21529 ++ return 0;
21530 ++ } else if (c == '/') {
21531 ++ while (*n != '\0' && *n != '/')
21532 ++ ++n;
21533 ++ if (*n == '/' && !glob_match(p, n + 1))
21534 ++ return 0;
21535 ++ } else {
21536 ++ for (--p; n < endp; ++n)
21537 ++ if (*n == c && !glob_match(p, n))
21538 ++ return 0;
21539 ++ }
21540 ++
21541 ++ return 1;
21542 ++ }
21543 ++ case '[':
21544 ++ {
21545 ++ int not;
21546 ++ char cold;
21547 ++
21548 ++ if (*n == '\0' || *n == '/')
21549 ++ return 1;
21550 ++
21551 ++ not = (*p == '!' || *p == '^');
21552 ++ if (not)
21553 ++ ++p;
21554 ++
21555 ++ c = *p++;
21556 ++ for (;;) {
21557 ++ unsigned char fn = (unsigned char)*n;
21558 ++
21559 ++ if (c == '\0')
21560 ++ return 1;
21561 ++ else {
21562 ++ if (c == fn)
21563 ++ goto matched;
21564 ++ cold = c;
21565 ++ c = *p++;
21566 ++
21567 ++ if (c == '-' && *p != ']') {
21568 ++ unsigned char cend = *p++;
21569 ++
21570 ++ if (cend == '\0')
21571 ++ return 1;
21572 ++
21573 ++ if (cold <= fn && fn <= cend)
21574 ++ goto matched;
21575 ++
21576 ++ c = *p++;
21577 ++ }
21578 ++ }
21579 ++
21580 ++ if (c == ']')
21581 ++ break;
21582 ++ }
21583 ++ if (!not)
21584 ++ return 1;
21585 ++ break;
21586 ++ matched:
21587 ++ while (c != ']') {
21588 ++ if (c == '\0')
21589 ++ return 1;
21590 ++
21591 ++ c = *p++;
21592 ++ }
21593 ++ if (not)
21594 ++ return 1;
21595 ++ }
21596 ++ break;
21597 ++ default:
21598 ++ if (c != *n)
21599 ++ return 1;
21600 ++ }
21601 ++
21602 ++ ++n;
21603 ++ }
21604 ++
21605 ++ if (*n == '\0')
21606 ++ return 0;
21607 ++
21608 ++ if (*n == '/')
21609 ++ return 0;
21610 ++
21611 ++ return 1;
21612 ++}
21613 ++
21614 ++static struct acl_object_label *
21615 ++chk_glob_label(struct acl_object_label *globbed,
21616 ++ struct dentry *dentry, struct vfsmount *mnt, char **path)
21617 ++{
21618 ++ struct acl_object_label *tmp;
21619 ++
21620 ++ if (*path == NULL)
21621 ++ *path = gr_to_filename_nolock(dentry, mnt);
21622 ++
21623 ++ tmp = globbed;
21624 ++
21625 ++ while (tmp) {
21626 ++ if (!glob_match(tmp->filename, *path))
21627 ++ return tmp;
21628 ++ tmp = tmp->next;
21629 ++ }
21630 ++
21631 ++ return NULL;
21632 ++}
21633 ++
21634 ++static struct acl_object_label *
21635 ++__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
21636 ++ const ino_t curr_ino, const dev_t curr_dev,
21637 ++ const struct acl_subject_label *subj, char **path)
21638 ++{
21639 ++ struct acl_subject_label *tmpsubj;
21640 ++ struct acl_object_label *retval;
21641 ++ struct acl_object_label *retval2;
21642 ++
21643 ++ tmpsubj = (struct acl_subject_label *) subj;
21644 ++ read_lock(&gr_inode_lock);
21645 ++ do {
21646 ++ retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
21647 ++ if (retval) {
21648 ++ if (retval->globbed) {
21649 ++ retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
21650 ++ (struct vfsmount *)orig_mnt, path);
21651 ++ if (retval2)
21652 ++ retval = retval2;
21653 ++ }
21654 ++ break;
21655 ++ }
21656 ++ } while ((tmpsubj = tmpsubj->parent_subject));
21657 ++ read_unlock(&gr_inode_lock);
21658 ++
21659 ++ return retval;
21660 ++}
21661 ++
21662 ++static __inline__ struct acl_object_label *
21663 ++full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
21664 ++ const struct dentry *curr_dentry,
21665 ++ const struct acl_subject_label *subj, char **path)
21666 ++{
21667 ++ return __full_lookup(orig_dentry, orig_mnt,
21668 ++ curr_dentry->d_inode->i_ino,
21669 ++ curr_dentry->d_inode->i_sb->s_dev, subj, path);
21670 ++}
21671 ++
21672 ++static struct acl_object_label *
21673 ++__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
21674 ++ const struct acl_subject_label *subj, char *path)
21675 ++{
21676 ++ struct dentry *dentry = (struct dentry *) l_dentry;
21677 ++ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
21678 ++ struct acl_object_label *retval;
21679 ++
21680 ++ spin_lock(&dcache_lock);
21681 ++
21682 ++ if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt ||
21683 ++ /* ignore Eric Biederman */
21684 ++ IS_PRIVATE(l_dentry->d_inode))) {
21685 ++ retval = fakefs_obj;
21686 ++ goto out;
21687 ++ }
21688 ++
21689 ++ for (;;) {
21690 ++ if (dentry == real_root && mnt == real_root_mnt)
21691 ++ break;
21692 ++
21693 ++ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
21694 ++ if (mnt->mnt_parent == mnt)
21695 ++ break;
21696 ++
21697 ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
21698 ++ if (retval != NULL)
21699 ++ goto out;
21700 ++
21701 ++ dentry = mnt->mnt_mountpoint;
21702 ++ mnt = mnt->mnt_parent;
21703 ++ continue;
21704 ++ }
21705 ++
21706 ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
21707 ++ if (retval != NULL)
21708 ++ goto out;
21709 ++
21710 ++ dentry = dentry->d_parent;
21711 ++ }
21712 ++
21713 ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
21714 ++
21715 ++ if (retval == NULL)
21716 ++ retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
21717 ++out:
21718 ++ spin_unlock(&dcache_lock);
21719 ++ return retval;
21720 ++}
21721 ++
21722 ++static __inline__ struct acl_object_label *
21723 ++chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
21724 ++ const struct acl_subject_label *subj)
21725 ++{
21726 ++ char *path = NULL;
21727 ++ return __chk_obj_label(l_dentry, l_mnt, subj, path);
21728 ++}
21729 ++
21730 ++static __inline__ struct acl_object_label *
21731 ++chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
21732 ++ const struct acl_subject_label *subj, char *path)
21733 ++{
21734 ++ return __chk_obj_label(l_dentry, l_mnt, subj, path);
21735 ++}
21736 ++
21737 ++static struct acl_subject_label *
21738 ++chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
21739 ++ const struct acl_role_label *role)
21740 ++{
21741 ++ struct dentry *dentry = (struct dentry *) l_dentry;
21742 ++ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
21743 ++ struct acl_subject_label *retval;
21744 ++
21745 ++ spin_lock(&dcache_lock);
21746 ++
21747 ++ for (;;) {
21748 ++ if (dentry == real_root && mnt == real_root_mnt)
21749 ++ break;
21750 ++ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
21751 ++ if (mnt->mnt_parent == mnt)
21752 ++ break;
21753 ++
21754 ++ read_lock(&gr_inode_lock);
21755 ++ retval =
21756 ++ lookup_acl_subj_label(dentry->d_inode->i_ino,
21757 ++ dentry->d_inode->i_sb->s_dev, role);
21758 ++ read_unlock(&gr_inode_lock);
21759 ++ if (retval != NULL)
21760 ++ goto out;
21761 ++
21762 ++ dentry = mnt->mnt_mountpoint;
21763 ++ mnt = mnt->mnt_parent;
21764 ++ continue;
21765 ++ }
21766 ++
21767 ++ read_lock(&gr_inode_lock);
21768 ++ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
21769 ++ dentry->d_inode->i_sb->s_dev, role);
21770 ++ read_unlock(&gr_inode_lock);
21771 ++ if (retval != NULL)
21772 ++ goto out;
21773 ++
21774 ++ dentry = dentry->d_parent;
21775 ++ }
21776 ++
21777 ++ read_lock(&gr_inode_lock);
21778 ++ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
21779 ++ dentry->d_inode->i_sb->s_dev, role);
21780 ++ read_unlock(&gr_inode_lock);
21781 ++
21782 ++ if (unlikely(retval == NULL)) {
21783 ++ read_lock(&gr_inode_lock);
21784 ++ retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
21785 ++ real_root->d_inode->i_sb->s_dev, role);
21786 ++ read_unlock(&gr_inode_lock);
21787 ++ }
21788 ++out:
21789 ++ spin_unlock(&dcache_lock);
21790 ++
21791 ++ return retval;
21792 ++}
21793 ++
21794 ++static void
21795 ++gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
21796 ++{
21797 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
21798 ++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
21799 ++ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
21800 ++ 1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
21801 ++
21802 ++ return;
21803 ++}
21804 ++
21805 ++static void
21806 ++gr_log_learn_sysctl(const struct task_struct *task, const char *path, const __u32 mode)
21807 ++{
21808 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
21809 ++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
21810 ++ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
21811 ++ 1, 1, path, (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
21812 ++
21813 ++ return;
21814 ++}
21815 ++
21816 ++static void
21817 ++gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real,
21818 ++ const unsigned int effective, const unsigned int fs)
21819 ++{
21820 ++ security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
21821 ++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
21822 ++ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
21823 ++ type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
21824 ++
21825 ++ return;
21826 ++}
21827 ++
21828 ++__u32
21829 ++gr_check_link(const struct dentry * new_dentry,
21830 ++ const struct dentry * parent_dentry,
21831 ++ const struct vfsmount * parent_mnt,
21832 ++ const struct dentry * old_dentry, const struct vfsmount * old_mnt)
21833 ++{
21834 ++ struct acl_object_label *obj;
21835 ++ __u32 oldmode, newmode;
21836 ++ __u32 needmode;
21837 ++
21838 ++ if (unlikely(!(gr_status & GR_READY)))
21839 ++ return (GR_CREATE | GR_LINK);
21840 ++
21841 ++ obj = chk_obj_label(old_dentry, old_mnt, current->acl);
21842 ++ oldmode = obj->mode;
21843 ++
21844 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
21845 ++ oldmode |= (GR_CREATE | GR_LINK);
21846 ++
21847 ++ needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
21848 ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
21849 ++ needmode |= GR_SETID | GR_AUDIT_SETID;
21850 ++
21851 ++ newmode =
21852 ++ gr_check_create(new_dentry, parent_dentry, parent_mnt,
21853 ++ oldmode | needmode);
21854 ++
21855 ++ needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
21856 ++ GR_SETID | GR_READ | GR_FIND | GR_DELETE |
21857 ++ GR_INHERIT | GR_AUDIT_INHERIT);
21858 ++
21859 ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
21860 ++ goto bad;
21861 ++
21862 ++ if ((oldmode & needmode) != needmode)
21863 ++ goto bad;
21864 ++
21865 ++ needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
21866 ++ if ((newmode & needmode) != needmode)
21867 ++ goto bad;
21868 ++
21869 ++ if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
21870 ++ return newmode;
21871 ++bad:
21872 ++ needmode = oldmode;
21873 ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
21874 ++ needmode |= GR_SETID;
21875 ++
21876 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
21877 ++ gr_log_learn(current, old_dentry, old_mnt, needmode);
21878 ++ return (GR_CREATE | GR_LINK);
21879 ++ } else if (newmode & GR_SUPPRESS)
21880 ++ return GR_SUPPRESS;
21881 ++ else
21882 ++ return 0;
21883 ++}
21884 ++
21885 ++__u32
21886 ++gr_search_file(const struct dentry * dentry, const __u32 mode,
21887 ++ const struct vfsmount * mnt)
21888 ++{
21889 ++ __u32 retval = mode;
21890 ++ struct acl_subject_label *curracl;
21891 ++ struct acl_object_label *currobj;
21892 ++
21893 ++ if (unlikely(!(gr_status & GR_READY)))
21894 ++ return (mode & ~GR_AUDITS);
21895 ++
21896 ++ curracl = current->acl;
21897 ++
21898 ++ currobj = chk_obj_label(dentry, mnt, curracl);
21899 ++ retval = currobj->mode & mode;
21900 ++
21901 ++ if (unlikely
21902 ++ ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
21903 ++ && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
21904 ++ __u32 new_mode = mode;
21905 ++
21906 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
21907 ++
21908 ++ retval = new_mode;
21909 ++
21910 ++ if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
21911 ++ new_mode |= GR_INHERIT;
21912 ++
21913 ++ if (!(mode & GR_NOLEARN))
21914 ++ gr_log_learn(current, dentry, mnt, new_mode);
21915 ++ }
21916 ++
21917 ++ return retval;
21918 ++}
21919 ++
21920 ++__u32
21921 ++gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
21922 ++ const struct vfsmount * mnt, const __u32 mode)
21923 ++{
21924 ++ struct name_entry *match;
21925 ++ struct acl_object_label *matchpo;
21926 ++ struct acl_subject_label *curracl;
21927 ++ char *path;
21928 ++ __u32 retval;
21929 ++
21930 ++ if (unlikely(!(gr_status & GR_READY)))
21931 ++ return (mode & ~GR_AUDITS);
21932 ++
21933 ++ preempt_disable();
21934 ++ path = gr_to_filename_rbac(new_dentry, mnt);
21935 ++ match = lookup_name_entry_create(path);
21936 ++
21937 ++ if (!match)
21938 ++ goto check_parent;
21939 ++
21940 ++ curracl = current->acl;
21941 ++
21942 ++ read_lock(&gr_inode_lock);
21943 ++ matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
21944 ++ read_unlock(&gr_inode_lock);
21945 ++
21946 ++ if (matchpo) {
21947 ++ if ((matchpo->mode & mode) !=
21948 ++ (mode & ~(GR_AUDITS | GR_SUPPRESS))
21949 ++ && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
21950 ++ __u32 new_mode = mode;
21951 ++
21952 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
21953 ++
21954 ++ gr_log_learn(current, new_dentry, mnt, new_mode);
21955 ++
21956 ++ preempt_enable();
21957 ++ return new_mode;
21958 ++ }
21959 ++ preempt_enable();
21960 ++ return (matchpo->mode & mode);
21961 ++ }
21962 ++
21963 ++ check_parent:
21964 ++ curracl = current->acl;
21965 ++
21966 ++ matchpo = chk_obj_create_label(parent, mnt, curracl, path);
21967 ++ retval = matchpo->mode & mode;
21968 ++
21969 ++ if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
21970 ++ && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
21971 ++ __u32 new_mode = mode;
21972 ++
21973 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
21974 ++
21975 ++ gr_log_learn(current, new_dentry, mnt, new_mode);
21976 ++ preempt_enable();
21977 ++ return new_mode;
21978 ++ }
21979 ++
21980 ++ preempt_enable();
21981 ++ return retval;
21982 ++}
21983 ++
21984 ++int
21985 ++gr_check_hidden_task(const struct task_struct *task)
21986 ++{
21987 ++ if (unlikely(!(gr_status & GR_READY)))
21988 ++ return 0;
21989 ++
21990 ++ if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
21991 ++ return 1;
21992 ++
21993 ++ return 0;
21994 ++}
21995 ++
21996 ++int
21997 ++gr_check_protected_task(const struct task_struct *task)
21998 ++{
21999 ++ if (unlikely(!(gr_status & GR_READY) || !task))
22000 ++ return 0;
22001 ++
22002 ++ if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
22003 ++ task->acl != current->acl)
22004 ++ return 1;
22005 ++
22006 ++ return 0;
22007 ++}
22008 ++
22009 ++void
22010 ++gr_copy_label(struct task_struct *tsk)
22011 ++{
22012 ++ tsk->signal->used_accept = 0;
22013 ++ tsk->acl_sp_role = 0;
22014 ++ tsk->acl_role_id = current->acl_role_id;
22015 ++ tsk->acl = current->acl;
22016 ++ tsk->role = current->role;
22017 ++ tsk->signal->curr_ip = current->signal->curr_ip;
22018 ++ if (current->exec_file)
22019 ++ get_file(current->exec_file);
22020 ++ tsk->exec_file = current->exec_file;
22021 ++ tsk->is_writable = current->is_writable;
22022 ++ if (unlikely(current->signal->used_accept))
22023 ++ current->signal->curr_ip = 0;
22024 ++
22025 ++ return;
22026 ++}
22027 ++
22028 ++static void
22029 ++gr_set_proc_res(struct task_struct *task)
22030 ++{
22031 ++ struct acl_subject_label *proc;
22032 ++ unsigned short i;
22033 ++
22034 ++ proc = task->acl;
22035 ++
22036 ++ if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
22037 ++ return;
22038 ++
22039 ++ for (i = 0; i < (GR_NLIMITS - 1); i++) {
22040 ++ if (!(proc->resmask & (1 << i)))
22041 ++ continue;
22042 ++
22043 ++ task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
22044 ++ task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
22045 ++ }
22046 ++
22047 ++ return;
22048 ++}
22049 ++
22050 ++int
22051 ++gr_check_user_change(int real, int effective, int fs)
22052 ++{
22053 ++ unsigned int i;
22054 ++ __u16 num;
22055 ++ uid_t *uidlist;
22056 ++ int curuid;
22057 ++ int realok = 0;
22058 ++ int effectiveok = 0;
22059 ++ int fsok = 0;
22060 ++
22061 ++ if (unlikely(!(gr_status & GR_READY)))
22062 ++ return 0;
22063 ++
22064 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
22065 ++ gr_log_learn_id_change(current, 'u', real, effective, fs);
22066 ++
22067 ++ num = current->acl->user_trans_num;
22068 ++ uidlist = current->acl->user_transitions;
22069 ++
22070 ++ if (uidlist == NULL)
22071 ++ return 0;
22072 ++
22073 ++ if (real == -1)
22074 ++ realok = 1;
22075 ++ if (effective == -1)
22076 ++ effectiveok = 1;
22077 ++ if (fs == -1)
22078 ++ fsok = 1;
22079 ++
22080 ++ if (current->acl->user_trans_type & GR_ID_ALLOW) {
22081 ++ for (i = 0; i < num; i++) {
22082 ++ curuid = (int)uidlist[i];
22083 ++ if (real == curuid)
22084 ++ realok = 1;
22085 ++ if (effective == curuid)
22086 ++ effectiveok = 1;
22087 ++ if (fs == curuid)
22088 ++ fsok = 1;
22089 ++ }
22090 ++ } else if (current->acl->user_trans_type & GR_ID_DENY) {
22091 ++ for (i = 0; i < num; i++) {
22092 ++ curuid = (int)uidlist[i];
22093 ++ if (real == curuid)
22094 ++ break;
22095 ++ if (effective == curuid)
22096 ++ break;
22097 ++ if (fs == curuid)
22098 ++ break;
22099 ++ }
22100 ++ /* not in deny list */
22101 ++ if (i == num) {
22102 ++ realok = 1;
22103 ++ effectiveok = 1;
22104 ++ fsok = 1;
22105 ++ }
22106 ++ }
22107 ++
22108 ++ if (realok && effectiveok && fsok)
22109 ++ return 0;
22110 ++ else {
22111 ++ gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
22112 ++ return 1;
22113 ++ }
22114 ++}
22115 ++
22116 ++int
22117 ++gr_check_group_change(int real, int effective, int fs)
22118 ++{
22119 ++ unsigned int i;
22120 ++ __u16 num;
22121 ++ gid_t *gidlist;
22122 ++ int curgid;
22123 ++ int realok = 0;
22124 ++ int effectiveok = 0;
22125 ++ int fsok = 0;
22126 ++
22127 ++ if (unlikely(!(gr_status & GR_READY)))
22128 ++ return 0;
22129 ++
22130 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
22131 ++ gr_log_learn_id_change(current, 'g', real, effective, fs);
22132 ++
22133 ++ num = current->acl->group_trans_num;
22134 ++ gidlist = current->acl->group_transitions;
22135 ++
22136 ++ if (gidlist == NULL)
22137 ++ return 0;
22138 ++
22139 ++ if (real == -1)
22140 ++ realok = 1;
22141 ++ if (effective == -1)
22142 ++ effectiveok = 1;
22143 ++ if (fs == -1)
22144 ++ fsok = 1;
22145 ++
22146 ++ if (current->acl->group_trans_type & GR_ID_ALLOW) {
22147 ++ for (i = 0; i < num; i++) {
22148 ++ curgid = (int)gidlist[i];
22149 ++ if (real == curgid)
22150 ++ realok = 1;
22151 ++ if (effective == curgid)
22152 ++ effectiveok = 1;
22153 ++ if (fs == curgid)
22154 ++ fsok = 1;
22155 ++ }
22156 ++ } else if (current->acl->group_trans_type & GR_ID_DENY) {
22157 ++ for (i = 0; i < num; i++) {
22158 ++ curgid = (int)gidlist[i];
22159 ++ if (real == curgid)
22160 ++ break;
22161 ++ if (effective == curgid)
22162 ++ break;
22163 ++ if (fs == curgid)
22164 ++ break;
22165 ++ }
22166 ++ /* not in deny list */
22167 ++ if (i == num) {
22168 ++ realok = 1;
22169 ++ effectiveok = 1;
22170 ++ fsok = 1;
22171 ++ }
22172 ++ }
22173 ++
22174 ++ if (realok && effectiveok && fsok)
22175 ++ return 0;
22176 ++ else {
22177 ++ gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
22178 ++ return 1;
22179 ++ }
22180 ++}
22181 ++
22182 ++void
22183 ++gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
22184 ++{
22185 ++ struct acl_role_label *role = task->role;
22186 ++ struct acl_subject_label *subj = NULL;
22187 ++ struct acl_object_label *obj;
22188 ++ struct file *filp;
22189 ++
22190 ++ if (unlikely(!(gr_status & GR_READY)))
22191 ++ return;
22192 ++
22193 ++ filp = task->exec_file;
22194 ++
22195 ++ /* kernel process, we'll give them the kernel role */
22196 ++ if (unlikely(!filp)) {
22197 ++ task->role = kernel_role;
22198 ++ task->acl = kernel_role->root_label;
22199 ++ return;
22200 ++ } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
22201 ++ role = lookup_acl_role_label(task, uid, gid);
22202 ++
22203 ++ /* perform subject lookup in possibly new role
22204 ++ we can use this result below in the case where role == task->role
22205 ++ */
22206 ++ subj = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, role);
22207 ++
22208 ++ /* if we changed uid/gid, but result in the same role
22209 ++ and are using inheritance, don't lose the inherited subject
22210 ++ if current subject is other than what normal lookup
22211 ++ would result in, we arrived via inheritance, don't
22212 ++ lose subject
22213 ++ */
22214 ++ if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
22215 ++ (subj == task->acl)))
22216 ++ task->acl = subj;
22217 ++
22218 ++ task->role = role;
22219 ++
22220 ++ task->is_writable = 0;
22221 ++
22222 ++ /* ignore additional mmap checks for processes that are writable
22223 ++ by the default ACL */
22224 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
22225 ++ if (unlikely(obj->mode & GR_WRITE))
22226 ++ task->is_writable = 1;
22227 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
22228 ++ if (unlikely(obj->mode & GR_WRITE))
22229 ++ task->is_writable = 1;
22230 ++
22231 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
22232 ++ printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
22233 ++#endif
22234 ++
22235 ++ gr_set_proc_res(task);
22236 ++
22237 ++ return;
22238 ++}
22239 ++
22240 ++int
22241 ++gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
22242 ++{
22243 ++ struct task_struct *task = current;
22244 ++ struct acl_subject_label *newacl;
22245 ++ struct acl_object_label *obj;
22246 ++ __u32 retmode;
22247 ++
22248 ++ if (unlikely(!(gr_status & GR_READY)))
22249 ++ return 0;
22250 ++
22251 ++ newacl = chk_subj_label(dentry, mnt, task->role);
22252 ++
22253 ++ task_lock(task);
22254 ++ if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
22255 ++ GR_POVERRIDE) && (task->acl != newacl) &&
22256 ++ !(task->role->roletype & GR_ROLE_GOD) &&
22257 ++ !gr_search_file(dentry, GR_PTRACERD, mnt) &&
22258 ++ !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
22259 ++ (atomic_read(&task->fs->count) > 1 ||
22260 ++ atomic_read(&task->files->count) > 1 ||
22261 ++ atomic_read(&task->sighand->count) > 1)) {
22262 ++ task_unlock(task);
22263 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
22264 ++ return -EACCES;
22265 ++ }
22266 ++ task_unlock(task);
22267 ++
22268 ++ obj = chk_obj_label(dentry, mnt, task->acl);
22269 ++ retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
22270 ++
22271 ++ if (!(task->acl->mode & GR_INHERITLEARN) &&
22272 ++ ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
22273 ++ if (obj->nested)
22274 ++ task->acl = obj->nested;
22275 ++ else
22276 ++ task->acl = newacl;
22277 ++ } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
22278 ++ gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
22279 ++
22280 ++ task->is_writable = 0;
22281 ++
22282 ++ /* ignore additional mmap checks for processes that are writable
22283 ++ by the default ACL */
22284 ++ obj = chk_obj_label(dentry, mnt, default_role->root_label);
22285 ++ if (unlikely(obj->mode & GR_WRITE))
22286 ++ task->is_writable = 1;
22287 ++ obj = chk_obj_label(dentry, mnt, task->role->root_label);
22288 ++ if (unlikely(obj->mode & GR_WRITE))
22289 ++ task->is_writable = 1;
22290 ++
22291 ++ gr_set_proc_res(task);
22292 ++
22293 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
22294 ++ printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
22295 ++#endif
22296 ++ return 0;
22297 ++}
22298 ++
22299 ++/* always called with valid inodev ptr */
22300 ++static void
22301 ++do_handle_delete(struct inodev_entry *inodev, const ino_t ino, const dev_t dev)
22302 ++{
22303 ++ struct acl_object_label *matchpo;
22304 ++ struct acl_subject_label *matchps;
22305 ++ struct acl_subject_label *subj;
22306 ++ struct acl_role_label *role;
22307 ++ unsigned int i, x;
22308 ++
22309 ++ FOR_EACH_ROLE_START(role, i)
22310 ++ FOR_EACH_SUBJECT_START(role, subj, x)
22311 ++ if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
22312 ++ matchpo->mode |= GR_DELETED;
22313 ++ FOR_EACH_SUBJECT_END(subj,x)
22314 ++ FOR_EACH_NESTED_SUBJECT_START(role, subj)
22315 ++ if (subj->inode == ino && subj->device == dev)
22316 ++ subj->mode |= GR_DELETED;
22317 ++ FOR_EACH_NESTED_SUBJECT_END(subj)
22318 ++ if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
22319 ++ matchps->mode |= GR_DELETED;
22320 ++ FOR_EACH_ROLE_END(role,i)
22321 ++
22322 ++ inodev->nentry->deleted = 1;
22323 ++
22324 ++ return;
22325 ++}
22326 ++
22327 ++void
22328 ++gr_handle_delete(const ino_t ino, const dev_t dev)
22329 ++{
22330 ++ struct inodev_entry *inodev;
22331 ++
22332 ++ if (unlikely(!(gr_status & GR_READY)))
22333 ++ return;
22334 ++
22335 ++ write_lock(&gr_inode_lock);
22336 ++ inodev = lookup_inodev_entry(ino, dev);
22337 ++ if (inodev != NULL)
22338 ++ do_handle_delete(inodev, ino, dev);
22339 ++ write_unlock(&gr_inode_lock);
22340 ++
22341 ++ return;
22342 ++}
22343 ++
22344 ++static void
22345 ++update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
22346 ++ const ino_t newinode, const dev_t newdevice,
22347 ++ struct acl_subject_label *subj)
22348 ++{
22349 ++ unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
22350 ++ struct acl_object_label *match;
22351 ++
22352 ++ match = subj->obj_hash[index];
22353 ++
22354 ++ while (match && (match->inode != oldinode ||
22355 ++ match->device != olddevice ||
22356 ++ !(match->mode & GR_DELETED)))
22357 ++ match = match->next;
22358 ++
22359 ++ if (match && (match->inode == oldinode)
22360 ++ && (match->device == olddevice)
22361 ++ && (match->mode & GR_DELETED)) {
22362 ++ if (match->prev == NULL) {
22363 ++ subj->obj_hash[index] = match->next;
22364 ++ if (match->next != NULL)
22365 ++ match->next->prev = NULL;
22366 ++ } else {
22367 ++ match->prev->next = match->next;
22368 ++ if (match->next != NULL)
22369 ++ match->next->prev = match->prev;
22370 ++ }
22371 ++ match->prev = NULL;
22372 ++ match->next = NULL;
22373 ++ match->inode = newinode;
22374 ++ match->device = newdevice;
22375 ++ match->mode &= ~GR_DELETED;
22376 ++
22377 ++ insert_acl_obj_label(match, subj);
22378 ++ }
22379 ++
22380 ++ return;
22381 ++}
22382 ++
22383 ++static void
22384 ++update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
22385 ++ const ino_t newinode, const dev_t newdevice,
22386 ++ struct acl_role_label *role)
22387 ++{
22388 ++ unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
22389 ++ struct acl_subject_label *match;
22390 ++
22391 ++ match = role->subj_hash[index];
22392 ++
22393 ++ while (match && (match->inode != oldinode ||
22394 ++ match->device != olddevice ||
22395 ++ !(match->mode & GR_DELETED)))
22396 ++ match = match->next;
22397 ++
22398 ++ if (match && (match->inode == oldinode)
22399 ++ && (match->device == olddevice)
22400 ++ && (match->mode & GR_DELETED)) {
22401 ++ if (match->prev == NULL) {
22402 ++ role->subj_hash[index] = match->next;
22403 ++ if (match->next != NULL)
22404 ++ match->next->prev = NULL;
22405 ++ } else {
22406 ++ match->prev->next = match->next;
22407 ++ if (match->next != NULL)
22408 ++ match->next->prev = match->prev;
22409 ++ }
22410 ++ match->prev = NULL;
22411 ++ match->next = NULL;
22412 ++ match->inode = newinode;
22413 ++ match->device = newdevice;
22414 ++ match->mode &= ~GR_DELETED;
22415 ++
22416 ++ insert_acl_subj_label(match, role);
22417 ++ }
22418 ++
22419 ++ return;
22420 ++}
22421 ++
22422 ++static void
22423 ++update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
22424 ++ const ino_t newinode, const dev_t newdevice)
22425 ++{
22426 ++ unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
22427 ++ struct inodev_entry *match;
22428 ++
22429 ++ match = inodev_set.i_hash[index];
22430 ++
22431 ++ while (match && (match->nentry->inode != oldinode ||
22432 ++ match->nentry->device != olddevice || !match->nentry->deleted))
22433 ++ match = match->next;
22434 ++
22435 ++ if (match && (match->nentry->inode == oldinode)
22436 ++ && (match->nentry->device == olddevice) &&
22437 ++ match->nentry->deleted) {
22438 ++ if (match->prev == NULL) {
22439 ++ inodev_set.i_hash[index] = match->next;
22440 ++ if (match->next != NULL)
22441 ++ match->next->prev = NULL;
22442 ++ } else {
22443 ++ match->prev->next = match->next;
22444 ++ if (match->next != NULL)
22445 ++ match->next->prev = match->prev;
22446 ++ }
22447 ++ match->prev = NULL;
22448 ++ match->next = NULL;
22449 ++ match->nentry->inode = newinode;
22450 ++ match->nentry->device = newdevice;
22451 ++ match->nentry->deleted = 0;
22452 ++
22453 ++ insert_inodev_entry(match);
22454 ++ }
22455 ++
22456 ++ return;
22457 ++}
22458 ++
22459 ++static void
22460 ++do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
22461 ++ const struct vfsmount *mnt)
22462 ++{
22463 ++ struct acl_subject_label *subj;
22464 ++ struct acl_role_label *role;
22465 ++ unsigned int i, x;
22466 ++
22467 ++ FOR_EACH_ROLE_START(role, i)
22468 ++ update_acl_subj_label(matchn->inode, matchn->device,
22469 ++ dentry->d_inode->i_ino,
22470 ++ dentry->d_inode->i_sb->s_dev, role);
22471 ++
22472 ++ FOR_EACH_NESTED_SUBJECT_START(role, subj)
22473 ++ if ((subj->inode == dentry->d_inode->i_ino) &&
22474 ++ (subj->device == dentry->d_inode->i_sb->s_dev)) {
22475 ++ subj->inode = dentry->d_inode->i_ino;
22476 ++ subj->device = dentry->d_inode->i_sb->s_dev;
22477 ++ }
22478 ++ FOR_EACH_NESTED_SUBJECT_END(subj)
22479 ++ FOR_EACH_SUBJECT_START(role, subj, x)
22480 ++ update_acl_obj_label(matchn->inode, matchn->device,
22481 ++ dentry->d_inode->i_ino,
22482 ++ dentry->d_inode->i_sb->s_dev, subj);
22483 ++ FOR_EACH_SUBJECT_END(subj,x)
22484 ++ FOR_EACH_ROLE_END(role,i)
22485 ++
22486 ++ update_inodev_entry(matchn->inode, matchn->device,
22487 ++ dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
22488 ++
22489 ++ return;
22490 ++}
22491 ++
22492 ++void
22493 ++gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
22494 ++{
22495 ++ struct name_entry *matchn;
22496 ++
22497 ++ if (unlikely(!(gr_status & GR_READY)))
22498 ++ return;
22499 ++
22500 ++ preempt_disable();
22501 ++ matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
22502 ++
22503 ++ if (unlikely((unsigned long)matchn)) {
22504 ++ write_lock(&gr_inode_lock);
22505 ++ do_handle_create(matchn, dentry, mnt);
22506 ++ write_unlock(&gr_inode_lock);
22507 ++ }
22508 ++ preempt_enable();
22509 ++
22510 ++ return;
22511 ++}
22512 ++
22513 ++void
22514 ++gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
22515 ++ struct dentry *old_dentry,
22516 ++ struct dentry *new_dentry,
22517 ++ struct vfsmount *mnt, const __u8 replace)
22518 ++{
22519 ++ struct name_entry *matchn;
22520 ++ struct inodev_entry *inodev;
22521 ++
22522 ++ /* vfs_rename swaps the name and parent link for old_dentry and
22523 ++ new_dentry
22524 ++ at this point, old_dentry has the new name, parent link, and inode
22525 ++ for the renamed file
22526 ++ if a file is being replaced by a rename, new_dentry has the inode
22527 ++ and name for the replaced file
22528 ++ */
22529 ++
22530 ++ if (unlikely(!(gr_status & GR_READY)))
22531 ++ return;
22532 ++
22533 ++ preempt_disable();
22534 ++ matchn = lookup_name_entry(gr_to_filename_rbac(old_dentry, mnt));
22535 ++
22536 ++ /* we wouldn't have to check d_inode if it weren't for
22537 ++ NFS silly-renaming
22538 ++ */
22539 ++
22540 ++ write_lock(&gr_inode_lock);
22541 ++ if (unlikely(replace && new_dentry->d_inode)) {
22542 ++ inodev = lookup_inodev_entry(new_dentry->d_inode->i_ino,
22543 ++ new_dentry->d_inode->i_sb->s_dev);
22544 ++ if (inodev != NULL && (new_dentry->d_inode->i_nlink <= 1))
22545 ++ do_handle_delete(inodev, new_dentry->d_inode->i_ino,
22546 ++ new_dentry->d_inode->i_sb->s_dev);
22547 ++ }
22548 ++
22549 ++ inodev = lookup_inodev_entry(old_dentry->d_inode->i_ino,
22550 ++ old_dentry->d_inode->i_sb->s_dev);
22551 ++ if (inodev != NULL && (old_dentry->d_inode->i_nlink <= 1))
22552 ++ do_handle_delete(inodev, old_dentry->d_inode->i_ino,
22553 ++ old_dentry->d_inode->i_sb->s_dev);
22554 ++
22555 ++ if (unlikely((unsigned long)matchn))
22556 ++ do_handle_create(matchn, old_dentry, mnt);
22557 ++
22558 ++ write_unlock(&gr_inode_lock);
22559 ++ preempt_enable();
22560 ++
22561 ++ return;
22562 ++}
22563 ++
22564 ++static int
22565 ++lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
22566 ++ unsigned char **sum)
22567 ++{
22568 ++ struct acl_role_label *r;
22569 ++ struct role_allowed_ip *ipp;
22570 ++ struct role_transition *trans;
22571 ++ unsigned int i;
22572 ++ int found = 0;
22573 ++
22574 ++ /* check transition table */
22575 ++
22576 ++ for (trans = current->role->transitions; trans; trans = trans->next) {
22577 ++ if (!strcmp(rolename, trans->rolename)) {
22578 ++ found = 1;
22579 ++ break;
22580 ++ }
22581 ++ }
22582 ++
22583 ++ if (!found)
22584 ++ return 0;
22585 ++
22586 ++ /* handle special roles that do not require authentication
22587 ++ and check ip */
22588 ++
22589 ++ FOR_EACH_ROLE_START(r, i)
22590 ++ if (!strcmp(rolename, r->rolename) &&
22591 ++ (r->roletype & GR_ROLE_SPECIAL)) {
22592 ++ found = 0;
22593 ++ if (r->allowed_ips != NULL) {
22594 ++ for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
22595 ++ if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
22596 ++ (ntohl(ipp->addr) & ipp->netmask))
22597 ++ found = 1;
22598 ++ }
22599 ++ } else
22600 ++ found = 2;
22601 ++ if (!found)
22602 ++ return 0;
22603 ++
22604 ++ if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
22605 ++ ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
22606 ++ *salt = NULL;
22607 ++ *sum = NULL;
22608 ++ return 1;
22609 ++ }
22610 ++ }
22611 ++ FOR_EACH_ROLE_END(r,i)
22612 ++
22613 ++ for (i = 0; i < num_sprole_pws; i++) {
22614 ++ if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
22615 ++ *salt = acl_special_roles[i]->salt;
22616 ++ *sum = acl_special_roles[i]->sum;
22617 ++ return 1;
22618 ++ }
22619 ++ }
22620 ++
22621 ++ return 0;
22622 ++}
22623 ++
22624 ++static void
22625 ++assign_special_role(char *rolename)
22626 ++{
22627 ++ struct acl_object_label *obj;
22628 ++ struct acl_role_label *r;
22629 ++ struct acl_role_label *assigned = NULL;
22630 ++ struct task_struct *tsk;
22631 ++ struct file *filp;
22632 ++ unsigned int i;
22633 ++
22634 ++ FOR_EACH_ROLE_START(r, i)
22635 ++ if (!strcmp(rolename, r->rolename) &&
22636 ++ (r->roletype & GR_ROLE_SPECIAL))
22637 ++ assigned = r;
22638 ++ FOR_EACH_ROLE_END(r,i)
22639 ++
22640 ++ if (!assigned)
22641 ++ return;
22642 ++
22643 ++ read_lock(&tasklist_lock);
22644 ++ read_lock(&grsec_exec_file_lock);
22645 ++
22646 ++ tsk = current->parent;
22647 ++ if (tsk == NULL)
22648 ++ goto out_unlock;
22649 ++
22650 ++ filp = tsk->exec_file;
22651 ++ if (filp == NULL)
22652 ++ goto out_unlock;
22653 ++
22654 ++ tsk->is_writable = 0;
22655 ++
22656 ++ tsk->acl_sp_role = 1;
22657 ++ tsk->acl_role_id = ++acl_sp_role_value;
22658 ++ tsk->role = assigned;
22659 ++ tsk->acl = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role);
22660 ++
22661 ++ /* ignore additional mmap checks for processes that are writable
22662 ++ by the default ACL */
22663 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
22664 ++ if (unlikely(obj->mode & GR_WRITE))
22665 ++ tsk->is_writable = 1;
22666 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role->root_label);
22667 ++ if (unlikely(obj->mode & GR_WRITE))
22668 ++ tsk->is_writable = 1;
22669 ++
22670 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
22671 ++ printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
22672 ++#endif
22673 ++
22674 ++out_unlock:
22675 ++ read_unlock(&grsec_exec_file_lock);
22676 ++ read_unlock(&tasklist_lock);
22677 ++ return;
22678 ++}
22679 ++
22680 ++int gr_check_secure_terminal(struct task_struct *task)
22681 ++{
22682 ++ struct task_struct *p, *p2, *p3;
22683 ++ struct files_struct *files;
22684 ++ struct fdtable *fdt;
22685 ++ struct file *our_file = NULL, *file;
22686 ++ int i;
22687 ++
22688 ++ if (task->signal->tty == NULL)
22689 ++ return 1;
22690 ++
22691 ++ files = get_files_struct(task);
22692 ++ if (files != NULL) {
22693 ++ rcu_read_lock();
22694 ++ fdt = files_fdtable(files);
22695 ++ for (i=0; i < fdt->max_fds; i++) {
22696 ++ file = fcheck_files(files, i);
22697 ++ if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
22698 ++ get_file(file);
22699 ++ our_file = file;
22700 ++ }
22701 ++ }
22702 ++ rcu_read_unlock();
22703 ++ put_files_struct(files);
22704 ++ }
22705 ++
22706 ++ if (our_file == NULL)
22707 ++ return 1;
22708 ++
22709 ++ read_lock(&tasklist_lock);
22710 ++ do_each_thread(p2, p) {
22711 ++ files = get_files_struct(p);
22712 ++ if (files == NULL ||
22713 ++ (p->signal && p->signal->tty == task->signal->tty)) {
22714 ++ if (files != NULL)
22715 ++ put_files_struct(files);
22716 ++ continue;
22717 ++ }
22718 ++ rcu_read_lock();
22719 ++ fdt = files_fdtable(files);
22720 ++ for (i=0; i < fdt->max_fds; i++) {
22721 ++ file = fcheck_files(files, i);
22722 ++ if (file && S_ISCHR(file->f_path.dentry->d_inode->i_mode) &&
22723 ++ file->f_path.dentry->d_inode->i_rdev == our_file->f_path.dentry->d_inode->i_rdev) {
22724 ++ p3 = task;
22725 ++ while (p3->pid > 0) {
22726 ++ if (p3 == p)
22727 ++ break;
22728 ++ p3 = p3->parent;
22729 ++ }
22730 ++ if (p3 == p)
22731 ++ break;
22732 ++ gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
22733 ++ gr_handle_alertkill(p);
22734 ++ rcu_read_unlock();
22735 ++ put_files_struct(files);
22736 ++ read_unlock(&tasklist_lock);
22737 ++ fput(our_file);
22738 ++ return 0;
22739 ++ }
22740 ++ }
22741 ++ rcu_read_unlock();
22742 ++ put_files_struct(files);
22743 ++ } while_each_thread(p2, p);
22744 ++ read_unlock(&tasklist_lock);
22745 ++
22746 ++ fput(our_file);
22747 ++ return 1;
22748 ++}
22749 ++
22750 ++ssize_t
22751 ++write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
22752 ++{
22753 ++ struct gr_arg_wrapper uwrap;
22754 ++ unsigned char *sprole_salt;
22755 ++ unsigned char *sprole_sum;
22756 ++ int error = sizeof (struct gr_arg_wrapper);
22757 ++ int error2 = 0;
22758 ++
22759 ++ down(&gr_dev_sem);
22760 ++
22761 ++ if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
22762 ++ error = -EPERM;
22763 ++ goto out;
22764 ++ }
22765 ++
22766 ++ if (count != sizeof (struct gr_arg_wrapper)) {
22767 ++ gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
22768 ++ error = -EINVAL;
22769 ++ goto out;
22770 ++ }
22771 ++
22772 ++
22773 ++ if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
22774 ++ gr_auth_expires = 0;
22775 ++ gr_auth_attempts = 0;
22776 ++ }
22777 ++
22778 ++ if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
22779 ++ error = -EFAULT;
22780 ++ goto out;
22781 ++ }
22782 ++
22783 ++ if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
22784 ++ error = -EINVAL;
22785 ++ goto out;
22786 ++ }
22787 ++
22788 ++ if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
22789 ++ error = -EFAULT;
22790 ++ goto out;
22791 ++ }
22792 ++
22793 ++ if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM &&
22794 ++ gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
22795 ++ time_after(gr_auth_expires, get_seconds())) {
22796 ++ error = -EBUSY;
22797 ++ goto out;
22798 ++ }
22799 ++
22800 ++ /* if non-root trying to do anything other than use a special role,
22801 ++ do not attempt authentication, do not count towards authentication
22802 ++ locking
22803 ++ */
22804 ++
22805 ++ if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS &&
22806 ++ gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM &&
22807 ++ current->uid) {
22808 ++ error = -EPERM;
22809 ++ goto out;
22810 ++ }
22811 ++
22812 ++ /* ensure pw and special role name are null terminated */
22813 ++
22814 ++ gr_usermode->pw[GR_PW_LEN - 1] = '\0';
22815 ++ gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
22816 ++
22817 ++ /* Okay.
22818 ++ * We have our enough of the argument structure..(we have yet
22819 ++ * to copy_from_user the tables themselves) . Copy the tables
22820 ++ * only if we need them, i.e. for loading operations. */
22821 ++
22822 ++ switch (gr_usermode->mode) {
22823 ++ case STATUS:
22824 ++ if (gr_status & GR_READY) {
22825 ++ error = 1;
22826 ++ if (!gr_check_secure_terminal(current))
22827 ++ error = 3;
22828 ++ } else
22829 ++ error = 2;
22830 ++ goto out;
22831 ++ case SHUTDOWN:
22832 ++ if ((gr_status & GR_READY)
22833 ++ && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
22834 ++ gr_status &= ~GR_READY;
22835 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
22836 ++ free_variables();
22837 ++ memset(gr_usermode, 0, sizeof (struct gr_arg));
22838 ++ memset(gr_system_salt, 0, GR_SALT_LEN);
22839 ++ memset(gr_system_sum, 0, GR_SHA_LEN);
22840 ++ } else if (gr_status & GR_READY) {
22841 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
22842 ++ error = -EPERM;
22843 ++ } else {
22844 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
22845 ++ error = -EAGAIN;
22846 ++ }
22847 ++ break;
22848 ++ case ENABLE:
22849 ++ if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
22850 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
22851 ++ else {
22852 ++ if (gr_status & GR_READY)
22853 ++ error = -EAGAIN;
22854 ++ else
22855 ++ error = error2;
22856 ++ gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
22857 ++ }
22858 ++ break;
22859 ++ case RELOAD:
22860 ++ if (!(gr_status & GR_READY)) {
22861 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
22862 ++ error = -EAGAIN;
22863 ++ } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
22864 ++ lock_kernel();
22865 ++ gr_status &= ~GR_READY;
22866 ++ free_variables();
22867 ++ if (!(error2 = gracl_init(gr_usermode))) {
22868 ++ unlock_kernel();
22869 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
22870 ++ } else {
22871 ++ unlock_kernel();
22872 ++ error = error2;
22873 ++ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
22874 ++ }
22875 ++ } else {
22876 ++ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
22877 ++ error = -EPERM;
22878 ++ }
22879 ++ break;
22880 ++ case SEGVMOD:
22881 ++ if (unlikely(!(gr_status & GR_READY))) {
22882 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
22883 ++ error = -EAGAIN;
22884 ++ break;
22885 ++ }
22886 ++
22887 ++ if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
22888 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
22889 ++ if (gr_usermode->segv_device && gr_usermode->segv_inode) {
22890 ++ struct acl_subject_label *segvacl;
22891 ++ segvacl =
22892 ++ lookup_acl_subj_label(gr_usermode->segv_inode,
22893 ++ gr_usermode->segv_device,
22894 ++ current->role);
22895 ++ if (segvacl) {
22896 ++ segvacl->crashes = 0;
22897 ++ segvacl->expires = 0;
22898 ++ }
22899 ++ } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
22900 ++ gr_remove_uid(gr_usermode->segv_uid);
22901 ++ }
22902 ++ } else {
22903 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
22904 ++ error = -EPERM;
22905 ++ }
22906 ++ break;
22907 ++ case SPROLE:
22908 ++ case SPROLEPAM:
22909 ++ if (unlikely(!(gr_status & GR_READY))) {
22910 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
22911 ++ error = -EAGAIN;
22912 ++ break;
22913 ++ }
22914 ++
22915 ++ if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
22916 ++ current->role->expires = 0;
22917 ++ current->role->auth_attempts = 0;
22918 ++ }
22919 ++
22920 ++ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
22921 ++ time_after(current->role->expires, get_seconds())) {
22922 ++ error = -EBUSY;
22923 ++ goto out;
22924 ++ }
22925 ++
22926 ++ if (lookup_special_role_auth
22927 ++ (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
22928 ++ && ((!sprole_salt && !sprole_sum)
22929 ++ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
22930 ++ char *p = "";
22931 ++ assign_special_role(gr_usermode->sp_role);
22932 ++ read_lock(&tasklist_lock);
22933 ++ if (current->parent)
22934 ++ p = current->parent->role->rolename;
22935 ++ read_unlock(&tasklist_lock);
22936 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
22937 ++ p, acl_sp_role_value);
22938 ++ } else {
22939 ++ gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
22940 ++ error = -EPERM;
22941 ++ if(!(current->role->auth_attempts++))
22942 ++ current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
22943 ++
22944 ++ goto out;
22945 ++ }
22946 ++ break;
22947 ++ case UNSPROLE:
22948 ++ if (unlikely(!(gr_status & GR_READY))) {
22949 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
22950 ++ error = -EAGAIN;
22951 ++ break;
22952 ++ }
22953 ++
22954 ++ if (current->role->roletype & GR_ROLE_SPECIAL) {
22955 ++ char *p = "";
22956 ++ int i = 0;
22957 ++
22958 ++ read_lock(&tasklist_lock);
22959 ++ if (current->parent) {
22960 ++ p = current->parent->role->rolename;
22961 ++ i = current->parent->acl_role_id;
22962 ++ }
22963 ++ read_unlock(&tasklist_lock);
22964 ++
22965 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
22966 ++ gr_set_acls(1);
22967 ++ } else {
22968 ++ gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
22969 ++ error = -EPERM;
22970 ++ goto out;
22971 ++ }
22972 ++ break;
22973 ++ default:
22974 ++ gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
22975 ++ error = -EINVAL;
22976 ++ break;
22977 ++ }
22978 ++
22979 ++ if (error != -EPERM)
22980 ++ goto out;
22981 ++
22982 ++ if(!(gr_auth_attempts++))
22983 ++ gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
22984 ++
22985 ++ out:
22986 ++ up(&gr_dev_sem);
22987 ++ return error;
22988 ++}
22989 ++
22990 ++int
22991 ++gr_set_acls(const int type)
22992 ++{
22993 ++ struct acl_object_label *obj;
22994 ++ struct task_struct *task, *task2;
22995 ++ struct file *filp;
22996 ++ struct acl_role_label *role = current->role;
22997 ++ __u16 acl_role_id = current->acl_role_id;
22998 ++
22999 ++ read_lock(&tasklist_lock);
23000 ++ read_lock(&grsec_exec_file_lock);
23001 ++ do_each_thread(task2, task) {
23002 ++ /* check to see if we're called from the exit handler,
23003 ++ if so, only replace ACLs that have inherited the admin
23004 ++ ACL */
23005 ++
23006 ++ if (type && (task->role != role ||
23007 ++ task->acl_role_id != acl_role_id))
23008 ++ continue;
23009 ++
23010 ++ task->acl_role_id = 0;
23011 ++ task->acl_sp_role = 0;
23012 ++
23013 ++ if ((filp = task->exec_file)) {
23014 ++ task->role = lookup_acl_role_label(task, task->uid, task->gid);
23015 ++
23016 ++ task->acl =
23017 ++ chk_subj_label(filp->f_path.dentry, filp->f_path.mnt,
23018 ++ task->role);
23019 ++ if (task->acl) {
23020 ++ struct acl_subject_label *curr;
23021 ++ curr = task->acl;
23022 ++
23023 ++ task->is_writable = 0;
23024 ++ /* ignore additional mmap checks for processes that are writable
23025 ++ by the default ACL */
23026 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
23027 ++ if (unlikely(obj->mode & GR_WRITE))
23028 ++ task->is_writable = 1;
23029 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
23030 ++ if (unlikely(obj->mode & GR_WRITE))
23031 ++ task->is_writable = 1;
23032 ++
23033 ++ gr_set_proc_res(task);
23034 ++
23035 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
23036 ++ printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
23037 ++#endif
23038 ++ } else {
23039 ++ read_unlock(&grsec_exec_file_lock);
23040 ++ read_unlock(&tasklist_lock);
23041 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
23042 ++ return 1;
23043 ++ }
23044 ++ } else {
23045 ++ // it's a kernel process
23046 ++ task->role = kernel_role;
23047 ++ task->acl = kernel_role->root_label;
23048 ++#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
23049 ++ task->acl->mode &= ~GR_PROCFIND;
23050 ++#endif
23051 ++ }
23052 ++ } while_each_thread(task2, task);
23053 ++ read_unlock(&grsec_exec_file_lock);
23054 ++ read_unlock(&tasklist_lock);
23055 ++ return 0;
23056 ++}
23057 ++
23058 ++void
23059 ++gr_learn_resource(const struct task_struct *task,
23060 ++ const int res, const unsigned long wanted, const int gt)
23061 ++{
23062 ++ struct acl_subject_label *acl;
23063 ++
23064 ++ if (unlikely((gr_status & GR_READY) &&
23065 ++ task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
23066 ++ goto skip_reslog;
23067 ++
23068 ++#ifdef CONFIG_GRKERNSEC_RESLOG
23069 ++ gr_log_resource(task, res, wanted, gt);
23070 ++#endif
23071 ++ skip_reslog:
23072 ++
23073 ++ if (unlikely(!(gr_status & GR_READY) || !wanted))
23074 ++ return;
23075 ++
23076 ++ acl = task->acl;
23077 ++
23078 ++ if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
23079 ++ !(acl->resmask & (1 << (unsigned short) res))))
23080 ++ return;
23081 ++
23082 ++ if (wanted >= acl->res[res].rlim_cur) {
23083 ++ unsigned long res_add;
23084 ++
23085 ++ res_add = wanted;
23086 ++ switch (res) {
23087 ++ case RLIMIT_CPU:
23088 ++ res_add += GR_RLIM_CPU_BUMP;
23089 ++ break;
23090 ++ case RLIMIT_FSIZE:
23091 ++ res_add += GR_RLIM_FSIZE_BUMP;
23092 ++ break;
23093 ++ case RLIMIT_DATA:
23094 ++ res_add += GR_RLIM_DATA_BUMP;
23095 ++ break;
23096 ++ case RLIMIT_STACK:
23097 ++ res_add += GR_RLIM_STACK_BUMP;
23098 ++ break;
23099 ++ case RLIMIT_CORE:
23100 ++ res_add += GR_RLIM_CORE_BUMP;
23101 ++ break;
23102 ++ case RLIMIT_RSS:
23103 ++ res_add += GR_RLIM_RSS_BUMP;
23104 ++ break;
23105 ++ case RLIMIT_NPROC:
23106 ++ res_add += GR_RLIM_NPROC_BUMP;
23107 ++ break;
23108 ++ case RLIMIT_NOFILE:
23109 ++ res_add += GR_RLIM_NOFILE_BUMP;
23110 ++ break;
23111 ++ case RLIMIT_MEMLOCK:
23112 ++ res_add += GR_RLIM_MEMLOCK_BUMP;
23113 ++ break;
23114 ++ case RLIMIT_AS:
23115 ++ res_add += GR_RLIM_AS_BUMP;
23116 ++ break;
23117 ++ case RLIMIT_LOCKS:
23118 ++ res_add += GR_RLIM_LOCKS_BUMP;
23119 ++ break;
23120 ++ }
23121 ++
23122 ++ acl->res[res].rlim_cur = res_add;
23123 ++
23124 ++ if (wanted > acl->res[res].rlim_max)
23125 ++ acl->res[res].rlim_max = res_add;
23126 ++
23127 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
23128 ++ task->role->roletype, acl->filename,
23129 ++ acl->res[res].rlim_cur, acl->res[res].rlim_max,
23130 ++ "", (unsigned long) res);
23131 ++ }
23132 ++
23133 ++ return;
23134 ++}
23135 ++
23136 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
23137 ++void
23138 ++pax_set_initial_flags(struct linux_binprm *bprm)
23139 ++{
23140 ++ struct task_struct *task = current;
23141 ++ struct acl_subject_label *proc;
23142 ++ unsigned long flags;
23143 ++
23144 ++ if (unlikely(!(gr_status & GR_READY)))
23145 ++ return;
23146 ++
23147 ++ flags = pax_get_flags(task);
23148 ++
23149 ++ proc = task->acl;
23150 ++
23151 ++ if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
23152 ++ flags &= ~MF_PAX_PAGEEXEC;
23153 ++ if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
23154 ++ flags &= ~MF_PAX_SEGMEXEC;
23155 ++ if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
23156 ++ flags &= ~MF_PAX_RANDMMAP;
23157 ++ if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
23158 ++ flags &= ~MF_PAX_EMUTRAMP;
23159 ++ if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
23160 ++ flags &= ~MF_PAX_MPROTECT;
23161 ++
23162 ++ if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
23163 ++ flags |= MF_PAX_PAGEEXEC;
23164 ++ if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
23165 ++ flags |= MF_PAX_SEGMEXEC;
23166 ++ if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
23167 ++ flags |= MF_PAX_RANDMMAP;
23168 ++ if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
23169 ++ flags |= MF_PAX_EMUTRAMP;
23170 ++ if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
23171 ++ flags |= MF_PAX_MPROTECT;
23172 ++
23173 ++ pax_set_flags(task, flags);
23174 ++
23175 ++ return;
23176 ++}
23177 ++#endif
23178 ++
23179 ++#ifdef CONFIG_SYSCTL
23180 ++/* Eric Biederman likes breaking userland ABI and every inode-based security
23181 ++ system to save 35kb of memory */
23182 ++
23183 ++/* we modify the passed in filename, but adjust it back before returning */
23184 ++static struct acl_object_label *gr_lookup_by_name(char *name, unsigned int len)
23185 ++{
23186 ++ struct name_entry *nmatch;
23187 ++ char *p, *lastp = NULL;
23188 ++ struct acl_object_label *obj = NULL, *tmp;
23189 ++ struct acl_subject_label *tmpsubj;
23190 ++ char c = '\0';
23191 ++
23192 ++ read_lock(&gr_inode_lock);
23193 ++
23194 ++ p = name + len - 1;
23195 ++ do {
23196 ++ nmatch = lookup_name_entry(name);
23197 ++ if (lastp != NULL)
23198 ++ *lastp = c;
23199 ++
23200 ++ if (nmatch == NULL)
23201 ++ goto next_component;
23202 ++ tmpsubj = current->acl;
23203 ++ do {
23204 ++ obj = lookup_acl_obj_label(nmatch->inode, nmatch->device, tmpsubj);
23205 ++ if (obj != NULL) {
23206 ++ tmp = obj->globbed;
23207 ++ while (tmp) {
23208 ++ if (!glob_match(tmp->filename, name)) {
23209 ++ obj = tmp;
23210 ++ goto found_obj;
23211 ++ }
23212 ++ tmp = tmp->next;
23213 ++ }
23214 ++ goto found_obj;
23215 ++ }
23216 ++ } while ((tmpsubj = tmpsubj->parent_subject));
23217 ++next_component:
23218 ++ /* end case */
23219 ++ if (p == name)
23220 ++ break;
23221 ++
23222 ++ while (*p != '/')
23223 ++ p--;
23224 ++ if (p == name)
23225 ++ lastp = p + 1;
23226 ++ else {
23227 ++ lastp = p;
23228 ++ p--;
23229 ++ }
23230 ++ c = *lastp;
23231 ++ *lastp = '\0';
23232 ++ } while (1);
23233 ++found_obj:
23234 ++ read_unlock(&gr_inode_lock);
23235 ++ /* obj returned will always be non-null */
23236 ++ return obj;
23237 ++}
23238 ++
23239 ++/* returns 0 when allowing, non-zero on error
23240 ++ op of 0 is used for readdir, so we don't log the names of hidden files
23241 ++*/
23242 ++__u32
23243 ++gr_handle_sysctl(const struct ctl_table *table, const int op)
23244 ++{
23245 ++ ctl_table *tmp;
23246 ++ const char *proc_sys = "/proc/sys";
23247 ++ char *path;
23248 ++ struct acl_object_label *obj;
23249 ++ unsigned short len = 0, pos = 0, depth = 0, i;
23250 ++ __u32 err = 0;
23251 ++ __u32 mode = 0;
23252 ++
23253 ++ if (unlikely(!(gr_status & GR_READY)))
23254 ++ return 0;
23255 ++
23256 ++ /* for now, ignore operations on non-sysctl entries if it's not a
23257 ++ readdir*/
23258 ++ if (table->child != NULL && op != 0)
23259 ++ return 0;
23260 ++
23261 ++ mode |= GR_FIND;
23262 ++ /* it's only a read if it's an entry, read on dirs is for readdir */
23263 ++ if (op & 004)
23264 ++ mode |= GR_READ;
23265 ++ if (op & 002)
23266 ++ mode |= GR_WRITE;
23267 ++
23268 ++ preempt_disable();
23269 ++
23270 ++ path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
23271 ++
23272 ++ /* it's only a read/write if it's an actual entry, not a dir
23273 ++ (which are opened for readdir)
23274 ++ */
23275 ++
23276 ++ /* convert the requested sysctl entry into a pathname */
23277 ++
23278 ++ for (tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
23279 ++ len += strlen(tmp->procname);
23280 ++ len++;
23281 ++ depth++;
23282 ++ }
23283 ++
23284 ++ if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE) {
23285 ++ /* deny */
23286 ++ goto out;
23287 ++ }
23288 ++
23289 ++ memset(path, 0, PAGE_SIZE);
23290 ++
23291 ++ memcpy(path, proc_sys, strlen(proc_sys));
23292 ++
23293 ++ pos += strlen(proc_sys);
23294 ++
23295 ++ for (; depth > 0; depth--) {
23296 ++ path[pos] = '/';
23297 ++ pos++;
23298 ++ for (i = 1, tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
23299 ++ if (depth == i) {
23300 ++ memcpy(path + pos, tmp->procname,
23301 ++ strlen(tmp->procname));
23302 ++ pos += strlen(tmp->procname);
23303 ++ }
23304 ++ i++;
23305 ++ }
23306 ++ }
23307 ++
23308 ++ obj = gr_lookup_by_name(path, pos);
23309 ++ err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
23310 ++
23311 ++ if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
23312 ++ ((err & mode) != mode))) {
23313 ++ __u32 new_mode = mode;
23314 ++
23315 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
23316 ++
23317 ++ err = 0;
23318 ++ gr_log_learn_sysctl(current, path, new_mode);
23319 ++ } else if (!(err & GR_FIND) && !(err & GR_SUPPRESS) && op != 0) {
23320 ++ gr_log_hidden_sysctl(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, path);
23321 ++ err = -ENOENT;
23322 ++ } else if (!(err & GR_FIND)) {
23323 ++ err = -ENOENT;
23324 ++ } else if (((err & mode) & ~GR_FIND) != (mode & ~GR_FIND) && !(err & GR_SUPPRESS)) {
23325 ++ gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
23326 ++ path, (mode & GR_READ) ? " reading" : "",
23327 ++ (mode & GR_WRITE) ? " writing" : "");
23328 ++ err = -EACCES;
23329 ++ } else if ((err & mode) != mode) {
23330 ++ err = -EACCES;
23331 ++ } else if ((((err & mode) & ~GR_FIND) == (mode & ~GR_FIND)) && (err & GR_AUDITS)) {
23332 ++ gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
23333 ++ path, (mode & GR_READ) ? " reading" : "",
23334 ++ (mode & GR_WRITE) ? " writing" : "");
23335 ++ err = 0;
23336 ++ } else
23337 ++ err = 0;
23338 ++
23339 ++ out:
23340 ++ preempt_enable();
23341 ++
23342 ++ return err;
23343 ++}
23344 ++#endif
23345 ++
23346 ++int
23347 ++gr_handle_proc_ptrace(struct task_struct *task)
23348 ++{
23349 ++ struct file *filp;
23350 ++ struct task_struct *tmp = task;
23351 ++ struct task_struct *curtemp = current;
23352 ++ __u32 retmode;
23353 ++
23354 ++ if (unlikely(!(gr_status & GR_READY)))
23355 ++ return 0;
23356 ++
23357 ++ read_lock(&tasklist_lock);
23358 ++ read_lock(&grsec_exec_file_lock);
23359 ++ filp = task->exec_file;
23360 ++
23361 ++ while (tmp->pid > 0) {
23362 ++ if (tmp == curtemp)
23363 ++ break;
23364 ++ tmp = tmp->parent;
23365 ++ }
23366 ++
23367 ++ if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
23368 ++ read_unlock(&grsec_exec_file_lock);
23369 ++ read_unlock(&tasklist_lock);
23370 ++ return 1;
23371 ++ }
23372 ++
23373 ++ retmode = gr_search_file(filp->f_path.dentry, GR_NOPTRACE, filp->f_path.mnt);
23374 ++ read_unlock(&grsec_exec_file_lock);
23375 ++ read_unlock(&tasklist_lock);
23376 ++
23377 ++ if (retmode & GR_NOPTRACE)
23378 ++ return 1;
23379 ++
23380 ++ if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
23381 ++ && (current->acl != task->acl || (current->acl != current->role->root_label
23382 ++ && current->pid != task->pid)))
23383 ++ return 1;
23384 ++
23385 ++ return 0;
23386 ++}
23387 ++
23388 ++int
23389 ++gr_handle_ptrace(struct task_struct *task, const long request)
23390 ++{
23391 ++ struct task_struct *tmp = task;
23392 ++ struct task_struct *curtemp = current;
23393 ++ __u32 retmode;
23394 ++
23395 ++ if (unlikely(!(gr_status & GR_READY)))
23396 ++ return 0;
23397 ++
23398 ++ read_lock(&tasklist_lock);
23399 ++ while (tmp->pid > 0) {
23400 ++ if (tmp == curtemp)
23401 ++ break;
23402 ++ tmp = tmp->parent;
23403 ++ }
23404 ++
23405 ++ if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
23406 ++ read_unlock(&tasklist_lock);
23407 ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
23408 ++ return 1;
23409 ++ }
23410 ++ read_unlock(&tasklist_lock);
23411 ++
23412 ++ read_lock(&grsec_exec_file_lock);
23413 ++ if (unlikely(!task->exec_file)) {
23414 ++ read_unlock(&grsec_exec_file_lock);
23415 ++ return 0;
23416 ++ }
23417 ++
23418 ++ retmode = gr_search_file(task->exec_file->f_path.dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_path.mnt);
23419 ++ read_unlock(&grsec_exec_file_lock);
23420 ++
23421 ++ if (retmode & GR_NOPTRACE) {
23422 ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
23423 ++ return 1;
23424 ++ }
23425 ++
23426 ++ if (retmode & GR_PTRACERD) {
23427 ++ switch (request) {
23428 ++ case PTRACE_POKETEXT:
23429 ++ case PTRACE_POKEDATA:
23430 ++ case PTRACE_POKEUSR:
23431 ++#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
23432 ++ case PTRACE_SETREGS:
23433 ++ case PTRACE_SETFPREGS:
23434 ++#endif
23435 ++#ifdef CONFIG_X86
23436 ++ case PTRACE_SETFPXREGS:
23437 ++#endif
23438 ++#ifdef CONFIG_ALTIVEC
23439 ++ case PTRACE_SETVRREGS:
23440 ++#endif
23441 ++ return 1;
23442 ++ default:
23443 ++ return 0;
23444 ++ }
23445 ++ } else if (!(current->acl->mode & GR_POVERRIDE) &&
23446 ++ !(current->role->roletype & GR_ROLE_GOD) &&
23447 ++ (current->acl != task->acl)) {
23448 ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
23449 ++ return 1;
23450 ++ }
23451 ++
23452 ++ return 0;
23453 ++}
23454 ++
23455 ++static int is_writable_mmap(const struct file *filp)
23456 ++{
23457 ++ struct task_struct *task = current;
23458 ++ struct acl_object_label *obj, *obj2;
23459 ++
23460 ++ if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
23461 ++ !task->is_writable && S_ISREG(filp->f_path.dentry->d_inode->i_mode)) {
23462 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
23463 ++ obj2 = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt,
23464 ++ task->role->root_label);
23465 ++ if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
23466 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_path.dentry, filp->f_path.mnt);
23467 ++ return 1;
23468 ++ }
23469 ++ }
23470 ++ return 0;
23471 ++}
23472 ++
23473 ++int
23474 ++gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
23475 ++{
23476 ++ __u32 mode;
23477 ++
23478 ++ if (unlikely(!file || !(prot & PROT_EXEC)))
23479 ++ return 1;
23480 ++
23481 ++ if (is_writable_mmap(file))
23482 ++ return 0;
23483 ++
23484 ++ mode =
23485 ++ gr_search_file(file->f_path.dentry,
23486 ++ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
23487 ++ file->f_path.mnt);
23488 ++
23489 ++ if (!gr_tpe_allow(file))
23490 ++ return 0;
23491 ++
23492 ++ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
23493 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
23494 ++ return 0;
23495 ++ } else if (unlikely(!(mode & GR_EXEC))) {
23496 ++ return 0;
23497 ++ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
23498 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
23499 ++ return 1;
23500 ++ }
23501 ++
23502 ++ return 1;
23503 ++}
23504 ++
23505 ++int
23506 ++gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
23507 ++{
23508 ++ __u32 mode;
23509 ++
23510 ++ if (unlikely(!file || !(prot & PROT_EXEC)))
23511 ++ return 1;
23512 ++
23513 ++ if (is_writable_mmap(file))
23514 ++ return 0;
23515 ++
23516 ++ mode =
23517 ++ gr_search_file(file->f_path.dentry,
23518 ++ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
23519 ++ file->f_path.mnt);
23520 ++
23521 ++ if (!gr_tpe_allow(file))
23522 ++ return 0;
23523 ++
23524 ++ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
23525 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
23526 ++ return 0;
23527 ++ } else if (unlikely(!(mode & GR_EXEC))) {
23528 ++ return 0;
23529 ++ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
23530 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
23531 ++ return 1;
23532 ++ }
23533 ++
23534 ++ return 1;
23535 ++}
23536 ++
23537 ++void
23538 ++gr_acl_handle_psacct(struct task_struct *task, const long code)
23539 ++{
23540 ++ unsigned long runtime;
23541 ++ unsigned long cputime;
23542 ++ unsigned int wday, cday;
23543 ++ __u8 whr, chr;
23544 ++ __u8 wmin, cmin;
23545 ++ __u8 wsec, csec;
23546 ++ struct timespec timeval;
23547 ++
23548 ++ if (unlikely(!(gr_status & GR_READY) || !task->acl ||
23549 ++ !(task->acl->mode & GR_PROCACCT)))
23550 ++ return;
23551 ++
23552 ++ do_posix_clock_monotonic_gettime(&timeval);
23553 ++ runtime = timeval.tv_sec - task->start_time.tv_sec;
23554 ++ wday = runtime / (3600 * 24);
23555 ++ runtime -= wday * (3600 * 24);
23556 ++ whr = runtime / 3600;
23557 ++ runtime -= whr * 3600;
23558 ++ wmin = runtime / 60;
23559 ++ runtime -= wmin * 60;
23560 ++ wsec = runtime;
23561 ++
23562 ++ cputime = (task->utime + task->stime) / HZ;
23563 ++ cday = cputime / (3600 * 24);
23564 ++ cputime -= cday * (3600 * 24);
23565 ++ chr = cputime / 3600;
23566 ++ cputime -= chr * 3600;
23567 ++ cmin = cputime / 60;
23568 ++ cputime -= cmin * 60;
23569 ++ csec = cputime;
23570 ++
23571 ++ gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
23572 ++
23573 ++ return;
23574 ++}
23575 ++
23576 ++void gr_set_kernel_label(struct task_struct *task)
23577 ++{
23578 ++ if (gr_status & GR_READY) {
23579 ++ task->role = kernel_role;
23580 ++ task->acl = kernel_role->root_label;
23581 ++ }
23582 ++ return;
23583 ++}
23584 ++
23585 ++int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
23586 ++{
23587 ++ struct task_struct *task = current;
23588 ++ struct dentry *dentry = file->f_path.dentry;
23589 ++ struct vfsmount *mnt = file->f_path.mnt;
23590 ++ struct acl_object_label *obj, *tmp;
23591 ++ struct acl_subject_label *subj;
23592 ++ unsigned int bufsize;
23593 ++ int is_not_root;
23594 ++ char *path;
23595 ++
23596 ++ if (unlikely(!(gr_status & GR_READY)))
23597 ++ return 1;
23598 ++
23599 ++ if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
23600 ++ return 1;
23601 ++
23602 ++ /* ignore Eric Biederman */
23603 ++ if (IS_PRIVATE(dentry->d_inode))
23604 ++ return 1;
23605 ++
23606 ++ subj = task->acl;
23607 ++ do {
23608 ++ obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
23609 ++ if (obj != NULL)
23610 ++ return (obj->mode & GR_FIND) ? 1 : 0;
23611 ++ } while ((subj = subj->parent_subject));
23612 ++
23613 ++ obj = chk_obj_label(dentry, mnt, task->acl);
23614 ++ if (obj->globbed == NULL)
23615 ++ return (obj->mode & GR_FIND) ? 1 : 0;
23616 ++
23617 ++ is_not_root = ((obj->filename[0] == '/') &&
23618 ++ (obj->filename[1] == '\0')) ? 0 : 1;
23619 ++ bufsize = PAGE_SIZE - namelen - is_not_root;
23620 ++
23621 ++ /* check bufsize > PAGE_SIZE || bufsize == 0 */
23622 ++ if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
23623 ++ return 1;
23624 ++
23625 ++ preempt_disable();
23626 ++ path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
23627 ++ bufsize);
23628 ++
23629 ++ bufsize = strlen(path);
23630 ++
23631 ++ /* if base is "/", don't append an additional slash */
23632 ++ if (is_not_root)
23633 ++ *(path + bufsize) = '/';
23634 ++ memcpy(path + bufsize + is_not_root, name, namelen);
23635 ++ *(path + bufsize + namelen + is_not_root) = '\0';
23636 ++
23637 ++ tmp = obj->globbed;
23638 ++ while (tmp) {
23639 ++ if (!glob_match(tmp->filename, path)) {
23640 ++ preempt_enable();
23641 ++ return (tmp->mode & GR_FIND) ? 1 : 0;
23642 ++ }
23643 ++ tmp = tmp->next;
23644 ++ }
23645 ++ preempt_enable();
23646 ++ return (obj->mode & GR_FIND) ? 1 : 0;
23647 ++}
23648 ++
23649 ++EXPORT_SYMBOL(gr_learn_resource);
23650 ++EXPORT_SYMBOL(gr_set_kernel_label);
23651 ++#ifdef CONFIG_SECURITY
23652 ++EXPORT_SYMBOL(gr_check_user_change);
23653 ++EXPORT_SYMBOL(gr_check_group_change);
23654 ++#endif
23655 ++
23656 +diff -urNp linux-2.6.26.6/grsecurity/gracl_cap.c linux-2.6.26.6/grsecurity/gracl_cap.c
23657 +--- linux-2.6.26.6/grsecurity/gracl_cap.c 1969-12-31 19:00:00.000000000 -0500
23658 ++++ linux-2.6.26.6/grsecurity/gracl_cap.c 2008-10-11 21:54:20.000000000 -0400
23659 +@@ -0,0 +1,129 @@
23660 ++#include <linux/kernel.h>
23661 ++#include <linux/module.h>
23662 ++#include <linux/sched.h>
23663 ++#include <linux/gracl.h>
23664 ++#include <linux/grsecurity.h>
23665 ++#include <linux/grinternal.h>
23666 ++
23667 ++static const char *captab_log[] = {
23668 ++ "CAP_CHOWN",
23669 ++ "CAP_DAC_OVERRIDE",
23670 ++ "CAP_DAC_READ_SEARCH",
23671 ++ "CAP_FOWNER",
23672 ++ "CAP_FSETID",
23673 ++ "CAP_KILL",
23674 ++ "CAP_SETGID",
23675 ++ "CAP_SETUID",
23676 ++ "CAP_SETPCAP",
23677 ++ "CAP_LINUX_IMMUTABLE",
23678 ++ "CAP_NET_BIND_SERVICE",
23679 ++ "CAP_NET_BROADCAST",
23680 ++ "CAP_NET_ADMIN",
23681 ++ "CAP_NET_RAW",
23682 ++ "CAP_IPC_LOCK",
23683 ++ "CAP_IPC_OWNER",
23684 ++ "CAP_SYS_MODULE",
23685 ++ "CAP_SYS_RAWIO",
23686 ++ "CAP_SYS_CHROOT",
23687 ++ "CAP_SYS_PTRACE",
23688 ++ "CAP_SYS_PACCT",
23689 ++ "CAP_SYS_ADMIN",
23690 ++ "CAP_SYS_BOOT",
23691 ++ "CAP_SYS_NICE",
23692 ++ "CAP_SYS_RESOURCE",
23693 ++ "CAP_SYS_TIME",
23694 ++ "CAP_SYS_TTY_CONFIG",
23695 ++ "CAP_MKNOD",
23696 ++ "CAP_LEASE",
23697 ++ "CAP_AUDIT_WRITE",
23698 ++ "CAP_AUDIT_CONTROL",
23699 ++ "CAP_SETFCAP",
23700 ++ "CAP_MAC_OVERRIDE",
23701 ++ "CAP_MAC_ADMIN"
23702 ++};
23703 ++
23704 ++EXPORT_SYMBOL(gr_task_is_capable);
23705 ++EXPORT_SYMBOL(gr_is_capable_nolog);
23706 ++
23707 ++int
23708 ++gr_task_is_capable(struct task_struct *task, const int cap)
23709 ++{
23710 ++ struct acl_subject_label *curracl;
23711 ++ kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
23712 ++
23713 ++ if (!gr_acl_is_enabled())
23714 ++ return 1;
23715 ++
23716 ++ curracl = task->acl;
23717 ++
23718 ++ cap_drop = curracl->cap_lower;
23719 ++ cap_mask = curracl->cap_mask;
23720 ++
23721 ++ while ((curracl = curracl->parent_subject)) {
23722 ++ /* if the cap isn't specified in the current computed mask but is specified in the
23723 ++ current level subject, and is lowered in the current level subject, then add
23724 ++ it to the set of dropped capabilities
23725 ++ otherwise, add the current level subject's mask to the current computed mask
23726 ++ */
23727 ++ if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
23728 ++ cap_raise(cap_mask, cap);
23729 ++ if (cap_raised(curracl->cap_lower, cap))
23730 ++ cap_raise(cap_drop, cap);
23731 ++ }
23732 ++ }
23733 ++
23734 ++ if (!cap_raised(cap_drop, cap))
23735 ++ return 1;
23736 ++
23737 ++ curracl = task->acl;
23738 ++
23739 ++ if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
23740 ++ && cap_raised(task->cap_effective, cap)) {
23741 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
23742 ++ task->role->roletype, task->uid,
23743 ++ task->gid, task->exec_file ?
23744 ++ gr_to_filename(task->exec_file->f_path.dentry,
23745 ++ task->exec_file->f_path.mnt) : curracl->filename,
23746 ++ curracl->filename, 0UL,
23747 ++ 0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
23748 ++ return 1;
23749 ++ }
23750 ++
23751 ++ if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap))
23752 ++ gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
23753 ++ return 0;
23754 ++}
23755 ++
23756 ++int
23757 ++gr_is_capable_nolog(const int cap)
23758 ++{
23759 ++ struct acl_subject_label *curracl;
23760 ++ kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
23761 ++
23762 ++ if (!gr_acl_is_enabled())
23763 ++ return 1;
23764 ++
23765 ++ curracl = current->acl;
23766 ++
23767 ++ cap_drop = curracl->cap_lower;
23768 ++ cap_mask = curracl->cap_mask;
23769 ++
23770 ++ while ((curracl = curracl->parent_subject)) {
23771 ++ /* if the cap isn't specified in the current computed mask but is specified in the
23772 ++ current level subject, and is lowered in the current level subject, then add
23773 ++ it to the set of dropped capabilities
23774 ++ otherwise, add the current level subject's mask to the current computed mask
23775 ++ */
23776 ++ if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
23777 ++ cap_raise(cap_mask, cap);
23778 ++ if (cap_raised(curracl->cap_lower, cap))
23779 ++ cap_raise(cap_drop, cap);
23780 ++ }
23781 ++ }
23782 ++
23783 ++ if (!cap_raised(cap_drop, cap))
23784 ++ return 1;
23785 ++
23786 ++ return 0;
23787 ++}
23788 ++
23789 +diff -urNp linux-2.6.26.6/grsecurity/gracl_fs.c linux-2.6.26.6/grsecurity/gracl_fs.c
23790 +--- linux-2.6.26.6/grsecurity/gracl_fs.c 1969-12-31 19:00:00.000000000 -0500
23791 ++++ linux-2.6.26.6/grsecurity/gracl_fs.c 2008-10-11 21:54:20.000000000 -0400
23792 +@@ -0,0 +1,423 @@
23793 ++#include <linux/kernel.h>
23794 ++#include <linux/sched.h>
23795 ++#include <linux/types.h>
23796 ++#include <linux/fs.h>
23797 ++#include <linux/file.h>
23798 ++#include <linux/stat.h>
23799 ++#include <linux/grsecurity.h>
23800 ++#include <linux/grinternal.h>
23801 ++#include <linux/gracl.h>
23802 ++
23803 ++__u32
23804 ++gr_acl_handle_hidden_file(const struct dentry * dentry,
23805 ++ const struct vfsmount * mnt)
23806 ++{
23807 ++ __u32 mode;
23808 ++
23809 ++ if (unlikely(!dentry->d_inode))
23810 ++ return GR_FIND;
23811 ++
23812 ++ mode =
23813 ++ gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
23814 ++
23815 ++ if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
23816 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
23817 ++ return mode;
23818 ++ } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
23819 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
23820 ++ return 0;
23821 ++ } else if (unlikely(!(mode & GR_FIND)))
23822 ++ return 0;
23823 ++
23824 ++ return GR_FIND;
23825 ++}
23826 ++
23827 ++__u32
23828 ++gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
23829 ++ const int fmode)
23830 ++{
23831 ++ __u32 reqmode = GR_FIND;
23832 ++ __u32 mode;
23833 ++
23834 ++ if (unlikely(!dentry->d_inode))
23835 ++ return reqmode;
23836 ++
23837 ++ if (unlikely(fmode & O_APPEND))
23838 ++ reqmode |= GR_APPEND;
23839 ++ else if (unlikely(fmode & FMODE_WRITE))
23840 ++ reqmode |= GR_WRITE;
23841 ++ if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
23842 ++ reqmode |= GR_READ;
23843 ++
23844 ++ mode =
23845 ++ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
23846 ++ mnt);
23847 ++
23848 ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
23849 ++ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
23850 ++ reqmode & GR_READ ? " reading" : "",
23851 ++ reqmode & GR_WRITE ? " writing" : reqmode &
23852 ++ GR_APPEND ? " appending" : "");
23853 ++ return reqmode;
23854 ++ } else
23855 ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
23856 ++ {
23857 ++ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
23858 ++ reqmode & GR_READ ? " reading" : "",
23859 ++ reqmode & GR_WRITE ? " writing" : reqmode &
23860 ++ GR_APPEND ? " appending" : "");
23861 ++ return 0;
23862 ++ } else if (unlikely((mode & reqmode) != reqmode))
23863 ++ return 0;
23864 ++
23865 ++ return reqmode;
23866 ++}
23867 ++
23868 ++__u32
23869 ++gr_acl_handle_creat(const struct dentry * dentry,
23870 ++ const struct dentry * p_dentry,
23871 ++ const struct vfsmount * p_mnt, const int fmode,
23872 ++ const int imode)
23873 ++{
23874 ++ __u32 reqmode = GR_WRITE | GR_CREATE;
23875 ++ __u32 mode;
23876 ++
23877 ++ if (unlikely(fmode & O_APPEND))
23878 ++ reqmode |= GR_APPEND;
23879 ++ if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
23880 ++ reqmode |= GR_READ;
23881 ++ if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
23882 ++ reqmode |= GR_SETID;
23883 ++
23884 ++ mode =
23885 ++ gr_check_create(dentry, p_dentry, p_mnt,
23886 ++ reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
23887 ++
23888 ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
23889 ++ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
23890 ++ reqmode & GR_READ ? " reading" : "",
23891 ++ reqmode & GR_WRITE ? " writing" : reqmode &
23892 ++ GR_APPEND ? " appending" : "");
23893 ++ return reqmode;
23894 ++ } else
23895 ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
23896 ++ {
23897 ++ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
23898 ++ reqmode & GR_READ ? " reading" : "",
23899 ++ reqmode & GR_WRITE ? " writing" : reqmode &
23900 ++ GR_APPEND ? " appending" : "");
23901 ++ return 0;
23902 ++ } else if (unlikely((mode & reqmode) != reqmode))
23903 ++ return 0;
23904 ++
23905 ++ return reqmode;
23906 ++}
23907 ++
23908 ++__u32
23909 ++gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
23910 ++ const int fmode)
23911 ++{
23912 ++ __u32 mode, reqmode = GR_FIND;
23913 ++
23914 ++ if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
23915 ++ reqmode |= GR_EXEC;
23916 ++ if (fmode & S_IWOTH)
23917 ++ reqmode |= GR_WRITE;
23918 ++ if (fmode & S_IROTH)
23919 ++ reqmode |= GR_READ;
23920 ++
23921 ++ mode =
23922 ++ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
23923 ++ mnt);
23924 ++
23925 ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
23926 ++ gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
23927 ++ reqmode & GR_READ ? " reading" : "",
23928 ++ reqmode & GR_WRITE ? " writing" : "",
23929 ++ reqmode & GR_EXEC ? " executing" : "");
23930 ++ return reqmode;
23931 ++ } else
23932 ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
23933 ++ {
23934 ++ gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
23935 ++ reqmode & GR_READ ? " reading" : "",
23936 ++ reqmode & GR_WRITE ? " writing" : "",
23937 ++ reqmode & GR_EXEC ? " executing" : "");
23938 ++ return 0;
23939 ++ } else if (unlikely((mode & reqmode) != reqmode))
23940 ++ return 0;
23941 ++
23942 ++ return reqmode;
23943 ++}
23944 ++
23945 ++static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
23946 ++{
23947 ++ __u32 mode;
23948 ++
23949 ++ mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
23950 ++
23951 ++ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
23952 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
23953 ++ return mode;
23954 ++ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
23955 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
23956 ++ return 0;
23957 ++ } else if (unlikely((mode & (reqmode)) != (reqmode)))
23958 ++ return 0;
23959 ++
23960 ++ return (reqmode);
23961 ++}
23962 ++
23963 ++__u32
23964 ++gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
23965 ++{
23966 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
23967 ++}
23968 ++
23969 ++__u32
23970 ++gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
23971 ++{
23972 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
23973 ++}
23974 ++
23975 ++__u32
23976 ++gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
23977 ++{
23978 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
23979 ++}
23980 ++
23981 ++__u32
23982 ++gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
23983 ++{
23984 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
23985 ++}
23986 ++
23987 ++__u32
23988 ++gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
23989 ++ mode_t mode)
23990 ++{
23991 ++ if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
23992 ++ return 1;
23993 ++
23994 ++ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
23995 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
23996 ++ GR_FCHMOD_ACL_MSG);
23997 ++ } else {
23998 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
23999 ++ }
24000 ++}
24001 ++
24002 ++__u32
24003 ++gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
24004 ++ mode_t mode)
24005 ++{
24006 ++ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
24007 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
24008 ++ GR_CHMOD_ACL_MSG);
24009 ++ } else {
24010 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
24011 ++ }
24012 ++}
24013 ++
24014 ++__u32
24015 ++gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
24016 ++{
24017 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
24018 ++}
24019 ++
24020 ++__u32
24021 ++gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
24022 ++{
24023 ++ return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
24024 ++}
24025 ++
24026 ++__u32
24027 ++gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
24028 ++{
24029 ++ return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
24030 ++ GR_UNIXCONNECT_ACL_MSG);
24031 ++}
24032 ++
24033 ++/* hardlinks require at minimum create permission,
24034 ++ any additional privilege required is based on the
24035 ++ privilege of the file being linked to
24036 ++*/
24037 ++__u32
24038 ++gr_acl_handle_link(const struct dentry * new_dentry,
24039 ++ const struct dentry * parent_dentry,
24040 ++ const struct vfsmount * parent_mnt,
24041 ++ const struct dentry * old_dentry,
24042 ++ const struct vfsmount * old_mnt, const char *to)
24043 ++{
24044 ++ __u32 mode;
24045 ++ __u32 needmode = GR_CREATE | GR_LINK;
24046 ++ __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
24047 ++
24048 ++ mode =
24049 ++ gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
24050 ++ old_mnt);
24051 ++
24052 ++ if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
24053 ++ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
24054 ++ return mode;
24055 ++ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
24056 ++ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
24057 ++ return 0;
24058 ++ } else if (unlikely((mode & needmode) != needmode))
24059 ++ return 0;
24060 ++
24061 ++ return 1;
24062 ++}
24063 ++
24064 ++__u32
24065 ++gr_acl_handle_symlink(const struct dentry * new_dentry,
24066 ++ const struct dentry * parent_dentry,
24067 ++ const struct vfsmount * parent_mnt, const char *from)
24068 ++{
24069 ++ __u32 needmode = GR_WRITE | GR_CREATE;
24070 ++ __u32 mode;
24071 ++
24072 ++ mode =
24073 ++ gr_check_create(new_dentry, parent_dentry, parent_mnt,
24074 ++ GR_CREATE | GR_AUDIT_CREATE |
24075 ++ GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
24076 ++
24077 ++ if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
24078 ++ gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
24079 ++ return mode;
24080 ++ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
24081 ++ gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
24082 ++ return 0;
24083 ++ } else if (unlikely((mode & needmode) != needmode))
24084 ++ return 0;
24085 ++
24086 ++ return (GR_WRITE | GR_CREATE);
24087 ++}
24088 ++
24089 ++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)
24090 ++{
24091 ++ __u32 mode;
24092 ++
24093 ++ mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
24094 ++
24095 ++ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
24096 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
24097 ++ return mode;
24098 ++ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
24099 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
24100 ++ return 0;
24101 ++ } else if (unlikely((mode & (reqmode)) != (reqmode)))
24102 ++ return 0;
24103 ++
24104 ++ return (reqmode);
24105 ++}
24106 ++
24107 ++__u32
24108 ++gr_acl_handle_mknod(const struct dentry * new_dentry,
24109 ++ const struct dentry * parent_dentry,
24110 ++ const struct vfsmount * parent_mnt,
24111 ++ const int mode)
24112 ++{
24113 ++ __u32 reqmode = GR_WRITE | GR_CREATE;
24114 ++ if (unlikely(mode & (S_ISUID | S_ISGID)))
24115 ++ reqmode |= GR_SETID;
24116 ++
24117 ++ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
24118 ++ reqmode, GR_MKNOD_ACL_MSG);
24119 ++}
24120 ++
24121 ++__u32
24122 ++gr_acl_handle_mkdir(const struct dentry *new_dentry,
24123 ++ const struct dentry *parent_dentry,
24124 ++ const struct vfsmount *parent_mnt)
24125 ++{
24126 ++ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
24127 ++ GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
24128 ++}
24129 ++
24130 ++#define RENAME_CHECK_SUCCESS(old, new) \
24131 ++ (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
24132 ++ ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
24133 ++
24134 ++int
24135 ++gr_acl_handle_rename(struct dentry *new_dentry,
24136 ++ struct dentry *parent_dentry,
24137 ++ const struct vfsmount *parent_mnt,
24138 ++ struct dentry *old_dentry,
24139 ++ struct inode *old_parent_inode,
24140 ++ struct vfsmount *old_mnt, const char *newname)
24141 ++{
24142 ++ __u32 comp1, comp2;
24143 ++ int error = 0;
24144 ++
24145 ++ if (unlikely(!gr_acl_is_enabled()))
24146 ++ return 0;
24147 ++
24148 ++ if (!new_dentry->d_inode) {
24149 ++ comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
24150 ++ GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
24151 ++ GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
24152 ++ comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
24153 ++ GR_DELETE | GR_AUDIT_DELETE |
24154 ++ GR_AUDIT_READ | GR_AUDIT_WRITE |
24155 ++ GR_SUPPRESS, old_mnt);
24156 ++ } else {
24157 ++ comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
24158 ++ GR_CREATE | GR_DELETE |
24159 ++ GR_AUDIT_CREATE | GR_AUDIT_DELETE |
24160 ++ GR_AUDIT_READ | GR_AUDIT_WRITE |
24161 ++ GR_SUPPRESS, parent_mnt);
24162 ++ comp2 =
24163 ++ gr_search_file(old_dentry,
24164 ++ GR_READ | GR_WRITE | GR_AUDIT_READ |
24165 ++ GR_DELETE | GR_AUDIT_DELETE |
24166 ++ GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
24167 ++ }
24168 ++
24169 ++ if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
24170 ++ ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
24171 ++ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
24172 ++ else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
24173 ++ && !(comp2 & GR_SUPPRESS)) {
24174 ++ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
24175 ++ error = -EACCES;
24176 ++ } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
24177 ++ error = -EACCES;
24178 ++
24179 ++ return error;
24180 ++}
24181 ++
24182 ++void
24183 ++gr_acl_handle_exit(void)
24184 ++{
24185 ++ u16 id;
24186 ++ char *rolename;
24187 ++ struct file *exec_file;
24188 ++
24189 ++ if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
24190 ++ id = current->acl_role_id;
24191 ++ rolename = current->role->rolename;
24192 ++ gr_set_acls(1);
24193 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
24194 ++ }
24195 ++
24196 ++ write_lock(&grsec_exec_file_lock);
24197 ++ exec_file = current->exec_file;
24198 ++ current->exec_file = NULL;
24199 ++ write_unlock(&grsec_exec_file_lock);
24200 ++
24201 ++ if (exec_file)
24202 ++ fput(exec_file);
24203 ++}
24204 ++
24205 ++int
24206 ++gr_acl_handle_procpidmem(const struct task_struct *task)
24207 ++{
24208 ++ if (unlikely(!gr_acl_is_enabled()))
24209 ++ return 0;
24210 ++
24211 ++ if (task != current && task->acl->mode & GR_PROTPROCFD)
24212 ++ return -EACCES;
24213 ++
24214 ++ return 0;
24215 ++}
24216 +diff -urNp linux-2.6.26.6/grsecurity/gracl_ip.c linux-2.6.26.6/grsecurity/gracl_ip.c
24217 +--- linux-2.6.26.6/grsecurity/gracl_ip.c 1969-12-31 19:00:00.000000000 -0500
24218 ++++ linux-2.6.26.6/grsecurity/gracl_ip.c 2008-10-11 21:54:20.000000000 -0400
24219 +@@ -0,0 +1,313 @@
24220 ++#include <linux/kernel.h>
24221 ++#include <asm/uaccess.h>
24222 ++#include <asm/errno.h>
24223 ++#include <net/sock.h>
24224 ++#include <linux/file.h>
24225 ++#include <linux/fs.h>
24226 ++#include <linux/net.h>
24227 ++#include <linux/in.h>
24228 ++#include <linux/skbuff.h>
24229 ++#include <linux/ip.h>
24230 ++#include <linux/udp.h>
24231 ++#include <linux/smp_lock.h>
24232 ++#include <linux/types.h>
24233 ++#include <linux/sched.h>
24234 ++#include <linux/netdevice.h>
24235 ++#include <linux/inetdevice.h>
24236 ++#include <linux/gracl.h>
24237 ++#include <linux/grsecurity.h>
24238 ++#include <linux/grinternal.h>
24239 ++
24240 ++#define GR_BIND 0x01
24241 ++#define GR_CONNECT 0x02
24242 ++#define GR_INVERT 0x04
24243 ++
24244 ++static const char * gr_protocols[256] = {
24245 ++ "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
24246 ++ "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
24247 ++ "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
24248 ++ "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
24249 ++ "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
24250 ++ "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
24251 ++ "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
24252 ++ "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
24253 ++ "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
24254 ++ "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
24255 ++ "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
24256 ++ "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
24257 ++ "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
24258 ++ "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
24259 ++ "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
24260 ++ "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
24261 ++ "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
24262 ++ "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
24263 ++ "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
24264 ++ "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
24265 ++ "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
24266 ++ "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
24267 ++ "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
24268 ++ "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
24269 ++ "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
24270 ++ "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
24271 ++ "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
24272 ++ "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
24273 ++ "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
24274 ++ "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
24275 ++ "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
24276 ++ "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
24277 ++ };
24278 ++
24279 ++static const char * gr_socktypes[11] = {
24280 ++ "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
24281 ++ "unknown:7", "unknown:8", "unknown:9", "packet"
24282 ++ };
24283 ++
24284 ++const char *
24285 ++gr_proto_to_name(unsigned char proto)
24286 ++{
24287 ++ return gr_protocols[proto];
24288 ++}
24289 ++
24290 ++const char *
24291 ++gr_socktype_to_name(unsigned char type)
24292 ++{
24293 ++ return gr_socktypes[type];
24294 ++}
24295 ++
24296 ++int
24297 ++gr_search_socket(const int domain, const int type, const int protocol)
24298 ++{
24299 ++ struct acl_subject_label *curr;
24300 ++
24301 ++ if (unlikely(!gr_acl_is_enabled()))
24302 ++ goto exit;
24303 ++
24304 ++ if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
24305 ++ || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
24306 ++ goto exit; // let the kernel handle it
24307 ++
24308 ++ curr = current->acl;
24309 ++
24310 ++ if (!curr->ips)
24311 ++ goto exit;
24312 ++
24313 ++ if ((curr->ip_type & (1 << type)) &&
24314 ++ (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
24315 ++ goto exit;
24316 ++
24317 ++ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
24318 ++ /* we don't place acls on raw sockets , and sometimes
24319 ++ dgram/ip sockets are opened for ioctl and not
24320 ++ bind/connect, so we'll fake a bind learn log */
24321 ++ if (type == SOCK_RAW || type == SOCK_PACKET) {
24322 ++ __u32 fakeip = 0;
24323 ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
24324 ++ current->role->roletype, current->uid,
24325 ++ current->gid, current->exec_file ?
24326 ++ gr_to_filename(current->exec_file->f_path.dentry,
24327 ++ current->exec_file->f_path.mnt) :
24328 ++ curr->filename, curr->filename,
24329 ++ NIPQUAD(fakeip), 0, type,
24330 ++ protocol, GR_CONNECT,
24331 ++NIPQUAD(current->signal->curr_ip));
24332 ++ } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
24333 ++ __u32 fakeip = 0;
24334 ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
24335 ++ current->role->roletype, current->uid,
24336 ++ current->gid, current->exec_file ?
24337 ++ gr_to_filename(current->exec_file->f_path.dentry,
24338 ++ current->exec_file->f_path.mnt) :
24339 ++ curr->filename, curr->filename,
24340 ++ NIPQUAD(fakeip), 0, type,
24341 ++ protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
24342 ++ }
24343 ++ /* we'll log when they use connect or bind */
24344 ++ goto exit;
24345 ++ }
24346 ++
24347 ++ gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet",
24348 ++ gr_socktype_to_name(type), gr_proto_to_name(protocol));
24349 ++
24350 ++ return 0;
24351 ++ exit:
24352 ++ return 1;
24353 ++}
24354 ++
24355 ++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)
24356 ++{
24357 ++ if ((ip->mode & mode) &&
24358 ++ (ip_port >= ip->low) &&
24359 ++ (ip_port <= ip->high) &&
24360 ++ ((ntohl(ip_addr) & our_netmask) ==
24361 ++ (ntohl(our_addr) & our_netmask))
24362 ++ && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
24363 ++ && (ip->type & (1 << type))) {
24364 ++ if (ip->mode & GR_INVERT)
24365 ++ return 2; // specifically denied
24366 ++ else
24367 ++ return 1; // allowed
24368 ++ }
24369 ++
24370 ++ return 0; // not specifically allowed, may continue parsing
24371 ++}
24372 ++
24373 ++static int
24374 ++gr_search_connectbind(const int mode, const struct sock *sk,
24375 ++ const struct sockaddr_in *addr, const int type)
24376 ++{
24377 ++ char iface[IFNAMSIZ] = {0};
24378 ++ struct acl_subject_label *curr;
24379 ++ struct acl_ip_label *ip;
24380 ++ struct net_device *dev;
24381 ++ struct in_device *idev;
24382 ++ unsigned long i;
24383 ++ int ret;
24384 ++ __u32 ip_addr = 0;
24385 ++ __u32 our_addr;
24386 ++ __u32 our_netmask;
24387 ++ char *p;
24388 ++ __u16 ip_port = 0;
24389 ++
24390 ++ if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
24391 ++ return 1;
24392 ++
24393 ++ curr = current->acl;
24394 ++
24395 ++ if (!curr->ips)
24396 ++ return 1;
24397 ++
24398 ++ ip_addr = addr->sin_addr.s_addr;
24399 ++ ip_port = ntohs(addr->sin_port);
24400 ++
24401 ++ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
24402 ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
24403 ++ current->role->roletype, current->uid,
24404 ++ current->gid, current->exec_file ?
24405 ++ gr_to_filename(current->exec_file->f_path.dentry,
24406 ++ current->exec_file->f_path.mnt) :
24407 ++ curr->filename, curr->filename,
24408 ++ NIPQUAD(ip_addr), ip_port, type,
24409 ++ sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
24410 ++ return 1;
24411 ++ }
24412 ++
24413 ++ for (i = 0; i < curr->ip_num; i++) {
24414 ++ ip = *(curr->ips + i);
24415 ++ if (ip->iface != NULL) {
24416 ++ strncpy(iface, ip->iface, IFNAMSIZ - 1);
24417 ++ p = strchr(iface, ':');
24418 ++ if (p != NULL)
24419 ++ *p = '\0';
24420 ++ dev = dev_get_by_name(sock_net(sk), iface);
24421 ++ if (dev == NULL)
24422 ++ continue;
24423 ++ idev = in_dev_get(dev);
24424 ++ if (idev == NULL) {
24425 ++ dev_put(dev);
24426 ++ continue;
24427 ++ }
24428 ++ rcu_read_lock();
24429 ++ for_ifa(idev) {
24430 ++ if (!strcmp(ip->iface, ifa->ifa_label)) {
24431 ++ our_addr = ifa->ifa_address;
24432 ++ our_netmask = 0xffffffff;
24433 ++ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
24434 ++ if (ret == 1) {
24435 ++ rcu_read_unlock();
24436 ++ in_dev_put(idev);
24437 ++ dev_put(dev);
24438 ++ return 1;
24439 ++ } else if (ret == 2) {
24440 ++ rcu_read_unlock();
24441 ++ in_dev_put(idev);
24442 ++ dev_put(dev);
24443 ++ goto denied;
24444 ++ }
24445 ++ }
24446 ++ } endfor_ifa(idev);
24447 ++ rcu_read_unlock();
24448 ++ in_dev_put(idev);
24449 ++ dev_put(dev);
24450 ++ } else {
24451 ++ our_addr = ip->addr;
24452 ++ our_netmask = ip->netmask;
24453 ++ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
24454 ++ if (ret == 1)
24455 ++ return 1;
24456 ++ else if (ret == 2)
24457 ++ goto denied;
24458 ++ }
24459 ++ }
24460 ++
24461 ++denied:
24462 ++ if (mode == GR_BIND)
24463 ++ 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));
24464 ++ else if (mode == GR_CONNECT)
24465 ++ 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));
24466 ++
24467 ++ return 0;
24468 ++}
24469 ++
24470 ++int
24471 ++gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
24472 ++{
24473 ++ return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
24474 ++}
24475 ++
24476 ++int
24477 ++gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
24478 ++{
24479 ++ return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
24480 ++}
24481 ++
24482 ++int gr_search_listen(const struct socket *sock)
24483 ++{
24484 ++ struct sock *sk = sock->sk;
24485 ++ struct sockaddr_in addr;
24486 ++
24487 ++ addr.sin_addr.s_addr = inet_sk(sk)->saddr;
24488 ++ addr.sin_port = inet_sk(sk)->sport;
24489 ++
24490 ++ return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
24491 ++}
24492 ++
24493 ++int gr_search_accept(const struct socket *sock)
24494 ++{
24495 ++ struct sock *sk = sock->sk;
24496 ++ struct sockaddr_in addr;
24497 ++
24498 ++ addr.sin_addr.s_addr = inet_sk(sk)->saddr;
24499 ++ addr.sin_port = inet_sk(sk)->sport;
24500 ++
24501 ++ return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
24502 ++}
24503 ++
24504 ++int
24505 ++gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
24506 ++{
24507 ++ if (addr)
24508 ++ return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
24509 ++ else {
24510 ++ struct sockaddr_in sin;
24511 ++ const struct inet_sock *inet = inet_sk(sk);
24512 ++
24513 ++ sin.sin_addr.s_addr = inet->daddr;
24514 ++ sin.sin_port = inet->dport;
24515 ++
24516 ++ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
24517 ++ }
24518 ++}
24519 ++
24520 ++int
24521 ++gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
24522 ++{
24523 ++ struct sockaddr_in sin;
24524 ++
24525 ++ if (unlikely(skb->len < sizeof (struct udphdr)))
24526 ++ return 1; // skip this packet
24527 ++
24528 ++ sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
24529 ++ sin.sin_port = udp_hdr(skb)->source;
24530 ++
24531 ++ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
24532 ++}
24533 +diff -urNp linux-2.6.26.6/grsecurity/gracl_learn.c linux-2.6.26.6/grsecurity/gracl_learn.c
24534 +--- linux-2.6.26.6/grsecurity/gracl_learn.c 1969-12-31 19:00:00.000000000 -0500
24535 ++++ linux-2.6.26.6/grsecurity/gracl_learn.c 2008-10-11 21:54:20.000000000 -0400
24536 +@@ -0,0 +1,211 @@
24537 ++#include <linux/kernel.h>
24538 ++#include <linux/mm.h>
24539 ++#include <linux/sched.h>
24540 ++#include <linux/poll.h>
24541 ++#include <linux/smp_lock.h>
24542 ++#include <linux/string.h>
24543 ++#include <linux/file.h>
24544 ++#include <linux/types.h>
24545 ++#include <linux/vmalloc.h>
24546 ++#include <linux/grinternal.h>
24547 ++
24548 ++extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
24549 ++ size_t count, loff_t *ppos);
24550 ++extern int gr_acl_is_enabled(void);
24551 ++
24552 ++static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
24553 ++static int gr_learn_attached;
24554 ++
24555 ++/* use a 512k buffer */
24556 ++#define LEARN_BUFFER_SIZE (512 * 1024)
24557 ++
24558 ++static DEFINE_SPINLOCK(gr_learn_lock);
24559 ++static DECLARE_MUTEX(gr_learn_user_sem);
24560 ++
24561 ++/* we need to maintain two buffers, so that the kernel context of grlearn
24562 ++ uses a semaphore around the userspace copying, and the other kernel contexts
24563 ++ use a spinlock when copying into the buffer, since they cannot sleep
24564 ++*/
24565 ++static char *learn_buffer;
24566 ++static char *learn_buffer_user;
24567 ++static int learn_buffer_len;
24568 ++static int learn_buffer_user_len;
24569 ++
24570 ++static ssize_t
24571 ++read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
24572 ++{
24573 ++ DECLARE_WAITQUEUE(wait, current);
24574 ++ ssize_t retval = 0;
24575 ++
24576 ++ add_wait_queue(&learn_wait, &wait);
24577 ++ set_current_state(TASK_INTERRUPTIBLE);
24578 ++ do {
24579 ++ down(&gr_learn_user_sem);
24580 ++ spin_lock(&gr_learn_lock);
24581 ++ if (learn_buffer_len)
24582 ++ break;
24583 ++ spin_unlock(&gr_learn_lock);
24584 ++ up(&gr_learn_user_sem);
24585 ++ if (file->f_flags & O_NONBLOCK) {
24586 ++ retval = -EAGAIN;
24587 ++ goto out;
24588 ++ }
24589 ++ if (signal_pending(current)) {
24590 ++ retval = -ERESTARTSYS;
24591 ++ goto out;
24592 ++ }
24593 ++
24594 ++ schedule();
24595 ++ } while (1);
24596 ++
24597 ++ memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
24598 ++ learn_buffer_user_len = learn_buffer_len;
24599 ++ retval = learn_buffer_len;
24600 ++ learn_buffer_len = 0;
24601 ++
24602 ++ spin_unlock(&gr_learn_lock);
24603 ++
24604 ++ if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
24605 ++ retval = -EFAULT;
24606 ++
24607 ++ up(&gr_learn_user_sem);
24608 ++out:
24609 ++ set_current_state(TASK_RUNNING);
24610 ++ remove_wait_queue(&learn_wait, &wait);
24611 ++ return retval;
24612 ++}
24613 ++
24614 ++static unsigned int
24615 ++poll_learn(struct file * file, poll_table * wait)
24616 ++{
24617 ++ poll_wait(file, &learn_wait, wait);
24618 ++
24619 ++ if (learn_buffer_len)
24620 ++ return (POLLIN | POLLRDNORM);
24621 ++
24622 ++ return 0;
24623 ++}
24624 ++
24625 ++void
24626 ++gr_clear_learn_entries(void)
24627 ++{
24628 ++ char *tmp;
24629 ++
24630 ++ down(&gr_learn_user_sem);
24631 ++ if (learn_buffer != NULL) {
24632 ++ spin_lock(&gr_learn_lock);
24633 ++ tmp = learn_buffer;
24634 ++ learn_buffer = NULL;
24635 ++ spin_unlock(&gr_learn_lock);
24636 ++ vfree(learn_buffer);
24637 ++ }
24638 ++ if (learn_buffer_user != NULL) {
24639 ++ vfree(learn_buffer_user);
24640 ++ learn_buffer_user = NULL;
24641 ++ }
24642 ++ learn_buffer_len = 0;
24643 ++ up(&gr_learn_user_sem);
24644 ++
24645 ++ return;
24646 ++}
24647 ++
24648 ++void
24649 ++gr_add_learn_entry(const char *fmt, ...)
24650 ++{
24651 ++ va_list args;
24652 ++ unsigned int len;
24653 ++
24654 ++ if (!gr_learn_attached)
24655 ++ return;
24656 ++
24657 ++ spin_lock(&gr_learn_lock);
24658 ++
24659 ++ /* leave a gap at the end so we know when it's "full" but don't have to
24660 ++ compute the exact length of the string we're trying to append
24661 ++ */
24662 ++ if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
24663 ++ spin_unlock(&gr_learn_lock);
24664 ++ wake_up_interruptible(&learn_wait);
24665 ++ return;
24666 ++ }
24667 ++ if (learn_buffer == NULL) {
24668 ++ spin_unlock(&gr_learn_lock);
24669 ++ return;
24670 ++ }
24671 ++
24672 ++ va_start(args, fmt);
24673 ++ len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
24674 ++ va_end(args);
24675 ++
24676 ++ learn_buffer_len += len + 1;
24677 ++
24678 ++ spin_unlock(&gr_learn_lock);
24679 ++ wake_up_interruptible(&learn_wait);
24680 ++
24681 ++ return;
24682 ++}
24683 ++
24684 ++static int
24685 ++open_learn(struct inode *inode, struct file *file)
24686 ++{
24687 ++ if (file->f_mode & FMODE_READ && gr_learn_attached)
24688 ++ return -EBUSY;
24689 ++ if (file->f_mode & FMODE_READ) {
24690 ++ int retval = 0;
24691 ++ down(&gr_learn_user_sem);
24692 ++ if (learn_buffer == NULL)
24693 ++ learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
24694 ++ if (learn_buffer_user == NULL)
24695 ++ learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
24696 ++ if (learn_buffer == NULL) {
24697 ++ retval = -ENOMEM;
24698 ++ goto out_error;
24699 ++ }
24700 ++ if (learn_buffer_user == NULL) {
24701 ++ retval = -ENOMEM;
24702 ++ goto out_error;
24703 ++ }
24704 ++ learn_buffer_len = 0;
24705 ++ learn_buffer_user_len = 0;
24706 ++ gr_learn_attached = 1;
24707 ++out_error:
24708 ++ up(&gr_learn_user_sem);
24709 ++ return retval;
24710 ++ }
24711 ++ return 0;
24712 ++}
24713 ++
24714 ++static int
24715 ++close_learn(struct inode *inode, struct file *file)
24716 ++{
24717 ++ char *tmp;
24718 ++
24719 ++ if (file->f_mode & FMODE_READ) {
24720 ++ down(&gr_learn_user_sem);
24721 ++ if (learn_buffer != NULL) {
24722 ++ spin_lock(&gr_learn_lock);
24723 ++ tmp = learn_buffer;
24724 ++ learn_buffer = NULL;
24725 ++ spin_unlock(&gr_learn_lock);
24726 ++ vfree(tmp);
24727 ++ }
24728 ++ if (learn_buffer_user != NULL) {
24729 ++ vfree(learn_buffer_user);
24730 ++ learn_buffer_user = NULL;
24731 ++ }
24732 ++ learn_buffer_len = 0;
24733 ++ learn_buffer_user_len = 0;
24734 ++ gr_learn_attached = 0;
24735 ++ up(&gr_learn_user_sem);
24736 ++ }
24737 ++
24738 ++ return 0;
24739 ++}
24740 ++
24741 ++struct file_operations grsec_fops = {
24742 ++ .read = read_learn,
24743 ++ .write = write_grsec_handler,
24744 ++ .open = open_learn,
24745 ++ .release = close_learn,
24746 ++ .poll = poll_learn,
24747 ++};
24748 +diff -urNp linux-2.6.26.6/grsecurity/gracl_res.c linux-2.6.26.6/grsecurity/gracl_res.c
24749 +--- linux-2.6.26.6/grsecurity/gracl_res.c 1969-12-31 19:00:00.000000000 -0500
24750 ++++ linux-2.6.26.6/grsecurity/gracl_res.c 2008-10-11 21:54:20.000000000 -0400
24751 +@@ -0,0 +1,45 @@
24752 ++#include <linux/kernel.h>
24753 ++#include <linux/sched.h>
24754 ++#include <linux/gracl.h>
24755 ++#include <linux/grinternal.h>
24756 ++
24757 ++static const char *restab_log[] = {
24758 ++ [RLIMIT_CPU] = "RLIMIT_CPU",
24759 ++ [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
24760 ++ [RLIMIT_DATA] = "RLIMIT_DATA",
24761 ++ [RLIMIT_STACK] = "RLIMIT_STACK",
24762 ++ [RLIMIT_CORE] = "RLIMIT_CORE",
24763 ++ [RLIMIT_RSS] = "RLIMIT_RSS",
24764 ++ [RLIMIT_NPROC] = "RLIMIT_NPROC",
24765 ++ [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
24766 ++ [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
24767 ++ [RLIMIT_AS] = "RLIMIT_AS",
24768 ++ [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
24769 ++ [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH"
24770 ++};
24771 ++
24772 ++void
24773 ++gr_log_resource(const struct task_struct *task,
24774 ++ const int res, const unsigned long wanted, const int gt)
24775 ++{
24776 ++ if (res == RLIMIT_NPROC &&
24777 ++ (cap_raised(task->cap_effective, CAP_SYS_ADMIN) ||
24778 ++ cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
24779 ++ return;
24780 ++ else if (res == RLIMIT_MEMLOCK &&
24781 ++ cap_raised(task->cap_effective, CAP_IPC_LOCK))
24782 ++ return;
24783 ++
24784 ++ if (!gr_acl_is_enabled() && !grsec_resource_logging)
24785 ++ return;
24786 ++
24787 ++ preempt_disable();
24788 ++
24789 ++ if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
24790 ++ (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
24791 ++ task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
24792 ++ gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
24793 ++ preempt_enable_no_resched();
24794 ++
24795 ++ return;
24796 ++}
24797 +diff -urNp linux-2.6.26.6/grsecurity/gracl_segv.c linux-2.6.26.6/grsecurity/gracl_segv.c
24798 +--- linux-2.6.26.6/grsecurity/gracl_segv.c 1969-12-31 19:00:00.000000000 -0500
24799 ++++ linux-2.6.26.6/grsecurity/gracl_segv.c 2008-10-11 21:54:20.000000000 -0400
24800 +@@ -0,0 +1,304 @@
24801 ++#include <linux/kernel.h>
24802 ++#include <linux/mm.h>
24803 ++#include <asm/uaccess.h>
24804 ++#include <asm/errno.h>
24805 ++#include <asm/mman.h>
24806 ++#include <net/sock.h>
24807 ++#include <linux/file.h>
24808 ++#include <linux/fs.h>
24809 ++#include <linux/net.h>
24810 ++#include <linux/in.h>
24811 ++#include <linux/smp_lock.h>
24812 ++#include <linux/slab.h>
24813 ++#include <linux/types.h>
24814 ++#include <linux/sched.h>
24815 ++#include <linux/timer.h>
24816 ++#include <linux/gracl.h>
24817 ++#include <linux/grsecurity.h>
24818 ++#include <linux/grinternal.h>
24819 ++
24820 ++static struct crash_uid *uid_set;
24821 ++static unsigned short uid_used;
24822 ++static DEFINE_SPINLOCK(gr_uid_lock);
24823 ++extern rwlock_t gr_inode_lock;
24824 ++extern struct acl_subject_label *
24825 ++ lookup_acl_subj_label(const ino_t inode, const dev_t dev,
24826 ++ struct acl_role_label *role);
24827 ++extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
24828 ++
24829 ++int
24830 ++gr_init_uidset(void)
24831 ++{
24832 ++ uid_set =
24833 ++ kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
24834 ++ uid_used = 0;
24835 ++
24836 ++ return uid_set ? 1 : 0;
24837 ++}
24838 ++
24839 ++void
24840 ++gr_free_uidset(void)
24841 ++{
24842 ++ if (uid_set)
24843 ++ kfree(uid_set);
24844 ++
24845 ++ return;
24846 ++}
24847 ++
24848 ++int
24849 ++gr_find_uid(const uid_t uid)
24850 ++{
24851 ++ struct crash_uid *tmp = uid_set;
24852 ++ uid_t buid;
24853 ++ int low = 0, high = uid_used - 1, mid;
24854 ++
24855 ++ while (high >= low) {
24856 ++ mid = (low + high) >> 1;
24857 ++ buid = tmp[mid].uid;
24858 ++ if (buid == uid)
24859 ++ return mid;
24860 ++ if (buid > uid)
24861 ++ high = mid - 1;
24862 ++ if (buid < uid)
24863 ++ low = mid + 1;
24864 ++ }
24865 ++
24866 ++ return -1;
24867 ++}
24868 ++
24869 ++static __inline__ void
24870 ++gr_insertsort(void)
24871 ++{
24872 ++ unsigned short i, j;
24873 ++ struct crash_uid index;
24874 ++
24875 ++ for (i = 1; i < uid_used; i++) {
24876 ++ index = uid_set[i];
24877 ++ j = i;
24878 ++ while ((j > 0) && uid_set[j - 1].uid > index.uid) {
24879 ++ uid_set[j] = uid_set[j - 1];
24880 ++ j--;
24881 ++ }
24882 ++ uid_set[j] = index;
24883 ++ }
24884 ++
24885 ++ return;
24886 ++}
24887 ++
24888 ++static __inline__ void
24889 ++gr_insert_uid(const uid_t uid, const unsigned long expires)
24890 ++{
24891 ++ int loc;
24892 ++
24893 ++ if (uid_used == GR_UIDTABLE_MAX)
24894 ++ return;
24895 ++
24896 ++ loc = gr_find_uid(uid);
24897 ++
24898 ++ if (loc >= 0) {
24899 ++ uid_set[loc].expires = expires;
24900 ++ return;
24901 ++ }
24902 ++
24903 ++ uid_set[uid_used].uid = uid;
24904 ++ uid_set[uid_used].expires = expires;
24905 ++ uid_used++;
24906 ++
24907 ++ gr_insertsort();
24908 ++
24909 ++ return;
24910 ++}
24911 ++
24912 ++void
24913 ++gr_remove_uid(const unsigned short loc)
24914 ++{
24915 ++ unsigned short i;
24916 ++
24917 ++ for (i = loc + 1; i < uid_used; i++)
24918 ++ uid_set[i - 1] = uid_set[i];
24919 ++
24920 ++ uid_used--;
24921 ++
24922 ++ return;
24923 ++}
24924 ++
24925 ++int
24926 ++gr_check_crash_uid(const uid_t uid)
24927 ++{
24928 ++ int loc;
24929 ++ int ret = 0;
24930 ++
24931 ++ if (unlikely(!gr_acl_is_enabled()))
24932 ++ return 0;
24933 ++
24934 ++ spin_lock(&gr_uid_lock);
24935 ++ loc = gr_find_uid(uid);
24936 ++
24937 ++ if (loc < 0)
24938 ++ goto out_unlock;
24939 ++
24940 ++ if (time_before_eq(uid_set[loc].expires, get_seconds()))
24941 ++ gr_remove_uid(loc);
24942 ++ else
24943 ++ ret = 1;
24944 ++
24945 ++out_unlock:
24946 ++ spin_unlock(&gr_uid_lock);
24947 ++ return ret;
24948 ++}
24949 ++
24950 ++static __inline__ int
24951 ++proc_is_setxid(const struct task_struct *task)
24952 ++{
24953 ++ if (task->uid != task->euid || task->uid != task->suid ||
24954 ++ task->uid != task->fsuid)
24955 ++ return 1;
24956 ++ if (task->gid != task->egid || task->gid != task->sgid ||
24957 ++ task->gid != task->fsgid)
24958 ++ return 1;
24959 ++
24960 ++ return 0;
24961 ++}
24962 ++static __inline__ int
24963 ++gr_fake_force_sig(int sig, struct task_struct *t)
24964 ++{
24965 ++ unsigned long int flags;
24966 ++ int ret, blocked, ignored;
24967 ++ struct k_sigaction *action;
24968 ++
24969 ++ spin_lock_irqsave(&t->sighand->siglock, flags);
24970 ++ action = &t->sighand->action[sig-1];
24971 ++ ignored = action->sa.sa_handler == SIG_IGN;
24972 ++ blocked = sigismember(&t->blocked, sig);
24973 ++ if (blocked || ignored) {
24974 ++ action->sa.sa_handler = SIG_DFL;
24975 ++ if (blocked) {
24976 ++ sigdelset(&t->blocked, sig);
24977 ++ recalc_sigpending_and_wake(t);
24978 ++ }
24979 ++ }
24980 ++ if (action->sa.sa_handler == SIG_DFL)
24981 ++ t->signal->flags &= ~SIGNAL_UNKILLABLE;
24982 ++ ret = specific_send_sig_info(sig, SEND_SIG_PRIV, t);
24983 ++
24984 ++ spin_unlock_irqrestore(&t->sighand->siglock, flags);
24985 ++
24986 ++ return ret;
24987 ++}
24988 ++
24989 ++void
24990 ++gr_handle_crash(struct task_struct *task, const int sig)
24991 ++{
24992 ++ struct acl_subject_label *curr;
24993 ++ struct acl_subject_label *curr2;
24994 ++ struct task_struct *tsk, *tsk2;
24995 ++
24996 ++ if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
24997 ++ return;
24998 ++
24999 ++ if (unlikely(!gr_acl_is_enabled()))
25000 ++ return;
25001 ++
25002 ++ curr = task->acl;
25003 ++
25004 ++ if (!(curr->resmask & (1 << GR_CRASH_RES)))
25005 ++ return;
25006 ++
25007 ++ if (time_before_eq(curr->expires, get_seconds())) {
25008 ++ curr->expires = 0;
25009 ++ curr->crashes = 0;
25010 ++ }
25011 ++
25012 ++ curr->crashes++;
25013 ++
25014 ++ if (!curr->expires)
25015 ++ curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
25016 ++
25017 ++ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
25018 ++ time_after(curr->expires, get_seconds())) {
25019 ++ if (task->uid && proc_is_setxid(task)) {
25020 ++ gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
25021 ++ spin_lock(&gr_uid_lock);
25022 ++ gr_insert_uid(task->uid, curr->expires);
25023 ++ spin_unlock(&gr_uid_lock);
25024 ++ curr->expires = 0;
25025 ++ curr->crashes = 0;
25026 ++ read_lock(&tasklist_lock);
25027 ++ do_each_thread(tsk2, tsk) {
25028 ++ if (tsk != task && tsk->uid == task->uid)
25029 ++ gr_fake_force_sig(SIGKILL, tsk);
25030 ++ } while_each_thread(tsk2, tsk);
25031 ++ read_unlock(&tasklist_lock);
25032 ++ } else {
25033 ++ gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
25034 ++ read_lock(&tasklist_lock);
25035 ++ do_each_thread(tsk2, tsk) {
25036 ++ if (likely(tsk != task)) {
25037 ++ curr2 = tsk->acl;
25038 ++
25039 ++ if (curr2->device == curr->device &&
25040 ++ curr2->inode == curr->inode)
25041 ++ gr_fake_force_sig(SIGKILL, tsk);
25042 ++ }
25043 ++ } while_each_thread(tsk2, tsk);
25044 ++ read_unlock(&tasklist_lock);
25045 ++ }
25046 ++ }
25047 ++
25048 ++ return;
25049 ++}
25050 ++
25051 ++int
25052 ++gr_check_crash_exec(const struct file *filp)
25053 ++{
25054 ++ struct acl_subject_label *curr;
25055 ++
25056 ++ if (unlikely(!gr_acl_is_enabled()))
25057 ++ return 0;
25058 ++
25059 ++ read_lock(&gr_inode_lock);
25060 ++ curr = lookup_acl_subj_label(filp->f_path.dentry->d_inode->i_ino,
25061 ++ filp->f_path.dentry->d_inode->i_sb->s_dev,
25062 ++ current->role);
25063 ++ read_unlock(&gr_inode_lock);
25064 ++
25065 ++ if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
25066 ++ (!curr->crashes && !curr->expires))
25067 ++ return 0;
25068 ++
25069 ++ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
25070 ++ time_after(curr->expires, get_seconds()))
25071 ++ return 1;
25072 ++ else if (time_before_eq(curr->expires, get_seconds())) {
25073 ++ curr->crashes = 0;
25074 ++ curr->expires = 0;
25075 ++ }
25076 ++
25077 ++ return 0;
25078 ++}
25079 ++
25080 ++void
25081 ++gr_handle_alertkill(struct task_struct *task)
25082 ++{
25083 ++ struct acl_subject_label *curracl;
25084 ++ __u32 curr_ip;
25085 ++ struct task_struct *p, *p2;
25086 ++
25087 ++ if (unlikely(!gr_acl_is_enabled()))
25088 ++ return;
25089 ++
25090 ++ curracl = task->acl;
25091 ++ curr_ip = task->signal->curr_ip;
25092 ++
25093 ++ if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
25094 ++ read_lock(&tasklist_lock);
25095 ++ do_each_thread(p2, p) {
25096 ++ if (p->signal->curr_ip == curr_ip)
25097 ++ gr_fake_force_sig(SIGKILL, p);
25098 ++ } while_each_thread(p2, p);
25099 ++ read_unlock(&tasklist_lock);
25100 ++ } else if (curracl->mode & GR_KILLPROC)
25101 ++ gr_fake_force_sig(SIGKILL, task);
25102 ++
25103 ++ return;
25104 ++}
25105 +diff -urNp linux-2.6.26.6/grsecurity/gracl_shm.c linux-2.6.26.6/grsecurity/gracl_shm.c
25106 +--- linux-2.6.26.6/grsecurity/gracl_shm.c 1969-12-31 19:00:00.000000000 -0500
25107 ++++ linux-2.6.26.6/grsecurity/gracl_shm.c 2008-10-11 21:54:20.000000000 -0400
25108 +@@ -0,0 +1,33 @@
25109 ++#include <linux/kernel.h>
25110 ++#include <linux/mm.h>
25111 ++#include <linux/sched.h>
25112 ++#include <linux/file.h>
25113 ++#include <linux/ipc.h>
25114 ++#include <linux/gracl.h>
25115 ++#include <linux/grsecurity.h>
25116 ++#include <linux/grinternal.h>
25117 ++
25118 ++int
25119 ++gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
25120 ++ const time_t shm_createtime, const uid_t cuid, const int shmid)
25121 ++{
25122 ++ struct task_struct *task;
25123 ++
25124 ++ if (!gr_acl_is_enabled())
25125 ++ return 1;
25126 ++
25127 ++ task = find_task_by_pid(shm_cprid);
25128 ++
25129 ++ if (unlikely(!task))
25130 ++ task = find_task_by_pid(shm_lapid);
25131 ++
25132 ++ if (unlikely(task && (time_before_eq((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
25133 ++ (task->pid == shm_lapid)) &&
25134 ++ (task->acl->mode & GR_PROTSHM) &&
25135 ++ (task->acl != current->acl))) {
25136 ++ gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
25137 ++ return 0;
25138 ++ }
25139 ++
25140 ++ return 1;
25141 ++}
25142 +diff -urNp linux-2.6.26.6/grsecurity/grsec_chdir.c linux-2.6.26.6/grsecurity/grsec_chdir.c
25143 +--- linux-2.6.26.6/grsecurity/grsec_chdir.c 1969-12-31 19:00:00.000000000 -0500
25144 ++++ linux-2.6.26.6/grsecurity/grsec_chdir.c 2008-10-11 21:54:20.000000000 -0400
25145 +@@ -0,0 +1,19 @@
25146 ++#include <linux/kernel.h>
25147 ++#include <linux/sched.h>
25148 ++#include <linux/fs.h>
25149 ++#include <linux/file.h>
25150 ++#include <linux/grsecurity.h>
25151 ++#include <linux/grinternal.h>
25152 ++
25153 ++void
25154 ++gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
25155 ++{
25156 ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
25157 ++ if ((grsec_enable_chdir && grsec_enable_group &&
25158 ++ in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
25159 ++ !grsec_enable_group)) {
25160 ++ gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
25161 ++ }
25162 ++#endif
25163 ++ return;
25164 ++}
25165 +diff -urNp linux-2.6.26.6/grsecurity/grsec_chroot.c linux-2.6.26.6/grsecurity/grsec_chroot.c
25166 +--- linux-2.6.26.6/grsecurity/grsec_chroot.c 1969-12-31 19:00:00.000000000 -0500
25167 ++++ linux-2.6.26.6/grsecurity/grsec_chroot.c 2008-10-11 21:54:20.000000000 -0400
25168 +@@ -0,0 +1,336 @@
25169 ++#include <linux/kernel.h>
25170 ++#include <linux/module.h>
25171 ++#include <linux/sched.h>
25172 ++#include <linux/file.h>
25173 ++#include <linux/fs.h>
25174 ++#include <linux/mount.h>
25175 ++#include <linux/types.h>
25176 ++#include <linux/pid_namespace.h>
25177 ++#include <linux/grsecurity.h>
25178 ++#include <linux/grinternal.h>
25179 ++
25180 ++int
25181 ++gr_handle_chroot_unix(const pid_t pid)
25182 ++{
25183 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
25184 ++ struct pid *spid = NULL;
25185 ++
25186 ++ if (unlikely(!grsec_enable_chroot_unix))
25187 ++ return 1;
25188 ++
25189 ++ if (likely(!proc_is_chrooted(current)))
25190 ++ return 1;
25191 ++
25192 ++ read_lock(&tasklist_lock);
25193 ++
25194 ++ spid = find_pid(pid);
25195 ++ if (spid) {
25196 ++ struct task_struct *p;
25197 ++ p = pid_task(spid, PIDTYPE_PID);
25198 ++ task_lock(p);
25199 ++ if (unlikely(!have_same_root(current, p))) {
25200 ++ task_unlock(p);
25201 ++ read_unlock(&tasklist_lock);
25202 ++ gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
25203 ++ return 0;
25204 ++ }
25205 ++ task_unlock(p);
25206 ++ }
25207 ++ read_unlock(&tasklist_lock);
25208 ++#endif
25209 ++ return 1;
25210 ++}
25211 ++
25212 ++int
25213 ++gr_handle_chroot_nice(void)
25214 ++{
25215 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
25216 ++ if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
25217 ++ gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
25218 ++ return -EPERM;
25219 ++ }
25220 ++#endif
25221 ++ return 0;
25222 ++}
25223 ++
25224 ++int
25225 ++gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
25226 ++{
25227 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
25228 ++ if (grsec_enable_chroot_nice && (niceval < task_nice(p))
25229 ++ && proc_is_chrooted(current)) {
25230 ++ gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
25231 ++ return -EACCES;
25232 ++ }
25233 ++#endif
25234 ++ return 0;
25235 ++}
25236 ++
25237 ++int
25238 ++gr_handle_chroot_rawio(const struct inode *inode)
25239 ++{
25240 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
25241 ++ if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
25242 ++ inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
25243 ++ return 1;
25244 ++#endif
25245 ++ return 0;
25246 ++}
25247 ++
25248 ++int
25249 ++gr_pid_is_chrooted(struct task_struct *p)
25250 ++{
25251 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
25252 ++ if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL)
25253 ++ return 0;
25254 ++
25255 ++ task_lock(p);
25256 ++ if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
25257 ++ !have_same_root(current, p)) {
25258 ++ task_unlock(p);
25259 ++ return 1;
25260 ++ }
25261 ++ task_unlock(p);
25262 ++#endif
25263 ++ return 0;
25264 ++}
25265 ++
25266 ++EXPORT_SYMBOL(gr_pid_is_chrooted);
25267 ++
25268 ++#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
25269 ++int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
25270 ++{
25271 ++ struct dentry *dentry = (struct dentry *)u_dentry;
25272 ++ struct vfsmount *mnt = (struct vfsmount *)u_mnt;
25273 ++ struct dentry *realroot;
25274 ++ struct vfsmount *realrootmnt;
25275 ++ struct dentry *currentroot;
25276 ++ struct vfsmount *currentmnt;
25277 ++ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
25278 ++ int ret = 1;
25279 ++
25280 ++ read_lock(&reaper->fs->lock);
25281 ++ realrootmnt = mntget(reaper->fs->root.mnt);
25282 ++ realroot = dget(reaper->fs->root.dentry);
25283 ++ read_unlock(&reaper->fs->lock);
25284 ++
25285 ++ read_lock(&current->fs->lock);
25286 ++ currentmnt = mntget(current->fs->root.mnt);
25287 ++ currentroot = dget(current->fs->root.dentry);
25288 ++ read_unlock(&current->fs->lock);
25289 ++
25290 ++ spin_lock(&dcache_lock);
25291 ++ for (;;) {
25292 ++ if (unlikely((dentry == realroot && mnt == realrootmnt)
25293 ++ || (dentry == currentroot && mnt == currentmnt)))
25294 ++ break;
25295 ++ if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
25296 ++ if (mnt->mnt_parent == mnt)
25297 ++ break;
25298 ++ dentry = mnt->mnt_mountpoint;
25299 ++ mnt = mnt->mnt_parent;
25300 ++ continue;
25301 ++ }
25302 ++ dentry = dentry->d_parent;
25303 ++ }
25304 ++ spin_unlock(&dcache_lock);
25305 ++
25306 ++ dput(currentroot);
25307 ++ mntput(currentmnt);
25308 ++
25309 ++ /* access is outside of chroot */
25310 ++ if (dentry == realroot && mnt == realrootmnt)
25311 ++ ret = 0;
25312 ++
25313 ++ dput(realroot);
25314 ++ mntput(realrootmnt);
25315 ++ return ret;
25316 ++}
25317 ++#endif
25318 ++
25319 ++int
25320 ++gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
25321 ++{
25322 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
25323 ++ if (!grsec_enable_chroot_fchdir)
25324 ++ return 1;
25325 ++
25326 ++ if (!proc_is_chrooted(current))
25327 ++ return 1;
25328 ++ else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
25329 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
25330 ++ return 0;
25331 ++ }
25332 ++#endif
25333 ++ return 1;
25334 ++}
25335 ++
25336 ++int
25337 ++gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
25338 ++ const time_t shm_createtime)
25339 ++{
25340 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
25341 ++ struct pid *pid = NULL;
25342 ++ time_t starttime;
25343 ++
25344 ++ if (unlikely(!grsec_enable_chroot_shmat))
25345 ++ return 1;
25346 ++
25347 ++ if (likely(!proc_is_chrooted(current)))
25348 ++ return 1;
25349 ++
25350 ++ read_lock(&tasklist_lock);
25351 ++
25352 ++ pid = find_pid(shm_cprid);
25353 ++ if (pid) {
25354 ++ struct task_struct *p;
25355 ++ p = pid_task(pid, PIDTYPE_PID);
25356 ++ task_lock(p);
25357 ++ starttime = p->start_time.tv_sec;
25358 ++ if (unlikely(!have_same_root(current, p) &&
25359 ++ time_before_eq((unsigned long)starttime, (unsigned long)shm_createtime))) {
25360 ++ task_unlock(p);
25361 ++ read_unlock(&tasklist_lock);
25362 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
25363 ++ return 0;
25364 ++ }
25365 ++ task_unlock(p);
25366 ++ } else {
25367 ++ pid = find_pid(shm_lapid);
25368 ++ if (pid) {
25369 ++ struct task_struct *p;
25370 ++ p = pid_task(pid, PIDTYPE_PID);
25371 ++ task_lock(p);
25372 ++ if (unlikely(!have_same_root(current, p))) {
25373 ++ task_unlock(p);
25374 ++ read_unlock(&tasklist_lock);
25375 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
25376 ++ return 0;
25377 ++ }
25378 ++ task_unlock(p);
25379 ++ }
25380 ++ }
25381 ++
25382 ++ read_unlock(&tasklist_lock);
25383 ++#endif
25384 ++ return 1;
25385 ++}
25386 ++
25387 ++void
25388 ++gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
25389 ++{
25390 ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
25391 ++ if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
25392 ++ gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
25393 ++#endif
25394 ++ return;
25395 ++}
25396 ++
25397 ++int
25398 ++gr_handle_chroot_mknod(const struct dentry *dentry,
25399 ++ const struct vfsmount *mnt, const int mode)
25400 ++{
25401 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
25402 ++ if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) &&
25403 ++ proc_is_chrooted(current)) {
25404 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
25405 ++ return -EPERM;
25406 ++ }
25407 ++#endif
25408 ++ return 0;
25409 ++}
25410 ++
25411 ++int
25412 ++gr_handle_chroot_mount(const struct dentry *dentry,
25413 ++ const struct vfsmount *mnt, const char *dev_name)
25414 ++{
25415 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
25416 ++ if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
25417 ++ gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
25418 ++ return -EPERM;
25419 ++ }
25420 ++#endif
25421 ++ return 0;
25422 ++}
25423 ++
25424 ++int
25425 ++gr_handle_chroot_pivot(void)
25426 ++{
25427 ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
25428 ++ if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
25429 ++ gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
25430 ++ return -EPERM;
25431 ++ }
25432 ++#endif
25433 ++ return 0;
25434 ++}
25435 ++
25436 ++int
25437 ++gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
25438 ++{
25439 ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
25440 ++ if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
25441 ++ !gr_is_outside_chroot(dentry, mnt)) {
25442 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
25443 ++ return -EPERM;
25444 ++ }
25445 ++#endif
25446 ++ return 0;
25447 ++}
25448 ++
25449 ++void
25450 ++gr_handle_chroot_caps(struct task_struct *task)
25451 ++{
25452 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
25453 ++ if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
25454 ++ kernel_cap_t chroot_caps = GR_CHROOT_CAPS;
25455 ++ task->cap_permitted =
25456 ++ cap_drop(task->cap_permitted, chroot_caps);
25457 ++ task->cap_inheritable =
25458 ++ cap_drop(task->cap_inheritable, chroot_caps);
25459 ++ task->cap_effective =
25460 ++ cap_drop(task->cap_effective, chroot_caps);
25461 ++ }
25462 ++#endif
25463 ++ return;
25464 ++}
25465 ++
25466 ++int
25467 ++gr_handle_chroot_sysctl(const int op)
25468 ++{
25469 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
25470 ++ if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
25471 ++ && (op & 002))
25472 ++ return -EACCES;
25473 ++#endif
25474 ++ return 0;
25475 ++}
25476 ++
25477 ++void
25478 ++gr_handle_chroot_chdir(struct path *path)
25479 ++{
25480 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
25481 ++ if (grsec_enable_chroot_chdir)
25482 ++ set_fs_pwd(current->fs, path);
25483 ++#endif
25484 ++ return;
25485 ++}
25486 ++
25487 ++int
25488 ++gr_handle_chroot_chmod(const struct dentry *dentry,
25489 ++ const struct vfsmount *mnt, const int mode)
25490 ++{
25491 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
25492 ++ if (grsec_enable_chroot_chmod &&
25493 ++ ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
25494 ++ proc_is_chrooted(current)) {
25495 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
25496 ++ return -EPERM;
25497 ++ }
25498 ++#endif
25499 ++ return 0;
25500 ++}
25501 ++
25502 ++#ifdef CONFIG_SECURITY
25503 ++EXPORT_SYMBOL(gr_handle_chroot_caps);
25504 ++#endif
25505 +diff -urNp linux-2.6.26.6/grsecurity/grsec_disabled.c linux-2.6.26.6/grsecurity/grsec_disabled.c
25506 +--- linux-2.6.26.6/grsecurity/grsec_disabled.c 1969-12-31 19:00:00.000000000 -0500
25507 ++++ linux-2.6.26.6/grsecurity/grsec_disabled.c 2008-10-11 21:54:20.000000000 -0400
25508 +@@ -0,0 +1,418 @@
25509 ++#include <linux/kernel.h>
25510 ++#include <linux/module.h>
25511 ++#include <linux/sched.h>
25512 ++#include <linux/file.h>
25513 ++#include <linux/fs.h>
25514 ++#include <linux/kdev_t.h>
25515 ++#include <linux/net.h>
25516 ++#include <linux/in.h>
25517 ++#include <linux/ip.h>
25518 ++#include <linux/skbuff.h>
25519 ++#include <linux/sysctl.h>
25520 ++
25521 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
25522 ++void
25523 ++pax_set_initial_flags(struct linux_binprm *bprm)
25524 ++{
25525 ++ return;
25526 ++}
25527 ++#endif
25528 ++
25529 ++#ifdef CONFIG_SYSCTL
25530 ++__u32
25531 ++gr_handle_sysctl(const struct ctl_table * table, const int op)
25532 ++{
25533 ++ return 0;
25534 ++}
25535 ++#endif
25536 ++
25537 ++int
25538 ++gr_acl_is_enabled(void)
25539 ++{
25540 ++ return 0;
25541 ++}
25542 ++
25543 ++int
25544 ++gr_handle_rawio(const struct inode *inode)
25545 ++{
25546 ++ return 0;
25547 ++}
25548 ++
25549 ++void
25550 ++gr_acl_handle_psacct(struct task_struct *task, const long code)
25551 ++{
25552 ++ return;
25553 ++}
25554 ++
25555 ++int
25556 ++gr_handle_ptrace(struct task_struct *task, const long request)
25557 ++{
25558 ++ return 0;
25559 ++}
25560 ++
25561 ++int
25562 ++gr_handle_proc_ptrace(struct task_struct *task)
25563 ++{
25564 ++ return 0;
25565 ++}
25566 ++
25567 ++void
25568 ++gr_learn_resource(const struct task_struct *task,
25569 ++ const int res, const unsigned long wanted, const int gt)
25570 ++{
25571 ++ return;
25572 ++}
25573 ++
25574 ++int
25575 ++gr_set_acls(const int type)
25576 ++{
25577 ++ return 0;
25578 ++}
25579 ++
25580 ++int
25581 ++gr_check_hidden_task(const struct task_struct *tsk)
25582 ++{
25583 ++ return 0;
25584 ++}
25585 ++
25586 ++int
25587 ++gr_check_protected_task(const struct task_struct *task)
25588 ++{
25589 ++ return 0;
25590 ++}
25591 ++
25592 ++void
25593 ++gr_copy_label(struct task_struct *tsk)
25594 ++{
25595 ++ return;
25596 ++}
25597 ++
25598 ++void
25599 ++gr_set_pax_flags(struct task_struct *task)
25600 ++{
25601 ++ return;
25602 ++}
25603 ++
25604 ++int
25605 ++gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
25606 ++{
25607 ++ return 0;
25608 ++}
25609 ++
25610 ++void
25611 ++gr_handle_delete(const ino_t ino, const dev_t dev)
25612 ++{
25613 ++ return;
25614 ++}
25615 ++
25616 ++void
25617 ++gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
25618 ++{
25619 ++ return;
25620 ++}
25621 ++
25622 ++void
25623 ++gr_handle_crash(struct task_struct *task, const int sig)
25624 ++{
25625 ++ return;
25626 ++}
25627 ++
25628 ++int
25629 ++gr_check_crash_exec(const struct file *filp)
25630 ++{
25631 ++ return 0;
25632 ++}
25633 ++
25634 ++int
25635 ++gr_check_crash_uid(const uid_t uid)
25636 ++{
25637 ++ return 0;
25638 ++}
25639 ++
25640 ++void
25641 ++gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
25642 ++ struct dentry *old_dentry,
25643 ++ struct dentry *new_dentry,
25644 ++ struct vfsmount *mnt, const __u8 replace)
25645 ++{
25646 ++ return;
25647 ++}
25648 ++
25649 ++int
25650 ++gr_search_socket(const int family, const int type, const int protocol)
25651 ++{
25652 ++ return 1;
25653 ++}
25654 ++
25655 ++int
25656 ++gr_search_connectbind(const int mode, const struct socket *sock,
25657 ++ const struct sockaddr_in *addr)
25658 ++{
25659 ++ return 1;
25660 ++}
25661 ++
25662 ++int
25663 ++gr_task_is_capable(struct task_struct *task, const int cap)
25664 ++{
25665 ++ return 1;
25666 ++}
25667 ++
25668 ++int
25669 ++gr_is_capable_nolog(const int cap)
25670 ++{
25671 ++ return 1;
25672 ++}
25673 ++
25674 ++void
25675 ++gr_handle_alertkill(struct task_struct *task)
25676 ++{
25677 ++ return;
25678 ++}
25679 ++
25680 ++__u32
25681 ++gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
25682 ++{
25683 ++ return 1;
25684 ++}
25685 ++
25686 ++__u32
25687 ++gr_acl_handle_hidden_file(const struct dentry * dentry,
25688 ++ const struct vfsmount * mnt)
25689 ++{
25690 ++ return 1;
25691 ++}
25692 ++
25693 ++__u32
25694 ++gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
25695 ++ const int fmode)
25696 ++{
25697 ++ return 1;
25698 ++}
25699 ++
25700 ++__u32
25701 ++gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
25702 ++{
25703 ++ return 1;
25704 ++}
25705 ++
25706 ++__u32
25707 ++gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
25708 ++{
25709 ++ return 1;
25710 ++}
25711 ++
25712 ++int
25713 ++gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
25714 ++ unsigned int *vm_flags)
25715 ++{
25716 ++ return 1;
25717 ++}
25718 ++
25719 ++__u32
25720 ++gr_acl_handle_truncate(const struct dentry * dentry,
25721 ++ const struct vfsmount * mnt)
25722 ++{
25723 ++ return 1;
25724 ++}
25725 ++
25726 ++__u32
25727 ++gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
25728 ++{
25729 ++ return 1;
25730 ++}
25731 ++
25732 ++__u32
25733 ++gr_acl_handle_access(const struct dentry * dentry,
25734 ++ const struct vfsmount * mnt, const int fmode)
25735 ++{
25736 ++ return 1;
25737 ++}
25738 ++
25739 ++__u32
25740 ++gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
25741 ++ mode_t mode)
25742 ++{
25743 ++ return 1;
25744 ++}
25745 ++
25746 ++__u32
25747 ++gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
25748 ++ mode_t mode)
25749 ++{
25750 ++ return 1;
25751 ++}
25752 ++
25753 ++__u32
25754 ++gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
25755 ++{
25756 ++ return 1;
25757 ++}
25758 ++
25759 ++void
25760 ++grsecurity_init(void)
25761 ++{
25762 ++ return;
25763 ++}
25764 ++
25765 ++__u32
25766 ++gr_acl_handle_mknod(const struct dentry * new_dentry,
25767 ++ const struct dentry * parent_dentry,
25768 ++ const struct vfsmount * parent_mnt,
25769 ++ const int mode)
25770 ++{
25771 ++ return 1;
25772 ++}
25773 ++
25774 ++__u32
25775 ++gr_acl_handle_mkdir(const struct dentry * new_dentry,
25776 ++ const struct dentry * parent_dentry,
25777 ++ const struct vfsmount * parent_mnt)
25778 ++{
25779 ++ return 1;
25780 ++}
25781 ++
25782 ++__u32
25783 ++gr_acl_handle_symlink(const struct dentry * new_dentry,
25784 ++ const struct dentry * parent_dentry,
25785 ++ const struct vfsmount * parent_mnt, const char *from)
25786 ++{
25787 ++ return 1;
25788 ++}
25789 ++
25790 ++__u32
25791 ++gr_acl_handle_link(const struct dentry * new_dentry,
25792 ++ const struct dentry * parent_dentry,
25793 ++ const struct vfsmount * parent_mnt,
25794 ++ const struct dentry * old_dentry,
25795 ++ const struct vfsmount * old_mnt, const char *to)
25796 ++{
25797 ++ return 1;
25798 ++}
25799 ++
25800 ++int
25801 ++gr_acl_handle_rename(const struct dentry *new_dentry,
25802 ++ const struct dentry *parent_dentry,
25803 ++ const struct vfsmount *parent_mnt,
25804 ++ const struct dentry *old_dentry,
25805 ++ const struct inode *old_parent_inode,
25806 ++ const struct vfsmount *old_mnt, const char *newname)
25807 ++{
25808 ++ return 0;
25809 ++}
25810 ++
25811 ++int
25812 ++gr_acl_handle_filldir(const struct file *file, const char *name,
25813 ++ const int namelen, const ino_t ino)
25814 ++{
25815 ++ return 1;
25816 ++}
25817 ++
25818 ++int
25819 ++gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
25820 ++ const time_t shm_createtime, const uid_t cuid, const int shmid)
25821 ++{
25822 ++ return 1;
25823 ++}
25824 ++
25825 ++int
25826 ++gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
25827 ++{
25828 ++ return 1;
25829 ++}
25830 ++
25831 ++int
25832 ++gr_search_accept(const struct socket *sock)
25833 ++{
25834 ++ return 1;
25835 ++}
25836 ++
25837 ++int
25838 ++gr_search_listen(const struct socket *sock)
25839 ++{
25840 ++ return 1;
25841 ++}
25842 ++
25843 ++int
25844 ++gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
25845 ++{
25846 ++ return 1;
25847 ++}
25848 ++
25849 ++__u32
25850 ++gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
25851 ++{
25852 ++ return 1;
25853 ++}
25854 ++
25855 ++__u32
25856 ++gr_acl_handle_creat(const struct dentry * dentry,
25857 ++ const struct dentry * p_dentry,
25858 ++ const struct vfsmount * p_mnt, const int fmode,
25859 ++ const int imode)
25860 ++{
25861 ++ return 1;
25862 ++}
25863 ++
25864 ++void
25865 ++gr_acl_handle_exit(void)
25866 ++{
25867 ++ return;
25868 ++}
25869 ++
25870 ++int
25871 ++gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
25872 ++{
25873 ++ return 1;
25874 ++}
25875 ++
25876 ++void
25877 ++gr_set_role_label(const uid_t uid, const gid_t gid)
25878 ++{
25879 ++ return;
25880 ++}
25881 ++
25882 ++int
25883 ++gr_acl_handle_procpidmem(const struct task_struct *task)
25884 ++{
25885 ++ return 0;
25886 ++}
25887 ++
25888 ++int
25889 ++gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
25890 ++{
25891 ++ return 1;
25892 ++}
25893 ++
25894 ++int
25895 ++gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
25896 ++{
25897 ++ return 1;
25898 ++}
25899 ++
25900 ++void
25901 ++gr_set_kernel_label(struct task_struct *task)
25902 ++{
25903 ++ return;
25904 ++}
25905 ++
25906 ++int
25907 ++gr_check_user_change(int real, int effective, int fs)
25908 ++{
25909 ++ return 0;
25910 ++}
25911 ++
25912 ++int
25913 ++gr_check_group_change(int real, int effective, int fs)
25914 ++{
25915 ++ return 0;
25916 ++}
25917 ++
25918 ++
25919 ++EXPORT_SYMBOL(gr_task_is_capable);
25920 ++EXPORT_SYMBOL(gr_is_capable_nolog);
25921 ++EXPORT_SYMBOL(gr_learn_resource);
25922 ++EXPORT_SYMBOL(gr_set_kernel_label);
25923 ++#ifdef CONFIG_SECURITY
25924 ++EXPORT_SYMBOL(gr_check_user_change);
25925 ++EXPORT_SYMBOL(gr_check_group_change);
25926 ++#endif
25927 +diff -urNp linux-2.6.26.6/grsecurity/grsec_exec.c linux-2.6.26.6/grsecurity/grsec_exec.c
25928 +--- linux-2.6.26.6/grsecurity/grsec_exec.c 1969-12-31 19:00:00.000000000 -0500
25929 ++++ linux-2.6.26.6/grsecurity/grsec_exec.c 2008-10-11 21:54:20.000000000 -0400
25930 +@@ -0,0 +1,88 @@
25931 ++#include <linux/kernel.h>
25932 ++#include <linux/sched.h>
25933 ++#include <linux/file.h>
25934 ++#include <linux/binfmts.h>
25935 ++#include <linux/smp_lock.h>
25936 ++#include <linux/fs.h>
25937 ++#include <linux/types.h>
25938 ++#include <linux/grdefs.h>
25939 ++#include <linux/grinternal.h>
25940 ++#include <linux/capability.h>
25941 ++
25942 ++#include <asm/uaccess.h>
25943 ++
25944 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
25945 ++static char gr_exec_arg_buf[132];
25946 ++static DECLARE_MUTEX(gr_exec_arg_sem);
25947 ++#endif
25948 ++
25949 ++int
25950 ++gr_handle_nproc(void)
25951 ++{
25952 ++#ifdef CONFIG_GRKERNSEC_EXECVE
25953 ++ if (grsec_enable_execve && current->user &&
25954 ++ (atomic_read(&current->user->processes) >
25955 ++ current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
25956 ++ !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
25957 ++ gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
25958 ++ return -EAGAIN;
25959 ++ }
25960 ++#endif
25961 ++ return 0;
25962 ++}
25963 ++
25964 ++void
25965 ++gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
25966 ++{
25967 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
25968 ++ char *grarg = gr_exec_arg_buf;
25969 ++ unsigned int i, x, execlen = 0;
25970 ++ char c;
25971 ++
25972 ++ if (!((grsec_enable_execlog && grsec_enable_group &&
25973 ++ in_group_p(grsec_audit_gid))
25974 ++ || (grsec_enable_execlog && !grsec_enable_group)))
25975 ++ return;
25976 ++
25977 ++ down(&gr_exec_arg_sem);
25978 ++ memset(grarg, 0, sizeof(gr_exec_arg_buf));
25979 ++
25980 ++ if (unlikely(argv == NULL))
25981 ++ goto log;
25982 ++
25983 ++ for (i = 0; i < bprm->argc && execlen < 128; i++) {
25984 ++ const char __user *p;
25985 ++ unsigned int len;
25986 ++
25987 ++ if (copy_from_user(&p, argv + i, sizeof(p)))
25988 ++ goto log;
25989 ++ if (!p)
25990 ++ goto log;
25991 ++ len = strnlen_user(p, 128 - execlen);
25992 ++ if (len > 128 - execlen)
25993 ++ len = 128 - execlen;
25994 ++ else if (len > 0)
25995 ++ len--;
25996 ++ if (copy_from_user(grarg + execlen, p, len))
25997 ++ goto log;
25998 ++
25999 ++ /* rewrite unprintable characters */
26000 ++ for (x = 0; x < len; x++) {
26001 ++ c = *(grarg + execlen + x);
26002 ++ if (c < 32 || c > 126)
26003 ++ *(grarg + execlen + x) = ' ';
26004 ++ }
26005 ++
26006 ++ execlen += len;
26007 ++ *(grarg + execlen) = ' ';
26008 ++ *(grarg + execlen + 1) = '\0';
26009 ++ execlen++;
26010 ++ }
26011 ++
26012 ++ log:
26013 ++ gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_path.dentry,
26014 ++ bprm->file->f_path.mnt, grarg);
26015 ++ up(&gr_exec_arg_sem);
26016 ++#endif
26017 ++ return;
26018 ++}
26019 +diff -urNp linux-2.6.26.6/grsecurity/grsec_fifo.c linux-2.6.26.6/grsecurity/grsec_fifo.c
26020 +--- linux-2.6.26.6/grsecurity/grsec_fifo.c 1969-12-31 19:00:00.000000000 -0500
26021 ++++ linux-2.6.26.6/grsecurity/grsec_fifo.c 2008-10-11 21:54:20.000000000 -0400
26022 +@@ -0,0 +1,22 @@
26023 ++#include <linux/kernel.h>
26024 ++#include <linux/sched.h>
26025 ++#include <linux/fs.h>
26026 ++#include <linux/file.h>
26027 ++#include <linux/grinternal.h>
26028 ++
26029 ++int
26030 ++gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
26031 ++ const struct dentry *dir, const int flag, const int acc_mode)
26032 ++{
26033 ++#ifdef CONFIG_GRKERNSEC_FIFO
26034 ++ if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
26035 ++ !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
26036 ++ (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
26037 ++ (current->fsuid != dentry->d_inode->i_uid)) {
26038 ++ if (!generic_permission(dentry->d_inode, acc_mode, NULL))
26039 ++ gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
26040 ++ return -EACCES;
26041 ++ }
26042 ++#endif
26043 ++ return 0;
26044 ++}
26045 +diff -urNp linux-2.6.26.6/grsecurity/grsec_fork.c linux-2.6.26.6/grsecurity/grsec_fork.c
26046 +--- linux-2.6.26.6/grsecurity/grsec_fork.c 1969-12-31 19:00:00.000000000 -0500
26047 ++++ linux-2.6.26.6/grsecurity/grsec_fork.c 2008-10-11 21:54:20.000000000 -0400
26048 +@@ -0,0 +1,15 @@
26049 ++#include <linux/kernel.h>
26050 ++#include <linux/sched.h>
26051 ++#include <linux/grsecurity.h>
26052 ++#include <linux/grinternal.h>
26053 ++#include <linux/errno.h>
26054 ++
26055 ++void
26056 ++gr_log_forkfail(const int retval)
26057 ++{
26058 ++#ifdef CONFIG_GRKERNSEC_FORKFAIL
26059 ++ if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
26060 ++ gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
26061 ++#endif
26062 ++ return;
26063 ++}
26064 +diff -urNp linux-2.6.26.6/grsecurity/grsec_init.c linux-2.6.26.6/grsecurity/grsec_init.c
26065 +--- linux-2.6.26.6/grsecurity/grsec_init.c 1969-12-31 19:00:00.000000000 -0500
26066 ++++ linux-2.6.26.6/grsecurity/grsec_init.c 2008-10-11 21:54:20.000000000 -0400
26067 +@@ -0,0 +1,230 @@
26068 ++#include <linux/kernel.h>
26069 ++#include <linux/sched.h>
26070 ++#include <linux/mm.h>
26071 ++#include <linux/smp_lock.h>
26072 ++#include <linux/gracl.h>
26073 ++#include <linux/slab.h>
26074 ++#include <linux/vmalloc.h>
26075 ++#include <linux/percpu.h>
26076 ++
26077 ++int grsec_enable_link;
26078 ++int grsec_enable_dmesg;
26079 ++int grsec_enable_fifo;
26080 ++int grsec_enable_execve;
26081 ++int grsec_enable_execlog;
26082 ++int grsec_enable_signal;
26083 ++int grsec_enable_forkfail;
26084 ++int grsec_enable_time;
26085 ++int grsec_enable_audit_textrel;
26086 ++int grsec_enable_group;
26087 ++int grsec_audit_gid;
26088 ++int grsec_enable_chdir;
26089 ++int grsec_enable_audit_ipc;
26090 ++int grsec_enable_mount;
26091 ++int grsec_enable_chroot_findtask;
26092 ++int grsec_enable_chroot_mount;
26093 ++int grsec_enable_chroot_shmat;
26094 ++int grsec_enable_chroot_fchdir;
26095 ++int grsec_enable_chroot_double;
26096 ++int grsec_enable_chroot_pivot;
26097 ++int grsec_enable_chroot_chdir;
26098 ++int grsec_enable_chroot_chmod;
26099 ++int grsec_enable_chroot_mknod;
26100 ++int grsec_enable_chroot_nice;
26101 ++int grsec_enable_chroot_execlog;
26102 ++int grsec_enable_chroot_caps;
26103 ++int grsec_enable_chroot_sysctl;
26104 ++int grsec_enable_chroot_unix;
26105 ++int grsec_enable_tpe;
26106 ++int grsec_tpe_gid;
26107 ++int grsec_enable_tpe_all;
26108 ++int grsec_enable_socket_all;
26109 ++int grsec_socket_all_gid;
26110 ++int grsec_enable_socket_client;
26111 ++int grsec_socket_client_gid;
26112 ++int grsec_enable_socket_server;
26113 ++int grsec_socket_server_gid;
26114 ++int grsec_resource_logging;
26115 ++int grsec_lock;
26116 ++
26117 ++DEFINE_SPINLOCK(grsec_alert_lock);
26118 ++unsigned long grsec_alert_wtime = 0;
26119 ++unsigned long grsec_alert_fyet = 0;
26120 ++
26121 ++DEFINE_SPINLOCK(grsec_audit_lock);
26122 ++
26123 ++DEFINE_RWLOCK(grsec_exec_file_lock);
26124 ++
26125 ++char *gr_shared_page[4];
26126 ++
26127 ++char *gr_alert_log_fmt;
26128 ++char *gr_audit_log_fmt;
26129 ++char *gr_alert_log_buf;
26130 ++char *gr_audit_log_buf;
26131 ++
26132 ++extern struct gr_arg *gr_usermode;
26133 ++extern unsigned char *gr_system_salt;
26134 ++extern unsigned char *gr_system_sum;
26135 ++
26136 ++void
26137 ++grsecurity_init(void)
26138 ++{
26139 ++ int j;
26140 ++ /* create the per-cpu shared pages */
26141 ++
26142 ++#ifdef CONFIG_X86
26143 ++ memset((char *)(0x41a + PAGE_OFFSET), 0, 36);
26144 ++#endif
26145 ++
26146 ++ for (j = 0; j < 4; j++) {
26147 ++ gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
26148 ++ if (gr_shared_page[j] == NULL) {
26149 ++ panic("Unable to allocate grsecurity shared page");
26150 ++ return;
26151 ++ }
26152 ++ }
26153 ++
26154 ++ /* allocate log buffers */
26155 ++ gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
26156 ++ if (!gr_alert_log_fmt) {
26157 ++ panic("Unable to allocate grsecurity alert log format buffer");
26158 ++ return;
26159 ++ }
26160 ++ gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
26161 ++ if (!gr_audit_log_fmt) {
26162 ++ panic("Unable to allocate grsecurity audit log format buffer");
26163 ++ return;
26164 ++ }
26165 ++ gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
26166 ++ if (!gr_alert_log_buf) {
26167 ++ panic("Unable to allocate grsecurity alert log buffer");
26168 ++ return;
26169 ++ }
26170 ++ gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
26171 ++ if (!gr_audit_log_buf) {
26172 ++ panic("Unable to allocate grsecurity audit log buffer");
26173 ++ return;
26174 ++ }
26175 ++
26176 ++ /* allocate memory for authentication structure */
26177 ++ gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
26178 ++ gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
26179 ++ gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
26180 ++
26181 ++ if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
26182 ++ panic("Unable to allocate grsecurity authentication structure");
26183 ++ return;
26184 ++ }
26185 ++
26186 ++#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
26187 ++#ifndef CONFIG_GRKERNSEC_SYSCTL
26188 ++ grsec_lock = 1;
26189 ++#endif
26190 ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
26191 ++ grsec_enable_audit_textrel = 1;
26192 ++#endif
26193 ++#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
26194 ++ grsec_enable_group = 1;
26195 ++ grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
26196 ++#endif
26197 ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
26198 ++ grsec_enable_chdir = 1;
26199 ++#endif
26200 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26201 ++ grsec_enable_audit_ipc = 1;
26202 ++#endif
26203 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
26204 ++ grsec_enable_mount = 1;
26205 ++#endif
26206 ++#ifdef CONFIG_GRKERNSEC_LINK
26207 ++ grsec_enable_link = 1;
26208 ++#endif
26209 ++#ifdef CONFIG_GRKERNSEC_DMESG
26210 ++ grsec_enable_dmesg = 1;
26211 ++#endif
26212 ++#ifdef CONFIG_GRKERNSEC_FIFO
26213 ++ grsec_enable_fifo = 1;
26214 ++#endif
26215 ++#ifdef CONFIG_GRKERNSEC_EXECVE
26216 ++ grsec_enable_execve = 1;
26217 ++#endif
26218 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
26219 ++ grsec_enable_execlog = 1;
26220 ++#endif
26221 ++#ifdef CONFIG_GRKERNSEC_SIGNAL
26222 ++ grsec_enable_signal = 1;
26223 ++#endif
26224 ++#ifdef CONFIG_GRKERNSEC_FORKFAIL
26225 ++ grsec_enable_forkfail = 1;
26226 ++#endif
26227 ++#ifdef CONFIG_GRKERNSEC_TIME
26228 ++ grsec_enable_time = 1;
26229 ++#endif
26230 ++#ifdef CONFIG_GRKERNSEC_RESLOG
26231 ++ grsec_resource_logging = 1;
26232 ++#endif
26233 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
26234 ++ grsec_enable_chroot_findtask = 1;
26235 ++#endif
26236 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
26237 ++ grsec_enable_chroot_unix = 1;
26238 ++#endif
26239 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
26240 ++ grsec_enable_chroot_mount = 1;
26241 ++#endif
26242 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
26243 ++ grsec_enable_chroot_fchdir = 1;
26244 ++#endif
26245 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
26246 ++ grsec_enable_chroot_shmat = 1;
26247 ++#endif
26248 ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
26249 ++ grsec_enable_chroot_double = 1;
26250 ++#endif
26251 ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
26252 ++ grsec_enable_chroot_pivot = 1;
26253 ++#endif
26254 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
26255 ++ grsec_enable_chroot_chdir = 1;
26256 ++#endif
26257 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
26258 ++ grsec_enable_chroot_chmod = 1;
26259 ++#endif
26260 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
26261 ++ grsec_enable_chroot_mknod = 1;
26262 ++#endif
26263 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
26264 ++ grsec_enable_chroot_nice = 1;
26265 ++#endif
26266 ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
26267 ++ grsec_enable_chroot_execlog = 1;
26268 ++#endif
26269 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
26270 ++ grsec_enable_chroot_caps = 1;
26271 ++#endif
26272 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
26273 ++ grsec_enable_chroot_sysctl = 1;
26274 ++#endif
26275 ++#ifdef CONFIG_GRKERNSEC_TPE
26276 ++ grsec_enable_tpe = 1;
26277 ++ grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
26278 ++#ifdef CONFIG_GRKERNSEC_TPE_ALL
26279 ++ grsec_enable_tpe_all = 1;
26280 ++#endif
26281 ++#endif
26282 ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
26283 ++ grsec_enable_socket_all = 1;
26284 ++ grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
26285 ++#endif
26286 ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
26287 ++ grsec_enable_socket_client = 1;
26288 ++ grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
26289 ++#endif
26290 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
26291 ++ grsec_enable_socket_server = 1;
26292 ++ grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
26293 ++#endif
26294 ++#endif
26295 ++
26296 ++ return;
26297 ++}
26298 +diff -urNp linux-2.6.26.6/grsecurity/grsec_ipc.c linux-2.6.26.6/grsecurity/grsec_ipc.c
26299 +--- linux-2.6.26.6/grsecurity/grsec_ipc.c 1969-12-31 19:00:00.000000000 -0500
26300 ++++ linux-2.6.26.6/grsecurity/grsec_ipc.c 2008-10-11 21:54:20.000000000 -0400
26301 +@@ -0,0 +1,81 @@
26302 ++#include <linux/kernel.h>
26303 ++#include <linux/sched.h>
26304 ++#include <linux/types.h>
26305 ++#include <linux/ipc.h>
26306 ++#include <linux/grsecurity.h>
26307 ++#include <linux/grinternal.h>
26308 ++
26309 ++void
26310 ++gr_log_msgget(const int ret, const int msgflg)
26311 ++{
26312 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26313 ++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
26314 ++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
26315 ++ !grsec_enable_group)) && (ret >= 0)
26316 ++ && (msgflg & IPC_CREAT))
26317 ++ gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
26318 ++#endif
26319 ++ return;
26320 ++}
26321 ++
26322 ++void
26323 ++gr_log_msgrm(const uid_t uid, const uid_t cuid)
26324 ++{
26325 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26326 ++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
26327 ++ grsec_enable_audit_ipc) ||
26328 ++ (grsec_enable_audit_ipc && !grsec_enable_group))
26329 ++ gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
26330 ++#endif
26331 ++ return;
26332 ++}
26333 ++
26334 ++void
26335 ++gr_log_semget(const int err, const int semflg)
26336 ++{
26337 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26338 ++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
26339 ++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
26340 ++ !grsec_enable_group)) && (err >= 0)
26341 ++ && (semflg & IPC_CREAT))
26342 ++ gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
26343 ++#endif
26344 ++ return;
26345 ++}
26346 ++
26347 ++void
26348 ++gr_log_semrm(const uid_t uid, const uid_t cuid)
26349 ++{
26350 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26351 ++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
26352 ++ grsec_enable_audit_ipc) ||
26353 ++ (grsec_enable_audit_ipc && !grsec_enable_group))
26354 ++ gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
26355 ++#endif
26356 ++ return;
26357 ++}
26358 ++
26359 ++void
26360 ++gr_log_shmget(const int err, const int shmflg, const size_t size)
26361 ++{
26362 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26363 ++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
26364 ++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
26365 ++ !grsec_enable_group)) && (err >= 0)
26366 ++ && (shmflg & IPC_CREAT))
26367 ++ gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
26368 ++#endif
26369 ++ return;
26370 ++}
26371 ++
26372 ++void
26373 ++gr_log_shmrm(const uid_t uid, const uid_t cuid)
26374 ++{
26375 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26376 ++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
26377 ++ grsec_enable_audit_ipc) ||
26378 ++ (grsec_enable_audit_ipc && !grsec_enable_group))
26379 ++ gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
26380 ++#endif
26381 ++ return;
26382 ++}
26383 +diff -urNp linux-2.6.26.6/grsecurity/grsec_link.c linux-2.6.26.6/grsecurity/grsec_link.c
26384 +--- linux-2.6.26.6/grsecurity/grsec_link.c 1969-12-31 19:00:00.000000000 -0500
26385 ++++ linux-2.6.26.6/grsecurity/grsec_link.c 2008-10-11 21:54:20.000000000 -0400
26386 +@@ -0,0 +1,39 @@
26387 ++#include <linux/kernel.h>
26388 ++#include <linux/sched.h>
26389 ++#include <linux/fs.h>
26390 ++#include <linux/file.h>
26391 ++#include <linux/grinternal.h>
26392 ++
26393 ++int
26394 ++gr_handle_follow_link(const struct inode *parent,
26395 ++ const struct inode *inode,
26396 ++ const struct dentry *dentry, const struct vfsmount *mnt)
26397 ++{
26398 ++#ifdef CONFIG_GRKERNSEC_LINK
26399 ++ if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
26400 ++ (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
26401 ++ (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
26402 ++ gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
26403 ++ return -EACCES;
26404 ++ }
26405 ++#endif
26406 ++ return 0;
26407 ++}
26408 ++
26409 ++int
26410 ++gr_handle_hardlink(const struct dentry *dentry,
26411 ++ const struct vfsmount *mnt,
26412 ++ struct inode *inode, const int mode, const char *to)
26413 ++{
26414 ++#ifdef CONFIG_GRKERNSEC_LINK
26415 ++ if (grsec_enable_link && current->fsuid != inode->i_uid &&
26416 ++ (!S_ISREG(mode) || (mode & S_ISUID) ||
26417 ++ ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
26418 ++ (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
26419 ++ !capable(CAP_FOWNER) && current->uid) {
26420 ++ gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
26421 ++ return -EPERM;
26422 ++ }
26423 ++#endif
26424 ++ return 0;
26425 ++}
26426 +diff -urNp linux-2.6.26.6/grsecurity/grsec_log.c linux-2.6.26.6/grsecurity/grsec_log.c
26427 +--- linux-2.6.26.6/grsecurity/grsec_log.c 1969-12-31 19:00:00.000000000 -0500
26428 ++++ linux-2.6.26.6/grsecurity/grsec_log.c 2008-10-11 21:54:20.000000000 -0400
26429 +@@ -0,0 +1,269 @@
26430 ++#include <linux/kernel.h>
26431 ++#include <linux/sched.h>
26432 ++#include <linux/file.h>
26433 ++#include <linux/tty.h>
26434 ++#include <linux/fs.h>
26435 ++#include <linux/grinternal.h>
26436 ++
26437 ++#define BEGIN_LOCKS(x) \
26438 ++ read_lock(&tasklist_lock); \
26439 ++ read_lock(&grsec_exec_file_lock); \
26440 ++ if (x != GR_DO_AUDIT) \
26441 ++ spin_lock(&grsec_alert_lock); \
26442 ++ else \
26443 ++ spin_lock(&grsec_audit_lock)
26444 ++
26445 ++#define END_LOCKS(x) \
26446 ++ if (x != GR_DO_AUDIT) \
26447 ++ spin_unlock(&grsec_alert_lock); \
26448 ++ else \
26449 ++ spin_unlock(&grsec_audit_lock); \
26450 ++ read_unlock(&grsec_exec_file_lock); \
26451 ++ read_unlock(&tasklist_lock); \
26452 ++ if (x == GR_DONT_AUDIT) \
26453 ++ gr_handle_alertkill(current)
26454 ++
26455 ++enum {
26456 ++ FLOODING,
26457 ++ NO_FLOODING
26458 ++};
26459 ++
26460 ++extern char *gr_alert_log_fmt;
26461 ++extern char *gr_audit_log_fmt;
26462 ++extern char *gr_alert_log_buf;
26463 ++extern char *gr_audit_log_buf;
26464 ++
26465 ++static int gr_log_start(int audit)
26466 ++{
26467 ++ char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
26468 ++ char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
26469 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
26470 ++
26471 ++ if (audit == GR_DO_AUDIT)
26472 ++ goto set_fmt;
26473 ++
26474 ++ if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
26475 ++ grsec_alert_wtime = jiffies;
26476 ++ grsec_alert_fyet = 0;
26477 ++ } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
26478 ++ grsec_alert_fyet++;
26479 ++ } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
26480 ++ grsec_alert_wtime = jiffies;
26481 ++ grsec_alert_fyet++;
26482 ++ printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
26483 ++ return FLOODING;
26484 ++ } else return FLOODING;
26485 ++
26486 ++set_fmt:
26487 ++ memset(buf, 0, PAGE_SIZE);
26488 ++ if (current->signal->curr_ip && gr_acl_is_enabled()) {
26489 ++ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
26490 ++ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
26491 ++ } else if (current->signal->curr_ip) {
26492 ++ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
26493 ++ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
26494 ++ } else if (gr_acl_is_enabled()) {
26495 ++ sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
26496 ++ snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
26497 ++ } else {
26498 ++ sprintf(fmt, "%s%s", loglevel, "grsec: ");
26499 ++ strcpy(buf, fmt);
26500 ++ }
26501 ++
26502 ++ return NO_FLOODING;
26503 ++}
26504 ++
26505 ++static void gr_log_middle(int audit, const char *msg, va_list ap)
26506 ++{
26507 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
26508 ++ unsigned int len = strlen(buf);
26509 ++
26510 ++ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
26511 ++
26512 ++ return;
26513 ++}
26514 ++
26515 ++static void gr_log_middle_varargs(int audit, const char *msg, ...)
26516 ++{
26517 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
26518 ++ unsigned int len = strlen(buf);
26519 ++ va_list ap;
26520 ++
26521 ++ va_start(ap, msg);
26522 ++ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
26523 ++ va_end(ap);
26524 ++
26525 ++ return;
26526 ++}
26527 ++
26528 ++static void gr_log_end(int audit)
26529 ++{
26530 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
26531 ++ unsigned int len = strlen(buf);
26532 ++
26533 ++ snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
26534 ++ printk("%s\n", buf);
26535 ++
26536 ++ return;
26537 ++}
26538 ++
26539 ++void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
26540 ++{
26541 ++ int logtype;
26542 ++ char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
26543 ++ char *str1, *str2, *str3;
26544 ++ int num1, num2;
26545 ++ unsigned long ulong1, ulong2;
26546 ++ struct dentry *dentry;
26547 ++ struct vfsmount *mnt;
26548 ++ struct file *file;
26549 ++ struct task_struct *task;
26550 ++ va_list ap;
26551 ++
26552 ++ BEGIN_LOCKS(audit);
26553 ++ logtype = gr_log_start(audit);
26554 ++ if (logtype == FLOODING) {
26555 ++ END_LOCKS(audit);
26556 ++ return;
26557 ++ }
26558 ++ va_start(ap, argtypes);
26559 ++ switch (argtypes) {
26560 ++ case GR_TTYSNIFF:
26561 ++ task = va_arg(ap, struct task_struct *);
26562 ++ 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);
26563 ++ break;
26564 ++ case GR_SYSCTL_HIDDEN:
26565 ++ str1 = va_arg(ap, char *);
26566 ++ gr_log_middle_varargs(audit, msg, result, str1);
26567 ++ break;
26568 ++ case GR_RBAC:
26569 ++ dentry = va_arg(ap, struct dentry *);
26570 ++ mnt = va_arg(ap, struct vfsmount *);
26571 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
26572 ++ break;
26573 ++ case GR_RBAC_STR:
26574 ++ dentry = va_arg(ap, struct dentry *);
26575 ++ mnt = va_arg(ap, struct vfsmount *);
26576 ++ str1 = va_arg(ap, char *);
26577 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
26578 ++ break;
26579 ++ case GR_STR_RBAC:
26580 ++ str1 = va_arg(ap, char *);
26581 ++ dentry = va_arg(ap, struct dentry *);
26582 ++ mnt = va_arg(ap, struct vfsmount *);
26583 ++ gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
26584 ++ break;
26585 ++ case GR_RBAC_MODE2:
26586 ++ dentry = va_arg(ap, struct dentry *);
26587 ++ mnt = va_arg(ap, struct vfsmount *);
26588 ++ str1 = va_arg(ap, char *);
26589 ++ str2 = va_arg(ap, char *);
26590 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
26591 ++ break;
26592 ++ case GR_RBAC_MODE3:
26593 ++ dentry = va_arg(ap, struct dentry *);
26594 ++ mnt = va_arg(ap, struct vfsmount *);
26595 ++ str1 = va_arg(ap, char *);
26596 ++ str2 = va_arg(ap, char *);
26597 ++ str3 = va_arg(ap, char *);
26598 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
26599 ++ break;
26600 ++ case GR_FILENAME:
26601 ++ dentry = va_arg(ap, struct dentry *);
26602 ++ mnt = va_arg(ap, struct vfsmount *);
26603 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
26604 ++ break;
26605 ++ case GR_STR_FILENAME:
26606 ++ str1 = va_arg(ap, char *);
26607 ++ dentry = va_arg(ap, struct dentry *);
26608 ++ mnt = va_arg(ap, struct vfsmount *);
26609 ++ gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
26610 ++ break;
26611 ++ case GR_FILENAME_STR:
26612 ++ dentry = va_arg(ap, struct dentry *);
26613 ++ mnt = va_arg(ap, struct vfsmount *);
26614 ++ str1 = va_arg(ap, char *);
26615 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
26616 ++ break;
26617 ++ case GR_FILENAME_TWO_INT:
26618 ++ dentry = va_arg(ap, struct dentry *);
26619 ++ mnt = va_arg(ap, struct vfsmount *);
26620 ++ num1 = va_arg(ap, int);
26621 ++ num2 = va_arg(ap, int);
26622 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
26623 ++ break;
26624 ++ case GR_FILENAME_TWO_INT_STR:
26625 ++ dentry = va_arg(ap, struct dentry *);
26626 ++ mnt = va_arg(ap, struct vfsmount *);
26627 ++ num1 = va_arg(ap, int);
26628 ++ num2 = va_arg(ap, int);
26629 ++ str1 = va_arg(ap, char *);
26630 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
26631 ++ break;
26632 ++ case GR_TEXTREL:
26633 ++ file = va_arg(ap, struct file *);
26634 ++ ulong1 = va_arg(ap, unsigned long);
26635 ++ ulong2 = va_arg(ap, unsigned long);
26636 ++ gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_path.dentry, file->f_path.mnt) : "<anonymous mapping>", ulong1, ulong2);
26637 ++ break;
26638 ++ case GR_PTRACE:
26639 ++ task = va_arg(ap, struct task_struct *);
26640 ++ gr_log_middle_varargs(audit, msg, task->exec_file ? gr_to_filename(task->exec_file->f_path.dentry, task->exec_file->f_path.mnt) : "(none)", task->comm, task->pid);
26641 ++ break;
26642 ++ case GR_RESOURCE:
26643 ++ task = va_arg(ap, struct task_struct *);
26644 ++ ulong1 = va_arg(ap, unsigned long);
26645 ++ str1 = va_arg(ap, char *);
26646 ++ ulong2 = va_arg(ap, unsigned long);
26647 ++ 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);
26648 ++ break;
26649 ++ case GR_CAP:
26650 ++ task = va_arg(ap, struct task_struct *);
26651 ++ str1 = va_arg(ap, char *);
26652 ++ 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);
26653 ++ break;
26654 ++ case GR_SIG:
26655 ++ task = va_arg(ap, struct task_struct *);
26656 ++ num1 = va_arg(ap, int);
26657 ++ 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);
26658 ++ break;
26659 ++ case GR_CRASH1:
26660 ++ task = va_arg(ap, struct task_struct *);
26661 ++ ulong1 = va_arg(ap, unsigned long);
26662 ++ 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);
26663 ++ break;
26664 ++ case GR_CRASH2:
26665 ++ task = va_arg(ap, struct task_struct *);
26666 ++ ulong1 = va_arg(ap, unsigned long);
26667 ++ 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);
26668 ++ break;
26669 ++ case GR_PSACCT:
26670 ++ {
26671 ++ unsigned int wday, cday;
26672 ++ __u8 whr, chr;
26673 ++ __u8 wmin, cmin;
26674 ++ __u8 wsec, csec;
26675 ++ char cur_tty[64] = { 0 };
26676 ++ char parent_tty[64] = { 0 };
26677 ++
26678 ++ task = va_arg(ap, struct task_struct *);
26679 ++ wday = va_arg(ap, unsigned int);
26680 ++ cday = va_arg(ap, unsigned int);
26681 ++ whr = va_arg(ap, int);
26682 ++ chr = va_arg(ap, int);
26683 ++ wmin = va_arg(ap, int);
26684 ++ cmin = va_arg(ap, int);
26685 ++ wsec = va_arg(ap, int);
26686 ++ csec = va_arg(ap, int);
26687 ++ ulong1 = va_arg(ap, unsigned long);
26688 ++
26689 ++ 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);
26690 ++ }
26691 ++ break;
26692 ++ default:
26693 ++ gr_log_middle(audit, msg, ap);
26694 ++ }
26695 ++ va_end(ap);
26696 ++ gr_log_end(audit);
26697 ++ END_LOCKS(audit);
26698 ++}
26699 +diff -urNp linux-2.6.26.6/grsecurity/grsec_mem.c linux-2.6.26.6/grsecurity/grsec_mem.c
26700 +--- linux-2.6.26.6/grsecurity/grsec_mem.c 1969-12-31 19:00:00.000000000 -0500
26701 ++++ linux-2.6.26.6/grsecurity/grsec_mem.c 2008-10-11 21:54:20.000000000 -0400
26702 +@@ -0,0 +1,71 @@
26703 ++#include <linux/kernel.h>
26704 ++#include <linux/sched.h>
26705 ++#include <linux/mm.h>
26706 ++#include <linux/mman.h>
26707 ++#include <linux/grinternal.h>
26708 ++
26709 ++void
26710 ++gr_handle_ioperm(void)
26711 ++{
26712 ++ gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
26713 ++ return;
26714 ++}
26715 ++
26716 ++void
26717 ++gr_handle_iopl(void)
26718 ++{
26719 ++ gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
26720 ++ return;
26721 ++}
26722 ++
26723 ++void
26724 ++gr_handle_mem_write(void)
26725 ++{
26726 ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
26727 ++ return;
26728 ++}
26729 ++
26730 ++void
26731 ++gr_handle_kmem_write(void)
26732 ++{
26733 ++ gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
26734 ++ return;
26735 ++}
26736 ++
26737 ++void
26738 ++gr_handle_open_port(void)
26739 ++{
26740 ++ gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
26741 ++ return;
26742 ++}
26743 ++
26744 ++int
26745 ++gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
26746 ++{
26747 ++ unsigned long start, end;
26748 ++
26749 ++ start = offset;
26750 ++ end = start + vma->vm_end - vma->vm_start;
26751 ++
26752 ++ if (start > end) {
26753 ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
26754 ++ return -EPERM;
26755 ++ }
26756 ++
26757 ++ /* allowed ranges : ISA I/O BIOS */
26758 ++ if ((start >= __pa(high_memory))
26759 ++#ifdef CONFIG_X86
26760 ++ || (start >= 0x000a0000 && end <= 0x00100000)
26761 ++ || (start >= 0x00000000 && end <= 0x00001000)
26762 ++#endif
26763 ++ )
26764 ++ return 0;
26765 ++
26766 ++ if (vma->vm_flags & VM_WRITE) {
26767 ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
26768 ++ return -EPERM;
26769 ++ } else
26770 ++ vma->vm_flags &= ~VM_MAYWRITE;
26771 ++
26772 ++ return 0;
26773 ++}
26774 +diff -urNp linux-2.6.26.6/grsecurity/grsec_mount.c linux-2.6.26.6/grsecurity/grsec_mount.c
26775 +--- linux-2.6.26.6/grsecurity/grsec_mount.c 1969-12-31 19:00:00.000000000 -0500
26776 ++++ linux-2.6.26.6/grsecurity/grsec_mount.c 2008-10-11 21:54:20.000000000 -0400
26777 +@@ -0,0 +1,34 @@
26778 ++#include <linux/kernel.h>
26779 ++#include <linux/sched.h>
26780 ++#include <linux/grsecurity.h>
26781 ++#include <linux/grinternal.h>
26782 ++
26783 ++void
26784 ++gr_log_remount(const char *devname, const int retval)
26785 ++{
26786 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
26787 ++ if (grsec_enable_mount && (retval >= 0))
26788 ++ gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
26789 ++#endif
26790 ++ return;
26791 ++}
26792 ++
26793 ++void
26794 ++gr_log_unmount(const char *devname, const int retval)
26795 ++{
26796 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
26797 ++ if (grsec_enable_mount && (retval >= 0))
26798 ++ gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
26799 ++#endif
26800 ++ return;
26801 ++}
26802 ++
26803 ++void
26804 ++gr_log_mount(const char *from, const char *to, const int retval)
26805 ++{
26806 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
26807 ++ if (grsec_enable_mount && (retval >= 0))
26808 ++ gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
26809 ++#endif
26810 ++ return;
26811 ++}
26812 +diff -urNp linux-2.6.26.6/grsecurity/grsec_sig.c linux-2.6.26.6/grsecurity/grsec_sig.c
26813 +--- linux-2.6.26.6/grsecurity/grsec_sig.c 1969-12-31 19:00:00.000000000 -0500
26814 ++++ linux-2.6.26.6/grsecurity/grsec_sig.c 2008-10-11 21:54:20.000000000 -0400
26815 +@@ -0,0 +1,58 @@
26816 ++#include <linux/kernel.h>
26817 ++#include <linux/sched.h>
26818 ++#include <linux/delay.h>
26819 ++#include <linux/grsecurity.h>
26820 ++#include <linux/grinternal.h>
26821 ++
26822 ++void
26823 ++gr_log_signal(const int sig, const struct task_struct *t)
26824 ++{
26825 ++#ifdef CONFIG_GRKERNSEC_SIGNAL
26826 ++ if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
26827 ++ (sig == SIGABRT) || (sig == SIGBUS))) {
26828 ++ if (t->pid == current->pid) {
26829 ++ gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
26830 ++ } else {
26831 ++ gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
26832 ++ }
26833 ++ }
26834 ++#endif
26835 ++ return;
26836 ++}
26837 ++
26838 ++int
26839 ++gr_handle_signal(const struct task_struct *p, const int sig)
26840 ++{
26841 ++#ifdef CONFIG_GRKERNSEC
26842 ++ if (current->pid > 1 && gr_check_protected_task(p)) {
26843 ++ gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
26844 ++ return -EPERM;
26845 ++ } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
26846 ++ return -EPERM;
26847 ++ }
26848 ++#endif
26849 ++ return 0;
26850 ++}
26851 ++
26852 ++void gr_handle_brute_attach(struct task_struct *p)
26853 ++{
26854 ++#ifdef CONFIG_GRKERNSEC_BRUTE
26855 ++ read_lock(&tasklist_lock);
26856 ++ read_lock(&grsec_exec_file_lock);
26857 ++ if (p->parent && p->parent->exec_file == p->exec_file)
26858 ++ p->parent->brute = 1;
26859 ++ read_unlock(&grsec_exec_file_lock);
26860 ++ read_unlock(&tasklist_lock);
26861 ++#endif
26862 ++ return;
26863 ++}
26864 ++
26865 ++void gr_handle_brute_check(void)
26866 ++{
26867 ++#ifdef CONFIG_GRKERNSEC_BRUTE
26868 ++ if (current->brute)
26869 ++ msleep(30 * 1000);
26870 ++#endif
26871 ++ return;
26872 ++}
26873 ++
26874 +diff -urNp linux-2.6.26.6/grsecurity/grsec_sock.c linux-2.6.26.6/grsecurity/grsec_sock.c
26875 +--- linux-2.6.26.6/grsecurity/grsec_sock.c 1969-12-31 19:00:00.000000000 -0500
26876 ++++ linux-2.6.26.6/grsecurity/grsec_sock.c 2008-10-11 21:54:20.000000000 -0400
26877 +@@ -0,0 +1,274 @@
26878 ++#include <linux/kernel.h>
26879 ++#include <linux/module.h>
26880 ++#include <linux/sched.h>
26881 ++#include <linux/file.h>
26882 ++#include <linux/net.h>
26883 ++#include <linux/in.h>
26884 ++#include <linux/ip.h>
26885 ++#include <net/sock.h>
26886 ++#include <net/inet_sock.h>
26887 ++#include <linux/grsecurity.h>
26888 ++#include <linux/grinternal.h>
26889 ++#include <linux/gracl.h>
26890 ++
26891 ++#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
26892 ++extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
26893 ++EXPORT_SYMBOL(udp_v4_lookup);
26894 ++#endif
26895 ++
26896 ++kernel_cap_t gr_cap_rtnetlink(struct sock *sock);
26897 ++EXPORT_SYMBOL(gr_cap_rtnetlink);
26898 ++
26899 ++extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
26900 ++extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
26901 ++
26902 ++EXPORT_SYMBOL(gr_search_udp_recvmsg);
26903 ++EXPORT_SYMBOL(gr_search_udp_sendmsg);
26904 ++
26905 ++#ifdef CONFIG_UNIX_MODULE
26906 ++EXPORT_SYMBOL(gr_acl_handle_unix);
26907 ++EXPORT_SYMBOL(gr_acl_handle_mknod);
26908 ++EXPORT_SYMBOL(gr_handle_chroot_unix);
26909 ++EXPORT_SYMBOL(gr_handle_create);
26910 ++#endif
26911 ++
26912 ++#ifdef CONFIG_GRKERNSEC
26913 ++#define gr_conn_table_size 32749
26914 ++struct conn_table_entry {
26915 ++ struct conn_table_entry *next;
26916 ++ struct signal_struct *sig;
26917 ++};
26918 ++
26919 ++struct conn_table_entry *gr_conn_table[gr_conn_table_size];
26920 ++DEFINE_SPINLOCK(gr_conn_table_lock);
26921 ++
26922 ++extern const char * gr_socktype_to_name(unsigned char type);
26923 ++extern const char * gr_proto_to_name(unsigned char proto);
26924 ++
26925 ++static __inline__ int
26926 ++conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
26927 ++{
26928 ++ return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
26929 ++}
26930 ++
26931 ++static __inline__ int
26932 ++conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr,
26933 ++ __u16 sport, __u16 dport)
26934 ++{
26935 ++ if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
26936 ++ sig->gr_sport == sport && sig->gr_dport == dport))
26937 ++ return 1;
26938 ++ else
26939 ++ return 0;
26940 ++}
26941 ++
26942 ++static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
26943 ++{
26944 ++ struct conn_table_entry **match;
26945 ++ unsigned int index;
26946 ++
26947 ++ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
26948 ++ sig->gr_sport, sig->gr_dport,
26949 ++ gr_conn_table_size);
26950 ++
26951 ++ newent->sig = sig;
26952 ++
26953 ++ match = &gr_conn_table[index];
26954 ++ newent->next = *match;
26955 ++ *match = newent;
26956 ++
26957 ++ return;
26958 ++}
26959 ++
26960 ++static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
26961 ++{
26962 ++ struct conn_table_entry *match, *last = NULL;
26963 ++ unsigned int index;
26964 ++
26965 ++ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
26966 ++ sig->gr_sport, sig->gr_dport,
26967 ++ gr_conn_table_size);
26968 ++
26969 ++ match = gr_conn_table[index];
26970 ++ while (match && !conn_match(match->sig,
26971 ++ sig->gr_saddr, sig->gr_daddr, sig->gr_sport,
26972 ++ sig->gr_dport)) {
26973 ++ last = match;
26974 ++ match = match->next;
26975 ++ }
26976 ++
26977 ++ if (match) {
26978 ++ if (last)
26979 ++ last->next = match->next;
26980 ++ else
26981 ++ gr_conn_table[index] = NULL;
26982 ++ kfree(match);
26983 ++ }
26984 ++
26985 ++ return;
26986 ++}
26987 ++
26988 ++static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
26989 ++ __u16 sport, __u16 dport)
26990 ++{
26991 ++ struct conn_table_entry *match;
26992 ++ unsigned int index;
26993 ++
26994 ++ index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
26995 ++
26996 ++ match = gr_conn_table[index];
26997 ++ while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
26998 ++ match = match->next;
26999 ++
27000 ++ if (match)
27001 ++ return match->sig;
27002 ++ else
27003 ++ return NULL;
27004 ++}
27005 ++
27006 ++#endif
27007 ++
27008 ++void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
27009 ++{
27010 ++#ifdef CONFIG_GRKERNSEC
27011 ++ struct signal_struct *sig = task->signal;
27012 ++ struct conn_table_entry *newent;
27013 ++
27014 ++ newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
27015 ++ if (newent == NULL)
27016 ++ return;
27017 ++ /* no bh lock needed since we are called with bh disabled */
27018 ++ spin_lock(&gr_conn_table_lock);
27019 ++ gr_del_task_from_ip_table_nolock(sig);
27020 ++ sig->gr_saddr = inet->rcv_saddr;
27021 ++ sig->gr_daddr = inet->daddr;
27022 ++ sig->gr_sport = inet->sport;
27023 ++ sig->gr_dport = inet->dport;
27024 ++ gr_add_to_task_ip_table_nolock(sig, newent);
27025 ++ spin_unlock(&gr_conn_table_lock);
27026 ++#endif
27027 ++ return;
27028 ++}
27029 ++
27030 ++void gr_del_task_from_ip_table(struct task_struct *task)
27031 ++{
27032 ++#ifdef CONFIG_GRKERNSEC
27033 ++ spin_lock_bh(&gr_conn_table_lock);
27034 ++ gr_del_task_from_ip_table_nolock(task->signal);
27035 ++ spin_unlock_bh(&gr_conn_table_lock);
27036 ++#endif
27037 ++ return;
27038 ++}
27039 ++
27040 ++void
27041 ++gr_attach_curr_ip(const struct sock *sk)
27042 ++{
27043 ++#ifdef CONFIG_GRKERNSEC
27044 ++ struct signal_struct *p, *set;
27045 ++ const struct inet_sock *inet = inet_sk(sk);
27046 ++
27047 ++ if (unlikely(sk->sk_protocol != IPPROTO_TCP))
27048 ++ return;
27049 ++
27050 ++ set = current->signal;
27051 ++
27052 ++ spin_lock_bh(&gr_conn_table_lock);
27053 ++ p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
27054 ++ inet->dport, inet->sport);
27055 ++ if (unlikely(p != NULL)) {
27056 ++ set->curr_ip = p->curr_ip;
27057 ++ set->used_accept = 1;
27058 ++ gr_del_task_from_ip_table_nolock(p);
27059 ++ spin_unlock_bh(&gr_conn_table_lock);
27060 ++ return;
27061 ++ }
27062 ++ spin_unlock_bh(&gr_conn_table_lock);
27063 ++
27064 ++ set->curr_ip = inet->daddr;
27065 ++ set->used_accept = 1;
27066 ++#endif
27067 ++ return;
27068 ++}
27069 ++
27070 ++int
27071 ++gr_handle_sock_all(const int family, const int type, const int protocol)
27072 ++{
27073 ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
27074 ++ if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
27075 ++ (family != AF_UNIX) && (family != AF_LOCAL)) {
27076 ++ gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
27077 ++ return -EACCES;
27078 ++ }
27079 ++#endif
27080 ++ return 0;
27081 ++}
27082 ++
27083 ++int
27084 ++gr_handle_sock_server(const struct sockaddr *sck)
27085 ++{
27086 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
27087 ++ if (grsec_enable_socket_server &&
27088 ++ in_group_p(grsec_socket_server_gid) &&
27089 ++ sck && (sck->sa_family != AF_UNIX) &&
27090 ++ (sck->sa_family != AF_LOCAL)) {
27091 ++ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
27092 ++ return -EACCES;
27093 ++ }
27094 ++#endif
27095 ++ return 0;
27096 ++}
27097 ++
27098 ++int
27099 ++gr_handle_sock_server_other(const struct sock *sck)
27100 ++{
27101 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
27102 ++ if (grsec_enable_socket_server &&
27103 ++ in_group_p(grsec_socket_server_gid) &&
27104 ++ sck && (sck->sk_family != AF_UNIX) &&
27105 ++ (sck->sk_family != AF_LOCAL)) {
27106 ++ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
27107 ++ return -EACCES;
27108 ++ }
27109 ++#endif
27110 ++ return 0;
27111 ++}
27112 ++
27113 ++int
27114 ++gr_handle_sock_client(const struct sockaddr *sck)
27115 ++{
27116 ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
27117 ++ if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
27118 ++ sck && (sck->sa_family != AF_UNIX) &&
27119 ++ (sck->sa_family != AF_LOCAL)) {
27120 ++ gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
27121 ++ return -EACCES;
27122 ++ }
27123 ++#endif
27124 ++ return 0;
27125 ++}
27126 ++
27127 ++kernel_cap_t
27128 ++gr_cap_rtnetlink(struct sock *sock)
27129 ++{
27130 ++#ifdef CONFIG_GRKERNSEC
27131 ++ if (!gr_acl_is_enabled())
27132 ++ return current->cap_effective;
27133 ++ else if (sock->sk_protocol == NETLINK_ISCSI &&
27134 ++ cap_raised(current->cap_effective, CAP_SYS_ADMIN) &&
27135 ++ gr_task_is_capable(current, CAP_SYS_ADMIN))
27136 ++ return current->cap_effective;
27137 ++ else if (sock->sk_protocol == NETLINK_AUDIT &&
27138 ++ cap_raised(current->cap_effective, CAP_AUDIT_WRITE) &&
27139 ++ gr_task_is_capable(current, CAP_AUDIT_WRITE) &&
27140 ++ cap_raised(current->cap_effective, CAP_AUDIT_CONTROL) &&
27141 ++ gr_task_is_capable(current, CAP_AUDIT_CONTROL))
27142 ++ return current->cap_effective;
27143 ++ else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
27144 ++ gr_task_is_capable(current, CAP_NET_ADMIN))
27145 ++ return current->cap_effective;
27146 ++ else
27147 ++ return __cap_empty_set;
27148 ++#else
27149 ++ return current->cap_effective;
27150 ++#endif
27151 ++}
27152 +diff -urNp linux-2.6.26.6/grsecurity/grsec_sysctl.c linux-2.6.26.6/grsecurity/grsec_sysctl.c
27153 +--- linux-2.6.26.6/grsecurity/grsec_sysctl.c 1969-12-31 19:00:00.000000000 -0500
27154 ++++ linux-2.6.26.6/grsecurity/grsec_sysctl.c 2008-10-11 21:54:20.000000000 -0400
27155 +@@ -0,0 +1,435 @@
27156 ++#include <linux/kernel.h>
27157 ++#include <linux/sched.h>
27158 ++#include <linux/sysctl.h>
27159 ++#include <linux/grsecurity.h>
27160 ++#include <linux/grinternal.h>
27161 ++
27162 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
27163 ++int grsec_modstop;
27164 ++#endif
27165 ++
27166 ++int
27167 ++gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
27168 ++{
27169 ++#ifdef CONFIG_GRKERNSEC_SYSCTL
27170 ++ if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
27171 ++ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
27172 ++ return -EACCES;
27173 ++ }
27174 ++#endif
27175 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
27176 ++ if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
27177 ++ grsec_modstop && (op & 002)) {
27178 ++ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
27179 ++ return -EACCES;
27180 ++ }
27181 ++#endif
27182 ++ return 0;
27183 ++}
27184 ++
27185 ++#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
27186 ++ctl_table grsecurity_table[] = {
27187 ++#ifdef CONFIG_GRKERNSEC_SYSCTL
27188 ++#ifdef CONFIG_GRKERNSEC_LINK
27189 ++ {
27190 ++ .ctl_name = CTL_UNNUMBERED,
27191 ++ .procname = "linking_restrictions",
27192 ++ .data = &grsec_enable_link,
27193 ++ .maxlen = sizeof(int),
27194 ++ .mode = 0600,
27195 ++ .proc_handler = &proc_dointvec,
27196 ++ },
27197 ++#endif
27198 ++#ifdef CONFIG_GRKERNSEC_FIFO
27199 ++ {
27200 ++ .ctl_name = CTL_UNNUMBERED,
27201 ++ .procname = "fifo_restrictions",
27202 ++ .data = &grsec_enable_fifo,
27203 ++ .maxlen = sizeof(int),
27204 ++ .mode = 0600,
27205 ++ .proc_handler = &proc_dointvec,
27206 ++ },
27207 ++#endif
27208 ++#ifdef CONFIG_GRKERNSEC_EXECVE
27209 ++ {
27210 ++ .ctl_name = CTL_UNNUMBERED,
27211 ++ .procname = "execve_limiting",
27212 ++ .data = &grsec_enable_execve,
27213 ++ .maxlen = sizeof(int),
27214 ++ .mode = 0600,
27215 ++ .proc_handler = &proc_dointvec,
27216 ++ },
27217 ++#endif
27218 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
27219 ++ {
27220 ++ .ctl_name = CTL_UNNUMBERED,
27221 ++ .procname = "exec_logging",
27222 ++ .data = &grsec_enable_execlog,
27223 ++ .maxlen = sizeof(int),
27224 ++ .mode = 0600,
27225 ++ .proc_handler = &proc_dointvec,
27226 ++ },
27227 ++#endif
27228 ++#ifdef CONFIG_GRKERNSEC_SIGNAL
27229 ++ {
27230 ++ .ctl_name = CTL_UNNUMBERED,
27231 ++ .procname = "signal_logging",
27232 ++ .data = &grsec_enable_signal,
27233 ++ .maxlen = sizeof(int),
27234 ++ .mode = 0600,
27235 ++ .proc_handler = &proc_dointvec,
27236 ++ },
27237 ++#endif
27238 ++#ifdef CONFIG_GRKERNSEC_FORKFAIL
27239 ++ {
27240 ++ .ctl_name = CTL_UNNUMBERED,
27241 ++ .procname = "forkfail_logging",
27242 ++ .data = &grsec_enable_forkfail,
27243 ++ .maxlen = sizeof(int),
27244 ++ .mode = 0600,
27245 ++ .proc_handler = &proc_dointvec,
27246 ++ },
27247 ++#endif
27248 ++#ifdef CONFIG_GRKERNSEC_TIME
27249 ++ {
27250 ++ .ctl_name = CTL_UNNUMBERED,
27251 ++ .procname = "timechange_logging",
27252 ++ .data = &grsec_enable_time,
27253 ++ .maxlen = sizeof(int),
27254 ++ .mode = 0600,
27255 ++ .proc_handler = &proc_dointvec,
27256 ++ },
27257 ++#endif
27258 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
27259 ++ {
27260 ++ .ctl_name = CTL_UNNUMBERED,
27261 ++ .procname = "chroot_deny_shmat",
27262 ++ .data = &grsec_enable_chroot_shmat,
27263 ++ .maxlen = sizeof(int),
27264 ++ .mode = 0600,
27265 ++ .proc_handler = &proc_dointvec,
27266 ++ },
27267 ++#endif
27268 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
27269 ++ {
27270 ++ .ctl_name = CTL_UNNUMBERED,
27271 ++ .procname = "chroot_deny_unix",
27272 ++ .data = &grsec_enable_chroot_unix,
27273 ++ .maxlen = sizeof(int),
27274 ++ .mode = 0600,
27275 ++ .proc_handler = &proc_dointvec,
27276 ++ },
27277 ++#endif
27278 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
27279 ++ {
27280 ++ .ctl_name = CTL_UNNUMBERED,
27281 ++ .procname = "chroot_deny_mount",
27282 ++ .data = &grsec_enable_chroot_mount,
27283 ++ .maxlen = sizeof(int),
27284 ++ .mode = 0600,
27285 ++ .proc_handler = &proc_dointvec,
27286 ++ },
27287 ++#endif
27288 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
27289 ++ {
27290 ++ .ctl_name = CTL_UNNUMBERED,
27291 ++ .procname = "chroot_deny_fchdir",
27292 ++ .data = &grsec_enable_chroot_fchdir,
27293 ++ .maxlen = sizeof(int),
27294 ++ .mode = 0600,
27295 ++ .proc_handler = &proc_dointvec,
27296 ++ },
27297 ++#endif
27298 ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
27299 ++ {
27300 ++ .ctl_name = CTL_UNNUMBERED,
27301 ++ .procname = "chroot_deny_chroot",
27302 ++ .data = &grsec_enable_chroot_double,
27303 ++ .maxlen = sizeof(int),
27304 ++ .mode = 0600,
27305 ++ .proc_handler = &proc_dointvec,
27306 ++ },
27307 ++#endif
27308 ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
27309 ++ {
27310 ++ .ctl_name = CTL_UNNUMBERED,
27311 ++ .procname = "chroot_deny_pivot",
27312 ++ .data = &grsec_enable_chroot_pivot,
27313 ++ .maxlen = sizeof(int),
27314 ++ .mode = 0600,
27315 ++ .proc_handler = &proc_dointvec,
27316 ++ },
27317 ++#endif
27318 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
27319 ++ {
27320 ++ .ctl_name = CTL_UNNUMBERED,
27321 ++ .procname = "chroot_enforce_chdir",
27322 ++ .data = &grsec_enable_chroot_chdir,
27323 ++ .maxlen = sizeof(int),
27324 ++ .mode = 0600,
27325 ++ .proc_handler = &proc_dointvec,
27326 ++ },
27327 ++#endif
27328 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
27329 ++ {
27330 ++ .ctl_name = CTL_UNNUMBERED,
27331 ++ .procname = "chroot_deny_chmod",
27332 ++ .data = &grsec_enable_chroot_chmod,
27333 ++ .maxlen = sizeof(int),
27334 ++ .mode = 0600,
27335 ++ .proc_handler = &proc_dointvec,
27336 ++ },
27337 ++#endif
27338 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
27339 ++ {
27340 ++ .ctl_name = CTL_UNNUMBERED,
27341 ++ .procname = "chroot_deny_mknod",
27342 ++ .data = &grsec_enable_chroot_mknod,
27343 ++ .maxlen = sizeof(int),
27344 ++ .mode = 0600,
27345 ++ .proc_handler = &proc_dointvec,
27346 ++ },
27347 ++#endif
27348 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
27349 ++ {
27350 ++ .ctl_name = CTL_UNNUMBERED,
27351 ++ .procname = "chroot_restrict_nice",
27352 ++ .data = &grsec_enable_chroot_nice,
27353 ++ .maxlen = sizeof(int),
27354 ++ .mode = 0600,
27355 ++ .proc_handler = &proc_dointvec,
27356 ++ },
27357 ++#endif
27358 ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
27359 ++ {
27360 ++ .ctl_name = CTL_UNNUMBERED,
27361 ++ .procname = "chroot_execlog",
27362 ++ .data = &grsec_enable_chroot_execlog,
27363 ++ .maxlen = sizeof(int),
27364 ++ .mode = 0600,
27365 ++ .proc_handler = &proc_dointvec,
27366 ++ },
27367 ++#endif
27368 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
27369 ++ {
27370 ++ .ctl_name = CTL_UNNUMBERED,
27371 ++ .procname = "chroot_caps",
27372 ++ .data = &grsec_enable_chroot_caps,
27373 ++ .maxlen = sizeof(int),
27374 ++ .mode = 0600,
27375 ++ .proc_handler = &proc_dointvec,
27376 ++ },
27377 ++#endif
27378 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
27379 ++ {
27380 ++ .ctl_name = CTL_UNNUMBERED,
27381 ++ .procname = "chroot_deny_sysctl",
27382 ++ .data = &grsec_enable_chroot_sysctl,
27383 ++ .maxlen = sizeof(int),
27384 ++ .mode = 0600,
27385 ++ .proc_handler = &proc_dointvec,
27386 ++ },
27387 ++#endif
27388 ++#ifdef CONFIG_GRKERNSEC_TPE
27389 ++ {
27390 ++ .ctl_name = CTL_UNNUMBERED,
27391 ++ .procname = "tpe",
27392 ++ .data = &grsec_enable_tpe,
27393 ++ .maxlen = sizeof(int),
27394 ++ .mode = 0600,
27395 ++ .proc_handler = &proc_dointvec,
27396 ++ },
27397 ++ {
27398 ++ .ctl_name = CTL_UNNUMBERED,
27399 ++ .procname = "tpe_gid",
27400 ++ .data = &grsec_tpe_gid,
27401 ++ .maxlen = sizeof(int),
27402 ++ .mode = 0600,
27403 ++ .proc_handler = &proc_dointvec,
27404 ++ },
27405 ++#endif
27406 ++#ifdef CONFIG_GRKERNSEC_TPE_ALL
27407 ++ {
27408 ++ .ctl_name = CTL_UNNUMBERED,
27409 ++ .procname = "tpe_restrict_all",
27410 ++ .data = &grsec_enable_tpe_all,
27411 ++ .maxlen = sizeof(int),
27412 ++ .mode = 0600,
27413 ++ .proc_handler = &proc_dointvec,
27414 ++ },
27415 ++#endif
27416 ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
27417 ++ {
27418 ++ .ctl_name = CTL_UNNUMBERED,
27419 ++ .procname = "socket_all",
27420 ++ .data = &grsec_enable_socket_all,
27421 ++ .maxlen = sizeof(int),
27422 ++ .mode = 0600,
27423 ++ .proc_handler = &proc_dointvec,
27424 ++ },
27425 ++ {
27426 ++ .ctl_name = CTL_UNNUMBERED,
27427 ++ .procname = "socket_all_gid",
27428 ++ .data = &grsec_socket_all_gid,
27429 ++ .maxlen = sizeof(int),
27430 ++ .mode = 0600,
27431 ++ .proc_handler = &proc_dointvec,
27432 ++ },
27433 ++#endif
27434 ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
27435 ++ {
27436 ++ .ctl_name = CTL_UNNUMBERED,
27437 ++ .procname = "socket_client",
27438 ++ .data = &grsec_enable_socket_client,
27439 ++ .maxlen = sizeof(int),
27440 ++ .mode = 0600,
27441 ++ .proc_handler = &proc_dointvec,
27442 ++ },
27443 ++ {
27444 ++ .ctl_name = CTL_UNNUMBERED,
27445 ++ .procname = "socket_client_gid",
27446 ++ .data = &grsec_socket_client_gid,
27447 ++ .maxlen = sizeof(int),
27448 ++ .mode = 0600,
27449 ++ .proc_handler = &proc_dointvec,
27450 ++ },
27451 ++#endif
27452 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
27453 ++ {
27454 ++ .ctl_name = CTL_UNNUMBERED,
27455 ++ .procname = "socket_server",
27456 ++ .data = &grsec_enable_socket_server,
27457 ++ .maxlen = sizeof(int),
27458 ++ .mode = 0600,
27459 ++ .proc_handler = &proc_dointvec,
27460 ++ },
27461 ++ {
27462 ++ .ctl_name = CTL_UNNUMBERED,
27463 ++ .procname = "socket_server_gid",
27464 ++ .data = &grsec_socket_server_gid,
27465 ++ .maxlen = sizeof(int),
27466 ++ .mode = 0600,
27467 ++ .proc_handler = &proc_dointvec,
27468 ++ },
27469 ++#endif
27470 ++#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
27471 ++ {
27472 ++ .ctl_name = CTL_UNNUMBERED,
27473 ++ .procname = "audit_group",
27474 ++ .data = &grsec_enable_group,
27475 ++ .maxlen = sizeof(int),
27476 ++ .mode = 0600,
27477 ++ .proc_handler = &proc_dointvec,
27478 ++ },
27479 ++ {
27480 ++ .ctl_name = CTL_UNNUMBERED,
27481 ++ .procname = "audit_gid",
27482 ++ .data = &grsec_audit_gid,
27483 ++ .maxlen = sizeof(int),
27484 ++ .mode = 0600,
27485 ++ .proc_handler = &proc_dointvec,
27486 ++ },
27487 ++#endif
27488 ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
27489 ++ {
27490 ++ .ctl_name = CTL_UNNUMBERED,
27491 ++ .procname = "audit_chdir",
27492 ++ .data = &grsec_enable_chdir,
27493 ++ .maxlen = sizeof(int),
27494 ++ .mode = 0600,
27495 ++ .proc_handler = &proc_dointvec,
27496 ++ },
27497 ++#endif
27498 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
27499 ++ {
27500 ++ .ctl_name = CTL_UNNUMBERED,
27501 ++ .procname = "audit_mount",
27502 ++ .data = &grsec_enable_mount,
27503 ++ .maxlen = sizeof(int),
27504 ++ .mode = 0600,
27505 ++ .proc_handler = &proc_dointvec,
27506 ++ },
27507 ++#endif
27508 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
27509 ++ {
27510 ++ .ctl_name = CTL_UNNUMBERED,
27511 ++ .procname = "audit_ipc",
27512 ++ .data = &grsec_enable_audit_ipc,
27513 ++ .maxlen = sizeof(int),
27514 ++ .mode = 0600,
27515 ++ .proc_handler = &proc_dointvec,
27516 ++ },
27517 ++#endif
27518 ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
27519 ++ {
27520 ++ .ctl_name = CTL_UNNUMBERED,
27521 ++ .procname = "audit_textrel",
27522 ++ .data = &grsec_enable_audit_textrel,
27523 ++ .maxlen = sizeof(int),
27524 ++ .mode = 0600,
27525 ++ .proc_handler = &proc_dointvec,
27526 ++ },
27527 ++#endif
27528 ++#ifdef CONFIG_GRKERNSEC_DMESG
27529 ++ {
27530 ++ .ctl_name = CTL_UNNUMBERED,
27531 ++ .procname = "dmesg",
27532 ++ .data = &grsec_enable_dmesg,
27533 ++ .maxlen = sizeof(int),
27534 ++ .mode = 0600,
27535 ++ .proc_handler = &proc_dointvec,
27536 ++ },
27537 ++#endif
27538 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
27539 ++ {
27540 ++ .ctl_name = CTL_UNNUMBERED,
27541 ++ .procname = "chroot_findtask",
27542 ++ .data = &grsec_enable_chroot_findtask,
27543 ++ .maxlen = sizeof(int),
27544 ++ .mode = 0600,
27545 ++ .proc_handler = &proc_dointvec,
27546 ++ },
27547 ++#endif
27548 ++#ifdef CONFIG_GRKERNSEC_RESLOG
27549 ++ {
27550 ++ .ctl_name = CTL_UNNUMBERED,
27551 ++ .procname = "resource_logging",
27552 ++ .data = &grsec_resource_logging,
27553 ++ .maxlen = sizeof(int),
27554 ++ .mode = 0600,
27555 ++ .proc_handler = &proc_dointvec,
27556 ++ },
27557 ++#endif
27558 ++ {
27559 ++ .ctl_name = CTL_UNNUMBERED,
27560 ++ .procname = "grsec_lock",
27561 ++ .data = &grsec_lock,
27562 ++ .maxlen = sizeof(int),
27563 ++ .mode = 0600,
27564 ++ .proc_handler = &proc_dointvec,
27565 ++ },
27566 ++#endif
27567 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
27568 ++ {
27569 ++ .ctl_name = CTL_UNNUMBERED,
27570 ++ .procname = "disable_modules",
27571 ++ .data = &grsec_modstop,
27572 ++ .maxlen = sizeof(int),
27573 ++ .mode = 0600,
27574 ++ .proc_handler = &proc_dointvec,
27575 ++ },
27576 ++#endif
27577 ++ { .ctl_name = 0 }
27578 ++};
27579 ++#endif
27580 ++
27581 ++int gr_check_modstop(void)
27582 ++{
27583 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
27584 ++ if (grsec_modstop == 1) {
27585 ++ gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
27586 ++ return 1;
27587 ++ }
27588 ++#endif
27589 ++ return 0;
27590 ++}
27591 +diff -urNp linux-2.6.26.6/grsecurity/grsec_textrel.c linux-2.6.26.6/grsecurity/grsec_textrel.c
27592 +--- linux-2.6.26.6/grsecurity/grsec_textrel.c 1969-12-31 19:00:00.000000000 -0500
27593 ++++ linux-2.6.26.6/grsecurity/grsec_textrel.c 2008-10-11 21:54:20.000000000 -0400
27594 +@@ -0,0 +1,16 @@
27595 ++#include <linux/kernel.h>
27596 ++#include <linux/sched.h>
27597 ++#include <linux/mm.h>
27598 ++#include <linux/file.h>
27599 ++#include <linux/grinternal.h>
27600 ++#include <linux/grsecurity.h>
27601 ++
27602 ++void
27603 ++gr_log_textrel(struct vm_area_struct * vma)
27604 ++{
27605 ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
27606 ++ if (grsec_enable_audit_textrel)
27607 ++ gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
27608 ++#endif
27609 ++ return;
27610 ++}
27611 +diff -urNp linux-2.6.26.6/grsecurity/grsec_time.c linux-2.6.26.6/grsecurity/grsec_time.c
27612 +--- linux-2.6.26.6/grsecurity/grsec_time.c 1969-12-31 19:00:00.000000000 -0500
27613 ++++ linux-2.6.26.6/grsecurity/grsec_time.c 2008-10-11 21:54:20.000000000 -0400
27614 +@@ -0,0 +1,13 @@
27615 ++#include <linux/kernel.h>
27616 ++#include <linux/sched.h>
27617 ++#include <linux/grinternal.h>
27618 ++
27619 ++void
27620 ++gr_log_timechange(void)
27621 ++{
27622 ++#ifdef CONFIG_GRKERNSEC_TIME
27623 ++ if (grsec_enable_time)
27624 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
27625 ++#endif
27626 ++ return;
27627 ++}
27628 +diff -urNp linux-2.6.26.6/grsecurity/grsec_tpe.c linux-2.6.26.6/grsecurity/grsec_tpe.c
27629 +--- linux-2.6.26.6/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500
27630 ++++ linux-2.6.26.6/grsecurity/grsec_tpe.c 2008-10-11 21:54:20.000000000 -0400
27631 +@@ -0,0 +1,37 @@
27632 ++#include <linux/kernel.h>
27633 ++#include <linux/sched.h>
27634 ++#include <linux/file.h>
27635 ++#include <linux/fs.h>
27636 ++#include <linux/grinternal.h>
27637 ++
27638 ++extern int gr_acl_tpe_check(void);
27639 ++
27640 ++int
27641 ++gr_tpe_allow(const struct file *file)
27642 ++{
27643 ++#ifdef CONFIG_GRKERNSEC
27644 ++ struct inode *inode = file->f_path.dentry->d_parent->d_inode;
27645 ++
27646 ++ if (current->uid && ((grsec_enable_tpe &&
27647 ++#ifdef CONFIG_GRKERNSEC_TPE_INVERT
27648 ++ !in_group_p(grsec_tpe_gid)
27649 ++#else
27650 ++ in_group_p(grsec_tpe_gid)
27651 ++#endif
27652 ++ ) || gr_acl_tpe_check()) &&
27653 ++ (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
27654 ++ (inode->i_mode & S_IWOTH))))) {
27655 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
27656 ++ return 0;
27657 ++ }
27658 ++#ifdef CONFIG_GRKERNSEC_TPE_ALL
27659 ++ if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
27660 ++ ((inode->i_uid && (inode->i_uid != current->uid)) ||
27661 ++ (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
27662 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
27663 ++ return 0;
27664 ++ }
27665 ++#endif
27666 ++#endif
27667 ++ return 1;
27668 ++}
27669 +diff -urNp linux-2.6.26.6/grsecurity/grsum.c linux-2.6.26.6/grsecurity/grsum.c
27670 +--- linux-2.6.26.6/grsecurity/grsum.c 1969-12-31 19:00:00.000000000 -0500
27671 ++++ linux-2.6.26.6/grsecurity/grsum.c 2008-10-11 21:54:20.000000000 -0400
27672 +@@ -0,0 +1,59 @@
27673 ++#include <linux/err.h>
27674 ++#include <linux/kernel.h>
27675 ++#include <linux/sched.h>
27676 ++#include <linux/mm.h>
27677 ++#include <linux/scatterlist.h>
27678 ++#include <linux/crypto.h>
27679 ++#include <linux/gracl.h>
27680 ++
27681 ++
27682 ++#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
27683 ++#error "crypto and sha256 must be built into the kernel"
27684 ++#endif
27685 ++
27686 ++int
27687 ++chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
27688 ++{
27689 ++ char *p;
27690 ++ struct crypto_hash *tfm;
27691 ++ struct hash_desc desc;
27692 ++ struct scatterlist sg;
27693 ++ unsigned char temp_sum[GR_SHA_LEN];
27694 ++ volatile int retval = 0;
27695 ++ volatile int dummy = 0;
27696 ++ unsigned int i;
27697 ++
27698 ++ tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
27699 ++ if (IS_ERR(tfm)) {
27700 ++ /* should never happen, since sha256 should be built in */
27701 ++ return 1;
27702 ++ }
27703 ++
27704 ++ desc.tfm = tfm;
27705 ++ desc.flags = 0;
27706 ++
27707 ++ crypto_hash_init(&desc);
27708 ++
27709 ++ p = salt;
27710 ++ sg_set_buf(&sg, p, GR_SALT_LEN);
27711 ++ crypto_hash_update(&desc, &sg, sg.length);
27712 ++
27713 ++ p = entry->pw;
27714 ++ sg_set_buf(&sg, p, strlen(p));
27715 ++
27716 ++ crypto_hash_update(&desc, &sg, sg.length);
27717 ++
27718 ++ crypto_hash_final(&desc, temp_sum);
27719 ++
27720 ++ memset(entry->pw, 0, GR_PW_LEN);
27721 ++
27722 ++ for (i = 0; i < GR_SHA_LEN; i++)
27723 ++ if (sum[i] != temp_sum[i])
27724 ++ retval = 1;
27725 ++ else
27726 ++ dummy = 1; // waste a cycle
27727 ++
27728 ++ crypto_free_hash(tfm);
27729 ++
27730 ++ return retval;
27731 ++}
27732 +diff -urNp linux-2.6.26.6/grsecurity/Kconfig linux-2.6.26.6/grsecurity/Kconfig
27733 +--- linux-2.6.26.6/grsecurity/Kconfig 1969-12-31 19:00:00.000000000 -0500
27734 ++++ linux-2.6.26.6/grsecurity/Kconfig 2008-10-11 21:54:20.000000000 -0400
27735 +@@ -0,0 +1,863 @@
27736 ++#
27737 ++# grecurity configuration
27738 ++#
27739 ++
27740 ++menu "Grsecurity"
27741 ++
27742 ++config GRKERNSEC
27743 ++ bool "Grsecurity"
27744 ++ select CRYPTO
27745 ++ select CRYPTO_SHA256
27746 ++ select SECURITY
27747 ++ select SECURITY_CAPABILITIES
27748 ++ help
27749 ++ If you say Y here, you will be able to configure many features
27750 ++ that will enhance the security of your system. It is highly
27751 ++ recommended that you say Y here and read through the help
27752 ++ for each option so that you fully understand the features and
27753 ++ can evaluate their usefulness for your machine.
27754 ++
27755 ++choice
27756 ++ prompt "Security Level"
27757 ++ depends on GRKERNSEC
27758 ++ default GRKERNSEC_CUSTOM
27759 ++
27760 ++config GRKERNSEC_LOW
27761 ++ bool "Low"
27762 ++ select GRKERNSEC_LINK
27763 ++ select GRKERNSEC_FIFO
27764 ++ select GRKERNSEC_EXECVE
27765 ++ select GRKERNSEC_RANDNET
27766 ++ select GRKERNSEC_DMESG
27767 ++ select GRKERNSEC_CHROOT_CHDIR
27768 ++ select GRKERNSEC_MODSTOP if (MODULES)
27769 ++
27770 ++ help
27771 ++ If you choose this option, several of the grsecurity options will
27772 ++ be enabled that will give you greater protection against a number
27773 ++ of attacks, while assuring that none of your software will have any
27774 ++ conflicts with the additional security measures. If you run a lot
27775 ++ of unusual software, or you are having problems with the higher
27776 ++ security levels, you should say Y here. With this option, the
27777 ++ following features are enabled:
27778 ++
27779 ++ - Linking restrictions
27780 ++ - FIFO restrictions
27781 ++ - Enforcing RLIMIT_NPROC on execve
27782 ++ - Restricted dmesg
27783 ++ - Enforced chdir("/") on chroot
27784 ++ - Runtime module disabling
27785 ++
27786 ++config GRKERNSEC_MEDIUM
27787 ++ bool "Medium"
27788 ++ select PAX
27789 ++ select PAX_EI_PAX
27790 ++ select PAX_PT_PAX_FLAGS
27791 ++ select PAX_HAVE_ACL_FLAGS
27792 ++ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
27793 ++ select GRKERNSEC_CHROOT_SYSCTL
27794 ++ select GRKERNSEC_LINK
27795 ++ select GRKERNSEC_FIFO
27796 ++ select GRKERNSEC_EXECVE
27797 ++ select GRKERNSEC_DMESG
27798 ++ select GRKERNSEC_RANDNET
27799 ++ select GRKERNSEC_FORKFAIL
27800 ++ select GRKERNSEC_TIME
27801 ++ select GRKERNSEC_SIGNAL
27802 ++ select GRKERNSEC_CHROOT
27803 ++ select GRKERNSEC_CHROOT_UNIX
27804 ++ select GRKERNSEC_CHROOT_MOUNT
27805 ++ select GRKERNSEC_CHROOT_PIVOT
27806 ++ select GRKERNSEC_CHROOT_DOUBLE
27807 ++ select GRKERNSEC_CHROOT_CHDIR
27808 ++ select GRKERNSEC_CHROOT_MKNOD
27809 ++ select GRKERNSEC_PROC
27810 ++ select GRKERNSEC_PROC_USERGROUP
27811 ++ select GRKERNSEC_MODSTOP if (MODULES)
27812 ++ select PAX_RANDUSTACK
27813 ++ select PAX_ASLR
27814 ++ select PAX_RANDMMAP
27815 ++ select PAX_REFCOUNT
27816 ++
27817 ++ help
27818 ++ If you say Y here, several features in addition to those included
27819 ++ in the low additional security level will be enabled. These
27820 ++ features provide even more security to your system, though in rare
27821 ++ cases they may be incompatible with very old or poorly written
27822 ++ software. If you enable this option, make sure that your auth
27823 ++ service (identd) is running as gid 1001. With this option,
27824 ++ the following features (in addition to those provided in the
27825 ++ low additional security level) will be enabled:
27826 ++
27827 ++ - Failed fork logging
27828 ++ - Time change logging
27829 ++ - Signal logging
27830 ++ - Deny mounts in chroot
27831 ++ - Deny double chrooting
27832 ++ - Deny sysctl writes in chroot
27833 ++ - Deny mknod in chroot
27834 ++ - Deny access to abstract AF_UNIX sockets out of chroot
27835 ++ - Deny pivot_root in chroot
27836 ++ - Denied writes of /dev/kmem, /dev/mem, and /dev/port
27837 ++ - /proc restrictions with special GID set to 10 (usually wheel)
27838 ++ - Address Space Layout Randomization (ASLR)
27839 ++
27840 ++config GRKERNSEC_HIGH
27841 ++ bool "High"
27842 ++ select GRKERNSEC_LINK
27843 ++ select GRKERNSEC_FIFO
27844 ++ select GRKERNSEC_EXECVE
27845 ++ select GRKERNSEC_DMESG
27846 ++ select GRKERNSEC_FORKFAIL
27847 ++ select GRKERNSEC_TIME
27848 ++ select GRKERNSEC_SIGNAL
27849 ++ select GRKERNSEC_CHROOT_SHMAT
27850 ++ select GRKERNSEC_CHROOT_UNIX
27851 ++ select GRKERNSEC_CHROOT_MOUNT
27852 ++ select GRKERNSEC_CHROOT_FCHDIR
27853 ++ select GRKERNSEC_CHROOT_PIVOT
27854 ++ select GRKERNSEC_CHROOT_DOUBLE
27855 ++ select GRKERNSEC_CHROOT_CHDIR
27856 ++ select GRKERNSEC_CHROOT_MKNOD
27857 ++ select GRKERNSEC_CHROOT_CAPS
27858 ++ select GRKERNSEC_CHROOT_SYSCTL
27859 ++ select GRKERNSEC_CHROOT_FINDTASK
27860 ++ select GRKERNSEC_PROC
27861 ++ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
27862 ++ select GRKERNSEC_HIDESYM
27863 ++ select GRKERNSEC_BRUTE
27864 ++ select GRKERNSEC_PROC_USERGROUP
27865 ++ select GRKERNSEC_KMEM
27866 ++ select GRKERNSEC_RESLOG
27867 ++ select GRKERNSEC_RANDNET
27868 ++ select GRKERNSEC_PROC_ADD
27869 ++ select GRKERNSEC_CHROOT_CHMOD
27870 ++ select GRKERNSEC_CHROOT_NICE
27871 ++ select GRKERNSEC_AUDIT_MOUNT
27872 ++ select GRKERNSEC_MODSTOP if (MODULES)
27873 ++ select PAX
27874 ++ select PAX_RANDUSTACK
27875 ++ select PAX_ASLR
27876 ++ select PAX_RANDMMAP
27877 ++ select PAX_NOEXEC
27878 ++ select PAX_MPROTECT
27879 ++ select PAX_EI_PAX
27880 ++ select PAX_PT_PAX_FLAGS
27881 ++ select PAX_HAVE_ACL_FLAGS
27882 ++ select PAX_KERNEXEC if (X86 && !EFI && !COMPAT_VDSO && !PARAVIRT && (!X86_32 || X86_WP_WORKS_OK))
27883 ++ select PAX_MEMORY_UDEREF if (!X86_64 && !COMPAT_VDSO)
27884 ++ select PAX_RANDKSTACK if (X86_TSC && !X86_64)
27885 ++ select PAX_SEGMEXEC if (X86 && !X86_64)
27886 ++ select PAX_PAGEEXEC if (!X86)
27887 ++ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
27888 ++ select PAX_DLRESOLVE if (SPARC32 || SPARC64)
27889 ++ select PAX_SYSCALL if (PPC32)
27890 ++ select PAX_EMUTRAMP if (PARISC)
27891 ++ select PAX_EMUSIGRT if (PARISC)
27892 ++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
27893 ++ select PAX_REFCOUNT
27894 ++ help
27895 ++ If you say Y here, many of the features of grsecurity will be
27896 ++ enabled, which will protect you against many kinds of attacks
27897 ++ against your system. The heightened security comes at a cost
27898 ++ of an increased chance of incompatibilities with rare software
27899 ++ on your machine. Since this security level enables PaX, you should
27900 ++ view <http://pax.grsecurity.net> and read about the PaX
27901 ++ project. While you are there, download chpax and run it on
27902 ++ binaries that cause problems with PaX. Also remember that
27903 ++ since the /proc restrictions are enabled, you must run your
27904 ++ identd as gid 1001. This security level enables the following
27905 ++ features in addition to those listed in the low and medium
27906 ++ security levels:
27907 ++
27908 ++ - Additional /proc restrictions
27909 ++ - Chmod restrictions in chroot
27910 ++ - No signals, ptrace, or viewing of processes outside of chroot
27911 ++ - Capability restrictions in chroot
27912 ++ - Deny fchdir out of chroot
27913 ++ - Priority restrictions in chroot
27914 ++ - Segmentation-based implementation of PaX
27915 ++ - Mprotect restrictions
27916 ++ - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
27917 ++ - Kernel stack randomization
27918 ++ - Mount/unmount/remount logging
27919 ++ - Kernel symbol hiding
27920 ++ - Prevention of memory exhaustion-based exploits
27921 ++config GRKERNSEC_CUSTOM
27922 ++ bool "Custom"
27923 ++ help
27924 ++ If you say Y here, you will be able to configure every grsecurity
27925 ++ option, which allows you to enable many more features that aren't
27926 ++ covered in the basic security levels. These additional features
27927 ++ include TPE, socket restrictions, and the sysctl system for
27928 ++ grsecurity. It is advised that you read through the help for
27929 ++ each option to determine its usefulness in your situation.
27930 ++
27931 ++endchoice
27932 ++
27933 ++menu "Address Space Protection"
27934 ++depends on GRKERNSEC
27935 ++
27936 ++config GRKERNSEC_KMEM
27937 ++ bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
27938 ++ help
27939 ++ If you say Y here, /dev/kmem and /dev/mem won't be allowed to
27940 ++ be written to via mmap or otherwise to modify the running kernel.
27941 ++ /dev/port will also not be allowed to be opened. If you have module
27942 ++ support disabled, enabling this will close up four ways that are
27943 ++ currently used to insert malicious code into the running kernel.
27944 ++ Even with all these features enabled, we still highly recommend that
27945 ++ you use the RBAC system, as it is still possible for an attacker to
27946 ++ modify the running kernel through privileged I/O granted by ioperm/iopl.
27947 ++ If you are not using XFree86, you may be able to stop this additional
27948 ++ case by enabling the 'Disable privileged I/O' option. Though nothing
27949 ++ legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
27950 ++ but only to video memory, which is the only writing we allow in this
27951 ++ case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
27952 ++ not be allowed to mprotect it with PROT_WRITE later.
27953 ++ It is highly recommended that you say Y here if you meet all the
27954 ++ conditions above.
27955 ++
27956 ++config GRKERNSEC_IO
27957 ++ bool "Disable privileged I/O"
27958 ++ depends on X86
27959 ++ select RTC
27960 ++ help
27961 ++ If you say Y here, all ioperm and iopl calls will return an error.
27962 ++ Ioperm and iopl can be used to modify the running kernel.
27963 ++ Unfortunately, some programs need this access to operate properly,
27964 ++ the most notable of which are XFree86 and hwclock. hwclock can be
27965 ++ remedied by having RTC support in the kernel, so CONFIG_RTC is
27966 ++ enabled if this option is enabled, to ensure that hwclock operates
27967 ++ correctly. XFree86 still will not operate correctly with this option
27968 ++ enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86
27969 ++ and you still want to protect your kernel against modification,
27970 ++ use the RBAC system.
27971 ++
27972 ++config GRKERNSEC_PROC_MEMMAP
27973 ++ bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
27974 ++ depends on PAX_NOEXEC || PAX_ASLR
27975 ++ help
27976 ++ If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
27977 ++ give no information about the addresses of its mappings if
27978 ++ PaX features that rely on random addresses are enabled on the task.
27979 ++ If you use PaX it is greatly recommended that you say Y here as it
27980 ++ closes up a hole that makes the full ASLR useless for suid
27981 ++ binaries.
27982 ++
27983 ++config GRKERNSEC_BRUTE
27984 ++ bool "Deter exploit bruteforcing"
27985 ++ help
27986 ++ If you say Y here, attempts to bruteforce exploits against forking
27987 ++ daemons such as apache or sshd will be deterred. When a child of a
27988 ++ forking daemon is killed by PaX or crashes due to an illegal
27989 ++ instruction, the parent process will be delayed 30 seconds upon every
27990 ++ subsequent fork until the administrator is able to assess the
27991 ++ situation and restart the daemon. It is recommended that you also
27992 ++ enable signal logging in the auditing section so that logs are
27993 ++ generated when a process performs an illegal instruction.
27994 ++
27995 ++config GRKERNSEC_MODSTOP
27996 ++ bool "Runtime module disabling"
27997 ++ depends on MODULES
27998 ++ help
27999 ++ If you say Y here, you will be able to disable the ability to (un)load
28000 ++ modules at runtime. This feature is useful if you need the ability
28001 ++ to load kernel modules at boot time, but do not want to allow an
28002 ++ attacker to load a rootkit kernel module into the system, or to remove
28003 ++ a loaded kernel module important to system functioning. You should
28004 ++ enable the /dev/mem protection feature as well, since rootkits can be
28005 ++ inserted into the kernel via other methods than kernel modules. Since
28006 ++ an untrusted module could still be loaded by modifying init scripts and
28007 ++ rebooting the system, it is also recommended that you enable the RBAC
28008 ++ system. If you enable this option, a sysctl option with name
28009 ++ "disable_modules" will be created. Setting this option to "1" disables
28010 ++ module loading. After this option is set, no further writes to it are
28011 ++ allowed until the system is rebooted.
28012 ++
28013 ++config GRKERNSEC_HIDESYM
28014 ++ bool "Hide kernel symbols"
28015 ++ help
28016 ++ If you say Y here, getting information on loaded modules, and
28017 ++ displaying all kernel symbols through a syscall will be restricted
28018 ++ to users with CAP_SYS_MODULE. This option is only effective
28019 ++ provided the following conditions are met:
28020 ++ 1) The kernel using grsecurity is not precompiled by some distribution
28021 ++ 2) You are using the RBAC system and hiding other files such as your
28022 ++ kernel image and System.map
28023 ++ 3) You have the additional /proc restrictions enabled, which removes
28024 ++ /proc/kcore
28025 ++ If the above conditions are met, this option will aid to provide a
28026 ++ useful protection against local and remote kernel exploitation of
28027 ++ overflows and arbitrary read/write vulnerabilities.
28028 ++
28029 ++endmenu
28030 ++menu "Role Based Access Control Options"
28031 ++depends on GRKERNSEC
28032 ++
28033 ++config GRKERNSEC_ACL_HIDEKERN
28034 ++ bool "Hide kernel processes"
28035 ++ help
28036 ++ If you say Y here, all kernel threads will be hidden to all
28037 ++ processes but those whose subject has the "view hidden processes"
28038 ++ flag.
28039 ++
28040 ++config GRKERNSEC_ACL_MAXTRIES
28041 ++ int "Maximum tries before password lockout"
28042 ++ default 3
28043 ++ help
28044 ++ This option enforces the maximum number of times a user can attempt
28045 ++ to authorize themselves with the grsecurity RBAC system before being
28046 ++ denied the ability to attempt authorization again for a specified time.
28047 ++ The lower the number, the harder it will be to brute-force a password.
28048 ++
28049 ++config GRKERNSEC_ACL_TIMEOUT
28050 ++ int "Time to wait after max password tries, in seconds"
28051 ++ default 30
28052 ++ help
28053 ++ This option specifies the time the user must wait after attempting to
28054 ++ authorize to the RBAC system with the maximum number of invalid
28055 ++ passwords. The higher the number, the harder it will be to brute-force
28056 ++ a password.
28057 ++
28058 ++endmenu
28059 ++menu "Filesystem Protections"
28060 ++depends on GRKERNSEC
28061 ++
28062 ++config GRKERNSEC_PROC
28063 ++ bool "Proc restrictions"
28064 ++ help
28065 ++ If you say Y here, the permissions of the /proc filesystem
28066 ++ will be altered to enhance system security and privacy. You MUST
28067 ++ choose either a user only restriction or a user and group restriction.
28068 ++ Depending upon the option you choose, you can either restrict users to
28069 ++ see only the processes they themselves run, or choose a group that can
28070 ++ view all processes and files normally restricted to root if you choose
28071 ++ the "restrict to user only" option. NOTE: If you're running identd as
28072 ++ a non-root user, you will have to run it as the group you specify here.
28073 ++
28074 ++config GRKERNSEC_PROC_USER
28075 ++ bool "Restrict /proc to user only"
28076 ++ depends on GRKERNSEC_PROC
28077 ++ help
28078 ++ If you say Y here, non-root users will only be able to view their own
28079 ++ processes, and restricts them from viewing network-related information,
28080 ++ and viewing kernel symbol and module information.
28081 ++
28082 ++config GRKERNSEC_PROC_USERGROUP
28083 ++ bool "Allow special group"
28084 ++ depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
28085 ++ help
28086 ++ If you say Y here, you will be able to select a group that will be
28087 ++ able to view all processes, network-related information, and
28088 ++ kernel and symbol information. This option is useful if you want
28089 ++ to run identd as a non-root user.
28090 ++
28091 ++config GRKERNSEC_PROC_GID
28092 ++ int "GID for special group"
28093 ++ depends on GRKERNSEC_PROC_USERGROUP
28094 ++ default 1001
28095 ++
28096 ++config GRKERNSEC_PROC_ADD
28097 ++ bool "Additional restrictions"
28098 ++ depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
28099 ++ help
28100 ++ If you say Y here, additional restrictions will be placed on
28101 ++ /proc that keep normal users from viewing device information and
28102 ++ slabinfo information that could be useful for exploits.
28103 ++
28104 ++config GRKERNSEC_LINK
28105 ++ bool "Linking restrictions"
28106 ++ help
28107 ++ If you say Y here, /tmp race exploits will be prevented, since users
28108 ++ will no longer be able to follow symlinks owned by other users in
28109 ++ world-writable +t directories (i.e. /tmp), unless the owner of the
28110 ++ symlink is the owner of the directory. users will also not be
28111 ++ able to hardlink to files they do not own. If the sysctl option is
28112 ++ enabled, a sysctl option with name "linking_restrictions" is created.
28113 ++
28114 ++config GRKERNSEC_FIFO
28115 ++ bool "FIFO restrictions"
28116 ++ help
28117 ++ If you say Y here, users will not be able to write to FIFOs they don't
28118 ++ own in world-writable +t directories (i.e. /tmp), unless the owner of
28119 ++ the FIFO is the same owner of the directory it's held in. If the sysctl
28120 ++ option is enabled, a sysctl option with name "fifo_restrictions" is
28121 ++ created.
28122 ++
28123 ++config GRKERNSEC_CHROOT
28124 ++ bool "Chroot jail restrictions"
28125 ++ help
28126 ++ If you say Y here, you will be able to choose several options that will
28127 ++ make breaking out of a chrooted jail much more difficult. If you
28128 ++ encounter no software incompatibilities with the following options, it
28129 ++ is recommended that you enable each one.
28130 ++
28131 ++config GRKERNSEC_CHROOT_MOUNT
28132 ++ bool "Deny mounts"
28133 ++ depends on GRKERNSEC_CHROOT
28134 ++ help
28135 ++ If you say Y here, processes inside a chroot will not be able to
28136 ++ mount or remount filesystems. If the sysctl option is enabled, a
28137 ++ sysctl option with name "chroot_deny_mount" is created.
28138 ++
28139 ++config GRKERNSEC_CHROOT_DOUBLE
28140 ++ bool "Deny double-chroots"
28141 ++ depends on GRKERNSEC_CHROOT
28142 ++ help
28143 ++ If you say Y here, processes inside a chroot will not be able to chroot
28144 ++ again outside the chroot. This is a widely used method of breaking
28145 ++ out of a chroot jail and should not be allowed. If the sysctl
28146 ++ option is enabled, a sysctl option with name
28147 ++ "chroot_deny_chroot" is created.
28148 ++
28149 ++config GRKERNSEC_CHROOT_PIVOT
28150 ++ bool "Deny pivot_root in chroot"
28151 ++ depends on GRKERNSEC_CHROOT
28152 ++ help
28153 ++ If you say Y here, processes inside a chroot will not be able to use
28154 ++ a function called pivot_root() that was introduced in Linux 2.3.41. It
28155 ++ works similar to chroot in that it changes the root filesystem. This
28156 ++ function could be misused in a chrooted process to attempt to break out
28157 ++ of the chroot, and therefore should not be allowed. If the sysctl
28158 ++ option is enabled, a sysctl option with name "chroot_deny_pivot" is
28159 ++ created.
28160 ++
28161 ++config GRKERNSEC_CHROOT_CHDIR
28162 ++ bool "Enforce chdir(\"/\") on all chroots"
28163 ++ depends on GRKERNSEC_CHROOT
28164 ++ help
28165 ++ If you say Y here, the current working directory of all newly-chrooted
28166 ++ applications will be set to the the root directory of the chroot.
28167 ++ The man page on chroot(2) states:
28168 ++ Note that this call does not change the current working
28169 ++ directory, so that `.' can be outside the tree rooted at
28170 ++ `/'. In particular, the super-user can escape from a
28171 ++ `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
28172 ++
28173 ++ It is recommended that you say Y here, since it's not known to break
28174 ++ any software. If the sysctl option is enabled, a sysctl option with
28175 ++ name "chroot_enforce_chdir" is created.
28176 ++
28177 ++config GRKERNSEC_CHROOT_CHMOD
28178 ++ bool "Deny (f)chmod +s"
28179 ++ depends on GRKERNSEC_CHROOT
28180 ++ help
28181 ++ If you say Y here, processes inside a chroot will not be able to chmod
28182 ++ or fchmod files to make them have suid or sgid bits. This protects
28183 ++ against another published method of breaking a chroot. If the sysctl
28184 ++ option is enabled, a sysctl option with name "chroot_deny_chmod" is
28185 ++ created.
28186 ++
28187 ++config GRKERNSEC_CHROOT_FCHDIR
28188 ++ bool "Deny fchdir out of chroot"
28189 ++ depends on GRKERNSEC_CHROOT
28190 ++ help
28191 ++ If you say Y here, a well-known method of breaking chroots by fchdir'ing
28192 ++ to a file descriptor of the chrooting process that points to a directory
28193 ++ outside the filesystem will be stopped. If the sysctl option
28194 ++ is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
28195 ++
28196 ++config GRKERNSEC_CHROOT_MKNOD
28197 ++ bool "Deny mknod"
28198 ++ depends on GRKERNSEC_CHROOT
28199 ++ help
28200 ++ If you say Y here, processes inside a chroot will not be allowed to
28201 ++ mknod. The problem with using mknod inside a chroot is that it
28202 ++ would allow an attacker to create a device entry that is the same
28203 ++ as one on the physical root of your system, which could range from
28204 ++ anything from the console device to a device for your harddrive (which
28205 ++ they could then use to wipe the drive or steal data). It is recommended
28206 ++ that you say Y here, unless you run into software incompatibilities.
28207 ++ If the sysctl option is enabled, a sysctl option with name
28208 ++ "chroot_deny_mknod" is created.
28209 ++
28210 ++config GRKERNSEC_CHROOT_SHMAT
28211 ++ bool "Deny shmat() out of chroot"
28212 ++ depends on GRKERNSEC_CHROOT
28213 ++ help
28214 ++ If you say Y here, processes inside a chroot will not be able to attach
28215 ++ to shared memory segments that were created outside of the chroot jail.
28216 ++ It is recommended that you say Y here. If the sysctl option is enabled,
28217 ++ a sysctl option with name "chroot_deny_shmat" is created.
28218 ++
28219 ++config GRKERNSEC_CHROOT_UNIX
28220 ++ bool "Deny access to abstract AF_UNIX sockets out of chroot"
28221 ++ depends on GRKERNSEC_CHROOT
28222 ++ help
28223 ++ If you say Y here, processes inside a chroot will not be able to
28224 ++ connect to abstract (meaning not belonging to a filesystem) Unix
28225 ++ domain sockets that were bound outside of a chroot. It is recommended
28226 ++ that you say Y here. If the sysctl option is enabled, a sysctl option
28227 ++ with name "chroot_deny_unix" is created.
28228 ++
28229 ++config GRKERNSEC_CHROOT_FINDTASK
28230 ++ bool "Protect outside processes"
28231 ++ depends on GRKERNSEC_CHROOT
28232 ++ help
28233 ++ If you say Y here, processes inside a chroot will not be able to
28234 ++ kill, send signals with fcntl, ptrace, capget, getpgid, getsid,
28235 ++ or view any process outside of the chroot. If the sysctl
28236 ++ option is enabled, a sysctl option with name "chroot_findtask" is
28237 ++ created.
28238 ++
28239 ++config GRKERNSEC_CHROOT_NICE
28240 ++ bool "Restrict priority changes"
28241 ++ depends on GRKERNSEC_CHROOT
28242 ++ help
28243 ++ If you say Y here, processes inside a chroot will not be able to raise
28244 ++ the priority of processes in the chroot, or alter the priority of
28245 ++ processes outside the chroot. This provides more security than simply
28246 ++ removing CAP_SYS_NICE from the process' capability set. If the
28247 ++ sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
28248 ++ is created.
28249 ++
28250 ++config GRKERNSEC_CHROOT_SYSCTL
28251 ++ bool "Deny sysctl writes"
28252 ++ depends on GRKERNSEC_CHROOT
28253 ++ help
28254 ++ If you say Y here, an attacker in a chroot will not be able to
28255 ++ write to sysctl entries, either by sysctl(2) or through a /proc
28256 ++ interface. It is strongly recommended that you say Y here. If the
28257 ++ sysctl option is enabled, a sysctl option with name
28258 ++ "chroot_deny_sysctl" is created.
28259 ++
28260 ++config GRKERNSEC_CHROOT_CAPS
28261 ++ bool "Capability restrictions"
28262 ++ depends on GRKERNSEC_CHROOT
28263 ++ help
28264 ++ If you say Y here, the capabilities on all root processes within a
28265 ++ chroot jail will be lowered to stop module insertion, raw i/o,
28266 ++ system and net admin tasks, rebooting the system, modifying immutable
28267 ++ files, modifying IPC owned by another, and changing the system time.
28268 ++ This is left an option because it can break some apps. Disable this
28269 ++ if your chrooted apps are having problems performing those kinds of
28270 ++ tasks. If the sysctl option is enabled, a sysctl option with
28271 ++ name "chroot_caps" is created.
28272 ++
28273 ++endmenu
28274 ++menu "Kernel Auditing"
28275 ++depends on GRKERNSEC
28276 ++
28277 ++config GRKERNSEC_AUDIT_GROUP
28278 ++ bool "Single group for auditing"
28279 ++ help
28280 ++ If you say Y here, the exec, chdir, (un)mount, and ipc logging features
28281 ++ will only operate on a group you specify. This option is recommended
28282 ++ if you only want to watch certain users instead of having a large
28283 ++ amount of logs from the entire system. If the sysctl option is enabled,
28284 ++ a sysctl option with name "audit_group" is created.
28285 ++
28286 ++config GRKERNSEC_AUDIT_GID
28287 ++ int "GID for auditing"
28288 ++ depends on GRKERNSEC_AUDIT_GROUP
28289 ++ default 1007
28290 ++
28291 ++config GRKERNSEC_EXECLOG
28292 ++ bool "Exec logging"
28293 ++ help
28294 ++ If you say Y here, all execve() calls will be logged (since the
28295 ++ other exec*() calls are frontends to execve(), all execution
28296 ++ will be logged). Useful for shell-servers that like to keep track
28297 ++ of their users. If the sysctl option is enabled, a sysctl option with
28298 ++ name "exec_logging" is created.
28299 ++ WARNING: This option when enabled will produce a LOT of logs, especially
28300 ++ on an active system.
28301 ++
28302 ++config GRKERNSEC_RESLOG
28303 ++ bool "Resource logging"
28304 ++ help
28305 ++ If you say Y here, all attempts to overstep resource limits will
28306 ++ be logged with the resource name, the requested size, and the current
28307 ++ limit. It is highly recommended that you say Y here. If the sysctl
28308 ++ option is enabled, a sysctl option with name "resource_logging" is
28309 ++ created. If the RBAC system is enabled, the sysctl value is ignored.
28310 ++
28311 ++config GRKERNSEC_CHROOT_EXECLOG
28312 ++ bool "Log execs within chroot"
28313 ++ help
28314 ++ If you say Y here, all executions inside a chroot jail will be logged
28315 ++ to syslog. This can cause a large amount of logs if certain
28316 ++ applications (eg. djb's daemontools) are installed on the system, and
28317 ++ is therefore left as an option. If the sysctl option is enabled, a
28318 ++ sysctl option with name "chroot_execlog" is created.
28319 ++
28320 ++config GRKERNSEC_AUDIT_CHDIR
28321 ++ bool "Chdir logging"
28322 ++ help
28323 ++ If you say Y here, all chdir() calls will be logged. If the sysctl
28324 ++ option is enabled, a sysctl option with name "audit_chdir" is created.
28325 ++
28326 ++config GRKERNSEC_AUDIT_MOUNT
28327 ++ bool "(Un)Mount logging"
28328 ++ help
28329 ++ If you say Y here, all mounts and unmounts will be logged. If the
28330 ++ sysctl option is enabled, a sysctl option with name "audit_mount" is
28331 ++ created.
28332 ++
28333 ++config GRKERNSEC_AUDIT_IPC
28334 ++ bool "IPC logging"
28335 ++ help
28336 ++ If you say Y here, creation and removal of message queues, semaphores,
28337 ++ and shared memory will be logged. If the sysctl option is enabled, a
28338 ++ sysctl option with name "audit_ipc" is created.
28339 ++
28340 ++config GRKERNSEC_SIGNAL
28341 ++ bool "Signal logging"
28342 ++ help
28343 ++ If you say Y here, certain important signals will be logged, such as
28344 ++ SIGSEGV, which will as a result inform you of when a error in a program
28345 ++ occurred, which in some cases could mean a possible exploit attempt.
28346 ++ If the sysctl option is enabled, a sysctl option with name
28347 ++ "signal_logging" is created.
28348 ++
28349 ++config GRKERNSEC_FORKFAIL
28350 ++ bool "Fork failure logging"
28351 ++ help
28352 ++ If you say Y here, all failed fork() attempts will be logged.
28353 ++ This could suggest a fork bomb, or someone attempting to overstep
28354 ++ their process limit. If the sysctl option is enabled, a sysctl option
28355 ++ with name "forkfail_logging" is created.
28356 ++
28357 ++config GRKERNSEC_TIME
28358 ++ bool "Time change logging"
28359 ++ help
28360 ++ If you say Y here, any changes of the system clock will be logged.
28361 ++ If the sysctl option is enabled, a sysctl option with name
28362 ++ "timechange_logging" is created.
28363 ++
28364 ++config GRKERNSEC_PROC_IPADDR
28365 ++ bool "/proc/<pid>/ipaddr support"
28366 ++ help
28367 ++ If you say Y here, a new entry will be added to each /proc/<pid>
28368 ++ directory that contains the IP address of the person using the task.
28369 ++ The IP is carried across local TCP and AF_UNIX stream sockets.
28370 ++ This information can be useful for IDS/IPSes to perform remote response
28371 ++ to a local attack. The entry is readable by only the owner of the
28372 ++ process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
28373 ++ the RBAC system), and thus does not create privacy concerns.
28374 ++
28375 ++config GRKERNSEC_AUDIT_TEXTREL
28376 ++ bool 'ELF text relocations logging (READ HELP)'
28377 ++ depends on PAX_MPROTECT
28378 ++ help
28379 ++ If you say Y here, text relocations will be logged with the filename
28380 ++ of the offending library or binary. The purpose of the feature is
28381 ++ to help Linux distribution developers get rid of libraries and
28382 ++ binaries that need text relocations which hinder the future progress
28383 ++ of PaX. Only Linux distribution developers should say Y here, and
28384 ++ never on a production machine, as this option creates an information
28385 ++ leak that could aid an attacker in defeating the randomization of
28386 ++ a single memory region. If the sysctl option is enabled, a sysctl
28387 ++ option with name "audit_textrel" is created.
28388 ++
28389 ++endmenu
28390 ++
28391 ++menu "Executable Protections"
28392 ++depends on GRKERNSEC
28393 ++
28394 ++config GRKERNSEC_EXECVE
28395 ++ bool "Enforce RLIMIT_NPROC on execs"
28396 ++ help
28397 ++ If you say Y here, users with a resource limit on processes will
28398 ++ have the value checked during execve() calls. The current system
28399 ++ only checks the system limit during fork() calls. If the sysctl option
28400 ++ is enabled, a sysctl option with name "execve_limiting" is created.
28401 ++
28402 ++config GRKERNSEC_DMESG
28403 ++ bool "Dmesg(8) restriction"
28404 ++ help
28405 ++ If you say Y here, non-root users will not be able to use dmesg(8)
28406 ++ to view up to the last 4kb of messages in the kernel's log buffer.
28407 ++ If the sysctl option is enabled, a sysctl option with name "dmesg" is
28408 ++ created.
28409 ++
28410 ++config GRKERNSEC_TPE
28411 ++ bool "Trusted Path Execution (TPE)"
28412 ++ help
28413 ++ If you say Y here, you will be able to choose a gid to add to the
28414 ++ supplementary groups of users you want to mark as "untrusted."
28415 ++ These users will not be able to execute any files that are not in
28416 ++ root-owned directories writable only by root. If the sysctl option
28417 ++ is enabled, a sysctl option with name "tpe" is created.
28418 ++
28419 ++config GRKERNSEC_TPE_ALL
28420 ++ bool "Partially restrict non-root users"
28421 ++ depends on GRKERNSEC_TPE
28422 ++ help
28423 ++ If you say Y here, All non-root users other than the ones in the
28424 ++ group specified in the main TPE option will only be allowed to
28425 ++ execute files in directories they own that are not group or
28426 ++ world-writable, or in directories owned by root and writable only by
28427 ++ root. If the sysctl option is enabled, a sysctl option with name
28428 ++ "tpe_restrict_all" is created.
28429 ++
28430 ++config GRKERNSEC_TPE_INVERT
28431 ++ bool "Invert GID option"
28432 ++ depends on GRKERNSEC_TPE
28433 ++ help
28434 ++ If you say Y here, the group you specify in the TPE configuration will
28435 ++ decide what group TPE restrictions will be *disabled* for. This
28436 ++ option is useful if you want TPE restrictions to be applied to most
28437 ++ users on the system.
28438 ++
28439 ++config GRKERNSEC_TPE_GID
28440 ++ int "GID for untrusted users"
28441 ++ depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
28442 ++ default 1005
28443 ++ help
28444 ++ If you have selected the "Invert GID option" above, setting this
28445 ++ GID determines what group TPE restrictions will be *disabled* for.
28446 ++ If you have not selected the "Invert GID option" above, setting this
28447 ++ GID determines what group TPE restrictions will be *enabled* for.
28448 ++ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
28449 ++ is created.
28450 ++
28451 ++config GRKERNSEC_TPE_GID
28452 ++ int "GID for trusted users"
28453 ++ depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
28454 ++ default 1005
28455 ++ help
28456 ++ If you have selected the "Invert GID option" above, setting this
28457 ++ GID determines what group TPE restrictions will be *disabled* for.
28458 ++ If you have not selected the "Invert GID option" above, setting this
28459 ++ GID determines what group TPE restrictions will be *enabled* for.
28460 ++ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
28461 ++ is created.
28462 ++
28463 ++endmenu
28464 ++menu "Network Protections"
28465 ++depends on GRKERNSEC
28466 ++
28467 ++config GRKERNSEC_RANDNET
28468 ++ bool "Larger entropy pools"
28469 ++ help
28470 ++ If you say Y here, the entropy pools used for many features of Linux
28471 ++ and grsecurity will be doubled in size. Since several grsecurity
28472 ++ features use additional randomness, it is recommended that you say Y
28473 ++ here. Saying Y here has a similar effect as modifying
28474 ++ /proc/sys/kernel/random/poolsize.
28475 ++
28476 ++config GRKERNSEC_SOCKET
28477 ++ bool "Socket restrictions"
28478 ++ help
28479 ++ If you say Y here, you will be able to choose from several options.
28480 ++ If you assign a GID on your system and add it to the supplementary
28481 ++ groups of users you want to restrict socket access to, this patch
28482 ++ will perform up to three things, based on the option(s) you choose.
28483 ++
28484 ++config GRKERNSEC_SOCKET_ALL
28485 ++ bool "Deny any sockets to group"
28486 ++ depends on GRKERNSEC_SOCKET
28487 ++ help
28488 ++ If you say Y here, you will be able to choose a GID of whose users will
28489 ++ be unable to connect to other hosts from your machine or run server
28490 ++ applications from your machine. If the sysctl option is enabled, a
28491 ++ sysctl option with name "socket_all" is created.
28492 ++
28493 ++config GRKERNSEC_SOCKET_ALL_GID
28494 ++ int "GID to deny all sockets for"
28495 ++ depends on GRKERNSEC_SOCKET_ALL
28496 ++ default 1004
28497 ++ help
28498 ++ Here you can choose the GID to disable socket access for. Remember to
28499 ++ add the users you want socket access disabled for to the GID
28500 ++ specified here. If the sysctl option is enabled, a sysctl option
28501 ++ with name "socket_all_gid" is created.
28502 ++
28503 ++config GRKERNSEC_SOCKET_CLIENT
28504 ++ bool "Deny client sockets to group"
28505 ++ depends on GRKERNSEC_SOCKET
28506 ++ help
28507 ++ If you say Y here, you will be able to choose a GID of whose users will
28508 ++ be unable to connect to other hosts from your machine, but will be
28509 ++ able to run servers. If this option is enabled, all users in the group
28510 ++ you specify will have to use passive mode when initiating ftp transfers
28511 ++ from the shell on your machine. If the sysctl option is enabled, a
28512 ++ sysctl option with name "socket_client" is created.
28513 ++
28514 ++config GRKERNSEC_SOCKET_CLIENT_GID
28515 ++ int "GID to deny client sockets for"
28516 ++ depends on GRKERNSEC_SOCKET_CLIENT
28517 ++ default 1003
28518 ++ help
28519 ++ Here you can choose the GID to disable client socket access for.
28520 ++ Remember to add the users you want client socket access disabled for to
28521 ++ the GID specified here. If the sysctl option is enabled, a sysctl
28522 ++ option with name "socket_client_gid" is created.
28523 ++
28524 ++config GRKERNSEC_SOCKET_SERVER
28525 ++ bool "Deny server sockets to group"
28526 ++ depends on GRKERNSEC_SOCKET
28527 ++ help
28528 ++ If you say Y here, you will be able to choose a GID of whose users will
28529 ++ be unable to run server applications from your machine. If the sysctl
28530 ++ option is enabled, a sysctl option with name "socket_server" is created.
28531 ++
28532 ++config GRKERNSEC_SOCKET_SERVER_GID
28533 ++ int "GID to deny server sockets for"
28534 ++ depends on GRKERNSEC_SOCKET_SERVER
28535 ++ default 1002
28536 ++ help
28537 ++ Here you can choose the GID to disable server socket access for.
28538 ++ Remember to add the users you want server socket access disabled for to
28539 ++ the GID specified here. If the sysctl option is enabled, a sysctl
28540 ++ option with name "socket_server_gid" is created.
28541 ++
28542 ++endmenu
28543 ++menu "Sysctl support"
28544 ++depends on GRKERNSEC && SYSCTL
28545 ++
28546 ++config GRKERNSEC_SYSCTL
28547 ++ bool "Sysctl support"
28548 ++ help
28549 ++ If you say Y here, you will be able to change the options that
28550 ++ grsecurity runs with at bootup, without having to recompile your
28551 ++ kernel. You can echo values to files in /proc/sys/kernel/grsecurity
28552 ++ to enable (1) or disable (0) various features. All the sysctl entries
28553 ++ are mutable until the "grsec_lock" entry is set to a non-zero value.
28554 ++ All features enabled in the kernel configuration are disabled at boot
28555 ++ if you do not say Y to the "Turn on features by default" option.
28556 ++ All options should be set at startup, and the grsec_lock entry should
28557 ++ be set to a non-zero value after all the options are set.
28558 ++ *THIS IS EXTREMELY IMPORTANT*
28559 ++
28560 ++config GRKERNSEC_SYSCTL_ON
28561 ++ bool "Turn on features by default"
28562 ++ depends on GRKERNSEC_SYSCTL
28563 ++ help
28564 ++ If you say Y here, instead of having all features enabled in the
28565 ++ kernel configuration disabled at boot time, the features will be
28566 ++ enabled at boot time. It is recommended you say Y here unless
28567 ++ there is some reason you would want all sysctl-tunable features to
28568 ++ be disabled by default. As mentioned elsewhere, it is important
28569 ++ to enable the grsec_lock entry once you have finished modifying
28570 ++ the sysctl entries.
28571 ++
28572 ++endmenu
28573 ++menu "Logging Options"
28574 ++depends on GRKERNSEC
28575 ++
28576 ++config GRKERNSEC_FLOODTIME
28577 ++ int "Seconds in between log messages (minimum)"
28578 ++ default 10
28579 ++ help
28580 ++ This option allows you to enforce the number of seconds between
28581 ++ grsecurity log messages. The default should be suitable for most
28582 ++ people, however, if you choose to change it, choose a value small enough
28583 ++ to allow informative logs to be produced, but large enough to
28584 ++ prevent flooding.
28585 ++
28586 ++config GRKERNSEC_FLOODBURST
28587 ++ int "Number of messages in a burst (maximum)"
28588 ++ default 4
28589 ++ help
28590 ++ This option allows you to choose the maximum number of messages allowed
28591 ++ within the flood time interval you chose in a separate option. The
28592 ++ default should be suitable for most people, however if you find that
28593 ++ many of your logs are being interpreted as flooding, you may want to
28594 ++ raise this value.
28595 ++
28596 ++endmenu
28597 ++
28598 ++endmenu
28599 +diff -urNp linux-2.6.26.6/grsecurity/Makefile linux-2.6.26.6/grsecurity/Makefile
28600 +--- linux-2.6.26.6/grsecurity/Makefile 1969-12-31 19:00:00.000000000 -0500
28601 ++++ linux-2.6.26.6/grsecurity/Makefile 2008-10-11 21:54:20.000000000 -0400
28602 +@@ -0,0 +1,20 @@
28603 ++# grsecurity's ACL system was originally written in 2001 by Michael Dalton
28604 ++# during 2001-2005 it has been completely redesigned by Brad Spengler
28605 ++# into an RBAC system
28606 ++#
28607 ++# All code in this directory and various hooks inserted throughout the kernel
28608 ++# are copyright Brad Spengler, and released under the GPL v2 or higher
28609 ++
28610 ++obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
28611 ++ grsec_mount.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
28612 ++ grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
28613 ++
28614 ++obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
28615 ++ gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
28616 ++ gracl_learn.o grsec_log.o
28617 ++obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
28618 ++
28619 ++ifndef CONFIG_GRKERNSEC
28620 ++obj-y += grsec_disabled.o
28621 ++endif
28622 ++
28623 +diff -urNp linux-2.6.26.6/include/asm-alpha/elf.h linux-2.6.26.6/include/asm-alpha/elf.h
28624 +--- linux-2.6.26.6/include/asm-alpha/elf.h 2008-10-08 23:24:05.000000000 -0400
28625 ++++ linux-2.6.26.6/include/asm-alpha/elf.h 2008-10-11 21:54:20.000000000 -0400
28626 +@@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
28627 +
28628 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
28629 +
28630 ++#ifdef CONFIG_PAX_ASLR
28631 ++#define PAX_ELF_ET_DYN_BASE (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
28632 ++
28633 ++#define PAX_DELTA_MMAP_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 28)
28634 ++#define PAX_DELTA_STACK_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 19)
28635 ++#endif
28636 ++
28637 + /* $0 is set by ld.so to a pointer to a function which might be
28638 + registered using atexit. This provides a mean for the dynamic
28639 + linker to call DT_FINI functions for shared libraries that have
28640 +diff -urNp linux-2.6.26.6/include/asm-alpha/kmap_types.h linux-2.6.26.6/include/asm-alpha/kmap_types.h
28641 +--- linux-2.6.26.6/include/asm-alpha/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28642 ++++ linux-2.6.26.6/include/asm-alpha/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28643 +@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
28644 + D(10) KM_IRQ1,
28645 + D(11) KM_SOFTIRQ0,
28646 + D(12) KM_SOFTIRQ1,
28647 +-D(13) KM_TYPE_NR
28648 ++D(13) KM_CLEARPAGE,
28649 ++D(14) KM_TYPE_NR
28650 + };
28651 +
28652 + #undef D
28653 +diff -urNp linux-2.6.26.6/include/asm-alpha/pgtable.h linux-2.6.26.6/include/asm-alpha/pgtable.h
28654 +--- linux-2.6.26.6/include/asm-alpha/pgtable.h 2008-10-08 23:24:05.000000000 -0400
28655 ++++ linux-2.6.26.6/include/asm-alpha/pgtable.h 2008-10-11 21:54:20.000000000 -0400
28656 +@@ -101,6 +101,17 @@ struct vm_area_struct;
28657 + #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
28658 + #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
28659 + #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
28660 ++
28661 ++#ifdef CONFIG_PAX_PAGEEXEC
28662 ++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
28663 ++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
28664 ++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
28665 ++#else
28666 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
28667 ++# define PAGE_COPY_NOEXEC PAGE_COPY
28668 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
28669 ++#endif
28670 ++
28671 + #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
28672 +
28673 + #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
28674 +diff -urNp linux-2.6.26.6/include/asm-arm/elf.h linux-2.6.26.6/include/asm-arm/elf.h
28675 +--- linux-2.6.26.6/include/asm-arm/elf.h 2008-10-08 23:24:05.000000000 -0400
28676 ++++ linux-2.6.26.6/include/asm-arm/elf.h 2008-10-11 21:54:20.000000000 -0400
28677 +@@ -87,7 +87,14 @@ extern char elf_platform[];
28678 + the loader. We need to make sure that it is out of the way of the program
28679 + that it will "exec", and that there is sufficient room for the brk. */
28680 +
28681 +-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
28682 ++#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
28683 ++
28684 ++#ifdef CONFIG_PAX_ASLR
28685 ++#define PAX_ELF_ET_DYN_BASE 0x00008000UL
28686 ++
28687 ++#define PAX_DELTA_MMAP_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
28688 ++#define PAX_DELTA_STACK_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
28689 ++#endif
28690 +
28691 + /* When the program starts, a1 contains a pointer to a function to be
28692 + registered with atexit, as per the SVR4 ABI. A value of 0 means we
28693 +diff -urNp linux-2.6.26.6/include/asm-arm/kmap_types.h linux-2.6.26.6/include/asm-arm/kmap_types.h
28694 +--- linux-2.6.26.6/include/asm-arm/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28695 ++++ linux-2.6.26.6/include/asm-arm/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28696 +@@ -18,6 +18,7 @@ enum km_type {
28697 + KM_IRQ1,
28698 + KM_SOFTIRQ0,
28699 + KM_SOFTIRQ1,
28700 ++ KM_CLEARPAGE,
28701 + KM_TYPE_NR
28702 + };
28703 +
28704 +diff -urNp linux-2.6.26.6/include/asm-avr32/elf.h linux-2.6.26.6/include/asm-avr32/elf.h
28705 +--- linux-2.6.26.6/include/asm-avr32/elf.h 2008-10-08 23:24:05.000000000 -0400
28706 ++++ linux-2.6.26.6/include/asm-avr32/elf.h 2008-10-11 21:54:20.000000000 -0400
28707 +@@ -85,8 +85,14 @@ typedef struct user_fpu_struct elf_fpreg
28708 + the loader. We need to make sure that it is out of the way of the program
28709 + that it will "exec", and that there is sufficient room for the brk. */
28710 +
28711 +-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
28712 ++#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
28713 +
28714 ++#ifdef CONFIG_PAX_ASLR
28715 ++#define PAX_ELF_ET_DYN_BASE 0x00001000UL
28716 ++
28717 ++#define PAX_DELTA_MMAP_LEN 15
28718 ++#define PAX_DELTA_STACK_LEN 15
28719 ++#endif
28720 +
28721 + /* This yields a mask that user programs can use to figure out what
28722 + instruction set this CPU supports. This could be done in user space,
28723 +diff -urNp linux-2.6.26.6/include/asm-avr32/kmap_types.h linux-2.6.26.6/include/asm-avr32/kmap_types.h
28724 +--- linux-2.6.26.6/include/asm-avr32/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28725 ++++ linux-2.6.26.6/include/asm-avr32/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28726 +@@ -22,7 +22,8 @@ D(10) KM_IRQ0,
28727 + D(11) KM_IRQ1,
28728 + D(12) KM_SOFTIRQ0,
28729 + D(13) KM_SOFTIRQ1,
28730 +-D(14) KM_TYPE_NR
28731 ++D(14) KM_CLEARPAGE,
28732 ++D(15) KM_TYPE_NR
28733 + };
28734 +
28735 + #undef D
28736 +diff -urNp linux-2.6.26.6/include/asm-blackfin/kmap_types.h linux-2.6.26.6/include/asm-blackfin/kmap_types.h
28737 +--- linux-2.6.26.6/include/asm-blackfin/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28738 ++++ linux-2.6.26.6/include/asm-blackfin/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28739 +@@ -15,6 +15,7 @@ enum km_type {
28740 + KM_IRQ1,
28741 + KM_SOFTIRQ0,
28742 + KM_SOFTIRQ1,
28743 ++ KM_CLEARPAGE,
28744 + KM_TYPE_NR
28745 + };
28746 +
28747 +diff -urNp linux-2.6.26.6/include/asm-cris/kmap_types.h linux-2.6.26.6/include/asm-cris/kmap_types.h
28748 +--- linux-2.6.26.6/include/asm-cris/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28749 ++++ linux-2.6.26.6/include/asm-cris/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28750 +@@ -19,6 +19,7 @@ enum km_type {
28751 + KM_IRQ1,
28752 + KM_SOFTIRQ0,
28753 + KM_SOFTIRQ1,
28754 ++ KM_CLEARPAGE,
28755 + KM_TYPE_NR
28756 + };
28757 +
28758 +diff -urNp linux-2.6.26.6/include/asm-frv/kmap_types.h linux-2.6.26.6/include/asm-frv/kmap_types.h
28759 +--- linux-2.6.26.6/include/asm-frv/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28760 ++++ linux-2.6.26.6/include/asm-frv/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28761 +@@ -23,6 +23,7 @@ enum km_type {
28762 + KM_IRQ1,
28763 + KM_SOFTIRQ0,
28764 + KM_SOFTIRQ1,
28765 ++ KM_CLEARPAGE,
28766 + KM_TYPE_NR
28767 + };
28768 +
28769 +diff -urNp linux-2.6.26.6/include/asm-generic/futex.h linux-2.6.26.6/include/asm-generic/futex.h
28770 +--- linux-2.6.26.6/include/asm-generic/futex.h 2008-10-08 23:24:05.000000000 -0400
28771 ++++ linux-2.6.26.6/include/asm-generic/futex.h 2008-10-11 21:54:20.000000000 -0400
28772 +@@ -6,7 +6,7 @@
28773 + #include <asm/errno.h>
28774 +
28775 + static inline int
28776 +-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
28777 ++futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
28778 + {
28779 + int op = (encoded_op >> 28) & 7;
28780 + int cmp = (encoded_op >> 24) & 15;
28781 +@@ -48,7 +48,7 @@ futex_atomic_op_inuser (int encoded_op,
28782 + }
28783 +
28784 + static inline int
28785 +-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
28786 ++futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
28787 + {
28788 + return -ENOSYS;
28789 + }
28790 +diff -urNp linux-2.6.26.6/include/asm-generic/vmlinux.lds.h linux-2.6.26.6/include/asm-generic/vmlinux.lds.h
28791 +--- linux-2.6.26.6/include/asm-generic/vmlinux.lds.h 2008-10-08 23:24:05.000000000 -0400
28792 ++++ linux-2.6.26.6/include/asm-generic/vmlinux.lds.h 2008-10-11 21:54:20.000000000 -0400
28793 +@@ -59,6 +59,7 @@
28794 + .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
28795 + VMLINUX_SYMBOL(__start_rodata) = .; \
28796 + *(.rodata) *(.rodata.*) \
28797 ++ *(.data.read_only) \
28798 + *(__vermagic) /* Kernel version magic */ \
28799 + *(__markers_strings) /* Markers: strings */ \
28800 + } \
28801 +diff -urNp linux-2.6.26.6/include/asm-h8300/kmap_types.h linux-2.6.26.6/include/asm-h8300/kmap_types.h
28802 +--- linux-2.6.26.6/include/asm-h8300/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28803 ++++ linux-2.6.26.6/include/asm-h8300/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28804 +@@ -15,6 +15,7 @@ enum km_type {
28805 + KM_IRQ1,
28806 + KM_SOFTIRQ0,
28807 + KM_SOFTIRQ1,
28808 ++ KM_CLEARPAGE,
28809 + KM_TYPE_NR
28810 + };
28811 +
28812 +diff -urNp linux-2.6.26.6/include/asm-ia64/elf.h linux-2.6.26.6/include/asm-ia64/elf.h
28813 +--- linux-2.6.26.6/include/asm-ia64/elf.h 2008-10-08 23:24:05.000000000 -0400
28814 ++++ linux-2.6.26.6/include/asm-ia64/elf.h 2008-10-11 21:54:20.000000000 -0400
28815 +@@ -187,7 +187,12 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
28816 + typedef struct ia64_fpreg elf_fpreg_t;
28817 + typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
28818 +
28819 ++#ifdef CONFIG_PAX_ASLR
28820 ++#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
28821 +
28822 ++#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
28823 ++#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
28824 ++#endif
28825 +
28826 + struct pt_regs; /* forward declaration... */
28827 + extern void ia64_elf_core_copy_regs (struct pt_regs *src, elf_gregset_t dst);
28828 +diff -urNp linux-2.6.26.6/include/asm-ia64/kmap_types.h linux-2.6.26.6/include/asm-ia64/kmap_types.h
28829 +--- linux-2.6.26.6/include/asm-ia64/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28830 ++++ linux-2.6.26.6/include/asm-ia64/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28831 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
28832 + D(10) KM_IRQ1,
28833 + D(11) KM_SOFTIRQ0,
28834 + D(12) KM_SOFTIRQ1,
28835 +-D(13) KM_TYPE_NR
28836 ++D(13) KM_CLEARPAGE,
28837 ++D(14) KM_TYPE_NR
28838 + };
28839 +
28840 + #undef D
28841 +diff -urNp linux-2.6.26.6/include/asm-ia64/pgtable.h linux-2.6.26.6/include/asm-ia64/pgtable.h
28842 +--- linux-2.6.26.6/include/asm-ia64/pgtable.h 2008-10-08 23:24:05.000000000 -0400
28843 ++++ linux-2.6.26.6/include/asm-ia64/pgtable.h 2008-10-11 21:54:20.000000000 -0400
28844 +@@ -143,6 +143,17 @@
28845 + #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
28846 + #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
28847 + #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
28848 ++
28849 ++#ifdef CONFIG_PAX_PAGEEXEC
28850 ++# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
28851 ++# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
28852 ++# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
28853 ++#else
28854 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
28855 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
28856 ++# define PAGE_COPY_NOEXEC PAGE_COPY
28857 ++#endif
28858 ++
28859 + #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
28860 + #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
28861 + #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
28862 +diff -urNp linux-2.6.26.6/include/asm-m32r/kmap_types.h linux-2.6.26.6/include/asm-m32r/kmap_types.h
28863 +--- linux-2.6.26.6/include/asm-m32r/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28864 ++++ linux-2.6.26.6/include/asm-m32r/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28865 +@@ -21,7 +21,8 @@ D(9) KM_IRQ0,
28866 + D(10) KM_IRQ1,
28867 + D(11) KM_SOFTIRQ0,
28868 + D(12) KM_SOFTIRQ1,
28869 +-D(13) KM_TYPE_NR
28870 ++D(13) KM_CLEARPAGE,
28871 ++D(14) KM_TYPE_NR
28872 + };
28873 +
28874 + #undef D
28875 +diff -urNp linux-2.6.26.6/include/asm-m68k/kmap_types.h linux-2.6.26.6/include/asm-m68k/kmap_types.h
28876 +--- linux-2.6.26.6/include/asm-m68k/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28877 ++++ linux-2.6.26.6/include/asm-m68k/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28878 +@@ -15,6 +15,7 @@ enum km_type {
28879 + KM_IRQ1,
28880 + KM_SOFTIRQ0,
28881 + KM_SOFTIRQ1,
28882 ++ KM_CLEARPAGE,
28883 + KM_TYPE_NR
28884 + };
28885 +
28886 +diff -urNp linux-2.6.26.6/include/asm-m68knommu/kmap_types.h linux-2.6.26.6/include/asm-m68knommu/kmap_types.h
28887 +--- linux-2.6.26.6/include/asm-m68knommu/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28888 ++++ linux-2.6.26.6/include/asm-m68knommu/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28889 +@@ -15,6 +15,7 @@ enum km_type {
28890 + KM_IRQ1,
28891 + KM_SOFTIRQ0,
28892 + KM_SOFTIRQ1,
28893 ++ KM_CLEARPAGE,
28894 + KM_TYPE_NR
28895 + };
28896 +
28897 +diff -urNp linux-2.6.26.6/include/asm-mips/elf.h linux-2.6.26.6/include/asm-mips/elf.h
28898 +--- linux-2.6.26.6/include/asm-mips/elf.h 2008-10-08 23:24:05.000000000 -0400
28899 ++++ linux-2.6.26.6/include/asm-mips/elf.h 2008-10-11 21:54:20.000000000 -0400
28900 +@@ -368,4 +368,11 @@ extern int dump_task_fpu(struct task_str
28901 + #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
28902 + #endif
28903 +
28904 ++#ifdef CONFIG_PAX_ASLR
28905 ++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
28906 ++
28907 ++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
28908 ++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
28909 ++#endif
28910 ++
28911 + #endif /* _ASM_ELF_H */
28912 +diff -urNp linux-2.6.26.6/include/asm-mips/kmap_types.h linux-2.6.26.6/include/asm-mips/kmap_types.h
28913 +--- linux-2.6.26.6/include/asm-mips/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28914 ++++ linux-2.6.26.6/include/asm-mips/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28915 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
28916 + D(10) KM_IRQ1,
28917 + D(11) KM_SOFTIRQ0,
28918 + D(12) KM_SOFTIRQ1,
28919 +-D(13) KM_TYPE_NR
28920 ++D(13) KM_CLEARPAGE,
28921 ++D(14) KM_TYPE_NR
28922 + };
28923 +
28924 + #undef D
28925 +diff -urNp linux-2.6.26.6/include/asm-mips/page.h linux-2.6.26.6/include/asm-mips/page.h
28926 +--- linux-2.6.26.6/include/asm-mips/page.h 2008-10-08 23:24:05.000000000 -0400
28927 ++++ linux-2.6.26.6/include/asm-mips/page.h 2008-10-11 21:54:20.000000000 -0400
28928 +@@ -79,7 +79,7 @@ extern void copy_user_highpage(struct pa
28929 + #ifdef CONFIG_CPU_MIPS32
28930 + typedef struct { unsigned long pte_low, pte_high; } pte_t;
28931 + #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
28932 +- #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
28933 ++ #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
28934 + #else
28935 + typedef struct { unsigned long long pte; } pte_t;
28936 + #define pte_val(x) ((x).pte)
28937 +diff -urNp linux-2.6.26.6/include/asm-mips/system.h linux-2.6.26.6/include/asm-mips/system.h
28938 +--- linux-2.6.26.6/include/asm-mips/system.h 2008-10-08 23:24:05.000000000 -0400
28939 ++++ linux-2.6.26.6/include/asm-mips/system.h 2008-10-11 21:54:20.000000000 -0400
28940 +@@ -215,6 +215,6 @@ extern void per_cpu_trap_init(void);
28941 + */
28942 + #define __ARCH_WANT_UNLOCKED_CTXSW
28943 +
28944 +-extern unsigned long arch_align_stack(unsigned long sp);
28945 ++#define arch_align_stack(x) (x)
28946 +
28947 + #endif /* _ASM_SYSTEM_H */
28948 +diff -urNp linux-2.6.26.6/include/asm-parisc/elf.h linux-2.6.26.6/include/asm-parisc/elf.h
28949 +--- linux-2.6.26.6/include/asm-parisc/elf.h 2008-10-08 23:24:05.000000000 -0400
28950 ++++ linux-2.6.26.6/include/asm-parisc/elf.h 2008-10-11 21:54:20.000000000 -0400
28951 +@@ -333,6 +333,13 @@ struct pt_regs; /* forward declaration..
28952 +
28953 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
28954 +
28955 ++#ifdef CONFIG_PAX_ASLR
28956 ++#define PAX_ELF_ET_DYN_BASE 0x10000UL
28957 ++
28958 ++#define PAX_DELTA_MMAP_LEN 16
28959 ++#define PAX_DELTA_STACK_LEN 16
28960 ++#endif
28961 ++
28962 + /* This yields a mask that user programs can use to figure out what
28963 + instruction set this CPU supports. This could be done in user space,
28964 + but it's not easy, and we've already done it here. */
28965 +diff -urNp linux-2.6.26.6/include/asm-parisc/kmap_types.h linux-2.6.26.6/include/asm-parisc/kmap_types.h
28966 +--- linux-2.6.26.6/include/asm-parisc/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28967 ++++ linux-2.6.26.6/include/asm-parisc/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28968 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
28969 + D(10) KM_IRQ1,
28970 + D(11) KM_SOFTIRQ0,
28971 + D(12) KM_SOFTIRQ1,
28972 +-D(13) KM_TYPE_NR
28973 ++D(13) KM_CLEARPAGE,
28974 ++D(14) KM_TYPE_NR
28975 + };
28976 +
28977 + #undef D
28978 +diff -urNp linux-2.6.26.6/include/asm-parisc/pgtable.h linux-2.6.26.6/include/asm-parisc/pgtable.h
28979 +--- linux-2.6.26.6/include/asm-parisc/pgtable.h 2008-10-08 23:24:05.000000000 -0400
28980 ++++ linux-2.6.26.6/include/asm-parisc/pgtable.h 2008-10-11 21:54:20.000000000 -0400
28981 +@@ -202,6 +202,17 @@
28982 + #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
28983 + #define PAGE_COPY PAGE_EXECREAD
28984 + #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
28985 ++
28986 ++#ifdef CONFIG_PAX_PAGEEXEC
28987 ++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
28988 ++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
28989 ++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
28990 ++#else
28991 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
28992 ++# define PAGE_COPY_NOEXEC PAGE_COPY
28993 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
28994 ++#endif
28995 ++
28996 + #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
28997 + #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
28998 + #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
28999 +diff -urNp linux-2.6.26.6/include/asm-powerpc/elf.h linux-2.6.26.6/include/asm-powerpc/elf.h
29000 +--- linux-2.6.26.6/include/asm-powerpc/elf.h 2008-10-08 23:24:05.000000000 -0400
29001 ++++ linux-2.6.26.6/include/asm-powerpc/elf.h 2008-10-11 21:54:20.000000000 -0400
29002 +@@ -160,6 +160,18 @@ typedef elf_vrreg_t elf_vrregset_t[ELF_N
29003 + typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
29004 + #endif
29005 +
29006 ++#ifdef CONFIG_PAX_ASLR
29007 ++#define PAX_ELF_ET_DYN_BASE (0x10000000UL)
29008 ++
29009 ++#ifdef __powerpc64__
29010 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
29011 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
29012 ++#else
29013 ++#define PAX_DELTA_MMAP_LEN 15
29014 ++#define PAX_DELTA_STACK_LEN 15
29015 ++#endif
29016 ++#endif
29017 ++
29018 + #ifdef __KERNEL__
29019 + /*
29020 + * This is used to ensure we don't load something for the wrong architecture.
29021 +diff -urNp linux-2.6.26.6/include/asm-powerpc/kmap_types.h linux-2.6.26.6/include/asm-powerpc/kmap_types.h
29022 +--- linux-2.6.26.6/include/asm-powerpc/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
29023 ++++ linux-2.6.26.6/include/asm-powerpc/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
29024 +@@ -26,6 +26,7 @@ enum km_type {
29025 + KM_SOFTIRQ1,
29026 + KM_PPC_SYNC_PAGE,
29027 + KM_PPC_SYNC_ICACHE,
29028 ++ KM_CLEARPAGE,
29029 + KM_TYPE_NR
29030 + };
29031 +
29032 +diff -urNp linux-2.6.26.6/include/asm-powerpc/page_64.h linux-2.6.26.6/include/asm-powerpc/page_64.h
29033 +--- linux-2.6.26.6/include/asm-powerpc/page_64.h 2008-10-08 23:24:05.000000000 -0400
29034 ++++ linux-2.6.26.6/include/asm-powerpc/page_64.h 2008-10-11 21:54:20.000000000 -0400
29035 +@@ -163,15 +163,18 @@ do { \
29036 + * stack by default, so in the absense of a PT_GNU_STACK program header
29037 + * we turn execute permission off.
29038 + */
29039 +-#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
29040 +- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
29041 ++#define VM_STACK_DEFAULT_FLAGS32 \
29042 ++ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
29043 ++ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
29044 +
29045 + #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
29046 + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
29047 +
29048 ++#ifndef CONFIG_PAX_PAGEEXEC
29049 + #define VM_STACK_DEFAULT_FLAGS \
29050 + (test_thread_flag(TIF_32BIT) ? \
29051 + VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
29052 ++#endif
29053 +
29054 + #include <asm-generic/page.h>
29055 +
29056 +diff -urNp linux-2.6.26.6/include/asm-powerpc/page.h linux-2.6.26.6/include/asm-powerpc/page.h
29057 +--- linux-2.6.26.6/include/asm-powerpc/page.h 2008-10-08 23:24:05.000000000 -0400
29058 ++++ linux-2.6.26.6/include/asm-powerpc/page.h 2008-10-11 21:54:20.000000000 -0400
29059 +@@ -100,8 +100,9 @@ extern phys_addr_t kernstart_addr;
29060 + * and needs to be executable. This means the whole heap ends
29061 + * up being executable.
29062 + */
29063 +-#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
29064 +- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
29065 ++#define VM_DATA_DEFAULT_FLAGS32 \
29066 ++ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
29067 ++ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
29068 +
29069 + #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
29070 + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
29071 +diff -urNp linux-2.6.26.6/include/asm-ppc/mmu_context.h linux-2.6.26.6/include/asm-ppc/mmu_context.h
29072 +--- linux-2.6.26.6/include/asm-ppc/mmu_context.h 2008-10-08 23:24:05.000000000 -0400
29073 ++++ linux-2.6.26.6/include/asm-ppc/mmu_context.h 2008-10-11 21:54:20.000000000 -0400
29074 +@@ -141,7 +141,8 @@ static inline void get_mmu_context(struc
29075 + static inline int init_new_context(struct task_struct *t, struct mm_struct *mm)
29076 + {
29077 + mm->context.id = NO_CONTEXT;
29078 +- mm->context.vdso_base = 0;
29079 ++ if (t == current)
29080 ++ mm->context.vdso_base = ~0UL;
29081 + return 0;
29082 + }
29083 +
29084 +diff -urNp linux-2.6.26.6/include/asm-ppc/pgtable.h linux-2.6.26.6/include/asm-ppc/pgtable.h
29085 +--- linux-2.6.26.6/include/asm-ppc/pgtable.h 2008-10-08 23:24:05.000000000 -0400
29086 ++++ linux-2.6.26.6/include/asm-ppc/pgtable.h 2008-10-11 21:54:20.000000000 -0400
29087 +@@ -390,11 +390,21 @@ extern unsigned long ioremap_bot, iorema
29088 +
29089 + #define PAGE_NONE __pgprot(_PAGE_BASE)
29090 + #define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
29091 +-#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
29092 ++#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
29093 + #define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
29094 +-#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
29095 ++#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
29096 + #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
29097 +-#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
29098 ++#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
29099 ++
29100 ++#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
29101 ++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
29102 ++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
29103 ++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
29104 ++#else
29105 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
29106 ++# define PAGE_COPY_NOEXEC PAGE_COPY
29107 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
29108 ++#endif
29109 +
29110 + #define PAGE_KERNEL __pgprot(_PAGE_RAM)
29111 + #define PAGE_KERNEL_NOCACHE __pgprot(_PAGE_IO)
29112 +@@ -406,21 +416,21 @@ extern unsigned long ioremap_bot, iorema
29113 + * This is the closest we can get..
29114 + */
29115 + #define __P000 PAGE_NONE
29116 +-#define __P001 PAGE_READONLY_X
29117 +-#define __P010 PAGE_COPY
29118 +-#define __P011 PAGE_COPY_X
29119 +-#define __P100 PAGE_READONLY
29120 ++#define __P001 PAGE_READONLY_NOEXEC
29121 ++#define __P010 PAGE_COPY_NOEXEC
29122 ++#define __P011 PAGE_COPY_NOEXEC
29123 ++#define __P100 PAGE_READONLY_X
29124 + #define __P101 PAGE_READONLY_X
29125 +-#define __P110 PAGE_COPY
29126 ++#define __P110 PAGE_COPY_X
29127 + #define __P111 PAGE_COPY_X
29128 +
29129 + #define __S000 PAGE_NONE
29130 +-#define __S001 PAGE_READONLY_X
29131 +-#define __S010 PAGE_SHARED
29132 +-#define __S011 PAGE_SHARED_X
29133 +-#define __S100 PAGE_READONLY
29134 ++#define __S001 PAGE_READONLY_NOEXEC
29135 ++#define __S010 PAGE_SHARED_NOEXEC
29136 ++#define __S011 PAGE_SHARED_NOEXEC
29137 ++#define __S100 PAGE_READONLY_X
29138 + #define __S101 PAGE_READONLY_X
29139 +-#define __S110 PAGE_SHARED
29140 ++#define __S110 PAGE_SHARED_X
29141 + #define __S111 PAGE_SHARED_X
29142 +
29143 + #ifndef __ASSEMBLY__
29144 +diff -urNp linux-2.6.26.6/include/asm-s390/kmap_types.h linux-2.6.26.6/include/asm-s390/kmap_types.h
29145 +--- linux-2.6.26.6/include/asm-s390/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
29146 ++++ linux-2.6.26.6/include/asm-s390/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
29147 +@@ -16,6 +16,7 @@ enum km_type {
29148 + KM_IRQ1,
29149 + KM_SOFTIRQ0,
29150 + KM_SOFTIRQ1,
29151 ++ KM_CLEARPAGE,
29152 + KM_TYPE_NR
29153 + };
29154 +
29155 +diff -urNp linux-2.6.26.6/include/asm-sh/kmap_types.h linux-2.6.26.6/include/asm-sh/kmap_types.h
29156 +--- linux-2.6.26.6/include/asm-sh/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
29157 ++++ linux-2.6.26.6/include/asm-sh/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
29158 +@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
29159 + D(10) KM_IRQ1,
29160 + D(11) KM_SOFTIRQ0,
29161 + D(12) KM_SOFTIRQ1,
29162 +-D(13) KM_TYPE_NR
29163 ++D(13) KM_CLEARPAGE,
29164 ++D(14) KM_TYPE_NR
29165 + };
29166 +
29167 + #undef D
29168 +diff -urNp linux-2.6.26.6/include/asm-sparc/elf.h linux-2.6.26.6/include/asm-sparc/elf.h
29169 +--- linux-2.6.26.6/include/asm-sparc/elf.h 2008-10-08 23:24:05.000000000 -0400
29170 ++++ linux-2.6.26.6/include/asm-sparc/elf.h 2008-10-11 21:54:20.000000000 -0400
29171 +@@ -119,6 +119,13 @@ typedef struct {
29172 +
29173 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
29174 +
29175 ++#ifdef CONFIG_PAX_ASLR
29176 ++#define PAX_ELF_ET_DYN_BASE 0x10000UL
29177 ++
29178 ++#define PAX_DELTA_MMAP_LEN 16
29179 ++#define PAX_DELTA_STACK_LEN 16
29180 ++#endif
29181 ++
29182 + /* This yields a mask that user programs can use to figure out what
29183 + instruction set this cpu supports. This can NOT be done in userspace
29184 + on Sparc. */
29185 +diff -urNp linux-2.6.26.6/include/asm-sparc/kmap_types.h linux-2.6.26.6/include/asm-sparc/kmap_types.h
29186 +--- linux-2.6.26.6/include/asm-sparc/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
29187 ++++ linux-2.6.26.6/include/asm-sparc/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
29188 +@@ -15,6 +15,7 @@ enum km_type {
29189 + KM_IRQ1,
29190 + KM_SOFTIRQ0,
29191 + KM_SOFTIRQ1,
29192 ++ KM_CLEARPAGE,
29193 + KM_TYPE_NR
29194 + };
29195 +
29196 +diff -urNp linux-2.6.26.6/include/asm-sparc/pgtable.h linux-2.6.26.6/include/asm-sparc/pgtable.h
29197 +--- linux-2.6.26.6/include/asm-sparc/pgtable.h 2008-10-08 23:24:05.000000000 -0400
29198 ++++ linux-2.6.26.6/include/asm-sparc/pgtable.h 2008-10-11 21:54:20.000000000 -0400
29199 +@@ -47,6 +47,13 @@ BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
29200 + BTFIXUPDEF_INT(page_none)
29201 + BTFIXUPDEF_INT(page_copy)
29202 + BTFIXUPDEF_INT(page_readonly)
29203 ++
29204 ++#ifdef CONFIG_PAX_PAGEEXEC
29205 ++BTFIXUPDEF_INT(page_shared_noexec)
29206 ++BTFIXUPDEF_INT(page_copy_noexec)
29207 ++BTFIXUPDEF_INT(page_readonly_noexec)
29208 ++#endif
29209 ++
29210 + BTFIXUPDEF_INT(page_kernel)
29211 +
29212 + #define PMD_SHIFT SUN4C_PMD_SHIFT
29213 +@@ -68,6 +75,16 @@ extern pgprot_t PAGE_SHARED;
29214 + #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
29215 + #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
29216 +
29217 ++#ifdef CONFIG_PAX_PAGEEXEC
29218 ++extern pgprot_t PAGE_SHARED_NOEXEC;
29219 ++# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec))
29220 ++# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec))
29221 ++#else
29222 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
29223 ++# define PAGE_COPY_NOEXEC PAGE_COPY
29224 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
29225 ++#endif
29226 ++
29227 + extern unsigned long page_kernel;
29228 +
29229 + #ifdef MODULE
29230 +diff -urNp linux-2.6.26.6/include/asm-sparc/pgtsrmmu.h linux-2.6.26.6/include/asm-sparc/pgtsrmmu.h
29231 +--- linux-2.6.26.6/include/asm-sparc/pgtsrmmu.h 2008-10-08 23:24:05.000000000 -0400
29232 ++++ linux-2.6.26.6/include/asm-sparc/pgtsrmmu.h 2008-10-11 21:54:20.000000000 -0400
29233 +@@ -115,6 +115,16 @@
29234 + SRMMU_EXEC | SRMMU_REF)
29235 + #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
29236 + SRMMU_EXEC | SRMMU_REF)
29237 ++
29238 ++#ifdef CONFIG_PAX_PAGEEXEC
29239 ++#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
29240 ++ SRMMU_WRITE | SRMMU_REF)
29241 ++#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
29242 ++ SRMMU_REF)
29243 ++#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
29244 ++ SRMMU_REF)
29245 ++#endif
29246 ++
29247 + #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
29248 + SRMMU_DIRTY | SRMMU_REF)
29249 +
29250 +diff -urNp linux-2.6.26.6/include/asm-sparc64/elf.h linux-2.6.26.6/include/asm-sparc64/elf.h
29251 +--- linux-2.6.26.6/include/asm-sparc64/elf.h 2008-10-08 23:24:05.000000000 -0400
29252 ++++ linux-2.6.26.6/include/asm-sparc64/elf.h 2008-10-11 21:54:20.000000000 -0400
29253 +@@ -163,6 +163,12 @@ typedef struct {
29254 + #define ELF_ET_DYN_BASE 0x0000010000000000UL
29255 + #define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL
29256 +
29257 ++#ifdef CONFIG_PAX_ASLR
29258 ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
29259 ++
29260 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 14 : 28 )
29261 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 15 : 29 )
29262 ++#endif
29263 +
29264 + /* This yields a mask that user programs can use to figure out what
29265 + instruction set this cpu supports. */
29266 +diff -urNp linux-2.6.26.6/include/asm-sparc64/kmap_types.h linux-2.6.26.6/include/asm-sparc64/kmap_types.h
29267 +--- linux-2.6.26.6/include/asm-sparc64/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
29268 ++++ linux-2.6.26.6/include/asm-sparc64/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
29269 +@@ -19,6 +19,7 @@ enum km_type {
29270 + KM_IRQ1,
29271 + KM_SOFTIRQ0,
29272 + KM_SOFTIRQ1,
29273 ++ KM_CLEARPAGE,
29274 + KM_TYPE_NR
29275 + };
29276 +
29277 +diff -urNp linux-2.6.26.6/include/asm-um/kmap_types.h linux-2.6.26.6/include/asm-um/kmap_types.h
29278 +--- linux-2.6.26.6/include/asm-um/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
29279 ++++ linux-2.6.26.6/include/asm-um/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
29280 +@@ -23,6 +23,7 @@ enum km_type {
29281 + KM_IRQ1,
29282 + KM_SOFTIRQ0,
29283 + KM_SOFTIRQ1,
29284 ++ KM_CLEARPAGE,
29285 + KM_TYPE_NR
29286 + };
29287 +
29288 +diff -urNp linux-2.6.26.6/include/asm-um/page.h linux-2.6.26.6/include/asm-um/page.h
29289 +--- linux-2.6.26.6/include/asm-um/page.h 2008-10-08 23:24:05.000000000 -0400
29290 ++++ linux-2.6.26.6/include/asm-um/page.h 2008-10-11 21:55:07.000000000 -0400
29291 +@@ -14,6 +14,9 @@
29292 + #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
29293 + #define PAGE_MASK (~(PAGE_SIZE-1))
29294 +
29295 ++#define ktla_ktva(addr) (addr)
29296 ++#define ktva_ktla(addr) (addr)
29297 ++
29298 + #ifndef __ASSEMBLY__
29299 +
29300 + struct page;
29301 +diff -urNp linux-2.6.26.6/include/asm-v850/kmap_types.h linux-2.6.26.6/include/asm-v850/kmap_types.h
29302 +--- linux-2.6.26.6/include/asm-v850/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
29303 ++++ linux-2.6.26.6/include/asm-v850/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
29304 +@@ -13,6 +13,7 @@ enum km_type {
29305 + KM_PTE1,
29306 + KM_IRQ0,
29307 + KM_IRQ1,
29308 ++ KM_CLEARPAGE,
29309 + KM_TYPE_NR
29310 + };
29311 +
29312 +diff -urNp linux-2.6.26.6/include/asm-x86/alternative.h linux-2.6.26.6/include/asm-x86/alternative.h
29313 +--- linux-2.6.26.6/include/asm-x86/alternative.h 2008-10-08 23:24:05.000000000 -0400
29314 ++++ linux-2.6.26.6/include/asm-x86/alternative.h 2008-10-11 21:54:20.000000000 -0400
29315 +@@ -94,7 +94,7 @@ static inline void alternatives_smp_swit
29316 + " .byte 662b-661b\n" /* sourcelen */ \
29317 + " .byte 664f-663f\n" /* replacementlen */ \
29318 + ".previous\n" \
29319 +- ".section .altinstr_replacement,\"ax\"\n" \
29320 ++ ".section .altinstr_replacement,\"a\"\n" \
29321 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
29322 + ".previous" :: "i" (feature) : "memory")
29323 +
29324 +@@ -118,7 +118,7 @@ static inline void alternatives_smp_swit
29325 + " .byte 662b-661b\n" /* sourcelen */ \
29326 + " .byte 664f-663f\n" /* replacementlen */ \
29327 + ".previous\n" \
29328 +- ".section .altinstr_replacement,\"ax\"\n" \
29329 ++ ".section .altinstr_replacement,\"a\"\n" \
29330 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
29331 + ".previous" :: "i" (feature), ##input)
29332 +
29333 +@@ -133,7 +133,7 @@ static inline void alternatives_smp_swit
29334 + " .byte 662b-661b\n" /* sourcelen */ \
29335 + " .byte 664f-663f\n" /* replacementlen */ \
29336 + ".previous\n" \
29337 +- ".section .altinstr_replacement,\"ax\"\n" \
29338 ++ ".section .altinstr_replacement,\"a\"\n" \
29339 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
29340 + ".previous" : output : [feat] "i" (feature), ##input)
29341 +
29342 +diff -urNp linux-2.6.26.6/include/asm-x86/apic.h linux-2.6.26.6/include/asm-x86/apic.h
29343 +--- linux-2.6.26.6/include/asm-x86/apic.h 2008-10-08 23:24:05.000000000 -0400
29344 ++++ linux-2.6.26.6/include/asm-x86/apic.h 2008-10-11 21:54:20.000000000 -0400
29345 +@@ -10,7 +10,7 @@
29346 +
29347 + #define ARCH_APICTIMER_STOPS_ON_C3 1
29348 +
29349 +-#define Dprintk(x...)
29350 ++#define Dprintk(x...) do {} while (0)
29351 +
29352 + /*
29353 + * Debugging macros
29354 +diff -urNp linux-2.6.26.6/include/asm-x86/atomic_32.h linux-2.6.26.6/include/asm-x86/atomic_32.h
29355 +--- linux-2.6.26.6/include/asm-x86/atomic_32.h 2008-10-08 23:24:05.000000000 -0400
29356 ++++ linux-2.6.26.6/include/asm-x86/atomic_32.h 2008-10-11 21:54:20.000000000 -0400
29357 +@@ -47,7 +47,15 @@ typedef struct {
29358 + */
29359 + static inline void atomic_add(int i, atomic_t *v)
29360 + {
29361 +- asm volatile(LOCK_PREFIX "addl %1,%0"
29362 ++ asm volatile(LOCK_PREFIX "addl %1,%0\n"
29363 ++
29364 ++#ifdef CONFIG_PAX_REFCOUNT
29365 ++ "jno 0f\n"
29366 ++ LOCK_PREFIX "subl %1,%0\n"
29367 ++ "into\n0:\n"
29368 ++ _ASM_EXTABLE(0b, 0b)
29369 ++#endif
29370 ++
29371 + : "+m" (v->counter)
29372 + : "ir" (i));
29373 + }
29374 +@@ -61,7 +69,15 @@ static inline void atomic_add(int i, ato
29375 + */
29376 + static inline void atomic_sub(int i, atomic_t *v)
29377 + {
29378 +- asm volatile(LOCK_PREFIX "subl %1,%0"
29379 ++ asm volatile(LOCK_PREFIX "subl %1,%0\n"
29380 ++
29381 ++#ifdef CONFIG_PAX_REFCOUNT
29382 ++ "jno 0f\n"
29383 ++ LOCK_PREFIX "addl %1,%0\n"
29384 ++ "into\n0:\n"
29385 ++ _ASM_EXTABLE(0b, 0b)
29386 ++#endif
29387 ++
29388 + : "+m" (v->counter)
29389 + : "ir" (i));
29390 + }
29391 +@@ -79,7 +95,16 @@ static inline int atomic_sub_and_test(in
29392 + {
29393 + unsigned char c;
29394 +
29395 +- asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
29396 ++ asm volatile(LOCK_PREFIX "subl %2,%0\n"
29397 ++
29398 ++#ifdef CONFIG_PAX_REFCOUNT
29399 ++ "jno 0f\n"
29400 ++ LOCK_PREFIX "addl %2,%0\n"
29401 ++ "into\n0:\n"
29402 ++ _ASM_EXTABLE(0b, 0b)
29403 ++#endif
29404 ++
29405 ++ "sete %1\n"
29406 + : "+m" (v->counter), "=qm" (c)
29407 + : "ir" (i) : "memory");
29408 + return c;
29409 +@@ -93,7 +118,18 @@ static inline int atomic_sub_and_test(in
29410 + */
29411 + static inline void atomic_inc(atomic_t *v)
29412 + {
29413 +- asm volatile(LOCK_PREFIX "incl %0"
29414 ++ asm volatile(LOCK_PREFIX "incl %0\n"
29415 ++
29416 ++#ifdef CONFIG_PAX_REFCOUNT
29417 ++ "into\n0:\n"
29418 ++ ".pushsection .fixup,\"ax\"\n"
29419 ++ "1:\n"
29420 ++ LOCK_PREFIX "decl %0\n"
29421 ++ "jmp 0b\n"
29422 ++ ".popsection\n"
29423 ++ _ASM_EXTABLE(0b, 1b)
29424 ++#endif
29425 ++
29426 + : "+m" (v->counter));
29427 + }
29428 +
29429 +@@ -105,7 +141,18 @@ static inline void atomic_inc(atomic_t *
29430 + */
29431 + static inline void atomic_dec(atomic_t *v)
29432 + {
29433 +- asm volatile(LOCK_PREFIX "decl %0"
29434 ++ asm volatile(LOCK_PREFIX "decl %0\n"
29435 ++
29436 ++#ifdef CONFIG_PAX_REFCOUNT
29437 ++ "into\n0:\n"
29438 ++ ".pushsection .fixup,\"ax\"\n"
29439 ++ "1: \n"
29440 ++ LOCK_PREFIX "incl %0\n"
29441 ++ "jmp 0b\n"
29442 ++ ".popsection\n"
29443 ++ _ASM_EXTABLE(0b, 1b)
29444 ++#endif
29445 ++
29446 + : "+m" (v->counter));
29447 + }
29448 +
29449 +@@ -121,7 +168,19 @@ static inline int atomic_dec_and_test(at
29450 + {
29451 + unsigned char c;
29452 +
29453 +- asm volatile(LOCK_PREFIX "decl %0; sete %1"
29454 ++ asm volatile(LOCK_PREFIX "decl %0\n"
29455 ++
29456 ++#ifdef CONFIG_PAX_REFCOUNT
29457 ++ "into\n0:\n"
29458 ++ ".pushsection .fixup,\"ax\"\n"
29459 ++ "1: \n"
29460 ++ LOCK_PREFIX "incl %0\n"
29461 ++ "jmp 0b\n"
29462 ++ ".popsection\n"
29463 ++ _ASM_EXTABLE(0b, 1b)
29464 ++#endif
29465 ++
29466 ++ "sete %1\n"
29467 + : "+m" (v->counter), "=qm" (c)
29468 + : : "memory");
29469 + return c != 0;
29470 +@@ -139,7 +198,19 @@ static inline int atomic_inc_and_test(at
29471 + {
29472 + unsigned char c;
29473 +
29474 +- asm volatile(LOCK_PREFIX "incl %0; sete %1"
29475 ++ asm volatile(LOCK_PREFIX "incl %0\n"
29476 ++
29477 ++#ifdef CONFIG_PAX_REFCOUNT
29478 ++ "into\n0:\n"
29479 ++ ".pushsection .fixup,\"ax\"\n"
29480 ++ "1: \n"
29481 ++ LOCK_PREFIX "decl %0\n"
29482 ++ "jmp 0b\n"
29483 ++ ".popsection\n"
29484 ++ _ASM_EXTABLE(0b, 1b)
29485 ++#endif
29486 ++
29487 ++ "sete %1\n"
29488 + : "+m" (v->counter), "=qm" (c)
29489 + : : "memory");
29490 + return c != 0;
29491 +@@ -158,7 +229,16 @@ static inline int atomic_add_negative(in
29492 + {
29493 + unsigned char c;
29494 +
29495 +- asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
29496 ++ asm volatile(LOCK_PREFIX "addl %2,%0\n"
29497 ++
29498 ++#ifdef CONFIG_PAX_REFCOUNT
29499 ++ "jno 0f\n"
29500 ++ LOCK_PREFIX "subl %2,%0\n"
29501 ++ "into\n0:\n"
29502 ++ _ASM_EXTABLE(0b, 0b)
29503 ++#endif
29504 ++
29505 ++ "sets %1\n"
29506 + : "+m" (v->counter), "=qm" (c)
29507 + : "ir" (i) : "memory");
29508 + return c;
29509 +@@ -181,7 +261,15 @@ static inline int atomic_add_return(int
29510 + #endif
29511 + /* Modern 486+ processor */
29512 + __i = i;
29513 +- asm volatile(LOCK_PREFIX "xaddl %0, %1"
29514 ++ asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
29515 ++
29516 ++#ifdef CONFIG_PAX_REFCOUNT
29517 ++ "jno 0f\n"
29518 ++ "movl %0, %1\n"
29519 ++ "into\n0:\n"
29520 ++ _ASM_EXTABLE(0b, 0b)
29521 ++#endif
29522 ++
29523 + : "+r" (i), "+m" (v->counter)
29524 + : : "memory");
29525 + return i + __i;
29526 +diff -urNp linux-2.6.26.6/include/asm-x86/atomic_64.h linux-2.6.26.6/include/asm-x86/atomic_64.h
29527 +--- linux-2.6.26.6/include/asm-x86/atomic_64.h 2008-10-08 23:24:05.000000000 -0400
29528 ++++ linux-2.6.26.6/include/asm-x86/atomic_64.h 2008-10-11 21:54:20.000000000 -0400
29529 +@@ -54,7 +54,15 @@ typedef struct {
29530 + */
29531 + static inline void atomic_add(int i, atomic_t *v)
29532 + {
29533 +- asm volatile(LOCK_PREFIX "addl %1,%0"
29534 ++ asm volatile(LOCK_PREFIX "addl %1,%0\n"
29535 ++
29536 ++#ifdef CONFIG_PAX_REFCOUNT
29537 ++ "jno 0f\n"
29538 ++ LOCK_PREFIX "subl %1,%0\n"
29539 ++ "int $4\n0:\n"
29540 ++ _ASM_EXTABLE(0b, 0b)
29541 ++#endif
29542 ++
29543 + : "=m" (v->counter)
29544 + : "ir" (i), "m" (v->counter));
29545 + }
29546 +@@ -68,7 +76,15 @@ static inline void atomic_add(int i, ato
29547 + */
29548 + static inline void atomic_sub(int i, atomic_t *v)
29549 + {
29550 +- asm volatile(LOCK_PREFIX "subl %1,%0"
29551 ++ asm volatile(LOCK_PREFIX "subl %1,%0\n"
29552 ++
29553 ++#ifdef CONFIG_PAX_REFCOUNT
29554 ++ "jno 0f\n"
29555 ++ LOCK_PREFIX "addl %1,%0\n"
29556 ++ "int $4\n0:\n"
29557 ++ _ASM_EXTABLE(0b, 0b)
29558 ++#endif
29559 ++
29560 + : "=m" (v->counter)
29561 + : "ir" (i), "m" (v->counter));
29562 + }
29563 +@@ -86,7 +102,16 @@ static inline int atomic_sub_and_test(in
29564 + {
29565 + unsigned char c;
29566 +
29567 +- asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
29568 ++ asm volatile(LOCK_PREFIX "subl %2,%0\n"
29569 ++
29570 ++#ifdef CONFIG_PAX_REFCOUNT
29571 ++ "jno 0f\n"
29572 ++ LOCK_PREFIX "addl %2,%0\n"
29573 ++ "int $4\n0:\n"
29574 ++ _ASM_EXTABLE(0b, 0b)
29575 ++#endif
29576 ++
29577 ++ "sete %1\n"
29578 + : "=m" (v->counter), "=qm" (c)
29579 + : "ir" (i), "m" (v->counter) : "memory");
29580 + return c;
29581 +@@ -100,7 +125,19 @@ static inline int atomic_sub_and_test(in
29582 + */
29583 + static inline void atomic_inc(atomic_t *v)
29584 + {
29585 +- asm volatile(LOCK_PREFIX "incl %0"
29586 ++ asm volatile(LOCK_PREFIX "incl %0\n"
29587 ++
29588 ++#ifdef CONFIG_PAX_REFCOUNT
29589 ++ "jno 0f\n"
29590 ++ "int $4\n0:\n"
29591 ++ ".pushsection .fixup,\"ax\"\n"
29592 ++ "1:\n"
29593 ++ LOCK_PREFIX "decl %0\n"
29594 ++ "jmp 0b\n"
29595 ++ ".popsection\n"
29596 ++ _ASM_EXTABLE(0b, 1b)
29597 ++#endif
29598 ++
29599 + : "=m" (v->counter)
29600 + : "m" (v->counter));
29601 + }
29602 +@@ -113,7 +150,19 @@ static inline void atomic_inc(atomic_t *
29603 + */
29604 + static inline void atomic_dec(atomic_t *v)
29605 + {
29606 +- asm volatile(LOCK_PREFIX "decl %0"
29607 ++ asm volatile(LOCK_PREFIX "decl %0\n"
29608 ++
29609 ++#ifdef CONFIG_PAX_REFCOUNT
29610 ++ "jno 0f\n"
29611 ++ "int $4\n0:\n"
29612 ++ ".pushsection .fixup,\"ax\"\n"
29613 ++ "1: \n"
29614 ++ LOCK_PREFIX "incl %0\n"
29615 ++ "jmp 0b\n"
29616 ++ ".popsection\n"
29617 ++ _ASM_EXTABLE(0b, 1b)
29618 ++#endif
29619 ++
29620 + : "=m" (v->counter)
29621 + : "m" (v->counter));
29622 + }
29623 +@@ -130,7 +179,20 @@ static inline int atomic_dec_and_test(at
29624 + {
29625 + unsigned char c;
29626 +
29627 +- asm volatile(LOCK_PREFIX "decl %0; sete %1"
29628 ++ asm volatile(LOCK_PREFIX "decl %0\n"
29629 ++
29630 ++#ifdef CONFIG_PAX_REFCOUNT
29631 ++ "jno 0f\n"
29632 ++ "int $4\n0:\n"
29633 ++ ".pushsection .fixup,\"ax\"\n"
29634 ++ "1: \n"
29635 ++ LOCK_PREFIX "incl %0\n"
29636 ++ "jmp 0b\n"
29637 ++ ".popsection\n"
29638 ++ _ASM_EXTABLE(0b, 1b)
29639 ++#endif
29640 ++
29641 ++ "sete %1\n"
29642 + : "=m" (v->counter), "=qm" (c)
29643 + : "m" (v->counter) : "memory");
29644 + return c != 0;
29645 +@@ -148,7 +210,20 @@ static inline int atomic_inc_and_test(at
29646 + {
29647 + unsigned char c;
29648 +
29649 +- asm volatile(LOCK_PREFIX "incl %0; sete %1"
29650 ++ asm volatile(LOCK_PREFIX "incl %0\n"
29651 ++
29652 ++#ifdef CONFIG_PAX_REFCOUNT
29653 ++ "jno 0f\n"
29654 ++ "int $4\n0:\n"
29655 ++ ".pushsection .fixup,\"ax\"\n"
29656 ++ "1: \n"
29657 ++ LOCK_PREFIX "decl %0\n"
29658 ++ "jmp 0b\n"
29659 ++ ".popsection\n"
29660 ++ _ASM_EXTABLE(0b, 1b)
29661 ++#endif
29662 ++
29663 ++ "sete %1\n"
29664 + : "=m" (v->counter), "=qm" (c)
29665 + : "m" (v->counter) : "memory");
29666 + return c != 0;
29667 +@@ -167,7 +242,16 @@ static inline int atomic_add_negative(in
29668 + {
29669 + unsigned char c;
29670 +
29671 +- asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
29672 ++ asm volatile(LOCK_PREFIX "addl %2,%0\n"
29673 ++
29674 ++#ifdef CONFIG_PAX_REFCOUNT
29675 ++ "jno 0f\n"
29676 ++ LOCK_PREFIX "subl %2,%0\n"
29677 ++ "int $4\n0:\n"
29678 ++ _ASM_EXTABLE(0b, 0b)
29679 ++#endif
29680 ++
29681 ++ "sets %1\n"
29682 + : "=m" (v->counter), "=qm" (c)
29683 + : "ir" (i), "m" (v->counter) : "memory");
29684 + return c;
29685 +@@ -183,7 +267,15 @@ static inline int atomic_add_negative(in
29686 + static inline int atomic_add_return(int i, atomic_t *v)
29687 + {
29688 + int __i = i;
29689 +- asm volatile(LOCK_PREFIX "xaddl %0, %1"
29690 ++ asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
29691 ++
29692 ++#ifdef CONFIG_PAX_REFCOUNT
29693 ++ "jno 0f\n"
29694 ++ "movl %0, %1\n"
29695 ++ "int $4\n0:\n"
29696 ++ _ASM_EXTABLE(0b, 0b)
29697 ++#endif
29698 ++
29699 + : "+r" (i), "+m" (v->counter)
29700 + : : "memory");
29701 + return i + __i;
29702 +@@ -232,7 +324,15 @@ typedef struct {
29703 + */
29704 + static inline void atomic64_add(long i, atomic64_t *v)
29705 + {
29706 +- asm volatile(LOCK_PREFIX "addq %1,%0"
29707 ++ asm volatile(LOCK_PREFIX "addq %1,%0\n"
29708 ++
29709 ++#ifdef CONFIG_PAX_REFCOUNT
29710 ++ "jno 0f\n"
29711 ++ LOCK_PREFIX "subq %1,%0\n"
29712 ++ "int $4\n0:\n"
29713 ++ _ASM_EXTABLE(0b, 0b)
29714 ++#endif
29715 ++
29716 + : "=m" (v->counter)
29717 + : "ir" (i), "m" (v->counter));
29718 + }
29719 +@@ -246,7 +346,15 @@ static inline void atomic64_add(long i,
29720 + */
29721 + static inline void atomic64_sub(long i, atomic64_t *v)
29722 + {
29723 +- asm volatile(LOCK_PREFIX "subq %1,%0"
29724 ++ asm volatile(LOCK_PREFIX "subq %1,%0\n"
29725 ++
29726 ++#ifdef CONFIG_PAX_REFCOUNT
29727 ++ "jno 0f\n"
29728 ++ LOCK_PREFIX "addq %1,%0\n"
29729 ++ "int $4\n0:\n"
29730 ++ _ASM_EXTABLE(0b, 0b)
29731 ++#endif
29732 ++
29733 + : "=m" (v->counter)
29734 + : "ir" (i), "m" (v->counter));
29735 + }
29736 +@@ -264,7 +372,16 @@ static inline int atomic64_sub_and_test(
29737 + {
29738 + unsigned char c;
29739 +
29740 +- asm volatile(LOCK_PREFIX "subq %2,%0; sete %1"
29741 ++ asm volatile(LOCK_PREFIX "subq %2,%0\n"
29742 ++
29743 ++#ifdef CONFIG_PAX_REFCOUNT
29744 ++ "jno 0f\n"
29745 ++ LOCK_PREFIX "addq %2,%0\n"
29746 ++ "int $4\n0:\n"
29747 ++ _ASM_EXTABLE(0b, 0b)
29748 ++#endif
29749 ++
29750 ++ "sete %1\n"
29751 + : "=m" (v->counter), "=qm" (c)
29752 + : "ir" (i), "m" (v->counter) : "memory");
29753 + return c;
29754 +@@ -278,7 +395,19 @@ static inline int atomic64_sub_and_test(
29755 + */
29756 + static inline void atomic64_inc(atomic64_t *v)
29757 + {
29758 +- asm volatile(LOCK_PREFIX "incq %0"
29759 ++ asm volatile(LOCK_PREFIX "incq %0\n"
29760 ++
29761 ++#ifdef CONFIG_PAX_REFCOUNT
29762 ++ "jno 0f\n"
29763 ++ "int $4\n0:\n"
29764 ++ ".pushsection .fixup,\"ax\"\n"
29765 ++ "1:\n"
29766 ++ LOCK_PREFIX "decq %0\n"
29767 ++ "jmp 0b\n"
29768 ++ ".popsection\n"
29769 ++ _ASM_EXTABLE(0b, 1b)
29770 ++#endif
29771 ++
29772 + : "=m" (v->counter)
29773 + : "m" (v->counter));
29774 + }
29775 +@@ -291,7 +420,19 @@ static inline void atomic64_inc(atomic64
29776 + */
29777 + static inline void atomic64_dec(atomic64_t *v)
29778 + {
29779 +- asm volatile(LOCK_PREFIX "decq %0"
29780 ++ asm volatile(LOCK_PREFIX "decq %0\n"
29781 ++
29782 ++#ifdef CONFIG_PAX_REFCOUNT
29783 ++ "jno 0f\n"
29784 ++ "int $4\n0:\n"
29785 ++ ".pushsection .fixup,\"ax\"\n"
29786 ++ "1: \n"
29787 ++ LOCK_PREFIX "incq %0\n"
29788 ++ "jmp 0b\n"
29789 ++ ".popsection\n"
29790 ++ _ASM_EXTABLE(0b, 1b)
29791 ++#endif
29792 ++
29793 + : "=m" (v->counter)
29794 + : "m" (v->counter));
29795 + }
29796 +@@ -308,7 +449,20 @@ static inline int atomic64_dec_and_test(
29797 + {
29798 + unsigned char c;
29799 +
29800 +- asm volatile(LOCK_PREFIX "decq %0; sete %1"
29801 ++ asm volatile(LOCK_PREFIX "decq %0\n"
29802 ++
29803 ++#ifdef CONFIG_PAX_REFCOUNT
29804 ++ "jno 0f\n"
29805 ++ "int $4\n0:\n"
29806 ++ ".pushsection .fixup,\"ax\"\n"
29807 ++ "1: \n"
29808 ++ LOCK_PREFIX "incq %0\n"
29809 ++ "jmp 0b\n"
29810 ++ ".popsection\n"
29811 ++ _ASM_EXTABLE(0b, 1b)
29812 ++#endif
29813 ++
29814 ++ "sete %1\n"
29815 + : "=m" (v->counter), "=qm" (c)
29816 + : "m" (v->counter) : "memory");
29817 + return c != 0;
29818 +@@ -326,7 +480,20 @@ static inline int atomic64_inc_and_test(
29819 + {
29820 + unsigned char c;
29821 +
29822 +- asm volatile(LOCK_PREFIX "incq %0; sete %1"
29823 ++ asm volatile(LOCK_PREFIX "incq %0\n"
29824 ++
29825 ++#ifdef CONFIG_PAX_REFCOUNT
29826 ++ "jno 0f\n"
29827 ++ "int $4\n0:\n"
29828 ++ ".pushsection .fixup,\"ax\"\n"
29829 ++ "1: \n"
29830 ++ LOCK_PREFIX "decq %0\n"
29831 ++ "jmp 0b\n"
29832 ++ ".popsection\n"
29833 ++ _ASM_EXTABLE(0b, 1b)
29834 ++#endif
29835 ++
29836 ++ "sete %1\n"
29837 + : "=m" (v->counter), "=qm" (c)
29838 + : "m" (v->counter) : "memory");
29839 + return c != 0;
29840 +@@ -345,7 +512,16 @@ static inline int atomic64_add_negative(
29841 + {
29842 + unsigned char c;
29843 +
29844 +- asm volatile(LOCK_PREFIX "addq %2,%0; sets %1"
29845 ++ asm volatile(LOCK_PREFIX "addq %2,%0\n"
29846 ++
29847 ++#ifdef CONFIG_PAX_REFCOUNT
29848 ++ "jno 0f\n"
29849 ++ LOCK_PREFIX "subq %2,%0\n"
29850 ++ "int $4\n0:\n"
29851 ++ _ASM_EXTABLE(0b, 0b)
29852 ++#endif
29853 ++
29854 ++ "sets %1\n"
29855 + : "=m" (v->counter), "=qm" (c)
29856 + : "ir" (i), "m" (v->counter) : "memory");
29857 + return c;
29858 +@@ -361,7 +537,15 @@ static inline int atomic64_add_negative(
29859 + static inline long atomic64_add_return(long i, atomic64_t *v)
29860 + {
29861 + long __i = i;
29862 +- asm volatile(LOCK_PREFIX "xaddq %0, %1;"
29863 ++ asm volatile(LOCK_PREFIX "xaddq %0, %1\n"
29864 ++
29865 ++#ifdef CONFIG_PAX_REFCOUNT
29866 ++ "jno 0f\n"
29867 ++ "movq %0, %1\n"
29868 ++ "int $4\n0:\n"
29869 ++ _ASM_EXTABLE(0b, 0b)
29870 ++#endif
29871 ++
29872 + : "+r" (i), "+m" (v->counter)
29873 + : : "memory");
29874 + return i + __i;
29875 +diff -urNp linux-2.6.26.6/include/asm-x86/boot.h linux-2.6.26.6/include/asm-x86/boot.h
29876 +--- linux-2.6.26.6/include/asm-x86/boot.h 2008-10-08 23:24:05.000000000 -0400
29877 ++++ linux-2.6.26.6/include/asm-x86/boot.h 2008-10-11 21:54:20.000000000 -0400
29878 +@@ -13,10 +13,15 @@
29879 + #define ASK_VGA 0xfffd /* ask for it at bootup */
29880 +
29881 + /* Physical address where kernel should be loaded. */
29882 +-#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
29883 ++#define ____LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
29884 + + (CONFIG_PHYSICAL_ALIGN - 1)) \
29885 + & ~(CONFIG_PHYSICAL_ALIGN - 1))
29886 +
29887 ++#ifndef __ASSEMBLY__
29888 ++extern unsigned char __LOAD_PHYSICAL_ADDR[];
29889 ++#define LOAD_PHYSICAL_ADDR ((unsigned long)__LOAD_PHYSICAL_ADDR)
29890 ++#endif
29891 ++
29892 + #ifdef CONFIG_X86_64
29893 + #define BOOT_HEAP_SIZE 0x7000
29894 + #define BOOT_STACK_SIZE 0x4000
29895 +diff -urNp linux-2.6.26.6/include/asm-x86/cache.h linux-2.6.26.6/include/asm-x86/cache.h
29896 +--- linux-2.6.26.6/include/asm-x86/cache.h 2008-10-08 23:24:05.000000000 -0400
29897 ++++ linux-2.6.26.6/include/asm-x86/cache.h 2008-10-11 21:54:20.000000000 -0400
29898 +@@ -6,6 +6,7 @@
29899 + #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
29900 +
29901 + #define __read_mostly __attribute__((__section__(".data.read_mostly")))
29902 ++#define __read_only __attribute__((__section__(".data.read_only")))
29903 +
29904 + #ifdef CONFIG_X86_VSMP
29905 + /* vSMP Internode cacheline shift */
29906 +diff -urNp linux-2.6.26.6/include/asm-x86/checksum_32.h linux-2.6.26.6/include/asm-x86/checksum_32.h
29907 +--- linux-2.6.26.6/include/asm-x86/checksum_32.h 2008-10-08 23:24:05.000000000 -0400
29908 ++++ linux-2.6.26.6/include/asm-x86/checksum_32.h 2008-10-11 21:54:20.000000000 -0400
29909 +@@ -31,6 +31,14 @@ asmlinkage __wsum csum_partial_copy_gene
29910 + int len, __wsum sum,
29911 + int *src_err_ptr, int *dst_err_ptr);
29912 +
29913 ++asmlinkage __wsum csum_partial_copy_generic_to_user(const void *src, void *dst,
29914 ++ int len, __wsum sum,
29915 ++ int *src_err_ptr, int *dst_err_ptr);
29916 ++
29917 ++asmlinkage __wsum csum_partial_copy_generic_from_user(const void *src, void *dst,
29918 ++ int len, __wsum sum,
29919 ++ int *src_err_ptr, int *dst_err_ptr);
29920 ++
29921 + /*
29922 + * Note: when you get a NULL pointer exception here this means someone
29923 + * passed in an incorrect kernel address to one of these functions.
29924 +@@ -50,7 +58,7 @@ static inline __wsum csum_partial_copy_f
29925 + int *err_ptr)
29926 + {
29927 + might_sleep();
29928 +- return csum_partial_copy_generic((__force void *)src, dst,
29929 ++ return csum_partial_copy_generic_from_user((__force void *)src, dst,
29930 + len, sum, err_ptr, NULL);
29931 + }
29932 +
29933 +@@ -177,7 +185,7 @@ static inline __wsum csum_and_copy_to_us
29934 + {
29935 + might_sleep();
29936 + if (access_ok(VERIFY_WRITE, dst, len))
29937 +- return csum_partial_copy_generic(src, (__force void *)dst,
29938 ++ return csum_partial_copy_generic_to_user(src, (__force void *)dst,
29939 + len, sum, NULL, err_ptr);
29940 +
29941 + if (len)
29942 +diff -urNp linux-2.6.26.6/include/asm-x86/desc.h linux-2.6.26.6/include/asm-x86/desc.h
29943 +--- linux-2.6.26.6/include/asm-x86/desc.h 2008-10-08 23:24:05.000000000 -0400
29944 ++++ linux-2.6.26.6/include/asm-x86/desc.h 2008-10-11 21:54:20.000000000 -0400
29945 +@@ -16,6 +16,7 @@ static inline void fill_ldt(struct desc_
29946 + desc->base1 = (info->base_addr & 0x00ff0000) >> 16;
29947 + desc->type = (info->read_exec_only ^ 1) << 1;
29948 + desc->type |= info->contents << 2;
29949 ++ desc->type |= info->seg_not_present ^ 1;
29950 + desc->s = 1;
29951 + desc->dpl = 0x3;
29952 + desc->p = info->seg_not_present ^ 1;
29953 +@@ -27,14 +28,15 @@ static inline void fill_ldt(struct desc_
29954 + }
29955 +
29956 + extern struct desc_ptr idt_descr;
29957 +-extern gate_desc idt_table[];
29958 ++extern gate_desc idt_table[256];
29959 +
29960 +-#ifdef CONFIG_X86_64
29961 +-extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
29962 +-extern struct desc_ptr cpu_gdt_descr[];
29963 +-/* the cpu gdt accessor */
29964 +-#define get_cpu_gdt_table(x) ((struct desc_struct *)cpu_gdt_descr[x].address)
29965 ++extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
29966 ++static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
29967 ++{
29968 ++ return cpu_gdt_table[cpu];
29969 ++}
29970 +
29971 ++#ifdef CONFIG_X86_64
29972 + static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func,
29973 + unsigned dpl, unsigned ist, unsigned seg)
29974 + {
29975 +@@ -51,16 +53,6 @@ static inline void pack_gate(gate_desc *
29976 + }
29977 +
29978 + #else
29979 +-struct gdt_page {
29980 +- struct desc_struct gdt[GDT_ENTRIES];
29981 +-} __attribute__((aligned(PAGE_SIZE)));
29982 +-DECLARE_PER_CPU(struct gdt_page, gdt_page);
29983 +-
29984 +-static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
29985 +-{
29986 +- return per_cpu(gdt_page, cpu).gdt;
29987 +-}
29988 +-
29989 + static inline void pack_gate(gate_desc *gate, unsigned char type,
29990 + unsigned long base, unsigned dpl, unsigned flags,
29991 + unsigned short seg)
29992 +@@ -69,7 +61,6 @@ static inline void pack_gate(gate_desc *
29993 + gate->b = (base & 0xffff0000) |
29994 + (((0x80 | type | (dpl << 5)) & 0xff) << 8);
29995 + }
29996 +-
29997 + #endif
29998 +
29999 + static inline int desc_empty(const void *ptr)
30000 +@@ -106,19 +97,48 @@ static inline int desc_empty(const void
30001 + static inline void native_write_idt_entry(gate_desc *idt, int entry,
30002 + const gate_desc *gate)
30003 + {
30004 ++
30005 ++#ifdef CONFIG_PAX_KERNEXEC
30006 ++ unsigned long cr0;
30007 ++
30008 ++ pax_open_kernel(cr0);
30009 ++#endif
30010 ++
30011 + memcpy(&idt[entry], gate, sizeof(*gate));
30012 ++
30013 ++#ifdef CONFIG_PAX_KERNEXEC
30014 ++ pax_close_kernel(cr0);
30015 ++#endif
30016 ++
30017 + }
30018 +
30019 + static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry,
30020 + const void *desc)
30021 + {
30022 ++
30023 ++#ifdef CONFIG_PAX_KERNEXEC
30024 ++ unsigned long cr0;
30025 ++
30026 ++ pax_open_kernel(cr0);
30027 ++#endif
30028 ++
30029 + memcpy(&ldt[entry], desc, 8);
30030 ++
30031 ++#ifdef CONFIG_PAX_KERNEXEC
30032 ++ pax_close_kernel(cr0);
30033 ++#endif
30034 ++
30035 + }
30036 +
30037 + static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry,
30038 + const void *desc, int type)
30039 + {
30040 + unsigned int size;
30041 ++
30042 ++#ifdef CONFIG_PAX_KERNEXEC
30043 ++ unsigned long cr0;
30044 ++#endif
30045 ++
30046 + switch (type) {
30047 + case DESC_TSS:
30048 + size = sizeof(tss_desc);
30049 +@@ -130,7 +150,17 @@ static inline void native_write_gdt_entr
30050 + size = sizeof(struct desc_struct);
30051 + break;
30052 + }
30053 ++
30054 ++#ifdef CONFIG_PAX_KERNEXEC
30055 ++ pax_open_kernel(cr0);
30056 ++#endif
30057 ++
30058 + memcpy(&gdt[entry], desc, size);
30059 ++
30060 ++#ifdef CONFIG_PAX_KERNEXEC
30061 ++ pax_close_kernel(cr0);
30062 ++#endif
30063 ++
30064 + }
30065 +
30066 + static inline void pack_descriptor(struct desc_struct *desc, unsigned long base,
30067 +@@ -202,7 +232,19 @@ static inline void native_set_ldt(const
30068 +
30069 + static inline void native_load_tr_desc(void)
30070 + {
30071 ++
30072 ++#ifdef CONFIG_PAX_KERNEXEC
30073 ++ unsigned long cr0;
30074 ++
30075 ++ pax_open_kernel(cr0);
30076 ++#endif
30077 ++
30078 + asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
30079 ++
30080 ++#ifdef CONFIG_PAX_KERNEXEC
30081 ++ pax_close_kernel(cr0);
30082 ++#endif
30083 ++
30084 + }
30085 +
30086 + static inline void native_load_gdt(const struct desc_ptr *dtr)
30087 +@@ -237,8 +279,19 @@ static inline void native_load_tls(struc
30088 + unsigned int i;
30089 + struct desc_struct *gdt = get_cpu_gdt_table(cpu);
30090 +
30091 ++#ifdef CONFIG_PAX_KERNEXEC
30092 ++ unsigned long cr0;
30093 ++
30094 ++ pax_open_kernel(cr0);
30095 ++#endif
30096 ++
30097 + for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
30098 + gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
30099 ++
30100 ++#ifdef CONFIG_PAX_KERNEXEC
30101 ++ pax_close_kernel(cr0);
30102 ++#endif
30103 ++
30104 + }
30105 +
30106 + #define _LDT_empty(info) \
30107 +@@ -354,6 +407,18 @@ static inline void set_system_gate_ist(i
30108 + _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS);
30109 + }
30110 +
30111 ++#ifdef CONFIG_X86_32
30112 ++static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
30113 ++{
30114 ++ struct desc_struct d;
30115 ++
30116 ++ if (likely(limit))
30117 ++ limit = (limit - 1UL) >> PAGE_SHIFT;
30118 ++ pack_descriptor(&d, base, limit, 0xFB, 0xC);
30119 ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, &d, DESCTYPE_S);
30120 ++}
30121 ++#endif
30122 ++
30123 + #else
30124 + /*
30125 + * GET_DESC_BASE reads the descriptor base of the specified segment.
30126 +diff -urNp linux-2.6.26.6/include/asm-x86/e820.h linux-2.6.26.6/include/asm-x86/e820.h
30127 +--- linux-2.6.26.6/include/asm-x86/e820.h 2008-10-08 23:24:05.000000000 -0400
30128 ++++ linux-2.6.26.6/include/asm-x86/e820.h 2008-10-11 21:54:20.000000000 -0400
30129 +@@ -25,7 +25,7 @@ struct e820map {
30130 + #define ISA_START_ADDRESS 0xa0000
30131 + #define ISA_END_ADDRESS 0x100000
30132 +
30133 +-#define BIOS_BEGIN 0x000a0000
30134 ++#define BIOS_BEGIN 0x000c0000
30135 + #define BIOS_END 0x00100000
30136 +
30137 + #ifdef __KERNEL__
30138 +diff -urNp linux-2.6.26.6/include/asm-x86/elf.h linux-2.6.26.6/include/asm-x86/elf.h
30139 +--- linux-2.6.26.6/include/asm-x86/elf.h 2008-10-08 23:24:05.000000000 -0400
30140 ++++ linux-2.6.26.6/include/asm-x86/elf.h 2008-10-11 21:54:20.000000000 -0400
30141 +@@ -251,7 +251,25 @@ extern int force_personality32;
30142 + the loader. We need to make sure that it is out of the way of the program
30143 + that it will "exec", and that there is sufficient room for the brk. */
30144 +
30145 ++#ifdef CONFIG_PAX_SEGMEXEC
30146 ++#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
30147 ++#else
30148 + #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
30149 ++#endif
30150 ++
30151 ++#ifdef CONFIG_PAX_ASLR
30152 ++#ifdef CONFIG_X86_32
30153 ++#define PAX_ELF_ET_DYN_BASE 0x10000000UL
30154 ++
30155 ++#define PAX_DELTA_MMAP_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
30156 ++#define PAX_DELTA_STACK_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
30157 ++#else
30158 ++#define PAX_ELF_ET_DYN_BASE 0x400000UL
30159 ++
30160 ++#define PAX_DELTA_MMAP_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
30161 ++#define PAX_DELTA_STACK_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
30162 ++#endif
30163 ++#endif
30164 +
30165 + /* This yields a mask that user programs can use to figure out what
30166 + instruction set this CPU supports. This could be done in user space,
30167 +@@ -303,8 +321,7 @@ do { \
30168 + #define ARCH_DLINFO \
30169 + do { \
30170 + if (vdso_enabled) \
30171 +- NEW_AUX_ENT(AT_SYSINFO_EHDR, \
30172 +- (unsigned long)current->mm->context.vdso); \
30173 ++ NEW_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso);\
30174 + } while (0)
30175 +
30176 + #define AT_SYSINFO 32
30177 +@@ -315,7 +332,7 @@ do { \
30178 +
30179 + #endif /* !CONFIG_X86_32 */
30180 +
30181 +-#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
30182 ++#define VDSO_CURRENT_BASE (current->mm->context.vdso)
30183 +
30184 + #define VDSO_ENTRY \
30185 + ((unsigned long)VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall))
30186 +@@ -329,7 +346,4 @@ extern int arch_setup_additional_pages(s
30187 + extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
30188 + #define compat_arch_setup_additional_pages syscall32_setup_pages
30189 +
30190 +-extern unsigned long arch_randomize_brk(struct mm_struct *mm);
30191 +-#define arch_randomize_brk arch_randomize_brk
30192 +-
30193 + #endif
30194 +diff -urNp linux-2.6.26.6/include/asm-x86/futex.h linux-2.6.26.6/include/asm-x86/futex.h
30195 +--- linux-2.6.26.6/include/asm-x86/futex.h 2008-10-08 23:24:05.000000000 -0400
30196 ++++ linux-2.6.26.6/include/asm-x86/futex.h 2008-10-11 21:55:52.000000000 -0400
30197 +@@ -11,6 +11,40 @@
30198 + #include <asm/processor.h>
30199 + #include <asm/system.h>
30200 +
30201 ++#ifdef CONFIG_X86_32
30202 ++#define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
30203 ++ asm volatile( \
30204 ++ "movw\t%w6, %%ds\n" \
30205 ++ "1:\t" insn "\n" \
30206 ++ "2:\tpushl\t%%ss\n" \
30207 ++ "\tpopl\t%%ds\n" \
30208 ++ "\t.section .fixup,\"ax\"\n" \
30209 ++ "3:\tmov\t%3, %1\n" \
30210 ++ "\tjmp\t2b\n" \
30211 ++ "\t.previous\n" \
30212 ++ _ASM_EXTABLE(1b, 3b) \
30213 ++ : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
30214 ++ : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS))
30215 ++
30216 ++#define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
30217 ++ asm volatile("movw\t%w7, %%es\n" \
30218 ++ "1:\tmovl\t%%es:%2, %0\n" \
30219 ++ "\tmovl\t%0, %3\n" \
30220 ++ "\t" insn "\n" \
30221 ++ "2:\tlock; cmpxchgl %3, %%es:%2\n" \
30222 ++ "\tjnz\t1b\n" \
30223 ++ "3:\tpushl\t%%ss\n" \
30224 ++ "\tpopl\t%%es\n" \
30225 ++ "\t.section .fixup,\"ax\"\n" \
30226 ++ "4:\tmov\t%5, %1\n" \
30227 ++ "\tjmp\t3b\n" \
30228 ++ "\t.previous\n" \
30229 ++ _ASM_EXTABLE(1b, 4b) \
30230 ++ _ASM_EXTABLE(2b, 4b) \
30231 ++ : "=&a" (oldval), "=&r" (ret), \
30232 ++ "+m" (*uaddr), "=&r" (tem) \
30233 ++ : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS))
30234 ++#else
30235 + #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
30236 + asm volatile("1:\t" insn "\n" \
30237 + "2:\t.section .fixup,\"ax\"\n" \
30238 +@@ -36,8 +70,9 @@
30239 + : "=&a" (oldval), "=&r" (ret), \
30240 + "+m" (*uaddr), "=&r" (tem) \
30241 + : "r" (oparg), "i" (-EFAULT), "1" (0))
30242 ++#endif
30243 +
30244 +-static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
30245 ++static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
30246 + {
30247 + int op = (encoded_op >> 28) & 7;
30248 + int cmp = (encoded_op >> 24) & 15;
30249 +@@ -61,11 +96,20 @@ static inline int futex_atomic_op_inuser
30250 +
30251 + switch (op) {
30252 + case FUTEX_OP_SET:
30253 ++#ifdef CONFIG_X86_32
30254 ++ __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg);
30255 ++#else
30256 + __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
30257 ++#endif
30258 + break;
30259 + case FUTEX_OP_ADD:
30260 ++#ifdef CONFIG_X86_32
30261 ++ __futex_atomic_op1("lock ; xaddl %0, %%ds:%2", ret, oldval,
30262 ++ uaddr, oparg);
30263 ++#else
30264 + __futex_atomic_op1("lock; xaddl %0, %2", ret, oldval,
30265 + uaddr, oparg);
30266 ++#endif
30267 + break;
30268 + case FUTEX_OP_OR:
30269 + __futex_atomic_op2("orl %4, %3", ret, oldval, uaddr, oparg);
30270 +@@ -109,7 +153,7 @@ static inline int futex_atomic_op_inuser
30271 + return ret;
30272 + }
30273 +
30274 +-static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval,
30275 ++static inline int futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval,
30276 + int newval)
30277 + {
30278 +
30279 +@@ -122,14 +166,27 @@ static inline int futex_atomic_cmpxchg_i
30280 + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
30281 + return -EFAULT;
30282 +
30283 +- asm volatile("1:\tlock; cmpxchgl %3, %1\n"
30284 ++ asm volatile(
30285 ++#ifdef CONFIG_X86_32
30286 ++ "\tmovw %w5, %%ds\n"
30287 ++ "1:\tlock; cmpxchgl %3, %1\n"
30288 ++ "2:\tpushl %%ss\n"
30289 ++ "\tpopl %%ds\n"
30290 ++ "\t.section .fixup, \"ax\"\n"
30291 ++#else
30292 ++ "1:\tlock; cmpxchgl %3, %1\n"
30293 + "2:\t.section .fixup, \"ax\"\n"
30294 ++#endif
30295 + "3:\tmov %2, %0\n"
30296 + "\tjmp 2b\n"
30297 + "\t.previous\n"
30298 + _ASM_EXTABLE(1b, 3b)
30299 + : "=a" (oldval), "+m" (*uaddr)
30300 ++#ifdef CONFIG_X86_32
30301 ++ : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS)
30302 ++#else
30303 + : "i" (-EFAULT), "r" (newval), "0" (oldval)
30304 ++#endif
30305 + : "memory"
30306 + );
30307 +
30308 +diff -urNp linux-2.6.26.6/include/asm-x86/i387.h linux-2.6.26.6/include/asm-x86/i387.h
30309 +--- linux-2.6.26.6/include/asm-x86/i387.h 2008-10-08 23:24:05.000000000 -0400
30310 ++++ linux-2.6.26.6/include/asm-x86/i387.h 2008-10-11 21:54:20.000000000 -0400
30311 +@@ -159,13 +159,8 @@ static inline void restore_fpu(struct ta
30312 + }
30313 +
30314 + /* We need a safe address that is cheap to find and that is already
30315 +- in L1 during context switch. The best choices are unfortunately
30316 +- different for UP and SMP */
30317 +-#ifdef CONFIG_SMP
30318 +-#define safe_address (__per_cpu_offset[0])
30319 +-#else
30320 +-#define safe_address (kstat_cpu(0).cpustat.user)
30321 +-#endif
30322 ++ in L1 during context switch. */
30323 ++#define safe_address (init_tss[smp_processor_id()].x86_tss.sp0)
30324 +
30325 + /*
30326 + * These must be called with preempt disabled
30327 +diff -urNp linux-2.6.26.6/include/asm-x86/io_64.h linux-2.6.26.6/include/asm-x86/io_64.h
30328 +--- linux-2.6.26.6/include/asm-x86/io_64.h 2008-10-08 23:24:05.000000000 -0400
30329 ++++ linux-2.6.26.6/include/asm-x86/io_64.h 2008-10-11 21:54:20.000000000 -0400
30330 +@@ -158,6 +158,17 @@ static inline void *phys_to_virt(unsigne
30331 + }
30332 + #endif
30333 +
30334 ++#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
30335 ++static inline int valid_phys_addr_range (unsigned long addr, size_t count)
30336 ++{
30337 ++ return ((addr + count + PAGE_SIZE - 1) >> PAGE_SHIFT) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
30338 ++}
30339 ++
30340 ++static inline int valid_mmap_phys_addr_range (unsigned long pfn, size_t count)
30341 ++{
30342 ++ return (pfn + (count >> PAGE_SHIFT)) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
30343 ++}
30344 ++
30345 + /*
30346 + * Change "struct page" to physical address.
30347 + */
30348 +diff -urNp linux-2.6.26.6/include/asm-x86/irqflags.h linux-2.6.26.6/include/asm-x86/irqflags.h
30349 +--- linux-2.6.26.6/include/asm-x86/irqflags.h 2008-10-08 23:24:05.000000000 -0400
30350 ++++ linux-2.6.26.6/include/asm-x86/irqflags.h 2008-10-11 21:54:20.000000000 -0400
30351 +@@ -120,6 +120,8 @@ static inline unsigned long __raw_local_
30352 + #define INTERRUPT_RETURN iret
30353 + #define ENABLE_INTERRUPTS_SYSCALL_RET sti; sysexit
30354 + #define GET_CR0_INTO_EAX movl %cr0, %eax
30355 ++#define GET_CR0_INTO_EDX movl %cr0, %edx
30356 ++#define SET_CR0_FROM_EDX movl %edx, %cr0
30357 + #endif
30358 +
30359 +
30360 +diff -urNp linux-2.6.26.6/include/asm-x86/kmap_types.h linux-2.6.26.6/include/asm-x86/kmap_types.h
30361 +--- linux-2.6.26.6/include/asm-x86/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
30362 ++++ linux-2.6.26.6/include/asm-x86/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
30363 +@@ -21,7 +21,8 @@ D(9) KM_IRQ0,
30364 + D(10) KM_IRQ1,
30365 + D(11) KM_SOFTIRQ0,
30366 + D(12) KM_SOFTIRQ1,
30367 +-D(13) KM_TYPE_NR
30368 ++D(13) KM_CLEARPAGE,
30369 ++D(14) KM_TYPE_NR
30370 + };
30371 +
30372 + #undef D
30373 +diff -urNp linux-2.6.26.6/include/asm-x86/linkage.h linux-2.6.26.6/include/asm-x86/linkage.h
30374 +--- linux-2.6.26.6/include/asm-x86/linkage.h 2008-10-08 23:24:05.000000000 -0400
30375 ++++ linux-2.6.26.6/include/asm-x86/linkage.h 2008-10-11 21:54:20.000000000 -0400
30376 +@@ -7,6 +7,11 @@
30377 + #ifdef CONFIG_X86_64
30378 + #define __ALIGN .p2align 4,,15
30379 + #define __ALIGN_STR ".p2align 4,,15"
30380 ++#else
30381 ++#ifdef CONFIG_X86_ALIGNMENT_16
30382 ++#define __ALIGN .align 16,0x90
30383 ++#define __ALIGN_STR ".align 16,0x90"
30384 ++#endif
30385 + #endif
30386 +
30387 + #ifdef CONFIG_X86_32
30388 +@@ -52,10 +57,5 @@
30389 +
30390 + #endif
30391 +
30392 +-#ifdef CONFIG_X86_ALIGNMENT_16
30393 +-#define __ALIGN .align 16,0x90
30394 +-#define __ALIGN_STR ".align 16,0x90"
30395 +-#endif
30396 +-
30397 + #endif
30398 +
30399 +diff -urNp linux-2.6.26.6/include/asm-x86/local.h linux-2.6.26.6/include/asm-x86/local.h
30400 +--- linux-2.6.26.6/include/asm-x86/local.h 2008-10-08 23:24:05.000000000 -0400
30401 ++++ linux-2.6.26.6/include/asm-x86/local.h 2008-10-11 21:54:20.000000000 -0400
30402 +@@ -18,26 +18,90 @@ typedef struct {
30403 +
30404 + static inline void local_inc(local_t *l)
30405 + {
30406 +- asm volatile(_ASM_INC "%0"
30407 ++ asm volatile(_ASM_INC "%0\n"
30408 ++
30409 ++#ifdef CONFIG_PAX_REFCOUNT
30410 ++#ifdef CONFIG_X86_32
30411 ++ "into\n0:\n"
30412 ++#else
30413 ++ "jno 0f\n"
30414 ++ "int $4\n0:\n"
30415 ++#endif
30416 ++ ".pushsection .fixup,\"ax\"\n"
30417 ++ "1:\n"
30418 ++ _ASM_DEC "%0\n"
30419 ++ "jmp 0b\n"
30420 ++ ".popsection\n"
30421 ++ _ASM_EXTABLE(0b, 1b)
30422 ++#endif
30423 ++
30424 + : "+m" (l->a.counter));
30425 + }
30426 +
30427 + static inline void local_dec(local_t *l)
30428 + {
30429 +- asm volatile(_ASM_DEC "%0"
30430 ++ asm volatile(_ASM_DEC "%0\n"
30431 ++
30432 ++#ifdef CONFIG_PAX_REFCOUNT
30433 ++#ifdef CONFIG_X86_32
30434 ++ "into\n0:\n"
30435 ++#else
30436 ++ "jno 0f\n"
30437 ++ "int $4\n0:\n"
30438 ++#endif
30439 ++ ".pushsection .fixup,\"ax\"\n"
30440 ++ "1:\n"
30441 ++ _ASM_INC "%0\n"
30442 ++ "jmp 0b\n"
30443 ++ ".popsection\n"
30444 ++ _ASM_EXTABLE(0b, 1b)
30445 ++#endif
30446 ++
30447 + : "+m" (l->a.counter));
30448 + }
30449 +
30450 + static inline void local_add(long i, local_t *l)
30451 + {
30452 +- asm volatile(_ASM_ADD "%1,%0"
30453 ++ asm volatile(_ASM_ADD "%1,%0\n"
30454 ++
30455 ++#ifdef CONFIG_PAX_REFCOUNT
30456 ++#ifdef CONFIG_X86_32
30457 ++ "into\n0:\n"
30458 ++#else
30459 ++ "jno 0f\n"
30460 ++ "int $4\n0:\n"
30461 ++#endif
30462 ++ ".pushsection .fixup,\"ax\"\n"
30463 ++ "1:\n"
30464 ++ _ASM_SUB "%1,%0\n"
30465 ++ "jmp 0b\n"
30466 ++ ".popsection\n"
30467 ++ _ASM_EXTABLE(0b, 1b)
30468 ++#endif
30469 ++
30470 + : "+m" (l->a.counter)
30471 + : "ir" (i));
30472 + }
30473 +
30474 + static inline void local_sub(long i, local_t *l)
30475 + {
30476 +- asm volatile(_ASM_SUB "%1,%0"
30477 ++ asm volatile(_ASM_SUB "%1,%0\n"
30478 ++
30479 ++#ifdef CONFIG_PAX_REFCOUNT
30480 ++#ifdef CONFIG_X86_32
30481 ++ "into\n0:\n"
30482 ++#else
30483 ++ "jno 0f\n"
30484 ++ "int $4\n0:\n"
30485 ++#endif
30486 ++ ".pushsection .fixup,\"ax\"\n"
30487 ++ "1:\n"
30488 ++ _ASM_ADD "%1,%0\n"
30489 ++ "jmp 0b\n"
30490 ++ ".popsection\n"
30491 ++ _ASM_EXTABLE(0b, 1b)
30492 ++#endif
30493 ++
30494 + : "+m" (l->a.counter)
30495 + : "ir" (i));
30496 + }
30497 +@@ -55,7 +119,24 @@ static inline int local_sub_and_test(lon
30498 + {
30499 + unsigned char c;
30500 +
30501 +- asm volatile(_ASM_SUB "%2,%0; sete %1"
30502 ++ asm volatile(_ASM_SUB "%2,%0\n"
30503 ++
30504 ++#ifdef CONFIG_PAX_REFCOUNT
30505 ++#ifdef CONFIG_X86_32
30506 ++ "into\n0:\n"
30507 ++#else
30508 ++ "jno 0f\n"
30509 ++ "int $4\n0:\n"
30510 ++#endif
30511 ++ ".pushsection .fixup,\"ax\"\n"
30512 ++ "1:\n"
30513 ++ _ASM_ADD "%2,%0\n"
30514 ++ "jmp 0b\n"
30515 ++ ".popsection\n"
30516 ++ _ASM_EXTABLE(0b, 1b)
30517 ++#endif
30518 ++
30519 ++ "sete %1\n"
30520 + : "+m" (l->a.counter), "=qm" (c)
30521 + : "ir" (i) : "memory");
30522 + return c;
30523 +@@ -73,7 +154,24 @@ static inline int local_dec_and_test(loc
30524 + {
30525 + unsigned char c;
30526 +
30527 +- asm volatile(_ASM_DEC "%0; sete %1"
30528 ++ asm volatile(_ASM_DEC "%0\n"
30529 ++
30530 ++#ifdef CONFIG_PAX_REFCOUNT
30531 ++#ifdef CONFIG_X86_32
30532 ++ "into\n0:\n"
30533 ++#else
30534 ++ "jno 0f\n"
30535 ++ "int $4\n0:\n"
30536 ++#endif
30537 ++ ".pushsection .fixup,\"ax\"\n"
30538 ++ "1:\n"
30539 ++ _ASM_INC "%0\n"
30540 ++ "jmp 0b\n"
30541 ++ ".popsection\n"
30542 ++ _ASM_EXTABLE(0b, 1b)
30543 ++#endif
30544 ++
30545 ++ "sete %1\n"
30546 + : "+m" (l->a.counter), "=qm" (c)
30547 + : : "memory");
30548 + return c != 0;
30549 +@@ -91,7 +189,24 @@ static inline int local_inc_and_test(loc
30550 + {
30551 + unsigned char c;
30552 +
30553 +- asm volatile(_ASM_INC "%0; sete %1"
30554 ++ asm volatile(_ASM_INC "%0\n"
30555 ++
30556 ++#ifdef CONFIG_PAX_REFCOUNT
30557 ++#ifdef CONFIG_X86_32
30558 ++ "into\n0:\n"
30559 ++#else
30560 ++ "jno 0f\n"
30561 ++ "int $4\n0:\n"
30562 ++#endif
30563 ++ ".pushsection .fixup,\"ax\"\n"
30564 ++ "1:\n"
30565 ++ _ASM_DEC "%0\n"
30566 ++ "jmp 0b\n"
30567 ++ ".popsection\n"
30568 ++ _ASM_EXTABLE(0b, 1b)
30569 ++#endif
30570 ++
30571 ++ "sete %1\n"
30572 + : "+m" (l->a.counter), "=qm" (c)
30573 + : : "memory");
30574 + return c != 0;
30575 +@@ -110,7 +225,24 @@ static inline int local_add_negative(lon
30576 + {
30577 + unsigned char c;
30578 +
30579 +- asm volatile(_ASM_ADD "%2,%0; sets %1"
30580 ++ asm volatile(_ASM_ADD "%2,%0\n"
30581 ++
30582 ++#ifdef CONFIG_PAX_REFCOUNT
30583 ++#ifdef CONFIG_X86_32
30584 ++ "into\n0:\n"
30585 ++#else
30586 ++ "jno 0f\n"
30587 ++ "int $4\n0:\n"
30588 ++#endif
30589 ++ ".pushsection .fixup,\"ax\"\n"
30590 ++ "1:\n"
30591 ++ _ASM_SUB "%2,%0\n"
30592 ++ "jmp 0b\n"
30593 ++ ".popsection\n"
30594 ++ _ASM_EXTABLE(0b, 1b)
30595 ++#endif
30596 ++
30597 ++ "sets %1\n"
30598 + : "+m" (l->a.counter), "=qm" (c)
30599 + : "ir" (i) : "memory");
30600 + return c;
30601 +@@ -133,7 +265,23 @@ static inline long local_add_return(long
30602 + #endif
30603 + /* Modern 486+ processor */
30604 + __i = i;
30605 +- asm volatile(_ASM_XADD "%0, %1;"
30606 ++ asm volatile(_ASM_XADD "%0, %1\n"
30607 ++
30608 ++#ifdef CONFIG_PAX_REFCOUNT
30609 ++#ifdef CONFIG_X86_32
30610 ++ "into\n0:\n"
30611 ++#else
30612 ++ "jno 0f\n"
30613 ++ "int $4\n0:\n"
30614 ++#endif
30615 ++ ".pushsection .fixup,\"ax\"\n"
30616 ++ "1:\n"
30617 ++ _ASM_MOV_UL "%0,%1\n"
30618 ++ "jmp 0b\n"
30619 ++ ".popsection\n"
30620 ++ _ASM_EXTABLE(0b, 1b)
30621 ++#endif
30622 ++
30623 + : "+r" (i), "+m" (l->a.counter)
30624 + : : "memory");
30625 + return i + __i;
30626 +diff -urNp linux-2.6.26.6/include/asm-x86/mach-default/apm.h linux-2.6.26.6/include/asm-x86/mach-default/apm.h
30627 +--- linux-2.6.26.6/include/asm-x86/mach-default/apm.h 2008-10-08 23:24:05.000000000 -0400
30628 ++++ linux-2.6.26.6/include/asm-x86/mach-default/apm.h 2008-10-11 21:54:20.000000000 -0400
30629 +@@ -34,7 +34,7 @@ static inline void apm_bios_call_asm(u32
30630 + __asm__ __volatile__(APM_DO_ZERO_SEGS
30631 + "pushl %%edi\n\t"
30632 + "pushl %%ebp\n\t"
30633 +- "lcall *%%cs:apm_bios_entry\n\t"
30634 ++ "lcall *%%ss:apm_bios_entry\n\t"
30635 + "setc %%al\n\t"
30636 + "popl %%ebp\n\t"
30637 + "popl %%edi\n\t"
30638 +@@ -58,7 +58,7 @@ static inline u8 apm_bios_call_simple_as
30639 + __asm__ __volatile__(APM_DO_ZERO_SEGS
30640 + "pushl %%edi\n\t"
30641 + "pushl %%ebp\n\t"
30642 +- "lcall *%%cs:apm_bios_entry\n\t"
30643 ++ "lcall *%%ss:apm_bios_entry\n\t"
30644 + "setc %%bl\n\t"
30645 + "popl %%ebp\n\t"
30646 + "popl %%edi\n\t"
30647 +diff -urNp linux-2.6.26.6/include/asm-x86/mman.h linux-2.6.26.6/include/asm-x86/mman.h
30648 +--- linux-2.6.26.6/include/asm-x86/mman.h 2008-10-08 23:24:05.000000000 -0400
30649 ++++ linux-2.6.26.6/include/asm-x86/mman.h 2008-10-11 21:54:20.000000000 -0400
30650 +@@ -16,4 +16,14 @@
30651 + #define MCL_CURRENT 1 /* lock all current mappings */
30652 + #define MCL_FUTURE 2 /* lock all future mappings */
30653 +
30654 ++#ifdef __KERNEL__
30655 ++#ifndef __ASSEMBLY__
30656 ++#ifdef CONFIG_X86_32
30657 ++#define arch_mmap_check i386_mmap_check
30658 ++int i386_mmap_check(unsigned long addr, unsigned long len,
30659 ++ unsigned long flags);
30660 ++#endif
30661 ++#endif
30662 ++#endif
30663 ++
30664 + #endif /* _ASM_X86_MMAN_H */
30665 +diff -urNp linux-2.6.26.6/include/asm-x86/mmu_context_32.h linux-2.6.26.6/include/asm-x86/mmu_context_32.h
30666 +--- linux-2.6.26.6/include/asm-x86/mmu_context_32.h 2008-10-08 23:24:05.000000000 -0400
30667 ++++ linux-2.6.26.6/include/asm-x86/mmu_context_32.h 2008-10-11 21:54:20.000000000 -0400
30668 +@@ -55,6 +55,22 @@ static inline void switch_mm(struct mm_s
30669 + */
30670 + if (unlikely(prev->context.ldt != next->context.ldt))
30671 + load_LDT_nolock(&next->context);
30672 ++
30673 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
30674 ++ if (!nx_enabled) {
30675 ++ smp_mb__before_clear_bit();
30676 ++ cpu_clear(cpu, prev->context.cpu_user_cs_mask);
30677 ++ smp_mb__after_clear_bit();
30678 ++ cpu_set(cpu, next->context.cpu_user_cs_mask);
30679 ++ }
30680 ++#endif
30681 ++
30682 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
30683 ++ if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
30684 ++ prev->context.user_cs_limit != next->context.user_cs_limit))
30685 ++ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
30686 ++#endif
30687 ++
30688 + }
30689 + #ifdef CONFIG_SMP
30690 + else {
30691 +@@ -67,6 +83,19 @@ static inline void switch_mm(struct mm_s
30692 + */
30693 + load_cr3(next->pgd);
30694 + load_LDT_nolock(&next->context);
30695 ++
30696 ++#ifdef CONFIG_PAX_PAGEEXEC
30697 ++ if (!nx_enabled)
30698 ++ cpu_set(cpu, next->context.cpu_user_cs_mask);
30699 ++#endif
30700 ++
30701 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
30702 ++#ifdef CONFIG_PAX_PAGEEXEC
30703 ++ if (!((next->pax_flags & MF_PAX_PAGEEXEC) && nx_enabled))
30704 ++#endif
30705 ++ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
30706 ++#endif
30707 ++
30708 + }
30709 + }
30710 + #endif
30711 +diff -urNp linux-2.6.26.6/include/asm-x86/mmu.h linux-2.6.26.6/include/asm-x86/mmu.h
30712 +--- linux-2.6.26.6/include/asm-x86/mmu.h 2008-10-08 23:24:05.000000000 -0400
30713 ++++ linux-2.6.26.6/include/asm-x86/mmu.h 2008-10-11 21:54:20.000000000 -0400
30714 +@@ -11,13 +11,26 @@
30715 + * cpu_vm_mask is used to optimize ldt flushing.
30716 + */
30717 + typedef struct {
30718 +- void *ldt;
30719 ++ struct desc_struct *ldt;
30720 + #ifdef CONFIG_X86_64
30721 + rwlock_t ldtlock;
30722 + #endif
30723 + int size;
30724 + struct mutex lock;
30725 +- void *vdso;
30726 ++ unsigned long vdso;
30727 ++
30728 ++#ifdef CONFIG_X86_32
30729 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
30730 ++ unsigned long user_cs_base;
30731 ++ unsigned long user_cs_limit;
30732 ++
30733 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
30734 ++ cpumask_t cpu_user_cs_mask;
30735 ++#endif
30736 ++
30737 ++#endif
30738 ++#endif
30739 ++
30740 + } mm_context_t;
30741 +
30742 + #ifdef CONFIG_SMP
30743 +diff -urNp linux-2.6.26.6/include/asm-x86/module.h linux-2.6.26.6/include/asm-x86/module.h
30744 +--- linux-2.6.26.6/include/asm-x86/module.h 2008-10-08 23:24:05.000000000 -0400
30745 ++++ linux-2.6.26.6/include/asm-x86/module.h 2008-10-11 21:54:20.000000000 -0400
30746 +@@ -76,7 +76,12 @@ struct mod_arch_specific {};
30747 + # else
30748 + # define MODULE_STACKSIZE ""
30749 + # endif
30750 +-# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
30751 ++# ifdef CONFIG_GRKERNSEC
30752 ++# define MODULE_GRSEC "GRSECURITY "
30753 ++# else
30754 ++# define MODULE_GRSEC ""
30755 ++# endif
30756 ++# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE MODULE_GRSEC
30757 + #endif
30758 +
30759 + #endif /* _ASM_MODULE_H */
30760 +diff -urNp linux-2.6.26.6/include/asm-x86/page_32.h linux-2.6.26.6/include/asm-x86/page_32.h
30761 +--- linux-2.6.26.6/include/asm-x86/page_32.h 2008-10-08 23:24:05.000000000 -0400
30762 ++++ linux-2.6.26.6/include/asm-x86/page_32.h 2008-10-11 21:54:20.000000000 -0400
30763 +@@ -13,6 +13,23 @@
30764 + */
30765 + #define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL)
30766 +
30767 ++#ifdef CONFIG_PAX_KERNEXEC
30768 ++#ifndef __ASSEMBLY__
30769 ++extern unsigned char MODULES_VADDR[];
30770 ++extern unsigned char MODULES_END[];
30771 ++extern unsigned char KERNEL_TEXT_OFFSET[];
30772 ++#define ktla_ktva(addr) (addr + (unsigned long)KERNEL_TEXT_OFFSET)
30773 ++#define ktva_ktla(addr) (addr - (unsigned long)KERNEL_TEXT_OFFSET)
30774 ++#endif
30775 ++#else
30776 ++#define ktla_ktva(addr) (addr)
30777 ++#define ktva_ktla(addr) (addr)
30778 ++#endif
30779 ++
30780 ++#ifdef CONFIG_PAX_PAGEEXEC
30781 ++#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
30782 ++#endif
30783 ++
30784 + #ifdef CONFIG_X86_PAE
30785 + /* 44=32+12, the limit we can fit into an unsigned long pfn */
30786 + #define __PHYSICAL_MASK_SHIFT 44
30787 +diff -urNp linux-2.6.26.6/include/asm-x86/page_64.h linux-2.6.26.6/include/asm-x86/page_64.h
30788 +--- linux-2.6.26.6/include/asm-x86/page_64.h 2008-10-08 23:24:05.000000000 -0400
30789 ++++ linux-2.6.26.6/include/asm-x86/page_64.h 2008-10-11 21:54:20.000000000 -0400
30790 +@@ -43,6 +43,9 @@
30791 + #define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START)
30792 + #define __START_KERNEL_map _AC(0xffffffff80000000, UL)
30793 +
30794 ++#define ktla_ktva(addr) (addr)
30795 ++#define ktva_ktla(addr) (addr)
30796 ++
30797 + /* See Documentation/x86_64/mm.txt for a description of the memory map. */
30798 + #define __PHYSICAL_MASK_SHIFT 46
30799 + #define __VIRTUAL_MASK_SHIFT 48
30800 +@@ -89,5 +92,6 @@ extern unsigned long init_memory_mapping
30801 + #define pfn_valid(pfn) ((pfn) < end_pfn)
30802 + #endif
30803 +
30804 ++#define nx_enabled (1)
30805 +
30806 + #endif /* _X86_64_PAGE_H */
30807 +diff -urNp linux-2.6.26.6/include/asm-x86/paravirt.h linux-2.6.26.6/include/asm-x86/paravirt.h
30808 +--- linux-2.6.26.6/include/asm-x86/paravirt.h 2008-10-08 23:24:05.000000000 -0400
30809 ++++ linux-2.6.26.6/include/asm-x86/paravirt.h 2008-10-11 21:54:20.000000000 -0400
30810 +@@ -1383,24 +1383,24 @@ static inline unsigned long __raw_local_
30811 +
30812 + #define INTERRUPT_RETURN \
30813 + PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_iret), CLBR_NONE, \
30814 +- jmp *%cs:pv_cpu_ops+PV_CPU_iret)
30815 ++ jmp *%ss:pv_cpu_ops+PV_CPU_iret)
30816 +
30817 + #define DISABLE_INTERRUPTS(clobbers) \
30818 + PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \
30819 + PV_SAVE_REGS; \
30820 +- call *%cs:pv_irq_ops+PV_IRQ_irq_disable; \
30821 ++ call *%ss:pv_irq_ops+PV_IRQ_irq_disable; \
30822 + PV_RESTORE_REGS;) \
30823 +
30824 + #define ENABLE_INTERRUPTS(clobbers) \
30825 + PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_enable), clobbers, \
30826 + PV_SAVE_REGS; \
30827 +- call *%cs:pv_irq_ops+PV_IRQ_irq_enable; \
30828 ++ call *%ss:pv_irq_ops+PV_IRQ_irq_enable; \
30829 + PV_RESTORE_REGS;)
30830 +
30831 + #define ENABLE_INTERRUPTS_SYSCALL_RET \
30832 + PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_syscall_ret),\
30833 + CLBR_NONE, \
30834 +- jmp *%cs:pv_cpu_ops+PV_CPU_irq_enable_syscall_ret)
30835 ++ jmp *%ss:pv_cpu_ops+PV_CPU_irq_enable_syscall_ret)
30836 +
30837 +
30838 + #ifdef CONFIG_X86_32
30839 +diff -urNp linux-2.6.26.6/include/asm-x86/pda.h linux-2.6.26.6/include/asm-x86/pda.h
30840 +--- linux-2.6.26.6/include/asm-x86/pda.h 2008-10-08 23:24:05.000000000 -0400
30841 ++++ linux-2.6.26.6/include/asm-x86/pda.h 2008-10-11 21:54:20.000000000 -0400
30842 +@@ -16,11 +16,9 @@ struct x8664_pda {
30843 + unsigned long oldrsp; /* 24 user rsp for system call */
30844 + int irqcount; /* 32 Irq nesting counter. Starts -1 */
30845 + unsigned int cpunumber; /* 36 Logical CPU number */
30846 +-#ifdef CONFIG_CC_STACKPROTECTOR
30847 + unsigned long stack_canary; /* 40 stack canary value */
30848 + /* gcc-ABI: this canary MUST be at
30849 + offset 40!!! */
30850 +-#endif
30851 + char *irqstackptr;
30852 + unsigned int __softirq_pending;
30853 + unsigned int __nmi_count; /* number of NMI on this CPUs */
30854 +diff -urNp linux-2.6.26.6/include/asm-x86/percpu.h linux-2.6.26.6/include/asm-x86/percpu.h
30855 +--- linux-2.6.26.6/include/asm-x86/percpu.h 2008-10-08 23:24:05.000000000 -0400
30856 ++++ linux-2.6.26.6/include/asm-x86/percpu.h 2008-10-11 21:54:20.000000000 -0400
30857 +@@ -67,6 +67,12 @@ DECLARE_PER_CPU(struct x8664_pda, pda);
30858 +
30859 + #define __my_cpu_offset x86_read_percpu(this_cpu_off)
30860 +
30861 ++#include <asm-generic/sections.h>
30862 ++#include <linux/threads.h>
30863 ++#define __per_cpu_offset __per_cpu_offset
30864 ++extern unsigned long __per_cpu_offset[NR_CPUS];
30865 ++#define per_cpu_offset(x) (__per_cpu_offset[x] + (unsigned long)__per_cpu_start)
30866 ++
30867 + /* fs segment starts at (positive) offset == __per_cpu_offset[cpu] */
30868 + #define __percpu_seg "%%fs:"
30869 +
30870 +diff -urNp linux-2.6.26.6/include/asm-x86/pgalloc.h linux-2.6.26.6/include/asm-x86/pgalloc.h
30871 +--- linux-2.6.26.6/include/asm-x86/pgalloc.h 2008-10-08 23:24:05.000000000 -0400
30872 ++++ linux-2.6.26.6/include/asm-x86/pgalloc.h 2008-10-11 21:54:20.000000000 -0400
30873 +@@ -47,7 +47,11 @@ static inline void pmd_populate_kernel(s
30874 + pmd_t *pmd, pte_t *pte)
30875 + {
30876 + paravirt_alloc_pte(mm, __pa(pte) >> PAGE_SHIFT);
30877 ++#ifdef CONFIG_COMPAT_VDSO
30878 + set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
30879 ++#else
30880 ++ set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE));
30881 ++#endif
30882 + }
30883 +
30884 + static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
30885 +diff -urNp linux-2.6.26.6/include/asm-x86/pgtable-2level.h linux-2.6.26.6/include/asm-x86/pgtable-2level.h
30886 +--- linux-2.6.26.6/include/asm-x86/pgtable-2level.h 2008-10-08 23:24:05.000000000 -0400
30887 ++++ linux-2.6.26.6/include/asm-x86/pgtable-2level.h 2008-10-11 21:54:20.000000000 -0400
30888 +@@ -18,7 +18,19 @@ static inline void native_set_pte(pte_t
30889 +
30890 + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
30891 + {
30892 ++
30893 ++#ifdef CONFIG_PAX_KERNEXEC
30894 ++ unsigned long cr0;
30895 ++
30896 ++ pax_open_kernel(cr0);
30897 ++#endif
30898 ++
30899 + *pmdp = pmd;
30900 ++
30901 ++#ifdef CONFIG_PAX_KERNEXEC
30902 ++ pax_close_kernel(cr0);
30903 ++#endif
30904 ++
30905 + }
30906 +
30907 + static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
30908 +diff -urNp linux-2.6.26.6/include/asm-x86/pgtable_32.h linux-2.6.26.6/include/asm-x86/pgtable_32.h
30909 +--- linux-2.6.26.6/include/asm-x86/pgtable_32.h 2008-10-08 23:24:05.000000000 -0400
30910 ++++ linux-2.6.26.6/include/asm-x86/pgtable_32.h 2008-10-11 21:54:20.000000000 -0400
30911 +@@ -25,8 +25,6 @@
30912 + struct mm_struct;
30913 + struct vm_area_struct;
30914 +
30915 +-extern pgd_t swapper_pg_dir[1024];
30916 +-
30917 + static inline void pgtable_cache_init(void) { }
30918 + static inline void check_pgt_cache(void) { }
30919 + void paging_init(void);
30920 +@@ -45,6 +43,11 @@ void paging_init(void);
30921 + # include <asm/pgtable-2level-defs.h>
30922 + #endif
30923 +
30924 ++extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
30925 ++#ifdef CONFIG_X86_PAE
30926 ++extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
30927 ++#endif
30928 ++
30929 + #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
30930 + #define PGDIR_MASK (~(PGDIR_SIZE - 1))
30931 +
30932 +@@ -81,7 +84,7 @@ void paging_init(void);
30933 + #undef TEST_ACCESS_OK
30934 +
30935 + /* The boot page tables (all created as a single array) */
30936 +-extern unsigned long pg0[];
30937 ++extern pte_t pg0[];
30938 +
30939 + #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
30940 +
30941 +@@ -208,6 +211,9 @@ static inline void __init paravirt_paget
30942 +
30943 + #endif /* !__ASSEMBLY__ */
30944 +
30945 ++#define HAVE_ARCH_UNMAPPED_AREA
30946 ++#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
30947 ++
30948 + /*
30949 + * kern_addr_valid() is (1) for FLATMEM and (0) for
30950 + * SPARSEMEM and DISCONTIGMEM
30951 +diff -urNp linux-2.6.26.6/include/asm-x86/pgtable-3level.h linux-2.6.26.6/include/asm-x86/pgtable-3level.h
30952 +--- linux-2.6.26.6/include/asm-x86/pgtable-3level.h 2008-10-08 23:24:05.000000000 -0400
30953 ++++ linux-2.6.26.6/include/asm-x86/pgtable-3level.h 2008-10-11 21:54:20.000000000 -0400
30954 +@@ -70,12 +70,36 @@ static inline void native_set_pte_atomic
30955 +
30956 + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
30957 + {
30958 ++
30959 ++#ifdef CONFIG_PAX_KERNEXEC
30960 ++ unsigned long cr0;
30961 ++
30962 ++ pax_open_kernel(cr0);
30963 ++#endif
30964 ++
30965 + set_64bit((unsigned long long *)(pmdp), native_pmd_val(pmd));
30966 ++
30967 ++#ifdef CONFIG_PAX_KERNEXEC
30968 ++ pax_close_kernel(cr0);
30969 ++#endif
30970 ++
30971 + }
30972 +
30973 + static inline void native_set_pud(pud_t *pudp, pud_t pud)
30974 + {
30975 ++
30976 ++#ifdef CONFIG_PAX_KERNEXEC
30977 ++ unsigned long cr0;
30978 ++
30979 ++ pax_open_kernel(cr0);
30980 ++#endif
30981 ++
30982 + set_64bit((unsigned long long *)(pudp), native_pud_val(pud));
30983 ++
30984 ++#ifdef CONFIG_PAX_KERNEXEC
30985 ++ pax_close_kernel(cr0);
30986 ++#endif
30987 ++
30988 + }
30989 +
30990 + /*
30991 +diff -urNp linux-2.6.26.6/include/asm-x86/pgtable_64.h linux-2.6.26.6/include/asm-x86/pgtable_64.h
30992 +--- linux-2.6.26.6/include/asm-x86/pgtable_64.h 2008-10-08 23:24:05.000000000 -0400
30993 ++++ linux-2.6.26.6/include/asm-x86/pgtable_64.h 2008-10-11 21:54:20.000000000 -0400
30994 +@@ -101,7 +101,19 @@ static inline pte_t native_ptep_get_and_
30995 +
30996 + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
30997 + {
30998 ++
30999 ++#ifdef CONFIG_PAX_KERNEXEC
31000 ++ unsigned long cr0;
31001 ++
31002 ++ pax_open_kernel(cr0);
31003 ++#endif
31004 ++
31005 + *pmdp = pmd;
31006 ++
31007 ++#ifdef CONFIG_PAX_KERNEXEC
31008 ++ pax_close_kernel(cr0);
31009 ++#endif
31010 ++
31011 + }
31012 +
31013 + static inline void native_pmd_clear(pmd_t *pmd)
31014 +@@ -153,17 +165,17 @@ static inline void native_pgd_clear(pgd_
31015 +
31016 + static inline int pgd_bad(pgd_t pgd)
31017 + {
31018 +- return (pgd_val(pgd) & ~(PTE_MASK | _PAGE_USER)) != _KERNPG_TABLE;
31019 ++ return (pgd_val(pgd) & ~(PTE_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
31020 + }
31021 +
31022 + static inline int pud_bad(pud_t pud)
31023 + {
31024 +- return (pud_val(pud) & ~(PTE_MASK | _PAGE_USER)) != _KERNPG_TABLE;
31025 ++ return (pud_val(pud) & ~(PTE_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
31026 + }
31027 +
31028 + static inline int pmd_bad(pmd_t pmd)
31029 + {
31030 +- return (pmd_val(pmd) & ~(PTE_MASK | _PAGE_USER)) != _KERNPG_TABLE;
31031 ++ return (pmd_val(pmd) & ~(PTE_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
31032 + }
31033 +
31034 + #define pte_none(x) (!pte_val((x)))
31035 +diff -urNp linux-2.6.26.6/include/asm-x86/pgtable.h linux-2.6.26.6/include/asm-x86/pgtable.h
31036 +--- linux-2.6.26.6/include/asm-x86/pgtable.h 2008-10-08 23:24:05.000000000 -0400
31037 ++++ linux-2.6.26.6/include/asm-x86/pgtable.h 2008-10-11 21:54:20.000000000 -0400
31038 +@@ -83,6 +83,9 @@
31039 + #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \
31040 + _PAGE_ACCESSED)
31041 +
31042 ++#define PAGE_READONLY_NOEXEC PAGE_READONLY
31043 ++#define PAGE_SHARED_NOEXEC PAGE_SHARED
31044 ++
31045 + #ifdef CONFIG_X86_32
31046 + #define _PAGE_KERNEL_EXEC \
31047 + (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
31048 +@@ -104,7 +107,7 @@ extern pteval_t __PAGE_KERNEL, __PAGE_KE
31049 + #define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
31050 + #define __PAGE_KERNEL_UC_MINUS (__PAGE_KERNEL | _PAGE_PCD)
31051 + #define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER)
31052 +-#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
31053 ++#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_RO | _PAGE_PCD | _PAGE_PWT | _PAGE_USER)
31054 + #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE)
31055 + #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE)
31056 +
31057 +@@ -158,10 +161,17 @@ extern unsigned long empty_zero_page[PAG
31058 + extern spinlock_t pgd_lock;
31059 + extern struct list_head pgd_list;
31060 +
31061 ++extern pteval_t __supported_pte_mask;
31062 ++
31063 + /*
31064 + * The following only work if pte_present() is true.
31065 + * Undefined behaviour if not..
31066 + */
31067 ++static inline int pte_user(pte_t pte)
31068 ++{
31069 ++ return pte_val(pte) & _PAGE_USER;
31070 ++}
31071 ++
31072 + static inline int pte_dirty(pte_t pte)
31073 + {
31074 + return pte_val(pte) & _PAGE_DIRTY;
31075 +@@ -223,9 +233,29 @@ static inline pte_t pte_wrprotect(pte_t
31076 + return __pte(pte_val(pte) & ~(pteval_t)_PAGE_RW);
31077 + }
31078 +
31079 ++static inline pte_t pte_mkread(pte_t pte)
31080 ++{
31081 ++ return __pte(pte_val(pte) | _PAGE_USER);
31082 ++}
31083 ++
31084 + static inline pte_t pte_mkexec(pte_t pte)
31085 + {
31086 +- return __pte(pte_val(pte) & ~(pteval_t)_PAGE_NX);
31087 ++#ifdef CONFIG_X86_PAE
31088 ++ if (__supported_pte_mask & _PAGE_NX)
31089 ++ return __pte(pte_val(pte) & ~(pteval_t)_PAGE_NX);
31090 ++ else
31091 ++#endif
31092 ++ return __pte(pte_val(pte) | _PAGE_USER);
31093 ++}
31094 ++
31095 ++static inline pte_t pte_exprotect(pte_t pte)
31096 ++{
31097 ++#ifdef CONFIG_X86_PAE
31098 ++ if (__supported_pte_mask & _PAGE_NX)
31099 ++ return __pte(pte_val(pte) | _PAGE_NX);
31100 ++ else
31101 ++#endif
31102 ++ return __pte(pte_val(pte) & ~_PAGE_USER);
31103 + }
31104 +
31105 + static inline pte_t pte_mkdirty(pte_t pte)
31106 +@@ -268,8 +298,6 @@ static inline pte_t pte_mkspecial(pte_t
31107 + return pte;
31108 + }
31109 +
31110 +-extern pteval_t __supported_pte_mask;
31111 +-
31112 + static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
31113 + {
31114 + return __pte((((phys_addr_t)page_nr << PAGE_SHIFT) |
31115 +@@ -480,7 +508,19 @@ static inline void ptep_set_wrprotect(st
31116 + */
31117 + static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
31118 + {
31119 +- memcpy(dst, src, count * sizeof(pgd_t));
31120 ++
31121 ++#ifdef CONFIG_PAX_KERNEXEC
31122 ++ unsigned long cr0;
31123 ++
31124 ++ pax_open_kernel(cr0);
31125 ++#endif
31126 ++
31127 ++ memcpy(dst, src, count * sizeof(pgd_t));
31128 ++
31129 ++#ifdef CONFIG_PAX_KERNEXEC
31130 ++ pax_close_kernel(cr0);
31131 ++#endif
31132 ++
31133 + }
31134 +
31135 +
31136 +diff -urNp linux-2.6.26.6/include/asm-x86/processor.h linux-2.6.26.6/include/asm-x86/processor.h
31137 +--- linux-2.6.26.6/include/asm-x86/processor.h 2008-10-08 23:24:05.000000000 -0400
31138 ++++ linux-2.6.26.6/include/asm-x86/processor.h 2008-10-11 21:54:20.000000000 -0400
31139 +@@ -273,7 +273,7 @@ struct tss_struct {
31140 +
31141 + } __attribute__((packed));
31142 +
31143 +-DECLARE_PER_CPU(struct tss_struct, init_tss);
31144 ++extern struct tss_struct init_tss[NR_CPUS];
31145 +
31146 + /*
31147 + * Save the original ist values for checking stack pointers during debugging
31148 +@@ -814,11 +814,20 @@ static inline void spin_lock_prefetch(co
31149 + * User space process size: 3GB (default).
31150 + */
31151 + #define TASK_SIZE PAGE_OFFSET
31152 ++
31153 ++#ifdef CONFIG_PAX_SEGMEXEC
31154 ++#define SEGMEXEC_TASK_SIZE (TASK_SIZE / 2)
31155 ++#endif
31156 ++
31157 ++#ifdef CONFIG_PAX_SEGMEXEC
31158 ++#define STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE:TASK_SIZE)
31159 ++#else
31160 + #define STACK_TOP TASK_SIZE
31161 +-#define STACK_TOP_MAX STACK_TOP
31162 ++#endif
31163 ++#define STACK_TOP_MAX TASK_SIZE
31164 +
31165 + #define INIT_THREAD { \
31166 +- .sp0 = sizeof(init_stack) + (long)&init_stack, \
31167 ++ .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
31168 + .vm86_info = NULL, \
31169 + .sysenter_cs = __KERNEL_CS, \
31170 + .io_bitmap_ptr = NULL, \
31171 +@@ -833,7 +842,7 @@ static inline void spin_lock_prefetch(co
31172 + */
31173 + #define INIT_TSS { \
31174 + .x86_tss = { \
31175 +- .sp0 = sizeof(init_stack) + (long)&init_stack, \
31176 ++ .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
31177 + .ss0 = __KERNEL_DS, \
31178 + .ss1 = __KERNEL_CS, \
31179 + .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
31180 +@@ -844,11 +853,7 @@ static inline void spin_lock_prefetch(co
31181 + extern unsigned long thread_saved_pc(struct task_struct *tsk);
31182 +
31183 + #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
31184 +-#define KSTK_TOP(info) \
31185 +-({ \
31186 +- unsigned long *__ptr = (unsigned long *)(info); \
31187 +- (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
31188 +-})
31189 ++#define KSTK_TOP(info) ((info)->task.thread.sp0)
31190 +
31191 + /*
31192 + * The below -8 is to reserve 8 bytes on top of the ring0 stack.
31193 +@@ -863,7 +868,7 @@ extern unsigned long thread_saved_pc(str
31194 + #define task_pt_regs(task) \
31195 + ({ \
31196 + struct pt_regs *__regs__; \
31197 +- __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
31198 ++ __regs__ = (struct pt_regs *)((task)->thread.sp0); \
31199 + __regs__ - 1; \
31200 + })
31201 +
31202 +@@ -879,7 +884,7 @@ extern unsigned long thread_saved_pc(str
31203 + * space during mmap's.
31204 + */
31205 + #define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? \
31206 +- 0xc0000000 : 0xFFFFe000)
31207 ++ 0xc0000000 : 0xFFFFf000)
31208 +
31209 + #define TASK_SIZE (test_thread_flag(TIF_IA32) ? \
31210 + IA32_PAGE_OFFSET : TASK_SIZE64)
31211 +@@ -916,6 +921,10 @@ extern void start_thread(struct pt_regs
31212 + */
31213 + #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
31214 +
31215 ++#ifdef CONFIG_PAX_SEGMEXEC
31216 ++#define SEGMEXEC_TASK_UNMAPPED_BASE (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3))
31217 ++#endif
31218 ++
31219 + #define KSTK_EIP(task) (task_pt_regs(task)->ip)
31220 +
31221 + /* Get/set a process' ability to use the timestamp counter instruction */
31222 +diff -urNp linux-2.6.26.6/include/asm-x86/ptrace.h linux-2.6.26.6/include/asm-x86/ptrace.h
31223 +--- linux-2.6.26.6/include/asm-x86/ptrace.h 2008-10-08 23:24:05.000000000 -0400
31224 ++++ linux-2.6.26.6/include/asm-x86/ptrace.h 2008-10-11 21:54:20.000000000 -0400
31225 +@@ -56,7 +56,6 @@ struct pt_regs {
31226 + };
31227 +
31228 + #include <asm/vm86.h>
31229 +-#include <asm/segment.h>
31230 +
31231 + #endif /* __KERNEL__ */
31232 +
31233 +@@ -129,6 +128,7 @@ struct pt_regs {
31234 +
31235 + /* the DS BTS struct is used for ptrace as well */
31236 + #include <asm/ds.h>
31237 ++#include <asm/segment.h>
31238 +
31239 + struct task_struct;
31240 +
31241 +@@ -152,28 +152,29 @@ static inline unsigned long regs_return_
31242 + }
31243 +
31244 + /*
31245 +- * user_mode_vm(regs) determines whether a register set came from user mode.
31246 ++ * user_mode(regs) determines whether a register set came from user mode.
31247 + * This is true if V8086 mode was enabled OR if the register set was from
31248 + * protected mode with RPL-3 CS value. This tricky test checks that with
31249 + * one comparison. Many places in the kernel can bypass this full check
31250 +- * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
31251 ++ * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
31252 ++ * be used.
31253 + */
31254 +-static inline int user_mode(struct pt_regs *regs)
31255 ++static inline int user_mode_novm(struct pt_regs *regs)
31256 + {
31257 + #ifdef CONFIG_X86_32
31258 + return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL;
31259 + #else
31260 +- return !!(regs->cs & 3);
31261 ++ return !!(regs->cs & SEGMENT_RPL_MASK);
31262 + #endif
31263 + }
31264 +
31265 +-static inline int user_mode_vm(struct pt_regs *regs)
31266 ++static inline int user_mode(struct pt_regs *regs)
31267 + {
31268 + #ifdef CONFIG_X86_32
31269 + return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >=
31270 + USER_RPL;
31271 + #else
31272 +- return user_mode(regs);
31273 ++ return user_mode_novm(regs);
31274 + #endif
31275 + }
31276 +
31277 +diff -urNp linux-2.6.26.6/include/asm-x86/reboot.h linux-2.6.26.6/include/asm-x86/reboot.h
31278 +--- linux-2.6.26.6/include/asm-x86/reboot.h 2008-10-08 23:24:05.000000000 -0400
31279 ++++ linux-2.6.26.6/include/asm-x86/reboot.h 2008-10-11 21:54:20.000000000 -0400
31280 +@@ -14,7 +14,7 @@ struct machine_ops {
31281 +
31282 + extern struct machine_ops machine_ops;
31283 +
31284 +-void machine_real_restart(unsigned char *code, int length);
31285 ++void machine_real_restart(const unsigned char *code, unsigned int length);
31286 + void native_machine_crash_shutdown(struct pt_regs *regs);
31287 + void native_machine_shutdown(void);
31288 +
31289 +diff -urNp linux-2.6.26.6/include/asm-x86/rwsem.h linux-2.6.26.6/include/asm-x86/rwsem.h
31290 +--- linux-2.6.26.6/include/asm-x86/rwsem.h 2008-10-08 23:24:05.000000000 -0400
31291 ++++ linux-2.6.26.6/include/asm-x86/rwsem.h 2008-10-11 21:54:20.000000000 -0400
31292 +@@ -106,10 +106,26 @@ static inline void __down_read(struct rw
31293 + {
31294 + asm volatile("# beginning down_read\n\t"
31295 + LOCK_PREFIX " incl (%%eax)\n\t"
31296 ++
31297 ++#ifdef CONFIG_PAX_REFCOUNT
31298 ++#ifdef CONFIG_X86_32
31299 ++ "into\n0:\n"
31300 ++#else
31301 ++ "jno 0f\n"
31302 ++ "int $4\n0:\n"
31303 ++#endif
31304 ++ ".pushsection .fixup,\"ax\"\n"
31305 ++ "1:\n"
31306 ++ LOCK_PREFIX "decl (%%eax)\n"
31307 ++ "jmp 0b\n"
31308 ++ ".popsection\n"
31309 ++ _ASM_EXTABLE(0b, 1b)
31310 ++#endif
31311 ++
31312 + /* adds 0x00000001, returns the old value */
31313 +- " jns 1f\n"
31314 ++ " jns 2f\n"
31315 + " call call_rwsem_down_read_failed\n"
31316 +- "1:\n\t"
31317 ++ "2:\n\t"
31318 + "# ending down_read\n\t"
31319 + : "+m" (sem->count)
31320 + : "a" (sem)
31321 +@@ -124,13 +140,29 @@ static inline int __down_read_trylock(st
31322 + __s32 result, tmp;
31323 + asm volatile("# beginning __down_read_trylock\n\t"
31324 + " movl %0,%1\n\t"
31325 +- "1:\n\t"
31326 ++ "2:\n\t"
31327 + " movl %1,%2\n\t"
31328 + " addl %3,%2\n\t"
31329 +- " jle 2f\n\t"
31330 ++
31331 ++#ifdef CONFIG_PAX_REFCOUNT
31332 ++#ifdef CONFIG_X86_32
31333 ++ "into\n0:\n"
31334 ++#else
31335 ++ "jno 0f\n"
31336 ++ "int $4\n0:\n"
31337 ++#endif
31338 ++ ".pushsection .fixup,\"ax\"\n"
31339 ++ "1:\n"
31340 ++ "subl %3,%2\n"
31341 ++ "jmp 0b\n"
31342 ++ ".popsection\n"
31343 ++ _ASM_EXTABLE(0b, 1b)
31344 ++#endif
31345 ++
31346 ++ " jle 3f\n\t"
31347 + LOCK_PREFIX " cmpxchgl %2,%0\n\t"
31348 +- " jnz 1b\n\t"
31349 +- "2:\n\t"
31350 ++ " jnz 2b\n\t"
31351 ++ "3:\n\t"
31352 + "# ending __down_read_trylock\n\t"
31353 + : "+m" (sem->count), "=&a" (result), "=&r" (tmp)
31354 + : "i" (RWSEM_ACTIVE_READ_BIAS)
31355 +@@ -148,12 +180,28 @@ static inline void __down_write_nested(s
31356 + tmp = RWSEM_ACTIVE_WRITE_BIAS;
31357 + asm volatile("# beginning down_write\n\t"
31358 + LOCK_PREFIX " xadd %%edx,(%%eax)\n\t"
31359 ++
31360 ++#ifdef CONFIG_PAX_REFCOUNT
31361 ++#ifdef CONFIG_X86_32
31362 ++ "into\n0:\n"
31363 ++#else
31364 ++ "jno 0f\n"
31365 ++ "int $4\n0:\n"
31366 ++#endif
31367 ++ ".pushsection .fixup,\"ax\"\n"
31368 ++ "1:\n"
31369 ++ "movl %%edx,(%%eax)\n"
31370 ++ "jmp 0b\n"
31371 ++ ".popsection\n"
31372 ++ _ASM_EXTABLE(0b, 1b)
31373 ++#endif
31374 ++
31375 + /* subtract 0x0000ffff, returns the old value */
31376 + " testl %%edx,%%edx\n\t"
31377 + /* was the count 0 before? */
31378 +- " jz 1f\n"
31379 ++ " jz 2f\n"
31380 + " call call_rwsem_down_write_failed\n"
31381 +- "1:\n"
31382 ++ "2:\n"
31383 + "# ending down_write"
31384 + : "+m" (sem->count), "=d" (tmp)
31385 + : "a" (sem), "1" (tmp)
31386 +@@ -186,10 +234,26 @@ static inline void __up_read(struct rw_s
31387 + __s32 tmp = -RWSEM_ACTIVE_READ_BIAS;
31388 + asm volatile("# beginning __up_read\n\t"
31389 + LOCK_PREFIX " xadd %%edx,(%%eax)\n\t"
31390 ++
31391 ++#ifdef CONFIG_PAX_REFCOUNT
31392 ++#ifdef CONFIG_X86_32
31393 ++ "into\n0:\n"
31394 ++#else
31395 ++ "jno 0f\n"
31396 ++ "int $4\n0:\n"
31397 ++#endif
31398 ++ ".pushsection .fixup,\"ax\"\n"
31399 ++ "1:\n"
31400 ++ "movl %%edx,(%%eax)\n"
31401 ++ "jmp 0b\n"
31402 ++ ".popsection\n"
31403 ++ _ASM_EXTABLE(0b, 1b)
31404 ++#endif
31405 ++
31406 + /* subtracts 1, returns the old value */
31407 +- " jns 1f\n\t"
31408 ++ " jns 2f\n\t"
31409 + " call call_rwsem_wake\n"
31410 +- "1:\n"
31411 ++ "2:\n"
31412 + "# ending __up_read\n"
31413 + : "+m" (sem->count), "=d" (tmp)
31414 + : "a" (sem), "1" (tmp)
31415 +@@ -204,11 +268,27 @@ static inline void __up_write(struct rw_
31416 + asm volatile("# beginning __up_write\n\t"
31417 + " movl %2,%%edx\n\t"
31418 + LOCK_PREFIX " xaddl %%edx,(%%eax)\n\t"
31419 ++
31420 ++#ifdef CONFIG_PAX_REFCOUNT
31421 ++#ifdef CONFIG_X86_32
31422 ++ "into\n0:\n"
31423 ++#else
31424 ++ "jno 0f\n"
31425 ++ "int $4\n0:\n"
31426 ++#endif
31427 ++ ".pushsection .fixup,\"ax\"\n"
31428 ++ "1:\n"
31429 ++ "movl %%edx,(%%eax)\n"
31430 ++ "jmp 0b\n"
31431 ++ ".popsection\n"
31432 ++ _ASM_EXTABLE(0b, 1b)
31433 ++#endif
31434 ++
31435 + /* tries to transition
31436 + 0xffff0001 -> 0x00000000 */
31437 +- " jz 1f\n"
31438 ++ " jz 2f\n"
31439 + " call call_rwsem_wake\n"
31440 +- "1:\n\t"
31441 ++ "2:\n\t"
31442 + "# ending __up_write\n"
31443 + : "+m" (sem->count)
31444 + : "a" (sem), "i" (-RWSEM_ACTIVE_WRITE_BIAS)
31445 +@@ -222,10 +302,26 @@ static inline void __downgrade_write(str
31446 + {
31447 + asm volatile("# beginning __downgrade_write\n\t"
31448 + LOCK_PREFIX " addl %2,(%%eax)\n\t"
31449 ++
31450 ++#ifdef CONFIG_PAX_REFCOUNT
31451 ++#ifdef CONFIG_X86_32
31452 ++ "into\n0:\n"
31453 ++#else
31454 ++ "jno 0f\n"
31455 ++ "int $4\n0:\n"
31456 ++#endif
31457 ++ ".pushsection .fixup,\"ax\"\n"
31458 ++ "1:\n"
31459 ++ LOCK_PREFIX "subl %2,(%%eax)\n"
31460 ++ "jmp 0b\n"
31461 ++ ".popsection\n"
31462 ++ _ASM_EXTABLE(0b, 1b)
31463 ++#endif
31464 ++
31465 + /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
31466 +- " jns 1f\n\t"
31467 ++ " jns 2f\n\t"
31468 + " call call_rwsem_downgrade_wake\n"
31469 +- "1:\n\t"
31470 ++ "2:\n\t"
31471 + "# ending __downgrade_write\n"
31472 + : "+m" (sem->count)
31473 + : "a" (sem), "i" (-RWSEM_WAITING_BIAS)
31474 +@@ -237,7 +333,23 @@ static inline void __downgrade_write(str
31475 + */
31476 + static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
31477 + {
31478 +- asm volatile(LOCK_PREFIX "addl %1,%0"
31479 ++ asm volatile(LOCK_PREFIX "addl %1,%0\n"
31480 ++
31481 ++#ifdef CONFIG_PAX_REFCOUNT
31482 ++#ifdef CONFIG_X86_32
31483 ++ "into\n0:\n"
31484 ++#else
31485 ++ "jno 0f\n"
31486 ++ "int $4\n0:\n"
31487 ++#endif
31488 ++ ".pushsection .fixup,\"ax\"\n"
31489 ++ "1:\n"
31490 ++ LOCK_PREFIX "subl %1,%0\n"
31491 ++ "jmp 0b\n"
31492 ++ ".popsection\n"
31493 ++ _ASM_EXTABLE(0b, 1b)
31494 ++#endif
31495 ++
31496 + : "+m" (sem->count)
31497 + : "ir" (delta));
31498 + }
31499 +@@ -249,7 +361,23 @@ static inline int rwsem_atomic_update(in
31500 + {
31501 + int tmp = delta;
31502 +
31503 +- asm volatile(LOCK_PREFIX "xadd %0,%1"
31504 ++ asm volatile(LOCK_PREFIX "xadd %0,%1\n"
31505 ++
31506 ++#ifdef CONFIG_PAX_REFCOUNT
31507 ++#ifdef CONFIG_X86_32
31508 ++ "into\n0:\n"
31509 ++#else
31510 ++ "jno 0f\n"
31511 ++ "int $4\n0:\n"
31512 ++#endif
31513 ++ ".pushsection .fixup,\"ax\"\n"
31514 ++ "1:\n"
31515 ++ "movl %0,%1\n"
31516 ++ "jmp 0b\n"
31517 ++ ".popsection\n"
31518 ++ _ASM_EXTABLE(0b, 1b)
31519 ++#endif
31520 ++
31521 + : "+r" (tmp), "+m" (sem->count)
31522 + : : "memory");
31523 +
31524 +diff -urNp linux-2.6.26.6/include/asm-x86/segment.h linux-2.6.26.6/include/asm-x86/segment.h
31525 +--- linux-2.6.26.6/include/asm-x86/segment.h 2008-10-08 23:24:05.000000000 -0400
31526 ++++ linux-2.6.26.6/include/asm-x86/segment.h 2008-10-11 21:54:20.000000000 -0400
31527 +@@ -83,13 +83,19 @@
31528 + #define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14)
31529 + #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
31530 +
31531 +-#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
31532 ++#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
31533 + #ifdef CONFIG_SMP
31534 + #define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
31535 + #else
31536 + #define __KERNEL_PERCPU 0
31537 + #endif
31538 +
31539 ++#define GDT_ENTRY_PCIBIOS_CS (GDT_ENTRY_KERNEL_BASE + 16)
31540 ++#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8)
31541 ++
31542 ++#define GDT_ENTRY_PCIBIOS_DS (GDT_ENTRY_KERNEL_BASE + 17)
31543 ++#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8)
31544 ++
31545 + #define GDT_ENTRY_DOUBLEFAULT_TSS 31
31546 +
31547 + /*
31548 +@@ -130,10 +136,10 @@
31549 + #define SEGMENT_IS_KERNEL_CODE(x) (((x) & 0xfc) == GDT_ENTRY_KERNEL_CS * 8)
31550 +
31551 + /* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */
31552 +-#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8)
31553 ++#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xFFFCU) == __KERNEL_CS || ((x) & 0xFFFCU) == __USER_CS)
31554 +
31555 + /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
31556 +-#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
31557 ++#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
31558 +
31559 +
31560 + #else
31561 +diff -urNp linux-2.6.26.6/include/asm-x86/spinlock.h linux-2.6.26.6/include/asm-x86/spinlock.h
31562 +--- linux-2.6.26.6/include/asm-x86/spinlock.h 2008-10-08 23:24:05.000000000 -0400
31563 ++++ linux-2.6.26.6/include/asm-x86/spinlock.h 2008-10-11 21:54:20.000000000 -0400
31564 +@@ -227,18 +227,50 @@ static inline int __raw_write_can_lock(r
31565 + static inline void __raw_read_lock(raw_rwlock_t *rw)
31566 + {
31567 + asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t"
31568 +- "jns 1f\n"
31569 +- "call __read_lock_failed\n\t"
31570 ++
31571 ++#ifdef CONFIG_PAX_REFCOUNT
31572 ++#ifdef CONFIG_X86_32
31573 ++ "into\n0:\n"
31574 ++#else
31575 ++ "jno 0f\n"
31576 ++ "int $4\n0:\n"
31577 ++#endif
31578 ++ ".pushsection .fixup,\"ax\"\n"
31579 + "1:\n"
31580 ++ LOCK_PREFIX " addl $1,(%0)\n"
31581 ++ "jmp 0b\n"
31582 ++ ".popsection\n"
31583 ++ _ASM_EXTABLE(0b, 1b)
31584 ++#endif
31585 ++
31586 ++ "jns 2f\n"
31587 ++ "call __read_lock_failed\n\t"
31588 ++ "2:\n"
31589 + ::LOCK_PTR_REG (rw) : "memory");
31590 + }
31591 +
31592 + static inline void __raw_write_lock(raw_rwlock_t *rw)
31593 + {
31594 + asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t"
31595 +- "jz 1f\n"
31596 +- "call __write_lock_failed\n\t"
31597 ++
31598 ++#ifdef CONFIG_PAX_REFCOUNT
31599 ++#ifdef CONFIG_X86_32
31600 ++ "into\n0:\n"
31601 ++#else
31602 ++ "jno 0f\n"
31603 ++ "int $4\n0:\n"
31604 ++#endif
31605 ++ ".pushsection .fixup,\"ax\"\n"
31606 + "1:\n"
31607 ++ LOCK_PREFIX " addl %1,(%0)\n"
31608 ++ "jmp 0b\n"
31609 ++ ".popsection\n"
31610 ++ _ASM_EXTABLE(0b, 1b)
31611 ++#endif
31612 ++
31613 ++ "jz 2f\n"
31614 ++ "call __write_lock_failed\n\t"
31615 ++ "2:\n"
31616 + ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory");
31617 + }
31618 +
31619 +@@ -265,12 +297,45 @@ static inline int __raw_write_trylock(ra
31620 +
31621 + static inline void __raw_read_unlock(raw_rwlock_t *rw)
31622 + {
31623 +- asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory");
31624 ++ asm volatile(LOCK_PREFIX "incl %0\n"
31625 ++
31626 ++#ifdef CONFIG_PAX_REFCOUNT
31627 ++#ifdef CONFIG_X86_32
31628 ++ "into\n0:\n"
31629 ++#else
31630 ++ "jno 0f\n"
31631 ++ "int $4\n0:\n"
31632 ++#endif
31633 ++ ".pushsection .fixup,\"ax\"\n"
31634 ++ "1:\n"
31635 ++ LOCK_PREFIX "decl %0\n"
31636 ++ "jmp 0b\n"
31637 ++ ".popsection\n"
31638 ++ _ASM_EXTABLE(0b, 1b)
31639 ++#endif
31640 ++
31641 ++ :"+m" (rw->lock) : : "memory");
31642 + }
31643 +
31644 + static inline void __raw_write_unlock(raw_rwlock_t *rw)
31645 + {
31646 +- asm volatile(LOCK_PREFIX "addl %1, %0"
31647 ++ asm volatile(LOCK_PREFIX "addl %1, %0\n"
31648 ++
31649 ++#ifdef CONFIG_PAX_REFCOUNT
31650 ++#ifdef CONFIG_X86_32
31651 ++ "into\n0:\n"
31652 ++#else
31653 ++ "jno 0f\n"
31654 ++ "int $4\n0:\n"
31655 ++#endif
31656 ++ ".pushsection .fixup,\"ax\"\n"
31657 ++ "1:\n"
31658 ++ LOCK_PREFIX "subl %1,%0\n"
31659 ++ "jmp 0b\n"
31660 ++ ".popsection\n"
31661 ++ _ASM_EXTABLE(0b, 1b)
31662 ++#endif
31663 ++
31664 + : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory");
31665 + }
31666 +
31667 +diff -urNp linux-2.6.26.6/include/asm-x86/system.h linux-2.6.26.6/include/asm-x86/system.h
31668 +--- linux-2.6.26.6/include/asm-x86/system.h 2008-10-08 23:24:05.000000000 -0400
31669 ++++ linux-2.6.26.6/include/asm-x86/system.h 2008-10-11 21:54:20.000000000 -0400
31670 +@@ -92,6 +92,8 @@ do { \
31671 + ".globl thread_return\n" \
31672 + "thread_return:\n\t" \
31673 + "movq %%gs:%P[pda_pcurrent],%%rsi\n\t" \
31674 ++ "movq %P[task_canary](%%rsi),%%r8\n\t" \
31675 ++ "movq %%r8,%%gs:%P[pda_canary]\n\t" \
31676 + "movq %P[thread_info](%%rsi),%%r8\n\t" \
31677 + LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \
31678 + "movq %%rax,%%rdi\n\t" \
31679 +@@ -103,7 +105,9 @@ do { \
31680 + [ti_flags] "i" (offsetof(struct thread_info, flags)), \
31681 + [tif_fork] "i" (TIF_FORK), \
31682 + [thread_info] "i" (offsetof(struct task_struct, stack)), \
31683 +- [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \
31684 ++ [task_canary] "i" (offsetof(struct task_struct, stack_canary)), \
31685 ++ [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)), \
31686 ++ [pda_canary] "i" (offsetof(struct x8664_pda, stack_canary))\
31687 + : "memory", "cc" __EXTRA_CLOBBER)
31688 + #endif
31689 +
31690 +@@ -166,7 +170,7 @@ static inline unsigned long get_limit(un
31691 + {
31692 + unsigned long __limit;
31693 + asm("lsll %1,%0" : "=r" (__limit) : "r" (segment));
31694 +- return __limit + 1;
31695 ++ return __limit;
31696 + }
31697 +
31698 + static inline void native_clts(void)
31699 +@@ -291,6 +295,21 @@ static inline void native_wbinvd(void)
31700 +
31701 + #define stts() write_cr0(8 | read_cr0())
31702 +
31703 ++#define pax_open_kernel(cr0) \
31704 ++do { \
31705 ++ typecheck(unsigned long, cr0); \
31706 ++ preempt_disable(); \
31707 ++ cr0 = read_cr0(); \
31708 ++ write_cr0(cr0 & ~X86_CR0_WP); \
31709 ++} while (0)
31710 ++
31711 ++#define pax_close_kernel(cr0) \
31712 ++do { \
31713 ++ typecheck(unsigned long, cr0); \
31714 ++ write_cr0(cr0); \
31715 ++ preempt_enable_no_resched(); \
31716 ++} while (0)
31717 ++
31718 + #endif /* __KERNEL__ */
31719 +
31720 + static inline void clflush(volatile void *__p)
31721 +@@ -306,7 +325,7 @@ void enable_hlt(void);
31722 + extern int es7000_plat;
31723 + void cpu_idle_wait(void);
31724 +
31725 +-extern unsigned long arch_align_stack(unsigned long sp);
31726 ++#define arch_align_stack(x) (x)
31727 + extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
31728 +
31729 + void default_idle(void);
31730 +diff -urNp linux-2.6.26.6/include/asm-x86/uaccess_32.h linux-2.6.26.6/include/asm-x86/uaccess_32.h
31731 +--- linux-2.6.26.6/include/asm-x86/uaccess_32.h 2008-10-08 23:24:05.000000000 -0400
31732 ++++ linux-2.6.26.6/include/asm-x86/uaccess_32.h 2008-10-11 21:54:20.000000000 -0400
31733 +@@ -10,6 +10,7 @@
31734 + #include <linux/string.h>
31735 + #include <asm/asm.h>
31736 + #include <asm/page.h>
31737 ++#include <asm/segment.h>
31738 +
31739 + #define VERIFY_READ 0
31740 + #define VERIFY_WRITE 1
31741 +@@ -30,7 +31,8 @@
31742 +
31743 + #define get_ds() (KERNEL_DS)
31744 + #define get_fs() (current_thread_info()->addr_limit)
31745 +-#define set_fs(x) (current_thread_info()->addr_limit = (x))
31746 ++void __set_fs(mm_segment_t x, int cpu);
31747 ++void set_fs(mm_segment_t x);
31748 +
31749 + #define segment_eq(a, b) ((a).seg == (b).seg)
31750 +
31751 +@@ -106,6 +108,7 @@ struct exception_table_entry {
31752 + };
31753 +
31754 + extern int fixup_exception(struct pt_regs *regs);
31755 ++#define ARCH_HAS_SORT_EXTABLE
31756 +
31757 + /*
31758 + * These are the main single-value transfer routines. They automatically
31759 +@@ -320,9 +323,12 @@ extern void __put_user_8(void);
31760 +
31761 +
31762 + #define __put_user_u64(x, addr, err) \
31763 +- asm volatile("1: movl %%eax,0(%2)\n" \
31764 +- "2: movl %%edx,4(%2)\n" \
31765 ++ asm volatile(" movw %w5,%%ds\n" \
31766 ++ "1: movl %%eax,%%ds:0(%2)\n" \
31767 ++ "2: movl %%edx,%%ds:4(%2)\n" \
31768 + "3:\n" \
31769 ++ " pushl %%ss\n" \
31770 ++ " popl %%ds\n" \
31771 + ".section .fixup,\"ax\"\n" \
31772 + "4: movl %3,%0\n" \
31773 + " jmp 3b\n" \
31774 +@@ -330,7 +336,8 @@ extern void __put_user_8(void);
31775 + _ASM_EXTABLE(1b, 4b) \
31776 + _ASM_EXTABLE(2b, 4b) \
31777 + : "=r" (err) \
31778 +- : "A" (x), "r" (addr), "i" (-EFAULT), "0" (err))
31779 ++ : "A" (x), "r" (addr), "i" (-EFAULT), "0" (err), \
31780 ++ "r"(__USER_DS))
31781 +
31782 + #ifdef CONFIG_X86_WP_WORKS_OK
31783 +
31784 +@@ -377,15 +384,19 @@ struct __large_struct { unsigned long bu
31785 + * aliasing issues.
31786 + */
31787 + #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
31788 +- asm volatile("1: mov"itype" %"rtype"1,%2\n" \
31789 ++ asm volatile(" movw %w5,%%ds\n" \
31790 ++ "1: mov"itype" %"rtype"1,%%ds:%2\n" \
31791 + "2:\n" \
31792 ++ " pushl %%ss\n" \
31793 ++ " popl %%ds\n" \
31794 + ".section .fixup,\"ax\"\n" \
31795 + "3: movl %3,%0\n" \
31796 + " jmp 2b\n" \
31797 + ".previous\n" \
31798 + _ASM_EXTABLE(1b, 3b) \
31799 + : "=r"(err) \
31800 +- : ltype (x), "m" (__m(addr)), "i" (errret), "0" (err))
31801 ++ : ltype (x), "m" (__m(addr)), "i" (errret), "0" (err),\
31802 ++ "r"(__USER_DS))
31803 +
31804 +
31805 + #define __get_user_nocheck(x, ptr, size) \
31806 +@@ -419,8 +430,11 @@ do { \
31807 + } while (0)
31808 +
31809 + #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
31810 +- asm volatile("1: mov"itype" %2,%"rtype"1\n" \
31811 ++ asm volatile(" movw %w5,%%ds\n" \
31812 ++ "1: mov"itype" %%ds:%2,%"rtype"1\n" \
31813 + "2:\n" \
31814 ++ " pushl %%ss\n" \
31815 ++ " popl %%ds\n" \
31816 + ".section .fixup,\"ax\"\n" \
31817 + "3: movl %3,%0\n" \
31818 + " xor"itype" %"rtype"1,%"rtype"1\n" \
31819 +@@ -428,7 +442,7 @@ do { \
31820 + ".previous\n" \
31821 + _ASM_EXTABLE(1b, 3b) \
31822 + : "=r" (err), ltype (x) \
31823 +- : "m" (__m(addr)), "i" (errret), "0" (err))
31824 ++ : "m" (__m(addr)), "i" (errret), "0" (err), "r"(__USER_DS))
31825 +
31826 +
31827 + unsigned long __must_check __copy_to_user_ll
31828 +diff -urNp linux-2.6.26.6/include/asm-x86/uaccess_64.h linux-2.6.26.6/include/asm-x86/uaccess_64.h
31829 +--- linux-2.6.26.6/include/asm-x86/uaccess_64.h 2008-10-08 23:24:05.000000000 -0400
31830 ++++ linux-2.6.26.6/include/asm-x86/uaccess_64.h 2008-10-11 21:54:20.000000000 -0400
31831 +@@ -71,6 +71,7 @@ struct exception_table_entry {
31832 + extern int fixup_exception(struct pt_regs *regs);
31833 +
31834 + #define ARCH_HAS_SEARCH_EXTABLE
31835 ++#define ARCH_HAS_SORT_EXTABLE
31836 +
31837 + /*
31838 + * These are the main single-value transfer routines. They automatically
31839 +diff -urNp linux-2.6.26.6/include/asm-xtensa/kmap_types.h linux-2.6.26.6/include/asm-xtensa/kmap_types.h
31840 +--- linux-2.6.26.6/include/asm-xtensa/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
31841 ++++ linux-2.6.26.6/include/asm-xtensa/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
31842 +@@ -25,6 +25,7 @@ enum km_type {
31843 + KM_IRQ1,
31844 + KM_SOFTIRQ0,
31845 + KM_SOFTIRQ1,
31846 ++ KM_CLEARPAGE,
31847 + KM_TYPE_NR
31848 + };
31849 +
31850 +diff -urNp linux-2.6.26.6/include/linux/a.out.h linux-2.6.26.6/include/linux/a.out.h
31851 +--- linux-2.6.26.6/include/linux/a.out.h 2008-10-08 23:24:05.000000000 -0400
31852 ++++ linux-2.6.26.6/include/linux/a.out.h 2008-10-11 21:54:20.000000000 -0400
31853 +@@ -39,6 +39,14 @@ enum machine_type {
31854 + M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
31855 + };
31856 +
31857 ++/* Constants for the N_FLAGS field */
31858 ++#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
31859 ++#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
31860 ++#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
31861 ++#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
31862 ++/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
31863 ++#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
31864 ++
31865 + #if !defined (N_MAGIC)
31866 + #define N_MAGIC(exec) ((exec).a_info & 0xffff)
31867 + #endif
31868 +diff -urNp linux-2.6.26.6/include/linux/cache.h linux-2.6.26.6/include/linux/cache.h
31869 +--- linux-2.6.26.6/include/linux/cache.h 2008-10-08 23:24:05.000000000 -0400
31870 ++++ linux-2.6.26.6/include/linux/cache.h 2008-10-11 21:54:20.000000000 -0400
31871 +@@ -16,6 +16,10 @@
31872 + #define __read_mostly
31873 + #endif
31874 +
31875 ++#ifndef __read_only
31876 ++#define __read_only __read_mostly
31877 ++#endif
31878 ++
31879 + #ifndef ____cacheline_aligned
31880 + #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
31881 + #endif
31882 +diff -urNp linux-2.6.26.6/include/linux/capability.h linux-2.6.26.6/include/linux/capability.h
31883 +--- linux-2.6.26.6/include/linux/capability.h 2008-10-08 23:24:05.000000000 -0400
31884 ++++ linux-2.6.26.6/include/linux/capability.h 2008-10-11 21:54:20.000000000 -0400
31885 +@@ -504,6 +504,7 @@ extern const kernel_cap_t __cap_init_eff
31886 + kernel_cap_t cap_set_effective(const kernel_cap_t pE_new);
31887 +
31888 + int capable(int cap);
31889 ++int capable_nolog(int cap);
31890 + int __capable(struct task_struct *t, int cap);
31891 +
31892 + #endif /* __KERNEL__ */
31893 +diff -urNp linux-2.6.26.6/include/linux/cpumask.h linux-2.6.26.6/include/linux/cpumask.h
31894 +--- linux-2.6.26.6/include/linux/cpumask.h 2008-10-08 23:24:05.000000000 -0400
31895 ++++ linux-2.6.26.6/include/linux/cpumask.h 2008-10-11 21:55:52.000000000 -0400
31896 +@@ -233,14 +233,14 @@ extern cpumask_t *cpumask_of_cpu_map;
31897 + #else
31898 + #define cpumask_of_cpu(cpu) \
31899 + (*({ \
31900 +- typeof(_unused_cpumask_arg_) m; \
31901 +- if (sizeof(m) == sizeof(unsigned long)) { \
31902 +- m.bits[0] = 1UL<<(cpu); \
31903 ++ typeof(_unused_cpumask_arg_) __m; \
31904 ++ if (sizeof(__m) == sizeof(unsigned long)) { \
31905 ++ __m.bits[0] = 1UL<<(cpu); \
31906 + } else { \
31907 +- cpus_clear(m); \
31908 +- cpu_set((cpu), m); \
31909 ++ cpus_clear(__m); \
31910 ++ cpu_set((cpu), __m); \
31911 + } \
31912 +- &m; \
31913 ++ &__m; \
31914 + }))
31915 + #endif
31916 +
31917 +diff -urNp linux-2.6.26.6/include/linux/elf.h linux-2.6.26.6/include/linux/elf.h
31918 +--- linux-2.6.26.6/include/linux/elf.h 2008-10-08 23:24:05.000000000 -0400
31919 ++++ linux-2.6.26.6/include/linux/elf.h 2008-10-11 21:54:20.000000000 -0400
31920 +@@ -50,6 +50,16 @@ typedef __s64 Elf64_Sxword;
31921 +
31922 + #define PT_GNU_STACK (PT_LOOS + 0x474e551)
31923 +
31924 ++#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
31925 ++
31926 ++/* Constants for the e_flags field */
31927 ++#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
31928 ++#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
31929 ++#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
31930 ++#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
31931 ++/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
31932 ++#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
31933 ++
31934 + /* These constants define the different elf file types */
31935 + #define ET_NONE 0
31936 + #define ET_REL 1
31937 +@@ -84,6 +94,8 @@ typedef __s64 Elf64_Sxword;
31938 + #define DT_DEBUG 21
31939 + #define DT_TEXTREL 22
31940 + #define DT_JMPREL 23
31941 ++#define DT_FLAGS 30
31942 ++ #define DF_TEXTREL 0x00000004
31943 + #define DT_ENCODING 32
31944 + #define OLD_DT_LOOS 0x60000000
31945 + #define DT_LOOS 0x6000000d
31946 +@@ -230,6 +242,19 @@ typedef struct elf64_hdr {
31947 + #define PF_W 0x2
31948 + #define PF_X 0x1
31949 +
31950 ++#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */
31951 ++#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */
31952 ++#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */
31953 ++#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */
31954 ++#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */
31955 ++#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */
31956 ++/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */
31957 ++/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */
31958 ++#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */
31959 ++#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */
31960 ++#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */
31961 ++#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */
31962 ++
31963 + typedef struct elf32_phdr{
31964 + Elf32_Word p_type;
31965 + Elf32_Off p_offset;
31966 +@@ -322,6 +347,8 @@ typedef struct elf64_shdr {
31967 + #define EI_OSABI 7
31968 + #define EI_PAD 8
31969 +
31970 ++#define EI_PAX 14
31971 ++
31972 + #define ELFMAG0 0x7f /* EI_MAG */
31973 + #define ELFMAG1 'E'
31974 + #define ELFMAG2 'L'
31975 +@@ -382,6 +409,7 @@ extern Elf32_Dyn _DYNAMIC [];
31976 + #define elf_phdr elf32_phdr
31977 + #define elf_note elf32_note
31978 + #define elf_addr_t Elf32_Off
31979 ++#define elf_dyn Elf32_Dyn
31980 +
31981 + #else
31982 +
31983 +@@ -390,6 +418,7 @@ extern Elf64_Dyn _DYNAMIC [];
31984 + #define elf_phdr elf64_phdr
31985 + #define elf_note elf64_note
31986 + #define elf_addr_t Elf64_Off
31987 ++#define elf_dyn Elf64_Dyn
31988 +
31989 + #endif
31990 +
31991 +diff -urNp linux-2.6.26.6/include/linux/gracl.h linux-2.6.26.6/include/linux/gracl.h
31992 +--- linux-2.6.26.6/include/linux/gracl.h 1969-12-31 19:00:00.000000000 -0500
31993 ++++ linux-2.6.26.6/include/linux/gracl.h 2008-10-11 21:54:20.000000000 -0400
31994 +@@ -0,0 +1,318 @@
31995 ++#ifndef GR_ACL_H
31996 ++#define GR_ACL_H
31997 ++
31998 ++#include <linux/grdefs.h>
31999 ++#include <linux/resource.h>
32000 ++#include <linux/capability.h>
32001 ++#include <linux/dcache.h>
32002 ++#include <asm/resource.h>
32003 ++
32004 ++/* Major status information */
32005 ++
32006 ++#define GR_VERSION "grsecurity 2.1.12"
32007 ++#define GRSECURITY_VERSION 0x2112
32008 ++
32009 ++enum {
32010 ++
32011 ++ SHUTDOWN = 0,
32012 ++ ENABLE = 1,
32013 ++ SPROLE = 2,
32014 ++ RELOAD = 3,
32015 ++ SEGVMOD = 4,
32016 ++ STATUS = 5,
32017 ++ UNSPROLE = 6,
32018 ++ PASSSET = 7,
32019 ++ SPROLEPAM = 8
32020 ++};
32021 ++
32022 ++/* Password setup definitions
32023 ++ * kernel/grhash.c */
32024 ++enum {
32025 ++ GR_PW_LEN = 128,
32026 ++ GR_SALT_LEN = 16,
32027 ++ GR_SHA_LEN = 32,
32028 ++};
32029 ++
32030 ++enum {
32031 ++ GR_SPROLE_LEN = 64,
32032 ++};
32033 ++
32034 ++#define GR_NLIMITS (RLIMIT_LOCKS + 2)
32035 ++
32036 ++/* Begin Data Structures */
32037 ++
32038 ++struct sprole_pw {
32039 ++ unsigned char *rolename;
32040 ++ unsigned char salt[GR_SALT_LEN];
32041 ++ unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
32042 ++};
32043 ++
32044 ++struct name_entry {
32045 ++ __u32 key;
32046 ++ ino_t inode;
32047 ++ dev_t device;
32048 ++ char *name;
32049 ++ __u16 len;
32050 ++ __u8 deleted;
32051 ++ struct name_entry *prev;
32052 ++ struct name_entry *next;
32053 ++};
32054 ++
32055 ++struct inodev_entry {
32056 ++ struct name_entry *nentry;
32057 ++ struct inodev_entry *prev;
32058 ++ struct inodev_entry *next;
32059 ++};
32060 ++
32061 ++struct acl_role_db {
32062 ++ struct acl_role_label **r_hash;
32063 ++ __u32 r_size;
32064 ++};
32065 ++
32066 ++struct inodev_db {
32067 ++ struct inodev_entry **i_hash;
32068 ++ __u32 i_size;
32069 ++};
32070 ++
32071 ++struct name_db {
32072 ++ struct name_entry **n_hash;
32073 ++ __u32 n_size;
32074 ++};
32075 ++
32076 ++struct crash_uid {
32077 ++ uid_t uid;
32078 ++ unsigned long expires;
32079 ++};
32080 ++
32081 ++struct gr_hash_struct {
32082 ++ void **table;
32083 ++ void **nametable;
32084 ++ void *first;
32085 ++ __u32 table_size;
32086 ++ __u32 used_size;
32087 ++ int type;
32088 ++};
32089 ++
32090 ++/* Userspace Grsecurity ACL data structures */
32091 ++
32092 ++struct acl_subject_label {
32093 ++ char *filename;
32094 ++ ino_t inode;
32095 ++ dev_t device;
32096 ++ __u32 mode;
32097 ++ kernel_cap_t cap_mask;
32098 ++ kernel_cap_t cap_lower;
32099 ++
32100 ++ struct rlimit res[GR_NLIMITS];
32101 ++ __u16 resmask;
32102 ++
32103 ++ __u8 user_trans_type;
32104 ++ __u8 group_trans_type;
32105 ++ uid_t *user_transitions;
32106 ++ gid_t *group_transitions;
32107 ++ __u16 user_trans_num;
32108 ++ __u16 group_trans_num;
32109 ++
32110 ++ __u32 ip_proto[8];
32111 ++ __u32 ip_type;
32112 ++ struct acl_ip_label **ips;
32113 ++ __u32 ip_num;
32114 ++
32115 ++ __u32 crashes;
32116 ++ unsigned long expires;
32117 ++
32118 ++ struct acl_subject_label *parent_subject;
32119 ++ struct gr_hash_struct *hash;
32120 ++ struct acl_subject_label *prev;
32121 ++ struct acl_subject_label *next;
32122 ++
32123 ++ struct acl_object_label **obj_hash;
32124 ++ __u32 obj_hash_size;
32125 ++ __u16 pax_flags;
32126 ++};
32127 ++
32128 ++struct role_allowed_ip {
32129 ++ __u32 addr;
32130 ++ __u32 netmask;
32131 ++
32132 ++ struct role_allowed_ip *prev;
32133 ++ struct role_allowed_ip *next;
32134 ++};
32135 ++
32136 ++struct role_transition {
32137 ++ char *rolename;
32138 ++
32139 ++ struct role_transition *prev;
32140 ++ struct role_transition *next;
32141 ++};
32142 ++
32143 ++struct acl_role_label {
32144 ++ char *rolename;
32145 ++ uid_t uidgid;
32146 ++ __u16 roletype;
32147 ++
32148 ++ __u16 auth_attempts;
32149 ++ unsigned long expires;
32150 ++
32151 ++ struct acl_subject_label *root_label;
32152 ++ struct gr_hash_struct *hash;
32153 ++
32154 ++ struct acl_role_label *prev;
32155 ++ struct acl_role_label *next;
32156 ++
32157 ++ struct role_transition *transitions;
32158 ++ struct role_allowed_ip *allowed_ips;
32159 ++ uid_t *domain_children;
32160 ++ __u16 domain_child_num;
32161 ++
32162 ++ struct acl_subject_label **subj_hash;
32163 ++ __u32 subj_hash_size;
32164 ++};
32165 ++
32166 ++struct user_acl_role_db {
32167 ++ struct acl_role_label **r_table;
32168 ++ __u32 num_pointers; /* Number of allocations to track */
32169 ++ __u32 num_roles; /* Number of roles */
32170 ++ __u32 num_domain_children; /* Number of domain children */
32171 ++ __u32 num_subjects; /* Number of subjects */
32172 ++ __u32 num_objects; /* Number of objects */
32173 ++};
32174 ++
32175 ++struct acl_object_label {
32176 ++ char *filename;
32177 ++ ino_t inode;
32178 ++ dev_t device;
32179 ++ __u32 mode;
32180 ++
32181 ++ struct acl_subject_label *nested;
32182 ++ struct acl_object_label *globbed;
32183 ++
32184 ++ /* next two structures not used */
32185 ++
32186 ++ struct acl_object_label *prev;
32187 ++ struct acl_object_label *next;
32188 ++};
32189 ++
32190 ++struct acl_ip_label {
32191 ++ char *iface;
32192 ++ __u32 addr;
32193 ++ __u32 netmask;
32194 ++ __u16 low, high;
32195 ++ __u8 mode;
32196 ++ __u32 type;
32197 ++ __u32 proto[8];
32198 ++
32199 ++ /* next two structures not used */
32200 ++
32201 ++ struct acl_ip_label *prev;
32202 ++ struct acl_ip_label *next;
32203 ++};
32204 ++
32205 ++struct gr_arg {
32206 ++ struct user_acl_role_db role_db;
32207 ++ unsigned char pw[GR_PW_LEN];
32208 ++ unsigned char salt[GR_SALT_LEN];
32209 ++ unsigned char sum[GR_SHA_LEN];
32210 ++ unsigned char sp_role[GR_SPROLE_LEN];
32211 ++ struct sprole_pw *sprole_pws;
32212 ++ dev_t segv_device;
32213 ++ ino_t segv_inode;
32214 ++ uid_t segv_uid;
32215 ++ __u16 num_sprole_pws;
32216 ++ __u16 mode;
32217 ++};
32218 ++
32219 ++struct gr_arg_wrapper {
32220 ++ struct gr_arg *arg;
32221 ++ __u32 version;
32222 ++ __u32 size;
32223 ++};
32224 ++
32225 ++struct subject_map {
32226 ++ struct acl_subject_label *user;
32227 ++ struct acl_subject_label *kernel;
32228 ++ struct subject_map *prev;
32229 ++ struct subject_map *next;
32230 ++};
32231 ++
32232 ++struct acl_subj_map_db {
32233 ++ struct subject_map **s_hash;
32234 ++ __u32 s_size;
32235 ++};
32236 ++
32237 ++/* End Data Structures Section */
32238 ++
32239 ++/* Hash functions generated by empirical testing by Brad Spengler
32240 ++ Makes good use of the low bits of the inode. Generally 0-1 times
32241 ++ in loop for successful match. 0-3 for unsuccessful match.
32242 ++ Shift/add algorithm with modulus of table size and an XOR*/
32243 ++
32244 ++static __inline__ unsigned int
32245 ++rhash(const uid_t uid, const __u16 type, const unsigned int sz)
32246 ++{
32247 ++ return (((uid << type) + (uid ^ type)) % sz);
32248 ++}
32249 ++
32250 ++ static __inline__ unsigned int
32251 ++shash(const struct acl_subject_label *userp, const unsigned int sz)
32252 ++{
32253 ++ return ((const unsigned long)userp % sz);
32254 ++}
32255 ++
32256 ++static __inline__ unsigned int
32257 ++fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
32258 ++{
32259 ++ return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
32260 ++}
32261 ++
32262 ++static __inline__ unsigned int
32263 ++nhash(const char *name, const __u16 len, const unsigned int sz)
32264 ++{
32265 ++ return full_name_hash(name, len) % sz;
32266 ++}
32267 ++
32268 ++#define FOR_EACH_ROLE_START(role,iter) \
32269 ++ role = NULL; \
32270 ++ iter = 0; \
32271 ++ while (iter < acl_role_set.r_size) { \
32272 ++ if (role == NULL) \
32273 ++ role = acl_role_set.r_hash[iter]; \
32274 ++ if (role == NULL) { \
32275 ++ iter++; \
32276 ++ continue; \
32277 ++ }
32278 ++
32279 ++#define FOR_EACH_ROLE_END(role,iter) \
32280 ++ role = role->next; \
32281 ++ if (role == NULL) \
32282 ++ iter++; \
32283 ++ }
32284 ++
32285 ++#define FOR_EACH_SUBJECT_START(role,subj,iter) \
32286 ++ subj = NULL; \
32287 ++ iter = 0; \
32288 ++ while (iter < role->subj_hash_size) { \
32289 ++ if (subj == NULL) \
32290 ++ subj = role->subj_hash[iter]; \
32291 ++ if (subj == NULL) { \
32292 ++ iter++; \
32293 ++ continue; \
32294 ++ }
32295 ++
32296 ++#define FOR_EACH_SUBJECT_END(subj,iter) \
32297 ++ subj = subj->next; \
32298 ++ if (subj == NULL) \
32299 ++ iter++; \
32300 ++ }
32301 ++
32302 ++
32303 ++#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
32304 ++ subj = role->hash->first; \
32305 ++ while (subj != NULL) {
32306 ++
32307 ++#define FOR_EACH_NESTED_SUBJECT_END(subj) \
32308 ++ subj = subj->next; \
32309 ++ }
32310 ++
32311 ++#endif
32312 ++
32313 +diff -urNp linux-2.6.26.6/include/linux/gralloc.h linux-2.6.26.6/include/linux/gralloc.h
32314 +--- linux-2.6.26.6/include/linux/gralloc.h 1969-12-31 19:00:00.000000000 -0500
32315 ++++ linux-2.6.26.6/include/linux/gralloc.h 2008-10-11 21:54:20.000000000 -0400
32316 +@@ -0,0 +1,8 @@
32317 ++#ifndef __GRALLOC_H
32318 ++#define __GRALLOC_H
32319 ++
32320 ++void acl_free_all(void);
32321 ++int acl_alloc_stack_init(unsigned long size);
32322 ++void *acl_alloc(unsigned long len);
32323 ++
32324 ++#endif
32325 +diff -urNp linux-2.6.26.6/include/linux/grdefs.h linux-2.6.26.6/include/linux/grdefs.h
32326 +--- linux-2.6.26.6/include/linux/grdefs.h 1969-12-31 19:00:00.000000000 -0500
32327 ++++ linux-2.6.26.6/include/linux/grdefs.h 2008-10-11 21:54:20.000000000 -0400
32328 +@@ -0,0 +1,131 @@
32329 ++#ifndef GRDEFS_H
32330 ++#define GRDEFS_H
32331 ++
32332 ++/* Begin grsecurity status declarations */
32333 ++
32334 ++enum {
32335 ++ GR_READY = 0x01,
32336 ++ GR_STATUS_INIT = 0x00 // disabled state
32337 ++};
32338 ++
32339 ++/* Begin ACL declarations */
32340 ++
32341 ++/* Role flags */
32342 ++
32343 ++enum {
32344 ++ GR_ROLE_USER = 0x0001,
32345 ++ GR_ROLE_GROUP = 0x0002,
32346 ++ GR_ROLE_DEFAULT = 0x0004,
32347 ++ GR_ROLE_SPECIAL = 0x0008,
32348 ++ GR_ROLE_AUTH = 0x0010,
32349 ++ GR_ROLE_NOPW = 0x0020,
32350 ++ GR_ROLE_GOD = 0x0040,
32351 ++ GR_ROLE_LEARN = 0x0080,
32352 ++ GR_ROLE_TPE = 0x0100,
32353 ++ GR_ROLE_DOMAIN = 0x0200,
32354 ++ GR_ROLE_PAM = 0x0400
32355 ++};
32356 ++
32357 ++/* ACL Subject and Object mode flags */
32358 ++enum {
32359 ++ GR_DELETED = 0x80000000
32360 ++};
32361 ++
32362 ++/* ACL Object-only mode flags */
32363 ++enum {
32364 ++ GR_READ = 0x00000001,
32365 ++ GR_APPEND = 0x00000002,
32366 ++ GR_WRITE = 0x00000004,
32367 ++ GR_EXEC = 0x00000008,
32368 ++ GR_FIND = 0x00000010,
32369 ++ GR_INHERIT = 0x00000020,
32370 ++ GR_SETID = 0x00000040,
32371 ++ GR_CREATE = 0x00000080,
32372 ++ GR_DELETE = 0x00000100,
32373 ++ GR_LINK = 0x00000200,
32374 ++ GR_AUDIT_READ = 0x00000400,
32375 ++ GR_AUDIT_APPEND = 0x00000800,
32376 ++ GR_AUDIT_WRITE = 0x00001000,
32377 ++ GR_AUDIT_EXEC = 0x00002000,
32378 ++ GR_AUDIT_FIND = 0x00004000,
32379 ++ GR_AUDIT_INHERIT= 0x00008000,
32380 ++ GR_AUDIT_SETID = 0x00010000,
32381 ++ GR_AUDIT_CREATE = 0x00020000,
32382 ++ GR_AUDIT_DELETE = 0x00040000,
32383 ++ GR_AUDIT_LINK = 0x00080000,
32384 ++ GR_PTRACERD = 0x00100000,
32385 ++ GR_NOPTRACE = 0x00200000,
32386 ++ GR_SUPPRESS = 0x00400000,
32387 ++ GR_NOLEARN = 0x00800000
32388 ++};
32389 ++
32390 ++#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
32391 ++ GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
32392 ++ GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
32393 ++
32394 ++/* ACL subject-only mode flags */
32395 ++enum {
32396 ++ GR_KILL = 0x00000001,
32397 ++ GR_VIEW = 0x00000002,
32398 ++ GR_PROTECTED = 0x00000004,
32399 ++ GR_LEARN = 0x00000008,
32400 ++ GR_OVERRIDE = 0x00000010,
32401 ++ /* just a placeholder, this mode is only used in userspace */
32402 ++ GR_DUMMY = 0x00000020,
32403 ++ GR_PROTSHM = 0x00000040,
32404 ++ GR_KILLPROC = 0x00000080,
32405 ++ GR_KILLIPPROC = 0x00000100,
32406 ++ /* just a placeholder, this mode is only used in userspace */
32407 ++ GR_NOTROJAN = 0x00000200,
32408 ++ GR_PROTPROCFD = 0x00000400,
32409 ++ GR_PROCACCT = 0x00000800,
32410 ++ GR_RELAXPTRACE = 0x00001000,
32411 ++ GR_NESTED = 0x00002000,
32412 ++ GR_INHERITLEARN = 0x00004000,
32413 ++ GR_PROCFIND = 0x00008000,
32414 ++ GR_POVERRIDE = 0x00010000,
32415 ++ GR_KERNELAUTH = 0x00020000,
32416 ++};
32417 ++
32418 ++enum {
32419 ++ GR_PAX_ENABLE_SEGMEXEC = 0x0001,
32420 ++ GR_PAX_ENABLE_PAGEEXEC = 0x0002,
32421 ++ GR_PAX_ENABLE_MPROTECT = 0x0004,
32422 ++ GR_PAX_ENABLE_RANDMMAP = 0x0008,
32423 ++ GR_PAX_ENABLE_EMUTRAMP = 0x0010,
32424 ++ GR_PAX_DISABLE_SEGMEXEC = 0x0100,
32425 ++ GR_PAX_DISABLE_PAGEEXEC = 0x0200,
32426 ++ GR_PAX_DISABLE_MPROTECT = 0x0400,
32427 ++ GR_PAX_DISABLE_RANDMMAP = 0x0800,
32428 ++ GR_PAX_DISABLE_EMUTRAMP = 0x1000,
32429 ++};
32430 ++
32431 ++enum {
32432 ++ GR_ID_USER = 0x01,
32433 ++ GR_ID_GROUP = 0x02,
32434 ++};
32435 ++
32436 ++enum {
32437 ++ GR_ID_ALLOW = 0x01,
32438 ++ GR_ID_DENY = 0x02,
32439 ++};
32440 ++
32441 ++#define GR_CRASH_RES 11
32442 ++#define GR_UIDTABLE_MAX 500
32443 ++
32444 ++/* begin resource learning section */
32445 ++enum {
32446 ++ GR_RLIM_CPU_BUMP = 60,
32447 ++ GR_RLIM_FSIZE_BUMP = 50000,
32448 ++ GR_RLIM_DATA_BUMP = 10000,
32449 ++ GR_RLIM_STACK_BUMP = 1000,
32450 ++ GR_RLIM_CORE_BUMP = 10000,
32451 ++ GR_RLIM_RSS_BUMP = 500000,
32452 ++ GR_RLIM_NPROC_BUMP = 1,
32453 ++ GR_RLIM_NOFILE_BUMP = 5,
32454 ++ GR_RLIM_MEMLOCK_BUMP = 50000,
32455 ++ GR_RLIM_AS_BUMP = 500000,
32456 ++ GR_RLIM_LOCKS_BUMP = 2
32457 ++};
32458 ++
32459 ++#endif
32460 +diff -urNp linux-2.6.26.6/include/linux/grinternal.h linux-2.6.26.6/include/linux/grinternal.h
32461 +--- linux-2.6.26.6/include/linux/grinternal.h 1969-12-31 19:00:00.000000000 -0500
32462 ++++ linux-2.6.26.6/include/linux/grinternal.h 2008-10-11 21:54:20.000000000 -0400
32463 +@@ -0,0 +1,210 @@
32464 ++#ifndef __GRINTERNAL_H
32465 ++#define __GRINTERNAL_H
32466 ++
32467 ++#ifdef CONFIG_GRKERNSEC
32468 ++
32469 ++#include <linux/fs.h>
32470 ++#include <linux/gracl.h>
32471 ++#include <linux/grdefs.h>
32472 ++#include <linux/grmsg.h>
32473 ++
32474 ++void gr_add_learn_entry(const char *fmt, ...);
32475 ++__u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
32476 ++ const struct vfsmount *mnt);
32477 ++__u32 gr_check_create(const struct dentry *new_dentry,
32478 ++ const struct dentry *parent,
32479 ++ const struct vfsmount *mnt, const __u32 mode);
32480 ++int gr_check_protected_task(const struct task_struct *task);
32481 ++__u32 to_gr_audit(const __u32 reqmode);
32482 ++int gr_set_acls(const int type);
32483 ++
32484 ++int gr_acl_is_enabled(void);
32485 ++char gr_roletype_to_char(void);
32486 ++
32487 ++void gr_handle_alertkill(struct task_struct *task);
32488 ++char *gr_to_filename(const struct dentry *dentry,
32489 ++ const struct vfsmount *mnt);
32490 ++char *gr_to_filename1(const struct dentry *dentry,
32491 ++ const struct vfsmount *mnt);
32492 ++char *gr_to_filename2(const struct dentry *dentry,
32493 ++ const struct vfsmount *mnt);
32494 ++char *gr_to_filename3(const struct dentry *dentry,
32495 ++ const struct vfsmount *mnt);
32496 ++
32497 ++extern int grsec_enable_link;
32498 ++extern int grsec_enable_fifo;
32499 ++extern int grsec_enable_execve;
32500 ++extern int grsec_enable_shm;
32501 ++extern int grsec_enable_execlog;
32502 ++extern int grsec_enable_signal;
32503 ++extern int grsec_enable_forkfail;
32504 ++extern int grsec_enable_time;
32505 ++extern int grsec_enable_chroot_shmat;
32506 ++extern int grsec_enable_chroot_findtask;
32507 ++extern int grsec_enable_chroot_mount;
32508 ++extern int grsec_enable_chroot_double;
32509 ++extern int grsec_enable_chroot_pivot;
32510 ++extern int grsec_enable_chroot_chdir;
32511 ++extern int grsec_enable_chroot_chmod;
32512 ++extern int grsec_enable_chroot_mknod;
32513 ++extern int grsec_enable_chroot_fchdir;
32514 ++extern int grsec_enable_chroot_nice;
32515 ++extern int grsec_enable_chroot_execlog;
32516 ++extern int grsec_enable_chroot_caps;
32517 ++extern int grsec_enable_chroot_sysctl;
32518 ++extern int grsec_enable_chroot_unix;
32519 ++extern int grsec_enable_tpe;
32520 ++extern int grsec_tpe_gid;
32521 ++extern int grsec_enable_tpe_all;
32522 ++extern int grsec_enable_sidcaps;
32523 ++extern int grsec_enable_socket_all;
32524 ++extern int grsec_socket_all_gid;
32525 ++extern int grsec_enable_socket_client;
32526 ++extern int grsec_socket_client_gid;
32527 ++extern int grsec_enable_socket_server;
32528 ++extern int grsec_socket_server_gid;
32529 ++extern int grsec_audit_gid;
32530 ++extern int grsec_enable_group;
32531 ++extern int grsec_enable_audit_ipc;
32532 ++extern int grsec_enable_audit_textrel;
32533 ++extern int grsec_enable_mount;
32534 ++extern int grsec_enable_chdir;
32535 ++extern int grsec_resource_logging;
32536 ++extern int grsec_lock;
32537 ++
32538 ++extern spinlock_t grsec_alert_lock;
32539 ++extern unsigned long grsec_alert_wtime;
32540 ++extern unsigned long grsec_alert_fyet;
32541 ++
32542 ++extern spinlock_t grsec_audit_lock;
32543 ++
32544 ++extern rwlock_t grsec_exec_file_lock;
32545 ++
32546 ++#define gr_task_fullpath(tsk) (tsk->exec_file ? \
32547 ++ gr_to_filename2(tsk->exec_file->f_path.dentry, \
32548 ++ tsk->exec_file->f_vfsmnt) : "/")
32549 ++
32550 ++#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
32551 ++ gr_to_filename3(tsk->parent->exec_file->f_path.dentry, \
32552 ++ tsk->parent->exec_file->f_vfsmnt) : "/")
32553 ++
32554 ++#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
32555 ++ gr_to_filename(tsk->exec_file->f_path.dentry, \
32556 ++ tsk->exec_file->f_vfsmnt) : "/")
32557 ++
32558 ++#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
32559 ++ gr_to_filename1(tsk->parent->exec_file->f_path.dentry, \
32560 ++ tsk->parent->exec_file->f_vfsmnt) : "/")
32561 ++
32562 ++#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
32563 ++ ((tsk_a->fs->root.dentry->d_inode->i_sb->s_dev != \
32564 ++ tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_sb->s_dev) || \
32565 ++ (tsk_a->fs->root.dentry->d_inode->i_ino != \
32566 ++ tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_ino)))
32567 ++
32568 ++#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
32569 ++ (tsk_a->fs->root.dentry->d_inode->i_sb->s_dev == \
32570 ++ tsk_b->fs->root.dentry->d_inode->i_sb->s_dev) && \
32571 ++ (tsk_a->fs->root.dentry->d_inode->i_ino == \
32572 ++ tsk_b->fs->root.dentry->d_inode->i_ino))
32573 ++
32574 ++#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
32575 ++ task->pid, task->uid, \
32576 ++ task->euid, task->gid, task->egid, \
32577 ++ gr_parent_task_fullpath(task), \
32578 ++ task->parent->comm, task->parent->pid, \
32579 ++ task->parent->uid, task->parent->euid, \
32580 ++ task->parent->gid, task->parent->egid
32581 ++
32582 ++#define GR_CHROOT_CAPS {{ \
32583 ++ CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
32584 ++ CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
32585 ++ CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
32586 ++ CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
32587 ++ CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
32588 ++ CAP_TO_MASK(CAP_IPC_OWNER) , 0 }}
32589 ++
32590 ++#define security_learn(normal_msg,args...) \
32591 ++({ \
32592 ++ read_lock(&grsec_exec_file_lock); \
32593 ++ gr_add_learn_entry(normal_msg "\n", ## args); \
32594 ++ read_unlock(&grsec_exec_file_lock); \
32595 ++})
32596 ++
32597 ++enum {
32598 ++ GR_DO_AUDIT,
32599 ++ GR_DONT_AUDIT,
32600 ++ GR_DONT_AUDIT_GOOD
32601 ++};
32602 ++
32603 ++enum {
32604 ++ GR_TTYSNIFF,
32605 ++ GR_RBAC,
32606 ++ GR_RBAC_STR,
32607 ++ GR_STR_RBAC,
32608 ++ GR_RBAC_MODE2,
32609 ++ GR_RBAC_MODE3,
32610 ++ GR_FILENAME,
32611 ++ GR_SYSCTL_HIDDEN,
32612 ++ GR_NOARGS,
32613 ++ GR_ONE_INT,
32614 ++ GR_ONE_INT_TWO_STR,
32615 ++ GR_ONE_STR,
32616 ++ GR_STR_INT,
32617 ++ GR_TWO_INT,
32618 ++ GR_THREE_INT,
32619 ++ GR_FIVE_INT_TWO_STR,
32620 ++ GR_TWO_STR,
32621 ++ GR_THREE_STR,
32622 ++ GR_FOUR_STR,
32623 ++ GR_STR_FILENAME,
32624 ++ GR_FILENAME_STR,
32625 ++ GR_FILENAME_TWO_INT,
32626 ++ GR_FILENAME_TWO_INT_STR,
32627 ++ GR_TEXTREL,
32628 ++ GR_PTRACE,
32629 ++ GR_RESOURCE,
32630 ++ GR_CAP,
32631 ++ GR_SIG,
32632 ++ GR_CRASH1,
32633 ++ GR_CRASH2,
32634 ++ GR_PSACCT
32635 ++};
32636 ++
32637 ++#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str)
32638 ++#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
32639 ++#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
32640 ++#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
32641 ++#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
32642 ++#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
32643 ++#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)
32644 ++#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
32645 ++#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
32646 ++#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
32647 ++#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
32648 ++#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
32649 ++#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
32650 ++#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
32651 ++#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
32652 ++#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)
32653 ++#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
32654 ++#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
32655 ++#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
32656 ++#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
32657 ++#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
32658 ++#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
32659 ++#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)
32660 ++#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
32661 ++#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
32662 ++#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
32663 ++#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
32664 ++#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
32665 ++#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
32666 ++#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
32667 ++#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)
32668 ++
32669 ++void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
32670 ++
32671 ++#endif
32672 ++
32673 ++#endif
32674 +diff -urNp linux-2.6.26.6/include/linux/grmsg.h linux-2.6.26.6/include/linux/grmsg.h
32675 +--- linux-2.6.26.6/include/linux/grmsg.h 1969-12-31 19:00:00.000000000 -0500
32676 ++++ linux-2.6.26.6/include/linux/grmsg.h 2008-10-11 21:54:20.000000000 -0400
32677 +@@ -0,0 +1,108 @@
32678 ++#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"
32679 ++#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"
32680 ++#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
32681 ++#define GR_STOPMOD_MSG "denied modification of module state by "
32682 ++#define GR_IOPERM_MSG "denied use of ioperm() by "
32683 ++#define GR_IOPL_MSG "denied use of iopl() by "
32684 ++#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
32685 ++#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
32686 ++#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
32687 ++#define GR_KMEM_MSG "denied write of /dev/kmem by "
32688 ++#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
32689 ++#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
32690 ++#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
32691 ++#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
32692 ++#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"
32693 ++#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"
32694 ++#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
32695 ++#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
32696 ++#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
32697 ++#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
32698 ++#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
32699 ++#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
32700 ++#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
32701 ++#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
32702 ++#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
32703 ++#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
32704 ++#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
32705 ++#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
32706 ++#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
32707 ++#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
32708 ++#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
32709 ++#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
32710 ++#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
32711 ++#define GR_NPROC_MSG "denied overstep of process limit by "
32712 ++#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
32713 ++#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
32714 ++#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
32715 ++#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
32716 ++#define GR_MOUNT_CHROOT_MSG "denied mount of %.30s as %.930s from chroot by "
32717 ++#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
32718 ++#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
32719 ++#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
32720 ++#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
32721 ++#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
32722 ++#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
32723 ++#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
32724 ++#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
32725 ++#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
32726 ++#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
32727 ++#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
32728 ++#define GR_INITF_ACL_MSG "init_variables() failed %s by "
32729 ++#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"
32730 ++#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
32731 ++#define GR_SHUTS_ACL_MSG "shutdown auth success for "
32732 ++#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
32733 ++#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
32734 ++#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
32735 ++#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
32736 ++#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
32737 ++#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
32738 ++#define GR_ENABLEF_ACL_MSG "unable to load %s for "
32739 ++#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
32740 ++#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
32741 ++#define GR_RELOADF_ACL_MSG "failed reload of %s for "
32742 ++#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
32743 ++#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
32744 ++#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
32745 ++#define GR_SPROLEF_ACL_MSG "special role %s failure for "
32746 ++#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
32747 ++#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
32748 ++#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
32749 ++#define GR_INVMODE_ACL_MSG "invalid mode %d by "
32750 ++#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
32751 ++#define GR_FAILFORK_MSG "failed fork with errno %d by "
32752 ++#define GR_NICE_CHROOT_MSG "denied priority change by "
32753 ++#define GR_UNISIGLOG_MSG "signal %d sent to "
32754 ++#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
32755 ++#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
32756 ++#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
32757 ++#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
32758 ++#define GR_TIME_MSG "time set by "
32759 ++#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
32760 ++#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
32761 ++#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
32762 ++#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
32763 ++#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
32764 ++#define GR_BIND_MSG "denied bind() by "
32765 ++#define GR_CONNECT_MSG "denied connect() by "
32766 ++#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
32767 ++#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
32768 ++#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"
32769 ++#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
32770 ++#define GR_CAP_ACL_MSG "use of %s denied for "
32771 ++#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
32772 ++#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
32773 ++#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by "
32774 ++#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by "
32775 ++#define GR_MOUNT_AUDIT_MSG "mount of %.30s to %.64s by "
32776 ++#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
32777 ++#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
32778 ++#define GR_MSGQ_AUDIT_MSG "message queue created by "
32779 ++#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
32780 ++#define GR_SEM_AUDIT_MSG "semaphore created by "
32781 ++#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
32782 ++#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
32783 ++#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
32784 ++#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
32785 ++#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
32786 +diff -urNp linux-2.6.26.6/include/linux/grsecurity.h linux-2.6.26.6/include/linux/grsecurity.h
32787 +--- linux-2.6.26.6/include/linux/grsecurity.h 1969-12-31 19:00:00.000000000 -0500
32788 ++++ linux-2.6.26.6/include/linux/grsecurity.h 2008-10-11 21:54:20.000000000 -0400
32789 +@@ -0,0 +1,200 @@
32790 ++#ifndef GR_SECURITY_H
32791 ++#define GR_SECURITY_H
32792 ++#include <linux/fs.h>
32793 ++#include <linux/binfmts.h>
32794 ++#include <linux/gracl.h>
32795 ++
32796 ++/* notify of brain-dead configs */
32797 ++#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC)
32798 ++#error "CONFIG_PAX_NOEXEC enabled, but PAGEEXEC, SEGMEXEC, and KERNEXEC are disabled."
32799 ++#endif
32800 ++#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
32801 ++#error "CONFIG_PAX_NOEXEC enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
32802 ++#endif
32803 ++#if defined(CONFIG_PAX_ASLR) && (defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
32804 ++#error "CONFIG_PAX_ASLR enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
32805 ++#endif
32806 ++#if defined(CONFIG_PAX_ASLR) && !defined(CONFIG_PAX_RANDKSTACK) && !defined(CONFIG_PAX_RANDUSTACK) && !defined(CONFIG_PAX_RANDMMAP)
32807 ++#error "CONFIG_PAX_ASLR enabled, but RANDKSTACK, RANDUSTACK, and RANDMMAP are disabled."
32808 ++#endif
32809 ++#if defined(CONFIG_PAX) && !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_ASLR)
32810 ++#error "CONFIG_PAX enabled, but no PaX options are enabled."
32811 ++#endif
32812 ++
32813 ++void gr_handle_brute_attach(struct task_struct *p);
32814 ++void gr_handle_brute_check(void);
32815 ++
32816 ++char gr_roletype_to_char(void);
32817 ++
32818 ++int gr_check_user_change(int real, int effective, int fs);
32819 ++int gr_check_group_change(int real, int effective, int fs);
32820 ++
32821 ++void gr_del_task_from_ip_table(struct task_struct *p);
32822 ++
32823 ++int gr_pid_is_chrooted(struct task_struct *p);
32824 ++int gr_handle_chroot_nice(void);
32825 ++int gr_handle_chroot_sysctl(const int op);
32826 ++int gr_handle_chroot_setpriority(struct task_struct *p,
32827 ++ const int niceval);
32828 ++int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
32829 ++int gr_handle_chroot_chroot(const struct dentry *dentry,
32830 ++ const struct vfsmount *mnt);
32831 ++void gr_handle_chroot_caps(struct task_struct *task);
32832 ++void gr_handle_chroot_chdir(struct path *path);
32833 ++int gr_handle_chroot_chmod(const struct dentry *dentry,
32834 ++ const struct vfsmount *mnt, const int mode);
32835 ++int gr_handle_chroot_mknod(const struct dentry *dentry,
32836 ++ const struct vfsmount *mnt, const int mode);
32837 ++int gr_handle_chroot_mount(const struct dentry *dentry,
32838 ++ const struct vfsmount *mnt,
32839 ++ const char *dev_name);
32840 ++int gr_handle_chroot_pivot(void);
32841 ++int gr_handle_chroot_unix(const pid_t pid);
32842 ++
32843 ++int gr_handle_rawio(const struct inode *inode);
32844 ++int gr_handle_nproc(void);
32845 ++
32846 ++void gr_handle_ioperm(void);
32847 ++void gr_handle_iopl(void);
32848 ++
32849 ++int gr_tpe_allow(const struct file *file);
32850 ++
32851 ++int gr_random_pid(void);
32852 ++
32853 ++void gr_log_forkfail(const int retval);
32854 ++void gr_log_timechange(void);
32855 ++void gr_log_signal(const int sig, const struct task_struct *t);
32856 ++void gr_log_chdir(const struct dentry *dentry,
32857 ++ const struct vfsmount *mnt);
32858 ++void gr_log_chroot_exec(const struct dentry *dentry,
32859 ++ const struct vfsmount *mnt);
32860 ++void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
32861 ++void gr_log_remount(const char *devname, const int retval);
32862 ++void gr_log_unmount(const char *devname, const int retval);
32863 ++void gr_log_mount(const char *from, const char *to, const int retval);
32864 ++void gr_log_msgget(const int ret, const int msgflg);
32865 ++void gr_log_msgrm(const uid_t uid, const uid_t cuid);
32866 ++void gr_log_semget(const int err, const int semflg);
32867 ++void gr_log_semrm(const uid_t uid, const uid_t cuid);
32868 ++void gr_log_shmget(const int err, const int shmflg, const size_t size);
32869 ++void gr_log_shmrm(const uid_t uid, const uid_t cuid);
32870 ++void gr_log_textrel(struct vm_area_struct *vma);
32871 ++
32872 ++int gr_handle_follow_link(const struct inode *parent,
32873 ++ const struct inode *inode,
32874 ++ const struct dentry *dentry,
32875 ++ const struct vfsmount *mnt);
32876 ++int gr_handle_fifo(const struct dentry *dentry,
32877 ++ const struct vfsmount *mnt,
32878 ++ const struct dentry *dir, const int flag,
32879 ++ const int acc_mode);
32880 ++int gr_handle_hardlink(const struct dentry *dentry,
32881 ++ const struct vfsmount *mnt,
32882 ++ struct inode *inode,
32883 ++ const int mode, const char *to);
32884 ++
32885 ++int gr_task_is_capable(struct task_struct *task, const int cap);
32886 ++int gr_is_capable_nolog(const int cap);
32887 ++void gr_learn_resource(const struct task_struct *task, const int limit,
32888 ++ const unsigned long wanted, const int gt);
32889 ++void gr_copy_label(struct task_struct *tsk);
32890 ++void gr_handle_crash(struct task_struct *task, const int sig);
32891 ++int gr_handle_signal(const struct task_struct *p, const int sig);
32892 ++int gr_check_crash_uid(const uid_t uid);
32893 ++int gr_check_protected_task(const struct task_struct *task);
32894 ++int gr_acl_handle_mmap(const struct file *file,
32895 ++ const unsigned long prot);
32896 ++int gr_acl_handle_mprotect(const struct file *file,
32897 ++ const unsigned long prot);
32898 ++int gr_check_hidden_task(const struct task_struct *tsk);
32899 ++__u32 gr_acl_handle_truncate(const struct dentry *dentry,
32900 ++ const struct vfsmount *mnt);
32901 ++__u32 gr_acl_handle_utime(const struct dentry *dentry,
32902 ++ const struct vfsmount *mnt);
32903 ++__u32 gr_acl_handle_access(const struct dentry *dentry,
32904 ++ const struct vfsmount *mnt, const int fmode);
32905 ++__u32 gr_acl_handle_fchmod(const struct dentry *dentry,
32906 ++ const struct vfsmount *mnt, mode_t mode);
32907 ++__u32 gr_acl_handle_chmod(const struct dentry *dentry,
32908 ++ const struct vfsmount *mnt, mode_t mode);
32909 ++__u32 gr_acl_handle_chown(const struct dentry *dentry,
32910 ++ const struct vfsmount *mnt);
32911 ++int gr_handle_ptrace(struct task_struct *task, const long request);
32912 ++int gr_handle_proc_ptrace(struct task_struct *task);
32913 ++__u32 gr_acl_handle_execve(const struct dentry *dentry,
32914 ++ const struct vfsmount *mnt);
32915 ++int gr_check_crash_exec(const struct file *filp);
32916 ++int gr_acl_is_enabled(void);
32917 ++void gr_set_kernel_label(struct task_struct *task);
32918 ++void gr_set_role_label(struct task_struct *task, const uid_t uid,
32919 ++ const gid_t gid);
32920 ++int gr_set_proc_label(const struct dentry *dentry,
32921 ++ const struct vfsmount *mnt);
32922 ++__u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
32923 ++ const struct vfsmount *mnt);
32924 ++__u32 gr_acl_handle_open(const struct dentry *dentry,
32925 ++ const struct vfsmount *mnt, const int fmode);
32926 ++__u32 gr_acl_handle_creat(const struct dentry *dentry,
32927 ++ const struct dentry *p_dentry,
32928 ++ const struct vfsmount *p_mnt, const int fmode,
32929 ++ const int imode);
32930 ++void gr_handle_create(const struct dentry *dentry,
32931 ++ const struct vfsmount *mnt);
32932 ++__u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
32933 ++ const struct dentry *parent_dentry,
32934 ++ const struct vfsmount *parent_mnt,
32935 ++ const int mode);
32936 ++__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
32937 ++ const struct dentry *parent_dentry,
32938 ++ const struct vfsmount *parent_mnt);
32939 ++__u32 gr_acl_handle_rmdir(const struct dentry *dentry,
32940 ++ const struct vfsmount *mnt);
32941 ++void gr_handle_delete(const ino_t ino, const dev_t dev);
32942 ++__u32 gr_acl_handle_unlink(const struct dentry *dentry,
32943 ++ const struct vfsmount *mnt);
32944 ++__u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
32945 ++ const struct dentry *parent_dentry,
32946 ++ const struct vfsmount *parent_mnt,
32947 ++ const char *from);
32948 ++__u32 gr_acl_handle_link(const struct dentry *new_dentry,
32949 ++ const struct dentry *parent_dentry,
32950 ++ const struct vfsmount *parent_mnt,
32951 ++ const struct dentry *old_dentry,
32952 ++ const struct vfsmount *old_mnt, const char *to);
32953 ++int gr_acl_handle_rename(struct dentry *new_dentry,
32954 ++ struct dentry *parent_dentry,
32955 ++ const struct vfsmount *parent_mnt,
32956 ++ struct dentry *old_dentry,
32957 ++ struct inode *old_parent_inode,
32958 ++ struct vfsmount *old_mnt, const char *newname);
32959 ++void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
32960 ++ struct dentry *old_dentry,
32961 ++ struct dentry *new_dentry,
32962 ++ struct vfsmount *mnt, const __u8 replace);
32963 ++__u32 gr_check_link(const struct dentry *new_dentry,
32964 ++ const struct dentry *parent_dentry,
32965 ++ const struct vfsmount *parent_mnt,
32966 ++ const struct dentry *old_dentry,
32967 ++ const struct vfsmount *old_mnt);
32968 ++int gr_acl_handle_filldir(const struct file *file, const char *name,
32969 ++ const unsigned int namelen, const ino_t ino);
32970 ++
32971 ++__u32 gr_acl_handle_unix(const struct dentry *dentry,
32972 ++ const struct vfsmount *mnt);
32973 ++void gr_acl_handle_exit(void);
32974 ++void gr_acl_handle_psacct(struct task_struct *task, const long code);
32975 ++int gr_acl_handle_procpidmem(const struct task_struct *task);
32976 ++
32977 ++#ifdef CONFIG_GRKERNSEC
32978 ++void gr_handle_mem_write(void);
32979 ++void gr_handle_kmem_write(void);
32980 ++void gr_handle_open_port(void);
32981 ++int gr_handle_mem_mmap(const unsigned long offset,
32982 ++ struct vm_area_struct *vma);
32983 ++
32984 ++extern int grsec_enable_dmesg;
32985 ++extern int grsec_enable_randsrc;
32986 ++extern int grsec_enable_shm;
32987 ++#endif
32988 ++
32989 ++#endif
32990 +diff -urNp linux-2.6.26.6/include/linux/highmem.h linux-2.6.26.6/include/linux/highmem.h
32991 +--- linux-2.6.26.6/include/linux/highmem.h 2008-10-08 23:24:05.000000000 -0400
32992 ++++ linux-2.6.26.6/include/linux/highmem.h 2008-10-11 21:54:20.000000000 -0400
32993 +@@ -122,6 +122,13 @@ static inline void clear_highpage(struct
32994 + kunmap_atomic(kaddr, KM_USER0);
32995 + }
32996 +
32997 ++static inline void sanitize_highpage(struct page *page)
32998 ++{
32999 ++ void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
33000 ++ clear_page(kaddr);
33001 ++ kunmap_atomic(kaddr, KM_CLEARPAGE);
33002 ++}
33003 ++
33004 + static inline void zero_user_segments(struct page *page,
33005 + unsigned start1, unsigned end1,
33006 + unsigned start2, unsigned end2)
33007 +diff -urNp linux-2.6.26.6/include/linux/jbd2.h linux-2.6.26.6/include/linux/jbd2.h
33008 +--- linux-2.6.26.6/include/linux/jbd2.h 2008-10-08 23:24:05.000000000 -0400
33009 ++++ linux-2.6.26.6/include/linux/jbd2.h 2008-10-11 21:54:20.000000000 -0400
33010 +@@ -66,7 +66,7 @@ extern u8 jbd2_journal_enable_debug;
33011 + } \
33012 + } while (0)
33013 + #else
33014 +-#define jbd_debug(f, a...) /**/
33015 ++#define jbd_debug(f, a...) do {} while (0)
33016 + #endif
33017 +
33018 + static inline void *jbd2_alloc(size_t size, gfp_t flags)
33019 +diff -urNp linux-2.6.26.6/include/linux/jbd.h linux-2.6.26.6/include/linux/jbd.h
33020 +--- linux-2.6.26.6/include/linux/jbd.h 2008-10-08 23:24:05.000000000 -0400
33021 ++++ linux-2.6.26.6/include/linux/jbd.h 2008-10-11 21:54:20.000000000 -0400
33022 +@@ -66,7 +66,7 @@ extern u8 journal_enable_debug;
33023 + } \
33024 + } while (0)
33025 + #else
33026 +-#define jbd_debug(f, a...) /**/
33027 ++#define jbd_debug(f, a...) do {} while (0)
33028 + #endif
33029 +
33030 + static inline void *jbd_alloc(size_t size, gfp_t flags)
33031 +diff -urNp linux-2.6.26.6/include/linux/libata.h linux-2.6.26.6/include/linux/libata.h
33032 +--- linux-2.6.26.6/include/linux/libata.h 2008-10-08 23:24:05.000000000 -0400
33033 ++++ linux-2.6.26.6/include/linux/libata.h 2008-10-11 21:54:20.000000000 -0400
33034 +@@ -63,11 +63,11 @@
33035 + #ifdef ATA_VERBOSE_DEBUG
33036 + #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
33037 + #else
33038 +-#define VPRINTK(fmt, args...)
33039 ++#define VPRINTK(fmt, args...) do {} while (0)
33040 + #endif /* ATA_VERBOSE_DEBUG */
33041 + #else
33042 +-#define DPRINTK(fmt, args...)
33043 +-#define VPRINTK(fmt, args...)
33044 ++#define DPRINTK(fmt, args...) do {} while (0)
33045 ++#define VPRINTK(fmt, args...) do {} while (0)
33046 + #endif /* ATA_DEBUG */
33047 +
33048 + #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
33049 +diff -urNp linux-2.6.26.6/include/linux/mm.h linux-2.6.26.6/include/linux/mm.h
33050 +--- linux-2.6.26.6/include/linux/mm.h 2008-10-08 23:24:05.000000000 -0400
33051 ++++ linux-2.6.26.6/include/linux/mm.h 2008-10-11 21:54:20.000000000 -0400
33052 +@@ -38,6 +38,7 @@ extern unsigned long mmap_min_addr;
33053 + #include <asm/page.h>
33054 + #include <asm/pgtable.h>
33055 + #include <asm/processor.h>
33056 ++#include <asm/mman.h>
33057 +
33058 + #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
33059 +
33060 +@@ -109,6 +110,14 @@ extern unsigned int kobjsize(const void
33061 + #define VM_CAN_NONLINEAR 0x08000000 /* Has ->fault & does nonlinear pages */
33062 + #define VM_MIXEDMAP 0x10000000 /* Can contain "struct page" and pure PFN pages */
33063 +
33064 ++#ifdef CONFIG_PAX_PAGEEXEC
33065 ++#define VM_PAGEEXEC 0x20000000 /* vma->vm_page_prot needs special handling */
33066 ++#endif
33067 ++
33068 ++#ifdef CONFIG_PAX_MPROTECT
33069 ++#define VM_MAYNOTWRITE 0x40000000 /* vma cannot be granted VM_WRITE any more */
33070 ++#endif
33071 ++
33072 + #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
33073 + #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
33074 + #endif
33075 +@@ -858,6 +867,8 @@ struct shrinker {
33076 + extern void register_shrinker(struct shrinker *);
33077 + extern void unregister_shrinker(struct shrinker *);
33078 +
33079 ++pgprot_t vm_get_page_prot(unsigned long vm_flags);
33080 ++
33081 + int vma_wants_writenotify(struct vm_area_struct *vma);
33082 +
33083 + extern pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl);
33084 +@@ -1109,6 +1120,7 @@ out:
33085 + }
33086 +
33087 + extern int do_munmap(struct mm_struct *, unsigned long, size_t);
33088 ++extern int __do_munmap(struct mm_struct *, unsigned long, size_t);
33089 +
33090 + extern unsigned long do_brk(unsigned long, unsigned long);
33091 +
33092 +@@ -1161,6 +1173,10 @@ extern struct vm_area_struct * find_vma(
33093 + extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
33094 + struct vm_area_struct **pprev);
33095 +
33096 ++extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma);
33097 ++extern void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma);
33098 ++extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl);
33099 ++
33100 + /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
33101 + NULL if none. Assume start_addr < end_addr. */
33102 + static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
33103 +@@ -1177,7 +1193,6 @@ static inline unsigned long vma_pages(st
33104 + return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
33105 + }
33106 +
33107 +-pgprot_t vm_get_page_prot(unsigned long vm_flags);
33108 + struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
33109 + int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
33110 + unsigned long pfn, unsigned long size, pgprot_t);
33111 +@@ -1266,5 +1281,11 @@ int vmemmap_populate_basepages(struct pa
33112 + int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
33113 + void vmemmap_populate_print_last(void);
33114 +
33115 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
33116 ++extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
33117 ++#else
33118 ++static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
33119 ++#endif
33120 ++
33121 + #endif /* __KERNEL__ */
33122 + #endif /* _LINUX_MM_H */
33123 +diff -urNp linux-2.6.26.6/include/linux/mm_types.h linux-2.6.26.6/include/linux/mm_types.h
33124 +--- linux-2.6.26.6/include/linux/mm_types.h 2008-10-08 23:24:05.000000000 -0400
33125 ++++ linux-2.6.26.6/include/linux/mm_types.h 2008-10-11 21:54:20.000000000 -0400
33126 +@@ -157,6 +157,8 @@ struct vm_area_struct {
33127 + #ifdef CONFIG_NUMA
33128 + struct mempolicy *vm_policy; /* NUMA policy for the VMA */
33129 + #endif
33130 ++
33131 ++ struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */
33132 + };
33133 +
33134 + struct mm_struct {
33135 +@@ -244,6 +246,24 @@ struct mm_struct {
33136 + struct file *exe_file;
33137 + unsigned long num_exe_file_vmas;
33138 + #endif
33139 ++
33140 ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
33141 ++ unsigned long pax_flags;
33142 ++#endif
33143 ++
33144 ++#ifdef CONFIG_PAX_DLRESOLVE
33145 ++ unsigned long call_dl_resolve;
33146 ++#endif
33147 ++
33148 ++#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
33149 ++ unsigned long call_syscall;
33150 ++#endif
33151 ++
33152 ++#ifdef CONFIG_PAX_ASLR
33153 ++ unsigned long delta_mmap; /* randomized offset */
33154 ++ unsigned long delta_stack; /* randomized offset */
33155 ++#endif
33156 ++
33157 + };
33158 +
33159 + #endif /* _LINUX_MM_TYPES_H */
33160 +diff -urNp linux-2.6.26.6/include/linux/module.h linux-2.6.26.6/include/linux/module.h
33161 +--- linux-2.6.26.6/include/linux/module.h 2008-10-08 23:24:05.000000000 -0400
33162 ++++ linux-2.6.26.6/include/linux/module.h 2008-10-11 21:54:20.000000000 -0400
33163 +@@ -279,16 +279,16 @@ struct module
33164 + int (*init)(void);
33165 +
33166 + /* If this is non-NULL, vfree after init() returns */
33167 +- void *module_init;
33168 ++ void *module_init_rx, *module_init_rw;
33169 +
33170 + /* Here is the actual code + data, vfree'd on unload. */
33171 +- void *module_core;
33172 ++ void *module_core_rx, *module_core_rw;
33173 +
33174 + /* Here are the sizes of the init and core sections */
33175 +- unsigned long init_size, core_size;
33176 ++ unsigned long init_size_rw, core_size_rw;
33177 +
33178 + /* The size of the executable code in each section. */
33179 +- unsigned long init_text_size, core_text_size;
33180 ++ unsigned long init_size_rx, core_size_rx;
33181 +
33182 + /* The handle returned from unwind_add_table. */
33183 + void *unwind_info;
33184 +diff -urNp linux-2.6.26.6/include/linux/moduleloader.h linux-2.6.26.6/include/linux/moduleloader.h
33185 +--- linux-2.6.26.6/include/linux/moduleloader.h 2008-10-08 23:24:05.000000000 -0400
33186 ++++ linux-2.6.26.6/include/linux/moduleloader.h 2008-10-11 21:54:20.000000000 -0400
33187 +@@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
33188 + sections. Returns NULL on failure. */
33189 + void *module_alloc(unsigned long size);
33190 +
33191 ++#ifdef CONFIG_PAX_KERNEXEC
33192 ++void *module_alloc_exec(unsigned long size);
33193 ++#else
33194 ++#define module_alloc_exec(x) module_alloc(x)
33195 ++#endif
33196 ++
33197 + /* Free memory returned from module_alloc. */
33198 + void module_free(struct module *mod, void *module_region);
33199 +
33200 ++#ifdef CONFIG_PAX_KERNEXEC
33201 ++void module_free_exec(struct module *mod, void *module_region);
33202 ++#else
33203 ++#define module_free_exec(x, y) module_free(x, y)
33204 ++#endif
33205 ++
33206 + /* Apply the given relocation to the (simplified) ELF. Return -error
33207 + or 0. */
33208 + int apply_relocate(Elf_Shdr *sechdrs,
33209 +diff -urNp linux-2.6.26.6/include/linux/namei.h linux-2.6.26.6/include/linux/namei.h
33210 +--- linux-2.6.26.6/include/linux/namei.h 2008-10-08 23:24:05.000000000 -0400
33211 ++++ linux-2.6.26.6/include/linux/namei.h 2008-10-11 21:54:20.000000000 -0400
33212 +@@ -21,7 +21,7 @@ struct nameidata {
33213 + unsigned int flags;
33214 + int last_type;
33215 + unsigned depth;
33216 +- char *saved_names[MAX_NESTED_LINKS + 1];
33217 ++ const char *saved_names[MAX_NESTED_LINKS + 1];
33218 +
33219 + /* Intent data */
33220 + union {
33221 +@@ -83,12 +83,12 @@ extern int follow_up(struct vfsmount **,
33222 + extern struct dentry *lock_rename(struct dentry *, struct dentry *);
33223 + extern void unlock_rename(struct dentry *, struct dentry *);
33224 +
33225 +-static inline void nd_set_link(struct nameidata *nd, char *path)
33226 ++static inline void nd_set_link(struct nameidata *nd, const char *path)
33227 + {
33228 + nd->saved_names[nd->depth] = path;
33229 + }
33230 +
33231 +-static inline char *nd_get_link(struct nameidata *nd)
33232 ++static inline const char *nd_get_link(struct nameidata *nd)
33233 + {
33234 + return nd->saved_names[nd->depth];
33235 + }
33236 +diff -urNp linux-2.6.26.6/include/linux/nodemask.h linux-2.6.26.6/include/linux/nodemask.h
33237 +--- linux-2.6.26.6/include/linux/nodemask.h 2008-10-08 23:24:05.000000000 -0400
33238 ++++ linux-2.6.26.6/include/linux/nodemask.h 2008-10-11 21:55:52.000000000 -0400
33239 +@@ -442,11 +442,11 @@ static inline int num_node_state(enum no
33240 +
33241 + #define any_online_node(mask) \
33242 + ({ \
33243 +- int node; \
33244 +- for_each_node_mask(node, (mask)) \
33245 +- if (node_online(node)) \
33246 ++ int __node; \
33247 ++ for_each_node_mask(__node, (mask)) \
33248 ++ if (node_online(__node)) \
33249 + break; \
33250 +- node; \
33251 ++ __node; \
33252 + })
33253 +
33254 + #define num_online_nodes() num_node_state(N_ONLINE)
33255 +diff -urNp linux-2.6.26.6/include/linux/percpu.h linux-2.6.26.6/include/linux/percpu.h
33256 +--- linux-2.6.26.6/include/linux/percpu.h 2008-10-08 23:24:05.000000000 -0400
33257 ++++ linux-2.6.26.6/include/linux/percpu.h 2008-10-11 21:54:20.000000000 -0400
33258 +@@ -43,7 +43,7 @@
33259 + #endif
33260 +
33261 + #define PERCPU_ENOUGH_ROOM \
33262 +- (__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE)
33263 ++ ((unsigned long)(__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE))
33264 + #endif /* PERCPU_ENOUGH_ROOM */
33265 +
33266 + /*
33267 +diff -urNp linux-2.6.26.6/include/linux/poison.h linux-2.6.26.6/include/linux/poison.h
33268 +--- linux-2.6.26.6/include/linux/poison.h 2008-10-08 23:24:05.000000000 -0400
33269 ++++ linux-2.6.26.6/include/linux/poison.h 2008-10-11 21:54:20.000000000 -0400
33270 +@@ -7,8 +7,8 @@
33271 + * under normal circumstances, used to verify that nobody uses
33272 + * non-initialized list entries.
33273 + */
33274 +-#define LIST_POISON1 ((void *) 0x00100100)
33275 +-#define LIST_POISON2 ((void *) 0x00200200)
33276 ++#define LIST_POISON1 ((void *) 0xFF1001FFFF1001FFULL)
33277 ++#define LIST_POISON2 ((void *) 0xFF2002FFFF2002FFULL)
33278 +
33279 + /********** include/linux/timer.h **********/
33280 + /*
33281 +diff -urNp linux-2.6.26.6/include/linux/random.h linux-2.6.26.6/include/linux/random.h
33282 +--- linux-2.6.26.6/include/linux/random.h 2008-10-08 23:24:05.000000000 -0400
33283 ++++ linux-2.6.26.6/include/linux/random.h 2008-10-11 21:54:20.000000000 -0400
33284 +@@ -72,6 +72,11 @@ unsigned long randomize_range(unsigned l
33285 + u32 random32(void);
33286 + void srandom32(u32 seed);
33287 +
33288 ++static inline unsigned long pax_get_random_long(void)
33289 ++{
33290 ++ return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0);
33291 ++}
33292 ++
33293 + #endif /* __KERNEL___ */
33294 +
33295 + #endif /* _LINUX_RANDOM_H */
33296 +diff -urNp linux-2.6.26.6/include/linux/sched.h linux-2.6.26.6/include/linux/sched.h
33297 +--- linux-2.6.26.6/include/linux/sched.h 2008-10-08 23:24:05.000000000 -0400
33298 ++++ linux-2.6.26.6/include/linux/sched.h 2008-10-11 21:54:20.000000000 -0400
33299 +@@ -95,6 +95,7 @@ struct exec_domain;
33300 + struct futex_pi_state;
33301 + struct robust_list_head;
33302 + struct bio;
33303 ++struct linux_binprm;
33304 +
33305 + /*
33306 + * List of flags we want to share for kernel threads,
33307 +@@ -542,6 +543,15 @@ struct signal_struct {
33308 + unsigned audit_tty;
33309 + struct tty_audit_buf *tty_audit_buf;
33310 + #endif
33311 ++
33312 ++#ifdef CONFIG_GRKERNSEC
33313 ++ u32 curr_ip;
33314 ++ u32 gr_saddr;
33315 ++ u32 gr_daddr;
33316 ++ u16 gr_sport;
33317 ++ u16 gr_dport;
33318 ++ u8 used_accept:1;
33319 ++#endif
33320 + };
33321 +
33322 + /* Context switch must be unlocked if interrupts are to be enabled */
33323 +@@ -1025,7 +1035,7 @@ struct sched_rt_entity {
33324 +
33325 + struct task_struct {
33326 + volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
33327 +- void *stack;
33328 ++ struct thread_info *stack;
33329 + atomic_t usage;
33330 + unsigned int flags; /* per process flags, defined below */
33331 + unsigned int ptrace;
33332 +@@ -1095,10 +1105,9 @@ struct task_struct {
33333 + pid_t pid;
33334 + pid_t tgid;
33335 +
33336 +-#ifdef CONFIG_CC_STACKPROTECTOR
33337 + /* Canary value for the -fstack-protector gcc feature */
33338 + unsigned long stack_canary;
33339 +-#endif
33340 ++
33341 + /*
33342 + * pointers to (original) parent process, youngest child, younger sibling,
33343 + * older sibling, respectively. (p->father can be replaced with
33344 +@@ -1119,8 +1128,8 @@ struct task_struct {
33345 + struct list_head thread_group;
33346 +
33347 + struct completion *vfork_done; /* for vfork() */
33348 +- int __user *set_child_tid; /* CLONE_CHILD_SETTID */
33349 +- int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
33350 ++ pid_t __user *set_child_tid; /* CLONE_CHILD_SETTID */
33351 ++ pid_t __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
33352 +
33353 + unsigned int rt_priority;
33354 + cputime_t utime, stime, utimescaled, stimescaled;
33355 +@@ -1303,8 +1312,64 @@ struct task_struct {
33356 + int latency_record_count;
33357 + struct latency_record latency_record[LT_SAVECOUNT];
33358 + #endif
33359 ++
33360 ++#ifdef CONFIG_GRKERNSEC
33361 ++ /* grsecurity */
33362 ++ struct acl_subject_label *acl;
33363 ++ struct acl_role_label *role;
33364 ++ struct file *exec_file;
33365 ++ u16 acl_role_id;
33366 ++ u8 acl_sp_role;
33367 ++ u8 is_writable;
33368 ++ u8 brute;
33369 ++#endif
33370 ++
33371 + };
33372 +
33373 ++#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
33374 ++#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
33375 ++#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
33376 ++#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
33377 ++/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */
33378 ++#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
33379 ++
33380 ++#ifdef CONFIG_PAX_SOFTMODE
33381 ++extern unsigned int pax_softmode;
33382 ++#endif
33383 ++
33384 ++extern int pax_check_flags(unsigned long *);
33385 ++
33386 ++/* if tsk != current then task_lock must be held on it */
33387 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
33388 ++static inline unsigned long pax_get_flags(struct task_struct *tsk)
33389 ++{
33390 ++ if (likely(tsk->mm))
33391 ++ return tsk->mm->pax_flags;
33392 ++ else
33393 ++ return 0UL;
33394 ++}
33395 ++
33396 ++/* if tsk != current then task_lock must be held on it */
33397 ++static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
33398 ++{
33399 ++ if (likely(tsk->mm)) {
33400 ++ tsk->mm->pax_flags = flags;
33401 ++ return 0;
33402 ++ }
33403 ++ return -EINVAL;
33404 ++}
33405 ++#endif
33406 ++
33407 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
33408 ++extern void pax_set_initial_flags(struct linux_binprm *bprm);
33409 ++#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
33410 ++extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
33411 ++#endif
33412 ++
33413 ++void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
33414 ++void pax_report_insns(void *pc, void *sp);
33415 ++void pax_report_refcount_overflow(struct pt_regs *regs);
33416 ++
33417 + /*
33418 + * Priority of a process goes from 0..MAX_PRIO-1, valid RT
33419 + * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
33420 +@@ -1855,7 +1920,7 @@ extern void __cleanup_sighand(struct sig
33421 + extern void exit_itimers(struct signal_struct *);
33422 + extern void flush_itimer_signals(void);
33423 +
33424 +-extern NORET_TYPE void do_group_exit(int);
33425 ++extern NORET_TYPE void do_group_exit(int) ATTRIB_NORET;
33426 +
33427 + extern void daemonize(const char *, ...);
33428 + extern int allow_signal(int);
33429 +@@ -1957,8 +2022,8 @@ static inline void unlock_task_sighand(s
33430 +
33431 + #ifndef __HAVE_THREAD_FUNCTIONS
33432 +
33433 +-#define task_thread_info(task) ((struct thread_info *)(task)->stack)
33434 +-#define task_stack_page(task) ((task)->stack)
33435 ++#define task_thread_info(task) ((task)->stack)
33436 ++#define task_stack_page(task) ((void *)(task)->stack)
33437 +
33438 + static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
33439 + {
33440 +@@ -2130,6 +2195,12 @@ extern void arch_pick_mmap_layout(struct
33441 + static inline void arch_pick_mmap_layout(struct mm_struct *mm)
33442 + {
33443 + mm->mmap_base = TASK_UNMAPPED_BASE;
33444 ++
33445 ++#ifdef CONFIG_PAX_RANDMMAP
33446 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
33447 ++ mm->mmap_base += mm->delta_mmap;
33448 ++#endif
33449 ++
33450 + mm->get_unmapped_area = arch_get_unmapped_area;
33451 + mm->unmap_area = arch_unmap_area;
33452 + }
33453 +diff -urNp linux-2.6.26.6/include/linux/screen_info.h linux-2.6.26.6/include/linux/screen_info.h
33454 +--- linux-2.6.26.6/include/linux/screen_info.h 2008-10-08 23:24:05.000000000 -0400
33455 ++++ linux-2.6.26.6/include/linux/screen_info.h 2008-10-11 21:54:20.000000000 -0400
33456 +@@ -42,7 +42,8 @@ struct screen_info {
33457 + __u16 pages; /* 0x32 */
33458 + __u16 vesa_attributes; /* 0x34 */
33459 + __u32 capabilities; /* 0x36 */
33460 +- __u8 _reserved[6]; /* 0x3a */
33461 ++ __u16 vesapm_size; /* 0x3a */
33462 ++ __u8 _reserved[4]; /* 0x3c */
33463 + } __attribute__((packed));
33464 +
33465 + #define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
33466 +diff -urNp linux-2.6.26.6/include/linux/shm.h linux-2.6.26.6/include/linux/shm.h
33467 +--- linux-2.6.26.6/include/linux/shm.h 2008-10-08 23:24:05.000000000 -0400
33468 ++++ linux-2.6.26.6/include/linux/shm.h 2008-10-11 21:54:20.000000000 -0400
33469 +@@ -95,6 +95,10 @@ struct shmid_kernel /* private to the ke
33470 + pid_t shm_cprid;
33471 + pid_t shm_lprid;
33472 + struct user_struct *mlock_user;
33473 ++#ifdef CONFIG_GRKERNSEC
33474 ++ time_t shm_createtime;
33475 ++ pid_t shm_lapid;
33476 ++#endif
33477 + };
33478 +
33479 + /* shm_mode upper byte flags */
33480 +diff -urNp linux-2.6.26.6/include/linux/slab.h linux-2.6.26.6/include/linux/slab.h
33481 +--- linux-2.6.26.6/include/linux/slab.h 2008-10-08 23:24:05.000000000 -0400
33482 ++++ linux-2.6.26.6/include/linux/slab.h 2008-10-11 21:54:20.000000000 -0400
33483 +@@ -45,10 +45,9 @@
33484 + * ZERO_SIZE_PTR can be passed to kfree though in the same way that NULL can.
33485 + * Both make kfree a no-op.
33486 + */
33487 +-#define ZERO_SIZE_PTR ((void *)16)
33488 ++#define ZERO_SIZE_PTR ((void *)-1024L)
33489 +
33490 +-#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= \
33491 +- (unsigned long)ZERO_SIZE_PTR)
33492 ++#define ZERO_OR_NULL_PTR(x) (!(x) || (x) == ZERO_SIZE_PTR)
33493 +
33494 + /*
33495 + * struct kmem_cache related prototypes
33496 +diff -urNp linux-2.6.26.6/include/linux/sysctl.h linux-2.6.26.6/include/linux/sysctl.h
33497 +--- linux-2.6.26.6/include/linux/sysctl.h 2008-10-08 23:24:05.000000000 -0400
33498 ++++ linux-2.6.26.6/include/linux/sysctl.h 2008-10-11 21:54:20.000000000 -0400
33499 +@@ -163,9 +163,21 @@ enum
33500 + KERN_MAX_LOCK_DEPTH=74,
33501 + KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */
33502 + KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
33503 +-};
33504 ++#ifdef CONFIG_GRKERNSEC
33505 ++ KERN_GRSECURITY=98, /* grsecurity */
33506 ++#endif
33507 ++
33508 ++#ifdef CONFIG_PAX_SOFTMODE
33509 ++ KERN_PAX=99, /* PaX control */
33510 ++#endif
33511 +
33512 ++};
33513 +
33514 ++#ifdef CONFIG_PAX_SOFTMODE
33515 ++enum {
33516 ++ PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */
33517 ++};
33518 ++#endif
33519 +
33520 + /* CTL_VM names: */
33521 + enum
33522 +diff -urNp linux-2.6.26.6/include/linux/thread_info.h linux-2.6.26.6/include/linux/thread_info.h
33523 +--- linux-2.6.26.6/include/linux/thread_info.h 2008-10-08 23:24:05.000000000 -0400
33524 ++++ linux-2.6.26.6/include/linux/thread_info.h 2008-10-11 21:55:52.000000000 -0400
33525 +@@ -23,7 +23,7 @@ struct restart_block {
33526 + };
33527 + /* For futex_wait */
33528 + struct {
33529 +- u32 *uaddr;
33530 ++ u32 __user *uaddr;
33531 + u32 val;
33532 + u32 flags;
33533 + u32 bitset;
33534 +diff -urNp linux-2.6.26.6/include/linux/uaccess.h linux-2.6.26.6/include/linux/uaccess.h
33535 +--- linux-2.6.26.6/include/linux/uaccess.h 2008-10-08 23:24:05.000000000 -0400
33536 ++++ linux-2.6.26.6/include/linux/uaccess.h 2008-10-11 21:54:20.000000000 -0400
33537 +@@ -76,11 +76,11 @@ static inline unsigned long __copy_from_
33538 + long ret; \
33539 + mm_segment_t old_fs = get_fs(); \
33540 + \
33541 +- set_fs(KERNEL_DS); \
33542 + pagefault_disable(); \
33543 ++ set_fs(KERNEL_DS); \
33544 + ret = __get_user(retval, (__force typeof(retval) __user *)(addr)); \
33545 +- pagefault_enable(); \
33546 + set_fs(old_fs); \
33547 ++ pagefault_enable(); \
33548 + ret; \
33549 + })
33550 +
33551 +diff -urNp linux-2.6.26.6/include/net/sctp/sctp.h linux-2.6.26.6/include/net/sctp/sctp.h
33552 +--- linux-2.6.26.6/include/net/sctp/sctp.h 2008-10-08 23:24:05.000000000 -0400
33553 ++++ linux-2.6.26.6/include/net/sctp/sctp.h 2008-10-11 21:54:20.000000000 -0400
33554 +@@ -309,8 +309,8 @@ extern int sctp_debug_flag;
33555 +
33556 + #else /* SCTP_DEBUG */
33557 +
33558 +-#define SCTP_DEBUG_PRINTK(whatever...)
33559 +-#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
33560 ++#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
33561 ++#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
33562 + #define SCTP_ENABLE_DEBUG
33563 + #define SCTP_DISABLE_DEBUG
33564 + #define SCTP_ASSERT(expr, str, func)
33565 +diff -urNp linux-2.6.26.6/include/sound/core.h linux-2.6.26.6/include/sound/core.h
33566 +--- linux-2.6.26.6/include/sound/core.h 2008-10-08 23:24:05.000000000 -0400
33567 ++++ linux-2.6.26.6/include/sound/core.h 2008-10-11 21:54:20.000000000 -0400
33568 +@@ -406,9 +406,9 @@ void snd_verbose_printd(const char *file
33569 +
33570 + #else /* !CONFIG_SND_DEBUG */
33571 +
33572 +-#define snd_printd(fmt, args...) /* nothing */
33573 ++#define snd_printd(fmt, args...) do {} while (0)
33574 + #define snd_assert(expr, args...) (void)(expr)
33575 +-#define snd_BUG() /* nothing */
33576 ++#define snd_BUG() do {} while (0)
33577 +
33578 + #endif /* CONFIG_SND_DEBUG */
33579 +
33580 +@@ -422,7 +422,7 @@ void snd_verbose_printd(const char *file
33581 + */
33582 + #define snd_printdd(format, args...) snd_printk(format, ##args)
33583 + #else
33584 +-#define snd_printdd(format, args...) /* nothing */
33585 ++#define snd_printdd(format, args...) do {} while (0)
33586 + #endif
33587 +
33588 +
33589 +diff -urNp linux-2.6.26.6/include/video/uvesafb.h linux-2.6.26.6/include/video/uvesafb.h
33590 +--- linux-2.6.26.6/include/video/uvesafb.h 2008-10-08 23:24:05.000000000 -0400
33591 ++++ linux-2.6.26.6/include/video/uvesafb.h 2008-10-11 21:54:20.000000000 -0400
33592 +@@ -175,6 +175,7 @@ struct uvesafb_par {
33593 + u8 ypan; /* 0 - nothing, 1 - ypan, 2 - ywrap */
33594 + u8 pmi_setpal; /* PMI for palette changes */
33595 + u16 *pmi_base; /* protected mode interface location */
33596 ++ u8 *pmi_code; /* protected mode code location */
33597 + void *pmi_start;
33598 + void *pmi_pal;
33599 + u8 *vbe_state_orig; /*
33600 +diff -urNp linux-2.6.26.6/init/do_mounts.c linux-2.6.26.6/init/do_mounts.c
33601 +--- linux-2.6.26.6/init/do_mounts.c 2008-10-08 23:24:05.000000000 -0400
33602 ++++ linux-2.6.26.6/init/do_mounts.c 2008-10-11 21:54:20.000000000 -0400
33603 +@@ -213,11 +213,11 @@ static void __init get_fs_names(char *pa
33604 +
33605 + static int __init do_mount_root(char *name, char *fs, int flags, void *data)
33606 + {
33607 +- int err = sys_mount(name, "/root", fs, flags, data);
33608 ++ int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data);
33609 + if (err)
33610 + return err;
33611 +
33612 +- sys_chdir("/root");
33613 ++ sys_chdir((char __user *)"/root");
33614 + ROOT_DEV = current->fs->pwd.mnt->mnt_sb->s_dev;
33615 + printk("VFS: Mounted root (%s filesystem)%s.\n",
33616 + current->fs->pwd.mnt->mnt_sb->s_type->name,
33617 +@@ -303,18 +303,18 @@ void __init change_floppy(char *fmt, ...
33618 + va_start(args, fmt);
33619 + vsprintf(buf, fmt, args);
33620 + va_end(args);
33621 +- fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
33622 ++ fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
33623 + if (fd >= 0) {
33624 + sys_ioctl(fd, FDEJECT, 0);
33625 + sys_close(fd);
33626 + }
33627 + printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
33628 +- fd = sys_open("/dev/console", O_RDWR, 0);
33629 ++ fd = sys_open((char __user *)"/dev/console", O_RDWR, 0);
33630 + if (fd >= 0) {
33631 + sys_ioctl(fd, TCGETS, (long)&termios);
33632 + termios.c_lflag &= ~ICANON;
33633 + sys_ioctl(fd, TCSETSF, (long)&termios);
33634 +- sys_read(fd, &c, 1);
33635 ++ sys_read(fd, (char __user *)&c, 1);
33636 + termios.c_lflag |= ICANON;
33637 + sys_ioctl(fd, TCSETSF, (long)&termios);
33638 + sys_close(fd);
33639 +@@ -400,7 +400,7 @@ void __init prepare_namespace(void)
33640 +
33641 + mount_root();
33642 + out:
33643 +- sys_mount(".", "/", NULL, MS_MOVE, NULL);
33644 +- sys_chroot(".");
33645 ++ sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
33646 ++ sys_chroot((char __user *)".");
33647 + }
33648 +
33649 +diff -urNp linux-2.6.26.6/init/do_mounts.h linux-2.6.26.6/init/do_mounts.h
33650 +--- linux-2.6.26.6/init/do_mounts.h 2008-10-08 23:24:05.000000000 -0400
33651 ++++ linux-2.6.26.6/init/do_mounts.h 2008-10-11 21:54:20.000000000 -0400
33652 +@@ -15,15 +15,15 @@ extern char *root_device_name;
33653 +
33654 + static inline int create_dev(char *name, dev_t dev)
33655 + {
33656 +- sys_unlink(name);
33657 +- return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
33658 ++ sys_unlink((char __user *)name);
33659 ++ return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
33660 + }
33661 +
33662 + #if BITS_PER_LONG == 32
33663 + static inline u32 bstat(char *name)
33664 + {
33665 + struct stat64 stat;
33666 +- if (sys_stat64(name, &stat) != 0)
33667 ++ if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0)
33668 + return 0;
33669 + if (!S_ISBLK(stat.st_mode))
33670 + return 0;
33671 +diff -urNp linux-2.6.26.6/init/do_mounts_initrd.c linux-2.6.26.6/init/do_mounts_initrd.c
33672 +--- linux-2.6.26.6/init/do_mounts_initrd.c 2008-10-08 23:24:05.000000000 -0400
33673 ++++ linux-2.6.26.6/init/do_mounts_initrd.c 2008-10-11 21:55:52.000000000 -0400
33674 +@@ -32,7 +32,7 @@ static int __init do_linuxrc(void * shel
33675 + sys_close(old_fd);sys_close(root_fd);
33676 + sys_close(0);sys_close(1);sys_close(2);
33677 + sys_setsid();
33678 +- (void) sys_open("/dev/console",O_RDWR,0);
33679 ++ (void) sys_open((const char __user *)"/dev/console",O_RDWR,0);
33680 + (void) sys_dup(0);
33681 + (void) sys_dup(0);
33682 + return kernel_execve(shell, argv, envp_init);
33683 +@@ -47,13 +47,13 @@ static void __init handle_initrd(void)
33684 + create_dev("/dev/root.old", Root_RAM0);
33685 + /* mount initrd on rootfs' /root */
33686 + mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
33687 +- sys_mkdir("/old", 0700);
33688 +- root_fd = sys_open("/", 0, 0);
33689 +- old_fd = sys_open("/old", 0, 0);
33690 ++ sys_mkdir((const char __user *)"/old", 0700);
33691 ++ root_fd = sys_open((const char __user *)"/", 0, 0);
33692 ++ old_fd = sys_open((const char __user *)"/old", 0, 0);
33693 + /* move initrd over / and chdir/chroot in initrd root */
33694 +- sys_chdir("/root");
33695 +- sys_mount(".", "/", NULL, MS_MOVE, NULL);
33696 +- sys_chroot(".");
33697 ++ sys_chdir((const char __user *)"/root");
33698 ++ sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
33699 ++ sys_chroot((const char __user *)".");
33700 +
33701 + /*
33702 + * In case that a resume from disk is carried out by linuxrc or one of
33703 +@@ -70,15 +70,15 @@ static void __init handle_initrd(void)
33704 +
33705 + /* move initrd to rootfs' /old */
33706 + sys_fchdir(old_fd);
33707 +- sys_mount("/", ".", NULL, MS_MOVE, NULL);
33708 ++ sys_mount((char __user *)"/", (char __user *)".", NULL, MS_MOVE, NULL);
33709 + /* switch root and cwd back to / of rootfs */
33710 + sys_fchdir(root_fd);
33711 +- sys_chroot(".");
33712 ++ sys_chroot((const char __user *)".");
33713 + sys_close(old_fd);
33714 + sys_close(root_fd);
33715 +
33716 + if (new_decode_dev(real_root_dev) == Root_RAM0) {
33717 +- sys_chdir("/old");
33718 ++ sys_chdir((const char __user *)"/old");
33719 + return;
33720 + }
33721 +
33722 +@@ -86,17 +86,17 @@ static void __init handle_initrd(void)
33723 + mount_root();
33724 +
33725 + printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
33726 +- error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
33727 ++ error = sys_mount((char __user *)"/old", (char __user *)"/root/initrd", NULL, MS_MOVE, NULL);
33728 + if (!error)
33729 + printk("okay\n");
33730 + else {
33731 +- int fd = sys_open("/dev/root.old", O_RDWR, 0);
33732 ++ int fd = sys_open((const char __user *)"/dev/root.old", O_RDWR, 0);
33733 + if (error == -ENOENT)
33734 + printk("/initrd does not exist. Ignored.\n");
33735 + else
33736 + printk("failed\n");
33737 + printk(KERN_NOTICE "Unmounting old root\n");
33738 +- sys_umount("/old", MNT_DETACH);
33739 ++ sys_umount((char __user *)"/old", MNT_DETACH);
33740 + printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
33741 + if (fd < 0) {
33742 + error = fd;
33743 +@@ -119,11 +119,11 @@ int __init initrd_load(void)
33744 + * mounted in the normal path.
33745 + */
33746 + if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) {
33747 +- sys_unlink("/initrd.image");
33748 ++ sys_unlink((const char __user *)"/initrd.image");
33749 + handle_initrd();
33750 + return 1;
33751 + }
33752 + }
33753 +- sys_unlink("/initrd.image");
33754 ++ sys_unlink((const char __user *)"/initrd.image");
33755 + return 0;
33756 + }
33757 +diff -urNp linux-2.6.26.6/init/do_mounts_md.c linux-2.6.26.6/init/do_mounts_md.c
33758 +--- linux-2.6.26.6/init/do_mounts_md.c 2008-10-08 23:24:05.000000000 -0400
33759 ++++ linux-2.6.26.6/init/do_mounts_md.c 2008-10-11 21:54:20.000000000 -0400
33760 +@@ -166,7 +166,7 @@ static void __init md_setup_drive(void)
33761 + partitioned ? "_d" : "", minor,
33762 + md_setup_args[ent].device_names);
33763 +
33764 +- fd = sys_open(name, 0, 0);
33765 ++ fd = sys_open((char __user *)name, 0, 0);
33766 + if (fd < 0) {
33767 + printk(KERN_ERR "md: open failed - cannot start "
33768 + "array %s\n", name);
33769 +@@ -229,7 +229,7 @@ static void __init md_setup_drive(void)
33770 + * array without it
33771 + */
33772 + sys_close(fd);
33773 +- fd = sys_open(name, 0, 0);
33774 ++ fd = sys_open((char __user *)name, 0, 0);
33775 + sys_ioctl(fd, BLKRRPART, 0);
33776 + }
33777 + sys_close(fd);
33778 +@@ -270,7 +270,7 @@ void __init md_run_setup(void)
33779 + if (raid_noautodetect)
33780 + printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
33781 + else {
33782 +- int fd = sys_open("/dev/md0", 0, 0);
33783 ++ int fd = sys_open((char __user *)"/dev/md0", 0, 0);
33784 + if (fd >= 0) {
33785 + sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
33786 + sys_close(fd);
33787 +diff -urNp linux-2.6.26.6/init/initramfs.c linux-2.6.26.6/init/initramfs.c
33788 +--- linux-2.6.26.6/init/initramfs.c 2008-10-08 23:24:05.000000000 -0400
33789 ++++ linux-2.6.26.6/init/initramfs.c 2008-10-11 21:54:20.000000000 -0400
33790 +@@ -240,7 +240,7 @@ static int __init maybe_link(void)
33791 + if (nlink >= 2) {
33792 + char *old = find_link(major, minor, ino, mode, collected);
33793 + if (old)
33794 +- return (sys_link(old, collected) < 0) ? -1 : 1;
33795 ++ return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1;
33796 + }
33797 + return 0;
33798 + }
33799 +@@ -249,11 +249,11 @@ static void __init clean_path(char *path
33800 + {
33801 + struct stat st;
33802 +
33803 +- if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
33804 ++ if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
33805 + if (S_ISDIR(st.st_mode))
33806 +- sys_rmdir(path);
33807 ++ sys_rmdir((char __user *)path);
33808 + else
33809 +- sys_unlink(path);
33810 ++ sys_unlink((char __user *)path);
33811 + }
33812 + }
33813 +
33814 +@@ -276,7 +276,7 @@ static int __init do_name(void)
33815 + int openflags = O_WRONLY|O_CREAT;
33816 + if (ml != 1)
33817 + openflags |= O_TRUNC;
33818 +- wfd = sys_open(collected, openflags, mode);
33819 ++ wfd = sys_open((char __user *)collected, openflags, mode);
33820 +
33821 + if (wfd >= 0) {
33822 + sys_fchown(wfd, uid, gid);
33823 +@@ -285,15 +285,15 @@ static int __init do_name(void)
33824 + }
33825 + }
33826 + } else if (S_ISDIR(mode)) {
33827 +- sys_mkdir(collected, mode);
33828 +- sys_chown(collected, uid, gid);
33829 +- sys_chmod(collected, mode);
33830 ++ sys_mkdir((char __user *)collected, mode);
33831 ++ sys_chown((char __user *)collected, uid, gid);
33832 ++ sys_chmod((char __user *)collected, mode);
33833 + } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
33834 + S_ISFIFO(mode) || S_ISSOCK(mode)) {
33835 + if (maybe_link() == 0) {
33836 +- sys_mknod(collected, mode, rdev);
33837 +- sys_chown(collected, uid, gid);
33838 +- sys_chmod(collected, mode);
33839 ++ sys_mknod((char __user *)collected, mode, rdev);
33840 ++ sys_chown((char __user *)collected, uid, gid);
33841 ++ sys_chmod((char __user *)collected, mode);
33842 + }
33843 + }
33844 + return 0;
33845 +@@ -302,13 +302,13 @@ static int __init do_name(void)
33846 + static int __init do_copy(void)
33847 + {
33848 + if (count >= body_len) {
33849 +- sys_write(wfd, victim, body_len);
33850 ++ sys_write(wfd, (char __user *)victim, body_len);
33851 + sys_close(wfd);
33852 + eat(body_len);
33853 + state = SkipIt;
33854 + return 0;
33855 + } else {
33856 +- sys_write(wfd, victim, count);
33857 ++ sys_write(wfd, (char __user *)victim, count);
33858 + body_len -= count;
33859 + eat(count);
33860 + return 1;
33861 +@@ -319,8 +319,8 @@ static int __init do_symlink(void)
33862 + {
33863 + collected[N_ALIGN(name_len) + body_len] = '\0';
33864 + clean_path(collected, 0);
33865 +- sys_symlink(collected + N_ALIGN(name_len), collected);
33866 +- sys_lchown(collected, uid, gid);
33867 ++ sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected);
33868 ++ sys_lchown((char __user *)collected, uid, gid);
33869 + state = SkipIt;
33870 + next_state = Reset;
33871 + return 0;
33872 +diff -urNp linux-2.6.26.6/init/Kconfig linux-2.6.26.6/init/Kconfig
33873 +--- linux-2.6.26.6/init/Kconfig 2008-10-08 23:24:05.000000000 -0400
33874 ++++ linux-2.6.26.6/init/Kconfig 2008-10-11 21:54:20.000000000 -0400
33875 +@@ -572,6 +572,7 @@ config SYSCTL_SYSCALL_CHECK
33876 + config KALLSYMS
33877 + bool "Load all symbols for debugging/ksymoops" if EMBEDDED
33878 + default y
33879 ++ depends on !GRKERNSEC_HIDESYM
33880 + help
33881 + Say Y here to let the kernel print out symbolic crash information and
33882 + symbolic stack backtraces. This increases the size of the kernel
33883 +@@ -791,8 +792,8 @@ config MARKERS
33884 + source "arch/Kconfig"
33885 +
33886 + config PROC_PAGE_MONITOR
33887 +- default y
33888 +- depends on PROC_FS && MMU
33889 ++ default n
33890 ++ depends on PROC_FS && MMU && !GRKERNSEC
33891 + bool "Enable /proc page monitoring" if EMBEDDED
33892 + help
33893 + Various /proc files exist to monitor process memory utilization:
33894 +@@ -804,9 +805,9 @@ endmenu # General setup
33895 +
33896 + config SLABINFO
33897 + bool
33898 +- depends on PROC_FS
33899 ++ depends on PROC_FS && !GRKERNSEC_PROC_ADD
33900 + depends on SLAB || SLUB_DEBUG
33901 +- default y
33902 ++ default n
33903 +
33904 + config RT_MUTEXES
33905 + boolean
33906 +diff -urNp linux-2.6.26.6/init/main.c linux-2.6.26.6/init/main.c
33907 +--- linux-2.6.26.6/init/main.c 2008-10-08 23:24:05.000000000 -0400
33908 ++++ linux-2.6.26.6/init/main.c 2008-10-11 21:54:20.000000000 -0400
33909 +@@ -103,6 +103,7 @@ static inline void mark_rodata_ro(void)
33910 + #ifdef CONFIG_TC
33911 + extern void tc_init(void);
33912 + #endif
33913 ++extern void grsecurity_init(void);
33914 +
33915 + enum system_states system_state;
33916 + EXPORT_SYMBOL(system_state);
33917 +@@ -189,6 +190,40 @@ static int __init set_reset_devices(char
33918 +
33919 + __setup("reset_devices", set_reset_devices);
33920 +
33921 ++#if defined(CONFIG_PAX_MEMORY_UDEREF) && defined(CONFIG_X86_32)
33922 ++static int __init setup_pax_nouderef(char *str)
33923 ++{
33924 ++ unsigned int cpu;
33925 ++
33926 ++#ifdef CONFIG_PAX_KERNEXEC
33927 ++ unsigned long cr0;
33928 ++
33929 ++ pax_open_kernel(cr0);
33930 ++#endif
33931 ++
33932 ++ for (cpu = 0; cpu < NR_CPUS; cpu++)
33933 ++ get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_DS].b = 0x00cf9300;
33934 ++
33935 ++#ifdef CONFIG_PAX_KERNEXEC
33936 ++ pax_close_kernel(cr0);
33937 ++#endif
33938 ++
33939 ++ return 1;
33940 ++}
33941 ++__setup("pax_nouderef", setup_pax_nouderef);
33942 ++#endif
33943 ++
33944 ++#ifdef CONFIG_PAX_SOFTMODE
33945 ++unsigned int pax_softmode;
33946 ++
33947 ++static int __init setup_pax_softmode(char *str)
33948 ++{
33949 ++ get_option(&str, &pax_softmode);
33950 ++ return 1;
33951 ++}
33952 ++__setup("pax_softmode=", setup_pax_softmode);
33953 ++#endif
33954 ++
33955 + static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
33956 + char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
33957 + static const char *panic_later, *panic_param;
33958 +@@ -387,7 +422,7 @@ static void __init setup_nr_cpu_ids(void
33959 + }
33960 +
33961 + #ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
33962 +-unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
33963 ++unsigned long __per_cpu_offset[NR_CPUS] __read_only;
33964 +
33965 + EXPORT_SYMBOL(__per_cpu_offset);
33966 +
33967 +@@ -697,6 +732,7 @@ static void __init do_one_initcall(initc
33968 + {
33969 + int count = preempt_count();
33970 + ktime_t t0, t1, delta;
33971 ++ const char *msg1 = "", *msg2 = "";
33972 + char msgbuf[64];
33973 + int result;
33974 +
33975 +@@ -722,16 +758,16 @@ static void __init do_one_initcall(initc
33976 + sprintf(msgbuf, "error code %d ", result);
33977 +
33978 + if (preempt_count() != count) {
33979 +- strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf));
33980 ++ msg1 = " preemption imbalance";
33981 + preempt_count() = count;
33982 + }
33983 + if (irqs_disabled()) {
33984 +- strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf));
33985 ++ msg2 = " disabled interrupts";
33986 + local_irq_enable();
33987 + }
33988 +- if (msgbuf[0]) {
33989 ++ if (msgbuf[0] || *msg1 || *msg2) {
33990 + print_fn_descriptor_symbol(KERN_WARNING "initcall %s", fn);
33991 +- printk(" returned with %s\n", msgbuf);
33992 ++ printk(" returned with %s%s%s\n", msgbuf, msg1, msg2);
33993 + }
33994 + }
33995 +
33996 +@@ -878,6 +914,8 @@ static int __init kernel_init(void * unu
33997 + prepare_namespace();
33998 + }
33999 +
34000 ++ grsecurity_init();
34001 ++
34002 + /*
34003 + * Ok, we have completed the initial bootup, and
34004 + * we're essentially up and running. Get rid of the
34005 +diff -urNp linux-2.6.26.6/init/noinitramfs.c linux-2.6.26.6/init/noinitramfs.c
34006 +--- linux-2.6.26.6/init/noinitramfs.c 2008-10-08 23:24:05.000000000 -0400
34007 ++++ linux-2.6.26.6/init/noinitramfs.c 2008-10-11 21:54:20.000000000 -0400
34008 +@@ -29,7 +29,7 @@ static int __init default_rootfs(void)
34009 + {
34010 + int err;
34011 +
34012 +- err = sys_mkdir("/dev", 0755);
34013 ++ err = sys_mkdir((const char __user *)"/dev", 0755);
34014 + if (err < 0)
34015 + goto out;
34016 +
34017 +@@ -39,7 +39,7 @@ static int __init default_rootfs(void)
34018 + if (err < 0)
34019 + goto out;
34020 +
34021 +- err = sys_mkdir("/root", 0700);
34022 ++ err = sys_mkdir((const char __user *)"/root", 0700);
34023 + if (err < 0)
34024 + goto out;
34025 +
34026 +diff -urNp linux-2.6.26.6/ipc/ipc_sysctl.c linux-2.6.26.6/ipc/ipc_sysctl.c
34027 +--- linux-2.6.26.6/ipc/ipc_sysctl.c 2008-10-08 23:24:05.000000000 -0400
34028 ++++ linux-2.6.26.6/ipc/ipc_sysctl.c 2008-10-11 21:54:20.000000000 -0400
34029 +@@ -222,7 +222,7 @@ static struct ctl_table ipc_kern_table[]
34030 + .proc_handler = proc_ipc_dointvec,
34031 + .strategy = sysctl_ipc_data,
34032 + },
34033 +- {}
34034 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
34035 + };
34036 +
34037 + static struct ctl_table ipc_root_table[] = {
34038 +@@ -232,7 +232,7 @@ static struct ctl_table ipc_root_table[]
34039 + .mode = 0555,
34040 + .child = ipc_kern_table,
34041 + },
34042 +- {}
34043 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
34044 + };
34045 +
34046 + static int __init ipc_sysctl_init(void)
34047 +diff -urNp linux-2.6.26.6/ipc/msg.c linux-2.6.26.6/ipc/msg.c
34048 +--- linux-2.6.26.6/ipc/msg.c 2008-10-08 23:24:05.000000000 -0400
34049 ++++ linux-2.6.26.6/ipc/msg.c 2008-10-11 21:54:20.000000000 -0400
34050 +@@ -38,6 +38,7 @@
34051 + #include <linux/rwsem.h>
34052 + #include <linux/nsproxy.h>
34053 + #include <linux/ipc_namespace.h>
34054 ++#include <linux/grsecurity.h>
34055 +
34056 + #include <asm/current.h>
34057 + #include <asm/uaccess.h>
34058 +@@ -314,6 +315,7 @@ asmlinkage long sys_msgget(key_t key, in
34059 + struct ipc_namespace *ns;
34060 + struct ipc_ops msg_ops;
34061 + struct ipc_params msg_params;
34062 ++ long err;
34063 +
34064 + ns = current->nsproxy->ipc_ns;
34065 +
34066 +@@ -324,7 +326,11 @@ asmlinkage long sys_msgget(key_t key, in
34067 + msg_params.key = key;
34068 + msg_params.flg = msgflg;
34069 +
34070 +- return ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
34071 ++ err = ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
34072 ++
34073 ++ gr_log_msgget(err, msgflg);
34074 ++
34075 ++ return err;
34076 + }
34077 +
34078 + static inline unsigned long
34079 +@@ -434,6 +440,7 @@ static int msgctl_down(struct ipc_namesp
34080 +
34081 + switch (cmd) {
34082 + case IPC_RMID:
34083 ++ gr_log_msgrm(ipcp->uid, ipcp->cuid);
34084 + freeque(ns, ipcp);
34085 + goto out_up;
34086 + case IPC_SET:
34087 +diff -urNp linux-2.6.26.6/ipc/sem.c linux-2.6.26.6/ipc/sem.c
34088 +--- linux-2.6.26.6/ipc/sem.c 2008-10-08 23:24:05.000000000 -0400
34089 ++++ linux-2.6.26.6/ipc/sem.c 2008-10-11 21:54:20.000000000 -0400
34090 +@@ -83,6 +83,7 @@
34091 + #include <linux/rwsem.h>
34092 + #include <linux/nsproxy.h>
34093 + #include <linux/ipc_namespace.h>
34094 ++#include <linux/grsecurity.h>
34095 +
34096 + #include <asm/uaccess.h>
34097 + #include "util.h"
34098 +@@ -314,6 +315,7 @@ asmlinkage long sys_semget(key_t key, in
34099 + struct ipc_namespace *ns;
34100 + struct ipc_ops sem_ops;
34101 + struct ipc_params sem_params;
34102 ++ long err;
34103 +
34104 + ns = current->nsproxy->ipc_ns;
34105 +
34106 +@@ -328,7 +330,11 @@ asmlinkage long sys_semget(key_t key, in
34107 + sem_params.flg = semflg;
34108 + sem_params.u.nsems = nsems;
34109 +
34110 +- return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
34111 ++ err = ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
34112 ++
34113 ++ gr_log_semget(err, semflg);
34114 ++
34115 ++ return err;
34116 + }
34117 +
34118 + /* Manage the doubly linked list sma->sem_pending as a FIFO:
34119 +@@ -876,6 +882,7 @@ static int semctl_down(struct ipc_namesp
34120 +
34121 + switch(cmd){
34122 + case IPC_RMID:
34123 ++ gr_log_semrm(ipcp->uid, ipcp->cuid);
34124 + freeary(ns, ipcp);
34125 + goto out_up;
34126 + case IPC_SET:
34127 +diff -urNp linux-2.6.26.6/ipc/shm.c linux-2.6.26.6/ipc/shm.c
34128 +--- linux-2.6.26.6/ipc/shm.c 2008-10-08 23:24:05.000000000 -0400
34129 ++++ linux-2.6.26.6/ipc/shm.c 2008-10-11 21:54:20.000000000 -0400
34130 +@@ -39,6 +39,7 @@
34131 + #include <linux/nsproxy.h>
34132 + #include <linux/mount.h>
34133 + #include <linux/ipc_namespace.h>
34134 ++#include <linux/grsecurity.h>
34135 +
34136 + #include <asm/uaccess.h>
34137 +
34138 +@@ -69,6 +70,14 @@ static void shm_destroy (struct ipc_name
34139 + static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
34140 + #endif
34141 +
34142 ++#ifdef CONFIG_GRKERNSEC
34143 ++extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
34144 ++ const time_t shm_createtime, const uid_t cuid,
34145 ++ const int shmid);
34146 ++extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
34147 ++ const time_t shm_createtime);
34148 ++#endif
34149 ++
34150 + void shm_init_ns(struct ipc_namespace *ns)
34151 + {
34152 + ns->shm_ctlmax = SHMMAX;
34153 +@@ -87,6 +96,8 @@ static void do_shm_rmid(struct ipc_names
34154 + struct shmid_kernel *shp;
34155 + shp = container_of(ipcp, struct shmid_kernel, shm_perm);
34156 +
34157 ++ gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
34158 ++
34159 + if (shp->shm_nattch){
34160 + shp->shm_perm.mode |= SHM_DEST;
34161 + /* Do not find it any more */
34162 +@@ -407,6 +418,14 @@ static int newseg(struct ipc_namespace *
34163 + shp->shm_lprid = 0;
34164 + shp->shm_atim = shp->shm_dtim = 0;
34165 + shp->shm_ctim = get_seconds();
34166 ++#ifdef CONFIG_GRKERNSEC
34167 ++ {
34168 ++ struct timespec timeval;
34169 ++ do_posix_clock_monotonic_gettime(&timeval);
34170 ++
34171 ++ shp->shm_createtime = timeval.tv_sec;
34172 ++ }
34173 ++#endif
34174 + shp->shm_segsz = size;
34175 + shp->shm_nattch = 0;
34176 + shp->shm_file = file;
34177 +@@ -460,6 +479,7 @@ asmlinkage long sys_shmget (key_t key, s
34178 + struct ipc_namespace *ns;
34179 + struct ipc_ops shm_ops;
34180 + struct ipc_params shm_params;
34181 ++ long err;
34182 +
34183 + ns = current->nsproxy->ipc_ns;
34184 +
34185 +@@ -471,7 +491,11 @@ asmlinkage long sys_shmget (key_t key, s
34186 + shm_params.flg = shmflg;
34187 + shm_params.u.size = size;
34188 +
34189 +- return ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
34190 ++ err = ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
34191 ++
34192 ++ gr_log_shmget(err, shmflg, size);
34193 ++
34194 ++ return err;
34195 + }
34196 +
34197 + static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version)
34198 +@@ -883,9 +907,21 @@ long do_shmat(int shmid, char __user *sh
34199 + if (err)
34200 + goto out_unlock;
34201 +
34202 ++#ifdef CONFIG_GRKERNSEC
34203 ++ if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
34204 ++ shp->shm_perm.cuid, shmid) ||
34205 ++ !gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
34206 ++ err = -EACCES;
34207 ++ goto out_unlock;
34208 ++ }
34209 ++#endif
34210 ++
34211 + path.dentry = dget(shp->shm_file->f_path.dentry);
34212 + path.mnt = shp->shm_file->f_path.mnt;
34213 + shp->shm_nattch++;
34214 ++#ifdef CONFIG_GRKERNSEC
34215 ++ shp->shm_lapid = current->pid;
34216 ++#endif
34217 + size = i_size_read(path.dentry->d_inode);
34218 + shm_unlock(shp);
34219 +
34220 +diff -urNp linux-2.6.26.6/kernel/acct.c linux-2.6.26.6/kernel/acct.c
34221 +--- linux-2.6.26.6/kernel/acct.c 2008-10-08 23:24:05.000000000 -0400
34222 ++++ linux-2.6.26.6/kernel/acct.c 2008-10-11 21:54:20.000000000 -0400
34223 +@@ -519,7 +519,7 @@ static void do_acct_process(struct pid_n
34224 + */
34225 + flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
34226 + current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
34227 +- file->f_op->write(file, (char *)&ac,
34228 ++ file->f_op->write(file, (char __user *)&ac,
34229 + sizeof(acct_t), &file->f_pos);
34230 + current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
34231 + set_fs(fs);
34232 +diff -urNp linux-2.6.26.6/kernel/capability.c linux-2.6.26.6/kernel/capability.c
34233 +--- linux-2.6.26.6/kernel/capability.c 2008-10-08 23:24:05.000000000 -0400
34234 ++++ linux-2.6.26.6/kernel/capability.c 2008-10-11 21:54:20.000000000 -0400
34235 +@@ -13,6 +13,7 @@
34236 + #include <linux/security.h>
34237 + #include <linux/syscalls.h>
34238 + #include <linux/pid_namespace.h>
34239 ++#include <linux/grsecurity.h>
34240 + #include <asm/uaccess.h>
34241 +
34242 + /*
34243 +@@ -384,15 +385,25 @@ out:
34244 +
34245 + int __capable(struct task_struct *t, int cap)
34246 + {
34247 +- if (security_capable(t, cap) == 0) {
34248 ++ if ((security_capable(t, cap) == 0) && gr_task_is_capable(t, cap)) {
34249 + t->flags |= PF_SUPERPRIV;
34250 + return 1;
34251 + }
34252 + return 0;
34253 + }
34254 +
34255 ++int capable_nolog(int cap)
34256 ++{
34257 ++ if ((security_capable(current, cap) == 0) && gr_is_capable_nolog(cap)) {
34258 ++ current->flags |= PF_SUPERPRIV;
34259 ++ return 1;
34260 ++ }
34261 ++ return 0;
34262 ++}
34263 ++
34264 + int capable(int cap)
34265 + {
34266 + return __capable(current, cap);
34267 + }
34268 + EXPORT_SYMBOL(capable);
34269 ++EXPORT_SYMBOL(capable_nolog);
34270 +diff -urNp linux-2.6.26.6/kernel/configs.c linux-2.6.26.6/kernel/configs.c
34271 +--- linux-2.6.26.6/kernel/configs.c 2008-10-08 23:24:05.000000000 -0400
34272 ++++ linux-2.6.26.6/kernel/configs.c 2008-10-11 21:54:20.000000000 -0400
34273 +@@ -79,8 +79,19 @@ static int __init ikconfig_init(void)
34274 + struct proc_dir_entry *entry;
34275 +
34276 + /* create the current config file */
34277 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
34278 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
34279 ++ entry = proc_create("config.gz", S_IFREG | S_IRUSR, NULL,
34280 ++ &ikconfig_file_ops);
34281 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
34282 ++ entry = proc_create("config.gz", S_IFREG | S_IRUSR | S_IRGRP, NULL,
34283 ++ &ikconfig_file_ops);
34284 ++#endif
34285 ++#else
34286 + entry = proc_create("config.gz", S_IFREG | S_IRUGO, NULL,
34287 + &ikconfig_file_ops);
34288 ++#endif
34289 ++
34290 + if (!entry)
34291 + return -ENOMEM;
34292 +
34293 +diff -urNp linux-2.6.26.6/kernel/cpu.c linux-2.6.26.6/kernel/cpu.c
34294 +--- linux-2.6.26.6/kernel/cpu.c 2008-10-08 23:24:05.000000000 -0400
34295 ++++ linux-2.6.26.6/kernel/cpu.c 2008-10-11 21:54:20.000000000 -0400
34296 +@@ -18,7 +18,7 @@
34297 + /* Serializes the updates to cpu_online_map, cpu_present_map */
34298 + static DEFINE_MUTEX(cpu_add_remove_lock);
34299 +
34300 +-static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain);
34301 ++static RAW_NOTIFIER_HEAD(cpu_chain);
34302 +
34303 + /* If set, cpu_up and cpu_down will return -EBUSY and do nothing.
34304 + * Should always be manipulated under cpu_add_remove_lock
34305 +diff -urNp linux-2.6.26.6/kernel/exit.c linux-2.6.26.6/kernel/exit.c
34306 +--- linux-2.6.26.6/kernel/exit.c 2008-10-08 23:24:05.000000000 -0400
34307 ++++ linux-2.6.26.6/kernel/exit.c 2008-10-11 21:54:20.000000000 -0400
34308 +@@ -45,6 +45,11 @@
34309 + #include <linux/resource.h>
34310 + #include <linux/blkdev.h>
34311 + #include <linux/task_io_accounting_ops.h>
34312 ++#include <linux/grsecurity.h>
34313 ++
34314 ++#ifdef CONFIG_GRKERNSEC
34315 ++extern rwlock_t grsec_exec_file_lock;
34316 ++#endif
34317 +
34318 + #include <asm/uaccess.h>
34319 + #include <asm/unistd.h>
34320 +@@ -132,6 +137,7 @@ static void __exit_signal(struct task_st
34321 + */
34322 + flush_sigqueue(&tsk->pending);
34323 +
34324 ++ gr_del_task_from_ip_table(tsk);
34325 + tsk->signal = NULL;
34326 + tsk->sighand = NULL;
34327 + spin_unlock(&sighand->siglock);
34328 +@@ -312,12 +318,23 @@ static void reparent_to_kthreadd(void)
34329 + {
34330 + write_lock_irq(&tasklist_lock);
34331 +
34332 ++#ifdef CONFIG_GRKERNSEC
34333 ++ write_lock(&grsec_exec_file_lock);
34334 ++ if (current->exec_file) {
34335 ++ fput(current->exec_file);
34336 ++ current->exec_file = NULL;
34337 ++ }
34338 ++ write_unlock(&grsec_exec_file_lock);
34339 ++#endif
34340 ++
34341 + ptrace_unlink(current);
34342 + /* Reparent to init */
34343 + remove_parent(current);
34344 + current->real_parent = current->parent = kthreadd_task;
34345 + add_parent(current);
34346 +
34347 ++ gr_set_kernel_label(current);
34348 ++
34349 + /* Set the exit signal to SIGCHLD so we signal init on exit */
34350 + current->exit_signal = SIGCHLD;
34351 +
34352 +@@ -411,6 +428,17 @@ void daemonize(const char *name, ...)
34353 + vsnprintf(current->comm, sizeof(current->comm), name, args);
34354 + va_end(args);
34355 +
34356 ++#ifdef CONFIG_GRKERNSEC
34357 ++ write_lock(&grsec_exec_file_lock);
34358 ++ if (current->exec_file) {
34359 ++ fput(current->exec_file);
34360 ++ current->exec_file = NULL;
34361 ++ }
34362 ++ write_unlock(&grsec_exec_file_lock);
34363 ++#endif
34364 ++
34365 ++ gr_set_kernel_label(current);
34366 ++
34367 + /*
34368 + * If we were started as result of loading a module, close all of the
34369 + * user space pages. We don't need them, and if we didn't close them
34370 +@@ -1046,6 +1074,9 @@ NORET_TYPE void do_exit(long code)
34371 + tsk->exit_code = code;
34372 + taskstats_exit(tsk, group_dead);
34373 +
34374 ++ gr_acl_handle_psacct(tsk, code);
34375 ++ gr_acl_handle_exit();
34376 ++
34377 + exit_mm(tsk);
34378 +
34379 + if (group_dead)
34380 +@@ -1256,7 +1287,7 @@ static int wait_task_zombie(struct task_
34381 + if (unlikely(noreap)) {
34382 + uid_t uid = p->uid;
34383 + int exit_code = p->exit_code;
34384 +- int why, status;
34385 ++ int why;
34386 +
34387 + get_task_struct(p);
34388 + read_unlock(&tasklist_lock);
34389 +diff -urNp linux-2.6.26.6/kernel/fork.c linux-2.6.26.6/kernel/fork.c
34390 +--- linux-2.6.26.6/kernel/fork.c 2008-10-08 23:24:05.000000000 -0400
34391 ++++ linux-2.6.26.6/kernel/fork.c 2008-10-11 21:54:20.000000000 -0400
34392 +@@ -54,6 +54,7 @@
34393 + #include <linux/tty.h>
34394 + #include <linux/proc_fs.h>
34395 + #include <linux/blkdev.h>
34396 ++#include <linux/grsecurity.h>
34397 +
34398 + #include <asm/pgtable.h>
34399 + #include <asm/pgalloc.h>
34400 +@@ -213,7 +214,7 @@ static struct task_struct *dup_task_stru
34401 + setup_thread_stack(tsk, orig);
34402 +
34403 + #ifdef CONFIG_CC_STACKPROTECTOR
34404 +- tsk->stack_canary = get_random_int();
34405 ++ tsk->stack_canary = pax_get_random_long();
34406 + #endif
34407 +
34408 + /* One for us, one for whoever does the "release_task()" (usually parent) */
34409 +@@ -250,8 +251,8 @@ static int dup_mmap(struct mm_struct *mm
34410 + mm->locked_vm = 0;
34411 + mm->mmap = NULL;
34412 + mm->mmap_cache = NULL;
34413 +- mm->free_area_cache = oldmm->mmap_base;
34414 +- mm->cached_hole_size = ~0UL;
34415 ++ mm->free_area_cache = oldmm->free_area_cache;
34416 ++ mm->cached_hole_size = oldmm->cached_hole_size;
34417 + mm->map_count = 0;
34418 + cpus_clear(mm->cpu_vm_mask);
34419 + mm->mm_rb = RB_ROOT;
34420 +@@ -288,6 +289,7 @@ static int dup_mmap(struct mm_struct *mm
34421 + tmp->vm_flags &= ~VM_LOCKED;
34422 + tmp->vm_mm = mm;
34423 + tmp->vm_next = NULL;
34424 ++ tmp->vm_mirror = NULL;
34425 + anon_vma_link(tmp);
34426 + file = tmp->vm_file;
34427 + if (file) {
34428 +@@ -324,6 +326,31 @@ static int dup_mmap(struct mm_struct *mm
34429 + if (retval)
34430 + goto out;
34431 + }
34432 ++
34433 ++#ifdef CONFIG_PAX_SEGMEXEC
34434 ++ if (oldmm->pax_flags & MF_PAX_SEGMEXEC) {
34435 ++ struct vm_area_struct *mpnt_m;
34436 ++
34437 ++ for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) {
34438 ++ BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm);
34439 ++
34440 ++ if (!mpnt->vm_mirror)
34441 ++ continue;
34442 ++
34443 ++ if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) {
34444 ++ BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt);
34445 ++ mpnt->vm_mirror = mpnt_m;
34446 ++ } else {
34447 ++ BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm);
34448 ++ mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror;
34449 ++ mpnt_m->vm_mirror->vm_mirror = mpnt_m;
34450 ++ mpnt->vm_mirror->vm_mirror = mpnt;
34451 ++ }
34452 ++ }
34453 ++ BUG_ON(mpnt_m);
34454 ++ }
34455 ++#endif
34456 ++
34457 + /* a new mm has just been created */
34458 + arch_dup_mmap(oldmm, mm);
34459 + retval = 0;
34460 +@@ -505,7 +532,7 @@ void mm_release(struct task_struct *tsk,
34461 + if (tsk->clear_child_tid
34462 + && !(tsk->flags & PF_SIGNALED)
34463 + && atomic_read(&mm->mm_users) > 1) {
34464 +- u32 __user * tidptr = tsk->clear_child_tid;
34465 ++ pid_t __user * tidptr = tsk->clear_child_tid;
34466 + tsk->clear_child_tid = NULL;
34467 +
34468 + /*
34469 +@@ -513,7 +540,7 @@ void mm_release(struct task_struct *tsk,
34470 + * not set up a proper pointer then tough luck.
34471 + */
34472 + put_user(0, tidptr);
34473 +- sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
34474 ++ sys_futex((u32 __user *)tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
34475 + }
34476 + }
34477 +
34478 +@@ -914,6 +941,9 @@ static struct task_struct *copy_process(
34479 + DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
34480 + #endif
34481 + retval = -EAGAIN;
34482 ++
34483 ++ gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
34484 ++
34485 + if (atomic_read(&p->user->processes) >=
34486 + p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
34487 + if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
34488 +@@ -1080,6 +1110,8 @@ static struct task_struct *copy_process(
34489 + if (clone_flags & CLONE_THREAD)
34490 + p->tgid = current->tgid;
34491 +
34492 ++ gr_copy_label(p);
34493 ++
34494 + p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
34495 + /*
34496 + * Clear TID on mm_release()?
34497 +@@ -1269,6 +1301,8 @@ bad_fork_cleanup_count:
34498 + bad_fork_free:
34499 + free_task(p);
34500 + fork_out:
34501 ++ gr_log_forkfail(retval);
34502 ++
34503 + return ERR_PTR(retval);
34504 + }
34505 +
34506 +@@ -1361,6 +1395,8 @@ long do_fork(unsigned long clone_flags,
34507 + if (clone_flags & CLONE_PARENT_SETTID)
34508 + put_user(nr, parent_tidptr);
34509 +
34510 ++ gr_handle_brute_check();
34511 ++
34512 + if (clone_flags & CLONE_VFORK) {
34513 + p->vfork_done = &vfork;
34514 + init_completion(&vfork);
34515 +diff -urNp linux-2.6.26.6/kernel/futex.c linux-2.6.26.6/kernel/futex.c
34516 +--- linux-2.6.26.6/kernel/futex.c 2008-10-08 23:24:05.000000000 -0400
34517 ++++ linux-2.6.26.6/kernel/futex.c 2008-10-11 21:55:52.000000000 -0400
34518 +@@ -188,6 +188,11 @@ static int get_futex_key(u32 __user *uad
34519 + struct page *page;
34520 + int err;
34521 +
34522 ++#ifdef CONFIG_PAX_SEGMEXEC
34523 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && address >= SEGMEXEC_TASK_SIZE)
34524 ++ return -EFAULT;
34525 ++#endif
34526 ++
34527 + /*
34528 + * The futex address must be "naturally" aligned.
34529 + */
34530 +@@ -214,8 +219,8 @@ static int get_futex_key(u32 __user *uad
34531 + * The futex is hashed differently depending on whether
34532 + * it's in a shared or private mapping. So check vma first.
34533 + */
34534 +- vma = find_extend_vma(mm, address);
34535 +- if (unlikely(!vma))
34536 ++ vma = find_vma(mm, address);
34537 ++ if (unlikely(!vma || address < vma->vm_start))
34538 + return -EFAULT;
34539 +
34540 + /*
34541 +@@ -1345,7 +1350,7 @@ static int futex_wait(u32 __user *uaddr,
34542 + struct restart_block *restart;
34543 + restart = &current_thread_info()->restart_block;
34544 + restart->fn = futex_wait_restart;
34545 +- restart->futex.uaddr = (u32 *)uaddr;
34546 ++ restart->futex.uaddr = uaddr;
34547 + restart->futex.val = val;
34548 + restart->futex.time = abs_time->tv64;
34549 + restart->futex.bitset = bitset;
34550 +@@ -1906,7 +1911,7 @@ retry:
34551 + */
34552 + static inline int fetch_robust_entry(struct robust_list __user **entry,
34553 + struct robust_list __user * __user *head,
34554 +- int *pi)
34555 ++ unsigned int *pi)
34556 + {
34557 + unsigned long uentry;
34558 +
34559 +diff -urNp linux-2.6.26.6/kernel/irq/handle.c linux-2.6.26.6/kernel/irq/handle.c
34560 +--- linux-2.6.26.6/kernel/irq/handle.c 2008-10-08 23:24:05.000000000 -0400
34561 ++++ linux-2.6.26.6/kernel/irq/handle.c 2008-10-11 21:54:20.000000000 -0400
34562 +@@ -55,7 +55,8 @@ struct irq_desc irq_desc[NR_IRQS] __cach
34563 + .depth = 1,
34564 + .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
34565 + #ifdef CONFIG_SMP
34566 +- .affinity = CPU_MASK_ALL
34567 ++ .affinity = CPU_MASK_ALL,
34568 ++ .cpu = 0,
34569 + #endif
34570 + }
34571 + };
34572 +diff -urNp linux-2.6.26.6/kernel/kallsyms.c linux-2.6.26.6/kernel/kallsyms.c
34573 +--- linux-2.6.26.6/kernel/kallsyms.c 2008-10-08 23:24:05.000000000 -0400
34574 ++++ linux-2.6.26.6/kernel/kallsyms.c 2008-10-11 21:54:20.000000000 -0400
34575 +@@ -62,6 +62,19 @@ static inline int is_kernel_text(unsigne
34576 +
34577 + static inline int is_kernel(unsigned long addr)
34578 + {
34579 ++
34580 ++#ifdef CONFIG_PAX_KERNEXEC
34581 ++
34582 ++#ifdef CONFIG_MODULES
34583 ++ if ((unsigned long)MODULES_VADDR <= ktla_ktva(addr) &&
34584 ++ ktla_ktva(addr) < (unsigned long)MODULES_END)
34585 ++ return 0;
34586 ++#endif
34587 ++
34588 ++ if (is_kernel_inittext(addr))
34589 ++ return 1;
34590 ++#endif
34591 ++
34592 + if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
34593 + return 1;
34594 + return in_gate_area_no_task(addr);
34595 +@@ -366,7 +379,6 @@ static unsigned long get_ksymbol_core(st
34596 +
34597 + static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
34598 + {
34599 +- iter->name[0] = '\0';
34600 + iter->nameoff = get_symbol_offset(new_pos);
34601 + iter->pos = new_pos;
34602 + }
34603 +@@ -450,7 +462,7 @@ static int kallsyms_open(struct inode *i
34604 + struct kallsym_iter *iter;
34605 + int ret;
34606 +
34607 +- iter = kmalloc(sizeof(*iter), GFP_KERNEL);
34608 ++ iter = kzalloc(sizeof(*iter), GFP_KERNEL);
34609 + if (!iter)
34610 + return -ENOMEM;
34611 + reset_iter(iter, 0);
34612 +@@ -472,7 +484,15 @@ static const struct file_operations kall
34613 +
34614 + static int __init kallsyms_init(void)
34615 + {
34616 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
34617 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
34618 ++ proc_create("kallsyms", S_IFREG | S_IRUSR, NULL, &kallsyms_operations);
34619 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
34620 ++ proc_create("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL, &kallsyms_operations);
34621 ++#endif
34622 ++#else
34623 + proc_create("kallsyms", 0444, NULL, &kallsyms_operations);
34624 ++#endif
34625 + return 0;
34626 + }
34627 + __initcall(kallsyms_init);
34628 +diff -urNp linux-2.6.26.6/kernel/kmod.c linux-2.6.26.6/kernel/kmod.c
34629 +--- linux-2.6.26.6/kernel/kmod.c 2008-10-08 23:24:05.000000000 -0400
34630 ++++ linux-2.6.26.6/kernel/kmod.c 2008-10-11 21:54:20.000000000 -0400
34631 +@@ -108,7 +108,7 @@ int request_module(const char *fmt, ...)
34632 + return -ENOMEM;
34633 + }
34634 +
34635 +- ret = call_usermodehelper(modprobe_path, argv, envp, 1);
34636 ++ ret = call_usermodehelper(modprobe_path, argv, envp, UMH_WAIT_PROC);
34637 + atomic_dec(&kmod_concurrent);
34638 + return ret;
34639 + }
34640 +diff -urNp linux-2.6.26.6/kernel/kprobes.c linux-2.6.26.6/kernel/kprobes.c
34641 +--- linux-2.6.26.6/kernel/kprobes.c 2008-10-08 23:24:05.000000000 -0400
34642 ++++ linux-2.6.26.6/kernel/kprobes.c 2008-10-11 21:54:20.000000000 -0400
34643 +@@ -174,7 +174,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
34644 + * kernel image and loaded module images reside. This is required
34645 + * so x86_64 can correctly handle the %rip-relative fixups.
34646 + */
34647 +- kip->insns = module_alloc(PAGE_SIZE);
34648 ++ kip->insns = module_alloc_exec(PAGE_SIZE);
34649 + if (!kip->insns) {
34650 + kfree(kip);
34651 + return NULL;
34652 +@@ -206,7 +206,7 @@ static int __kprobes collect_one_slot(st
34653 + hlist_add_head(&kip->hlist,
34654 + &kprobe_insn_pages);
34655 + } else {
34656 +- module_free(NULL, kip->insns);
34657 ++ module_free_exec(NULL, kip->insns);
34658 + kfree(kip);
34659 + }
34660 + return 1;
34661 +diff -urNp linux-2.6.26.6/kernel/lockdep.c linux-2.6.26.6/kernel/lockdep.c
34662 +--- linux-2.6.26.6/kernel/lockdep.c 2008-10-08 23:24:05.000000000 -0400
34663 ++++ linux-2.6.26.6/kernel/lockdep.c 2008-10-11 21:54:20.000000000 -0400
34664 +@@ -598,6 +598,10 @@ static int static_obj(void *obj)
34665 + int i;
34666 + #endif
34667 +
34668 ++#ifdef CONFIG_PAX_KERNEXEC
34669 ++ start = (unsigned long )&_data;
34670 ++#endif
34671 ++
34672 + /*
34673 + * static variable?
34674 + */
34675 +@@ -609,9 +613,12 @@ static int static_obj(void *obj)
34676 + * percpu var?
34677 + */
34678 + for_each_possible_cpu(i) {
34679 ++#ifdef CONFIG_X86_32
34680 ++ start = per_cpu_offset(i);
34681 ++#else
34682 + start = (unsigned long) &__per_cpu_start + per_cpu_offset(i);
34683 +- end = (unsigned long) &__per_cpu_start + PERCPU_ENOUGH_ROOM
34684 +- + per_cpu_offset(i);
34685 ++#endif
34686 ++ end = start + PERCPU_ENOUGH_ROOM;
34687 +
34688 + if ((addr >= start) && (addr < end))
34689 + return 1;
34690 +diff -urNp linux-2.6.26.6/kernel/module.c linux-2.6.26.6/kernel/module.c
34691 +--- linux-2.6.26.6/kernel/module.c 2008-10-08 23:24:05.000000000 -0400
34692 ++++ linux-2.6.26.6/kernel/module.c 2008-10-11 21:55:52.000000000 -0400
34693 +@@ -44,6 +44,11 @@
34694 + #include <linux/unwind.h>
34695 + #include <asm/uaccess.h>
34696 + #include <asm/cacheflush.h>
34697 ++
34698 ++#ifdef CONFIG_PAX_KERNEXEC
34699 ++#include <asm/desc.h>
34700 ++#endif
34701 ++
34702 + #include <linux/license.h>
34703 + #include <asm/sections.h>
34704 +
34705 +@@ -70,6 +75,8 @@ static DECLARE_WAIT_QUEUE_HEAD(module_wq
34706 +
34707 + static BLOCKING_NOTIFIER_HEAD(module_notify_list);
34708 +
34709 ++extern int gr_check_modstop(void);
34710 ++
34711 + int register_module_notifier(struct notifier_block * nb)
34712 + {
34713 + return blocking_notifier_chain_register(&module_notify_list, nb);
34714 +@@ -273,7 +280,7 @@ static unsigned long find_symbol(const c
34715 +
34716 + /* Now try modules. */
34717 + list_for_each_entry(mod, &modules, list) {
34718 +- struct symsearch arr[] = {
34719 ++ struct symsearch modarr[] = {
34720 + { mod->syms, mod->syms + mod->num_syms, mod->crcs,
34721 + always_ok },
34722 + { mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms,
34723 +@@ -289,7 +296,7 @@ static unsigned long find_symbol(const c
34724 + mod->unused_gpl_crcs, gpl_only_unused_warning },
34725 + };
34726 +
34727 +- ks = search_symarrays(arr, ARRAY_SIZE(arr),
34728 ++ ks = search_symarrays(modarr, ARRAY_SIZE(modarr),
34729 + name, gplok, warn, crc);
34730 + if (ks) {
34731 + if (owner)
34732 +@@ -352,6 +359,8 @@ static inline unsigned int block_size(in
34733 + return val;
34734 + }
34735 +
34736 ++EXPORT_SYMBOL(__per_cpu_start);
34737 ++
34738 + static void *percpu_modalloc(unsigned long size, unsigned long align,
34739 + const char *name)
34740 + {
34741 +@@ -359,7 +368,7 @@ static void *percpu_modalloc(unsigned lo
34742 + unsigned int i;
34743 + void *ptr;
34744 +
34745 +- if (align > PAGE_SIZE) {
34746 ++ if (align-1 >= PAGE_SIZE) {
34747 + printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
34748 + name, align, PAGE_SIZE);
34749 + align = PAGE_SIZE;
34750 +@@ -441,7 +450,11 @@ static void percpu_modcopy(void *pcpudes
34751 + int cpu;
34752 +
34753 + for_each_possible_cpu(cpu)
34754 ++#ifdef CONFIG_X86_32
34755 ++ memcpy(pcpudest + __per_cpu_offset[cpu], from, size);
34756 ++#else
34757 + memcpy(pcpudest + per_cpu_offset(cpu), from, size);
34758 ++#endif
34759 + }
34760 +
34761 + static int percpu_modinit(void)
34762 +@@ -692,6 +705,9 @@ sys_delete_module(const char __user *nam
34763 + char name[MODULE_NAME_LEN];
34764 + int ret, forced = 0;
34765 +
34766 ++ if (gr_check_modstop())
34767 ++ return -EPERM;
34768 ++
34769 + if (!capable(CAP_SYS_MODULE))
34770 + return -EPERM;
34771 +
34772 +@@ -1400,16 +1416,19 @@ static void free_module(struct module *m
34773 + module_unload_free(mod);
34774 +
34775 + /* This may be NULL, but that's OK */
34776 +- module_free(mod, mod->module_init);
34777 ++ module_free(mod, mod->module_init_rw);
34778 ++ module_free_exec(mod, mod->module_init_rx);
34779 + kfree(mod->args);
34780 + if (mod->percpu)
34781 + percpu_modfree(mod->percpu);
34782 +
34783 + /* Free lock-classes: */
34784 +- lockdep_free_key_range(mod->module_core, mod->core_size);
34785 ++ lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
34786 ++ lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
34787 +
34788 + /* Finally, free the core (containing the module structure) */
34789 +- module_free(mod, mod->module_core);
34790 ++ module_free_exec(mod, mod->module_core_rx);
34791 ++ module_free(mod, mod->module_core_rw);
34792 + }
34793 +
34794 + void *__symbol_get(const char *symbol)
34795 +@@ -1473,10 +1492,14 @@ static int simplify_symbols(Elf_Shdr *se
34796 + struct module *mod)
34797 + {
34798 + Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
34799 +- unsigned long secbase;
34800 ++ unsigned long secbase, symbol;
34801 + unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
34802 + int ret = 0;
34803 +
34804 ++#ifdef CONFIG_PAX_KERNEXEC
34805 ++ unsigned long cr0;
34806 ++#endif
34807 ++
34808 + for (i = 1; i < n; i++) {
34809 + switch (sym[i].st_shndx) {
34810 + case SHN_COMMON:
34811 +@@ -1495,10 +1518,19 @@ static int simplify_symbols(Elf_Shdr *se
34812 + break;
34813 +
34814 + case SHN_UNDEF:
34815 +- sym[i].st_value
34816 +- = resolve_symbol(sechdrs, versindex,
34817 ++ symbol = resolve_symbol(sechdrs, versindex,
34818 + strtab + sym[i].st_name, mod);
34819 +
34820 ++#ifdef CONFIG_PAX_KERNEXEC
34821 ++ pax_open_kernel(cr0);
34822 ++#endif
34823 ++
34824 ++ sym[i].st_value = symbol;
34825 ++
34826 ++#ifdef CONFIG_PAX_KERNEXEC
34827 ++ pax_close_kernel(cr0);
34828 ++#endif
34829 ++
34830 + /* Ok if resolved. */
34831 + if (!IS_ERR_VALUE(sym[i].st_value))
34832 + break;
34833 +@@ -1513,11 +1545,27 @@ static int simplify_symbols(Elf_Shdr *se
34834 +
34835 + default:
34836 + /* Divert to percpu allocation if a percpu var. */
34837 +- if (sym[i].st_shndx == pcpuindex)
34838 ++ if (sym[i].st_shndx == pcpuindex) {
34839 ++
34840 ++#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
34841 ++ secbase = (unsigned long)mod->percpu - (unsigned long)__per_cpu_start;
34842 ++#else
34843 + secbase = (unsigned long)mod->percpu;
34844 +- else
34845 ++#endif
34846 ++
34847 ++ } else
34848 + secbase = sechdrs[sym[i].st_shndx].sh_addr;
34849 ++
34850 ++#ifdef CONFIG_PAX_KERNEXEC
34851 ++ pax_open_kernel(cr0);
34852 ++#endif
34853 ++
34854 + sym[i].st_value += secbase;
34855 ++
34856 ++#ifdef CONFIG_PAX_KERNEXEC
34857 ++ pax_close_kernel(cr0);
34858 ++#endif
34859 ++
34860 + break;
34861 + }
34862 + }
34863 +@@ -1569,11 +1617,14 @@ static void layout_sections(struct modul
34864 + || strncmp(secstrings + s->sh_name,
34865 + ".init", 5) == 0)
34866 + continue;
34867 +- s->sh_entsize = get_offset(&mod->core_size, s);
34868 ++ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
34869 ++ s->sh_entsize = get_offset(&mod->core_size_rw, s);
34870 ++ else
34871 ++ s->sh_entsize = get_offset(&mod->core_size_rx, s);
34872 + DEBUGP("\t%s\n", secstrings + s->sh_name);
34873 + }
34874 + if (m == 0)
34875 +- mod->core_text_size = mod->core_size;
34876 ++ mod->core_size_rx = mod->core_size_rx;
34877 + }
34878 +
34879 + DEBUGP("Init section allocation order:\n");
34880 +@@ -1587,12 +1638,15 @@ static void layout_sections(struct modul
34881 + || strncmp(secstrings + s->sh_name,
34882 + ".init", 5) != 0)
34883 + continue;
34884 +- s->sh_entsize = (get_offset(&mod->init_size, s)
34885 +- | INIT_OFFSET_MASK);
34886 ++ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
34887 ++ s->sh_entsize = get_offset(&mod->init_size_rw, s);
34888 ++ else
34889 ++ s->sh_entsize = get_offset(&mod->init_size_rx, s);
34890 ++ s->sh_entsize |= INIT_OFFSET_MASK;
34891 + DEBUGP("\t%s\n", secstrings + s->sh_name);
34892 + }
34893 + if (m == 0)
34894 +- mod->init_text_size = mod->init_size;
34895 ++ mod->init_size_rx = mod->init_size_rx;
34896 + }
34897 + }
34898 +
34899 +@@ -1719,14 +1773,31 @@ static void add_kallsyms(struct module *
34900 + {
34901 + unsigned int i;
34902 +
34903 ++#ifdef CONFIG_PAX_KERNEXEC
34904 ++ unsigned long cr0;
34905 ++#endif
34906 ++
34907 + mod->symtab = (void *)sechdrs[symindex].sh_addr;
34908 + mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
34909 + mod->strtab = (void *)sechdrs[strindex].sh_addr;
34910 +
34911 + /* Set types up while we still have access to sections. */
34912 +- for (i = 0; i < mod->num_symtab; i++)
34913 +- mod->symtab[i].st_info
34914 +- = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
34915 ++
34916 ++ for (i = 0; i < mod->num_symtab; i++) {
34917 ++ char type = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
34918 ++
34919 ++#ifdef CONFIG_PAX_KERNEXEC
34920 ++ pax_open_kernel(cr0);
34921 ++#endif
34922 ++
34923 ++ mod->symtab[i].st_info = type;
34924 ++
34925 ++#ifdef CONFIG_PAX_KERNEXEC
34926 ++ pax_close_kernel(cr0);
34927 ++#endif
34928 ++
34929 ++ }
34930 ++
34931 + }
34932 + #else
34933 + static inline void add_kallsyms(struct module *mod,
34934 +@@ -1776,6 +1847,10 @@ static struct module *load_module(void _
34935 + struct exception_table_entry *extable;
34936 + mm_segment_t old_fs;
34937 +
34938 ++#ifdef CONFIG_PAX_KERNEXEC
34939 ++ unsigned long cr0;
34940 ++#endif
34941 ++
34942 + DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
34943 + umod, len, uargs);
34944 + if (len < sizeof(*hdr))
34945 +@@ -1935,21 +2010,57 @@ static struct module *load_module(void _
34946 + layout_sections(mod, hdr, sechdrs, secstrings);
34947 +
34948 + /* Do the allocs. */
34949 +- ptr = module_alloc(mod->core_size);
34950 ++ ptr = module_alloc(mod->core_size_rw);
34951 + if (!ptr) {
34952 + err = -ENOMEM;
34953 + goto free_percpu;
34954 + }
34955 +- memset(ptr, 0, mod->core_size);
34956 +- mod->module_core = ptr;
34957 ++ memset(ptr, 0, mod->core_size_rw);
34958 ++ mod->module_core_rw = ptr;
34959 ++
34960 ++ ptr = module_alloc(mod->init_size_rw);
34961 ++ if (!ptr && mod->init_size_rw) {
34962 ++ err = -ENOMEM;
34963 ++ goto free_core_rw;
34964 ++ }
34965 ++ memset(ptr, 0, mod->init_size_rw);
34966 ++ mod->module_init_rw = ptr;
34967 ++
34968 ++ ptr = module_alloc_exec(mod->core_size_rx);
34969 ++ if (!ptr) {
34970 ++ err = -ENOMEM;
34971 ++ goto free_init_rw;
34972 ++ }
34973 +
34974 +- ptr = module_alloc(mod->init_size);
34975 +- if (!ptr && mod->init_size) {
34976 ++#ifdef CONFIG_PAX_KERNEXEC
34977 ++ pax_open_kernel(cr0);
34978 ++#endif
34979 ++
34980 ++ memset(ptr, 0, mod->core_size_rx);
34981 ++
34982 ++#ifdef CONFIG_PAX_KERNEXEC
34983 ++ pax_close_kernel(cr0);
34984 ++#endif
34985 ++
34986 ++ mod->module_core_rx = ptr;
34987 ++
34988 ++ ptr = module_alloc_exec(mod->init_size_rx);
34989 ++ if (!ptr && mod->init_size_rx) {
34990 + err = -ENOMEM;
34991 +- goto free_core;
34992 ++ goto free_core_rx;
34993 + }
34994 +- memset(ptr, 0, mod->init_size);
34995 +- mod->module_init = ptr;
34996 ++
34997 ++#ifdef CONFIG_PAX_KERNEXEC
34998 ++ pax_open_kernel(cr0);
34999 ++#endif
35000 ++
35001 ++ memset(ptr, 0, mod->init_size_rx);
35002 ++
35003 ++#ifdef CONFIG_PAX_KERNEXEC
35004 ++ pax_close_kernel(cr0);
35005 ++#endif
35006 ++
35007 ++ mod->module_init_rx = ptr;
35008 +
35009 + /* Transfer each section which specifies SHF_ALLOC */
35010 + DEBUGP("final section addresses:\n");
35011 +@@ -1959,17 +2070,41 @@ static struct module *load_module(void _
35012 + if (!(sechdrs[i].sh_flags & SHF_ALLOC))
35013 + continue;
35014 +
35015 +- if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
35016 +- dest = mod->module_init
35017 +- + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
35018 +- else
35019 +- dest = mod->module_core + sechdrs[i].sh_entsize;
35020 ++ if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
35021 ++ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
35022 ++ dest = mod->module_init_rw
35023 ++ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
35024 ++ else
35025 ++ dest = mod->module_init_rx
35026 ++ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
35027 ++ } else {
35028 ++ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
35029 ++ dest = mod->module_core_rw + sechdrs[i].sh_entsize;
35030 ++ else
35031 ++ dest = mod->module_core_rx + sechdrs[i].sh_entsize;
35032 ++ }
35033 ++
35034 ++ if (sechdrs[i].sh_type != SHT_NOBITS) {
35035 +
35036 +- if (sechdrs[i].sh_type != SHT_NOBITS)
35037 +- memcpy(dest, (void *)sechdrs[i].sh_addr,
35038 +- sechdrs[i].sh_size);
35039 ++#ifdef CONFIG_PAX_KERNEXEC
35040 ++ if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC)) {
35041 ++ pax_open_kernel(cr0);
35042 ++ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
35043 ++ pax_close_kernel(cr0);
35044 ++ } else
35045 ++#endif
35046 ++
35047 ++ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
35048 ++ }
35049 + /* Update sh_addr to point to copy in image. */
35050 +- sechdrs[i].sh_addr = (unsigned long)dest;
35051 ++
35052 ++#ifdef CONFIG_PAX_KERNEXEC
35053 ++ if (sechdrs[i].sh_flags & SHF_EXECINSTR)
35054 ++ sechdrs[i].sh_addr = ktva_ktla((unsigned long)dest);
35055 ++ else
35056 ++#endif
35057 ++
35058 ++ sechdrs[i].sh_addr = (unsigned long)dest;
35059 + DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
35060 + }
35061 + /* Module has been moved. */
35062 +@@ -2052,8 +2187,8 @@ static struct module *load_module(void _
35063 +
35064 + /* Now do relocations. */
35065 + for (i = 1; i < hdr->e_shnum; i++) {
35066 +- const char *strtab = (char *)sechdrs[strindex].sh_addr;
35067 + unsigned int info = sechdrs[i].sh_info;
35068 ++ strtab = (char *)sechdrs[strindex].sh_addr;
35069 +
35070 + /* Not a valid relocation section? */
35071 + if (info >= hdr->e_shnum)
35072 +@@ -2112,12 +2247,12 @@ static struct module *load_module(void _
35073 + * Do it before processing of module parameters, so the module
35074 + * can provide parameter accessor functions of its own.
35075 + */
35076 +- if (mod->module_init)
35077 +- flush_icache_range((unsigned long)mod->module_init,
35078 +- (unsigned long)mod->module_init
35079 +- + mod->init_size);
35080 +- flush_icache_range((unsigned long)mod->module_core,
35081 +- (unsigned long)mod->module_core + mod->core_size);
35082 ++ if (mod->module_init_rx)
35083 ++ flush_icache_range((unsigned long)mod->module_init_rx,
35084 ++ (unsigned long)mod->module_init_rx
35085 ++ + mod->init_size_rx);
35086 ++ flush_icache_range((unsigned long)mod->module_core_rx,
35087 ++ (unsigned long)mod->module_core_rx + mod->core_size_rx);
35088 +
35089 + set_fs(old_fs);
35090 +
35091 +@@ -2170,9 +2305,13 @@ static struct module *load_module(void _
35092 + kobject_put(&mod->mkobj.kobj);
35093 + free_unload:
35094 + module_unload_free(mod);
35095 +- module_free(mod, mod->module_init);
35096 +- free_core:
35097 +- module_free(mod, mod->module_core);
35098 ++ module_free_exec(mod, mod->module_init_rx);
35099 ++ free_core_rx:
35100 ++ module_free_exec(mod, mod->module_core_rx);
35101 ++ free_init_rw:
35102 ++ module_free(mod, mod->module_init_rw);
35103 ++ free_core_rw:
35104 ++ module_free(mod, mod->module_core_rw);
35105 + free_percpu:
35106 + if (percpu)
35107 + percpu_modfree(percpu);
35108 +@@ -2197,6 +2336,9 @@ sys_init_module(void __user *umod,
35109 + struct module *mod;
35110 + int ret = 0;
35111 +
35112 ++ if (gr_check_modstop())
35113 ++ return -EPERM;
35114 ++
35115 + /* Must have permission */
35116 + if (!capable(CAP_SYS_MODULE))
35117 + return -EPERM;
35118 +@@ -2252,10 +2394,12 @@ sys_init_module(void __user *umod,
35119 + /* Drop initial reference. */
35120 + module_put(mod);
35121 + unwind_remove_table(mod->unwind_info, 1);
35122 +- module_free(mod, mod->module_init);
35123 +- mod->module_init = NULL;
35124 +- mod->init_size = 0;
35125 +- mod->init_text_size = 0;
35126 ++ module_free(mod, mod->module_init_rw);
35127 ++ module_free_exec(mod, mod->module_init_rx);
35128 ++ mod->module_init_rw = NULL;
35129 ++ mod->module_init_rx = NULL;
35130 ++ mod->init_size_rw = 0;
35131 ++ mod->init_size_rx = 0;
35132 + mutex_unlock(&module_mutex);
35133 +
35134 + return 0;
35135 +@@ -2263,6 +2407,13 @@ sys_init_module(void __user *umod,
35136 +
35137 + static inline int within(unsigned long addr, void *start, unsigned long size)
35138 + {
35139 ++
35140 ++#ifdef CONFIG_PAX_KERNEXEC
35141 ++ if (ktla_ktva(addr) >= (unsigned long)start &&
35142 ++ ktla_ktva(addr) < (unsigned long)start + size)
35143 ++ return 1;
35144 ++#endif
35145 ++
35146 + return ((void *)addr >= start && (void *)addr < start + size);
35147 + }
35148 +
35149 +@@ -2286,10 +2437,14 @@ static const char *get_ksymbol(struct mo
35150 + unsigned long nextval;
35151 +
35152 + /* At worse, next value is at end of module */
35153 +- if (within(addr, mod->module_init, mod->init_size))
35154 +- nextval = (unsigned long)mod->module_init+mod->init_text_size;
35155 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx))
35156 ++ nextval = (unsigned long)mod->module_init_rx+mod->init_size_rx;
35157 ++ else if (within(addr, mod->module_init_rw, mod->init_size_rw))
35158 ++ nextval = (unsigned long)mod->module_init_rw+mod->init_size_rw;
35159 ++ else if (within(addr, mod->module_core_rx, mod->core_size_rx))
35160 ++ nextval = (unsigned long)mod->module_core_rx+mod->core_size_rx;
35161 + else
35162 +- nextval = (unsigned long)mod->module_core+mod->core_text_size;
35163 ++ nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
35164 +
35165 + /* Scan for closest preceeding symbol, and next symbol. (ELF
35166 + starts real symbols at 1). */
35167 +@@ -2334,8 +2489,10 @@ const char *module_address_lookup(unsign
35168 +
35169 + preempt_disable();
35170 + list_for_each_entry(mod, &modules, list) {
35171 +- if (within(addr, mod->module_init, mod->init_size)
35172 +- || within(addr, mod->module_core, mod->core_size)) {
35173 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
35174 ++ within(addr, mod->module_init_rw, mod->init_size_rw) ||
35175 ++ within(addr, mod->module_core_rx, mod->core_size_rx) ||
35176 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
35177 + if (modname)
35178 + *modname = mod->name;
35179 + ret = get_ksymbol(mod, addr, size, offset);
35180 +@@ -2357,8 +2514,10 @@ int lookup_module_symbol_name(unsigned l
35181 +
35182 + preempt_disable();
35183 + list_for_each_entry(mod, &modules, list) {
35184 +- if (within(addr, mod->module_init, mod->init_size) ||
35185 +- within(addr, mod->module_core, mod->core_size)) {
35186 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
35187 ++ within(addr, mod->module_init_rw, mod->init_size_rw) ||
35188 ++ within(addr, mod->module_core_rx, mod->core_size_rx) ||
35189 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
35190 + const char *sym;
35191 +
35192 + sym = get_ksymbol(mod, addr, NULL, NULL);
35193 +@@ -2381,8 +2540,10 @@ int lookup_module_symbol_attrs(unsigned
35194 +
35195 + preempt_disable();
35196 + list_for_each_entry(mod, &modules, list) {
35197 +- if (within(addr, mod->module_init, mod->init_size) ||
35198 +- within(addr, mod->module_core, mod->core_size)) {
35199 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
35200 ++ within(addr, mod->module_init_rw, mod->init_size_rw) ||
35201 ++ within(addr, mod->module_core_rx, mod->core_size_rx) ||
35202 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
35203 + const char *sym;
35204 +
35205 + sym = get_ksymbol(mod, addr, size, offset);
35206 +@@ -2513,7 +2674,7 @@ static int m_show(struct seq_file *m, vo
35207 + char buf[8];
35208 +
35209 + seq_printf(m, "%s %lu",
35210 +- mod->name, mod->init_size + mod->core_size);
35211 ++ mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
35212 + print_unload_info(m, mod);
35213 +
35214 + /* Informative for users. */
35215 +@@ -2522,7 +2683,7 @@ static int m_show(struct seq_file *m, vo
35216 + mod->state == MODULE_STATE_COMING ? "Loading":
35217 + "Live");
35218 + /* Used by oprofile and other similar tools. */
35219 +- seq_printf(m, " 0x%p", mod->module_core);
35220 ++ seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
35221 +
35222 + /* Taints info */
35223 + if (mod->taints)
35224 +@@ -2578,7 +2739,8 @@ int is_module_address(unsigned long addr
35225 + preempt_disable();
35226 +
35227 + list_for_each_entry(mod, &modules, list) {
35228 +- if (within(addr, mod->module_core, mod->core_size)) {
35229 ++ if (within(addr, mod->module_core_rx, mod->core_size_rx) ||
35230 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
35231 + preempt_enable();
35232 + return 1;
35233 + }
35234 +@@ -2596,8 +2758,8 @@ struct module *__module_text_address(uns
35235 + struct module *mod;
35236 +
35237 + list_for_each_entry(mod, &modules, list)
35238 +- if (within(addr, mod->module_init, mod->init_text_size)
35239 +- || within(addr, mod->module_core, mod->core_text_size))
35240 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx)
35241 ++ || within(addr, mod->module_core_rx, mod->core_size_rx))
35242 + return mod;
35243 + return NULL;
35244 + }
35245 +diff -urNp linux-2.6.26.6/kernel/mutex.c linux-2.6.26.6/kernel/mutex.c
35246 +--- linux-2.6.26.6/kernel/mutex.c 2008-10-08 23:24:05.000000000 -0400
35247 ++++ linux-2.6.26.6/kernel/mutex.c 2008-10-11 21:54:20.000000000 -0400
35248 +@@ -82,7 +82,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou
35249 + *
35250 + * This function is similar to (but not equivalent to) down().
35251 + */
35252 +-void inline __sched mutex_lock(struct mutex *lock)
35253 ++inline void __sched mutex_lock(struct mutex *lock)
35254 + {
35255 + might_sleep();
35256 + /*
35257 +diff -urNp linux-2.6.26.6/kernel/panic.c linux-2.6.26.6/kernel/panic.c
35258 +--- linux-2.6.26.6/kernel/panic.c 2008-10-08 23:24:05.000000000 -0400
35259 ++++ linux-2.6.26.6/kernel/panic.c 2008-10-11 21:54:20.000000000 -0400
35260 +@@ -327,6 +327,8 @@ EXPORT_SYMBOL(warn_on_slowpath);
35261 + */
35262 + void __stack_chk_fail(void)
35263 + {
35264 ++ print_symbol("stack corrupted in: %s\n", (unsigned long)__builtin_return_address(0));
35265 ++ dump_stack();
35266 + panic("stack-protector: Kernel stack is corrupted");
35267 + }
35268 + EXPORT_SYMBOL(__stack_chk_fail);
35269 +diff -urNp linux-2.6.26.6/kernel/pid.c linux-2.6.26.6/kernel/pid.c
35270 +--- linux-2.6.26.6/kernel/pid.c 2008-10-08 23:24:05.000000000 -0400
35271 ++++ linux-2.6.26.6/kernel/pid.c 2008-10-11 21:54:20.000000000 -0400
35272 +@@ -35,6 +35,7 @@
35273 + #include <linux/pid_namespace.h>
35274 + #include <linux/init_task.h>
35275 + #include <linux/syscalls.h>
35276 ++#include <linux/grsecurity.h>
35277 +
35278 + #define pid_hashfn(nr, ns) \
35279 + hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
35280 +@@ -44,7 +45,7 @@ struct pid init_struct_pid = INIT_STRUCT
35281 +
35282 + int pid_max = PID_MAX_DEFAULT;
35283 +
35284 +-#define RESERVED_PIDS 300
35285 ++#define RESERVED_PIDS 500
35286 +
35287 + int pid_max_min = RESERVED_PIDS + 1;
35288 + int pid_max_max = PID_MAX_LIMIT;
35289 +@@ -386,7 +387,14 @@ EXPORT_SYMBOL(pid_task);
35290 + struct task_struct *find_task_by_pid_type_ns(int type, int nr,
35291 + struct pid_namespace *ns)
35292 + {
35293 +- return pid_task(find_pid_ns(nr, ns), type);
35294 ++ struct task_struct *task;
35295 ++
35296 ++ task = pid_task(find_pid_ns(nr, ns), type);
35297 ++
35298 ++ if (gr_pid_is_chrooted(task))
35299 ++ return NULL;
35300 ++
35301 ++ return task;
35302 + }
35303 +
35304 + EXPORT_SYMBOL(find_task_by_pid_type_ns);
35305 +diff -urNp linux-2.6.26.6/kernel/posix-cpu-timers.c linux-2.6.26.6/kernel/posix-cpu-timers.c
35306 +--- linux-2.6.26.6/kernel/posix-cpu-timers.c 2008-10-08 23:24:05.000000000 -0400
35307 ++++ linux-2.6.26.6/kernel/posix-cpu-timers.c 2008-10-11 21:55:52.000000000 -0400
35308 +@@ -6,6 +6,7 @@
35309 + #include <linux/posix-timers.h>
35310 + #include <linux/errno.h>
35311 + #include <linux/math64.h>
35312 ++#include <linux/grsecurity.h>
35313 + #include <asm/uaccess.h>
35314 +
35315 + static int check_clock(const clockid_t which_clock)
35316 +@@ -1173,6 +1174,7 @@ static void check_process_timers(struct
35317 + __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
35318 + return;
35319 + }
35320 ++ gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1);
35321 + if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
35322 + /*
35323 + * At the soft limit, send a SIGXCPU every second.
35324 +@@ -1367,17 +1369,17 @@ void run_posix_cpu_timers(struct task_st
35325 + * timer call will interfere.
35326 + */
35327 + list_for_each_entry_safe(timer, next, &firing, it.cpu.entry) {
35328 +- int firing;
35329 ++ int __firing;
35330 + spin_lock(&timer->it_lock);
35331 + list_del_init(&timer->it.cpu.entry);
35332 +- firing = timer->it.cpu.firing;
35333 ++ __firing = timer->it.cpu.firing;
35334 + timer->it.cpu.firing = 0;
35335 + /*
35336 + * The firing flag is -1 if we collided with a reset
35337 + * of the timer, which already reported this
35338 + * almost-firing as an overrun. So don't generate an event.
35339 + */
35340 +- if (likely(firing >= 0)) {
35341 ++ if (likely(__firing >= 0)) {
35342 + cpu_timer_fire(timer);
35343 + }
35344 + spin_unlock(&timer->it_lock);
35345 +diff -urNp linux-2.6.26.6/kernel/power/poweroff.c linux-2.6.26.6/kernel/power/poweroff.c
35346 +--- linux-2.6.26.6/kernel/power/poweroff.c 2008-10-08 23:24:05.000000000 -0400
35347 ++++ linux-2.6.26.6/kernel/power/poweroff.c 2008-10-11 21:54:20.000000000 -0400
35348 +@@ -35,7 +35,7 @@ static struct sysrq_key_op sysrq_powerof
35349 + .enable_mask = SYSRQ_ENABLE_BOOT,
35350 + };
35351 +
35352 +-static int pm_sysrq_init(void)
35353 ++static int __init pm_sysrq_init(void)
35354 + {
35355 + register_sysrq_key('o', &sysrq_poweroff_op);
35356 + return 0;
35357 +diff -urNp linux-2.6.26.6/kernel/printk.c linux-2.6.26.6/kernel/printk.c
35358 +--- linux-2.6.26.6/kernel/printk.c 2008-10-08 23:24:05.000000000 -0400
35359 ++++ linux-2.6.26.6/kernel/printk.c 2008-10-11 21:54:20.000000000 -0400
35360 +@@ -32,6 +32,7 @@
35361 + #include <linux/security.h>
35362 + #include <linux/bootmem.h>
35363 + #include <linux/syscalls.h>
35364 ++#include <linux/grsecurity.h>
35365 +
35366 + #include <asm/uaccess.h>
35367 +
35368 +@@ -302,6 +303,11 @@ int do_syslog(int type, char __user *buf
35369 + char c;
35370 + int error = 0;
35371 +
35372 ++#ifdef CONFIG_GRKERNSEC_DMESG
35373 ++ if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
35374 ++ return -EPERM;
35375 ++#endif
35376 ++
35377 + error = security_syslog(type);
35378 + if (error)
35379 + return error;
35380 +diff -urNp linux-2.6.26.6/kernel/ptrace.c linux-2.6.26.6/kernel/ptrace.c
35381 +--- linux-2.6.26.6/kernel/ptrace.c 2008-10-08 23:24:05.000000000 -0400
35382 ++++ linux-2.6.26.6/kernel/ptrace.c 2008-10-11 21:54:20.000000000 -0400
35383 +@@ -21,6 +21,7 @@
35384 + #include <linux/audit.h>
35385 + #include <linux/pid_namespace.h>
35386 + #include <linux/syscalls.h>
35387 ++#include <linux/grsecurity.h>
35388 +
35389 + #include <asm/pgtable.h>
35390 + #include <asm/uaccess.h>
35391 +@@ -140,12 +141,12 @@ int __ptrace_may_attach(struct task_stru
35392 + (current->uid != task->uid) ||
35393 + (current->gid != task->egid) ||
35394 + (current->gid != task->sgid) ||
35395 +- (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
35396 ++ (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
35397 + return -EPERM;
35398 + smp_rmb();
35399 + if (task->mm)
35400 + dumpable = get_dumpable(task->mm);
35401 +- if (!dumpable && !capable(CAP_SYS_PTRACE))
35402 ++ if (!dumpable && !capable_nolog(CAP_SYS_PTRACE))
35403 + return -EPERM;
35404 +
35405 + return security_ptrace(current, task);
35406 +@@ -201,7 +202,7 @@ repeat:
35407 +
35408 + /* Go */
35409 + task->ptrace |= PT_PTRACED;
35410 +- if (capable(CAP_SYS_PTRACE))
35411 ++ if (capable_nolog(CAP_SYS_PTRACE))
35412 + task->ptrace |= PT_PTRACE_CAP;
35413 +
35414 + __ptrace_link(task, current);
35415 +@@ -571,6 +572,11 @@ asmlinkage long sys_ptrace(long request,
35416 + if (ret < 0)
35417 + goto out_put_task_struct;
35418 +
35419 ++ if (gr_handle_ptrace(child, request)) {
35420 ++ ret = -EPERM;
35421 ++ goto out_put_task_struct;
35422 ++ }
35423 ++
35424 + ret = arch_ptrace(child, request, addr, data);
35425 + if (ret < 0)
35426 + goto out_put_task_struct;
35427 +diff -urNp linux-2.6.26.6/kernel/relay.c linux-2.6.26.6/kernel/relay.c
35428 +--- linux-2.6.26.6/kernel/relay.c 2008-10-08 23:24:05.000000000 -0400
35429 ++++ linux-2.6.26.6/kernel/relay.c 2008-10-11 21:54:20.000000000 -0400
35430 +@@ -1179,7 +1179,7 @@ static int subbuf_splice_actor(struct fi
35431 + return 0;
35432 +
35433 + ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
35434 +- if (ret < 0 || ret < total_len)
35435 ++ if ((int)ret < 0 || ret < total_len)
35436 + return ret;
35437 +
35438 + if (read_start + ret == nonpad_end)
35439 +diff -urNp linux-2.6.26.6/kernel/resource.c linux-2.6.26.6/kernel/resource.c
35440 +--- linux-2.6.26.6/kernel/resource.c 2008-10-08 23:24:05.000000000 -0400
35441 ++++ linux-2.6.26.6/kernel/resource.c 2008-10-11 21:54:20.000000000 -0400
35442 +@@ -131,8 +131,18 @@ static const struct file_operations proc
35443 +
35444 + static int __init ioresources_init(void)
35445 + {
35446 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
35447 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
35448 ++ proc_create("ioports", S_IRUSR, NULL, &proc_ioports_operations);
35449 ++ proc_create("iomem", S_IRUSR, NULL, &proc_iomem_operations);
35450 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
35451 ++ proc_create("ioports", S_IRUSR | S_IRGRP, NULL, &proc_ioports_operations);
35452 ++ proc_create("iomem", S_IRUSR | S_IRGRP, NULL, &proc_iomem_operations);
35453 ++#endif
35454 ++#else
35455 + proc_create("ioports", 0, NULL, &proc_ioports_operations);
35456 + proc_create("iomem", 0, NULL, &proc_iomem_operations);
35457 ++#endif
35458 + return 0;
35459 + }
35460 + __initcall(ioresources_init);
35461 +diff -urNp linux-2.6.26.6/kernel/sched.c linux-2.6.26.6/kernel/sched.c
35462 +--- linux-2.6.26.6/kernel/sched.c 2008-10-08 23:24:05.000000000 -0400
35463 ++++ linux-2.6.26.6/kernel/sched.c 2008-10-11 21:54:20.000000000 -0400
35464 +@@ -70,6 +70,7 @@
35465 + #include <linux/bootmem.h>
35466 + #include <linux/debugfs.h>
35467 + #include <linux/ctype.h>
35468 ++#include <linux/grsecurity.h>
35469 +
35470 + #include <asm/tlb.h>
35471 + #include <asm/irq_regs.h>
35472 +@@ -4714,7 +4715,8 @@ asmlinkage long sys_nice(int increment)
35473 + if (nice > 19)
35474 + nice = 19;
35475 +
35476 +- if (increment < 0 && !can_nice(current, nice))
35477 ++ if (increment < 0 && (!can_nice(current, nice) ||
35478 ++ gr_handle_chroot_nice()))
35479 + return -EPERM;
35480 +
35481 + retval = security_task_setnice(current, nice);
35482 +@@ -5961,7 +5963,7 @@ static struct ctl_table sd_ctl_dir[] = {
35483 + .procname = "sched_domain",
35484 + .mode = 0555,
35485 + },
35486 +- {0, },
35487 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
35488 + };
35489 +
35490 + static struct ctl_table sd_ctl_root[] = {
35491 +@@ -5971,7 +5973,7 @@ static struct ctl_table sd_ctl_root[] =
35492 + .mode = 0555,
35493 + .child = sd_ctl_dir,
35494 + },
35495 +- {0, },
35496 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
35497 + };
35498 +
35499 + static struct ctl_table *sd_alloc_ctl_entry(int n)
35500 +diff -urNp linux-2.6.26.6/kernel/signal.c linux-2.6.26.6/kernel/signal.c
35501 +--- linux-2.6.26.6/kernel/signal.c 2008-10-08 23:24:05.000000000 -0400
35502 ++++ linux-2.6.26.6/kernel/signal.c 2008-10-11 21:55:52.000000000 -0400
35503 +@@ -25,6 +25,7 @@
35504 + #include <linux/capability.h>
35505 + #include <linux/freezer.h>
35506 + #include <linux/pid_namespace.h>
35507 ++#include <linux/grsecurity.h>
35508 + #include <linux/nsproxy.h>
35509 +
35510 + #include <asm/param.h>
35511 +@@ -597,6 +598,9 @@ static int check_kill_permission(int sig
35512 + }
35513 + }
35514 +
35515 ++ if (gr_handle_signal(t, sig))
35516 ++ return -EPERM;
35517 ++
35518 + return security_task_kill(t, info, sig, 0);
35519 + }
35520 +
35521 +@@ -888,8 +892,8 @@ static void print_fatal_signal(struct pt
35522 + for (i = 0; i < 16; i++) {
35523 + unsigned char insn;
35524 +
35525 +- __get_user(insn, (unsigned char *)(regs->ip + i));
35526 +- printk("%02x ", insn);
35527 ++ if (!get_user(insn, (unsigned char __user *)(regs->ip + i)))
35528 ++ printk("%02x ", insn);
35529 + }
35530 + }
35531 + #endif
35532 +@@ -912,7 +916,7 @@ __group_send_sig_info(int sig, struct si
35533 + return send_signal(sig, info, p, 1);
35534 + }
35535 +
35536 +-static int
35537 ++int
35538 + specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
35539 + {
35540 + return send_signal(sig, info, t, 0);
35541 +@@ -950,8 +954,12 @@ force_sig_info(int sig, struct siginfo *
35542 + if (action->sa.sa_handler == SIG_DFL)
35543 + t->signal->flags &= ~SIGNAL_UNKILLABLE;
35544 + ret = specific_send_sig_info(sig, info, t);
35545 ++
35546 + spin_unlock_irqrestore(&t->sighand->siglock, flags);
35547 +
35548 ++ gr_log_signal(sig, t);
35549 ++ gr_handle_crash(t, sig);
35550 ++
35551 + return ret;
35552 + }
35553 +
35554 +@@ -1022,6 +1030,8 @@ int group_send_sig_info(int sig, struct
35555 + ret = __group_send_sig_info(sig, info, p);
35556 + unlock_task_sighand(p, &flags);
35557 + }
35558 ++ if (!ret)
35559 ++ gr_log_signal(sig, p);
35560 + }
35561 +
35562 + return ret;
35563 +diff -urNp linux-2.6.26.6/kernel/softirq.c linux-2.6.26.6/kernel/softirq.c
35564 +--- linux-2.6.26.6/kernel/softirq.c 2008-10-08 23:24:05.000000000 -0400
35565 ++++ linux-2.6.26.6/kernel/softirq.c 2008-10-11 21:54:20.000000000 -0400
35566 +@@ -482,9 +482,9 @@ void tasklet_kill(struct tasklet_struct
35567 + printk("Attempt to kill tasklet from interrupt\n");
35568 +
35569 + while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
35570 +- do
35571 ++ do {
35572 + yield();
35573 +- while (test_bit(TASKLET_STATE_SCHED, &t->state));
35574 ++ } while (test_bit(TASKLET_STATE_SCHED, &t->state));
35575 + }
35576 + tasklet_unlock_wait(t);
35577 + clear_bit(TASKLET_STATE_SCHED, &t->state);
35578 +diff -urNp linux-2.6.26.6/kernel/sys.c linux-2.6.26.6/kernel/sys.c
35579 +--- linux-2.6.26.6/kernel/sys.c 2008-10-08 23:24:05.000000000 -0400
35580 ++++ linux-2.6.26.6/kernel/sys.c 2008-10-11 21:54:20.000000000 -0400
35581 +@@ -33,6 +33,7 @@
35582 + #include <linux/task_io_accounting_ops.h>
35583 + #include <linux/seccomp.h>
35584 + #include <linux/cpu.h>
35585 ++#include <linux/grsecurity.h>
35586 +
35587 + #include <linux/compat.h>
35588 + #include <linux/syscalls.h>
35589 +@@ -125,6 +126,12 @@ static int set_one_prio(struct task_stru
35590 + error = -EACCES;
35591 + goto out;
35592 + }
35593 ++
35594 ++ if (gr_handle_chroot_setpriority(p, niceval)) {
35595 ++ error = -EACCES;
35596 ++ goto out;
35597 ++ }
35598 ++
35599 + no_nice = security_task_setnice(p, niceval);
35600 + if (no_nice) {
35601 + error = no_nice;
35602 +@@ -181,10 +188,10 @@ asmlinkage long sys_setpriority(int whic
35603 + if ((who != current->uid) && !(user = find_user(who)))
35604 + goto out_unlock; /* No processes for this user */
35605 +
35606 +- do_each_thread(g, p)
35607 ++ do_each_thread(g, p) {
35608 + if (p->uid == who)
35609 + error = set_one_prio(p, niceval, error);
35610 +- while_each_thread(g, p);
35611 ++ } while_each_thread(g, p);
35612 + if (who != current->uid)
35613 + free_uid(user); /* For find_user() */
35614 + break;
35615 +@@ -243,13 +250,13 @@ asmlinkage long sys_getpriority(int whic
35616 + if ((who != current->uid) && !(user = find_user(who)))
35617 + goto out_unlock; /* No processes for this user */
35618 +
35619 +- do_each_thread(g, p)
35620 ++ do_each_thread(g, p) {
35621 + if (p->uid == who) {
35622 + niceval = 20 - task_nice(p);
35623 + if (niceval > retval)
35624 + retval = niceval;
35625 + }
35626 +- while_each_thread(g, p);
35627 ++ } while_each_thread(g, p);
35628 + if (who != current->uid)
35629 + free_uid(user); /* for find_user() */
35630 + break;
35631 +@@ -514,6 +521,10 @@ asmlinkage long sys_setregid(gid_t rgid,
35632 + else
35633 + return -EPERM;
35634 + }
35635 ++
35636 ++ if (gr_check_group_change(new_rgid, new_egid, -1))
35637 ++ return -EPERM;
35638 ++
35639 + if (new_egid != old_egid) {
35640 + set_dumpable(current->mm, suid_dumpable);
35641 + smp_wmb();
35642 +@@ -521,6 +532,9 @@ asmlinkage long sys_setregid(gid_t rgid,
35643 + if (rgid != (gid_t) -1 ||
35644 + (egid != (gid_t) -1 && egid != old_rgid))
35645 + current->sgid = new_egid;
35646 ++
35647 ++ gr_set_role_label(current, current->uid, new_rgid);
35648 ++
35649 + current->fsgid = new_egid;
35650 + current->egid = new_egid;
35651 + current->gid = new_rgid;
35652 +@@ -543,11 +557,17 @@ asmlinkage long sys_setgid(gid_t gid)
35653 + if (retval)
35654 + return retval;
35655 +
35656 ++ if (gr_check_group_change(gid, gid, gid))
35657 ++ return -EPERM;
35658 ++
35659 + if (capable(CAP_SETGID)) {
35660 + if (old_egid != gid) {
35661 + set_dumpable(current->mm, suid_dumpable);
35662 + smp_wmb();
35663 + }
35664 ++
35665 ++ gr_set_role_label(current, current->uid, gid);
35666 ++
35667 + current->gid = current->egid = current->sgid = current->fsgid = gid;
35668 + } else if ((gid == current->gid) || (gid == current->sgid)) {
35669 + if (old_egid != gid) {
35670 +@@ -585,6 +605,9 @@ static int set_user(uid_t new_ruid, int
35671 + set_dumpable(current->mm, suid_dumpable);
35672 + smp_wmb();
35673 + }
35674 ++
35675 ++ gr_set_role_label(current, new_ruid, current->gid);
35676 ++
35677 + current->uid = new_ruid;
35678 + return 0;
35679 + }
35680 +@@ -634,6 +657,9 @@ asmlinkage long sys_setreuid(uid_t ruid,
35681 + return -EPERM;
35682 + }
35683 +
35684 ++ if (gr_check_user_change(new_ruid, new_euid, -1))
35685 ++ return -EPERM;
35686 ++
35687 + if (new_ruid != old_ruid && set_user(new_ruid, new_euid != old_euid) < 0)
35688 + return -EAGAIN;
35689 +
35690 +@@ -680,6 +706,12 @@ asmlinkage long sys_setuid(uid_t uid)
35691 + old_suid = current->suid;
35692 + new_suid = old_suid;
35693 +
35694 ++ if (gr_check_crash_uid(uid))
35695 ++ return -EPERM;
35696 ++
35697 ++ if (gr_check_user_change(uid, uid, uid))
35698 ++ return -EPERM;
35699 ++
35700 + if (capable(CAP_SETUID)) {
35701 + if (uid != old_ruid && set_user(uid, old_euid != uid) < 0)
35702 + return -EAGAIN;
35703 +@@ -727,6 +759,10 @@ asmlinkage long sys_setresuid(uid_t ruid
35704 + (suid != current->euid) && (suid != current->suid))
35705 + return -EPERM;
35706 + }
35707 ++
35708 ++ if (gr_check_user_change(ruid, euid, -1))
35709 ++ return -EPERM;
35710 ++
35711 + if (ruid != (uid_t) -1) {
35712 + if (ruid != current->uid && set_user(ruid, euid != current->euid) < 0)
35713 + return -EAGAIN;
35714 +@@ -781,6 +817,10 @@ asmlinkage long sys_setresgid(gid_t rgid
35715 + (sgid != current->egid) && (sgid != current->sgid))
35716 + return -EPERM;
35717 + }
35718 ++
35719 ++ if (gr_check_group_change(rgid, egid, -1))
35720 ++ return -EPERM;
35721 ++
35722 + if (egid != (gid_t) -1) {
35723 + if (egid != current->egid) {
35724 + set_dumpable(current->mm, suid_dumpable);
35725 +@@ -789,8 +829,10 @@ asmlinkage long sys_setresgid(gid_t rgid
35726 + current->egid = egid;
35727 + }
35728 + current->fsgid = current->egid;
35729 +- if (rgid != (gid_t) -1)
35730 ++ if (rgid != (gid_t) -1) {
35731 ++ gr_set_role_label(current, current->uid, rgid);
35732 + current->gid = rgid;
35733 ++ }
35734 + if (sgid != (gid_t) -1)
35735 + current->sgid = sgid;
35736 +
35737 +@@ -825,6 +867,9 @@ asmlinkage long sys_setfsuid(uid_t uid)
35738 + if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS))
35739 + return old_fsuid;
35740 +
35741 ++ if (gr_check_user_change(-1, -1, uid))
35742 ++ return old_fsuid;
35743 ++
35744 + if (uid == current->uid || uid == current->euid ||
35745 + uid == current->suid || uid == current->fsuid ||
35746 + capable(CAP_SETUID)) {
35747 +@@ -857,6 +902,9 @@ asmlinkage long sys_setfsgid(gid_t gid)
35748 + if (gid == current->gid || gid == current->egid ||
35749 + gid == current->sgid || gid == current->fsgid ||
35750 + capable(CAP_SETGID)) {
35751 ++ if (gr_check_group_change(-1, -1, gid))
35752 ++ return old_fsgid;
35753 ++
35754 + if (gid != old_fsgid) {
35755 + set_dumpable(current->mm, suid_dumpable);
35756 + smp_wmb();
35757 +@@ -938,7 +986,10 @@ asmlinkage long sys_setpgid(pid_t pid, p
35758 + write_lock_irq(&tasklist_lock);
35759 +
35760 + err = -ESRCH;
35761 +- p = find_task_by_vpid(pid);
35762 ++ /* grsec: replaced find_task_by_vpid with equivalent call which
35763 ++ lacks the chroot restriction
35764 ++ */
35765 ++ p = pid_task(find_pid_ns(pid, current->nsproxy->pid_ns), PIDTYPE_PID);
35766 + if (!p)
35767 + goto out;
35768 +
35769 +@@ -1672,7 +1723,7 @@ asmlinkage long sys_prctl(int option, un
35770 + error = get_dumpable(current->mm);
35771 + break;
35772 + case PR_SET_DUMPABLE:
35773 +- if (arg2 < 0 || arg2 > 1) {
35774 ++ if (arg2 > 1) {
35775 + error = -EINVAL;
35776 + break;
35777 + }
35778 +diff -urNp linux-2.6.26.6/kernel/sysctl.c linux-2.6.26.6/kernel/sysctl.c
35779 +--- linux-2.6.26.6/kernel/sysctl.c 2008-10-08 23:24:05.000000000 -0400
35780 ++++ linux-2.6.26.6/kernel/sysctl.c 2008-10-11 21:54:20.000000000 -0400
35781 +@@ -59,6 +59,13 @@
35782 + static int deprecated_sysctl_warning(struct __sysctl_args *args);
35783 +
35784 + #if defined(CONFIG_SYSCTL)
35785 ++#include <linux/grsecurity.h>
35786 ++#include <linux/grinternal.h>
35787 ++
35788 ++extern __u32 gr_handle_sysctl(const ctl_table *table, const int op);
35789 ++extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
35790 ++ const int op);
35791 ++extern int gr_handle_chroot_sysctl(const int op);
35792 +
35793 + /* External variables not in a header file. */
35794 + extern int C_A_D;
35795 +@@ -152,6 +159,7 @@ static int proc_do_cad_pid(struct ctl_ta
35796 + static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp,
35797 + void __user *buffer, size_t *lenp, loff_t *ppos);
35798 + #endif
35799 ++extern ctl_table grsecurity_table[];
35800 +
35801 + static struct ctl_table root_table[];
35802 + static struct ctl_table_root sysctl_table_root;
35803 +@@ -179,6 +187,21 @@ extern struct ctl_table inotify_table[];
35804 + int sysctl_legacy_va_layout;
35805 + #endif
35806 +
35807 ++#ifdef CONFIG_PAX_SOFTMODE
35808 ++static ctl_table pax_table[] = {
35809 ++ {
35810 ++ .ctl_name = CTL_UNNUMBERED,
35811 ++ .procname = "softmode",
35812 ++ .data = &pax_softmode,
35813 ++ .maxlen = sizeof(unsigned int),
35814 ++ .mode = 0600,
35815 ++ .proc_handler = &proc_dointvec,
35816 ++ },
35817 ++
35818 ++ { .ctl_name = 0 }
35819 ++};
35820 ++#endif
35821 ++
35822 + extern int prove_locking;
35823 + extern int lock_stat;
35824 +
35825 +@@ -215,6 +238,7 @@ static struct ctl_table root_table[] = {
35826 + .mode = 0555,
35827 + .child = dev_table,
35828 + },
35829 ++
35830 + /*
35831 + * NOTE: do not add new entries to this table unless you have read
35832 + * Documentation/sysctl/ctl_unnumbered.txt
35833 +@@ -813,6 +837,25 @@ static struct ctl_table kern_table[] = {
35834 + .child = key_sysctls,
35835 + },
35836 + #endif
35837 ++
35838 ++#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
35839 ++ {
35840 ++ .ctl_name = CTL_UNNUMBERED,
35841 ++ .procname = "grsecurity",
35842 ++ .mode = 0500,
35843 ++ .child = grsecurity_table,
35844 ++ },
35845 ++#endif
35846 ++
35847 ++#ifdef CONFIG_PAX_SOFTMODE
35848 ++ {
35849 ++ .ctl_name = CTL_UNNUMBERED,
35850 ++ .procname = "pax",
35851 ++ .mode = 0500,
35852 ++ .child = pax_table,
35853 ++ },
35854 ++#endif
35855 ++
35856 + /*
35857 + * NOTE: do not add new entries to this table unless you have read
35858 + * Documentation/sysctl/ctl_unnumbered.txt
35859 +@@ -1140,6 +1183,7 @@ static struct ctl_table vm_table[] = {
35860 + .extra2 = &one,
35861 + },
35862 + #endif
35863 ++
35864 + /*
35865 + * NOTE: do not add new entries to this table unless you have read
35866 + * Documentation/sysctl/ctl_unnumbered.txt
35867 +@@ -1472,6 +1516,8 @@ static int do_sysctl_strategy(struct ctl
35868 + return 0;
35869 + }
35870 +
35871 ++static int sysctl_perm_nochk(struct ctl_table_root *root, struct ctl_table *table, int op);
35872 ++
35873 + static int parse_table(int __user *name, int nlen,
35874 + void __user *oldval, size_t __user *oldlenp,
35875 + void __user *newval, size_t newlen,
35876 +@@ -1490,7 +1536,7 @@ repeat:
35877 + if (n == table->ctl_name) {
35878 + int error;
35879 + if (table->child) {
35880 +- if (sysctl_perm(root, table, 001))
35881 ++ if (sysctl_perm_nochk(root, table, 001))
35882 + return -EPERM;
35883 + name++;
35884 + nlen--;
35885 +@@ -1575,6 +1621,33 @@ int sysctl_perm(struct ctl_table_root *r
35886 + int error;
35887 + int mode;
35888 +
35889 ++ if (table->parent != NULL && table->parent->procname != NULL &&
35890 ++ table->procname != NULL &&
35891 ++ gr_handle_sysctl_mod(table->parent->procname, table->procname, op))
35892 ++ return -EACCES;
35893 ++ if (gr_handle_chroot_sysctl(op))
35894 ++ return -EACCES;
35895 ++ error = gr_handle_sysctl(table, op);
35896 ++ if (error)
35897 ++ return error;
35898 ++
35899 ++ error = security_sysctl(table, op);
35900 ++ if (error)
35901 ++ return error;
35902 ++
35903 ++ if (root->permissions)
35904 ++ mode = root->permissions(root, current->nsproxy, table);
35905 ++ else
35906 ++ mode = table->mode;
35907 ++
35908 ++ return test_perm(mode, op);
35909 ++}
35910 ++
35911 ++static int sysctl_perm_nochk(struct ctl_table_root *root, struct ctl_table *table, int op)
35912 ++{
35913 ++ int error;
35914 ++ int mode;
35915 ++
35916 + error = security_sysctl(table, op);
35917 + if (error)
35918 + return error;
35919 +diff -urNp linux-2.6.26.6/kernel/time/tick-broadcast.c linux-2.6.26.6/kernel/time/tick-broadcast.c
35920 +--- linux-2.6.26.6/kernel/time/tick-broadcast.c 2008-10-08 23:24:05.000000000 -0400
35921 ++++ linux-2.6.26.6/kernel/time/tick-broadcast.c 2008-10-11 21:55:52.000000000 -0400
35922 +@@ -113,7 +113,7 @@ int tick_device_uses_broadcast(struct cl
35923 + * then clear the broadcast bit.
35924 + */
35925 + if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) {
35926 +- int cpu = smp_processor_id();
35927 ++ cpu = smp_processor_id();
35928 +
35929 + cpu_clear(cpu, tick_broadcast_mask);
35930 + tick_broadcast_clear_oneshot(cpu);
35931 +diff -urNp linux-2.6.26.6/kernel/time.c linux-2.6.26.6/kernel/time.c
35932 +--- linux-2.6.26.6/kernel/time.c 2008-10-08 23:24:05.000000000 -0400
35933 ++++ linux-2.6.26.6/kernel/time.c 2008-10-11 21:54:20.000000000 -0400
35934 +@@ -37,6 +37,7 @@
35935 + #include <linux/fs.h>
35936 + #include <linux/slab.h>
35937 + #include <linux/math64.h>
35938 ++#include <linux/grsecurity.h>
35939 +
35940 + #include <asm/uaccess.h>
35941 + #include <asm/unistd.h>
35942 +@@ -92,6 +93,9 @@ asmlinkage long sys_stime(time_t __user
35943 + return err;
35944 +
35945 + do_settimeofday(&tv);
35946 ++
35947 ++ gr_log_timechange();
35948 ++
35949 + return 0;
35950 + }
35951 +
35952 +@@ -200,6 +204,8 @@ asmlinkage long sys_settimeofday(struct
35953 + return -EFAULT;
35954 + }
35955 +
35956 ++ gr_log_timechange();
35957 ++
35958 + return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
35959 + }
35960 +
35961 +@@ -238,7 +244,7 @@ EXPORT_SYMBOL(current_fs_time);
35962 + * Avoid unnecessary multiplications/divisions in the
35963 + * two most common HZ cases:
35964 + */
35965 +-unsigned int inline jiffies_to_msecs(const unsigned long j)
35966 ++inline unsigned int jiffies_to_msecs(const unsigned long j)
35967 + {
35968 + #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
35969 + return (MSEC_PER_SEC / HZ) * j;
35970 +@@ -254,7 +260,7 @@ unsigned int inline jiffies_to_msecs(con
35971 + }
35972 + EXPORT_SYMBOL(jiffies_to_msecs);
35973 +
35974 +-unsigned int inline jiffies_to_usecs(const unsigned long j)
35975 ++inline unsigned int jiffies_to_usecs(const unsigned long j)
35976 + {
35977 + #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
35978 + return (USEC_PER_SEC / HZ) * j;
35979 +diff -urNp linux-2.6.26.6/kernel/utsname_sysctl.c linux-2.6.26.6/kernel/utsname_sysctl.c
35980 +--- linux-2.6.26.6/kernel/utsname_sysctl.c 2008-10-08 23:24:05.000000000 -0400
35981 ++++ linux-2.6.26.6/kernel/utsname_sysctl.c 2008-10-11 21:54:20.000000000 -0400
35982 +@@ -125,7 +125,7 @@ static struct ctl_table uts_kern_table[]
35983 + .proc_handler = proc_do_uts_string,
35984 + .strategy = sysctl_uts_string,
35985 + },
35986 +- {}
35987 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
35988 + };
35989 +
35990 + static struct ctl_table uts_root_table[] = {
35991 +@@ -135,7 +135,7 @@ static struct ctl_table uts_root_table[]
35992 + .mode = 0555,
35993 + .child = uts_kern_table,
35994 + },
35995 +- {}
35996 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
35997 + };
35998 +
35999 + static int __init utsname_sysctl_init(void)
36000 +diff -urNp linux-2.6.26.6/lib/radix-tree.c linux-2.6.26.6/lib/radix-tree.c
36001 +--- linux-2.6.26.6/lib/radix-tree.c 2008-10-08 23:24:05.000000000 -0400
36002 ++++ linux-2.6.26.6/lib/radix-tree.c 2008-10-11 21:54:20.000000000 -0400
36003 +@@ -81,7 +81,7 @@ struct radix_tree_preload {
36004 + int nr;
36005 + struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
36006 + };
36007 +-DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
36008 ++DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads);
36009 +
36010 + static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
36011 + {
36012 +diff -urNp linux-2.6.26.6/localversion-grsec linux-2.6.26.6/localversion-grsec
36013 +--- linux-2.6.26.6/localversion-grsec 1969-12-31 19:00:00.000000000 -0500
36014 ++++ linux-2.6.26.6/localversion-grsec 2008-10-11 21:54:20.000000000 -0400
36015 +@@ -0,0 +1 @@
36016 ++-grsec
36017 +diff -urNp linux-2.6.26.6/Makefile linux-2.6.26.6/Makefile
36018 +--- linux-2.6.26.6/Makefile 2008-10-08 23:24:05.000000000 -0400
36019 ++++ linux-2.6.26.6/Makefile 2008-10-11 21:54:20.000000000 -0400
36020 +@@ -214,7 +214,7 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH"
36021 +
36022 + HOSTCC = gcc
36023 + HOSTCXX = g++
36024 +-HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
36025 ++HOSTCFLAGS = -Wall -W -Wno-unused -Wno-sign-compare -Wstrict-prototypes -O2 -fomit-frame-pointer
36026 + HOSTCXXFLAGS = -O2
36027 +
36028 + # Decide whether to build built-in, modular, or both.
36029 +@@ -607,7 +607,7 @@ export mod_strip_cmd
36030 +
36031 +
36032 + ifeq ($(KBUILD_EXTMOD),)
36033 +-core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
36034 ++core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
36035 +
36036 + vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
36037 + $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
36038 +diff -urNp linux-2.6.26.6/mm/filemap.c linux-2.6.26.6/mm/filemap.c
36039 +--- linux-2.6.26.6/mm/filemap.c 2008-10-08 23:24:05.000000000 -0400
36040 ++++ linux-2.6.26.6/mm/filemap.c 2008-10-11 21:54:20.000000000 -0400
36041 +@@ -33,6 +33,7 @@
36042 + #include <linux/cpuset.h>
36043 + #include <linux/hardirq.h> /* for BUG_ON(!in_atomic()) only */
36044 + #include <linux/memcontrol.h>
36045 ++#include <linux/grsecurity.h>
36046 + #include "internal.h"
36047 +
36048 + /*
36049 +@@ -1488,7 +1489,7 @@ int generic_file_mmap(struct file * file
36050 + struct address_space *mapping = file->f_mapping;
36051 +
36052 + if (!mapping->a_ops->readpage)
36053 +- return -ENOEXEC;
36054 ++ return -ENODEV;
36055 + file_accessed(file);
36056 + vma->vm_ops = &generic_file_vm_ops;
36057 + vma->vm_flags |= VM_CAN_NONLINEAR;
36058 +@@ -1848,6 +1849,7 @@ inline int generic_write_checks(struct f
36059 + *pos = i_size_read(inode);
36060 +
36061 + if (limit != RLIM_INFINITY) {
36062 ++ gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
36063 + if (*pos >= limit) {
36064 + send_sig(SIGXFSZ, current, 0);
36065 + return -EFBIG;
36066 +diff -urNp linux-2.6.26.6/mm/fremap.c linux-2.6.26.6/mm/fremap.c
36067 +--- linux-2.6.26.6/mm/fremap.c 2008-10-08 23:24:05.000000000 -0400
36068 ++++ linux-2.6.26.6/mm/fremap.c 2008-10-11 21:54:20.000000000 -0400
36069 +@@ -150,6 +150,13 @@ asmlinkage long sys_remap_file_pages(uns
36070 + retry:
36071 + vma = find_vma(mm, start);
36072 +
36073 ++#ifdef CONFIG_PAX_SEGMEXEC
36074 ++ if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC)) {
36075 ++ up_read(&mm->mmap_sem);
36076 ++ return err;
36077 ++ }
36078 ++#endif
36079 ++
36080 + /*
36081 + * Make sure the vma is shared, that it supports prefaulting,
36082 + * and that the remapped range is valid and fully within
36083 +diff -urNp linux-2.6.26.6/mm/hugetlb.c linux-2.6.26.6/mm/hugetlb.c
36084 +--- linux-2.6.26.6/mm/hugetlb.c 2008-10-08 23:24:05.000000000 -0400
36085 ++++ linux-2.6.26.6/mm/hugetlb.c 2008-10-11 21:55:52.000000000 -0400
36086 +@@ -603,7 +603,6 @@ static unsigned long set_max_huge_pages(
36087 + }
36088 +
36089 + while (count > persistent_huge_pages) {
36090 +- int ret;
36091 + /*
36092 + * If this allocation races such that we no longer need the
36093 + * page, free_huge_page will handle it by freeing the page
36094 +@@ -867,6 +866,26 @@ void unmap_hugepage_range(struct vm_area
36095 + }
36096 + }
36097 +
36098 ++#ifdef CONFIG_PAX_SEGMEXEC
36099 ++static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m)
36100 ++{
36101 ++ struct mm_struct *mm = vma->vm_mm;
36102 ++ struct vm_area_struct *vma_m;
36103 ++ unsigned long address_m;
36104 ++ pte_t *ptep_m;
36105 ++
36106 ++ vma_m = pax_find_mirror_vma(vma);
36107 ++ if (!vma_m)
36108 ++ return;
36109 ++
36110 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
36111 ++ address_m = address + SEGMEXEC_TASK_SIZE;
36112 ++ ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK);
36113 ++ get_page(page_m);
36114 ++ set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0));
36115 ++}
36116 ++#endif
36117 ++
36118 + static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
36119 + unsigned long address, pte_t *ptep, pte_t pte)
36120 + {
36121 +@@ -902,6 +921,11 @@ static int hugetlb_cow(struct mm_struct
36122 + huge_ptep_clear_flush(vma, address, ptep);
36123 + set_huge_pte_at(mm, address, ptep,
36124 + make_huge_pte(vma, new_page, 1));
36125 ++
36126 ++#ifdef CONFIG_PAX_SEGMEXEC
36127 ++ pax_mirror_huge_pte(vma, address, new_page);
36128 ++#endif
36129 ++
36130 + /* Make the old page be freed below */
36131 + new_page = old_page;
36132 + }
36133 +@@ -974,6 +998,10 @@ retry:
36134 + && (vma->vm_flags & VM_SHARED)));
36135 + set_huge_pte_at(mm, address, ptep, new_pte);
36136 +
36137 ++#ifdef CONFIG_PAX_SEGMEXEC
36138 ++ pax_mirror_huge_pte(vma, address, page);
36139 ++#endif
36140 ++
36141 + if (write_access && !(vma->vm_flags & VM_SHARED)) {
36142 + /* Optimization, do the COW without a second fault */
36143 + ret = hugetlb_cow(mm, vma, address, ptep, new_pte);
36144 +@@ -999,6 +1027,27 @@ int hugetlb_fault(struct mm_struct *mm,
36145 + int ret;
36146 + static DEFINE_MUTEX(hugetlb_instantiation_mutex);
36147 +
36148 ++#ifdef CONFIG_PAX_SEGMEXEC
36149 ++ struct vm_area_struct *vma_m;
36150 ++
36151 ++ vma_m = pax_find_mirror_vma(vma);
36152 ++ if (vma_m) {
36153 ++ unsigned long address_m;
36154 ++
36155 ++ if (vma->vm_start > vma_m->vm_start) {
36156 ++ address_m = address;
36157 ++ address -= SEGMEXEC_TASK_SIZE;
36158 ++ vma = vma_m;
36159 ++ } else
36160 ++ address_m = address + SEGMEXEC_TASK_SIZE;
36161 ++
36162 ++ if (!huge_pte_alloc(mm, address_m))
36163 ++ return VM_FAULT_OOM;
36164 ++ address_m &= HPAGE_MASK;
36165 ++ unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE);
36166 ++ }
36167 ++#endif
36168 ++
36169 + ptep = huge_pte_alloc(mm, address);
36170 + if (!ptep)
36171 + return VM_FAULT_OOM;
36172 +diff -urNp linux-2.6.26.6/mm/madvise.c linux-2.6.26.6/mm/madvise.c
36173 +--- linux-2.6.26.6/mm/madvise.c 2008-10-08 23:24:05.000000000 -0400
36174 ++++ linux-2.6.26.6/mm/madvise.c 2008-10-11 21:54:20.000000000 -0400
36175 +@@ -43,6 +43,10 @@ static long madvise_behavior(struct vm_a
36176 + pgoff_t pgoff;
36177 + int new_flags = vma->vm_flags;
36178 +
36179 ++#ifdef CONFIG_PAX_SEGMEXEC
36180 ++ struct vm_area_struct *vma_m;
36181 ++#endif
36182 ++
36183 + switch (behavior) {
36184 + case MADV_NORMAL:
36185 + new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
36186 +@@ -92,6 +96,13 @@ success:
36187 + /*
36188 + * vm_flags is protected by the mmap_sem held in write mode.
36189 + */
36190 ++
36191 ++#ifdef CONFIG_PAX_SEGMEXEC
36192 ++ vma_m = pax_find_mirror_vma(vma);
36193 ++ if (vma_m)
36194 ++ vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT);
36195 ++#endif
36196 ++
36197 + vma->vm_flags = new_flags;
36198 +
36199 + out:
36200 +@@ -236,6 +247,17 @@ madvise_vma(struct vm_area_struct *vma,
36201 +
36202 + case MADV_DONTNEED:
36203 + error = madvise_dontneed(vma, prev, start, end);
36204 ++
36205 ++#ifdef CONFIG_PAX_SEGMEXEC
36206 ++ if (!error) {
36207 ++ struct vm_area_struct *vma_m, *prev_m;
36208 ++
36209 ++ vma_m = pax_find_mirror_vma(vma);
36210 ++ if (vma_m)
36211 ++ error = madvise_dontneed(vma_m, &prev_m, start + SEGMEXEC_TASK_SIZE, end + SEGMEXEC_TASK_SIZE);
36212 ++ }
36213 ++#endif
36214 ++
36215 + break;
36216 +
36217 + default:
36218 +@@ -308,6 +330,16 @@ asmlinkage long sys_madvise(unsigned lon
36219 + if (end < start)
36220 + goto out;
36221 +
36222 ++#ifdef CONFIG_PAX_SEGMEXEC
36223 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
36224 ++ if (end > SEGMEXEC_TASK_SIZE)
36225 ++ goto out;
36226 ++ } else
36227 ++#endif
36228 ++
36229 ++ if (end > TASK_SIZE)
36230 ++ goto out;
36231 ++
36232 + error = 0;
36233 + if (end == start)
36234 + goto out;
36235 +diff -urNp linux-2.6.26.6/mm/memory.c linux-2.6.26.6/mm/memory.c
36236 +--- linux-2.6.26.6/mm/memory.c 2008-10-08 23:24:05.000000000 -0400
36237 ++++ linux-2.6.26.6/mm/memory.c 2008-10-11 21:54:20.000000000 -0400
36238 +@@ -51,6 +51,7 @@
36239 + #include <linux/init.h>
36240 + #include <linux/writeback.h>
36241 + #include <linux/memcontrol.h>
36242 ++#include <linux/grsecurity.h>
36243 +
36244 + #include <asm/pgalloc.h>
36245 + #include <asm/uaccess.h>
36246 +@@ -1082,11 +1083,11 @@ int get_user_pages(struct task_struct *t
36247 + vm_flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
36248 + i = 0;
36249 +
36250 +- do {
36251 ++ while (len) {
36252 + struct vm_area_struct *vma;
36253 + unsigned int foll_flags;
36254 +
36255 +- vma = find_extend_vma(mm, start);
36256 ++ vma = find_vma(mm, start);
36257 + if (!vma && in_gate_area(tsk, start)) {
36258 + unsigned long pg = start & PAGE_MASK;
36259 + struct vm_area_struct *gate_vma = get_gate_vma(tsk);
36260 +@@ -1126,7 +1127,7 @@ int get_user_pages(struct task_struct *t
36261 + continue;
36262 + }
36263 +
36264 +- if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP))
36265 ++ if (!vma || start < vma->vm_start || (vma->vm_flags & (VM_IO | VM_PFNMAP))
36266 + || !(vm_flags & vma->vm_flags))
36267 + return i ? : -EFAULT;
36268 +
36269 +@@ -1199,7 +1200,7 @@ int get_user_pages(struct task_struct *t
36270 + start += PAGE_SIZE;
36271 + len--;
36272 + } while (len && start < vma->vm_end);
36273 +- } while (len);
36274 ++ }
36275 + return i;
36276 + }
36277 + EXPORT_SYMBOL(get_user_pages);
36278 +@@ -1668,6 +1669,186 @@ static inline void cow_user_page(struct
36279 + copy_user_highpage(dst, src, va, vma);
36280 + }
36281 +
36282 ++#ifdef CONFIG_PAX_SEGMEXEC
36283 ++static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd)
36284 ++{
36285 ++ struct mm_struct *mm = vma->vm_mm;
36286 ++ spinlock_t *ptl;
36287 ++ pte_t *pte, entry;
36288 ++
36289 ++ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
36290 ++ entry = *pte;
36291 ++ if (!pte_present(entry)) {
36292 ++ if (!pte_none(entry)) {
36293 ++ BUG_ON(pte_file(entry));
36294 ++ free_swap_and_cache(pte_to_swp_entry(entry));
36295 ++ pte_clear_not_present_full(mm, address, pte, 0);
36296 ++ }
36297 ++ } else {
36298 ++ struct page *page;
36299 ++
36300 ++ flush_cache_page(vma, address, pte_pfn(entry));
36301 ++ entry = ptep_clear_flush(vma, address, pte);
36302 ++ BUG_ON(pte_dirty(entry));
36303 ++ page = vm_normal_page(vma, address, entry);
36304 ++ if (page) {
36305 ++ update_hiwater_rss(mm);
36306 ++ if (PageAnon(page))
36307 ++ dec_mm_counter(mm, anon_rss);
36308 ++ else
36309 ++ dec_mm_counter(mm, file_rss);
36310 ++ page_remove_rmap(page, vma);
36311 ++ page_cache_release(page);
36312 ++ }
36313 ++ }
36314 ++ pte_unmap_unlock(pte, ptl);
36315 ++}
36316 ++
36317 ++/* PaX: if vma is mirrored, synchronize the mirror's PTE
36318 ++ *
36319 ++ * the ptl of the lower mapped page is held on entry and is not released on exit
36320 ++ * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
36321 ++ */
36322 ++static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
36323 ++{
36324 ++ struct mm_struct *mm = vma->vm_mm;
36325 ++ unsigned long address_m;
36326 ++ spinlock_t *ptl_m;
36327 ++ struct vm_area_struct *vma_m;
36328 ++ pmd_t *pmd_m;
36329 ++ pte_t *pte_m, entry_m;
36330 ++
36331 ++ BUG_ON(!page_m || !PageAnon(page_m));
36332 ++
36333 ++ vma_m = pax_find_mirror_vma(vma);
36334 ++ if (!vma_m)
36335 ++ return;
36336 ++
36337 ++ BUG_ON(!PageLocked(page_m));
36338 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
36339 ++ address_m = address + SEGMEXEC_TASK_SIZE;
36340 ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
36341 ++ pte_m = pte_offset_map_nested(pmd_m, address_m);
36342 ++ ptl_m = pte_lockptr(mm, pmd_m);
36343 ++ if (ptl != ptl_m) {
36344 ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
36345 ++ if (!pte_none(*pte_m))
36346 ++ goto out;
36347 ++ }
36348 ++
36349 ++ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
36350 ++ page_cache_get(page_m);
36351 ++ page_add_anon_rmap(page_m, vma_m, address_m);
36352 ++ inc_mm_counter(mm, anon_rss);
36353 ++ set_pte_at(mm, address_m, pte_m, entry_m);
36354 ++ update_mmu_cache(vma_m, address_m, entry_m);
36355 ++out:
36356 ++ if (ptl != ptl_m)
36357 ++ spin_unlock(ptl_m);
36358 ++ pte_unmap_nested(pte_m);
36359 ++ unlock_page(page_m);
36360 ++}
36361 ++
36362 ++void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
36363 ++{
36364 ++ struct mm_struct *mm = vma->vm_mm;
36365 ++ unsigned long address_m;
36366 ++ spinlock_t *ptl_m;
36367 ++ struct vm_area_struct *vma_m;
36368 ++ pmd_t *pmd_m;
36369 ++ pte_t *pte_m, entry_m;
36370 ++
36371 ++ BUG_ON(!page_m || PageAnon(page_m));
36372 ++
36373 ++ vma_m = pax_find_mirror_vma(vma);
36374 ++ if (!vma_m)
36375 ++ return;
36376 ++
36377 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
36378 ++ address_m = address + SEGMEXEC_TASK_SIZE;
36379 ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
36380 ++ pte_m = pte_offset_map_nested(pmd_m, address_m);
36381 ++ ptl_m = pte_lockptr(mm, pmd_m);
36382 ++ if (ptl != ptl_m) {
36383 ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
36384 ++ if (!pte_none(*pte_m))
36385 ++ goto out;
36386 ++ }
36387 ++
36388 ++ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
36389 ++ page_cache_get(page_m);
36390 ++ page_add_file_rmap(page_m);
36391 ++ inc_mm_counter(mm, file_rss);
36392 ++ set_pte_at(mm, address_m, pte_m, entry_m);
36393 ++ update_mmu_cache(vma_m, address_m, entry_m);
36394 ++out:
36395 ++ if (ptl != ptl_m)
36396 ++ spin_unlock(ptl_m);
36397 ++ pte_unmap_nested(pte_m);
36398 ++}
36399 ++
36400 ++static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl)
36401 ++{
36402 ++ struct mm_struct *mm = vma->vm_mm;
36403 ++ unsigned long address_m;
36404 ++ spinlock_t *ptl_m;
36405 ++ struct vm_area_struct *vma_m;
36406 ++ pmd_t *pmd_m;
36407 ++ pte_t *pte_m, entry_m;
36408 ++
36409 ++ vma_m = pax_find_mirror_vma(vma);
36410 ++ if (!vma_m)
36411 ++ return;
36412 ++
36413 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
36414 ++ address_m = address + SEGMEXEC_TASK_SIZE;
36415 ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
36416 ++ pte_m = pte_offset_map_nested(pmd_m, address_m);
36417 ++ ptl_m = pte_lockptr(mm, pmd_m);
36418 ++ if (ptl != ptl_m) {
36419 ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
36420 ++ if (!pte_none(*pte_m))
36421 ++ goto out;
36422 ++ }
36423 ++
36424 ++ entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
36425 ++ set_pte_at(mm, address_m, pte_m, entry_m);
36426 ++out:
36427 ++ if (ptl != ptl_m)
36428 ++ spin_unlock(ptl_m);
36429 ++ pte_unmap_nested(pte_m);
36430 ++}
36431 ++
36432 ++static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, pmd_t *pmd, spinlock_t *ptl)
36433 ++{
36434 ++ struct page *page_m;
36435 ++ pte_t entry;
36436 ++
36437 ++ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC))
36438 ++ goto out;
36439 ++
36440 ++ entry = *pte;
36441 ++ page_m = vm_normal_page(vma, address, entry);
36442 ++ if (!page_m)
36443 ++ pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl);
36444 ++ else if (PageAnon(page_m)) {
36445 ++ if (pax_find_mirror_vma(vma)) {
36446 ++ pte_unmap_unlock(pte, ptl);
36447 ++ lock_page(page_m);
36448 ++ pte = pte_offset_map_lock(vma->vm_mm, pmd, address, &ptl);
36449 ++ if (pte_same(entry, *pte))
36450 ++ pax_mirror_anon_pte(vma, address, page_m, ptl);
36451 ++ else
36452 ++ unlock_page(page_m);
36453 ++ }
36454 ++ } else
36455 ++ pax_mirror_file_pte(vma, address, page_m, ptl);
36456 ++
36457 ++out:
36458 ++ pte_unmap_unlock(pte, ptl);
36459 ++}
36460 ++#endif
36461 ++
36462 + /*
36463 + * This routine handles present pages, when users try to write
36464 + * to a shared page. It is done by copying the page to a new address
36465 +@@ -1796,6 +1977,12 @@ gotten:
36466 + */
36467 + page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
36468 + if (likely(pte_same(*page_table, orig_pte))) {
36469 ++
36470 ++#ifdef CONFIG_PAX_SEGMEXEC
36471 ++ if (pax_find_mirror_vma(vma))
36472 ++ BUG_ON(TestSetPageLocked(new_page));
36473 ++#endif
36474 ++
36475 + if (old_page) {
36476 + if (!PageAnon(old_page)) {
36477 + dec_mm_counter(mm, file_rss);
36478 +@@ -1844,6 +2031,10 @@ gotten:
36479 + page_remove_rmap(old_page, vma);
36480 + }
36481 +
36482 ++#ifdef CONFIG_PAX_SEGMEXEC
36483 ++ pax_mirror_anon_pte(vma, address, new_page, ptl);
36484 ++#endif
36485 ++
36486 + /* Free the old page.. */
36487 + new_page = old_page;
36488 + ret |= VM_FAULT_WRITE;
36489 +@@ -2103,6 +2294,7 @@ int vmtruncate(struct inode * inode, lof
36490 + unsigned long limit;
36491 +
36492 + limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
36493 ++ gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
36494 + if (limit != RLIM_INFINITY && offset > limit)
36495 + goto out_sig;
36496 + if (offset > inode->i_sb->s_maxbytes)
36497 +@@ -2253,6 +2445,11 @@ static int do_swap_page(struct mm_struct
36498 + swap_free(entry);
36499 + if (vm_swap_full())
36500 + remove_exclusive_swap_page(page);
36501 ++
36502 ++#ifdef CONFIG_PAX_SEGMEXEC
36503 ++ if (write_access || !pax_find_mirror_vma(vma))
36504 ++#endif
36505 ++
36506 + unlock_page(page);
36507 +
36508 + if (write_access) {
36509 +@@ -2264,6 +2461,11 @@ static int do_swap_page(struct mm_struct
36510 +
36511 + /* No need to invalidate - it was non-present before */
36512 + update_mmu_cache(vma, address, pte);
36513 ++
36514 ++#ifdef CONFIG_PAX_SEGMEXEC
36515 ++ pax_mirror_anon_pte(vma, address, page, ptl);
36516 ++#endif
36517 ++
36518 + unlock:
36519 + pte_unmap_unlock(page_table, ptl);
36520 + out:
36521 +@@ -2308,6 +2510,12 @@ static int do_anonymous_page(struct mm_s
36522 + page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
36523 + if (!pte_none(*page_table))
36524 + goto release;
36525 ++
36526 ++#ifdef CONFIG_PAX_SEGMEXEC
36527 ++ if (pax_find_mirror_vma(vma))
36528 ++ BUG_ON(TestSetPageLocked(page));
36529 ++#endif
36530 ++
36531 + inc_mm_counter(mm, anon_rss);
36532 + lru_cache_add_active(page);
36533 + page_add_new_anon_rmap(page, vma, address);
36534 +@@ -2315,6 +2523,11 @@ static int do_anonymous_page(struct mm_s
36535 +
36536 + /* No need to invalidate - it was non-present before */
36537 + update_mmu_cache(vma, address, entry);
36538 ++
36539 ++#ifdef CONFIG_PAX_SEGMEXEC
36540 ++ pax_mirror_anon_pte(vma, address, page, ptl);
36541 ++#endif
36542 ++
36543 + unlock:
36544 + pte_unmap_unlock(page_table, ptl);
36545 + return 0;
36546 +@@ -2443,6 +2656,12 @@ static int __do_fault(struct mm_struct *
36547 + */
36548 + /* Only go through if we didn't race with anybody else... */
36549 + if (likely(pte_same(*page_table, orig_pte))) {
36550 ++
36551 ++#ifdef CONFIG_PAX_SEGMEXEC
36552 ++ if (anon && pax_find_mirror_vma(vma))
36553 ++ BUG_ON(TestSetPageLocked(page));
36554 ++#endif
36555 ++
36556 + flush_icache_page(vma, page);
36557 + entry = mk_pte(page, vma->vm_page_prot);
36558 + if (flags & FAULT_FLAG_WRITE)
36559 +@@ -2463,6 +2682,14 @@ static int __do_fault(struct mm_struct *
36560 +
36561 + /* no need to invalidate: a not-present page won't be cached */
36562 + update_mmu_cache(vma, address, entry);
36563 ++
36564 ++#ifdef CONFIG_PAX_SEGMEXEC
36565 ++ if (anon)
36566 ++ pax_mirror_anon_pte(vma, address, page, ptl);
36567 ++ else
36568 ++ pax_mirror_file_pte(vma, address, page, ptl);
36569 ++#endif
36570 ++
36571 + } else {
36572 + mem_cgroup_uncharge_page(page);
36573 + if (anon)
36574 +@@ -2549,6 +2776,11 @@ static noinline int do_no_pfn(struct mm_
36575 + if (write_access)
36576 + entry = maybe_mkwrite(pte_mkdirty(entry), vma);
36577 + set_pte_at(mm, address, page_table, entry);
36578 ++
36579 ++#ifdef CONFIG_PAX_SEGMEXEC
36580 ++ pax_mirror_pfn_pte(vma, address, pfn, ptl);
36581 ++#endif
36582 ++
36583 + }
36584 + pte_unmap_unlock(page_table, ptl);
36585 + return 0;
36586 +@@ -2651,6 +2883,12 @@ static inline int handle_pte_fault(struc
36587 + if (write_access)
36588 + flush_tlb_page(vma, address);
36589 + }
36590 ++
36591 ++#ifdef CONFIG_PAX_SEGMEXEC
36592 ++ pax_mirror_pte(vma, address, pte, pmd, ptl);
36593 ++ return 0;
36594 ++#endif
36595 ++
36596 + unlock:
36597 + pte_unmap_unlock(pte, ptl);
36598 + return 0;
36599 +@@ -2667,6 +2905,10 @@ int handle_mm_fault(struct mm_struct *mm
36600 + pmd_t *pmd;
36601 + pte_t *pte;
36602 +
36603 ++#ifdef CONFIG_PAX_SEGMEXEC
36604 ++ struct vm_area_struct *vma_m;
36605 ++#endif
36606 ++
36607 + __set_current_state(TASK_RUNNING);
36608 +
36609 + count_vm_event(PGFAULT);
36610 +@@ -2674,6 +2916,34 @@ int handle_mm_fault(struct mm_struct *mm
36611 + if (unlikely(is_vm_hugetlb_page(vma)))
36612 + return hugetlb_fault(mm, vma, address, write_access);
36613 +
36614 ++#ifdef CONFIG_PAX_SEGMEXEC
36615 ++ vma_m = pax_find_mirror_vma(vma);
36616 ++ if (vma_m) {
36617 ++ unsigned long address_m;
36618 ++ pgd_t *pgd_m;
36619 ++ pud_t *pud_m;
36620 ++ pmd_t *pmd_m;
36621 ++
36622 ++ if (vma->vm_start > vma_m->vm_start) {
36623 ++ address_m = address;
36624 ++ address -= SEGMEXEC_TASK_SIZE;
36625 ++ vma = vma_m;
36626 ++ } else
36627 ++ address_m = address + SEGMEXEC_TASK_SIZE;
36628 ++
36629 ++ pgd_m = pgd_offset(mm, address_m);
36630 ++ pud_m = pud_alloc(mm, pgd_m, address_m);
36631 ++ if (!pud_m)
36632 ++ return VM_FAULT_OOM;
36633 ++ pmd_m = pmd_alloc(mm, pud_m, address_m);
36634 ++ if (!pmd_m)
36635 ++ return VM_FAULT_OOM;
36636 ++ if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
36637 ++ return VM_FAULT_OOM;
36638 ++ pax_unmap_mirror_pte(vma_m, address_m, pmd_m);
36639 ++ }
36640 ++#endif
36641 ++
36642 + pgd = pgd_offset(mm, address);
36643 + pud = pud_alloc(mm, pgd, address);
36644 + if (!pud)
36645 +@@ -2781,7 +3051,7 @@ static int __init gate_vma_init(void)
36646 + gate_vma.vm_start = FIXADDR_USER_START;
36647 + gate_vma.vm_end = FIXADDR_USER_END;
36648 + gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
36649 +- gate_vma.vm_page_prot = __P101;
36650 ++ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
36651 + /*
36652 + * Make sure the vDSO gets into every core dump.
36653 + * Dumping its contents makes post-mortem fully interpretable later
36654 +diff -urNp linux-2.6.26.6/mm/mempolicy.c linux-2.6.26.6/mm/mempolicy.c
36655 +--- linux-2.6.26.6/mm/mempolicy.c 2008-10-08 23:24:05.000000000 -0400
36656 ++++ linux-2.6.26.6/mm/mempolicy.c 2008-10-11 21:54:20.000000000 -0400
36657 +@@ -555,6 +555,10 @@ static int mbind_range(struct vm_area_st
36658 + struct vm_area_struct *next;
36659 + int err;
36660 +
36661 ++#ifdef CONFIG_PAX_SEGMEXEC
36662 ++ struct vm_area_struct *vma_m;
36663 ++#endif
36664 ++
36665 + err = 0;
36666 + for (; vma && vma->vm_start < end; vma = next) {
36667 + next = vma->vm_next;
36668 +@@ -566,6 +570,16 @@ static int mbind_range(struct vm_area_st
36669 + err = policy_vma(vma, new);
36670 + if (err)
36671 + break;
36672 ++
36673 ++#ifdef CONFIG_PAX_SEGMEXEC
36674 ++ vma_m = pax_find_mirror_vma(vma);
36675 ++ if (vma_m) {
36676 ++ err = policy_vma(vma_m, new);
36677 ++ if (err)
36678 ++ break;
36679 ++ }
36680 ++#endif
36681 ++
36682 + }
36683 + return err;
36684 + }
36685 +@@ -952,6 +966,17 @@ static long do_mbind(unsigned long start
36686 +
36687 + if (end < start)
36688 + return -EINVAL;
36689 ++
36690 ++#ifdef CONFIG_PAX_SEGMEXEC
36691 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC) {
36692 ++ if (end > SEGMEXEC_TASK_SIZE)
36693 ++ return -EINVAL;
36694 ++ } else
36695 ++#endif
36696 ++
36697 ++ if (end > TASK_SIZE)
36698 ++ return -EINVAL;
36699 ++
36700 + if (end == start)
36701 + return 0;
36702 +
36703 +diff -urNp linux-2.6.26.6/mm/mlock.c linux-2.6.26.6/mm/mlock.c
36704 +--- linux-2.6.26.6/mm/mlock.c 2008-10-08 23:24:05.000000000 -0400
36705 ++++ linux-2.6.26.6/mm/mlock.c 2008-10-11 21:54:20.000000000 -0400
36706 +@@ -12,6 +12,7 @@
36707 + #include <linux/syscalls.h>
36708 + #include <linux/sched.h>
36709 + #include <linux/module.h>
36710 ++#include <linux/grsecurity.h>
36711 +
36712 + int can_do_mlock(void)
36713 + {
36714 +@@ -93,6 +94,17 @@ static int do_mlock(unsigned long start,
36715 + return -EINVAL;
36716 + if (end == start)
36717 + return 0;
36718 ++
36719 ++#ifdef CONFIG_PAX_SEGMEXEC
36720 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
36721 ++ if (end > SEGMEXEC_TASK_SIZE)
36722 ++ return -EINVAL;
36723 ++ } else
36724 ++#endif
36725 ++
36726 ++ if (end > TASK_SIZE)
36727 ++ return -EINVAL;
36728 ++
36729 + vma = find_vma_prev(current->mm, start, &prev);
36730 + if (!vma || vma->vm_start > start)
36731 + return -ENOMEM;
36732 +@@ -150,6 +162,7 @@ asmlinkage long sys_mlock(unsigned long
36733 + lock_limit >>= PAGE_SHIFT;
36734 +
36735 + /* check against resource limits */
36736 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
36737 + if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
36738 + error = do_mlock(start, len, 1);
36739 + up_write(&current->mm->mmap_sem);
36740 +@@ -171,10 +184,10 @@ asmlinkage long sys_munlock(unsigned lon
36741 + static int do_mlockall(int flags)
36742 + {
36743 + struct vm_area_struct * vma, * prev = NULL;
36744 +- unsigned int def_flags = 0;
36745 ++ unsigned int def_flags = current->mm->def_flags & ~VM_LOCKED;
36746 +
36747 + if (flags & MCL_FUTURE)
36748 +- def_flags = VM_LOCKED;
36749 ++ def_flags |= VM_LOCKED;
36750 + current->mm->def_flags = def_flags;
36751 + if (flags == MCL_FUTURE)
36752 + goto out;
36753 +@@ -182,6 +195,12 @@ static int do_mlockall(int flags)
36754 + for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
36755 + unsigned int newflags;
36756 +
36757 ++#ifdef CONFIG_PAX_SEGMEXEC
36758 ++ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
36759 ++ break;
36760 ++#endif
36761 ++
36762 ++ BUG_ON(vma->vm_end > TASK_SIZE);
36763 + newflags = vma->vm_flags | VM_LOCKED;
36764 + if (!(flags & MCL_CURRENT))
36765 + newflags &= ~VM_LOCKED;
36766 +@@ -211,6 +230,7 @@ asmlinkage long sys_mlockall(int flags)
36767 + lock_limit >>= PAGE_SHIFT;
36768 +
36769 + ret = -ENOMEM;
36770 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
36771 + if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
36772 + capable(CAP_IPC_LOCK))
36773 + ret = do_mlockall(flags);
36774 +diff -urNp linux-2.6.26.6/mm/mmap.c linux-2.6.26.6/mm/mmap.c
36775 +--- linux-2.6.26.6/mm/mmap.c 2008-10-08 23:24:05.000000000 -0400
36776 ++++ linux-2.6.26.6/mm/mmap.c 2008-10-11 21:54:20.000000000 -0400
36777 +@@ -26,6 +26,7 @@
36778 + #include <linux/mount.h>
36779 + #include <linux/mempolicy.h>
36780 + #include <linux/rmap.h>
36781 ++#include <linux/grsecurity.h>
36782 +
36783 + #include <asm/uaccess.h>
36784 + #include <asm/cacheflush.h>
36785 +@@ -40,6 +41,16 @@
36786 + #define arch_rebalance_pgtables(addr, len) (addr)
36787 + #endif
36788 +
36789 ++static inline void verify_mm_writelocked(struct mm_struct *mm)
36790 ++{
36791 ++#if defined(CONFIG_DEBUG_VM) || defined(CONFIG_PAX)
36792 ++ if (unlikely(down_read_trylock(&mm->mmap_sem))) {
36793 ++ up_read(&mm->mmap_sem);
36794 ++ BUG();
36795 ++ }
36796 ++#endif
36797 ++}
36798 ++
36799 + static void unmap_region(struct mm_struct *mm,
36800 + struct vm_area_struct *vma, struct vm_area_struct *prev,
36801 + unsigned long start, unsigned long end);
36802 +@@ -65,15 +76,23 @@ static void unmap_region(struct mm_struc
36803 + * x: (no) no x: (no) yes x: (no) yes x: (yes) yes
36804 + *
36805 + */
36806 +-pgprot_t protection_map[16] = {
36807 ++pgprot_t protection_map[16] __read_only = {
36808 + __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
36809 + __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
36810 + };
36811 +
36812 + pgprot_t vm_get_page_prot(unsigned long vm_flags)
36813 + {
36814 +- return protection_map[vm_flags &
36815 +- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
36816 ++ pgprot_t prot = protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
36817 ++
36818 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
36819 ++ if (!nx_enabled &&
36820 ++ (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC &&
36821 ++ (vm_flags & (VM_READ | VM_WRITE)))
36822 ++ prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot)))));
36823 ++#endif
36824 ++
36825 ++ return prot;
36826 + }
36827 + EXPORT_SYMBOL(vm_get_page_prot);
36828 +
36829 +@@ -228,6 +247,7 @@ static struct vm_area_struct *remove_vma
36830 + struct vm_area_struct *next = vma->vm_next;
36831 +
36832 + might_sleep();
36833 ++ BUG_ON(vma->vm_mirror);
36834 + if (vma->vm_ops && vma->vm_ops->close)
36835 + vma->vm_ops->close(vma);
36836 + if (vma->vm_file) {
36837 +@@ -264,6 +284,7 @@ asmlinkage unsigned long sys_brk(unsigne
36838 + * not page aligned -Ram Gupta
36839 + */
36840 + rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
36841 ++ gr_learn_resource(current, RLIMIT_DATA, (brk - mm->start_brk) + (mm->end_data - mm->start_data), 1);
36842 + if (rlim < RLIM_INFINITY && (brk - mm->start_brk) +
36843 + (mm->end_data - mm->start_data) > rlim)
36844 + goto out;
36845 +@@ -365,8 +386,12 @@ find_vma_prepare(struct mm_struct *mm, u
36846 +
36847 + if (vma_tmp->vm_end > addr) {
36848 + vma = vma_tmp;
36849 +- if (vma_tmp->vm_start <= addr)
36850 +- return vma;
36851 ++ if (vma_tmp->vm_start <= addr) {
36852 ++//printk("PAX: prep: %08lx-%08lx %08lx pr:%p l:%p pa:%p ",
36853 ++//vma->vm_start, vma->vm_end, addr, *pprev, *rb_link, *rb_parent);
36854 ++//__print_symbol("%s\n", __builtin_extract_return_addr(__builtin_return_address(0)));
36855 ++ break;
36856 ++ }
36857 + __rb_link = &__rb_parent->rb_left;
36858 + } else {
36859 + rb_prev = __rb_parent;
36860 +@@ -693,6 +718,12 @@ static int
36861 + can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
36862 + struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
36863 + {
36864 ++
36865 ++#ifdef CONFIG_PAX_SEGMEXEC
36866 ++ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE)
36867 ++ return 0;
36868 ++#endif
36869 ++
36870 + if (is_mergeable_vma(vma, file, vm_flags) &&
36871 + is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
36872 + if (vma->vm_pgoff == vm_pgoff)
36873 +@@ -712,6 +743,12 @@ static int
36874 + can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
36875 + struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
36876 + {
36877 ++
36878 ++#ifdef CONFIG_PAX_SEGMEXEC
36879 ++ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE)
36880 ++ return 0;
36881 ++#endif
36882 ++
36883 + if (is_mergeable_vma(vma, file, vm_flags) &&
36884 + is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
36885 + pgoff_t vm_pglen;
36886 +@@ -754,12 +791,19 @@ can_vma_merge_after(struct vm_area_struc
36887 + struct vm_area_struct *vma_merge(struct mm_struct *mm,
36888 + struct vm_area_struct *prev, unsigned long addr,
36889 + unsigned long end, unsigned long vm_flags,
36890 +- struct anon_vma *anon_vma, struct file *file,
36891 ++ struct anon_vma *anon_vma, struct file *file,
36892 + pgoff_t pgoff, struct mempolicy *policy)
36893 + {
36894 + pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
36895 + struct vm_area_struct *area, *next;
36896 +
36897 ++#ifdef CONFIG_PAX_SEGMEXEC
36898 ++ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE;
36899 ++ struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL;
36900 ++
36901 ++ BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end);
36902 ++#endif
36903 ++
36904 + /*
36905 + * We later require that vma->vm_flags == vm_flags,
36906 + * so this tests vma->vm_flags & VM_SPECIAL, too.
36907 +@@ -775,6 +819,15 @@ struct vm_area_struct *vma_merge(struct
36908 + if (next && next->vm_end == end) /* cases 6, 7, 8 */
36909 + next = next->vm_next;
36910 +
36911 ++#ifdef CONFIG_PAX_SEGMEXEC
36912 ++ if (prev)
36913 ++ prev_m = pax_find_mirror_vma(prev);
36914 ++ if (area)
36915 ++ area_m = pax_find_mirror_vma(area);
36916 ++ if (next)
36917 ++ next_m = pax_find_mirror_vma(next);
36918 ++#endif
36919 ++
36920 + /*
36921 + * Can it merge with the predecessor?
36922 + */
36923 +@@ -794,9 +847,24 @@ struct vm_area_struct *vma_merge(struct
36924 + /* cases 1, 6 */
36925 + vma_adjust(prev, prev->vm_start,
36926 + next->vm_end, prev->vm_pgoff, NULL);
36927 +- } else /* cases 2, 5, 7 */
36928 ++
36929 ++#ifdef CONFIG_PAX_SEGMEXEC
36930 ++ if (prev_m)
36931 ++ vma_adjust(prev_m, prev_m->vm_start,
36932 ++ next_m->vm_end, prev_m->vm_pgoff, NULL);
36933 ++#endif
36934 ++
36935 ++ } else { /* cases 2, 5, 7 */
36936 + vma_adjust(prev, prev->vm_start,
36937 + end, prev->vm_pgoff, NULL);
36938 ++
36939 ++#ifdef CONFIG_PAX_SEGMEXEC
36940 ++ if (prev_m)
36941 ++ vma_adjust(prev_m, prev_m->vm_start,
36942 ++ end_m, prev_m->vm_pgoff, NULL);
36943 ++#endif
36944 ++
36945 ++ }
36946 + return prev;
36947 + }
36948 +
36949 +@@ -807,12 +875,27 @@ struct vm_area_struct *vma_merge(struct
36950 + mpol_equal(policy, vma_policy(next)) &&
36951 + can_vma_merge_before(next, vm_flags,
36952 + anon_vma, file, pgoff+pglen)) {
36953 +- if (prev && addr < prev->vm_end) /* case 4 */
36954 ++ if (prev && addr < prev->vm_end) { /* case 4 */
36955 + vma_adjust(prev, prev->vm_start,
36956 + addr, prev->vm_pgoff, NULL);
36957 +- else /* cases 3, 8 */
36958 ++
36959 ++#ifdef CONFIG_PAX_SEGMEXEC
36960 ++ if (prev_m)
36961 ++ vma_adjust(prev_m, prev_m->vm_start,
36962 ++ addr_m, prev_m->vm_pgoff, NULL);
36963 ++#endif
36964 ++
36965 ++ } else { /* cases 3, 8 */
36966 + vma_adjust(area, addr, next->vm_end,
36967 + next->vm_pgoff - pglen, NULL);
36968 ++
36969 ++#ifdef CONFIG_PAX_SEGMEXEC
36970 ++ if (area_m)
36971 ++ vma_adjust(area_m, addr_m, next_m->vm_end,
36972 ++ next_m->vm_pgoff - pglen, NULL);
36973 ++#endif
36974 ++
36975 ++ }
36976 + return area;
36977 + }
36978 +
36979 +@@ -887,14 +970,11 @@ none:
36980 + void vm_stat_account(struct mm_struct *mm, unsigned long flags,
36981 + struct file *file, long pages)
36982 + {
36983 +- const unsigned long stack_flags
36984 +- = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
36985 +-
36986 + if (file) {
36987 + mm->shared_vm += pages;
36988 + if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
36989 + mm->exec_vm += pages;
36990 +- } else if (flags & stack_flags)
36991 ++ } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
36992 + mm->stack_vm += pages;
36993 + if (flags & (VM_RESERVED|VM_IO))
36994 + mm->reserved_vm += pages;
36995 +@@ -922,7 +1002,7 @@ unsigned long do_mmap_pgoff(struct file
36996 + * (the exception is when the underlying filesystem is noexec
36997 + * mounted, in which case we dont add PROT_EXEC.)
36998 + */
36999 +- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
37000 ++ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
37001 + if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
37002 + prot |= PROT_EXEC;
37003 +
37004 +@@ -932,15 +1012,15 @@ unsigned long do_mmap_pgoff(struct file
37005 + if (!(flags & MAP_FIXED))
37006 + addr = round_hint_to_min(addr);
37007 +
37008 +- error = arch_mmap_check(addr, len, flags);
37009 +- if (error)
37010 +- return error;
37011 +-
37012 + /* Careful about overflows.. */
37013 + len = PAGE_ALIGN(len);
37014 + if (!len || len > TASK_SIZE)
37015 + return -ENOMEM;
37016 +
37017 ++ error = arch_mmap_check(addr, len, flags);
37018 ++ if (error)
37019 ++ return error;
37020 ++
37021 + /* offset overflow? */
37022 + if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
37023 + return -EOVERFLOW;
37024 +@@ -952,7 +1032,7 @@ unsigned long do_mmap_pgoff(struct file
37025 + /* Obtain the address to map to. we verify (or select) it and ensure
37026 + * that it represents a valid section of the address space.
37027 + */
37028 +- addr = get_unmapped_area(file, addr, len, pgoff, flags);
37029 ++ addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
37030 + if (addr & ~PAGE_MASK)
37031 + return addr;
37032 +
37033 +@@ -963,6 +1043,26 @@ unsigned long do_mmap_pgoff(struct file
37034 + vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
37035 + mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
37036 +
37037 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
37038 ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
37039 ++
37040 ++#ifdef CONFIG_PAX_MPROTECT
37041 ++ if (mm->pax_flags & MF_PAX_MPROTECT) {
37042 ++ if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
37043 ++ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
37044 ++ else
37045 ++ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
37046 ++ }
37047 ++#endif
37048 ++
37049 ++ }
37050 ++#endif
37051 ++
37052 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
37053 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file)
37054 ++ vm_flags &= ~VM_PAGEEXEC;
37055 ++#endif
37056 ++
37057 + if (flags & MAP_LOCKED) {
37058 + if (!can_do_mlock())
37059 + return -EPERM;
37060 +@@ -975,6 +1075,7 @@ unsigned long do_mmap_pgoff(struct file
37061 + locked += mm->locked_vm;
37062 + lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
37063 + lock_limit >>= PAGE_SHIFT;
37064 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
37065 + if (locked > lock_limit && !capable(CAP_IPC_LOCK))
37066 + return -EAGAIN;
37067 + }
37068 +@@ -1043,6 +1144,9 @@ unsigned long do_mmap_pgoff(struct file
37069 + if (error)
37070 + return error;
37071 +
37072 ++ if (!gr_acl_handle_mmap(file, prot))
37073 ++ return -EACCES;
37074 ++
37075 + return mmap_region(file, addr, len, flags, vm_flags, pgoff,
37076 + accountable);
37077 + }
37078 +@@ -1056,10 +1160,10 @@ EXPORT_SYMBOL(do_mmap_pgoff);
37079 + */
37080 + int vma_wants_writenotify(struct vm_area_struct *vma)
37081 + {
37082 +- unsigned int vm_flags = vma->vm_flags;
37083 ++ unsigned long vm_flags = vma->vm_flags;
37084 +
37085 + /* If it was private or non-writable, the write bit is already clear */
37086 +- if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED)))
37087 ++ if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED))
37088 + return 0;
37089 +
37090 + /* The backer wishes to know when pages are first written to? */
37091 +@@ -1093,14 +1197,24 @@ unsigned long mmap_region(struct file *f
37092 + unsigned long charged = 0;
37093 + struct inode *inode = file ? file->f_path.dentry->d_inode : NULL;
37094 +
37095 ++#ifdef CONFIG_PAX_SEGMEXEC
37096 ++ struct vm_area_struct *vma_m = NULL;
37097 ++#endif
37098 ++
37099 ++ /*
37100 ++ * mm->mmap_sem is required to protect against another thread
37101 ++ * changing the mappings in case we sleep.
37102 ++ */
37103 ++ verify_mm_writelocked(mm);
37104 ++
37105 + /* Clear old maps */
37106 + error = -ENOMEM;
37107 +-munmap_back:
37108 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
37109 + if (vma && vma->vm_start < addr + len) {
37110 + if (do_munmap(mm, addr, len))
37111 + return -ENOMEM;
37112 +- goto munmap_back;
37113 ++ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
37114 ++ BUG_ON(vma && vma->vm_start < addr + len);
37115 + }
37116 +
37117 + /* Check against address space limit. */
37118 +@@ -1144,6 +1258,16 @@ munmap_back:
37119 + goto unacct_error;
37120 + }
37121 +
37122 ++#ifdef CONFIG_PAX_SEGMEXEC
37123 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) {
37124 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
37125 ++ if (!vma_m) {
37126 ++ error = -ENOMEM;
37127 ++ goto free_vma;
37128 ++ }
37129 ++ }
37130 ++#endif
37131 ++
37132 + vma->vm_mm = mm;
37133 + vma->vm_start = addr;
37134 + vma->vm_end = addr + len;
37135 +@@ -1166,6 +1290,19 @@ munmap_back:
37136 + error = file->f_op->mmap(file, vma);
37137 + if (error)
37138 + goto unmap_and_free_vma;
37139 ++
37140 ++#ifdef CONFIG_PAX_SEGMEXEC
37141 ++ if (vma_m && (vm_flags & VM_EXECUTABLE))
37142 ++ added_exe_file_vma(mm);
37143 ++#endif
37144 ++
37145 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
37146 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) {
37147 ++ vma->vm_flags |= VM_PAGEEXEC;
37148 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
37149 ++ }
37150 ++#endif
37151 ++
37152 + if (vm_flags & VM_EXECUTABLE)
37153 + added_exe_file_vma(mm);
37154 + } else if (vm_flags & VM_SHARED) {
37155 +@@ -1198,12 +1335,29 @@ munmap_back:
37156 + vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) {
37157 + mpol_put(vma_policy(vma));
37158 + kmem_cache_free(vm_area_cachep, vma);
37159 ++ vma = NULL;
37160 + fput(file);
37161 ++
37162 ++#ifdef CONFIG_PAX_SEGMEXEC
37163 ++ if (vma_m) {
37164 ++ kmem_cache_free(vm_area_cachep, vma_m);
37165 ++
37166 ++ if (vm_flags & VM_EXECUTABLE)
37167 ++ removed_exe_file_vma(mm);
37168 ++ }
37169 ++#endif
37170 ++
37171 + if (vm_flags & VM_EXECUTABLE)
37172 + removed_exe_file_vma(mm);
37173 + } else {
37174 + vma_link(mm, vma, prev, rb_link, rb_parent);
37175 + file = vma->vm_file;
37176 ++
37177 ++#ifdef CONFIG_PAX_SEGMEXEC
37178 ++ if (vma_m)
37179 ++ pax_mirror_vma(vma_m, vma);
37180 ++#endif
37181 ++
37182 + }
37183 +
37184 + /* Once vma denies write, undo our temporary denial count */
37185 +@@ -1212,6 +1366,7 @@ munmap_back:
37186 + out:
37187 + mm->total_vm += len >> PAGE_SHIFT;
37188 + vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
37189 ++ track_exec_limit(mm, addr, addr + len, vm_flags);
37190 + if (vm_flags & VM_LOCKED) {
37191 + mm->locked_vm += len >> PAGE_SHIFT;
37192 + make_pages_present(addr, addr + len);
37193 +@@ -1230,6 +1385,12 @@ unmap_and_free_vma:
37194 + unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
37195 + charged = 0;
37196 + free_vma:
37197 ++
37198 ++#ifdef CONFIG_PAX_SEGMEXEC
37199 ++ if (vma_m)
37200 ++ kmem_cache_free(vm_area_cachep, vma_m);
37201 ++#endif
37202 ++
37203 + kmem_cache_free(vm_area_cachep, vma);
37204 + unacct_error:
37205 + if (charged)
37206 +@@ -1263,6 +1424,10 @@ arch_get_unmapped_area(struct file *filp
37207 + if (flags & MAP_FIXED)
37208 + return addr;
37209 +
37210 ++#ifdef CONFIG_PAX_RANDMMAP
37211 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
37212 ++#endif
37213 ++
37214 + if (addr) {
37215 + addr = PAGE_ALIGN(addr);
37216 + vma = find_vma(mm, addr);
37217 +@@ -1271,10 +1436,10 @@ arch_get_unmapped_area(struct file *filp
37218 + return addr;
37219 + }
37220 + if (len > mm->cached_hole_size) {
37221 +- start_addr = addr = mm->free_area_cache;
37222 ++ start_addr = addr = mm->free_area_cache;
37223 + } else {
37224 +- start_addr = addr = TASK_UNMAPPED_BASE;
37225 +- mm->cached_hole_size = 0;
37226 ++ start_addr = addr = mm->mmap_base;
37227 ++ mm->cached_hole_size = 0;
37228 + }
37229 +
37230 + full_search:
37231 +@@ -1285,9 +1450,8 @@ full_search:
37232 + * Start a new search - just in case we missed
37233 + * some holes.
37234 + */
37235 +- if (start_addr != TASK_UNMAPPED_BASE) {
37236 +- addr = TASK_UNMAPPED_BASE;
37237 +- start_addr = addr;
37238 ++ if (start_addr != mm->mmap_base) {
37239 ++ start_addr = addr = mm->mmap_base;
37240 + mm->cached_hole_size = 0;
37241 + goto full_search;
37242 + }
37243 +@@ -1309,10 +1473,16 @@ full_search:
37244 +
37245 + void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
37246 + {
37247 ++
37248 ++#ifdef CONFIG_PAX_SEGMEXEC
37249 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
37250 ++ return;
37251 ++#endif
37252 ++
37253 + /*
37254 + * Is this a new hole at the lowest possible address?
37255 + */
37256 +- if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
37257 ++ if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
37258 + mm->free_area_cache = addr;
37259 + mm->cached_hole_size = ~0UL;
37260 + }
37261 +@@ -1330,7 +1500,7 @@ arch_get_unmapped_area_topdown(struct fi
37262 + {
37263 + struct vm_area_struct *vma;
37264 + struct mm_struct *mm = current->mm;
37265 +- unsigned long addr = addr0;
37266 ++ unsigned long base = mm->mmap_base, addr = addr0;
37267 +
37268 + /* requested length too big for entire address space */
37269 + if (len > TASK_SIZE)
37270 +@@ -1339,6 +1509,10 @@ arch_get_unmapped_area_topdown(struct fi
37271 + if (flags & MAP_FIXED)
37272 + return addr;
37273 +
37274 ++#ifdef CONFIG_PAX_RANDMMAP
37275 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
37276 ++#endif
37277 ++
37278 + /* requesting a specific address */
37279 + if (addr) {
37280 + addr = PAGE_ALIGN(addr);
37281 +@@ -1396,13 +1570,21 @@ bottomup:
37282 + * can happen with large stack limits and large mmap()
37283 + * allocations.
37284 + */
37285 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
37286 ++
37287 ++#ifdef CONFIG_PAX_RANDMMAP
37288 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
37289 ++ mm->mmap_base += mm->delta_mmap;
37290 ++#endif
37291 ++
37292 ++ mm->free_area_cache = mm->mmap_base;
37293 + mm->cached_hole_size = ~0UL;
37294 +- mm->free_area_cache = TASK_UNMAPPED_BASE;
37295 + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
37296 + /*
37297 + * Restore the topdown base:
37298 + */
37299 +- mm->free_area_cache = mm->mmap_base;
37300 ++ mm->mmap_base = base;
37301 ++ mm->free_area_cache = base;
37302 + mm->cached_hole_size = ~0UL;
37303 +
37304 + return addr;
37305 +@@ -1411,6 +1593,12 @@ bottomup:
37306 +
37307 + void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
37308 + {
37309 ++
37310 ++#ifdef CONFIG_PAX_SEGMEXEC
37311 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
37312 ++ return;
37313 ++#endif
37314 ++
37315 + /*
37316 + * Is this a new hole at the highest possible address?
37317 + */
37318 +@@ -1418,8 +1606,10 @@ void arch_unmap_area_topdown(struct mm_s
37319 + mm->free_area_cache = addr;
37320 +
37321 + /* dont allow allocations above current base */
37322 +- if (mm->free_area_cache > mm->mmap_base)
37323 ++ if (mm->free_area_cache > mm->mmap_base) {
37324 + mm->free_area_cache = mm->mmap_base;
37325 ++ mm->cached_hole_size = ~0UL;
37326 ++ }
37327 + }
37328 +
37329 + unsigned long
37330 +@@ -1519,6 +1709,33 @@ out:
37331 + return prev ? prev->vm_next : vma;
37332 + }
37333 +
37334 ++#ifdef CONFIG_PAX_SEGMEXEC
37335 ++struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
37336 ++{
37337 ++ struct vm_area_struct *vma_m;
37338 ++
37339 ++ BUG_ON(!vma || vma->vm_start >= vma->vm_end);
37340 ++ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) {
37341 ++ BUG_ON(vma->vm_mirror);
37342 ++ return NULL;
37343 ++ }
37344 ++ BUG_ON(vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < vma->vm_start - SEGMEXEC_TASK_SIZE - 1);
37345 ++ vma_m = vma->vm_mirror;
37346 ++ BUG_ON(!vma_m || vma_m->vm_mirror != vma);
37347 ++ BUG_ON(vma->vm_file != vma_m->vm_file);
37348 ++ BUG_ON(vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start);
37349 ++ BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff || vma->anon_vma != vma_m->anon_vma);
37350 ++
37351 ++#ifdef CONFIG_PAX_MPROTECT
37352 ++ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED | VM_MAYNOTWRITE));
37353 ++#else
37354 ++ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED));
37355 ++#endif
37356 ++
37357 ++ return vma_m;
37358 ++}
37359 ++#endif
37360 ++
37361 + /*
37362 + * Verify that the stack growth is acceptable and
37363 + * update accounting. This is shared with both the
37364 +@@ -1535,6 +1752,7 @@ static int acct_stack_growth(struct vm_a
37365 + return -ENOMEM;
37366 +
37367 + /* Stack limit test */
37368 ++ gr_learn_resource(current, RLIMIT_STACK, size, 1);
37369 + if (size > rlim[RLIMIT_STACK].rlim_cur)
37370 + return -ENOMEM;
37371 +
37372 +@@ -1544,6 +1762,7 @@ static int acct_stack_growth(struct vm_a
37373 + unsigned long limit;
37374 + locked = mm->locked_vm + grow;
37375 + limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
37376 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
37377 + if (locked > limit && !capable(CAP_IPC_LOCK))
37378 + return -ENOMEM;
37379 + }
37380 +@@ -1558,7 +1777,7 @@ static int acct_stack_growth(struct vm_a
37381 + * Overcommit.. This must be the final test, as it will
37382 + * update security statistics.
37383 + */
37384 +- if (security_vm_enough_memory(grow))
37385 ++ if (security_vm_enough_memory_mm(mm, grow))
37386 + return -ENOMEM;
37387 +
37388 + /* Ok, everything looks good - let it rip */
37389 +@@ -1579,35 +1798,40 @@ static inline
37390 + #endif
37391 + int expand_upwards(struct vm_area_struct *vma, unsigned long address)
37392 + {
37393 +- int error;
37394 ++ int error, locknext;
37395 +
37396 + if (!(vma->vm_flags & VM_GROWSUP))
37397 + return -EFAULT;
37398 +
37399 ++ /* Also guard against wrapping around to address 0. */
37400 ++ if (address < PAGE_ALIGN(address+1))
37401 ++ address = PAGE_ALIGN(address+1);
37402 ++ else
37403 ++ return -ENOMEM;
37404 ++
37405 + /*
37406 + * We must make sure the anon_vma is allocated
37407 + * so that the anon_vma locking is not a noop.
37408 + */
37409 + if (unlikely(anon_vma_prepare(vma)))
37410 + return -ENOMEM;
37411 ++ locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN);
37412 ++ if (locknext && unlikely(anon_vma_prepare(vma->vm_next)))
37413 ++ return -ENOMEM;
37414 + anon_vma_lock(vma);
37415 ++ if (locknext)
37416 ++ anon_vma_lock(vma->vm_next);
37417 +
37418 + /*
37419 + * vma->vm_start/vm_end cannot change under us because the caller
37420 + * is required to hold the mmap_sem in read mode. We need the
37421 +- * anon_vma lock to serialize against concurrent expand_stacks.
37422 +- * Also guard against wrapping around to address 0.
37423 ++ * anon_vma locks to serialize against concurrent expand_stacks
37424 ++ * and expand_upwards.
37425 + */
37426 +- if (address < PAGE_ALIGN(address+4))
37427 +- address = PAGE_ALIGN(address+4);
37428 +- else {
37429 +- anon_vma_unlock(vma);
37430 +- return -ENOMEM;
37431 +- }
37432 + error = 0;
37433 +
37434 + /* Somebody else might have raced and expanded it already */
37435 +- if (address > vma->vm_end) {
37436 ++ if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) {
37437 + unsigned long size, grow;
37438 +
37439 + size = address - vma->vm_start;
37440 +@@ -1617,6 +1841,8 @@ int expand_upwards(struct vm_area_struct
37441 + if (!error)
37442 + vma->vm_end = address;
37443 + }
37444 ++ if (locknext)
37445 ++ anon_vma_unlock(vma->vm_next);
37446 + anon_vma_unlock(vma);
37447 + return error;
37448 + }
37449 +@@ -1628,7 +1854,8 @@ int expand_upwards(struct vm_area_struct
37450 + static inline int expand_downwards(struct vm_area_struct *vma,
37451 + unsigned long address)
37452 + {
37453 +- int error;
37454 ++ int error, lockprev = 0;
37455 ++ struct vm_area_struct *prev = NULL;
37456 +
37457 + /*
37458 + * We must make sure the anon_vma is allocated
37459 +@@ -1642,6 +1869,15 @@ static inline int expand_downwards(struc
37460 + if (error)
37461 + return error;
37462 +
37463 ++#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
37464 ++ find_vma_prev(vma->vm_mm, address, &prev);
37465 ++ lockprev = prev && (prev->vm_flags & VM_GROWSUP);
37466 ++#endif
37467 ++ if (lockprev && unlikely(anon_vma_prepare(prev)))
37468 ++ return -ENOMEM;
37469 ++ if (lockprev)
37470 ++ anon_vma_lock(prev);
37471 ++
37472 + anon_vma_lock(vma);
37473 +
37474 + /*
37475 +@@ -1651,9 +1887,15 @@ static inline int expand_downwards(struc
37476 + */
37477 +
37478 + /* Somebody else might have raced and expanded it already */
37479 +- if (address < vma->vm_start) {
37480 ++ if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) {
37481 + unsigned long size, grow;
37482 +
37483 ++#ifdef CONFIG_PAX_SEGMEXEC
37484 ++ struct vm_area_struct *vma_m;
37485 ++
37486 ++ vma_m = pax_find_mirror_vma(vma);
37487 ++#endif
37488 ++
37489 + size = vma->vm_end - address;
37490 + grow = (vma->vm_start - address) >> PAGE_SHIFT;
37491 +
37492 +@@ -1661,9 +1903,20 @@ static inline int expand_downwards(struc
37493 + if (!error) {
37494 + vma->vm_start = address;
37495 + vma->vm_pgoff -= grow;
37496 ++ track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
37497 ++
37498 ++#ifdef CONFIG_PAX_SEGMEXEC
37499 ++ if (vma_m) {
37500 ++ vma_m->vm_start -= grow << PAGE_SHIFT;
37501 ++ vma_m->vm_pgoff -= grow;
37502 ++ }
37503 ++#endif
37504 ++
37505 + }
37506 + }
37507 + anon_vma_unlock(vma);
37508 ++ if (lockprev)
37509 ++ anon_vma_unlock(prev);
37510 + return error;
37511 + }
37512 +
37513 +@@ -1735,6 +1988,13 @@ static void remove_vma_list(struct mm_st
37514 + do {
37515 + long nrpages = vma_pages(vma);
37516 +
37517 ++#ifdef CONFIG_PAX_SEGMEXEC
37518 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) {
37519 ++ vma = remove_vma(vma);
37520 ++ continue;
37521 ++ }
37522 ++#endif
37523 ++
37524 + mm->total_vm -= nrpages;
37525 + if (vma->vm_flags & VM_LOCKED)
37526 + mm->locked_vm -= nrpages;
37527 +@@ -1781,6 +2041,16 @@ detach_vmas_to_be_unmapped(struct mm_str
37528 +
37529 + insertion_point = (prev ? &prev->vm_next : &mm->mmap);
37530 + do {
37531 ++
37532 ++#ifdef CONFIG_PAX_SEGMEXEC
37533 ++ if (vma->vm_mirror) {
37534 ++ BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma);
37535 ++ vma->vm_mirror->vm_mirror = NULL;
37536 ++ vma->vm_mirror->vm_flags &= ~VM_EXEC;
37537 ++ vma->vm_mirror = NULL;
37538 ++ }
37539 ++#endif
37540 ++
37541 + rb_erase(&vma->vm_rb, &mm->mm_rb);
37542 + mm->map_count--;
37543 + tail_vma = vma;
37544 +@@ -1800,6 +2070,108 @@ detach_vmas_to_be_unmapped(struct mm_str
37545 + * Split a vma into two pieces at address 'addr', a new vma is allocated
37546 + * either for the first part or the tail.
37547 + */
37548 ++
37549 ++#ifdef CONFIG_PAX_SEGMEXEC
37550 ++int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
37551 ++ unsigned long addr, int new_below)
37552 ++{
37553 ++ struct mempolicy *pol;
37554 ++ struct vm_area_struct *new, *vma_m, *new_m = NULL;
37555 ++ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE;
37556 ++
37557 ++ if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK))
37558 ++ return -EINVAL;
37559 ++
37560 ++ vma_m = pax_find_mirror_vma(vma);
37561 ++ if (vma_m) {
37562 ++ BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE);
37563 ++ if (mm->map_count >= sysctl_max_map_count-1)
37564 ++ return -ENOMEM;
37565 ++ } else if (mm->map_count >= sysctl_max_map_count)
37566 ++ return -ENOMEM;
37567 ++
37568 ++ new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
37569 ++ if (!new)
37570 ++ return -ENOMEM;
37571 ++
37572 ++ if (vma_m) {
37573 ++ new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
37574 ++ if (!new_m) {
37575 ++ kmem_cache_free(vm_area_cachep, new);
37576 ++ return -ENOMEM;
37577 ++ }
37578 ++ }
37579 ++
37580 ++ /* most fields are the same, copy all, and then fixup */
37581 ++ *new = *vma;
37582 ++
37583 ++ if (new_below)
37584 ++ new->vm_end = addr;
37585 ++ else {
37586 ++ new->vm_start = addr;
37587 ++ new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
37588 ++ }
37589 ++
37590 ++ if (vma_m) {
37591 ++ *new_m = *vma_m;
37592 ++ new_m->vm_mirror = new;
37593 ++ new->vm_mirror = new_m;
37594 ++
37595 ++ if (new_below)
37596 ++ new_m->vm_end = addr_m;
37597 ++ else {
37598 ++ new_m->vm_start = addr_m;
37599 ++ new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT);
37600 ++ }
37601 ++ }
37602 ++
37603 ++ pol = mpol_dup(vma_policy(vma));
37604 ++ if (IS_ERR(pol)) {
37605 ++ if (new_m)
37606 ++ kmem_cache_free(vm_area_cachep, new_m);
37607 ++ kmem_cache_free(vm_area_cachep, new);
37608 ++ return PTR_ERR(pol);
37609 ++ }
37610 ++ vma_set_policy(new, pol);
37611 ++
37612 ++ if (new->vm_file) {
37613 ++ get_file(new->vm_file);
37614 ++ if (vma->vm_flags & VM_EXECUTABLE)
37615 ++ added_exe_file_vma(mm);
37616 ++ }
37617 ++
37618 ++ if (new->vm_ops && new->vm_ops->open)
37619 ++ new->vm_ops->open(new);
37620 ++
37621 ++ if (new_below)
37622 ++ vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
37623 ++ ((addr - new->vm_start) >> PAGE_SHIFT), new);
37624 ++ else
37625 ++ vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
37626 ++
37627 ++ if (vma_m) {
37628 ++ mpol_get(pol);
37629 ++ vma_set_policy(new_m, pol);
37630 ++
37631 ++ if (new_m->vm_file) {
37632 ++ get_file(new_m->vm_file);
37633 ++ if (vma_m->vm_flags & VM_EXECUTABLE)
37634 ++ added_exe_file_vma(mm);
37635 ++ }
37636 ++
37637 ++ if (new_m->vm_ops && new_m->vm_ops->open)
37638 ++ new_m->vm_ops->open(new_m);
37639 ++
37640 ++ if (new_below)
37641 ++ vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff +
37642 ++ ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m);
37643 ++ else
37644 ++ vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m);
37645 ++ }
37646 ++
37647 ++ return 0;
37648 ++}
37649 ++#else
37650 + int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
37651 + unsigned long addr, int new_below)
37652 + {
37653 +@@ -1850,17 +2222,37 @@ int split_vma(struct mm_struct * mm, str
37654 +
37655 + return 0;
37656 + }
37657 ++#endif
37658 +
37659 + /* Munmap is split into 2 main parts -- this part which finds
37660 + * what needs doing, and the areas themselves, which do the
37661 + * work. This now handles partial unmappings.
37662 + * Jeremy Fitzhardinge <jeremy@××××.org>
37663 + */
37664 ++#ifdef CONFIG_PAX_SEGMEXEC
37665 ++int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
37666 ++{
37667 ++ int ret = __do_munmap(mm, start, len);
37668 ++ if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC))
37669 ++ return ret;
37670 ++
37671 ++ return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
37672 ++}
37673 ++
37674 ++int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
37675 ++#else
37676 + int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
37677 ++#endif
37678 + {
37679 + unsigned long end;
37680 + struct vm_area_struct *vma, *prev, *last;
37681 +
37682 ++ /*
37683 ++ * mm->mmap_sem is required to protect against another thread
37684 ++ * changing the mappings in case we sleep.
37685 ++ */
37686 ++ verify_mm_writelocked(mm);
37687 ++
37688 + if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
37689 + return -EINVAL;
37690 +
37691 +@@ -1910,6 +2302,8 @@ int do_munmap(struct mm_struct *mm, unsi
37692 + /* Fix up all other VM information */
37693 + remove_vma_list(mm, vma);
37694 +
37695 ++ track_exec_limit(mm, start, end, 0UL);
37696 ++
37697 + return 0;
37698 + }
37699 +
37700 +@@ -1922,22 +2316,18 @@ asmlinkage long sys_munmap(unsigned long
37701 +
37702 + profile_munmap(addr);
37703 +
37704 ++#ifdef CONFIG_PAX_SEGMEXEC
37705 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
37706 ++ (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
37707 ++ return -EINVAL;
37708 ++#endif
37709 ++
37710 + down_write(&mm->mmap_sem);
37711 + ret = do_munmap(mm, addr, len);
37712 + up_write(&mm->mmap_sem);
37713 + return ret;
37714 + }
37715 +
37716 +-static inline void verify_mm_writelocked(struct mm_struct *mm)
37717 +-{
37718 +-#ifdef CONFIG_DEBUG_VM
37719 +- if (unlikely(down_read_trylock(&mm->mmap_sem))) {
37720 +- WARN_ON(1);
37721 +- up_read(&mm->mmap_sem);
37722 +- }
37723 +-#endif
37724 +-}
37725 +-
37726 + /*
37727 + * this is really a simplified "do_mmap". it only handles
37728 + * anonymous maps. eventually we may be able to do some
37729 +@@ -1951,6 +2341,11 @@ unsigned long do_brk(unsigned long addr,
37730 + struct rb_node ** rb_link, * rb_parent;
37731 + pgoff_t pgoff = addr >> PAGE_SHIFT;
37732 + int error;
37733 ++ unsigned long charged;
37734 ++
37735 ++#ifdef CONFIG_PAX_SEGMEXEC
37736 ++ struct vm_area_struct *vma_m = NULL;
37737 ++#endif
37738 +
37739 + len = PAGE_ALIGN(len);
37740 + if (!len)
37741 +@@ -1968,19 +2363,34 @@ unsigned long do_brk(unsigned long addr,
37742 +
37743 + flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
37744 +
37745 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
37746 ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
37747 ++ flags &= ~VM_EXEC;
37748 ++
37749 ++#ifdef CONFIG_PAX_MPROTECT
37750 ++ if (mm->pax_flags & MF_PAX_MPROTECT)
37751 ++ flags &= ~VM_MAYEXEC;
37752 ++#endif
37753 ++
37754 ++ }
37755 ++#endif
37756 ++
37757 + error = arch_mmap_check(addr, len, flags);
37758 + if (error)
37759 + return error;
37760 +
37761 ++ charged = len >> PAGE_SHIFT;
37762 ++
37763 + /*
37764 + * mlock MCL_FUTURE?
37765 + */
37766 + if (mm->def_flags & VM_LOCKED) {
37767 + unsigned long locked, lock_limit;
37768 +- locked = len >> PAGE_SHIFT;
37769 ++ locked = charged;
37770 + locked += mm->locked_vm;
37771 + lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
37772 + lock_limit >>= PAGE_SHIFT;
37773 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
37774 + if (locked > lock_limit && !capable(CAP_IPC_LOCK))
37775 + return -EAGAIN;
37776 + }
37777 +@@ -1994,22 +2404,22 @@ unsigned long do_brk(unsigned long addr,
37778 + /*
37779 + * Clear old maps. this also does some error checking for us
37780 + */
37781 +- munmap_back:
37782 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
37783 + if (vma && vma->vm_start < addr + len) {
37784 + if (do_munmap(mm, addr, len))
37785 + return -ENOMEM;
37786 +- goto munmap_back;
37787 ++ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
37788 ++ BUG_ON(vma && vma->vm_start < addr + len);
37789 + }
37790 +
37791 + /* Check against address space limits *after* clearing old maps... */
37792 +- if (!may_expand_vm(mm, len >> PAGE_SHIFT))
37793 ++ if (!may_expand_vm(mm, charged))
37794 + return -ENOMEM;
37795 +
37796 + if (mm->map_count > sysctl_max_map_count)
37797 + return -ENOMEM;
37798 +
37799 +- if (security_vm_enough_memory(len >> PAGE_SHIFT))
37800 ++ if (security_vm_enough_memory(charged))
37801 + return -ENOMEM;
37802 +
37803 + /* Can we just expand an old private anonymous mapping? */
37804 +@@ -2022,10 +2432,21 @@ unsigned long do_brk(unsigned long addr,
37805 + */
37806 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
37807 + if (!vma) {
37808 +- vm_unacct_memory(len >> PAGE_SHIFT);
37809 ++ vm_unacct_memory(charged);
37810 + return -ENOMEM;
37811 + }
37812 +
37813 ++#ifdef CONFIG_PAX_SEGMEXEC
37814 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (flags & VM_EXEC)) {
37815 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
37816 ++ if (!vma_m) {
37817 ++ kmem_cache_free(vm_area_cachep, vma);
37818 ++ vm_unacct_memory(charged);
37819 ++ return -ENOMEM;
37820 ++ }
37821 ++ }
37822 ++#endif
37823 ++
37824 + vma->vm_mm = mm;
37825 + vma->vm_start = addr;
37826 + vma->vm_end = addr + len;
37827 +@@ -2033,12 +2454,19 @@ unsigned long do_brk(unsigned long addr,
37828 + vma->vm_flags = flags;
37829 + vma->vm_page_prot = vm_get_page_prot(flags);
37830 + vma_link(mm, vma, prev, rb_link, rb_parent);
37831 ++
37832 ++#ifdef CONFIG_PAX_SEGMEXEC
37833 ++ if (vma_m)
37834 ++ pax_mirror_vma(vma_m, vma);
37835 ++#endif
37836 ++
37837 + out:
37838 +- mm->total_vm += len >> PAGE_SHIFT;
37839 ++ mm->total_vm += charged;
37840 + if (flags & VM_LOCKED) {
37841 +- mm->locked_vm += len >> PAGE_SHIFT;
37842 ++ mm->locked_vm += charged;
37843 + make_pages_present(addr, addr + len);
37844 + }
37845 ++ track_exec_limit(mm, addr, addr + len, flags);
37846 + return addr;
37847 + }
37848 +
37849 +@@ -2069,8 +2497,10 @@ void exit_mmap(struct mm_struct *mm)
37850 + * Walk the list again, actually closing and freeing it,
37851 + * with preemption enabled, without holding any MM locks.
37852 + */
37853 +- while (vma)
37854 ++ while (vma) {
37855 ++ vma->vm_mirror = NULL;
37856 + vma = remove_vma(vma);
37857 ++ }
37858 +
37859 + BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
37860 + }
37861 +@@ -2084,6 +2514,10 @@ int insert_vm_struct(struct mm_struct *
37862 + struct vm_area_struct * __vma, * prev;
37863 + struct rb_node ** rb_link, * rb_parent;
37864 +
37865 ++#ifdef CONFIG_PAX_SEGMEXEC
37866 ++ struct vm_area_struct *vma_m = NULL;
37867 ++#endif
37868 ++
37869 + /*
37870 + * The vm_pgoff of a purely anonymous vma should be irrelevant
37871 + * until its first write fault, when page's anon_vma and index
37872 +@@ -2106,7 +2540,22 @@ int insert_vm_struct(struct mm_struct *
37873 + if ((vma->vm_flags & VM_ACCOUNT) &&
37874 + security_vm_enough_memory_mm(mm, vma_pages(vma)))
37875 + return -ENOMEM;
37876 ++
37877 ++#ifdef CONFIG_PAX_SEGMEXEC
37878 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) {
37879 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
37880 ++ if (!vma_m)
37881 ++ return -ENOMEM;
37882 ++ }
37883 ++#endif
37884 ++
37885 + vma_link(mm, vma, prev, rb_link, rb_parent);
37886 ++
37887 ++#ifdef CONFIG_PAX_SEGMEXEC
37888 ++ if (vma_m)
37889 ++ pax_mirror_vma(vma_m, vma);
37890 ++#endif
37891 ++
37892 + return 0;
37893 + }
37894 +
37895 +@@ -2124,6 +2573,8 @@ struct vm_area_struct *copy_vma(struct v
37896 + struct rb_node **rb_link, *rb_parent;
37897 + struct mempolicy *pol;
37898 +
37899 ++ BUG_ON(vma->vm_mirror);
37900 ++
37901 + /*
37902 + * If anonymous vma has not yet been faulted, update new pgoff
37903 + * to match new location, to increase its chance of merging.
37904 +@@ -2167,6 +2618,35 @@ struct vm_area_struct *copy_vma(struct v
37905 + return new_vma;
37906 + }
37907 +
37908 ++#ifdef CONFIG_PAX_SEGMEXEC
37909 ++void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma)
37910 ++{
37911 ++ struct vm_area_struct *prev_m;
37912 ++ struct rb_node **rb_link_m, *rb_parent_m;
37913 ++ struct mempolicy *pol_m;
37914 ++
37915 ++ BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC));
37916 ++ BUG_ON(vma->vm_mirror || vma_m->vm_mirror);
37917 ++ BUG_ON(!mpol_equal(vma_policy(vma), vma_policy(vma_m)));
37918 ++ *vma_m = *vma;
37919 ++ pol_m = vma_policy(vma_m);
37920 ++ mpol_get(pol_m);
37921 ++ vma_set_policy(vma_m, pol_m);
37922 ++ vma_m->vm_start += SEGMEXEC_TASK_SIZE;
37923 ++ vma_m->vm_end += SEGMEXEC_TASK_SIZE;
37924 ++ vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED);
37925 ++ vma_m->vm_page_prot = vm_get_page_prot(vma_m->vm_flags);
37926 ++ if (vma_m->vm_file)
37927 ++ get_file(vma_m->vm_file);
37928 ++ if (vma_m->vm_ops && vma_m->vm_ops->open)
37929 ++ vma_m->vm_ops->open(vma_m);
37930 ++ find_vma_prepare(vma->vm_mm, vma_m->vm_start, &prev_m, &rb_link_m, &rb_parent_m);
37931 ++ vma_link(vma->vm_mm, vma_m, prev_m, rb_link_m, rb_parent_m);
37932 ++ vma_m->vm_mirror = vma;
37933 ++ vma->vm_mirror = vma_m;
37934 ++}
37935 ++#endif
37936 ++
37937 + /*
37938 + * Return true if the calling process may expand its vm space by the passed
37939 + * number of pages
37940 +@@ -2177,7 +2657,7 @@ int may_expand_vm(struct mm_struct *mm,
37941 + unsigned long lim;
37942 +
37943 + lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
37944 +-
37945 ++ gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
37946 + if (cur + npages > lim)
37947 + return 0;
37948 + return 1;
37949 +@@ -2246,6 +2726,15 @@ int install_special_mapping(struct mm_st
37950 + vma->vm_start = addr;
37951 + vma->vm_end = addr + len;
37952 +
37953 ++#ifdef CONFIG_PAX_MPROTECT
37954 ++ if (mm->pax_flags & MF_PAX_MPROTECT) {
37955 ++ if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC)
37956 ++ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
37957 ++ else
37958 ++ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
37959 ++ }
37960 ++#endif
37961 ++
37962 + vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
37963 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
37964 +
37965 +diff -urNp linux-2.6.26.6/mm/mprotect.c linux-2.6.26.6/mm/mprotect.c
37966 +--- linux-2.6.26.6/mm/mprotect.c 2008-10-08 23:24:05.000000000 -0400
37967 ++++ linux-2.6.26.6/mm/mprotect.c 2008-10-11 21:54:20.000000000 -0400
37968 +@@ -21,10 +21,17 @@
37969 + #include <linux/syscalls.h>
37970 + #include <linux/swap.h>
37971 + #include <linux/swapops.h>
37972 ++#include <linux/grsecurity.h>
37973 ++
37974 ++#ifdef CONFIG_PAX_MPROTECT
37975 ++#include <linux/elf.h>
37976 ++#endif
37977 ++
37978 + #include <asm/uaccess.h>
37979 + #include <asm/pgtable.h>
37980 + #include <asm/cacheflush.h>
37981 + #include <asm/tlbflush.h>
37982 ++#include <asm/mmu_context.h>
37983 +
37984 + #ifndef pgprot_modify
37985 + static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
37986 +@@ -134,6 +141,48 @@ static void change_protection(struct vm_
37987 + flush_tlb_range(vma, start, end);
37988 + }
37989 +
37990 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
37991 ++/* called while holding the mmap semaphor for writing except stack expansion */
37992 ++void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
37993 ++{
37994 ++ unsigned long oldlimit, newlimit = 0UL;
37995 ++
37996 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || nx_enabled)
37997 ++ return;
37998 ++
37999 ++ spin_lock(&mm->page_table_lock);
38000 ++ oldlimit = mm->context.user_cs_limit;
38001 ++ if ((prot & VM_EXEC) && oldlimit < end)
38002 ++ /* USER_CS limit moved up */
38003 ++ newlimit = end;
38004 ++ else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
38005 ++ /* USER_CS limit moved down */
38006 ++ newlimit = start;
38007 ++
38008 ++ if (newlimit) {
38009 ++ mm->context.user_cs_limit = newlimit;
38010 ++
38011 ++#ifdef CONFIG_SMP
38012 ++ wmb();
38013 ++ cpus_clear(mm->context.cpu_user_cs_mask);
38014 ++ cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
38015 ++#endif
38016 ++
38017 ++ set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
38018 ++ }
38019 ++ spin_unlock(&mm->page_table_lock);
38020 ++ if (newlimit == end) {
38021 ++ struct vm_area_struct *vma = find_vma(mm, oldlimit);
38022 ++
38023 ++ for (; vma && vma->vm_start < end; vma = vma->vm_next)
38024 ++ if (is_vm_hugetlb_page(vma))
38025 ++ hugetlb_change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
38026 ++ else
38027 ++ change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
38028 ++ }
38029 ++}
38030 ++#endif
38031 ++
38032 + int
38033 + mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
38034 + unsigned long start, unsigned long end, unsigned long newflags)
38035 +@@ -146,6 +195,14 @@ mprotect_fixup(struct vm_area_struct *vm
38036 + int error;
38037 + int dirty_accountable = 0;
38038 +
38039 ++#ifdef CONFIG_PAX_SEGMEXEC
38040 ++ struct vm_area_struct *vma_m = NULL;
38041 ++ unsigned long start_m, end_m;
38042 ++
38043 ++ start_m = start + SEGMEXEC_TASK_SIZE;
38044 ++ end_m = end + SEGMEXEC_TASK_SIZE;
38045 ++#endif
38046 ++
38047 + if (newflags == oldflags) {
38048 + *pprev = vma;
38049 + return 0;
38050 +@@ -168,6 +225,38 @@ mprotect_fixup(struct vm_area_struct *vm
38051 + }
38052 + }
38053 +
38054 ++#ifdef CONFIG_PAX_SEGMEXEC
38055 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && ((oldflags ^ newflags) & VM_EXEC)) {
38056 ++ if (start != vma->vm_start) {
38057 ++ error = split_vma(mm, vma, start, 1);
38058 ++ if (error)
38059 ++ goto fail;
38060 ++ BUG_ON(!*pprev || (*pprev)->vm_next == vma);
38061 ++ *pprev = (*pprev)->vm_next;
38062 ++ }
38063 ++
38064 ++ if (end != vma->vm_end) {
38065 ++ error = split_vma(mm, vma, end, 0);
38066 ++ if (error)
38067 ++ goto fail;
38068 ++ }
38069 ++
38070 ++ if (pax_find_mirror_vma(vma)) {
38071 ++ error = __do_munmap(mm, start_m, end_m - start_m);
38072 ++ if (error)
38073 ++ goto fail;
38074 ++ } else {
38075 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
38076 ++ if (!vma_m) {
38077 ++ error = -ENOMEM;
38078 ++ goto fail;
38079 ++ }
38080 ++ vma->vm_flags = newflags;
38081 ++ pax_mirror_vma(vma_m, vma);
38082 ++ }
38083 ++ }
38084 ++#endif
38085 ++
38086 + /*
38087 + * First try to merge with previous and/or next vma.
38088 + */
38089 +@@ -220,6 +309,70 @@ fail:
38090 + return error;
38091 + }
38092 +
38093 ++#ifdef CONFIG_PAX_MPROTECT
38094 ++/* PaX: non-PIC ELF libraries need relocations on their executable segments
38095 ++ * therefore we'll grant them VM_MAYWRITE once during their life.
38096 ++ *
38097 ++ * The checks favour ld-linux.so behaviour which operates on a per ELF segment
38098 ++ * basis because we want to allow the common case and not the special ones.
38099 ++ */
38100 ++static inline void pax_handle_maywrite(struct vm_area_struct *vma, unsigned long start)
38101 ++{
38102 ++ struct elfhdr elf_h;
38103 ++ struct elf_phdr elf_p;
38104 ++ elf_addr_t dyn_offset = 0UL;
38105 ++ elf_dyn dyn;
38106 ++ unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
38107 ++
38108 ++#ifndef CONFIG_PAX_NOELFRELOCS
38109 ++ if ((vma->vm_start != start) ||
38110 ++ !vma->vm_file ||
38111 ++ !(vma->vm_flags & VM_MAYEXEC) ||
38112 ++ (vma->vm_flags & VM_MAYNOTWRITE))
38113 ++#endif
38114 ++
38115 ++ return;
38116 ++
38117 ++ if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) ||
38118 ++ memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
38119 ++
38120 ++#ifdef CONFIG_PAX_ETEXECRELOCS
38121 ++ (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
38122 ++#else
38123 ++ elf_h.e_type != ET_DYN ||
38124 ++#endif
38125 ++
38126 ++ !elf_check_arch(&elf_h) ||
38127 ++ elf_h.e_phentsize != sizeof(struct elf_phdr) ||
38128 ++ elf_h.e_phnum > j)
38129 ++ return;
38130 ++
38131 ++ for (i = 0UL; i < elf_h.e_phnum; i++) {
38132 ++ if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p)))
38133 ++ return;
38134 ++ if (elf_p.p_type == PT_DYNAMIC) {
38135 ++ dyn_offset = elf_p.p_offset;
38136 ++ j = i;
38137 ++ }
38138 ++ }
38139 ++ if (elf_h.e_phnum <= j)
38140 ++ return;
38141 ++
38142 ++ i = 0UL;
38143 ++ do {
38144 ++ if (sizeof(dyn) != kernel_read(vma->vm_file, dyn_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn)))
38145 ++ return;
38146 ++ if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
38147 ++ gr_log_textrel(vma);
38148 ++ vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
38149 ++ return;
38150 ++ }
38151 ++ i++;
38152 ++ } while (dyn.d_tag != DT_NULL);
38153 ++ return;
38154 ++}
38155 ++#endif
38156 ++
38157 + asmlinkage long
38158 + sys_mprotect(unsigned long start, size_t len, unsigned long prot)
38159 + {
38160 +@@ -239,6 +392,17 @@ sys_mprotect(unsigned long start, size_t
38161 + end = start + len;
38162 + if (end <= start)
38163 + return -ENOMEM;
38164 ++
38165 ++#ifdef CONFIG_PAX_SEGMEXEC
38166 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
38167 ++ if (end > SEGMEXEC_TASK_SIZE)
38168 ++ return -EINVAL;
38169 ++ } else
38170 ++#endif
38171 ++
38172 ++ if (end > TASK_SIZE)
38173 ++ return -EINVAL;
38174 ++
38175 + if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
38176 + return -EINVAL;
38177 +
38178 +@@ -246,7 +410,7 @@ sys_mprotect(unsigned long start, size_t
38179 + /*
38180 + * Does the application expect PROT_READ to imply PROT_EXEC:
38181 + */
38182 +- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
38183 ++ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
38184 + prot |= PROT_EXEC;
38185 +
38186 + vm_flags = calc_vm_prot_bits(prot);
38187 +@@ -278,6 +442,16 @@ sys_mprotect(unsigned long start, size_t
38188 + if (start > vma->vm_start)
38189 + prev = vma;
38190 +
38191 ++ if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
38192 ++ error = -EACCES;
38193 ++ goto out;
38194 ++ }
38195 ++
38196 ++#ifdef CONFIG_PAX_MPROTECT
38197 ++ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
38198 ++ pax_handle_maywrite(vma, start);
38199 ++#endif
38200 ++
38201 + for (nstart = start ; ; ) {
38202 + unsigned long newflags;
38203 +
38204 +@@ -291,6 +465,12 @@ sys_mprotect(unsigned long start, size_t
38205 + goto out;
38206 + }
38207 +
38208 ++#ifdef CONFIG_PAX_MPROTECT
38209 ++ /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
38210 ++ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
38211 ++ newflags &= ~VM_MAYWRITE;
38212 ++#endif
38213 ++
38214 + error = security_file_mprotect(vma, reqprot, prot);
38215 + if (error)
38216 + goto out;
38217 +@@ -301,6 +481,9 @@ sys_mprotect(unsigned long start, size_t
38218 + error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
38219 + if (error)
38220 + goto out;
38221 ++
38222 ++ track_exec_limit(current->mm, nstart, tmp, vm_flags);
38223 ++
38224 + nstart = tmp;
38225 +
38226 + if (nstart < prev->vm_end)
38227 +diff -urNp linux-2.6.26.6/mm/mremap.c linux-2.6.26.6/mm/mremap.c
38228 +--- linux-2.6.26.6/mm/mremap.c 2008-10-08 23:24:05.000000000 -0400
38229 ++++ linux-2.6.26.6/mm/mremap.c 2008-10-11 21:54:20.000000000 -0400
38230 +@@ -106,6 +106,12 @@ static void move_ptes(struct vm_area_str
38231 + continue;
38232 + pte = ptep_clear_flush(vma, old_addr, old_pte);
38233 + pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
38234 ++
38235 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
38236 ++ if (!nx_enabled && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC)
38237 ++ pte = pte_exprotect(pte);
38238 ++#endif
38239 ++
38240 + set_pte_at(mm, new_addr, new_pte, pte);
38241 + }
38242 +
38243 +@@ -254,6 +260,7 @@ unsigned long do_mremap(unsigned long ad
38244 + struct vm_area_struct *vma;
38245 + unsigned long ret = -EINVAL;
38246 + unsigned long charged = 0;
38247 ++ unsigned long pax_task_size = TASK_SIZE;
38248 +
38249 + if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
38250 + goto out;
38251 +@@ -272,6 +279,15 @@ unsigned long do_mremap(unsigned long ad
38252 + if (!new_len)
38253 + goto out;
38254 +
38255 ++#ifdef CONFIG_PAX_SEGMEXEC
38256 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
38257 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
38258 ++#endif
38259 ++
38260 ++ if (new_len > pax_task_size || addr > pax_task_size-new_len ||
38261 ++ old_len > pax_task_size || addr > pax_task_size-old_len)
38262 ++ goto out;
38263 ++
38264 + /* new_addr is only valid if MREMAP_FIXED is specified */
38265 + if (flags & MREMAP_FIXED) {
38266 + if (new_addr & ~PAGE_MASK)
38267 +@@ -279,16 +295,13 @@ unsigned long do_mremap(unsigned long ad
38268 + if (!(flags & MREMAP_MAYMOVE))
38269 + goto out;
38270 +
38271 +- if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
38272 ++ if (new_addr > pax_task_size - new_len)
38273 + goto out;
38274 +
38275 + /* Check if the location we're moving into overlaps the
38276 + * old location at all, and fail if it does.
38277 + */
38278 +- if ((new_addr <= addr) && (new_addr+new_len) > addr)
38279 +- goto out;
38280 +-
38281 +- if ((addr <= new_addr) && (addr+old_len) > new_addr)
38282 ++ if (addr + old_len > new_addr && new_addr + new_len > addr)
38283 + goto out;
38284 +
38285 + ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
38286 +@@ -326,6 +339,14 @@ unsigned long do_mremap(unsigned long ad
38287 + ret = -EINVAL;
38288 + goto out;
38289 + }
38290 ++
38291 ++#ifdef CONFIG_PAX_SEGMEXEC
38292 ++ if (pax_find_mirror_vma(vma)) {
38293 ++ ret = -EINVAL;
38294 ++ goto out;
38295 ++ }
38296 ++#endif
38297 ++
38298 + /* We can't remap across vm area boundaries */
38299 + if (old_len > vma->vm_end - addr)
38300 + goto out;
38301 +@@ -359,7 +380,7 @@ unsigned long do_mremap(unsigned long ad
38302 + if (old_len == vma->vm_end - addr &&
38303 + !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
38304 + (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
38305 +- unsigned long max_addr = TASK_SIZE;
38306 ++ unsigned long max_addr = pax_task_size;
38307 + if (vma->vm_next)
38308 + max_addr = vma->vm_next->vm_start;
38309 + /* can we just expand the current mapping? */
38310 +@@ -377,6 +398,7 @@ unsigned long do_mremap(unsigned long ad
38311 + addr + new_len);
38312 + }
38313 + ret = addr;
38314 ++ track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
38315 + goto out;
38316 + }
38317 + }
38318 +@@ -387,8 +409,8 @@ unsigned long do_mremap(unsigned long ad
38319 + */
38320 + ret = -ENOMEM;
38321 + if (flags & MREMAP_MAYMOVE) {
38322 ++ unsigned long map_flags = 0;
38323 + if (!(flags & MREMAP_FIXED)) {
38324 +- unsigned long map_flags = 0;
38325 + if (vma->vm_flags & VM_MAYSHARE)
38326 + map_flags |= MAP_SHARED;
38327 +
38328 +@@ -403,7 +425,12 @@ unsigned long do_mremap(unsigned long ad
38329 + if (ret)
38330 + goto out;
38331 + }
38332 ++ map_flags = vma->vm_flags;
38333 + ret = move_vma(vma, addr, old_len, new_len, new_addr);
38334 ++ if (!(ret & ~PAGE_MASK)) {
38335 ++ track_exec_limit(current->mm, addr, addr + old_len, 0UL);
38336 ++ track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
38337 ++ }
38338 + }
38339 + out:
38340 + if (ret & ~PAGE_MASK)
38341 +diff -urNp linux-2.6.26.6/mm/nommu.c linux-2.6.26.6/mm/nommu.c
38342 +--- linux-2.6.26.6/mm/nommu.c 2008-10-08 23:24:05.000000000 -0400
38343 ++++ linux-2.6.26.6/mm/nommu.c 2008-10-11 21:54:20.000000000 -0400
38344 +@@ -416,15 +416,6 @@ struct vm_area_struct *find_vma(struct m
38345 + }
38346 + EXPORT_SYMBOL(find_vma);
38347 +
38348 +-/*
38349 +- * find a VMA
38350 +- * - we don't extend stack VMAs under NOMMU conditions
38351 +- */
38352 +-struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
38353 +-{
38354 +- return find_vma(mm, addr);
38355 +-}
38356 +-
38357 + int expand_stack(struct vm_area_struct *vma, unsigned long address)
38358 + {
38359 + return -ENOMEM;
38360 +diff -urNp linux-2.6.26.6/mm/page_alloc.c linux-2.6.26.6/mm/page_alloc.c
38361 +--- linux-2.6.26.6/mm/page_alloc.c 2008-10-08 23:24:05.000000000 -0400
38362 ++++ linux-2.6.26.6/mm/page_alloc.c 2008-10-11 21:54:20.000000000 -0400
38363 +@@ -497,9 +497,20 @@ static void free_pages_bulk(struct zone
38364 +
38365 + static void free_one_page(struct zone *zone, struct page *page, int order)
38366 + {
38367 ++
38368 ++#ifdef CONFIG_PAX_MEMORY_SANITIZE
38369 ++ unsigned long index = 1UL << order;
38370 ++#endif
38371 ++
38372 + spin_lock(&zone->lock);
38373 + zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE);
38374 + zone->pages_scanned = 0;
38375 ++
38376 ++#ifdef CONFIG_PAX_MEMORY_SANITIZE
38377 ++ for (; index; --index)
38378 ++ sanitize_highpage(page + index - 1);
38379 ++#endif
38380 ++
38381 + __free_one_page(page, zone, order);
38382 + spin_unlock(&zone->lock);
38383 + }
38384 +@@ -617,8 +628,10 @@ static int prep_new_page(struct page *pa
38385 + arch_alloc_page(page, order);
38386 + kernel_map_pages(page, 1 << order, 1);
38387 +
38388 ++#ifndef CONFIG_PAX_MEMORY_SANITIZE
38389 + if (gfp_flags & __GFP_ZERO)
38390 + prep_zero_page(page, order, gfp_flags);
38391 ++#endif
38392 +
38393 + if (order && (gfp_flags & __GFP_COMP))
38394 + prep_compound_page(page, order);
38395 +@@ -990,6 +1003,11 @@ static void free_hot_cold_page(struct pa
38396 + list_add(&page->lru, &pcp->list);
38397 + set_page_private(page, get_pageblock_migratetype(page));
38398 + pcp->count++;
38399 ++
38400 ++#ifdef CONFIG_PAX_MEMORY_SANITIZE
38401 ++ sanitize_highpage(page);
38402 ++#endif
38403 ++
38404 + if (pcp->count >= pcp->high) {
38405 + free_pages_bulk(zone, pcp->batch, &pcp->list, 0);
38406 + pcp->count -= pcp->batch;
38407 +diff -urNp linux-2.6.26.6/mm/rmap.c linux-2.6.26.6/mm/rmap.c
38408 +--- linux-2.6.26.6/mm/rmap.c 2008-10-08 23:24:05.000000000 -0400
38409 ++++ linux-2.6.26.6/mm/rmap.c 2008-10-11 21:54:20.000000000 -0400
38410 +@@ -64,6 +64,10 @@ int anon_vma_prepare(struct vm_area_stru
38411 + struct mm_struct *mm = vma->vm_mm;
38412 + struct anon_vma *allocated, *locked;
38413 +
38414 ++#ifdef CONFIG_PAX_SEGMEXEC
38415 ++ struct vm_area_struct *vma_m;
38416 ++#endif
38417 ++
38418 + anon_vma = find_mergeable_anon_vma(vma);
38419 + if (anon_vma) {
38420 + allocated = NULL;
38421 +@@ -80,6 +84,15 @@ int anon_vma_prepare(struct vm_area_stru
38422 + /* page_table_lock to protect against threads */
38423 + spin_lock(&mm->page_table_lock);
38424 + if (likely(!vma->anon_vma)) {
38425 ++
38426 ++#ifdef CONFIG_PAX_SEGMEXEC
38427 ++ vma_m = pax_find_mirror_vma(vma);
38428 ++ if (vma_m) {
38429 ++ vma_m->anon_vma = anon_vma;
38430 ++ __anon_vma_link(vma_m);
38431 ++ }
38432 ++#endif
38433 ++
38434 + vma->anon_vma = anon_vma;
38435 + list_add_tail(&vma->anon_vma_node, &anon_vma->head);
38436 + allocated = NULL;
38437 +diff -urNp linux-2.6.26.6/mm/shmem.c linux-2.6.26.6/mm/shmem.c
38438 +--- linux-2.6.26.6/mm/shmem.c 2008-10-08 23:24:05.000000000 -0400
38439 ++++ linux-2.6.26.6/mm/shmem.c 2008-10-11 21:54:20.000000000 -0400
38440 +@@ -2460,7 +2460,7 @@ static struct file_system_type tmpfs_fs_
38441 + .get_sb = shmem_get_sb,
38442 + .kill_sb = kill_litter_super,
38443 + };
38444 +-static struct vfsmount *shm_mnt;
38445 ++struct vfsmount *shm_mnt;
38446 +
38447 + static int __init init_tmpfs(void)
38448 + {
38449 +diff -urNp linux-2.6.26.6/mm/slab.c linux-2.6.26.6/mm/slab.c
38450 +--- linux-2.6.26.6/mm/slab.c 2008-10-08 23:24:05.000000000 -0400
38451 ++++ linux-2.6.26.6/mm/slab.c 2008-10-11 21:54:20.000000000 -0400
38452 +@@ -304,7 +304,7 @@ struct kmem_list3 {
38453 + * Need this for bootstrapping a per node allocator.
38454 + */
38455 + #define NUM_INIT_LISTS (3 * MAX_NUMNODES)
38456 +-struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
38457 ++struct kmem_list3 initkmem_list3[NUM_INIT_LISTS];
38458 + #define CACHE_CACHE 0
38459 + #define SIZE_AC MAX_NUMNODES
38460 + #define SIZE_L3 (2 * MAX_NUMNODES)
38461 +@@ -653,14 +653,14 @@ struct cache_names {
38462 + static struct cache_names __initdata cache_names[] = {
38463 + #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
38464 + #include <linux/kmalloc_sizes.h>
38465 +- {NULL,}
38466 ++ {NULL, NULL}
38467 + #undef CACHE
38468 + };
38469 +
38470 + static struct arraycache_init initarray_cache __initdata =
38471 +- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
38472 ++ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
38473 + static struct arraycache_init initarray_generic =
38474 +- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
38475 ++ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
38476 +
38477 + /* internal cache of cache description objs */
38478 + static struct kmem_cache cache_cache = {
38479 +@@ -3005,7 +3005,7 @@ retry:
38480 + * there must be at least one object available for
38481 + * allocation.
38482 + */
38483 +- BUG_ON(slabp->inuse < 0 || slabp->inuse >= cachep->num);
38484 ++ BUG_ON(slabp->inuse >= cachep->num);
38485 +
38486 + while (slabp->inuse < cachep->num && batchcount--) {
38487 + STATS_INC_ALLOCED(cachep);
38488 +diff -urNp linux-2.6.26.6/mm/swap.c linux-2.6.26.6/mm/swap.c
38489 +--- linux-2.6.26.6/mm/swap.c 2008-10-08 23:24:05.000000000 -0400
38490 ++++ linux-2.6.26.6/mm/swap.c 2008-10-11 21:54:20.000000000 -0400
38491 +@@ -34,9 +34,9 @@
38492 + /* How many pages do we try to swap or page in/out together? */
38493 + int page_cluster;
38494 +
38495 +-static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, };
38496 +-static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, };
38497 +-static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs) = { 0, };
38498 ++static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs);
38499 ++static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs);
38500 ++static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs);
38501 +
38502 + /*
38503 + * This path almost never happens for VM activity - pages are normally
38504 +diff -urNp linux-2.6.26.6/mm/tiny-shmem.c linux-2.6.26.6/mm/tiny-shmem.c
38505 +--- linux-2.6.26.6/mm/tiny-shmem.c 2008-10-08 23:24:05.000000000 -0400
38506 ++++ linux-2.6.26.6/mm/tiny-shmem.c 2008-10-11 21:54:20.000000000 -0400
38507 +@@ -26,7 +26,7 @@ static struct file_system_type tmpfs_fs_
38508 + .kill_sb = kill_litter_super,
38509 + };
38510 +
38511 +-static struct vfsmount *shm_mnt;
38512 ++struct vfsmount *shm_mnt;
38513 +
38514 + static int __init init_tmpfs(void)
38515 + {
38516 +diff -urNp linux-2.6.26.6/mm/vmalloc.c linux-2.6.26.6/mm/vmalloc.c
38517 +--- linux-2.6.26.6/mm/vmalloc.c 2008-10-08 23:24:05.000000000 -0400
38518 ++++ linux-2.6.26.6/mm/vmalloc.c 2008-10-11 21:54:20.000000000 -0400
38519 +@@ -248,20 +248,15 @@ __get_vm_area_node(unsigned long size, u
38520 + (unsigned long)tmp->addr, align);
38521 + continue;
38522 + }
38523 +- if ((size + addr) < addr)
38524 +- goto out;
38525 + if (size + addr <= (unsigned long)tmp->addr)
38526 +- goto found;
38527 ++ break;
38528 + addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
38529 +- if (addr > end - size)
38530 +- goto out;
38531 + }
38532 + if ((size + addr) < addr)
38533 + goto out;
38534 + if (addr > end - size)
38535 + goto out;
38536 +
38537 +-found:
38538 + area->next = *p;
38539 + *p = area;
38540 +
38541 +@@ -653,7 +648,7 @@ EXPORT_SYMBOL(vmalloc_node);
38542 +
38543 + void *vmalloc_exec(unsigned long size)
38544 + {
38545 +- return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC);
38546 ++ return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL_EXEC);
38547 + }
38548 +
38549 + #if defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA32)
38550 +diff -urNp linux-2.6.26.6/net/bridge/br_stp_if.c linux-2.6.26.6/net/bridge/br_stp_if.c
38551 +--- linux-2.6.26.6/net/bridge/br_stp_if.c 2008-10-08 23:24:05.000000000 -0400
38552 ++++ linux-2.6.26.6/net/bridge/br_stp_if.c 2008-10-11 21:54:20.000000000 -0400
38553 +@@ -148,7 +148,7 @@ static void br_stp_stop(struct net_bridg
38554 + char *envp[] = { NULL };
38555 +
38556 + if (br->stp_enabled == BR_USER_STP) {
38557 +- r = call_usermodehelper(BR_STP_PROG, argv, envp, 1);
38558 ++ r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
38559 + printk(KERN_INFO "%s: userspace STP stopped, return code %d\n",
38560 + br->dev->name, r);
38561 +
38562 +diff -urNp linux-2.6.26.6/net/core/flow.c linux-2.6.26.6/net/core/flow.c
38563 +--- linux-2.6.26.6/net/core/flow.c 2008-10-08 23:24:05.000000000 -0400
38564 ++++ linux-2.6.26.6/net/core/flow.c 2008-10-11 21:54:20.000000000 -0400
38565 +@@ -39,7 +39,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT(
38566 +
38567 + static u32 flow_hash_shift;
38568 + #define flow_hash_size (1 << flow_hash_shift)
38569 +-static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL };
38570 ++static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables);
38571 +
38572 + #define flow_table(cpu) (per_cpu(flow_tables, cpu))
38573 +
38574 +@@ -52,7 +52,7 @@ struct flow_percpu_info {
38575 + u32 hash_rnd;
38576 + int count;
38577 + };
38578 +-static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 };
38579 ++static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info);
38580 +
38581 + #define flow_hash_rnd_recalc(cpu) \
38582 + (per_cpu(flow_hash_info, cpu).hash_rnd_recalc)
38583 +@@ -69,7 +69,7 @@ struct flow_flush_info {
38584 + atomic_t cpuleft;
38585 + struct completion completion;
38586 + };
38587 +-static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL };
38588 ++static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets);
38589 +
38590 + #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu))
38591 +
38592 +diff -urNp linux-2.6.26.6/net/dccp/ccids/ccid3.c linux-2.6.26.6/net/dccp/ccids/ccid3.c
38593 +--- linux-2.6.26.6/net/dccp/ccids/ccid3.c 2008-10-08 23:24:05.000000000 -0400
38594 ++++ linux-2.6.26.6/net/dccp/ccids/ccid3.c 2008-10-11 21:54:20.000000000 -0400
38595 +@@ -43,7 +43,7 @@
38596 + static int ccid3_debug;
38597 + #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
38598 + #else
38599 +-#define ccid3_pr_debug(format, a...)
38600 ++#define ccid3_pr_debug(format, a...) do {} while (0)
38601 + #endif
38602 +
38603 + /*
38604 +diff -urNp linux-2.6.26.6/net/dccp/dccp.h linux-2.6.26.6/net/dccp/dccp.h
38605 +--- linux-2.6.26.6/net/dccp/dccp.h 2008-10-08 23:24:05.000000000 -0400
38606 ++++ linux-2.6.26.6/net/dccp/dccp.h 2008-10-11 21:54:20.000000000 -0400
38607 +@@ -43,8 +43,8 @@ extern int dccp_debug;
38608 + #define dccp_pr_debug(format, a...) DCCP_PR_DEBUG(dccp_debug, format, ##a)
38609 + #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a)
38610 + #else
38611 +-#define dccp_pr_debug(format, a...)
38612 +-#define dccp_pr_debug_cat(format, a...)
38613 ++#define dccp_pr_debug(format, a...) do {} while (0)
38614 ++#define dccp_pr_debug_cat(format, a...) do {} while (0)
38615 + #endif
38616 +
38617 + extern struct inet_hashinfo dccp_hashinfo;
38618 +diff -urNp linux-2.6.26.6/net/ipv4/inet_connection_sock.c linux-2.6.26.6/net/ipv4/inet_connection_sock.c
38619 +--- linux-2.6.26.6/net/ipv4/inet_connection_sock.c 2008-10-08 23:24:05.000000000 -0400
38620 ++++ linux-2.6.26.6/net/ipv4/inet_connection_sock.c 2008-10-11 21:54:20.000000000 -0400
38621 +@@ -15,6 +15,7 @@
38622 +
38623 + #include <linux/module.h>
38624 + #include <linux/jhash.h>
38625 ++#include <linux/grsecurity.h>
38626 +
38627 + #include <net/inet_connection_sock.h>
38628 + #include <net/inet_hashtables.h>
38629 +diff -urNp linux-2.6.26.6/net/ipv4/inet_hashtables.c linux-2.6.26.6/net/ipv4/inet_hashtables.c
38630 +--- linux-2.6.26.6/net/ipv4/inet_hashtables.c 2008-10-08 23:24:05.000000000 -0400
38631 ++++ linux-2.6.26.6/net/ipv4/inet_hashtables.c 2008-10-11 21:54:20.000000000 -0400
38632 +@@ -18,11 +18,14 @@
38633 + #include <linux/sched.h>
38634 + #include <linux/slab.h>
38635 + #include <linux/wait.h>
38636 ++#include <linux/grsecurity.h>
38637 +
38638 + #include <net/inet_connection_sock.h>
38639 + #include <net/inet_hashtables.h>
38640 + #include <net/ip.h>
38641 +
38642 ++extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
38643 ++
38644 + /*
38645 + * Allocate and initialize a new local port bind bucket.
38646 + * The bindhash mutex for snum's hash chain must be held here.
38647 +@@ -484,6 +487,8 @@ ok:
38648 + }
38649 + spin_unlock(&head->lock);
38650 +
38651 ++ gr_update_task_in_ip_table(current, inet_sk(sk));
38652 ++
38653 + if (tw) {
38654 + inet_twsk_deschedule(tw, death_row);
38655 + inet_twsk_put(tw);
38656 +diff -urNp linux-2.6.26.6/net/ipv4/netfilter/ipt_stealth.c linux-2.6.26.6/net/ipv4/netfilter/ipt_stealth.c
38657 +--- linux-2.6.26.6/net/ipv4/netfilter/ipt_stealth.c 1969-12-31 19:00:00.000000000 -0500
38658 ++++ linux-2.6.26.6/net/ipv4/netfilter/ipt_stealth.c 2008-10-11 21:54:20.000000000 -0400
38659 +@@ -0,0 +1,114 @@
38660 ++/* Kernel module to add stealth support.
38661 ++ *
38662 ++ * Copyright (C) 2002-2006 Brad Spengler <spender@××××××××××.net>
38663 ++ *
38664 ++ */
38665 ++
38666 ++#include <linux/kernel.h>
38667 ++#include <linux/module.h>
38668 ++#include <linux/skbuff.h>
38669 ++#include <linux/net.h>
38670 ++#include <linux/sched.h>
38671 ++#include <linux/inet.h>
38672 ++#include <linux/stddef.h>
38673 ++
38674 ++#include <net/ip.h>
38675 ++#include <net/sock.h>
38676 ++#include <net/tcp.h>
38677 ++#include <net/udp.h>
38678 ++#include <net/route.h>
38679 ++#include <net/inet_common.h>
38680 ++
38681 ++#include <linux/netfilter_ipv4/ip_tables.h>
38682 ++
38683 ++MODULE_LICENSE("GPL");
38684 ++
38685 ++extern struct sock *udp_v4_lookup(struct net *net, u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
38686 ++
38687 ++static bool
38688 ++match(const struct sk_buff *skb,
38689 ++ const struct net_device *in,
38690 ++ const struct net_device *out,
38691 ++ const struct xt_match *match,
38692 ++ const void *matchinfo,
38693 ++ int offset,
38694 ++ unsigned int protoff,
38695 ++ bool *hotdrop)
38696 ++{
38697 ++ struct iphdr *ip = ip_hdr(skb);
38698 ++ struct tcphdr th;
38699 ++ struct udphdr uh;
38700 ++ struct sock *sk = NULL;
38701 ++
38702 ++ if (!ip || offset) return false;
38703 ++
38704 ++ switch(ip->protocol) {
38705 ++ case IPPROTO_TCP:
38706 ++ if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &th, sizeof(th)) < 0) {
38707 ++ *hotdrop = true;
38708 ++ return false;
38709 ++ }
38710 ++ if (!(th.syn && !th.ack)) return false;
38711 ++ sk = inet_lookup_listener(dev_net(skb->dev), &tcp_hashinfo, ip->daddr, th.dest, inet_iif(skb));
38712 ++ break;
38713 ++ case IPPROTO_UDP:
38714 ++ if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &uh, sizeof(uh)) < 0) {
38715 ++ *hotdrop = true;
38716 ++ return false;
38717 ++ }
38718 ++ sk = udp_v4_lookup(dev_net(skb->dev), ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
38719 ++ break;
38720 ++ default:
38721 ++ return false;
38722 ++ }
38723 ++
38724 ++ if(!sk) // port is being listened on, match this
38725 ++ return true;
38726 ++ else {
38727 ++ sock_put(sk);
38728 ++ return false;
38729 ++ }
38730 ++}
38731 ++
38732 ++/* Called when user tries to insert an entry of this type. */
38733 ++static bool
38734 ++checkentry(const char *tablename,
38735 ++ const void *nip,
38736 ++ const struct xt_match *match,
38737 ++ void *matchinfo,
38738 ++ unsigned int hook_mask)
38739 ++{
38740 ++ const struct ipt_ip *ip = (const struct ipt_ip *)nip;
38741 ++
38742 ++ if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
38743 ++ ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
38744 ++ && (hook_mask & (1 << NF_INET_LOCAL_IN)))
38745 ++ return true;
38746 ++
38747 ++ printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
38748 ++
38749 ++ return false;
38750 ++}
38751 ++
38752 ++
38753 ++static struct xt_match stealth_match __read_mostly = {
38754 ++ .name = "stealth",
38755 ++ .family = AF_INET,
38756 ++ .match = match,
38757 ++ .checkentry = checkentry,
38758 ++ .destroy = NULL,
38759 ++ .me = THIS_MODULE
38760 ++};
38761 ++
38762 ++static int __init init(void)
38763 ++{
38764 ++ return xt_register_match(&stealth_match);
38765 ++}
38766 ++
38767 ++static void __exit fini(void)
38768 ++{
38769 ++ xt_unregister_match(&stealth_match);
38770 ++}
38771 ++
38772 ++module_init(init);
38773 ++module_exit(fini);
38774 +diff -urNp linux-2.6.26.6/net/ipv4/netfilter/Kconfig linux-2.6.26.6/net/ipv4/netfilter/Kconfig
38775 +--- linux-2.6.26.6/net/ipv4/netfilter/Kconfig 2008-10-08 23:24:05.000000000 -0400
38776 ++++ linux-2.6.26.6/net/ipv4/netfilter/Kconfig 2008-10-11 21:54:20.000000000 -0400
38777 +@@ -111,6 +111,21 @@ config IP_NF_MATCH_ADDRTYPE
38778 + If you want to compile it as a module, say M here and read
38779 + <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
38780 +
38781 ++config IP_NF_MATCH_STEALTH
38782 ++ tristate "stealth match support"
38783 ++ depends on IP_NF_IPTABLES
38784 ++ help
38785 ++ Enabling this option will drop all syn packets coming to unserved tcp
38786 ++ ports as well as all packets coming to unserved udp ports. If you
38787 ++ are using your system to route any type of packets (ie. via NAT)
38788 ++ you should put this module at the end of your ruleset, since it will
38789 ++ drop packets that aren't going to ports that are listening on your
38790 ++ machine itself, it doesn't take into account that the packet might be
38791 ++ destined for someone on your internal network if you're using NAT for
38792 ++ instance.
38793 ++
38794 ++ To compile it as a module, choose M here. If unsure, say N.
38795 ++
38796 + # `filter', generic and specific targets
38797 + config IP_NF_FILTER
38798 + tristate "Packet filtering"
38799 +@@ -396,4 +411,3 @@ config IP_NF_ARP_MANGLE
38800 + hardware and network addresses.
38801 +
38802 + endmenu
38803 +-
38804 +diff -urNp linux-2.6.26.6/net/ipv4/netfilter/Makefile linux-2.6.26.6/net/ipv4/netfilter/Makefile
38805 +--- linux-2.6.26.6/net/ipv4/netfilter/Makefile 2008-10-08 23:24:05.000000000 -0400
38806 ++++ linux-2.6.26.6/net/ipv4/netfilter/Makefile 2008-10-11 21:54:20.000000000 -0400
38807 +@@ -58,6 +58,7 @@ obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) +=
38808 + obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
38809 + obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
38810 + obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
38811 ++obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
38812 + obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
38813 + obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
38814 +
38815 +diff -urNp linux-2.6.26.6/net/ipv4/tcp_ipv4.c linux-2.6.26.6/net/ipv4/tcp_ipv4.c
38816 +--- linux-2.6.26.6/net/ipv4/tcp_ipv4.c 2008-10-08 23:24:05.000000000 -0400
38817 ++++ linux-2.6.26.6/net/ipv4/tcp_ipv4.c 2008-10-11 21:54:20.000000000 -0400
38818 +@@ -61,6 +61,7 @@
38819 + #include <linux/jhash.h>
38820 + #include <linux/init.h>
38821 + #include <linux/times.h>
38822 ++#include <linux/grsecurity.h>
38823 +
38824 + #include <net/net_namespace.h>
38825 + #include <net/icmp.h>
38826 +diff -urNp linux-2.6.26.6/net/ipv4/udp.c linux-2.6.26.6/net/ipv4/udp.c
38827 +--- linux-2.6.26.6/net/ipv4/udp.c 2008-10-08 23:24:05.000000000 -0400
38828 ++++ linux-2.6.26.6/net/ipv4/udp.c 2008-10-11 21:54:20.000000000 -0400
38829 +@@ -99,6 +99,7 @@
38830 + #include <linux/skbuff.h>
38831 + #include <linux/proc_fs.h>
38832 + #include <linux/seq_file.h>
38833 ++#include <linux/grsecurity.h>
38834 + #include <net/net_namespace.h>
38835 + #include <net/icmp.h>
38836 + #include <net/route.h>
38837 +@@ -106,6 +107,11 @@
38838 + #include <net/xfrm.h>
38839 + #include "udp_impl.h"
38840 +
38841 ++extern int gr_search_udp_recvmsg(const struct sock *sk,
38842 ++ const struct sk_buff *skb);
38843 ++extern int gr_search_udp_sendmsg(const struct sock *sk,
38844 ++ const struct sockaddr_in *addr);
38845 ++
38846 + /*
38847 + * Snmp MIB for the UDP layer
38848 + */
38849 +@@ -307,6 +313,13 @@ static struct sock *__udp4_lib_lookup(st
38850 + return result;
38851 + }
38852 +
38853 ++struct sock *udp_v4_lookup(struct net *net, __be32 saddr, __be16 sport,
38854 ++ __be32 daddr, __be16 dport, int dif)
38855 ++{
38856 ++ return __udp4_lib_lookup(net, saddr, sport, daddr, dport, dif, udp_hash);
38857 ++}
38858 ++
38859 ++
38860 + static inline struct sock *udp_v4_mcast_next(struct sock *sk,
38861 + __be16 loc_port, __be32 loc_addr,
38862 + __be16 rmt_port, __be32 rmt_addr,
38863 +@@ -594,9 +607,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
38864 + dport = usin->sin_port;
38865 + if (dport == 0)
38866 + return -EINVAL;
38867 ++
38868 ++ if (!gr_search_udp_sendmsg(sk, usin))
38869 ++ return -EPERM;
38870 + } else {
38871 + if (sk->sk_state != TCP_ESTABLISHED)
38872 + return -EDESTADDRREQ;
38873 ++
38874 ++ if (!gr_search_udp_sendmsg(sk, NULL))
38875 ++ return -EPERM;
38876 ++
38877 + daddr = inet->daddr;
38878 + dport = inet->dport;
38879 + /* Open fast path for connected socket.
38880 +@@ -858,6 +878,11 @@ try_again:
38881 + if (!skb)
38882 + goto out;
38883 +
38884 ++ if (!gr_search_udp_recvmsg(sk, skb)) {
38885 ++ err = -EPERM;
38886 ++ goto out_free;
38887 ++ }
38888 ++
38889 + ulen = skb->len - sizeof(struct udphdr);
38890 + copied = len;
38891 + if (copied > ulen)
38892 +diff -urNp linux-2.6.26.6/net/ipv6/exthdrs.c linux-2.6.26.6/net/ipv6/exthdrs.c
38893 +--- linux-2.6.26.6/net/ipv6/exthdrs.c 2008-10-08 23:24:05.000000000 -0400
38894 ++++ linux-2.6.26.6/net/ipv6/exthdrs.c 2008-10-11 21:54:20.000000000 -0400
38895 +@@ -626,7 +626,7 @@ static struct tlvtype_proc tlvprochopopt
38896 + .type = IPV6_TLV_JUMBO,
38897 + .func = ipv6_hop_jumbo,
38898 + },
38899 +- { -1, }
38900 ++ { -1, NULL }
38901 + };
38902 +
38903 + int ipv6_parse_hopopts(struct sk_buff *skb)
38904 +diff -urNp linux-2.6.26.6/net/ipv6/raw.c linux-2.6.26.6/net/ipv6/raw.c
38905 +--- linux-2.6.26.6/net/ipv6/raw.c 2008-10-08 23:24:05.000000000 -0400
38906 ++++ linux-2.6.26.6/net/ipv6/raw.c 2008-10-11 21:54:20.000000000 -0400
38907 +@@ -602,7 +602,7 @@ out:
38908 + return err;
38909 + }
38910 +
38911 +-static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
38912 ++static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
38913 + struct flowi *fl, struct rt6_info *rt,
38914 + unsigned int flags)
38915 + {
38916 +diff -urNp linux-2.6.26.6/net/irda/ircomm/ircomm_tty.c linux-2.6.26.6/net/irda/ircomm/ircomm_tty.c
38917 +--- linux-2.6.26.6/net/irda/ircomm/ircomm_tty.c 2008-10-08 23:24:05.000000000 -0400
38918 ++++ linux-2.6.26.6/net/irda/ircomm/ircomm_tty.c 2008-10-11 21:54:20.000000000 -0400
38919 +@@ -371,7 +371,7 @@ static int ircomm_tty_open(struct tty_st
38920 + IRDA_DEBUG(2, "%s()\n", __func__ );
38921 +
38922 + line = tty->index;
38923 +- if ((line < 0) || (line >= IRCOMM_TTY_PORTS)) {
38924 ++ if (line >= IRCOMM_TTY_PORTS) {
38925 + return -ENODEV;
38926 + }
38927 +
38928 +diff -urNp linux-2.6.26.6/net/sctp/socket.c linux-2.6.26.6/net/sctp/socket.c
38929 +--- linux-2.6.26.6/net/sctp/socket.c 2008-10-08 23:24:05.000000000 -0400
38930 ++++ linux-2.6.26.6/net/sctp/socket.c 2008-10-11 21:55:52.000000000 -0400
38931 +@@ -1386,7 +1386,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
38932 + struct sctp_sndrcvinfo *sinfo;
38933 + struct sctp_initmsg *sinit;
38934 + sctp_assoc_t associd = 0;
38935 +- sctp_cmsgs_t cmsgs = { NULL };
38936 ++ sctp_cmsgs_t cmsgs = { NULL, NULL };
38937 + int err;
38938 + sctp_scope_t scope;
38939 + long timeo;
38940 +@@ -5472,7 +5472,6 @@ pp_found:
38941 + */
38942 + int reuse = sk->sk_reuse;
38943 + struct sock *sk2;
38944 +- struct hlist_node *node;
38945 +
38946 + SCTP_DEBUG_PRINTK("sctp_get_port() found a possible match\n");
38947 + if (pp->fastreuse && sk->sk_reuse &&
38948 +diff -urNp linux-2.6.26.6/net/socket.c linux-2.6.26.6/net/socket.c
38949 +--- linux-2.6.26.6/net/socket.c 2008-10-08 23:24:05.000000000 -0400
38950 ++++ linux-2.6.26.6/net/socket.c 2008-10-11 21:54:20.000000000 -0400
38951 +@@ -85,6 +85,7 @@
38952 + #include <linux/audit.h>
38953 + #include <linux/wireless.h>
38954 + #include <linux/nsproxy.h>
38955 ++#include <linux/in.h>
38956 +
38957 + #include <asm/uaccess.h>
38958 + #include <asm/unistd.h>
38959 +@@ -94,6 +95,21 @@
38960 + #include <net/sock.h>
38961 + #include <linux/netfilter.h>
38962 +
38963 ++extern void gr_attach_curr_ip(const struct sock *sk);
38964 ++extern int gr_handle_sock_all(const int family, const int type,
38965 ++ const int protocol);
38966 ++extern int gr_handle_sock_server(const struct sockaddr *sck);
38967 ++extern int gr_handle_sock_server_other(const struct socket *sck);
38968 ++extern int gr_handle_sock_client(const struct sockaddr *sck);
38969 ++extern int gr_search_connect(const struct socket * sock,
38970 ++ const struct sockaddr_in * addr);
38971 ++extern int gr_search_bind(const struct socket * sock,
38972 ++ const struct sockaddr_in * addr);
38973 ++extern int gr_search_listen(const struct socket * sock);
38974 ++extern int gr_search_accept(const struct socket * sock);
38975 ++extern int gr_search_socket(const int domain, const int type,
38976 ++ const int protocol);
38977 ++
38978 + static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
38979 + static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
38980 + unsigned long nr_segs, loff_t pos);
38981 +@@ -297,7 +313,7 @@ static int sockfs_get_sb(struct file_sys
38982 + mnt);
38983 + }
38984 +
38985 +-static struct vfsmount *sock_mnt __read_mostly;
38986 ++struct vfsmount *sock_mnt __read_mostly;
38987 +
38988 + static struct file_system_type sock_fs_type = {
38989 + .name = "sockfs",
38990 +@@ -1218,6 +1234,16 @@ asmlinkage long sys_socket(int family, i
38991 + int retval;
38992 + struct socket *sock;
38993 +
38994 ++ if(!gr_search_socket(family, type, protocol)) {
38995 ++ retval = -EACCES;
38996 ++ goto out;
38997 ++ }
38998 ++
38999 ++ if (gr_handle_sock_all(family, type, protocol)) {
39000 ++ retval = -EACCES;
39001 ++ goto out;
39002 ++ }
39003 ++
39004 + retval = sock_create(family, type, protocol, &sock);
39005 + if (retval < 0)
39006 + goto out;
39007 +@@ -1348,6 +1374,12 @@ asmlinkage long sys_bind(int fd, struct
39008 + if (sock) {
39009 + err = move_addr_to_kernel(umyaddr, addrlen, address);
39010 + if (err >= 0) {
39011 ++ if (!gr_search_bind(sock, (struct sockaddr_in *)address) ||
39012 ++ gr_handle_sock_server((struct sockaddr *)address)) {
39013 ++ err = -EACCES;
39014 ++ goto error;
39015 ++ }
39016 ++
39017 + err = security_socket_bind(sock,
39018 + (struct sockaddr *)address,
39019 + addrlen);
39020 +@@ -1356,6 +1388,7 @@ asmlinkage long sys_bind(int fd, struct
39021 + (struct sockaddr *)
39022 + address, addrlen);
39023 + }
39024 ++error:
39025 + fput_light(sock->file, fput_needed);
39026 + }
39027 + return err;
39028 +@@ -1379,10 +1412,17 @@ asmlinkage long sys_listen(int fd, int b
39029 + if ((unsigned)backlog > somaxconn)
39030 + backlog = somaxconn;
39031 +
39032 ++ if (gr_handle_sock_server_other(sock) ||
39033 ++ !gr_search_listen(sock)) {
39034 ++ err = -EPERM;
39035 ++ goto error;
39036 ++ }
39037 ++
39038 + err = security_socket_listen(sock, backlog);
39039 + if (!err)
39040 + err = sock->ops->listen(sock, backlog);
39041 +
39042 ++error:
39043 + fput_light(sock->file, fput_needed);
39044 + }
39045 + return err;
39046 +@@ -1419,6 +1459,13 @@ asmlinkage long sys_accept(int fd, struc
39047 + newsock->type = sock->type;
39048 + newsock->ops = sock->ops;
39049 +
39050 ++ if (gr_handle_sock_server_other(sock) ||
39051 ++ !gr_search_accept(sock)) {
39052 ++ err = -EPERM;
39053 ++ sock_release(newsock);
39054 ++ goto out_put;
39055 ++ }
39056 ++
39057 + /*
39058 + * We don't need try_module_get here, as the listening socket (sock)
39059 + * has the protocol module (sock->ops->owner) held.
39060 +@@ -1462,6 +1509,7 @@ asmlinkage long sys_accept(int fd, struc
39061 + err = newfd;
39062 +
39063 + security_socket_post_accept(sock, newsock);
39064 ++ gr_attach_curr_ip(newsock->sk);
39065 +
39066 + out_put:
39067 + fput_light(sock->file, fput_needed);
39068 +@@ -1495,6 +1543,7 @@ asmlinkage long sys_connect(int fd, stru
39069 + {
39070 + struct socket *sock;
39071 + char address[MAX_SOCK_ADDR];
39072 ++ struct sockaddr *sck;
39073 + int err, fput_needed;
39074 +
39075 + sock = sockfd_lookup_light(fd, &err, &fput_needed);
39076 +@@ -1504,6 +1553,13 @@ asmlinkage long sys_connect(int fd, stru
39077 + if (err < 0)
39078 + goto out_put;
39079 +
39080 ++ sck = (struct sockaddr *)address;
39081 ++ if (!gr_search_connect(sock, (struct sockaddr_in *)sck) ||
39082 ++ gr_handle_sock_client(sck)) {
39083 ++ err = -EACCES;
39084 ++ goto out_put;
39085 ++ }
39086 ++
39087 + err =
39088 + security_socket_connect(sock, (struct sockaddr *)address, addrlen);
39089 + if (err)
39090 +@@ -1770,6 +1826,7 @@ asmlinkage long sys_shutdown(int fd, int
39091 + err = sock->ops->shutdown(sock, how);
39092 + fput_light(sock->file, fput_needed);
39093 + }
39094 ++
39095 + return err;
39096 + }
39097 +
39098 +diff -urNp linux-2.6.26.6/net/unix/af_unix.c linux-2.6.26.6/net/unix/af_unix.c
39099 +--- linux-2.6.26.6/net/unix/af_unix.c 2008-10-08 23:24:05.000000000 -0400
39100 ++++ linux-2.6.26.6/net/unix/af_unix.c 2008-10-11 21:54:20.000000000 -0400
39101 +@@ -116,6 +116,7 @@
39102 + #include <linux/mount.h>
39103 + #include <net/checksum.h>
39104 + #include <linux/security.h>
39105 ++#include <linux/grsecurity.h>
39106 +
39107 + static struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
39108 + static DEFINE_SPINLOCK(unix_table_lock);
39109 +@@ -727,6 +728,12 @@ static struct sock *unix_find_other(stru
39110 + err = -ECONNREFUSED;
39111 + if (!S_ISSOCK(nd.path.dentry->d_inode->i_mode))
39112 + goto put_fail;
39113 ++
39114 ++ if (!gr_acl_handle_unix(nd.path.dentry, nd.path.mnt)) {
39115 ++ err = -EACCES;
39116 ++ goto put_fail;
39117 ++ }
39118 ++
39119 + u = unix_find_socket_byinode(net, nd.path.dentry->d_inode);
39120 + if (!u)
39121 + goto put_fail;
39122 +@@ -747,6 +754,13 @@ static struct sock *unix_find_other(stru
39123 + if (u) {
39124 + struct dentry *dentry;
39125 + dentry = unix_sk(u)->dentry;
39126 ++
39127 ++ if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
39128 ++ err = -EPERM;
39129 ++ sock_put(u);
39130 ++ goto fail;
39131 ++ }
39132 ++
39133 + if (dentry)
39134 + touch_atime(unix_sk(u)->mnt, dentry);
39135 + } else
39136 +@@ -829,10 +843,20 @@ static int unix_bind(struct socket *sock
39137 + err = mnt_want_write(nd.path.mnt);
39138 + if (err)
39139 + goto out_mknod_dput;
39140 ++
39141 ++ if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
39142 ++ err = -EACCES;
39143 ++ mnt_drop_write(nd.path.mnt);
39144 ++ goto out_mknod_dput;
39145 ++ }
39146 ++
39147 + err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0);
39148 + mnt_drop_write(nd.path.mnt);
39149 + if (err)
39150 + goto out_mknod_dput;
39151 ++
39152 ++ gr_handle_create(dentry, nd.path.mnt);
39153 ++
39154 + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
39155 + dput(nd.path.dentry);
39156 + nd.path.dentry = dentry;
39157 +@@ -850,6 +874,10 @@ static int unix_bind(struct socket *sock
39158 + goto out_unlock;
39159 + }
39160 +
39161 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
39162 ++ sk->sk_peercred.pid = current->pid;
39163 ++#endif
39164 ++
39165 + list = &unix_socket_table[addr->hash];
39166 + } else {
39167 + list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
39168 +diff -urNp linux-2.6.26.6/scripts/pnmtologo.c linux-2.6.26.6/scripts/pnmtologo.c
39169 +--- linux-2.6.26.6/scripts/pnmtologo.c 2008-10-08 23:24:05.000000000 -0400
39170 ++++ linux-2.6.26.6/scripts/pnmtologo.c 2008-10-11 21:54:20.000000000 -0400
39171 +@@ -237,14 +237,14 @@ static void write_header(void)
39172 + fprintf(out, " * Linux logo %s\n", logoname);
39173 + fputs(" */\n\n", out);
39174 + fputs("#include <linux/linux_logo.h>\n\n", out);
39175 +- fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
39176 ++ fprintf(out, "static unsigned char %s_data[] = {\n",
39177 + logoname);
39178 + }
39179 +
39180 + static void write_footer(void)
39181 + {
39182 + fputs("\n};\n\n", out);
39183 +- fprintf(out, "struct linux_logo %s __initdata = {\n", logoname);
39184 ++ fprintf(out, "struct linux_logo %s = {\n", logoname);
39185 + fprintf(out, " .type\t= %s,\n", logo_types[logo_type]);
39186 + fprintf(out, " .width\t= %d,\n", logo_width);
39187 + fprintf(out, " .height\t= %d,\n", logo_height);
39188 +@@ -374,7 +374,7 @@ static void write_logo_clut224(void)
39189 + fputs("\n};\n\n", out);
39190 +
39191 + /* write logo clut */
39192 +- fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
39193 ++ fprintf(out, "static unsigned char %s_clut[] = {\n",
39194 + logoname);
39195 + write_hex_cnt = 0;
39196 + for (i = 0; i < logo_clutsize; i++) {
39197 +diff -urNp linux-2.6.26.6/security/commoncap.c linux-2.6.26.6/security/commoncap.c
39198 +--- linux-2.6.26.6/security/commoncap.c 2008-10-08 23:24:05.000000000 -0400
39199 ++++ linux-2.6.26.6/security/commoncap.c 2008-10-11 21:54:20.000000000 -0400
39200 +@@ -26,10 +26,13 @@
39201 + #include <linux/sched.h>
39202 + #include <linux/prctl.h>
39203 + #include <linux/securebits.h>
39204 ++#include <linux/grsecurity.h>
39205 ++
39206 ++extern kernel_cap_t gr_cap_rtnetlink(struct sock *sk);
39207 +
39208 + int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
39209 + {
39210 +- NETLINK_CB(skb).eff_cap = current->cap_effective;
39211 ++ NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink(sk);
39212 + return 0;
39213 + }
39214 +
39215 +@@ -51,7 +54,15 @@ EXPORT_SYMBOL(cap_netlink_recv);
39216 + int cap_capable (struct task_struct *tsk, int cap)
39217 + {
39218 + /* Derived from include/linux/sched.h:capable. */
39219 +- if (cap_raised(tsk->cap_effective, cap))
39220 ++ if (cap_raised (tsk->cap_effective, cap))
39221 ++ return 0;
39222 ++ return -EPERM;
39223 ++}
39224 ++
39225 ++int cap_capable_nolog (struct task_struct *tsk, int cap)
39226 ++{
39227 ++ /* tsk = current for all callers */
39228 ++ if (cap_raised(tsk->cap_effective, cap) && gr_is_capable_nolog(cap))
39229 + return 0;
39230 + return -EPERM;
39231 + }
39232 +@@ -356,8 +367,11 @@ void cap_bprm_apply_creds (struct linux_
39233 + }
39234 + }
39235 +
39236 +- current->suid = current->euid = current->fsuid = bprm->e_uid;
39237 +- current->sgid = current->egid = current->fsgid = bprm->e_gid;
39238 ++ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
39239 ++ current->suid = current->euid = current->fsuid = bprm->e_uid;
39240 ++
39241 ++ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
39242 ++ current->sgid = current->egid = current->fsgid = bprm->e_gid;
39243 +
39244 + /* For init, we want to retain the capabilities set
39245 + * in the init_task struct. Thus we skip the usual
39246 +@@ -370,6 +384,8 @@ void cap_bprm_apply_creds (struct linux_
39247 + cap_clear(current->cap_effective);
39248 + }
39249 +
39250 ++ gr_handle_chroot_caps(current);
39251 ++
39252 + /* AUD: Audit candidate if current->cap_effective is set */
39253 +
39254 + current->securebits &= ~issecure_mask(SECURE_KEEP_CAPS);
39255 +@@ -684,7 +700,7 @@ int cap_vm_enough_memory(struct mm_struc
39256 + {
39257 + int cap_sys_admin = 0;
39258 +
39259 +- if (cap_capable(current, CAP_SYS_ADMIN) == 0)
39260 ++ if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
39261 + cap_sys_admin = 1;
39262 + return __vm_enough_memory(mm, pages, cap_sys_admin);
39263 + }
39264 +diff -urNp linux-2.6.26.6/security/dummy.c linux-2.6.26.6/security/dummy.c
39265 +--- linux-2.6.26.6/security/dummy.c 2008-10-08 23:24:05.000000000 -0400
39266 ++++ linux-2.6.26.6/security/dummy.c 2008-10-11 21:54:20.000000000 -0400
39267 +@@ -29,6 +29,7 @@
39268 + #include <linux/file.h>
39269 + #include <linux/prctl.h>
39270 + #include <linux/securebits.h>
39271 ++#include <linux/grsecurity.h>
39272 +
39273 + static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
39274 + {
39275 +@@ -142,8 +143,11 @@ static void dummy_bprm_apply_creds (stru
39276 + }
39277 + }
39278 +
39279 +- current->suid = current->euid = current->fsuid = bprm->e_uid;
39280 +- current->sgid = current->egid = current->fsgid = bprm->e_gid;
39281 ++ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
39282 ++ current->suid = current->euid = current->fsuid = bprm->e_uid;
39283 ++
39284 ++ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
39285 ++ current->sgid = current->egid = current->fsgid = bprm->e_gid;
39286 +
39287 + dummy_capget(current, &current->cap_effective, &current->cap_inheritable, &current->cap_permitted);
39288 + }
39289 +diff -urNp linux-2.6.26.6/security/Kconfig linux-2.6.26.6/security/Kconfig
39290 +--- linux-2.6.26.6/security/Kconfig 2008-10-08 23:24:05.000000000 -0400
39291 ++++ linux-2.6.26.6/security/Kconfig 2008-10-11 21:56:26.000000000 -0400
39292 +@@ -4,6 +4,447 @@
39293 +
39294 + menu "Security options"
39295 +
39296 ++source grsecurity/Kconfig
39297 ++
39298 ++menu "PaX"
39299 ++
39300 ++config PAX
39301 ++ bool "Enable various PaX features"
39302 ++ depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86)
39303 ++ help
39304 ++ This allows you to enable various PaX features. PaX adds
39305 ++ intrusion prevention mechanisms to the kernel that reduce
39306 ++ the risks posed by exploitable memory corruption bugs.
39307 ++
39308 ++menu "PaX Control"
39309 ++ depends on PAX
39310 ++
39311 ++config PAX_SOFTMODE
39312 ++ bool 'Support soft mode'
39313 ++ help
39314 ++ Enabling this option will allow you to run PaX in soft mode, that
39315 ++ is, PaX features will not be enforced by default, only on executables
39316 ++ marked explicitly. You must also enable PT_PAX_FLAGS support as it
39317 ++ is the only way to mark executables for soft mode use.
39318 ++
39319 ++ Soft mode can be activated by using the "pax_softmode=1" kernel command
39320 ++ line option on boot. Furthermore you can control various PaX features
39321 ++ at runtime via the entries in /proc/sys/kernel/pax.
39322 ++
39323 ++config PAX_EI_PAX
39324 ++ bool 'Use legacy ELF header marking'
39325 ++ help
39326 ++ Enabling this option will allow you to control PaX features on
39327 ++ a per executable basis via the 'chpax' utility available at
39328 ++ http://pax.grsecurity.net/. The control flags will be read from
39329 ++ an otherwise reserved part of the ELF header. This marking has
39330 ++ numerous drawbacks (no support for soft-mode, toolchain does not
39331 ++ know about the non-standard use of the ELF header) therefore it
39332 ++ has been deprecated in favour of PT_PAX_FLAGS support.
39333 ++
39334 ++ If you have applications not marked by the PT_PAX_FLAGS ELF
39335 ++ program header then you MUST enable this option otherwise they
39336 ++ will not get any protection.
39337 ++
39338 ++ Note that if you enable PT_PAX_FLAGS marking support as well,
39339 ++ the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
39340 ++
39341 ++config PAX_PT_PAX_FLAGS
39342 ++ bool 'Use ELF program header marking'
39343 ++ help
39344 ++ Enabling this option will allow you to control PaX features on
39345 ++ a per executable basis via the 'paxctl' utility available at
39346 ++ http://pax.grsecurity.net/. The control flags will be read from
39347 ++ a PaX specific ELF program header (PT_PAX_FLAGS). This marking
39348 ++ has the benefits of supporting both soft mode and being fully
39349 ++ integrated into the toolchain (the binutils patch is available
39350 ++ from http://pax.grsecurity.net).
39351 ++
39352 ++ If you have applications not marked by the PT_PAX_FLAGS ELF
39353 ++ program header then you MUST enable the EI_PAX marking support
39354 ++ otherwise they will not get any protection.
39355 ++
39356 ++ Note that if you enable the legacy EI_PAX marking support as well,
39357 ++ the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
39358 ++
39359 ++choice
39360 ++ prompt 'MAC system integration'
39361 ++ default PAX_HAVE_ACL_FLAGS
39362 ++ help
39363 ++ Mandatory Access Control systems have the option of controlling
39364 ++ PaX flags on a per executable basis, choose the method supported
39365 ++ by your particular system.
39366 ++
39367 ++ - "none": if your MAC system does not interact with PaX,
39368 ++ - "direct": if your MAC system defines pax_set_initial_flags() itself,
39369 ++ - "hook": if your MAC system uses the pax_set_initial_flags_func callback.
39370 ++
39371 ++ NOTE: this option is for developers/integrators only.
39372 ++
39373 ++ config PAX_NO_ACL_FLAGS
39374 ++ bool 'none'
39375 ++
39376 ++ config PAX_HAVE_ACL_FLAGS
39377 ++ bool 'direct'
39378 ++
39379 ++ config PAX_HOOK_ACL_FLAGS
39380 ++ bool 'hook'
39381 ++endchoice
39382 ++
39383 ++endmenu
39384 ++
39385 ++menu "Non-executable pages"
39386 ++ depends on PAX
39387 ++
39388 ++config PAX_NOEXEC
39389 ++ bool "Enforce non-executable pages"
39390 ++ 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)
39391 ++ help
39392 ++ By design some architectures do not allow for protecting memory
39393 ++ pages against execution or even if they do, Linux does not make
39394 ++ use of this feature. In practice this means that if a page is
39395 ++ readable (such as the stack or heap) it is also executable.
39396 ++
39397 ++ There is a well known exploit technique that makes use of this
39398 ++ fact and a common programming mistake where an attacker can
39399 ++ introduce code of his choice somewhere in the attacked program's
39400 ++ memory (typically the stack or the heap) and then execute it.
39401 ++
39402 ++ If the attacked program was running with different (typically
39403 ++ higher) privileges than that of the attacker, then he can elevate
39404 ++ his own privilege level (e.g. get a root shell, write to files for
39405 ++ which he does not have write access to, etc).
39406 ++
39407 ++ Enabling this option will let you choose from various features
39408 ++ that prevent the injection and execution of 'foreign' code in
39409 ++ a program.
39410 ++
39411 ++ This will also break programs that rely on the old behaviour and
39412 ++ expect that dynamically allocated memory via the malloc() family
39413 ++ of functions is executable (which it is not). Notable examples
39414 ++ are the XFree86 4.x server, the java runtime and wine.
39415 ++
39416 ++config PAX_PAGEEXEC
39417 ++ bool "Paging based non-executable pages"
39418 ++ depends on !COMPAT_VDSO && PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MPENTIUM4 || MPSC || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2 || MVIAC7)
39419 ++ help
39420 ++ This implementation is based on the paging feature of the CPU.
39421 ++ On i386 without hardware non-executable bit support there is a
39422 ++ variable but usually low performance impact, however on Intel's
39423 ++ P4 core based CPUs it is very high so you should not enable this
39424 ++ for kernels meant to be used on such CPUs.
39425 ++
39426 ++ On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386
39427 ++ with hardware non-executable bit support there is no performance
39428 ++ impact, on ppc the impact is negligible.
39429 ++
39430 ++ Note that several architectures require various emulations due to
39431 ++ badly designed userland ABIs, this will cause a performance impact
39432 ++ but will disappear as soon as userland is fixed (e.g., ppc users
39433 ++ can make use of the secure-plt feature found in binutils).
39434 ++
39435 ++config PAX_SEGMEXEC
39436 ++ bool "Segmentation based non-executable pages"
39437 ++ depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32
39438 ++ help
39439 ++ This implementation is based on the segmentation feature of the
39440 ++ CPU and has a very small performance impact, however applications
39441 ++ will be limited to a 1.5 GB address space instead of the normal
39442 ++ 3 GB.
39443 ++
39444 ++config PAX_EMUTRAMP
39445 ++ bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86)
39446 ++ default y if PARISC || PPC32
39447 ++ help
39448 ++ There are some programs and libraries that for one reason or
39449 ++ another attempt to execute special small code snippets from
39450 ++ non-executable memory pages. Most notable examples are the
39451 ++ signal handler return code generated by the kernel itself and
39452 ++ the GCC trampolines.
39453 ++
39454 ++ If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
39455 ++ such programs will no longer work under your kernel.
39456 ++
39457 ++ As a remedy you can say Y here and use the 'chpax' or 'paxctl'
39458 ++ utilities to enable trampoline emulation for the affected programs
39459 ++ yet still have the protection provided by the non-executable pages.
39460 ++
39461 ++ On parisc and ppc you MUST enable this option and EMUSIGRT as
39462 ++ well, otherwise your system will not even boot.
39463 ++
39464 ++ Alternatively you can say N here and use the 'chpax' or 'paxctl'
39465 ++ utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
39466 ++ for the affected files.
39467 ++
39468 ++ NOTE: enabling this feature *may* open up a loophole in the
39469 ++ protection provided by non-executable pages that an attacker
39470 ++ could abuse. Therefore the best solution is to not have any
39471 ++ files on your system that would require this option. This can
39472 ++ be achieved by not using libc5 (which relies on the kernel
39473 ++ signal handler return code) and not using or rewriting programs
39474 ++ that make use of the nested function implementation of GCC.
39475 ++ Skilled users can just fix GCC itself so that it implements
39476 ++ nested function calls in a way that does not interfere with PaX.
39477 ++
39478 ++config PAX_EMUSIGRT
39479 ++ bool "Automatically emulate sigreturn trampolines"
39480 ++ depends on PAX_EMUTRAMP && (PARISC || PPC32)
39481 ++ default y
39482 ++ help
39483 ++ Enabling this option will have the kernel automatically detect
39484 ++ and emulate signal return trampolines executing on the stack
39485 ++ that would otherwise lead to task termination.
39486 ++
39487 ++ This solution is intended as a temporary one for users with
39488 ++ legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
39489 ++ Modula-3 runtime, etc) or executables linked to such, basically
39490 ++ everything that does not specify its own SA_RESTORER function in
39491 ++ normal executable memory like glibc 2.1+ does.
39492 ++
39493 ++ On parisc and ppc you MUST enable this option, otherwise your
39494 ++ system will not even boot.
39495 ++
39496 ++ NOTE: this feature cannot be disabled on a per executable basis
39497 ++ and since it *does* open up a loophole in the protection provided
39498 ++ by non-executable pages, the best solution is to not have any
39499 ++ files on your system that would require this option.
39500 ++
39501 ++config PAX_MPROTECT
39502 ++ bool "Restrict mprotect()"
39503 ++ depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
39504 ++ help
39505 ++ Enabling this option will prevent programs from
39506 ++ - changing the executable status of memory pages that were
39507 ++ not originally created as executable,
39508 ++ - making read-only executable pages writable again,
39509 ++ - creating executable pages from anonymous memory.
39510 ++
39511 ++ You should say Y here to complete the protection provided by
39512 ++ the enforcement of non-executable pages.
39513 ++
39514 ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
39515 ++ this feature on a per file basis.
39516 ++
39517 ++config PAX_NOELFRELOCS
39518 ++ bool "Disallow ELF text relocations"
39519 ++ depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86)
39520 ++ help
39521 ++ Non-executable pages and mprotect() restrictions are effective
39522 ++ in preventing the introduction of new executable code into an
39523 ++ attacked task's address space. There remain only two venues
39524 ++ for this kind of attack: if the attacker can execute already
39525 ++ existing code in the attacked task then he can either have it
39526 ++ create and mmap() a file containing his code or have it mmap()
39527 ++ an already existing ELF library that does not have position
39528 ++ independent code in it and use mprotect() on it to make it
39529 ++ writable and copy his code there. While protecting against
39530 ++ the former approach is beyond PaX, the latter can be prevented
39531 ++ by having only PIC ELF libraries on one's system (which do not
39532 ++ need to relocate their code). If you are sure this is your case,
39533 ++ then enable this option otherwise be careful as you may not even
39534 ++ be able to boot or log on your system (for example, some PAM
39535 ++ modules are erroneously compiled as non-PIC by default).
39536 ++
39537 ++ NOTE: if you are using dynamic ELF executables (as suggested
39538 ++ when using ASLR) then you must have made sure that you linked
39539 ++ your files using the PIC version of crt1 (the et_dyn.tar.gz package
39540 ++ referenced there has already been updated to support this).
39541 ++
39542 ++config PAX_ETEXECRELOCS
39543 ++ bool "Allow ELF ET_EXEC text relocations"
39544 ++ depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
39545 ++ default y
39546 ++ help
39547 ++ On some architectures there are incorrectly created applications
39548 ++ that require text relocations and would not work without enabling
39549 ++ this option. If you are an alpha, ia64 or parisc user, you should
39550 ++ enable this option and disable it once you have made sure that
39551 ++ none of your applications need it.
39552 ++
39553 ++config PAX_EMUPLT
39554 ++ bool "Automatically emulate ELF PLT"
39555 ++ depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
39556 ++ default y
39557 ++ help
39558 ++ Enabling this option will have the kernel automatically detect
39559 ++ and emulate the Procedure Linkage Table entries in ELF files.
39560 ++ On some architectures such entries are in writable memory, and
39561 ++ become non-executable leading to task termination. Therefore
39562 ++ it is mandatory that you enable this option on alpha, parisc,
39563 ++ ppc (if secure-plt is not used throughout in userland), sparc
39564 ++ and sparc64, otherwise your system would not even boot.
39565 ++
39566 ++ NOTE: this feature *does* open up a loophole in the protection
39567 ++ provided by the non-executable pages, therefore the proper
39568 ++ solution is to modify the toolchain to produce a PLT that does
39569 ++ not need to be writable.
39570 ++
39571 ++config PAX_DLRESOLVE
39572 ++ bool
39573 ++ depends on PAX_EMUPLT && (SPARC32 || SPARC64)
39574 ++ default y
39575 ++
39576 ++config PAX_SYSCALL
39577 ++ bool
39578 ++ depends on PAX_PAGEEXEC && PPC32
39579 ++ default y
39580 ++
39581 ++config PAX_KERNEXEC
39582 ++ bool "Enforce non-executable kernel pages"
39583 ++ depends on PAX_NOEXEC && X86 && !EFI && !COMPAT_VDSO && (!X86_32 || X86_WP_WORKS_OK) && !PARAVIRT
39584 ++ help
39585 ++ This is the kernel land equivalent of PAGEEXEC and MPROTECT,
39586 ++ that is, enabling this option will make it harder to inject
39587 ++ and execute 'foreign' code in kernel memory itself.
39588 ++
39589 ++endmenu
39590 ++
39591 ++menu "Address Space Layout Randomization"
39592 ++ depends on PAX
39593 ++
39594 ++config PAX_ASLR
39595 ++ bool "Address Space Layout Randomization"
39596 ++ depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
39597 ++ help
39598 ++ Many if not most exploit techniques rely on the knowledge of
39599 ++ certain addresses in the attacked program. The following options
39600 ++ will allow the kernel to apply a certain amount of randomization
39601 ++ to specific parts of the program thereby forcing an attacker to
39602 ++ guess them in most cases. Any failed guess will most likely crash
39603 ++ the attacked program which allows the kernel to detect such attempts
39604 ++ and react on them. PaX itself provides no reaction mechanisms,
39605 ++ instead it is strongly encouraged that you make use of Nergal's
39606 ++ segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
39607 ++ (http://www.grsecurity.net/) built-in crash detection features or
39608 ++ develop one yourself.
39609 ++
39610 ++ By saying Y here you can choose to randomize the following areas:
39611 ++ - top of the task's kernel stack
39612 ++ - top of the task's userland stack
39613 ++ - base address for mmap() requests that do not specify one
39614 ++ (this includes all libraries)
39615 ++ - base address of the main executable
39616 ++
39617 ++ It is strongly recommended to say Y here as address space layout
39618 ++ randomization has negligible impact on performance yet it provides
39619 ++ a very effective protection.
39620 ++
39621 ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
39622 ++ this feature on a per file basis.
39623 ++
39624 ++config PAX_RANDKSTACK
39625 ++ bool "Randomize kernel stack base"
39626 ++ depends on PAX_ASLR && X86_TSC && X86_32
39627 ++ help
39628 ++ By saying Y here the kernel will randomize every task's kernel
39629 ++ stack on every system call. This will not only force an attacker
39630 ++ to guess it but also prevent him from making use of possible
39631 ++ leaked information about it.
39632 ++
39633 ++ Since the kernel stack is a rather scarce resource, randomization
39634 ++ may cause unexpected stack overflows, therefore you should very
39635 ++ carefully test your system. Note that once enabled in the kernel
39636 ++ configuration, this feature cannot be disabled on a per file basis.
39637 ++
39638 ++config PAX_RANDUSTACK
39639 ++ bool "Randomize user stack base"
39640 ++ depends on PAX_ASLR
39641 ++ help
39642 ++ By saying Y here the kernel will randomize every task's userland
39643 ++ stack. The randomization is done in two steps where the second
39644 ++ one may apply a big amount of shift to the top of the stack and
39645 ++ cause problems for programs that want to use lots of memory (more
39646 ++ than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
39647 ++ For this reason the second step can be controlled by 'chpax' or
39648 ++ 'paxctl' on a per file basis.
39649 ++
39650 ++config PAX_RANDMMAP
39651 ++ bool "Randomize mmap() base"
39652 ++ depends on PAX_ASLR
39653 ++ help
39654 ++ By saying Y here the kernel will use a randomized base address for
39655 ++ mmap() requests that do not specify one themselves. As a result
39656 ++ all dynamically loaded libraries will appear at random addresses
39657 ++ and therefore be harder to exploit by a technique where an attacker
39658 ++ attempts to execute library code for his purposes (e.g. spawn a
39659 ++ shell from an exploited program that is running at an elevated
39660 ++ privilege level).
39661 ++
39662 ++ Furthermore, if a program is relinked as a dynamic ELF file, its
39663 ++ base address will be randomized as well, completing the full
39664 ++ randomization of the address space layout. Attacking such programs
39665 ++ becomes a guess game. You can find an example of doing this at
39666 ++ http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
39667 ++ http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
39668 ++
39669 ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
39670 ++ feature on a per file basis.
39671 ++
39672 ++endmenu
39673 ++
39674 ++menu "Miscellaneous hardening features"
39675 ++
39676 ++config PAX_MEMORY_SANITIZE
39677 ++ bool "Sanitize all freed memory"
39678 ++ help
39679 ++ By saying Y here the kernel will erase memory pages as soon as they
39680 ++ are freed. This in turn reduces the lifetime of data stored in the
39681 ++ pages, making it less likely that sensitive information such as
39682 ++ passwords, cryptographic secrets, etc stay in memory for too long.
39683 ++
39684 ++ This is especially useful for programs whose runtime is short, long
39685 ++ lived processes and the kernel itself benefit from this as long as
39686 ++ they operate on whole memory pages and ensure timely freeing of pages
39687 ++ that may hold sensitive information.
39688 ++
39689 ++ The tradeoff is performance impact, on a single CPU system kernel
39690 ++ compilation sees a 3% slowdown, other systems and workloads may vary
39691 ++ and you are advised to test this feature on your expected workload
39692 ++ before deploying it.
39693 ++
39694 ++ Note that this feature does not protect data stored in live pages,
39695 ++ e.g., process memory swapped to disk may stay there for a long time.
39696 ++
39697 ++config PAX_MEMORY_UDEREF
39698 ++ bool "Prevent invalid userland pointer dereference"
39699 ++ depends on X86_32 && !COMPAT_VDSO && !UML_X86
39700 ++ help
39701 ++ By saying Y here the kernel will be prevented from dereferencing
39702 ++ userland pointers in contexts where the kernel expects only kernel
39703 ++ pointers. This is both a useful runtime debugging feature and a
39704 ++ security measure that prevents exploiting a class of kernel bugs.
39705 ++
39706 ++ The tradeoff is that some virtualization solutions may experience
39707 ++ a huge slowdown and therefore you should not enable this feature
39708 ++ for kernels meant to run in such environments. Whether a given VM
39709 ++ solution is affected or not is best determined by simply trying it
39710 ++ out, the performance impact will be obvious right on boot as this
39711 ++ mechanism engages from very early on. A good rule of thumb is that
39712 ++ VMs running on CPUs without hardware virtualization support (i.e.,
39713 ++ the majority of IA-32 CPUs) will likely experience the slowdown.
39714 ++
39715 ++config PAX_REFCOUNT
39716 ++ bool "Prevent various kernel object reference counter overflows"
39717 ++ depends on X86
39718 ++ help
39719 ++ By saying Y here the kernel will detect and prevent overflowing
39720 ++ various (but not all) kinds of object reference counters. Such
39721 ++ overflows can normally occur due to bugs only and are often, if
39722 ++ not always, exploitable.
39723 ++
39724 ++ The tradeoff is that data structures protected by an oveflowed
39725 ++ refcount will never be freed and therefore will leak memory. Note
39726 ++ that this leak also happens even without this protection but in
39727 ++ that case the overflow can eventually trigger the freeing of the
39728 ++ data structure while it is still being used elsewhere, resulting
39729 ++ in the exploitable situation that this feature prevents.
39730 ++
39731 ++ Since this has a negligible performance impact, you should enable
39732 ++ this feature.
39733 ++endmenu
39734 ++
39735 ++endmenu
39736 ++
39737 + config KEYS
39738 + bool "Enable access key retention support"
39739 + help
39740 +diff -urNp linux-2.6.26.6/sound/core/oss/pcm_oss.c linux-2.6.26.6/sound/core/oss/pcm_oss.c
39741 +--- linux-2.6.26.6/sound/core/oss/pcm_oss.c 2008-10-08 23:24:05.000000000 -0400
39742 ++++ linux-2.6.26.6/sound/core/oss/pcm_oss.c 2008-10-11 21:54:20.000000000 -0400
39743 +@@ -2911,8 +2911,8 @@ static void snd_pcm_oss_proc_done(struct
39744 + }
39745 + }
39746 + #else /* !CONFIG_SND_VERBOSE_PROCFS */
39747 +-#define snd_pcm_oss_proc_init(pcm)
39748 +-#define snd_pcm_oss_proc_done(pcm)
39749 ++#define snd_pcm_oss_proc_init(pcm) do {} while (0)
39750 ++#define snd_pcm_oss_proc_done(pcm) do {} while (0)
39751 + #endif /* CONFIG_SND_VERBOSE_PROCFS */
39752 +
39753 + /*
39754 +diff -urNp linux-2.6.26.6/sound/core/seq/seq_lock.h linux-2.6.26.6/sound/core/seq/seq_lock.h
39755 +--- linux-2.6.26.6/sound/core/seq/seq_lock.h 2008-10-08 23:24:05.000000000 -0400
39756 ++++ linux-2.6.26.6/sound/core/seq/seq_lock.h 2008-10-11 21:54:20.000000000 -0400
39757 +@@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo
39758 + #else /* SMP || CONFIG_SND_DEBUG */
39759 +
39760 + typedef spinlock_t snd_use_lock_t; /* dummy */
39761 +-#define snd_use_lock_init(lockp) /**/
39762 +-#define snd_use_lock_use(lockp) /**/
39763 +-#define snd_use_lock_free(lockp) /**/
39764 +-#define snd_use_lock_sync(lockp) /**/
39765 ++#define snd_use_lock_init(lockp) do {} while (0)
39766 ++#define snd_use_lock_use(lockp) do {} while (0)
39767 ++#define snd_use_lock_free(lockp) do {} while (0)
39768 ++#define snd_use_lock_sync(lockp) do {} while (0)
39769 +
39770 + #endif /* SMP || CONFIG_SND_DEBUG */
39771 +
39772 +diff -urNp linux-2.6.26.6/sound/pci/ac97/ac97_patch.c linux-2.6.26.6/sound/pci/ac97/ac97_patch.c
39773 +--- linux-2.6.26.6/sound/pci/ac97/ac97_patch.c 2008-10-08 23:24:05.000000000 -0400
39774 ++++ linux-2.6.26.6/sound/pci/ac97/ac97_patch.c 2008-10-11 21:54:20.000000000 -0400
39775 +@@ -1497,7 +1497,7 @@ static const struct snd_ac97_res_table a
39776 + { AC97_VIDEO, 0x9f1f },
39777 + { AC97_AUX, 0x9f1f },
39778 + { AC97_PCM, 0x9f1f },
39779 +- { } /* terminator */
39780 ++ { 0, 0 } /* terminator */
39781 + };
39782 +
39783 + static int patch_ad1819(struct snd_ac97 * ac97)
39784 +@@ -3591,7 +3591,7 @@ static struct snd_ac97_res_table lm4550_
39785 + { AC97_AUX, 0x1f1f },
39786 + { AC97_PCM, 0x1f1f },
39787 + { AC97_REC_GAIN, 0x0f0f },
39788 +- { } /* terminator */
39789 ++ { 0, 0 } /* terminator */
39790 + };
39791 +
39792 + static int patch_lm4550(struct snd_ac97 *ac97)
39793 +diff -urNp linux-2.6.26.6/sound/pci/ens1370.c linux-2.6.26.6/sound/pci/ens1370.c
39794 +--- linux-2.6.26.6/sound/pci/ens1370.c 2008-10-08 23:24:05.000000000 -0400
39795 ++++ linux-2.6.26.6/sound/pci/ens1370.c 2008-10-11 21:54:20.000000000 -0400
39796 +@@ -452,7 +452,7 @@ static struct pci_device_id snd_audiopci
39797 + { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1373 - CT5880 */
39798 + { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ectiva EV1938 */
39799 + #endif
39800 +- { 0, }
39801 ++ { 0, 0, 0, 0, 0, 0, 0 }
39802 + };
39803 +
39804 + MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
39805 +diff -urNp linux-2.6.26.6/sound/pci/intel8x0.c linux-2.6.26.6/sound/pci/intel8x0.c
39806 +--- linux-2.6.26.6/sound/pci/intel8x0.c 2008-10-08 23:24:05.000000000 -0400
39807 ++++ linux-2.6.26.6/sound/pci/intel8x0.c 2008-10-11 21:54:20.000000000 -0400
39808 +@@ -437,7 +437,7 @@ static struct pci_device_id snd_intel8x0
39809 + { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
39810 + { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
39811 + { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
39812 +- { 0, }
39813 ++ { 0, 0, 0, 0, 0, 0, 0 }
39814 + };
39815 +
39816 + MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
39817 +@@ -2076,7 +2076,7 @@ static struct ac97_quirk ac97_quirks[] _
39818 + .type = AC97_TUNE_HP_ONLY
39819 + },
39820 + #endif
39821 +- { } /* terminator */
39822 ++ { 0, 0, 0, 0, NULL, 0 } /* terminator */
39823 + };
39824 +
39825 + static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
39826 +diff -urNp linux-2.6.26.6/sound/pci/intel8x0m.c linux-2.6.26.6/sound/pci/intel8x0m.c
39827 +--- linux-2.6.26.6/sound/pci/intel8x0m.c 2008-10-08 23:24:05.000000000 -0400
39828 ++++ linux-2.6.26.6/sound/pci/intel8x0m.c 2008-10-11 21:54:20.000000000 -0400
39829 +@@ -239,7 +239,7 @@ static struct pci_device_id snd_intel8x0
39830 + { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
39831 + { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
39832 + #endif
39833 +- { 0, }
39834 ++ { 0, 0, 0, 0, 0, 0, 0 }
39835 + };
39836 +
39837 + MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
39838 +@@ -1257,7 +1257,7 @@ static struct shortname_table {
39839 + { 0x5455, "ALi M5455" },
39840 + { 0x746d, "AMD AMD8111" },
39841 + #endif
39842 +- { 0 },
39843 ++ { 0, NULL },
39844 + };
39845 +
39846 + static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
39847 +diff -urNp linux-2.6.26.6/virt/kvm/kvm_main.c linux-2.6.26.6/virt/kvm/kvm_main.c
39848 +--- linux-2.6.26.6/virt/kvm/kvm_main.c 2008-10-08 23:24:05.000000000 -0400
39849 ++++ linux-2.6.26.6/virt/kvm/kvm_main.c 2008-10-11 21:55:52.000000000 -0400
39850 +@@ -1182,7 +1182,6 @@ static int kvm_dev_ioctl_create_vm(void)
39851 + static long kvm_dev_ioctl(struct file *filp,
39852 + unsigned int ioctl, unsigned long arg)
39853 + {
39854 +- void __user *argp = (void __user *)arg;
39855 + long r = -EINVAL;
39856 +
39857 + switch (ioctl) {
39858 +@@ -1199,7 +1198,7 @@ static long kvm_dev_ioctl(struct file *f
39859 + r = kvm_dev_ioctl_create_vm();
39860 + break;
39861 + case KVM_CHECK_EXTENSION:
39862 +- r = kvm_dev_ioctl_check_extension((long)argp);
39863 ++ r = kvm_dev_ioctl_check_extension(arg);
39864 + break;
39865 + case KVM_GET_VCPU_MMAP_SIZE:
39866 + r = -EINVAL;
39867 +@@ -1231,6 +1230,9 @@ static struct miscdevice kvm_dev = {
39868 + KVM_MINOR,
39869 + "kvm",
39870 + &kvm_chardev_ops,
39871 ++ {NULL, NULL},
39872 ++ NULL,
39873 ++ NULL
39874 + };
39875 +
39876 + static void hardware_enable(void *junk)
39877
39878 Added: hardened/2.6/tags/2.6.26-9/4421_grsec-remove-localversion-grsec.patch
39879 ===================================================================
39880 --- hardened/2.6/tags/2.6.26-9/4421_grsec-remove-localversion-grsec.patch (rev 0)
39881 +++ hardened/2.6/tags/2.6.26-9/4421_grsec-remove-localversion-grsec.patch 2009-01-20 21:29:55 UTC (rev 1479)
39882 @@ -0,0 +1,9 @@
39883 +From: Kerin Millar <kerframil@×××××.com>
39884 +
39885 +Remove grsecurity's localversion-grsec file as it is inconsistent with
39886 +Gentoo's kernel practices and naming scheme.
39887 +
39888 +--- a/localversion-grsec 2008-02-24 14:26:59.000000000 +0000
39889 ++++ b/localversion-grsec 1970-01-01 01:00:00.000000000 +0100
39890 +@@ -1 +0,0 @@
39891 +--grsec
39892
39893 Added: hardened/2.6/tags/2.6.26-9/4422_grsec-mute-warnings.patch
39894 ===================================================================
39895 --- hardened/2.6/tags/2.6.26-9/4422_grsec-mute-warnings.patch (rev 0)
39896 +++ hardened/2.6/tags/2.6.26-9/4422_grsec-mute-warnings.patch 2009-01-20 21:29:55 UTC (rev 1479)
39897 @@ -0,0 +1,28 @@
39898 +From: Gordon Malm <gengor@g.o>
39899 +
39900 +Updated patch for kernel series 2.6.24.
39901 +
39902 +The credits/description from the original version of this patch remain accurate
39903 +and are included below.
39904 +
39905 +---
39906 +From: Alexander Gabert <gaberta@××××××××.de>
39907 +
39908 +This patch removes the warnings introduced by grsec patch 2.1.9 and later.
39909 +It removes the -W options added by the patch and restores the original
39910 +warning flags of vanilla kernel versions.
39911 +
39912 +Acked-by: Christian Heim <phreak@g.o>
39913 +---
39914 +
39915 +--- a/Makefile
39916 ++++ b/Makefile
39917 +@@ -214,7 +214,7 @@
39918 +
39919 + HOSTCC = gcc
39920 + HOSTCXX = g++
39921 +-HOSTCFLAGS = -Wall -W -Wno-unused -Wno-sign-compare -Wstrict-prototypes -O2 -fomit-frame-pointer
39922 ++HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
39923 + HOSTCXXFLAGS = -O2
39924 +
39925 + # Decide whether to build built-in, modular, or both.
39926
39927 Added: hardened/2.6/tags/2.6.26-9/4425_grsec-pax-without-grsec.patch
39928 ===================================================================
39929 --- hardened/2.6/tags/2.6.26-9/4425_grsec-pax-without-grsec.patch (rev 0)
39930 +++ hardened/2.6/tags/2.6.26-9/4425_grsec-pax-without-grsec.patch 2009-01-20 21:29:55 UTC (rev 1479)
39931 @@ -0,0 +1,47 @@
39932 +From: Gordon Malm <gengor@g.o>
39933 +
39934 +Allow PaX options to be selected without first selecting CONFIG_GRKERNSEC.
39935 +
39936 +This patch has been updated to keep current with newer kernel versions.
39937 +The original version of this patch contained no credits/description.
39938 +
39939 +--- a/arch/x86/mm/fault.c
39940 ++++ b/arch/x86/mm/fault.c
39941 +@@ -422,10 +422,12 @@ static void show_fault_oops(struct pt_re
39942 + #else
39943 + if (init_mm.start_code <= address && address < init_mm.end_code)
39944 + #endif
39945 ++#ifdef CONFIG_GRKERNSEC
39946 + if (current->signal->curr_ip)
39947 + printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
39948 + NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current->uid, current->euid);
39949 + else
39950 ++#endif
39951 + printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
39952 + current->comm, task_pid_nr(current), current->uid, current->euid);
39953 + #endif
39954 +--- a/fs/exec.c
39955 ++++ b/fs/exec.c
39956 +@@ -1682,9 +1682,11 @@ void pax_report_fault(struct pt_regs *re
39957 + }
39958 + up_read(&mm->mmap_sem);
39959 + }
39960 ++#ifdef CONFIG_GRKERNSEC
39961 + if (tsk->signal->curr_ip)
39962 + 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);
39963 + else
39964 ++#endif
39965 + printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
39966 + printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
39967 + "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
39968 +--- a/security/Kconfig
39969 ++++ b/security/Kconfig
39970 +@@ -10,7 +10,7 @@ menu "PaX"
39971 +
39972 + config PAX
39973 + bool "Enable various PaX features"
39974 +- depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86)
39975 ++ depends on (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86)
39976 + help
39977 + This allows you to enable various PaX features. PaX adds
39978 + intrusion prevention mechanisms to the kernel that reduce
39979
39980 Added: hardened/2.6/tags/2.6.26-9/4430_grsec-kconfig-default-gids.patch
39981 ===================================================================
39982 --- hardened/2.6/tags/2.6.26-9/4430_grsec-kconfig-default-gids.patch (rev 0)
39983 +++ hardened/2.6/tags/2.6.26-9/4430_grsec-kconfig-default-gids.patch 2009-01-20 21:29:55 UTC (rev 1479)
39984 @@ -0,0 +1,76 @@
39985 +From: Kerin Millar <kerframil@×××××.com>
39986 +
39987 +grsecurity contains a number of options which allow certain protections
39988 +to be applied to or exempted from members of a given group. However, the
39989 +default GIDs specified in the upstream patch are entirely arbitrary and
39990 +there is no telling which (if any) groups the GIDs will correlate with
39991 +on an end-user's system. Because some users don't pay a great deal of
39992 +attention to the finer points of kernel configuration, it is probably
39993 +wise to specify some reasonable defaults so as to stop careless users
39994 +from shooting themselves in the foot.
39995 +
39996 +--- a/grsecurity/Kconfig
39997 ++++ b/grsecurity/Kconfig
39998 +@@ -352,7 +564,7 @@
39999 + config GRKERNSEC_PROC_GID
40000 + int "GID for special group"
40001 + depends on GRKERNSEC_PROC_USERGROUP
40002 +- default 1001
40003 ++ default 10
40004 +
40005 + config GRKERNSEC_PROC_ADD
40006 + bool "Additional restrictions"
40007 +@@ -547,7 +759,7 @@
40008 + config GRKERNSEC_AUDIT_GID
40009 + int "GID for auditing"
40010 + depends on GRKERNSEC_AUDIT_GROUP
40011 +- default 1007
40012 ++ default 100
40013 +
40014 + config GRKERNSEC_EXECLOG
40015 + bool "Exec logging"
40016 +@@ -700,7 +912,7 @@
40017 + config GRKERNSEC_TPE_GID
40018 + int "GID for untrusted users"
40019 + depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
40020 +- default 1005
40021 ++ default 100
40022 + help
40023 + If you have selected the "Invert GID option" above, setting this
40024 + GID determines what group TPE restrictions will be *disabled* for.
40025 +@@ -712,7 +924,7 @@
40026 + config GRKERNSEC_TPE_GID
40027 + int "GID for trusted users"
40028 + depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
40029 +- default 1005
40030 ++ default 10
40031 + help
40032 + If you have selected the "Invert GID option" above, setting this
40033 + GID determines what group TPE restrictions will be *disabled* for.
40034 +@@ -754,7 +966,7 @@
40035 + config GRKERNSEC_SOCKET_ALL_GID
40036 + int "GID to deny all sockets for"
40037 + depends on GRKERNSEC_SOCKET_ALL
40038 +- default 1004
40039 ++ default 65534
40040 + help
40041 + Here you can choose the GID to disable socket access for. Remember to
40042 + add the users you want socket access disabled for to the GID
40043 +@@ -775,7 +987,7 @@
40044 + config GRKERNSEC_SOCKET_CLIENT_GID
40045 + int "GID to deny client sockets for"
40046 + depends on GRKERNSEC_SOCKET_CLIENT
40047 +- default 1003
40048 ++ default 65534
40049 + help
40050 + Here you can choose the GID to disable client socket access for.
40051 + Remember to add the users you want client socket access disabled for to
40052 +@@ -793,7 +1005,7 @@
40053 + config GRKERNSEC_SOCKET_SERVER_GID
40054 + int "GID to deny server sockets for"
40055 + depends on GRKERNSEC_SOCKET_SERVER
40056 +- default 1002
40057 ++ default 65534
40058 + help
40059 + Here you can choose the GID to disable server socket access for.
40060 + Remember to add the users you want server socket access disabled for to
40061
40062 Added: hardened/2.6/tags/2.6.26-9/4435_grsec-kconfig-gentoo.patch
40063 ===================================================================
40064 --- hardened/2.6/tags/2.6.26-9/4435_grsec-kconfig-gentoo.patch (rev 0)
40065 +++ hardened/2.6/tags/2.6.26-9/4435_grsec-kconfig-gentoo.patch 2009-01-20 21:29:55 UTC (rev 1479)
40066 @@ -0,0 +1,243 @@
40067 +From: Gordon Malm <gengor@g.o>
40068 +From: Kerin Millar <kerframil@×××××.com>
40069 +
40070 +Add Hardened Gentoo [server/workstation] predefined grsecurity
40071 +levels. They're designed to provide a comparitively high level of
40072 +security while remaining generally suitable for as great a majority
40073 +of the userbase as possible (particularly new users).
40074 +
40075 +Make Hardened Gentoo [workstation] predefined grsecurity level the
40076 +default. The Hardened Gentoo [server] level is more restrictive
40077 +and conflicts with some software and thus would be less suitable.
40078 +
40079 +The original version of this patch was conceived and created by:
40080 +Ned Ludd <solar@g.o>
40081 +
40082 +--- a/grsecurity/Kconfig
40083 ++++ b/grsecurity/Kconfig
40084 +@@ -20,7 +20,7 @@ config GRKERNSEC
40085 + choice
40086 + prompt "Security Level"
40087 + depends on GRKERNSEC
40088 +- default GRKERNSEC_CUSTOM
40089 ++ default GRKERNSEC_HARDENED_WORKSTATION
40090 +
40091 + config GRKERNSEC_LOW
40092 + bool "Low"
40093 +@@ -183,6 +183,216 @@ config GRKERNSEC_HIGH
40094 + - Mount/unmount/remount logging
40095 + - Kernel symbol hiding
40096 + - Prevention of memory exhaustion-based exploits
40097 ++
40098 ++config GRKERNSEC_HARDENED_SERVER
40099 ++ bool "Hardened Gentoo [server]"
40100 ++ select GRKERNSEC_AUDIT_MOUNT
40101 ++ select GRKERNSEC_BRUTE
40102 ++ select GRKERNSEC_CHROOT
40103 ++ select GRKERNSEC_CHROOT_CAPS
40104 ++ select GRKERNSEC_CHROOT_CHDIR
40105 ++ select GRKERNSEC_CHROOT_CHMOD
40106 ++ select GRKERNSEC_CHROOT_DOUBLE
40107 ++ select GRKERNSEC_CHROOT_FCHDIR
40108 ++ select GRKERNSEC_CHROOT_FINDTASK
40109 ++ select GRKERNSEC_CHROOT_MKNOD
40110 ++ select GRKERNSEC_CHROOT_MOUNT
40111 ++ select GRKERNSEC_CHROOT_NICE
40112 ++ select GRKERNSEC_CHROOT_PIVOT
40113 ++ select GRKERNSEC_CHROOT_SHMAT
40114 ++ select GRKERNSEC_CHROOT_SYSCTL
40115 ++ select GRKERNSEC_CHROOT_UNIX
40116 ++ select GRKERNSEC_DMESG
40117 ++ select GRKERNSEC_EXECVE
40118 ++ select GRKERNSEC_FIFO
40119 ++ select GRKERNSEC_FORKFAIL
40120 ++ select GRKERNSEC_HIDESYM
40121 ++ select GRKERNSEC_IO if (X86)
40122 ++ select GRKERNSEC_KMEM
40123 ++ select GRKERNSEC_LINK
40124 ++ select GRKERNSEC_MODSTOP if (MODULES)
40125 ++ select GRKERNSEC_PROC
40126 ++ select GRKERNSEC_PROC_ADD
40127 ++ select GRKERNSEC_PROC_IPADDR
40128 ++ select GRKERNSEC_PROC_MEMMAP
40129 ++ select GRKERNSEC_PROC_USERGROUP
40130 ++ select GRKERNSEC_RANDNET
40131 ++ select GRKERNSEC_RESLOG
40132 ++ select GRKERNSEC_SIGNAL
40133 ++# select GRKERNSEC_SOCKET
40134 ++# select GRKERNSEC_SOCKET_SERVER
40135 ++ select GRKERNSEC_SYSCTL
40136 ++ select GRKERNSEC_SYSCTL_ON
40137 ++ select GRKERNSEC_TIME
40138 ++ select PAX
40139 ++ select PAX_ASLR
40140 ++ select PAX_DLRESOLVE if (SPARC32 || SPARC64)
40141 ++ select PAX_EI_PAX
40142 ++ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
40143 ++ select PAX_EMUSIGRT if (PARISC || PPC32)
40144 ++ select PAX_EMUTRAMP if (PARISC || PPC32)
40145 ++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
40146 ++ select PAX_KERNEXEC if (X86 && !EFI && !COMPAT_VDSO && !PARAVIRT && (!X86_32 || X86_WP_WORKS_OK))
40147 ++ select PAX_MEMORY_SANITIZE
40148 ++ select PAX_MEMORY_UDEREF if (X86_32 && !COMPAT_VDSO && !UML_X86)
40149 ++ select PAX_MPROTECT if (!PPC64)
40150 ++ select PAX_HAVE_ACL_FLAGS
40151 ++ select PAX_NOELFRELOCS if (X86)
40152 ++ select PAX_NOEXEC
40153 ++ select PAX_PAGEEXEC
40154 ++ select PAX_PT_PAX_FLAGS
40155 ++ select PAX_RANDKSTACK if (X86_32 && X86_TSC)
40156 ++ select PAX_RANDMMAP
40157 ++ select PAX_RANDUSTACK
40158 ++ select PAX_REFCOUNT if (X86)
40159 ++ select PAX_SEGMEXEC if (X86_32)
40160 ++ select PAX_SYSCALL if (PPC32)
40161 ++ help
40162 ++ If you say Y here, a configuration will be used that is endorsed by
40163 ++ the Hardened Gentoo project. Therefore, many of the protections
40164 ++ made available by grsecurity and PaX will be enabled.
40165 ++
40166 ++ Hardened Gentoo's pre-defined security levels are designed to provide
40167 ++ a high level of security while minimizing incompatibilities with the
40168 ++ majority of available software. For further information, please
40169 ++ view <http://www.grsecurity.net> and <http://pax.grsecurity.net> as
40170 ++ well as the Hardened Gentoo Primer at
40171 ++ <http://www.gentoo.org/proj/en/hardened/primer.xml>.
40172 ++
40173 ++ This Hardened Gentoo [server] level is identical to the
40174 ++ Hardened Gentoo [workstation] level, but with the GRKERNSEC_IO,
40175 ++ PAX_KERNEXEC and PAX_NOELFRELOCS security features enabled.
40176 ++ Accordingly, this is the preferred security level if the system will
40177 ++ not be utilizing software incompatible with the aforementioned
40178 ++ grsecurity/PaX features.
40179 ++
40180 ++ You may wish to emerge paxctl, a utility which allows you to toggle
40181 ++ PaX features on problematic binaries on an individual basis. Note that
40182 ++ this only works for ELF binaries that contain a PT_PAX_FLAGS header.
40183 ++ Translated, this means that if you wish to toggle PaX features on
40184 ++ binaries provided by applications that are distributed only in binary
40185 ++ format (rather than being built locally from sources), you will need to
40186 ++ run paxctl -C on the binaries beforehand so as to inject the missing
40187 ++ headers.
40188 ++
40189 ++ When this level is selected, some options cannot be changed. However,
40190 ++ you may opt to fully customize the options that are selected by
40191 ++ choosing "Custom" in the Security Level menu. You may find it helpful
40192 ++ to inherit the options selected by the "Hardened Gentoo [server]"
40193 ++ security level as a starting point for further configuration. To
40194 ++ accomplish this, select this security level then exit the menuconfig
40195 ++ interface, saving changes when prompted. Then, run make menuconfig
40196 ++ again and select the "Custom" level.
40197 ++
40198 ++ Note that this security level probably should not be used if the
40199 ++ target system is a 32bit x86 virtualized guest. If you intend to run
40200 ++ the kernel in a 32bit x86 virtualized guest you will likely need to
40201 ++ disable the PAX_MEMORY_UDEREF option in order to avoid an unacceptable
40202 ++ impact on performance.
40203 ++
40204 ++config GRKERNSEC_HARDENED_WORKSTATION
40205 ++ bool "Hardened Gentoo [workstation]"
40206 ++ select GRKERNSEC_AUDIT_MOUNT
40207 ++ select GRKERNSEC_BRUTE
40208 ++ select GRKERNSEC_CHROOT
40209 ++ select GRKERNSEC_CHROOT_CAPS
40210 ++ select GRKERNSEC_CHROOT_CHDIR
40211 ++ select GRKERNSEC_CHROOT_CHMOD
40212 ++ select GRKERNSEC_CHROOT_DOUBLE
40213 ++ select GRKERNSEC_CHROOT_FCHDIR
40214 ++ select GRKERNSEC_CHROOT_FINDTASK
40215 ++ select GRKERNSEC_CHROOT_MKNOD
40216 ++ select GRKERNSEC_CHROOT_MOUNT
40217 ++ select GRKERNSEC_CHROOT_NICE
40218 ++ select GRKERNSEC_CHROOT_PIVOT
40219 ++ select GRKERNSEC_CHROOT_SHMAT
40220 ++ select GRKERNSEC_CHROOT_SYSCTL
40221 ++ select GRKERNSEC_CHROOT_UNIX
40222 ++ select GRKERNSEC_DMESG
40223 ++ select GRKERNSEC_EXECVE
40224 ++ select GRKERNSEC_FIFO
40225 ++ select GRKERNSEC_FORKFAIL
40226 ++ select GRKERNSEC_HIDESYM
40227 ++ select GRKERNSEC_KMEM
40228 ++ select GRKERNSEC_LINK
40229 ++ select GRKERNSEC_MODSTOP if (MODULES)
40230 ++ select GRKERNSEC_PROC
40231 ++ select GRKERNSEC_PROC_ADD
40232 ++ select GRKERNSEC_PROC_IPADDR
40233 ++ select GRKERNSEC_PROC_MEMMAP
40234 ++ select GRKERNSEC_PROC_USERGROUP
40235 ++ select GRKERNSEC_RANDNET
40236 ++ select GRKERNSEC_RESLOG
40237 ++ select GRKERNSEC_SIGNAL
40238 ++# select GRKERNSEC_SOCKET
40239 ++# select GRKERNSEC_SOCKET_SERVER
40240 ++ select GRKERNSEC_SYSCTL
40241 ++ select GRKERNSEC_SYSCTL_ON
40242 ++ select GRKERNSEC_TIME
40243 ++ select PAX
40244 ++ select PAX_ASLR
40245 ++ select PAX_DLRESOLVE if (SPARC32 || SPARC64)
40246 ++ select PAX_EI_PAX
40247 ++ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
40248 ++ select PAX_EMUSIGRT if (PARISC || PPC32)
40249 ++ select PAX_EMUTRAMP if (PARISC || PPC32)
40250 ++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
40251 ++ select PAX_MEMORY_SANITIZE
40252 ++ select PAX_MEMORY_UDEREF if (X86_32 && !COMPAT_VDSO && !UML_X86)
40253 ++ select PAX_MPROTECT if (!PPC64)
40254 ++ select PAX_HAVE_ACL_FLAGS
40255 ++ select PAX_NOEXEC
40256 ++ select PAX_PAGEEXEC
40257 ++ select PAX_PT_PAX_FLAGS
40258 ++ select PAX_RANDKSTACK if (X86_32 && X86_TSC)
40259 ++ select PAX_RANDMMAP
40260 ++ select PAX_RANDUSTACK
40261 ++ select PAX_REFCOUNT if (X86)
40262 ++ select PAX_SEGMEXEC if (X86_32)
40263 ++ select PAX_SYSCALL if (PPC32)
40264 ++ help
40265 ++ If you say Y here, a configuration will be used that is endorsed by
40266 ++ the Hardened Gentoo project. Therefore, many of the protections
40267 ++ made available by grsecurity and PaX will be enabled.
40268 ++
40269 ++ Hardened Gentoo's pre-defined security levels are designed to provide
40270 ++ a high level of security while minimizing incompatibilities with the
40271 ++ majority of available software. For further information, please
40272 ++ view <http://www.grsecurity.net> and <http://pax.grsecurity.net> as
40273 ++ well as the Hardened Gentoo Primer at
40274 ++ <http://www.gentoo.org/proj/en/hardened/primer.xml>.
40275 ++
40276 ++ This Hardened Gentoo [workstation] level is designed for machines
40277 ++ which are intended to run software not compatible with the
40278 ++ GRKERNSEC_IO, PAX_KERNEXEC and PAX_NOELFRELOCS features of grsecurity.
40279 ++ Accordingly, this security level is suitable for use with the X server
40280 ++ "Xorg" and/or any system that will act as host OS to the virtualization
40281 ++ softwares vmware-server or virtualbox.
40282 ++
40283 ++ You may wish to emerge paxctl, a utility which allows you to toggle
40284 ++ PaX features on problematic binaries on an individual basis. Note that
40285 ++ this only works for ELF binaries that contain a PT_PAX_FLAGS header.
40286 ++ Translated, this means that if you wish to toggle PaX features on
40287 ++ binaries provided by applications that are distributed only in binary
40288 ++ format (rather than being built locally from sources), you will need to
40289 ++ run paxctl -C on the binaries beforehand so as to inject the missing
40290 ++ headers.
40291 ++
40292 ++ When this level is selected, some options cannot be changed. However,
40293 ++ you may opt to fully customize the options that are selected by
40294 ++ choosing "Custom" in the Security Level menu. You may find it helpful
40295 ++ to inherit the options selected by the "Hardened Gentoo [workstation]"
40296 ++ security level as a starting point for further configuration. To
40297 ++ accomplish this, select this security level then exit the menuconfig
40298 ++ interface, saving changes when prompted. Then, run make menuconfig
40299 ++ again and select the "Custom" level.
40300 ++
40301 ++ Note that this security level probably should not be used if the
40302 ++ target system is a 32bit x86 virtualized guest. If you intend to run
40303 ++ the kernel in a 32bit x86 virtualized guest you will likely need to
40304 ++ disable the PAX_MEMORY_UDEREF option in order to avoid an unacceptable
40305 ++ impact on performance.
40306 ++
40307 + config GRKERNSEC_CUSTOM
40308 + bool "Custom"
40309 + help
40310
40311 Added: hardened/2.6/tags/2.6.26-9/4440_selinux-avc_audit-log-curr_ip.patch
40312 ===================================================================
40313 --- hardened/2.6/tags/2.6.26-9/4440_selinux-avc_audit-log-curr_ip.patch (rev 0)
40314 +++ hardened/2.6/tags/2.6.26-9/4440_selinux-avc_audit-log-curr_ip.patch 2009-01-20 21:29:55 UTC (rev 1479)
40315 @@ -0,0 +1,65 @@
40316 +From: Gordon Malm <gengor@g.o>
40317 +
40318 +This is a reworked version of the original
40319 +*_selinux-avc_audit-log-curr_ip.patch carried in earlier releases of
40320 +hardened-sources.
40321 +
40322 +Dropping the patch, or simply fixing the #ifdef of the original patch
40323 +could break automated logging setups so this route was necessary.
40324 +
40325 +Suggestions for improving the help text are welcome.
40326 +
40327 +The original patch's description is still accurate and included below.
40328 +
40329 +---
40330 +Provides support for a new field ipaddr within the SELinux
40331 +AVC audit log, relying in task_struct->curr_ip (ipv4 only)
40332 +provided by grSecurity patch to be applied before.
40333 +
40334 +Signed-off-by: Lorenzo Hernandez Garcia-Hierro <lorenzo@×××.org>
40335 +---
40336 +
40337 +--- a/grsecurity/Kconfig
40338 ++++ b/grsecurity/Kconfig
40339 +@@ -1044,6 +1044,27 @@ endmenu
40340 + menu "Logging Options"
40341 + depends on GRKERNSEC
40342 +
40343 ++config GRKERNSEC_SELINUX_AVC_LOG_IPADDR
40344 ++ def_bool n
40345 ++ prompt "Add source IP address to SELinux AVC log messages"
40346 ++ depends on GRKERNSEC && SECURITY_SELINUX
40347 ++ help
40348 ++ If you say Y here, a new field "ipaddr=" will be added to many SELinux
40349 ++ AVC log messages. The value of this field in any given message
40350 ++ represents the source IP address of the remote machine/user that created
40351 ++ the offending process.
40352 ++
40353 ++ This information is sourced from task_struct->curr_ip provided by
40354 ++ grsecurity's GRKERNSEC top-level configuration option. One limitation
40355 ++ is that only IPv4 is supported.
40356 ++
40357 ++ In many instances SELinux AVC log messages already log a superior level
40358 ++ of information that also includes source port and destination ip/port.
40359 ++ Additionally, SELinux's AVC log code supports IPv6.
40360 ++
40361 ++ However, grsecurity's task_struct->curr_ip will sometimes (often?)
40362 ++ provide the offender's IP address where stock SELinux logging fails to.
40363 ++
40364 + config GRKERNSEC_FLOODTIME
40365 + int "Seconds in between log messages (minimum)"
40366 + default 10
40367 +--- a/security/selinux/avc.c
40368 ++++ b/security/selinux/avc.c
40369 +@@ -202,6 +202,11 @@ static void avc_dump_query(struct audit_
40370 + char *scontext;
40371 + u32 scontext_len;
40372 +
40373 ++#ifdef CONFIG_GRKERNSEC_SELINUX_AVC_LOG_IPADDR
40374 ++ if (current->signal->curr_ip)
40375 ++ audit_log_format(ab, "ipaddr=%u.%u.%u.%u ", NIPQUAD(current->signal->curr_ip));
40376 ++#endif
40377 ++
40378 + rc = security_sid_to_context(ssid, &scontext, &scontext_len);
40379 + if (rc)
40380 + audit_log_format(ab, "ssid=%d", ssid);
40381
40382 Added: hardened/2.6/tags/2.6.26-9/4445_disable-compat_vdso.patch
40383 ===================================================================
40384 --- hardened/2.6/tags/2.6.26-9/4445_disable-compat_vdso.patch (rev 0)
40385 +++ hardened/2.6/tags/2.6.26-9/4445_disable-compat_vdso.patch 2009-01-20 21:29:55 UTC (rev 1479)
40386 @@ -0,0 +1,74 @@
40387 +From: Gordon Malm <gengor@g.o>
40388 +From: Kerin Millar <kerframil@×××××.com>
40389 +
40390 +COMPAT_VDSO is inappropriate for any modern Hardened Gentoo system. It
40391 +conflicts with various parts of PaX, crashing the system if enabled
40392 +while PaX's NOEXEC or UDEREF features are active. Moreover, it prevents
40393 +a number of important PaX options from appearing in the configuration
40394 +menu, including all PaX NOEXEC implementations. Unfortunately, the
40395 +reason for the disappearance of these PaX configuration options is
40396 +often far from obvious to inexperienced users.
40397 +
40398 +Therefore, we disable the COMPAT_VDSO menu entry entirely. However,
40399 +COMPAT_VDSO operation can still be enabled via bootparam and sysctl
40400 +interfaces. Consequently, we must also disable the ability to select
40401 +COMPAT_VDSO operation at boot or runtime. Here we patch the kernel so
40402 +that selecting COMPAT_VDSO operation at boot/runtime has no effect if
40403 +conflicting PaX options are enabled, leaving VDSO_ENABLED operation
40404 +intact.
40405 +
40406 +Closes bug: http://bugs.gentoo.org/show_bug.cgi?id=210138
40407 +
40408 +--- a/arch/x86/Kconfig
40409 ++++ b/arch/x86/Kconfig
40410 +@@ -1215,16 +1215,7 @@ config HOTPLUG_CPU
40411 +
40412 + config COMPAT_VDSO
40413 + def_bool n
40414 +- prompt "Compat VDSO support"
40415 + depends on (X86_32 || IA32_EMULATION) && !PAX_NOEXEC
40416 +- help
40417 +- Map the 32-bit VDSO to the predictable old-style address too.
40418 +- ---help---
40419 +- Say N here if you are running a sufficiently recent glibc
40420 +- version (2.3.3 or later), to remove the high-mapped
40421 +- VDSO mapping and to exclusively use the randomized VDSO.
40422 +-
40423 +- If unsure, say Y.
40424 +
40425 + endmenu
40426 +
40427 +--- a/arch/x86/vdso/vdso32-setup.c
40428 ++++ b/arch/x86/vdso/vdso32-setup.c
40429 +@@ -333,17 +333,21 @@ int arch_setup_additional_pages(struct l
40430 +
40431 + map_compat_vdso(compat);
40432 +
40433 ++#if !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF)
40434 + if (compat)
40435 + addr = VDSO_HIGH_BASE;
40436 + else {
40437 ++#endif
40438 + addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
40439 + if (IS_ERR_VALUE(addr)) {
40440 + ret = addr;
40441 + goto up_fail;
40442 + }
40443 ++#if !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF)
40444 + }
40445 +
40446 + if (compat_uses_vma || !compat) {
40447 ++#endif
40448 + /*
40449 + * MAYWRITE to allow gdb to COW and set breakpoints
40450 + *
40451 +@@ -361,7 +365,9 @@ int arch_setup_additional_pages(struct l
40452 +
40453 + if (ret)
40454 + goto up_fail;
40455 ++#if !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF)
40456 + }
40457 ++#endif
40458 +
40459 + current->mm->context.vdso = addr;
40460 + current_thread_info()->sysenter_return =
40461
40462 Added: hardened/2.6/tags/2.6.26-9/4450_pax-2.6.26.7-test32-to-test33.patch
40463 ===================================================================
40464 --- hardened/2.6/tags/2.6.26-9/4450_pax-2.6.26.7-test32-to-test33.patch (rev 0)
40465 +++ hardened/2.6/tags/2.6.26-9/4450_pax-2.6.26.7-test32-to-test33.patch 2009-01-20 21:29:55 UTC (rev 1479)
40466 @@ -0,0 +1,92 @@
40467 +From: Gordon Malm <gengor@g.o>
40468 +
40469 +PaX: Add changes from pax-2.6.26.7-test33 which are not
40470 +integrated into main grsecurity-2.6.26.X patch.
40471 +
40472 +--- a/arch/mips/kernel/binfmt_elfn32.c
40473 ++++ b/arch/mips/kernel/binfmt_elfn32.c
40474 +@@ -51,10 +51,10 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
40475 + #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
40476 +
40477 + #ifdef CONFIG_PAX_ASLR
40478 +-#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
40479 ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
40480 +
40481 +-#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
40482 +-#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
40483 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
40484 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
40485 + #endif
40486 +
40487 + #include <asm/processor.h>
40488 +--- a/arch/mips/kernel/binfmt_elfo32.c
40489 ++++ b/arch/mips/kernel/binfmt_elfo32.c
40490 +@@ -53,10 +53,10 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
40491 + #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
40492 +
40493 + #ifdef CONFIG_PAX_ASLR
40494 +-#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
40495 ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
40496 +
40497 +-#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
40498 +-#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
40499 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
40500 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
40501 + #endif
40502 +
40503 + #include <asm/processor.h>
40504 +--- a/arch/mips/kernel/process.c
40505 ++++ b/arch/mips/kernel/process.c
40506 +@@ -464,15 +464,3 @@ unsigned long get_wchan(struct task_stru
40507 + out:
40508 + return pc;
40509 + }
40510 +-
40511 +-/*
40512 +- * Don't forget that the stack pointer must be aligned on a 8 bytes
40513 +- * boundary for 32-bits ABI and 16 bytes for 64-bits ABI.
40514 +- */
40515 +-unsigned long arch_align_stack(unsigned long sp)
40516 +-{
40517 +- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
40518 +- sp -= get_random_int() & ~PAGE_MASK;
40519 +-
40520 +- return sp & ALMASK;
40521 +-}
40522 +--- a/include/asm-mips/elf.h
40523 ++++ b/include/asm-mips/elf.h
40524 +@@ -369,10 +369,10 @@ extern int dump_task_fpu(struct task_str
40525 + #endif
40526 +
40527 + #ifdef CONFIG_PAX_ASLR
40528 +-#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
40529 ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
40530 +
40531 +-#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
40532 +-#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
40533 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
40534 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
40535 + #endif
40536 +
40537 + #endif /* _ASM_ELF_H */
40538 +--- a/include/asm-mips/system.h
40539 ++++ b/include/asm-mips/system.h
40540 +@@ -215,6 +215,6 @@ extern void per_cpu_trap_init(void);
40541 + */
40542 + #define __ARCH_WANT_UNLOCKED_CTXSW
40543 +
40544 +-#define arch_align_stack(x) (x)
40545 ++#define arch_align_stack(x) ((x) & ALMASK)
40546 +
40547 + #endif /* _ASM_SYSTEM_H */
40548 +--- a/include/asm-x86/system.h
40549 ++++ b/include/asm-x86/system.h
40550 +@@ -325,7 +325,7 @@ void enable_hlt(void);
40551 + extern int es7000_plat;
40552 + void cpu_idle_wait(void);
40553 +
40554 +-#define arch_align_stack(x) (x)
40555 ++#define arch_align_stack(x) ((x) & ~0xfUL)
40556 + extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
40557 +
40558 + void default_idle(void);
40559
40560 Added: hardened/2.6/tags/2.6.26-9/4455_grsec-make-PAX_REFCOUNT-conditional-on-x86.patch
40561 ===================================================================
40562 --- hardened/2.6/tags/2.6.26-9/4455_grsec-make-PAX_REFCOUNT-conditional-on-x86.patch (rev 0)
40563 +++ hardened/2.6/tags/2.6.26-9/4455_grsec-make-PAX_REFCOUNT-conditional-on-x86.patch 2009-01-20 21:29:55 UTC (rev 1479)
40564 @@ -0,0 +1,32 @@
40565 +From: Gordon Malm <gengor@g.o>
40566 +
40567 +Make selection of PAX_REFCOUNT depend on X86.
40568 +PAX_REFCOUNT is an X86-only feature.
40569 +
40570 +Fixes bug #246763.
40571 +
40572 +Thanks to Tom Lloyd for reporting.
40573 +
40574 +This patch is present in upstream grsecurity patches as of
40575 +grsecurity-2.1.12-2.6.27.7-200811201849.patch.
40576 +
40577 +--- a/grsecurity/Kconfig
40578 ++++ b/grsecurity/Kconfig
40579 +@@ -77,7 +77,7 @@ config GRKERNSEC_MEDIUM
40580 + select PAX_RANDUSTACK
40581 + select PAX_ASLR
40582 + select PAX_RANDMMAP
40583 +- select PAX_REFCOUNT
40584 ++ select PAX_REFCOUNT if (X86)
40585 +
40586 + help
40587 + If you say Y here, several features in addition to those included
40588 +@@ -155,7 +155,7 @@ config GRKERNSEC_HIGH
40589 + select PAX_EMUTRAMP if (PARISC)
40590 + select PAX_EMUSIGRT if (PARISC)
40591 + select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
40592 +- select PAX_REFCOUNT
40593 ++ select PAX_REFCOUNT if (X86)
40594 + help
40595 + If you say Y here, many of the features of grsecurity will be
40596 + enabled, which will protect you against many kinds of attacks
40597
40598 Added: hardened/2.6/tags/2.6.26-9/4460_pax-fix-mmap-BUG_ON-task-size-check.patch
40599 ===================================================================
40600 --- hardened/2.6/tags/2.6.26-9/4460_pax-fix-mmap-BUG_ON-task-size-check.patch (rev 0)
40601 +++ hardened/2.6/tags/2.6.26-9/4460_pax-fix-mmap-BUG_ON-task-size-check.patch 2009-01-20 21:29:55 UTC (rev 1479)
40602 @@ -0,0 +1,22 @@
40603 +From: Gordon Malm <gengor@g.o>
40604 +
40605 +Fix incorrect vma task size check under SEGMEXEC.
40606 +
40607 +Fixes bug #246607.
40608 +
40609 +Thanks to Hugo Mildenberger for reporting and PaX Team for the fix.
40610 +
40611 +This patch is present in upstream grsecurity patches as of
40612 +pax-linux-2.6.27.7-test22.patch.
40613 +
40614 +--- a/mm/mmap.c
40615 ++++ b/mm/mmap.c
40616 +@@ -1719,7 +1719,7 @@ struct vm_area_struct *pax_find_mirror_v
40617 + BUG_ON(vma->vm_mirror);
40618 + return NULL;
40619 + }
40620 +- BUG_ON(vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < vma->vm_start - SEGMEXEC_TASK_SIZE - 1);
40621 ++ BUG_ON(vma->vm_start < SEGMEXEC_TASK_SIZE && SEGMEXEC_TASK_SIZE < vma->vm_end);
40622 + vma_m = vma->vm_mirror;
40623 + BUG_ON(!vma_m || vma_m->vm_mirror != vma);
40624 + BUG_ON(vma->vm_file != vma_m->vm_file);
40625
40626 Added: hardened/2.6/tags/2.6.26-9/4465_pax-fix-false-RLIMIT_STACK-warnings.patch
40627 ===================================================================
40628 --- hardened/2.6/tags/2.6.26-9/4465_pax-fix-false-RLIMIT_STACK-warnings.patch (rev 0)
40629 +++ hardened/2.6/tags/2.6.26-9/4465_pax-fix-false-RLIMIT_STACK-warnings.patch 2009-01-20 21:29:55 UTC (rev 1479)
40630 @@ -0,0 +1,88 @@
40631 +From: Gordon Malm <gengor@g.o>
40632 +
40633 +Fix false-positive RLIMIT_STACK warnings.
40634 +
40635 +Thanks to PaX Team for the heads up.
40636 +
40637 +This patch is present in upstream grsecurity patches as of
40638 +pax-linux-2.6.27.7-test22.patch.
40639 +
40640 +--- a/arch/x86/mm/fault.c
40641 ++++ b/arch/x86/mm/fault.c
40642 +@@ -844,16 +844,14 @@ not_pax_fault:
40643 + goto good_area;
40644 + if (!(vma->vm_flags & VM_GROWSDOWN))
40645 + goto bad_area;
40646 +- if (error_code & PF_USER) {
40647 +- /*
40648 +- * Accessing the stack below %sp is always a bug.
40649 +- * The large cushion allows instructions like enter
40650 +- * and pusha to work. ("enter $65535,$31" pushes
40651 +- * 32 pointers and then decrements %sp by 65535.)
40652 +- */
40653 +- if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp)
40654 +- goto bad_area;
40655 +- }
40656 ++ /*
40657 ++ * Accessing the stack below %sp is always a bug.
40658 ++ * The large cushion allows instructions like enter
40659 ++ * and pusha to work. ("enter $65535,$31" pushes
40660 ++ * 32 pointers and then decrements %sp by 65535.)
40661 ++ */
40662 ++ if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp)
40663 ++ goto bad_area;
40664 +
40665 + #ifdef CONFIG_PAX_SEGMEXEC
40666 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)
40667 +--- a/kernel/exit.c
40668 ++++ b/kernel/exit.c
40669 +@@ -39,7 +39,6 @@
40670 + #include <linux/cn_proc.h>
40671 + #include <linux/mutex.h>
40672 + #include <linux/futex.h>
40673 +-#include <linux/compat.h>
40674 + #include <linux/pipe_fs_i.h>
40675 + #include <linux/audit.h> /* for audit_free() */
40676 + #include <linux/resource.h>
40677 +@@ -1058,14 +1057,6 @@ NORET_TYPE void do_exit(long code)
40678 + exit_itimers(tsk->signal);
40679 + }
40680 + acct_collect(code, group_dead);
40681 +-#ifdef CONFIG_FUTEX
40682 +- if (unlikely(tsk->robust_list))
40683 +- exit_robust_list(tsk);
40684 +-#ifdef CONFIG_COMPAT
40685 +- if (unlikely(tsk->compat_robust_list))
40686 +- compat_exit_robust_list(tsk);
40687 +-#endif
40688 +-#endif
40689 + if (group_dead)
40690 + tty_audit_exit();
40691 + if (unlikely(tsk->audit_context))
40692 +--- a/kernel/fork.c
40693 ++++ b/kernel/fork.c
40694 +@@ -36,6 +36,7 @@
40695 + #include <linux/syscalls.h>
40696 + #include <linux/jiffies.h>
40697 + #include <linux/futex.h>
40698 ++#include <linux/compat.h>
40699 + #include <linux/task_io_accounting_ops.h>
40700 + #include <linux/rcupdate.h>
40701 + #include <linux/ptrace.h>
40702 +@@ -514,6 +515,16 @@ void mm_release(struct task_struct *tsk,
40703 + {
40704 + struct completion *vfork_done = tsk->vfork_done;
40705 +
40706 ++ /* Get rid of any futexes when releasing the mm */
40707 ++#ifdef CONFIG_FUTEX
40708 ++ if (unlikely(tsk->robust_list))
40709 ++ exit_robust_list(tsk);
40710 ++#ifdef CONFIG_COMPAT
40711 ++ if (unlikely(tsk->compat_robust_list))
40712 ++ compat_exit_robust_list(tsk);
40713 ++#endif
40714 ++#endif
40715 ++
40716 + /* Get rid of any cached register state */
40717 + deactivate_mm(tsk, mm);
40718 +
40719 \ No newline at end of file